一、Docker简介
所需软件
链接:https://pan.baidu.com/s/1DrVFq6ObBqz-AN-sggUlFw
提取码:79rr
复制这段内容后打开百度网盘手机App,操作更方便哦
1.1 Docker诞生
Docker是dotcloud公司开源的一款产品dotcloud是2010年新成立的一家公司,主要基于PAAS(PlatfromasaService)平台为开发者提供服务。2013年10月dotcloud公司改名为Docker股份有限公司
1.2 Docker相关解释
- LinuxContainer是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源
- Docker是PAAS提供商dotCloud开源的一个基于LXC的高级容器引擎,源代码托管在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
[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
YUM Install
[root@localhost ~]$ yum update
[root@localhost ~]$ cat > /etc/yum.repos.d/docker.repo << EOF
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF
[root@localhost ~]$ yum install docker
RPM Install
https://download.docker.com/linux/centos/7/x86_64/stable/Packages/
软件包https://wws.lanzous.com/b0201bgkb
密码:b1hf
#环境设置
[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://dev.aliyun.com/search.html
[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
2.3 Docker化应用体验
环境分析
WordPress运行环境需要如下软件的支持:
- PHP5.6或更新软件
- MySQL5.6或更新版本
- Apache和mod_rewrite模块
#下载镜像
[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指令的基本用法:
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 | 容器的删除 |
docker start/stop | 容器启动停止 |
Docker指令除了单条使用外,还支持赋值、解析变量、嵌套使用
3.3 单一容器管理命令
每个容器被创建后,都会分配一个CONTAINERID作为容器的唯一标示,后续对容器的启动、停止、修改、删除等所有操作,都是通过CONTAINERID来完成,偏向于数据库概念中的主键
命令 | 含义 |
---|---|
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
[root@localhost ~]$ curl -Lhttps://github.com/docker/compose/releases/download/1.14.0/docker-compose - `uname-s`-`uname -m` >/usr/local/bin/docker-compose
[root@localhost ~]$ docker version
Docker-compose用法
参数 | 含义 |
---|---|
-f | 指定使用的yaml文件位置 |
ps | 显示所有容器信息 |
restart | 重新启动容器 |
logs | 查看日志信息 |
config -q | 验证yaml配置文件是否正确 |
stop | 停止容器 |
start | 启动容器 |
up -d | 启动容器项目 |
pause | 暂停容器 |
unpause | 恢复暂停 |
rm | 删除容器 |
示例
[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:
- 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技术挂载一个“可写”层
4.2 容器转换为镜像
[root@localhost ~]$ docker commit CID xx.xx.xx
#指定仓库拉取镜像
[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
转换命令
[root@localhost ~]$ docker build -t wangyang/jdk-tomcat .
Dockerfile语法
1、FROM(指定基础image):
构建指令,必须指定且需要在Dockerfile其他指令的前面。后续的指令都依赖于该指令指定的image。
FROM指令指定的基础image可以是官方远程仓库中的,也可以位于本地仓库
FROM centos:7.2 #有且只有一个
FROM centos
2、MAINTAINER(用来指定镜像创建者信息):
构建指令,用于将image的制作者相关的信息写入到image中。当我们对该image执行docker inspect命令时,输出中有相应的字段记录该信息。
MAINTAINER wangyang"wangyang@itxdl.cn"
3、RUN(安装软件用):
构建指令,RUN可以运行任何被基础image支持的命令。如基础image选择了Centos,那么软件管理部分只能使用Centos的包管理命令,需要执行shell命令,前面加run
#常用
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启动时指定的操作。该操作可以是执行自定义脚本,也可以是执行系统命令。该指令只能在文件中存在一次,如果有多个,则只执行最后一条
CMD echo "Hello World!"
5、ENTRYPOINT(设置container启动时执行的操作):
设置指令,指定容器启动时执行的命令,可以多次设置,但是只有最后一个有效。
ENTRYPOINT ls -l
该指令的使用分为两种情况,一种是独自使用,另一种和CMD指令配合使用。当独自使用时,如果你还使用了CMD命令且CMD是一个完整的可执行的命令,那么CMD指令和ENTRYPOINT会互相覆盖只有最后一个CMD或者ENTRYPOINT有效
#CMD指令将不会被执行,只有ENTRYPOINT指令被执行
CMD echo "Hello World!"
ENTRYPOINT ls -l
另一种用法和CMD指令配合使用来指定ENTRYPOINT的默认参数,这时CMD指令不是一个完整的可执行命令,仅仅是参数部分;ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数
FROM ubuntu
CMD ["-l"]
ENTRYPOINT ["/usr/bin/ls"]
6、USER(设置container容器的用户):
设置指令,设置启动容器的用户,默认是root用户
USER daemon = ENTRYPOINT ["memcached","-u","daemon"]
7、EXPOSE(指定容器需要映射到宿主机器的端口):
设置指令,该指令会将容器中的端口映射成宿主机器中的某个端口。当你需要访问容器的时候,可以不是用容器的IP地址而是使用宿主机器的IP地址和映射后的端口。要完成整个操作需要两个步骤,首先在Dockerfile使用EXPOSE设置需要映射的容器端口,然后在运行容器的时候指定-p选项加上EXPOSE设置的端口,这样EXPOSE设置的端口号会被随机映射成宿主机器中的一个端口号。也可以指定需要映射到宿主机器的那个端口,这时要确保宿主机器上的端口号没有被使用。EXPOSE指令可以一次设置多个端口号,相应的运行容器的时候,可以配套的多次使用 -p 选项。
#映射一个端口
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启动后,可以通过dockerinspect查看这个环
境变量,也可以通过在docker run --env key=value时设置或修改环境变量。假如你安装了JAVA程序,需要设置JAVA HOME,那么可以在Dockerfile中这样写:
ENVJAVA_HOME /path/to/java/dirent
9、ADD(从src复制文件到container的dest路径)
add 解压
ADD <src> <dest>
<src>是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件url;
<dest>是container中的绝对路径
10、COPY(从src复制文件到container的dest路径)
copy不解压
COPY <src> <dest>
11、VOLUME(指定挂载点):
设置指令,使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。我们知道容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令
FROM base
VOLUME ["/tmp/data"]
12、WORKDIR(切换目录):设置指令,可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效
WORKDIR /p1 WORKDIR p2 RUN vim a.txt
13、ONBUILD(在子镜像中执行):
ONBUILD指定的命令在构建镜像时并不执行,而是在它的子镜像中执行
ONBUILD ADD./app/src
ONBUILD RUN /usr/local/bin/python-build--dir /app/src
所需软件,前面百度网盘已提供
创建一个tomcat的dockfile
[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 镜像的导出以及导入
导出:docker save -o xx.xx.xxxx.xx.xx.tar
导入:docker load -i xx.xx.xx.tar
五、镜像仓库构建
5.1 官方仓库构建方式
仓库服务器配置:
[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"]
}
客户机设置:
[root@localhost ~]$ vim/etc/sysconfig/docker
--insecure-registry 10.10.10.11:5000 增加
curl -XGET http://10.10.10.11:5000/v2/_catalog 查看已有镜像
5.2 Harbor构建
六、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转换)
#防火墙的nat转换
[root@localhost ~]$ iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -o docker0 -j MASQUERADE
外部网络访问容器(dnat转换)
[root@localhost ~]$ docker run -d -p 80:80 apache
iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL-j DOCKER
iptables -t nat -A DOCKER !-i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80
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选项的使用格式
-p : <ContainerPort>:将制定的容器端口映射至主机所有地址的一个动态端口
-p <HostPort>:<ContainerPort>:映射至指定的主机端口
-p <IP>::<ContainerPort>:映射至指定的主机的IP的动态端口
-p <IP>:<HostPort>:<ContainerPort>:映射至指定的主机IP的主机端口
-P(大):暴露所需要的所有端口
[root@localhost ~]$ docker port ContainerName #可以查看容器当前的映射关系
6.6 网络隔离
基础命令说明
#查看当前可用的网络类型
[root@localhost ~]$ docker network ls
#类型网络空间名称
[root@localhost ~]$ docker network create -d 类型 网络空间名称
#类型分为:
overlay
bridge
使用网络名字空间进行隔离代码记录
[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进行通讯
- 配置真实网桥
[root@localhost ~]$ cd /etc/sysconfig/network-scripts
[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-eth0
#改成这样
DEVICE=br0
TYPE=Bridge
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.216.131
NETMASK=255.255.255.0
GATEWAY=192.168.216.2
DNS=8.8.8.8
- 使用工具分配地址
[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
[root@localhost ~]$ docker run -it --name roc -v MOUNTDIR roc/lamp:v1.0
[root@localhost ~]$ docker inspect -f {{.Mounts}} roc
Bind-mount Volume
[root@localhost ~]$ docker run -it --name roc -v HOSTDIR:VOLUMEDIR roc/lamp:v1.0
Union Volume
[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进入主线,性能和稳定性优异,第一选择
[root@localhost ~]$ mount -t overlay overlay-olowerdir=./low,upperdir=./upper,workdir=./work./merged
修改为overlayfs存储驱动
[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):
-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限制方式
[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 限制性实验
[root@localhost ~]$ docker run --name stress -it --rm -m 256m lorel/docker-stress-ng:latest stress-vm2
[root@localhost ~]$ docker run --name stress -it --rm --cpus 2 lorel/docker-stress-ng:latest stress --cpu 8
[root@localhost ~]$ docker run --name stress -it --rm --cpuset-cpus 0 lorel/docker-stress-ng:latest stress --cpu 8