容器技术 - docker

文章目录
  • 一、Docker简介
    • [1.1 Docker诞生](#1.1 Docker诞生)
    • [1.2 Docker相关解释](#1.2 Docker相关解释)
    • [1.3 Docker与传统虚拟化对比](#1.3 Docker与传统虚拟化对比)
    • [1.4 Docker的构成](#1.4 Docker的构成)
  • 二、Docker安装
    • [2.1 Docker的安装方式](#2.1 Docker的安装方式)
    • [2.2 Docker镜像加速配置](#2.2 Docker镜像加速配置)
    • [2.3 Docker化应用体验](#2.3 Docker化应用体验)
  • 三、Docker容器管理
    • [3.1 Docker基础概念](#3.1 Docker基础概念)
    • [3.2 Docker基础命令](#3.2 Docker基础命令)
    • [3.3 单一容器管理命令](#3.3 单一容器管理命令)
    • [3.4 Run延伸](#3.4 Run延伸)
    • [3.5 Docker-Compose](#3.5 Docker-Compose)
  • 四、Docker镜像管理
    • [4.1 镜像的特性](#4.1 镜像的特性)
    • [4.2 容器转换为镜像](#4.2 容器转换为镜像)
    • [4.3 Dockerfile](#4.3 Dockerfile)
    • [4.4 镜像的导出以及导入](#4.4 镜像的导出以及导入)
  • 五、镜像仓库构建
    • [5.1 官方仓库构建方式](#5.1 官方仓库构建方式)
    • [5.2 Harbor构建](#5.2 Harbor构建)
  • 六、Docker中的网络
    • [6.1 Linux 内核中的 NameSpace](#6.1 Linux 内核中的 NameSpace)
    • [6.2 Docker网络通讯示意图](#6.2 Docker网络通讯示意图)
    • [6.3 Docker中的防火墙规则](#6.3 Docker中的防火墙规则)
    • [6.4 Docker网络的修改](#6.4 Docker网络的修改)
    • [6.5 端口的暴露方式](#6.5 端口的暴露方式)
    • [6.6 网络隔离](#6.6 网络隔离)
  • 七、数据存储
    • [7.1 数据卷特性](#7.1 数据卷特性)
    • [7.2 数据卷的意义](#7.2 数据卷的意义)
    • [7.3 数据卷的类型](#7.3 数据卷的类型)
    • [7.4 容器中使用数据卷的方法](#7.4 容器中使用数据卷的方法)
    • [7.5 存储驱动](#7.5 存储驱动)
  • 八、资源限制
    • [8.1 内存资源限制](#8.1 内存资源限制)
    • [8.2 内存限制设置方式](#8.2 内存限制设置方式)
    • [8.3 参数示意图](#8.3 参数示意图)
    • [8.4 CPU资源限制](#8.4 CPU资源限制)
    • [8.5 限制性实验](#8.5 限制性实验)

一、Docker简介

所需软件

链接:http:// https://pan.baidu.com/s/5XplIFUDTP1K51LxEaPt3VQ

复制这段内容后打开百度网盘手机App,操作更方便哦

1.1 Docker诞生

Docker是dotcloud公司开源的一款产品dotcloud是2010年新成立的一家公司,主要基于PAAS(PlatfromasaService)平台为开发者提供服务。2013年10月dotcloud公司改名为Docker股份有限公司

1.2 Docker相关解释

  • LinuxContainer是一种内核虚拟化技术可以提供轻量级的虚拟化,以便隔离进程和资源
  • Docker是PAAS提供商dotCloud开源的一个基于LXC( LinuxContainer**)的高级容器引擎** ,源代码托管在Github上,基于go语言并遵从Apache2.0协议开源
  • Docker设想是交付运行环境如同海运,OS如同一个货轮,每一个在OS基础上的软件都如同一个集装箱,用户可以通过标准化手段自由组装运行环境,同时集装箱的内容可以由用户自定义,也可以由专业人员制造

1.3 Docker与传统虚拟化对比


比较 Docker 和传统虚拟化方式的不同之处:

  • 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程。
  • 而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
  • 每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。

1.4 Docker的构成

  • Docker仓库:https://hub.docker.com
  • Docker自身组件
    • DockerClient:Docker的客户端
    • DockerServer:Dockerdaemon的主要组成部分,接受用户通过DockerClient发出的请求,并按照相应的路由规则实现路由分发
    • Docker镜像:Docker镜像运行之后变成容器(dockerrun)

二、Docker安装

2.1 Docker的安装方式

Script Install(脚本安装)

方式一:

bash 复制代码
[root@localhost ~]$ yum update
[root@localhost ~]$ curl -sSL https://get.docker.com/ | sh
[root@localhost ~]$ systemctl start docker
[root@localhost ~]$ systemctl enable docker
[root@localhost ~]$ docker run hello-world

方式二:(一键安装)

bash 复制代码
bash <(wget -qO- https://xuanyuan.cloud/docker.sh)

YUM Install

Ubuntu

bash 复制代码
Ubuntu(使用 apt-get 进行安装)

# step 1: 安装必要的一些系统工具
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg

# step 2: 信任 Docker 的 GPG 公钥
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Step 3: 写入软件源信息
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
 
# Step 4: 安装Docker
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# apt-cache madison docker-ce
#   docker-ce | 17.03.1~ce-0~ubuntu-xenial | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
#   docker-ce | 17.03.0~ce-0~ubuntu-xenial | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
# Step 2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.1~ce-0~ubuntu-xenial)
# sudo apt-get -y install docker-ce=[VERSION]

centos

bash 复制代码
# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils

# Step 2: 添加软件源信息
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# Step 3: 安装Docker
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Step 4: 开启Docker服务
sudo service docker start

# 注意:
# 官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,您可以通过以下方式开启。同理可以开启各种测试版本等。
# vim /etc/yum.repos.d/docker-ce.repo
#   将[docker-ce-test]下方的enabled=0修改为enabled=1
#
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# yum list docker-ce.x86_64 --showduplicates | sort -r
#   Loading mirror speeds from cached hostfile
#   Loaded plugins: branch, fastestmirror, langpacks
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            docker-ce-stable
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            @docker-ce-stable
#   docker-ce.x86_64            17.03.0.ce-1.el7.centos            docker-ce-stable
#   Available Packages
# Step2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.0.ce.1-1.el7.centos)
# sudo yum -y install docker-ce-[VERSION]
bash 复制代码
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://docker.1ms.run",
    "https://1ms.run/"
  ]
}
EOF
systemctl daemon-reload && systemctl restart docker


#或一键配置
# 一键配置,简单快捷,告别拉取超时
sudo bash -c "$(curl -sSL https://n3.ink/helper)"


https://1ms.run(1毫米镜像源)

会有一个安装包docker-compose-plugin-2.27.1-1.el7.x86_64.rpm 阿里云yum源里没有

手动安装

软件:http:// https://pan.baidu.com/s/5XplIFUDTP1K51LxEaPt3VQ

RPM Install

https://download.docker.com/linux/centos/7/x86_64/stable/Packages/

软件包:http:// https://pan.baidu.com/s/5XplIFUDTP1K51LxEaPt3VQ

bash 复制代码
#环境设置
[root@localhost ~]$ yum -y install iptables-services
[root@localhost ~]$ systemctl start iptables && systemctl enable iptables
[root@localhost ~]$ iptables -F && service iptables save



[root@localhost ~]$ mkdir docker && mv docker* docker/ && cd docker

#安装docker
[root@localhost ~]$ yum -y install * 

#启动docker
[root@localhost ~]$ systemctl start docker && systemctl enable docker

#测试命令
[root@localhost ~]$ docker run hello-world

2.2 Docker镜像加速配置

阿里云Docker加速官网:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

bash 复制代码
[root@localhost ~]$ cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service
[root@localhost ~]$ chmod 777 /etc/systemd/system/docker.service
[root@localhost ~]$ vim /etc/systemd/system/docker.service
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd --registry-mirror=https://kfp63jaj.mirror.aliyuncs.com




[root@localhost ~]$ systemctl daemon-reload
[root@localhost ~]$ systemctl restart docker
[root@localhost ~]$ ps -ef | grep docker

非阿里云的产品加速镜像并不适用

推荐:

1、Docker镜像极速下载服务 - 毫秒镜像

2、Docker 镜像免费公共测试访问入口 | 轩辕镜像免费版

2.3 Docker化应用体验

环境分析

WordPress运行环境需要如下软件的支持:

  • PHP5.6或更新软件
  • MySQL5.6或更新版本
  • Apache和mod_rewrite模块
bash 复制代码
#下载镜像
[root@localhost ~]$ docker pull mariadb
[root@localhost ~]$ docker pull wordpress


[root@localhost ~]$ docker run --name db --env MYSQL_ROOT_PASSWORD=example -d mariadb
#docker run 把镜像转换成一个容器
#--name db 给这个镜像起一个名字db
#--env MYSQL_ROOT_PASSWORD=example 指定环境变量
#-d 后台运行容器,并返回容器ID
#mariadb 镜像名字
#docker run是利用镜像生成容器,并启动容器,而docker start是启动一个之前生成过的容器


[root@localhost ~]$ docker run --name MyWordPress --link db:mysql -p 8080:80 -d wordpress
#--link 衔接关系
#-p 端口映射,主机(宿主)端口:容器端口

三、Docker容器管理

3.1 Docker基础概念

Docker的三个重要概念:

  • 镜像(image)

    镜像,简单的来说,就是面向对象中的类,相当于一个模板。Docker 镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。

  • 容器(container)
    Docker 利用容器(Container)独立运行的一个或一组应用。容器是用镜像创建的运行实例。可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

  • 仓库(repository)

    仓库(Repository)是集中存放镜像文件的场所。

Docker指令的基本用法:

bash 复制代码
docker + 命令关键字(COMMAND) + 一系列的参数

3.2 Docker基础命令

命令 含义
docker info 守护进程的系统资源设置
docker search 镜像名 Docker仓库的查询
docker pull 镜像名 Docker仓库的下载
docker images Docker镜像的查询
docker rmi 镜像id(或镜像名:版本号) Docker镜像的删除
docker ps 容器的查询
docker run 容器的创建启动
docker rm 容器id号(或者 容器名称) 容器的删除
docker start/stop 容器启动停止

Docker指令除了单条使用外,还支持赋值、解析变量、嵌套使用

3.3 单一容器管理命令

每个容器被创建后,都会分配一个CONTAINER ID作为容器的唯一标示,后续对容器的启动、停止、修改、删除等所有操作,都是通过CONTAINER ID或者容器名来完成,偏向于数据库概念中的主键

命令 含义
docker ps --no-trunc 查看
docker stop/start CONTAINERID 停止
docker start/stop MywordPress 通过容器别名启动/停止
docker inspect MywordPress 查看容器所有基本信息
docker logs MywordPress 查看容器日志
docker stats MywordPress 查看容器所占用的系统资源
docker exec 容器名 容器内执行的命令 容器执行命令
docker exec -it 容器名 /bin/bash 登入容器的bash

3.4 Run延伸

参数 含义
--restart=always 容器的自动启动
-h x.xx.xx 设置容器主机名
- dns xx.xx.xx.xx 设置容器使用的DNS服务器
--dns-search DNS搜索设置
--add-host hostname:IP 注入hostname<>IP解析
--rm 服务停止时自动删除

3.5 Docker-Compose

Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

安装Docker-compose

bash 复制代码
[root@localhost ~]$curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

[root@localhost ~]$ chmod +x /usr/local/bin/docker-compose
[root@localhost ~]$ docker-compose --version

Docker-compose用法

参数 含义
-f 指定使用的yaml文件位置
ps 显示所有容器信息
restart 重新启动容器
logs 查看日志信息
config -q 验证yaml配置文件是否正确
stop 停止容器
start 启动容器
up -d 启动容器项目
pause 暂停容器
unpause 恢复暂停
rm 删除容器

示例

bash 复制代码
[root@localhost ~]$ vim wordpress.yaml
version: '2' #版本

services:   #定义一种服务
  db: #第一个容器的名字
    image: mysql:5.7
    restart: always
    environment: #环境变量
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress: #第二个容器的名字
    depends_on:    #相当于--link
      - db
    image: wordpress:latest
    restart: always
    ports:
      - "8000:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress



[root@localhost ~]$ mv wordpress.yaml docker-compose.yaml
[root@localhost ~]$ docker-compose up -d #启动

[root@localhost ~]$ docker ps -a  #启动成功
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                   PORTS                  NAMES
cceb5a8ed799        wordpress:latest    "docker-entrypoint..."   9 minutes ago       Up 9 minutes             0.0.0.0:8000->80/tcp   root_wordpress_1_a2264aaee26c
d3f99d415eac        mysql:5.7           "docker-entrypoint..."   9 minutes ago       Up 9 minutes             3306/tcp, 33060/tcp    root_db_1_87a386700a32
02428d68a259        wordpress           "docker-entrypoint..."   3 weeks ago         Exited (0) 3 weeks ago                          MyWordPress
ae0f8de9e8fd        mariadb             "docker-entrypoint..."   3 weeks ago         Exited (0) 3 weeks ago                          db
8ac302f04535        hello-world         "/hello"                 3 weeks ago         Exited (0) 3 weeks ago                          kickass_noyce



[root@localhost ~]$ docker-compose logs  #启动成功

命令总结:

四、Docker镜像管理

4.1 镜像的特性

容器创建时需要指定镜像,每个镜像都由唯一的标示ImageID,和容器的ContainerID一样,默

认128位,可以使用前16为缩略形式,也可以使用镜像名与版本号两部分组合唯一标示,如果省

略版本号,默认使用最新版本标签(latesr)

镜像的分层: Docker的镜像通过联合文件系统(union filesystem)将各层文件系统叠加在一起

bootfs:用于系统引导的文件系统,包括bootloader和kernel,容器启动完成后会被卸载以节省

内存资源

roofs:位于bootfs之上,表现为Docker容器的跟文件系统

传统模式中,系统启动时,内核挂载rootfs时会首先将其挂载为"只读"模式,完整性自检

完成后将其挂载为读写模式
Docker中,rootfs由内核挂载为"只读"模式,而后通过UFS技术挂载一个"可写"层

1.已有分层只能读不能修改

2.上层镜像优先级大于底层镜像

4.2 容器转换为镜像

bash 复制代码
[root@localhost ~]$ docker commit CID xx.xx.xx
bash 复制代码
#指定仓库拉取镜像
[root@localhost ~]$ docker pull hub.c.163.com/public/centos:6.7-tools

#启动mysql容器
[root@localhost ~]$ docker run --name mysql -d hub.c.163.com/public/centos:6.7-tools

#进入容器
[root@localhost ~]$ docker exec -it mysql /bin/bash

#在容器内安装mysql
[root@396607d4389d /]$ yum -y install mysql mysql-server


[root@localhost ~]$ docker commit mysql mysql:5.1

4.3 Dockerfile

Dockfile是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令。Docker程序将这些Dockerfile指令翻译真正的Linux命令。Dockerfile有自己书写格式和支持的命令,Docker程序解决这些命令间的依赖关系,类似于Makefile。Docker程序将读取Dockerfile,根据指令生成定制的image

转换命令

bash 复制代码
[root@localhost ~]$ docker build -t wangyang/jdk-tomcat .

Dockerfile语法

1、FROM(指定基础image):

构建指令,必须指定且需要在Dockerfile其他指令的前面。后续的指令都依赖于该指令指定的image。

FROM指令指定的基础image可以是官方远程仓库中的,也可以位于本地仓库

bash 复制代码
FROM centos:7.2 #有且只有一个
FROM centos

2、MAINTAINER(用来指定镜像创建者信息):

构建指令,用于将image的制作者相关的信息写入到image中。当我们对该image执行docker inspect命令时,输出中有相应的字段记录该信息。

bash 复制代码
MAINTAINER wangyang"wangyang@itxdl.cn"
#maintainer

3、RUN(安装软件用):

构建指令,RUN可以运行任何被基础image支持的命令。如基础image选择了Centos,那么软件管理部分只能使用Centos的包管理命令,需要执行shell命令,前面加run

bash 复制代码
#常用
RUN cd /tmp && curl-L http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.8/bin/apache-tomcat-7.0.8.tar.gz'|tar-xz  

RUN ["/bin/bash","-c","echo hello"]

4、CMD(设置container容器 启动时执行的操作):

设置指令,用于container启动时指定的操作。该操作可以是执行自定义脚本,也可以是执行系统命令。该指令只能在文件中存在一次,如果有多个,则只执行最后一条

bash 复制代码
CMD echo "Hello World!"

5、ENTRYPOINT(设置container启动时执行的操作):

设置指令,指定容器启动时执行的命令,可以多次设置,但是只有最后一个有效。

bash 复制代码
ENTRYPOINT ls -l
#entrypoint ls -l

该指令的使用分为两种情况,一种是独自使用,另一种和CMD指令配合使用。当独自使用时,如果你还使用了CMD命令且CMD是一个完整的可执行的命令,那么CMD指令和ENTRYPOINT会互相覆盖只有最后一个CMD或者ENTRYPOINT有效

bash 复制代码
#CMD指令将不会被执行,只有ENTRYPOINT指令被执行
CMD echo "Hello World!"
ENTRYPOINT ls -l
#entrypoint

另一种用法和CMD指令配合使用来指定ENTRYPOINT的默认参数,这时CMD指令不是一个完整的可执行命令,仅仅是参数部分;ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数

bash 复制代码
FROM ubuntu
CMD ["-l"]
ENTRYPOINT ["/usr/bin/ls"]
#entrypoint

6、USER(设置container容器的用户):

设置指令,设置启动容器的用户,默认是root用户

bash 复制代码
USER daemon = ENTRYPOINT ["memcached","-u","daemon"]
#entrypoint

7、EXPOSE(指定容器需要映射到宿主机器的端口):

设置指令,该指令会将容器中的端口映射成宿主机器中的某个端口。当你需要访问容器的时候,可以不是用容器的IP地址而是使用宿主机器的IP地址和映射后的端口。要完成整个操作需要两个步骤,首先在Dockerfile使用EXPOSE设置需要映射的容器端口,然后在运行容器的时候指定-p选项加上EXPOSE设置的端口,这样EXPOSE设置的端口号会被随机映射成宿主机器中的一个端口号。也可以指定需要映射到宿主机器的那个端口,这时要确保宿主机器上的端口号没有被使用。EXPOSE指令可以一次设置多个端口号,相应的运行容器的时候,可以配套的多次使用 -p 选项。

bash 复制代码
#映射一个端口
EXPOSE 22

#相应的运行容器使用的命令
docker run -p port1 image

#映射多个端口
EXPOSE port1 port2 port3

#相应的运行容器使用的命令
docker run -p port1 -p port2 -p port3 image

#还可以指定需要映射到宿主机器上的某个端口号
docker run -p host_port1:port1-p host_port2:port2 -p host_port3:port3 image

8、ENV(用于设置环境变量):构建指令,在image中设置一个环境变量

设置了后,后续的RUN命令都可以使用,container启动后,可以通过docker inspect查看这个环

境变量,也可以通过在docker run --env key=value时设置或修改环境变量。假如你安装了JAVA程序,需要设置JAVA HOME,那么可以在Dockerfile中这样写:

bash 复制代码
ENV JAVA_HOME /path/to/java/dirent
#env java_home /path/to/java/dirent

9、ADD(从src复制文件到container的dest路径)
add 解压

bash 复制代码
ADD <src> <dest>
	<src>是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件url;
	<dest>是container中的绝对路径

10、COPY(从src复制文件到container的dest路径)
copy不解压

bash 复制代码
COPY <src> <dest>

11、VOLUME(指定挂载点):

设置指令,使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。我们知道容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令

bash 复制代码
FROM base
VOLUME ["/tmp/data"]

12、WORKDIR(切换目录):设置指令,可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效

bash 复制代码
WORKDIR /p1 WORKDIR p2 RUN vim a.txt
#等同于
run cd  /p1/p2 && vim a.txt

13、ONBUILD(在子镜像中执行):

ONBUILD指定的命令在构建镜像时并不执行,而是在它的子镜像中执行

bash 复制代码
ONBUILD ADD./app/src
ONBUILD RUN /usr/local/bin/python-build--dir /app/src

创建一个tomcat的dockfile

bash 复制代码
[root@localhost ~]$ cat Dockerfile
FROM hub.c.163.com/public/centos:6.7  #基础镜像
MAINTAINER wangyang@itxdl.cn   #坐着信息

ADD ./apache-tomcat-7.0.42.tar.gz /root  #复制文件到容器内
ADD ./jdk-7u25-linux-x64.tar.gz /root

ENV JAVA_HOME /root/jdk1.7.0_25   #设置环境变量
ENV PATH $JAVA_HOME/bin:$PATH

EXPOSE 8080  #开放端口

ENTRYPOINT /root/apache-tomcat-7.0.42/bin/startup.sh && tailf /root/apache-tomcat-7.0.42/logs/catalina.out   #执行命令




#dockerfile转换成镜像
[root@localhost ~]$ docker build -t tomcat:v1.0 .


#镜像转换成容器
[root@localhost ~]$ docker run --name tomcat -p 80:8080 tomcat:v1.0

命令不能超过128行

4.4 镜像的导出以及导入

bash 复制代码
导出:docker save -o xx.xx.xxxx.xx.xx.tar
导入:docker load -i xx.xx.xx.tar

五、镜像仓库构建

5.1 官方仓库构建方式

仓库服务器配置:

bash 复制代码
[root@localhost ~]$ docker run -d -v /opt/registry:/var/lib/registry -p 5000:5000 --restart=always registry

[root@localhost ~]$ vim /etc/docker/daemon.json
{
	"insecure-registries":["10.10.10.11:5000"]
}

客户机设置:

bash 复制代码
[root@localhost ~]$ vim/etc/sysconfig/docker
{
  "registry-mirrors": [
    "https://docker.ims.run",
    "https://ims.run/"
  ],
  "insecure-registries": [
    "10.10.10.11:5000"
  ]
}
#增加
curl -XGET http://10.10.10.11:5000/v2/_catalog 
#查看已有镜像

5.2 Harbor构建

https://www.yuque.com/office/yuque/0/2020/pdf/393192/1603727507994-60aba29a-b8fc-4b89-ab0c-323cc94e7dd0.pdf?from=https%3A%2F%2Fwww.yuque.com%2Fmo_ming%2Fgl7b70%2Fyixtbh

docker报错ERROR: client version 1.22 is too old. Minimum supported API version is 1.24, please upgrade your client to a newer version

这个问题其实是你docker-compose.yaml中

vim /root/software/harbor/docker-compose.yaml

把原来version: '2'改成version: '2.1'就可以了

六、Docker中的网络

6.1 Linux 内核中的 NameSpace

namespace 系统调用参数 隔离内容 内核版本
UTS CLONE_NEWUTS 主机名和域名 2.6.19
IPC CLONE_NEWIPC 信号量、消息队列和共享内存 2.6.19
PID CLONE_NEWPID 进程编号 2.6.24
NetWork CLONE_NEWNET 网络设备、网络栈、端口等 2 .6.29
Mount CLONE_NEWNS 挂载点(文件系统) 2.4.19
User CLONE_NEWUSER 用户和用户组 3.8

6.2 Docker网络通讯示意图

容器与容器之间通过namespace进行隔离,隔离为两端,一端放在容器内部,充当eth0网卡,另一端放在宿主机上进行连通,不同容器之前通过docker0网桥进行通信

6.3 Docker中的防火墙规则

容器访问外部网络(防火墙nat转换)

bash 复制代码
#防火墙的nat转换
[root@localhost ~]$ iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -o docker0 -j MASQUERADE





-t nat	指定操作的 iptables 表为nat表(网络地址转换表),专门处理 IP / 端口的转换,Docker 网络的地址伪装、端口映射都依赖这个表
-A POSTROUTING	-A是 ** 追加(Append)** 规则到指定链,POSTROUTING是 nat 表的出站链,数据包离开本机网卡前会经过这个链,是做源地址转换(SNAT/MASQUERADE)的核心链
-s 172.17.0.0/16	匹配源 IP为 172.17.0.0/16 网段的数据包(这是 Docker 默认的桥接网络网段,所有默认桥接的容器都会分配这个网段的 IP)
-o docker0	匹配 ** 出站网卡(Output)** 为docker0的数据包(docker0是 Docker 创建的默认网桥,容器默认桥接到此网卡,与宿主机互通)
-j MASQUERADE	-j是跳转(Jump)到指定目标动作,MASQUERADE是动态源地址伪装,属于 SNAT(源地址转换)的特殊形式,会将数据包的源 IP 替换为出站网卡(docker0)的 IP,让外部网络认为数据包来自宿主机的 docker0 网卡,而非容器的私有 IP

外部网络访问容器(dnat转换)

bash 复制代码
[root@localhost ~]$ docker run -d -p 80:80 apache


这是创建并启动 Apache 容器的基础命令,核心是端口映射,各参数作用:
-d:后台运行容器(守护进程模式),不会占用当前终端;
-p 80:80:宿主机端口:容器端口的映射规则,将宿主机的 80 端口,转发到容器内的 80 端口(Apache 默认监听 80 端口);
apache:基于官方apache镜像创建容器,Docker 会自动拉取镜像(本地无的话)。

执行后 Docker 会做两件核心事:
为容器分配私有 IP(示例中是 172.17.0.2,属于 docker0 网桥的 172.17.0.0/16 网段);
自动在 iptables 的 nat 表中添加你后续手动执行的这两条转发规则(这是 Docker 端口映射的底层实现,无需手动写,这里手动执行是复现 Docker 的自动操作)。

iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL-j DOCKER

-t nat	操作 nat 表(网络地址转换表),端口映射属于目标地址转换(DNAT),必须用 nat 表;
-A PREROUTING	追加规则到 PREROUTING 链,数据包进入本机网卡后、路由决策前会经过此链,是 DNAT 的核心链(所有外部 / 本地对宿主机端口的请求,都会先走这里);
-m addrtype --dst-type LOCAL	加载addrtype匹配模块,匹配 ** 目标地址类型为本地(LOCAL)** 的数据包(包括宿主机的公网 IP、内网 IP、127.0.0.1 回环地址,简单说:所有访问宿主机自身 IP / 端口的请求,都符合这个条件);
-j DOCKER	将匹配的数据包跳转到Docker 自定义的 DOCKER 链(Docker 启动时会自动创建这个链,专门存放所有端口映射的转发规则,避免和系统原有规则混淆)。


iptables -t nat -A DOCKER !-i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80

-A DOCKER	追加规则到 Docker 自定义的DOCKER链(承接规则 1 的跳转,做具体转发);
! -i docker0	关键:!是 "非" 的意思,-i是匹配入站网卡(Input);整体表示「匹配不是从 docker0 网卡进入的数据包」(避免容器之间访问宿主机端口时重复转发,造成网络环路);
-p tcp -m tcp	先指定协议为 TCP,再加载 tcp 匹配模块(精细化匹配 TCP 协议的特征,如端口);
--dport 80	匹配目标端口为 80 的数据包(即访问宿主机 80 端口的请求);
-j DNAT	跳转执行目标地址转换(DNAT),修改数据包的目标 IP 和端口,是端口映射的核心动作;
--to-destination 172.17.0.2:80	DNAT 的目标地址:将数据包的目标 IP 改为容器私有 IP 172.17.0.2,目标端口改为 80(容器内 Apache 的监听端口)。

6.4 Docker网络的修改

Docker进程网络修改

  • b,--bridge=""指定Docker使用的网桥设备,默认情况下Docker会自动创建和使用docker0网桥设备,通过此参数可以使用已经存在的设备
  • --bip指定Docker0的IP和掩码,使用标准的CIDR形式,如10.10.10.10/24
  • dns配置容器的DNS,在启动Docker进程是添加,所有容器全部生效

Docker容器网络修改

  • -- dns用于指定启动的容器的DNS
  • --net用于指定容器的网络通讯方式,有以下四个值
    • bridge:Docker默认方式,网桥模式
    • none:容器没有网络栈
    • container:使用其它容器的网络栈,Docker容器会加入其它容器的network namespace
    • host:表示容器使用Host的网络,没有自己独立的网络栈。容器可以完全访问Host的网络,不安全

6.5 端口的暴露方式

- p/P选项的使用格式

bash 复制代码
-p : <ContainerPort>:将制定的容器端口映射至主机所有地址的一个动态端口
-p <HostPort>:<ContainerPort>:映射至指定的主机端口
-p <IP>::<ContainerPort>:映射至指定的主机的IP的动态端口
-p <IP>:<HostPort>:<ContainerPort>:映射至指定的主机IP的主机端口
-P(大):暴露所需要的所有端口



[root@localhost ~]$ docker port ContainerName #可以查看容器当前的映射关系

6.6 网络隔离

基础命令说明

bash 复制代码
#查看当前可用的网络类型
[root@localhost ~]$ docker network ls

#类型网络空间名称
[root@localhost ~]$ docker network create -d 类型 网络空间名称
#类型分为:
	overlay
	bridge

使用网络名字空间进行隔离代码记录

bash 复制代码
[root@localhost ~]$ docker network create -d bridge --subnet "172.26.0.0/16" --gateway "172.26.0.1" my-bridge-network

[root@localhost ~]$ docker run -d --network=my-bridge-network --name test1 hub.c.163.com/public/centos:6.7-tools

[root@localhost ~]$ docker run -d --name test2 hub.c.163.com/public/centos:6.7-tools

使容器配置上独立IP进行通讯

  1. 配置真实网桥
bash 复制代码
[root@localhost ~]$ cd /etc/sysconfig/network-scripts

cp -a ifcfg-ens33 ifcfg-br0

[root@localhost ~]$ vi ifcfg-eth0
DEVICE=eth0
HWADDR=00:0C:29:06:A2:35
TYPE=Ethernet
UUID=34b706cc-aa46-4be3-91fc-d1f48c301f23
ONBOOT=yes
BRIDGE=br0
NM_CONTROLLED=yes
BOOTPROTO=static



[root@localhost ~]$ vi ifcfg-br0
#改成这样
TYPE=Bridge
NAME=br0
DEVICE=br0
ONBOOT=yes
BOOTPROTO=static
IPADDR=10.10.10.17
GATEWAY=10.10.10.2
DNS1=8.8.8.8
DNS2=114.114.114.114
  1. 使用工具分配地址
bash 复制代码
[root@localhost ~]$ yum install -y git

[root@localhost ~]$ git clone https://github.com/jpetazzo/pipework

[root@localhost ~]$ cp pipework/pipework/usr/local/bin/

[root@localhost ~]$ docker run -itd --net=none --name=ff centos-6-x86 bash

[root@localhost ~]$ pipework br0 fl 192.168.216.135/24

七、数据存储

7.1 数据卷特性

  • Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层
  • 如果运行中的容器修改了现有的一个已经存在的文件,那么该文件将会从读写层下面的的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,次即"写时复制"机制

7.2 数据卷的意义

  • Volume可以在运行容器时即完成创建与绑定操作。当然,前提需要拥有对应的申明
  • Volume的初衷就是数据持久化

7.3 数据卷的类型

  • Bind mount volume
  • Docker-managed volume

7.4 容器中使用数据卷的方法

Docker-managed Volume(自动绑定)

bash 复制代码
[root@localhost ~]$ docker run -it --name roc -v MOUNTDIR roc/lamp:v1.0
[root@localhost ~]$ docker inspect -f {{.Mounts}} roc

Bind-mount Volume(手动绑定)

bash 复制代码
[root@localhost ~]$ docker run -it --name roc -v HOSTDIR:VOLUMEDIR roc/lamp:v1.0

Union Volume(联合卷-共享自动绑定)

bash 复制代码
[root@localhost ~]$ docker run -it --name roc --volumes-from ContainerName roc/lamp:v1.0

7.5 存储驱动

Docker存储驱动(storage driver)是Docker的核心组件,它是Docker实现分成镜像的基础

  • device mapper(DM):性能和稳定性存在问题,不推荐生产环境使用
  • btrfs:社区实现了btrfs driver,稳定性和性能存在问题
  • overlayfs:内核3.18overlayfs进入主线,性能和稳定性优异,第一选择
bash 复制代码
[root@localhost ~]$ mount -t overlay overlay -o lowerdir=./low,upperdir=./upper,workdir=./work ./merged





[root@localhost overlay] tree .
.
├── low            #最底层
│   └── 1.txt
├── merged         #用户展示层
│   ├── 1.txt
│   └── 2.txt
├── upper          #中间层
│   └── 2.txt
└── work           #工作层
    └── work

修改为overlayfs存储驱动

bash 复制代码
[root@localhost ~]$ echo "overlay" > /etc/modules-load.d/overlay.conf
[root@localhost ~]$ cat /proc/modules|grep overlay
[root@localhost ~]$ reboot
[root@localhost ~]$ vim /etc/systemd/system/docker.service
	storage-driver=overlay\

八、资源限制

8.1 内存资源限制

相关说明

  • CGroup是Control Groups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物力资源(如cpu memory i/o等等)的机制。2007年进入Linux2.6.24内核,CGroups不是全新创造的,它将进程管理从cpuset中剥离出来,作者是Google的Paul Menage
  • 默认情况下,如果不对容器做任何限制,容器能够占用当前系统能给容器提供的所有资源
  • Docker限制可以从Memory、CPU、BlockI/O三个方面
  • OOME:Out Of Memory Exception
    • 一旦发生OOME,任何进程都有可能被杀死,包括docker daemon在内
    • 为此,Docker调整了docker daemon的OOM优先级,以免被内核关闭

重点提示

  • 为应用做内存压力测试,理解正常业务需求下使用的内存情况,然后才能进入生产环境使用
  • 一定要限制容器的内存使用上限
  • 尽量保证主机的资源充足,一旦通过监控发现资源不足,就进行扩容或者对容器进行迁移
  • 如果可以(内存资源充足的情况),尽量不要使用swap,swap的使用会导致内存计算复杂,对调度器非常不友好

8.2 内存限制设置方式

在docker启动参数中,和内存限制有关的包括(参数的值一般是内存大小,也就是一个正数,后面跟着内存单位b、k、m、g,分别对应bytes、KB、MB、和GB):

bash 复制代码
-m --memory:容器能使用的最大内存大小,最小值为4m

--memory-swap:容器能够使用的swap大小

--memory-swappiness:默认情况下,主机可以把容器使用的匿名页(anonymouspage)swap出来,你可以设置一个0-100之间的值,代表允许swap出来的比例

--memory-reservation:设置一个内存使用的softlimit,设置值小于--m设置

--kernel-memory:容器能够使用的kernelmemory大小,最小值为4m。

--oom-kill-disable:是否运行OOM的时候杀死容器。只有设置了-m,才可以把这个选项设置为false,否则容器会耗尽主机内存,而且导致主机应用被杀死

8.3 参数示意图

8.4 CPU资源限制

Docker提供的CPU资源限制选项可以在多核系统上限制容器能利用哪些vCPU。而对容器最多能使用的CPU时间有两种限制方式:

  • 一是有多个CPU密集型的容器竞争CPU时,设置各个容器能使用的CPU时间相对比例
  • 二是以绝对的方式设置容器在每个调度周期内最多能使用的CPU时间

CPU限制方式

bash 复制代码
[root@localhost ~]$ docker run -it --cpu-period=50000 --cpu-quota=25000 ubuntu:16.04 /bin/bash
[root@localhost ~]$ docker run -it --cpu-period=10000 --cpu-quota=20000 ubuntu:16.04 /bin/bash

--cpuset-cpus=""     允许使用的CPU集,值可以为0-3,0,1

-c,--cpu-shares=0    CPU共享权值(相对权重),默认值1024

--cpuset-mems=""     允许在上执行的内存节点(MEMs)

--cpu-period=0       即可设置调度周期,CFS周期的有效范围是1ms~1s,对应的--cpu-period的数值范围是1000~1000000

--cpu-quota=0        设置在每个周期内容器能使用的CPU时间,容器的CPU配额必须不小于1ms,即--cpu-quota的值必须>=1000,单位微秒

--cpus                能够限制容器可以使用的主机CPU个数,并且还可以指定如1.5之类的小数

8.5 限制性实验

bash 复制代码
[root@localhost ~]$ docker run --name stress -it --rm -m 256m lorel/docker-stress-ng:latest stress-ng --vm 2

启动一个临时的、限制 256MB 内存的 stress-ng 容器,用 2 个进程执行内存压力测试,容器退出后自动删除

docker run	Docker 核心命令,创建并启动一个新容器
--name stress	给容器命名为stress,方便后续通过docker ps/kill stress操作容器
-it	组合参数:-i保持标准输入打开,-t分配伪终端,保证能看到压测实时输出
--rm	容器停止 / 退出后自动删除容器,避免产生无用的僵尸容器,适合临时压测
-m 256m	限制容器的可用内存上限为 256MB(m=MB),超出后容器会被 OOM 杀死 / 限制
lorel/docker-stress-ng:latest	压测使用的基础镜像,已预装stress-ng压力测试工具,无需自己安装
stress-ng	容器内执行的核心压测命令,是 Linux 主流的多维度压力测试工具(CPU / 内存 / 磁盘等)
--vm 2	stress-ng 的内存压测参数:启动2 个内存分配进程,持续申请 / 释放内存压测

[root@localhost ~]$docker run --name stress -it --rm --cpus 2 lorel/docker-stress-ng:latest stress-ng --cpu 8

创建一个临时容器,限制其最多使用宿主机 2 个 CPU 核心,同时启动 8 个 CPU 密集型压测进程,让这 8 个进程竞争 2 核 CPU 资源,打满容器的 CPU 配额

--cpus 2	核心限制:Docker 给容器分配2 个 CPU 核心的计算能力,容器内所有进程的 CPU 使用率总和最大为 200%(宿主机top中看容器进程会体现)
stress-ng --cpu 8	启动8 个 CPU 压测进程(每个进程做纯计算密集型操作,比如循环计算)
其余--name/-it/--rm	与之前一致:命名容器、分配终端看实时输出、容器退出后自动删除

[root@localhost ~]$ docker run --name stress -it --rm --cpuset-cpus 0 lorel/docker-stress-ng:latest stress-ng --cpu 8

容器被强制限定只能使用宿主机第 0 号 CPU 核心,无法使用其他任何核心,8 个 CPU 压测进程在这颗核心上竞争运行,将其 100% 打满

--cpuset-cpus 0	精准 CPU 核心绑定:容器内所有进程只能运行在宿主机第 0 号物理 CPU 核心,完全隔离其他核心;支持多核心绑定,如0,1(0 和 1 核)、0-2(0/1/2 核)
--cpu 8	启动 8 个 CPU 密集型压测进程(循环计算),竞争--cpuset-cpus 0绑定的单核资源
--name/-it/--rm	容器命名为 stress、分配终端看实时输出、退出后自动删除,与之前一致
stress/stress-ng	前者是软链兼容旧版,后者是镜像原生命令,推荐用后者

核心逻辑	容器只能跑在指定物理核心,独占 / 竞争该核心的 100% 资源,无法使用其他核心	容器可跨宿主机所有 CPU 核心运行,只是总计算能力被限制为 1 个核心(100%)
资源隔离性	极高:容器进程不会跑到其他核心,适合需要物理核心隔离的场景(如性能测试、独占资源)	较低:进程会被 Docker 调度到不同核心,只是总使用率被限流,适合普通的资源限制
宿主机 CPU 显示	宿主机top中只有第 0 号核心的使用率会拉满到 100%,其他核心不受影响	宿主机top中多个核心会分摊使用率(比如 2 个核心各 50%),总和接近 100%
适用场景	精准性能测试、核心独占、容器间 CPU 隔离、排查单核心性能问题	普通业务容器的 CPU 限流、不关心物理核心分布,只限制总计算能力



--cpuset-cpus是绑「物理核心」,--cpus是限「计算能力」,你的这条命令用--cpuset-cpus 0,会让宿主机仅第 0 核被打满,其他核心完全空闲,这是和之前--cpus 2最本质的区别。

# 新开一个终端执行,实时查看容器资源
docker stats stress
相关推荐
FJW0208142 小时前
《Nginx 高级应用:变量、Rewrite、反向代理与 OpenResty 扩展》(3)
运维·nginx·openresty
feng68_2 小时前
LVS(linuxvirtualserver)
运维·服务器·lvs
Cyber4K2 小时前
【Kubernetes专项】Ingress、Ingress-Controller
云原生·容器·kubernetes
云道轩3 小时前
在Rocky Linux 上在线安装OpenClaw 2026.2.13
linux·运维·人工智能·智能体·openclaw
IT 行者4 小时前
OpenClaw 浏览器自动化测试的那些坑(一):Linux Snap 版本的 Chromium 无法使用托管模式
linux·运维·服务器·人工智能
t***44235 小时前
CORS:跨域访问、如何在Nginx中配置允许跨域访问
运维·nginx
RisunJan6 小时前
Linux命令-lvdisplay(显示逻辑卷属性)
linux·运维·服务器
何中应6 小时前
使用Jenkins部署后端项目(Maven)
运维·ci/cd·jenkins
Trouvaille ~6 小时前
【Linux】网络层与IP协议详解:从地址到路由的完整指南
linux·运维·服务器·网络·tcp/ip·路由器·网络层