2023年7月6日发(作者:)
Docker原理及使⽤ 虚拟化系统: 1. Type-I: 此种虚拟化是Hypervisor直接运⾏在硬件之上,来创建虚拟机. 2. Type-II: 这种虚拟化类似与VMware Workstations。 IPC: 在相同的名称空间中的进程才能通过IPC实现进程间通信。 PID: 在每个名称空间中必须有⼀个进程ID为1的进程,它是所有进程的⽗进程,即init进程,所以要实现⽤户空间隔离,就需要让每个⽤户空间中进程,以为⾃⼰是运⾏在init进程下的. user: 要让每个⽤户空间中的进程以为⾃⼰是运⾏在独⽴的主机中,那就必须实现每个⽤户空间中都⼀个UID为0的⽤户, 但该⽤户在真实系统中,却是⼀个普通⽤户。容器虚拟化: 资源限制:
通常有两种,⼀种是弹性百分⽐限制能使⽤全部资源的百分⽐.另⼀种是决对资源限制. 实现资源限制的是Cgroups(Control Groups): 1. blkio: 块设备IO 2. cpu: CPU 3. cpuacct: CPU资源使⽤报告 4. cpuset: 多处理器平台上的CPU集合 5. devices: 设备访问 6. freezer: 挂起 或 恢复任务 7. memory: 内存⽤量及报告 8. perf_event: 对cgroup中的任务进⾏统⼀性能测试 9. net_cls: cgroup中的任务创建的数据报⽂的类别标识符.Docker、LXC、CNCF: Docker是⼀家商业公司开发的容器技术,早期是容器内核是基于LXC(LinuX Container),来实现容器的创建和管理的。 LXC: 早期有⼀种技术叫 jail(监狱,或叫沙盒),这种技术可让⼀个应⽤程序运⾏在⼀个沙箱中,该应⽤程序⽆论做出任何对系统的破坏都不会影响到真实的系统,仅仅只是沙箱中的虚拟环境。后来这种技术在Linux也引⼊了,叫vserver,即现在我们⽐较熟悉的chroot功能。但是在Linux系统中早期内核⽀持名称空间,是需要通过⾃⼰编写代码,调⽤系统调⽤来创建出UTS,Network,IPC,等不同的名称空间,结合chroot实现在⼀个操作系统上创建出⼀个⽤户空间,但这对普通⽤户来说,是很困难的,⽽LXC则提供了⼀组⼯具,将这些功能整合成⼯具,⽤户若需要创建容器,只需要使⽤lxc-create等命令⾏⼯具,就可以很轻松的创建容器,但是LXC在创建容器时,它需要借助于template(模板),当允许lxc-create来创建⼀个容器时,你可以在CentOS的系统上,创建⼀个Ubuntu的容器,或FreeBSD的容器等,都可以只有你提供相应的template和这些系统的软件包安装源即可; 但LXC这种⽅式带来的问题是使⽤上依然⾮常困难,应⽤模板的创建并不容易,⽽且⼜产⽣了很多冗余数据;如:我想创建两个Ubuntu的容器,我就需要安装两份相同的数据; ⽽且若我需要将⼀个容器迁移到另⼀台主机上,怎么做?LXC没有提供相应的⼯具。所以它并不适合⼤规模使⽤。Docker:它早期创建容器的内核是LXC,但它使⽤了⽐LXC更⾼效,更精巧的⽅式来创建容器,它不在使⽤模板来安装容器,⽽是将容器制作成镜像,当需要使⽤容器时,直接从镜像仓库中下载之前制作好的镜像到本地,直接启动容器即可。并且它的镜像采⽤⼀种叫做叠加镜像的⽅式解决数据冗余的问题,实际上它采⽤⼀种叫三层叠加镜像的⽅式来实现数据的⾼效利⽤ 和 容器私有数据的保存。借助于共享存储来将容器的私有数据保存在宿主机的外部,当宿主机宕机时,只要在新的宿主机上下载镜像,启动容器,挂载数据即可恢复服务。具体如下图: 注: Docker为了管理容器⽅便,它定义⼀个容器中只能运⾏⼀个进程, 但实际上容器跟虚拟机类似,它是可运⾏多个进程的,只是为了管理⽅便,限制容器中只能运⾏⼀个进程。
容器这种技术带来好处: 对于开发⼈员来说,是天⼤的好处,因为Docker的出现真正解决代码⼀次编写到处运⾏,⽆论底层是什么系统,只要能运⾏docker,将镜像做好后,直接编排好,然后在宿主机上启动容器即可。对于运维⼈员来说,带来的问题是,系统构架更加复杂,原本的调试进程的⽅式,在容器时代变的异常困难,因为容器中很可能没有各种调试⼯具等。容器部署上的问题: 如NMP环境的构建上, 通常我们需要先部署MySQL容器,接着是PHP容器,最后是Nginx容器,这样的顺序部署才能让环境都正常⼯作,否则可能出现Nginx代理PHP服务器,结果找不到PHP服务器,因为容器启动后,它的IP地址会改变,那通过DHCP根据MAC不是可以固定分配IP吗?但其实是不可以的,因为容器是没有固定MAC的,它的⽹卡是虚拟的,是通过Linux上的"虚拟⽹线”创建的两个虚拟⽹卡,⼀端接⼊容器,⼀端接⼊Docker0(默认桥)桥上,这样就实现了容器能接⼊⽹络中,因此每次启动容器时,是⽆法知道这⼀次创建的虚拟⽹卡的MAC地址是多少的,因此必须使⽤其它⽅法来获取启动完成后的容器的IP地址,这也就是为啥容器需要编排,对于LNMP环境,Nginx要依赖PHP,因为它要代理PHP,⽽PHP⼜依赖MySQL,因为PHP应⽤程序要从MySQL中获取数据,因此必须先启动MySQL容器,这样才能获取MySQL容器当前使⽤的IP,接着启动PHP容器,将MySQL容器的IP传⼊到PHP容器中,这样PHP容器就可以知道MySQL的IP,⽽Nginx也是⼀样,这样编排后,LNMP环境中每个容器就都能获取它所依赖的容器的IP,就可以正常通信了。为了解决部署容器的顺序问题,容器技术,必须结合编排⼯具⼀起使⽤,才能实现⼤规模应⽤。⽬前⽐较知名的编排⼯具: Docker: machine+swarm+compose,这三个⼯具配合使⽤来实现编排。 第三⽅提供的编排⼯具: mesos+marathon Google: kubernetes-->简称k8slibcontainer:
⼜称为RunC,它是Docker官⽅提供的新Docker构建容器的核⼼程序,由于LXC在功能上,没有与时俱进,因此Docker官⽅,最终决定⾃⼰开发⼀个新的容器构建核⼼,它就是runC。Docker,Moby,CNCF的历史故事: Docker我们知道它是⼀家商业公司,早期Docker刚出现时,以下轰动世界,为了让Docker技术,能够有更⼤的发展,Docker将⾃⼰的产品分成商业版和社区开源版,但是Docker的商业版在商业领域上始终没能活动 ⼤佬们的信赖,没能得到太多融资,但是社区开源版确始终⽕热的不⾏,Docker为了能获得更多商业利益,它最终决定将社区版的Docker更名为Moby,希望能吸引更多关注的⽬光到它的商业版上,但事与愿违。 ⽽此时Google发现⾃⼰秘密使⽤了⼗⼏年的容器技术竟然被Docker给开源了,⽽且还发展的如此红⽕,尽⼈皆知,但Google不希望⾃⼰在容器技术上的话语权落到Docker⼿中,它决定扶持⼀家⼩容器公司,但这家公司的产品在Google⼤⼒扶植下,依然是名落孙⼭,不是Docker的对⼿,最后,Google发现Docker在编排⼯具的开发上,好⽆建树,⽽⾃⼰拥有⼗⼏年的容器使⽤经验(Google内部的容器叫Borg(博格)),因此就组织了⼯程师开发了Kubernetes,⼜鉴于Docker⼀家公司为了商业⽬的,随意更改Docker社区版,改变Docker的性质,因此Google将Kubernetes捐给了CNCF,⽽CNCF是容器标准化基⾦会组织,它是Google联合多家知名公司,如:IBM,微软,Facebook等联合成⽴的组织。向世⼈表态为不会左右Kubernetes的发展进程,加上Kubernetes从其诞⽣就是站在Bong的肩膀上成⽴的,所以它⼀经发布就成为世⼈聚焦的⽬标,短短3年,就已经从0.1发展到1.1版本,以每年4个版本迭代,2018年为⽌,其市场占有率达到80%以上.OCI(Open Container Initiative): 它由Linux基⾦会主导于2015年6⽉创⽴,皆在围绕容器格式和运⾏时制定了⼀个开放的⼯业标准. 它制定了两个规范标准: 1. 运⾏时标准(The Runtime Specifications (runtime-spec)) 2. 镜像格式标准(The Image Specification (image-spec))OCF(Open Container Format): OCF开放容器格式就是OCI的倡导下产⽣的标准。Docker的基本架构: 注: Docker的镜像: Registry:在Docker中称为镜像仓库,Docker的镜像仓库有点类似与yum源仓库,但它的组织⽅式是这样的: 官⽅提供的Docker镜像仓库地址: ,当然国内也有很多docker镜像站. Docker镜像仓库的组织格式为: 应⽤程序名:版本号 其中: 应⽤程序名为仓库名. 版本号: 为仓库中镜像名.也是它的tag标签号. 以Nginx为例: Nginx:为仓库名. nginx:1.15 这就是⼀个镜像名.同时⼀个镜像可能有多个名字, ⽐如: 1.15是Nginx的最新发⾏版,则还会给它提供⼀个名字叫: nginx:lasted 即最新版, 这个名字会随着Nginx发布的最新版⽽改变。 nginx:1.14 另外我们知道,Nginx的发⾏版中,次号码为偶数表⽰,此版本为稳定版, 为奇数则为开发版,所以这种版本通常也会有⼀个名字: nginx:stated 即稳定版的nginx镜像. docker的下载站有很多: 若使⽤清华⼤学的repo仓库,下载其repo⽂件后,还需要修改其repo镜像的站点为清华⼤学的镜像站. yum install docker-ce 安装完docker后,要下载其docker镜像,可使⽤国内的镜像加速器来下载:使⽤⽅式: mkdir /etc/docker vim /etc/docker/ { "registry-mirrors": [""] } 查看docker版本信息: docker version docker info docker的常⽤操作: docker search :搜索docker镜像仓库中指定的镜像名. docker pull : 下载指定镜像到本地. docker images : 列出本地已有的镜像 下载docker镜像: docker image pull nginx:1.14-alpine
注: alpine:这是⼀个⼩发⾏版的nginx,⼤⼩很⼩. 它仅集成了nginx运⾏所必须的环境,其它什么都没有,若你需要⼀些调试⼯具,它就不太适合了。 另外,⼀般官⽅发⾏的镜像,⼀般都很少会带调试⼯具。 另注: 我们搜索docker镜像时,会看到类似 tom/nginx 这类的镜像,它们是表⽰ tom这个⼈,在docker官⽅注册了账号,上传了⾃⼰制作的nginx镜像. docker pull busybox docker imgle ls --help #查看ls⼦命令的帮助. docker imgle --help
创建容器: docker container create #仅创建容器,但不运⾏. docker container run #创建容器,并运⾏。 docker container start #启动⼀个或多个已经创建好的容器。 docker container stop |kill #都可以停在⼀个或多个容器. docker container top #查看那些容器最消耗资源. docker container run [options] Image [Command] [参数...] options: -t :启动镜像时,给其添加⼀个终端访问接⼝,以便能够启动后,连接登录. -i :启动为交互模式. --rm :停⽌后,直接删除该容器. -d : 运⾏到后台. --name
终端1: docker start -a -i b1 #重新启动停⽌的容器b1 终端2: docker ps
docker kill b1 #可强制关闭b1容器. 正常情况下应该使⽤stop,可保障数据不丢失. docker rm b1 #删除停⽌的容器b1 ⽰例3: docker run --name nginx1 -d nginx:1.14-alpine #若本机能访问互联⽹,这⾥可直接运⾏,docker会⾃动下载镜像. 注: 在容器中运⾏应⽤程序,它必须⼯作在前台,否则容器已启动就会关闭,因为在容器中只有⼀个进程,该进程是⽀撑容器的⾻架 docker ps docker run --name redis1 -d redis:4-alpine #启动⼀个redis容器,它将⾃动下载该镜像.并启动. ⽰例4: docker exec -it redis1 /bin/sh #在指定容器redis1上运⾏⼀个命令,/bin/sh,并使⽤交互式登录. /data # ps #这样就可以登录到redis1这个容器上了. docker logs nginx1 #查看容器nginx1的⽇志信息.docker 所有状态转化⽰意 Docker的镜像: Docker镜像包含了启动容器所需的⽂件系统及其内容,因此它⽤于创建并启动docker容器. docker镜像采⽤分层构建的机制,最底层为bootfs,其上为rootfs. bootfs: ⽤于系统引导⽂件系统,包括bootloader和kernel,容器启动完成后,bootfs会被卸载,以节省内存空间. rootfs: 它在运⾏中的docker容器中变现为根⽂件系统. 如: docker exec -it nginx1 /bin/sh #登录后, ls / 可以看到全部的根⽂件系统⽬录.
传统OS:
系统启动时,内核挂载rootfs时,为确保不会误删除⽂件,通常会先以只读模式挂载,完整性⾃检完成后,再重新以读写模式挂载rootfs. docker: 它在启动内核,挂载rootfs时,始终是以只读模式挂载, ⽽后在通过联合挂载技术额外挂载⼀个可写层.实现读写操作。Docker Image Layer 此镜像显⽰了Docker的镜像层级,从上到下分别为: 可写层 add Apache 和 add emacs(类似于vim的编辑器): 这两层为⾃⼰通过yum安装在镜像中的⼯具. Debian: 这是为安装的⼯具提供的基本的最⼩安装的根⽂件系统已共Apache能运⾏起来.这⾥使⽤的是Debian.还可以使⽤CentOS等. bootfs: 这⼀层则是启动Debian这个rootfs所需的bootloader和kernel,通常在将Debian启动起来后,它将⾃动被卸载.Docker实现叠加挂载镜像的⽂件系统: overlayfs: 从kernel3.18以后被整合到Linux内核中了. 它叫 叠加⽂件系统, 再早期Docker实现叠加挂载是使⽤Aufs(Advanced multi-layered unification filesystem:⾼级多层统⼀⽂件系统), ⽽此⽂件系统是2006年开发,但因代码质量问题,⼀直未被整合到kernel中; 据说它的代码有3万⾏,⽽ext4这种⽂件系统总代码量4千多⾏。所以早期要使⽤docker有两种⽅式 ⼀种⼿动给内核打aufs的补丁,另⼀种就是使⽤Ubuntu系统,因为它⽐较早的将Aufs整合到它的kernel中了。不过现在⽬前 CentOS系统已经能⽀持overlayfs的第2版了,所以可以直接使⽤docker即可. docker info
#输出中Storage Driver: overlay2 ,overlay2是⼀种虚拟抽象层的⽂件系统,它是建构在Backing Filesystem: xfs ,即后端⽂件系统xfs之上的⽂件系统。 docker pull /coreos/flannel:v0.10.0-amd64
#下载 这个⽹站的coreos名称空间下的flannel仓库中的tag为v0.10.0-amd64 的镜像。默认docker使⽤https去下载. 是docker镜像很有名的第三⽅提供者. ⽰例1: #基于busybox创建⼀个测试镜像: docker run --name bx1 -it busybox / #mkdir -p /data/html / #vi /data/html/
Hello busybox HTTP Server
终端2: docker commit -p bx1 #-p是让bx1容器先暂停,避免有⼈访问镜像,导致镜像创建不完成. docker image ls #可看到刚创建的镜像. docker tag#登录到另⼀台docker上就可以执⾏: docker load -i #就可以导⼊镜像了 docker image ls ⽰例6: docker exec -it --name bx1 / #wget -O - -q 1.1.1.2/ # 假如Nginx容器启动后的地址为1.1.1.2,则通过wget测试访问. -O :加载完成页⾯后,不保存,直接输出当标准输出."-"Docker的四种⽹络模型: 第⼀种是Closed Container(封闭式容器): 它主要是⽤来处理⼀些Docker计算任务的,完成后就⾃动退出了,因此它⽆需⽹络协议栈. 第⼆种是Bridge Container(桥接式容器): 它是通过创建⼀根虚拟⽹线,⼀头接⼊容器中,也就是Container Virtual interface,另⼀头接在Docker bridge Virtual Interface上. 第三种是Joined Container(联合容器): 它是让A和B两个容器都共享⼀组Net,UTS,IPC名称空间,这样的好处是A和B可以直接通过lo接⼝通信,并且还可以桥接到Docker桥上,共享⽹络接⼝。 第四种是Open Container(开放容器): 它是第三种的扩展,它直接与物理机共享了Net,UTS,IPC名称空间,因此物理机上的⽹络接⼝它都可以看到,并且可以直接管理。 ⽰例1: #inspect 查看docker组件的详细信息. docker network ls docker network inspect bridge #查看bridge⽹络的详细信息。 ⽰例2: #创建⽹络模型3 终端1: docker run --name bx1 -it --rm busybox / # wget -O - -q 127.0.0.0.1/ 终端2: docker run --name bx2 -it --network container:bx1 --rm busybox / #echo "hello world." > /tmp/ / #httpd -f -h /tmp ⽰例2: vim /etc/docker/ #以下仅供参考,新版本有些参数以不⽀持!! { "bip": "1.1.1.1/24", #设置docker0的IP “fixed-cidr”:"10.20.0.0/16", "fixed-cidr-v6":"2001:db8::/64", "mtu":"1500", "default-gateway":"10.20.1.1", "default-gateway-v6":"2001:db8:dbcd::89", "dns":["10.20.1.2","8.8.8.8"], "hosts":["tcp://0.0.0.0:2375","unix:///var/run/"] #启动docker监听在2375端⼝上. } systemctl restart docker #新版本建议直接修改启动脚本,已参数形式传⼊ 在主机2: docker -H 1.1.1.1:2375 image ls #这样就可以查看1.1.1.1这台主机上docker的是否有镜像了。 ⽰例3: #创建docker⽹络 docker network create -d bridge --subnet "1.1.1.0/16" --gateway "1.1.1.1" mybr0 docker run -it --name bx1 --net mybr0 busybox:v0.1 ⽰例4: #启动容器时传递参数: docker run --name t1 -it --network bridge -h --rm busybox:latest docker run --name t1 -it --network bridge -h --dns 114.114.114.114 --rm busybox:latest docker run --name t1 -it --network bridge -h --dns 114.114.114.114 --add-host :1.1.1.1 --rm busybox:latest ⽰例5: docker run --name myweb --rm -p 80 tom/bbox:v0.2 #创建⼀个地址映射,允许外部访问此容器. #注: -p 80 ,实际是创建了⼀条 iptables DNAT规则. docker port myweb #查看docker创建的端⼝映射 docker run --name myweb --rm -p 1.1.1.1::80 tom/bbox:v0.2 docker run --name myweb --rm -p 80:80 tom/bbox:v0.2 docker run --name myweb --rm -p 1.1.1.1:80:80 tom/bbox:v0.2Docker的数据卷(Data Volume): 为避免关闭再重启容器,其数据不受影响,但删除Docker容器,则其更改将会全部丢失. 存在的问题:
1. 存储于联合⽂件系统中的数据,宿主机不易访问. 2. 容器间数据共享不⽅便. 3. 删除容器其数据会丢失. 解决⽅案:"卷(Volume)": 卷是容器上的⼀个或多个⽬录(即:多个卷),此类⽬录可绕过联合⽂件系统,与宿主机上的某⽬录绑定(即关联)Docker有两种类型的卷: 1. Bind mount volume(绑定挂载卷):这是有⽤户⾃定义指定docker中的某⽬录挂载到宿主机的某个指定⽬录. 2. Docker-managed volume(docker管理的卷): 这是由docker⾃⼰维护,⽤户需要在/etc/docker/中指定启⽤docker⾃动启动容器时,关联宿主机上由docker默认⾃动创建⼀个⽬录,并与容器中指定⽬录关联的⽅式。 ⽰例: #由docker管理的卷: docker run --rm --name b2 -it -v /data busybox:latest 终端2: docker inspect b2 #可查看其“Mounts”段,其中有说明容器中/data ⽬录与宿主机上的那个⽬录建⽴的关联. 接着可测试在宿主机上⽬录中创建⽂件,在容器中编辑,是否可⾏。
⽰例2: docker run --name b2 --rm -it -v /data/volumes/b2:/data busybox:latest 终端2: echo “Hello Container busybox.” >> /data/volumes/b2/ #接着在容器中查看. # 再尝试删除容器,再关联相同⽬录,查看数据是否依然可访问。 docker inspect -f {{.Mounts}} b2 #简单过滤. #注: JSON中使⽤"[]": 表⽰这是⼀个列表, {}: 表⽰这是⼀个关联数组(也叫Hash映射),它可嵌套. 在关联数组中的格式: {
"Key":"Value", #每个键 值对要使⽤ 逗号分隔. "Key":"Value", "key0": { "key1":"Value1", #key1的上层是“key0”, ⽽key0上层是 根(通常⽤"."表⽰.) .. }, .. } docker inspect -f {{.Mounts}} b2
#最外层{} 为引⽤格式, 内层{.Mounts} 为引⽤数组中.Mounts . :表⽰根,.Mounts:表⽰根下的Mounts. docker inspect -f {{.ess}} b2 #这是简单的Go模板,go模板还⽀持循环,判断等. ⽰例3: #创建⼀个基础容器,让其它容器共享它的UTS,IPC,Network名称空间 已经它的卷映射. 终端1: docker run --name infraCon -it -v /data/volumes/b2:/data/web/html busybox / #ifconfig 终端2: docker run --name nginx --network container:infraCon --volumes-from infraCon -it busybox / #ifconfig 终端3: docker inspect infraCon docker inspect nginx #查看“Mounts” 和 Networks是否与上⾯的⼀样。Dockerfile: 格式: # : #号开头为注释. FROM : 第⼀个指令必须是FROM,它⽤来指明,依据那个基础镜像做镜像。 ⼀般指令建议使⽤⼤写以区分参数, 但指令不区分⼤⼩写. 格式: FROM <仓库名>[:
5. dockerfile中的指令: 1. copy
#指定要对外暴露TCP的80端⼝,但这⾥指定暴露,实际并不会直接暴露,⽽是需要在启动容器时,使⽤ “-P” 才会真正暴露此端⼝给外部⽤户. # docker port 容器名 #在不加"-P"时,可使⽤它来验证是否暴露了80端⼝. #ENV
#RUN的第⼆种语法格式.它使⽤JSON数组,Executable为要运⾏的命令,后⾯为命令的参数,可有多个.此格式启动的命令不会以/bin/sh -c 的⽅式启动,因此它不能使⽤sh的命令语法,如:变量替换,通配符等. 若想使⽤shell特性的话,可⽤以下⽅式: RUN ["/bin/sh","-c","
4. 给⾃⼰做的镜像打上⾃⼰的仓库地址的标签. docker tag myweb:v0.3.11 :5000/myweb:v0.3.11 5. 将⾃⼰打好标签的镜像push上去. docker push :5000/myweb:v0.3.11 #这⾥会报错,说我们使⽤了不安全的http. 6. 若我们是内⽹使⽤, 不想使⽤HTTPS,可修改配置⽂件为: vim /etc/docker/ { ... "insecure-registries": [":5000"] } systemctl restart docker 7. 再次push 8. 可到其它节点上测试下载. docker pull :5000/myweb:v0.3.11Docker的资源限制: Linux Capabilities: Linux Kernel相关的知识 Memory: OOM: 对于⽐较重要的容器,在启动时就要调整其OOM_adj, 其值调整越⼩, OOM_score的评分就越低,当内核发现内存不⾜,发⽣OOM时,就优先将OOM_score得分⾼的优先kill掉. 默认: docker daemon会⾃动将⾃⼰的OOM_adj调整很低,避免内核发⽣OOM时,被内核kill掉.可调整容器使⽤内存的限制: -m | --memory= #限制容器能使⽤的物理内存⼤⼩.单位:k, m, g; 若设置⼀个容器可⽤内存为4m,若容器使⽤超过,将被kill掉. --memory-swap= #要使⽤它,必须先使⽤ -m 选项,否则它不⽣效.
若设置: -m 7G --memory-swap=10G, 则表⽰Swap+Ram=10G, Swap=10-7=3G,即可使⽤3G的Swap内存. 若设置: -m 7G --memory-swap=7G, 则表⽰不使⽤Swap内存.即 若设置这两个参数值相同,表⽰禁⽤SWAP. 若设置: -m 7G --memory-swap=0, 则表⽰SWAP未设置, 则若DockerHost启⽤了SWAP,则表⽰容器可⽤的SWAP⼤⼩=2*RAM的⼤⼩. 若设置: -m 7G --memory-swap=-1, 则表⽰DockerHost上启⽤了Swap,则容器可使⽤的全部的SWAP⼤⼩. 注: free : 在容器中使⽤free看到的swap空间使⽤情况并⾮上⾯这些参数计算出来的实际情况, 也就是说free查看容器使⽤的内存空间是⾮常不准确的。 --memory-swappiness: 设置容器使⽤SWAP内存的倾向性. 值的范围: 0~100, 0:能不⽤就不⽤, 100:只要能需要就使⽤. --memory-reservation: 设置要预留多少内存空间。 --oom-kill-disable 设置当发⽣OOM时,是否禁⽌此容器被kill掉,它要可-m⼀起使⽤.
CPU: 默认所有容器使⽤CPU资源都没有限制。 --cpu-shares #CPU是可压缩性资源,若当前有A,B,C三个容器, 假如分配给他们CPU占⽤的⽐例为:1024:512:2048. 则表⽰,将CPU资源分2+1+4,即分成7份, 三个容器都需要CPU,则A使⽤2份CPU时间, B使⽤1份 CPU时间, C使⽤4份CPU时间, 若B和C当前都空闲,则A可使⽤全部CPU资源; 若此时A和B都需要 ⽤CPU资源,则按照A使⽤2份CPU资源, B使⽤1份CPU时间, 若⼜新加了D,则再重新分割CPU时间⽚. --cpus= #限制单个容器最多可使⽤⼏核CPU, 即: 假如有4个核⼼, 还是A,B,C, 若此时B和C都不使⽤CPU 在不限制的情况下,A可使⽤4个核⼼,即最⼤可使⽤400%的计算能⼒.若设置了单个容器的 最多可使⽤CPU核⼼数,则基本当前所有容器都不⽤CPU,你也只能使⽤限制个数的核⼼数. --cpus=1.5 #表⽰最多可⽤150%,注意容器最多可使⽤150%的CPU计算能⼒,指的是 只有能限制它最多使⽤这么多计算能⼒即可,⾄于容器在那个CPU核⼼上 运⾏⽆所谓,随机分配,分到那个核⼼上就在那个核⼼上运⾏。但总量是不会超过150%的。 --cpuset-cpus= #这是限制容器能够运⾏在那个CPU核⼼上的, 假如:有4核⼼, 则⽤0~3来表⽰4个核⼼的编号. --cpuset-cpus=0,1 # 则表⽰容器只能运⾏在核⼼0和1上,其它上⾯不⾏。 --cpu-period= #限制最多可⽤CPU的时间. --cpu-quota=以上这些选项在docker run 时可以设置。docker压测⼯具: docker pull lorel/docker-stress-ng docker run --name stress -it --rm -m 256m lorel/docker-stress-ng:latest stress --help #可查看帮助. docker run --name stress -it --rm -m 256m lorel/docker-stress-ng:latest stress --vm 2 #限制其最多使⽤256M内存. docker run --name stress -it --rm --cpus 2 lorel/docker-stress-ng:latest stress --cpu 8 #限制最多使⽤2个CPU核⼼的计算资源. 终端1: docker run --name stress -it --rm --cpu-shares 1024 lorel/docker-stress-ng:latest stress --cpu 8 终端3: docker run --name stress -it --rm --cpu-shares 512 lorel/docker-stress-ng:latest stress --cpu 8 终端2: docker top stress #查看容器进程数 docker stats #查看docker资源的消耗情况。
发布者:admin,转转请注明出处:http://www.yc00.com/news/1688594315a153206.html
评论列表(0条)