在一家传媒公司做网站编辑_如何?,12306网站 谁做的,个人网站和企业网站区别,进入建设银行的网站就打不了字一、docker资源限制 在使用 docker 运行容器时#xff0c;一台主机上可能会运行几百个容器#xff0c;这些容器虽然互相隔离#xff0c;但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制#xff0c;那么容器之间会互相影响#xff0c;小的来说…一、docker资源限制 在使用 docker 运行容器时一台主机上可能会运行几百个容器这些容器虽然互相隔离但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制那么容器之间会互相影响小的来说会导致容器资源使用不公平大的来说可能会导致主机和集群资源耗尽服务完全不可用。 CPU 和内存的资源限制已经是比较成熟和易用能够满足大部分用户的需求。磁盘限制也是不错的虽然现在无法动态地限制容量但是限制磁盘读写速度也能应对很多场景。 至于网络docker 现在并没有给出网络限制的方案也不会在可见的未来做这件事情因为目前网络是通过插件来实现的和容器本身的功能相对独立不是很容易实现扩展性也很差。 资源限制一方面可以让我们为容器应用设置合理的 CPU、内存等资源方便管理另外一方面也能有效地预防恶意的攻击和异常对容器来说是非常重要的功能。 系统压力测试工具stress
stress是一个linux下的压力测试工具专门为那些想要测试自己的系统完全高负荷和监督这些设备运行的用户。
1. cpu资源限制
1.1 限制CPU Share
什么是cpu share: docker 允许用户为每个容器设置一个数字代表容器的 CPU share默认情况下每个容器的 share 是 1024。这个 share 是相对的本身并不能代表任何确定的意义。当主机上有多个容器运行时每个容器占用的 CPU 时间比例为它的 share 在总额中的比例。docker 会根据主机上运行的容器和进程动态调整每个容器使用 CPU 的时间比例。 例子 如果主机上有两个一直使用 CPU 的容器为了简化理解不考虑主机上其他进程其 CPU share 都是 1024那么两个容器 CPU 使用率都是 50%如果把其中一个容器的 share 设置为 512那么两者 CPU 的使用率分别为 67% 和 33%如果删除 share 为 1024 的容器剩下来容器的 CPU 使用率将会是 100%。 好处 能保证 CPU 尽可能处于运行状态充分利用 CPU 资源而且保证所有容器的相对公平 缺点 无法指定容器使用 CPU 的确定值。 设置 CPU share 的参数 -c --cpu-shares它的值是一个整数 我的机器是 4 核 CPU因此运行一个stress容器,使用 stress 启动 4 个进程来产生计算压力无CPU限制
[rootyixuan ~]# docker pull progrium/stress
[rootyixuan ~]# yum install -y htop
[rootyixuan ~]# docker run --rm -it progrium/stress --cpu 4
stress: info: [1] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 12000us
stress: dbug: [1] -- hogcpu worker 4 [6] forked
stress: dbug: [1] using backoff sleep of 9000us
stress: dbug: [1] -- hogcpu worker 3 [7] forked
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] -- hogcpu worker 2 [8] forked
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] -- hogcpu worker 1 [9] forked
在另外一个 terminal 使用 htop 查看资源的使用情况 上图中看到CPU 四个核资源都达到了 100%。
为了比较另外启动一个 share 为 512 的容器
# 1.先将没有做限制的命令运行起来
[rootyixuan ~]# docker run --rm -it progrium/stress --cpu 4#2.在开启一个终端运行做了CPU限制的命令
[rootyixuan ~]# docker run --rm -it -c 512 progrium/stress --cpu 4
stress: info: [1] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 12000us
stress: dbug: [1] -- hogcpu worker 4 [6] forked
stress: dbug: [1] using backoff sleep of 9000us
stress: dbug: [1] -- hogcpu worker 3 [7] forked
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] -- hogcpu worker 2 [8] forked
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] -- hogcpu worker 1 [9] forked#3.在开启一个终端执行htop命令
[rootyixuan ~]# htop 因为默认情况下容器的 CPU share 为 1024所以这两个容器的 CPU 使用率应该大致为 21下面是启动第二个容器之后的监控截图 两个容器分别启动了四个 stress 进程第一个容器 stress 进程 CPU 使用率都在 60% 左右第二个容器 stress 进程 CPU 使用率在 30% 左右比例关系大致为 21符合之前的预期。 1.2 限制CPU 核数
限制容器能使用的 CPU 核数 -c --cpu-shares 参数只能限制容器使用 CPU 的比例或者说优先级无法确定地限制容器使用 CPU 的具体核数从 1.13 版本之后docker 提供了 --cpus 参数可以限定容器能使用的 CPU 核数。这个功能可以让我们更精确地设置容器 CPU 使用量是一种更容易理解也因此更常用的手段. --cpus 后面跟着一个浮点数代表容器最多使用的核数可以精确到小数点二位也就是说容器最小可以使用 0.01 核 CPU。 限制容器只能使用 1.5 核数 CPU
[rootyixuan ~]# docker run --rm -it --cpus 1.5 progrium/stress --cpu 3
stress: info: [1] dispatching hogs: 3 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 9000us
stress: dbug: [1] -- hogcpu worker 3 [6] forked
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] -- hogcpu worker 2 [7] forked
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] -- hogcpu worker 1 [8] forked 在容器里启动三个 stress 来跑 CPU 压力如果不加限制这个容器会导致 CPU 的使用率为 300% 左右也就是说会占用三个核的计算能力。实际的监控如下图 可以看到每个 stress 进程 CPU 使用率大约在 50%总共的使用率为 150%符合 1.5 核的设置。
如果设置的 --cpus 值大于主机的 CPU 核数docker 会直接报错
[rootyixuan ~]# docker run --rm -it --cpus 8 progrium/stress --cpu 3 #启用三个进程做测试
docker: Error response from daemon: Range of CPUs is from 0.01 to 4.00, as there are only 4 CPUs available.
See docker run --help. 如果多个容器都设置了 --cpus 并且它们之和超过主机的 CPU 核数并不会导致容器失败或者退出这些容器之间会竞争使用 CPU具体分配的 CPU 数量取决于主机运行情况和容器的 CPU share 值。也就是说 --cpus 只能保证在 CPU 资源充足的情况下容器最多能使用的 CPU 数docker 并不能保证在任何情况下容器都能使用这么多的 CPU因为这根本是不可能的。
1.3 CPU 绑定
限制容器运行在某些 CPU 核
注一般并不推荐在生产中这样使用
docker 允许调度的时候限定容器运行在哪个 CPU 上。
案例
假如主机上有 4 个核可以通过 --cpuset 参数让容器只运行在前两个核上
[rootyixuan ~]# docker run --rm -it --cpuset-cpus0,1 progrium/stress --cpu 2
stress: info: [1] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] -- hogcpu worker 2 [6] forked
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] -- hogcpu worker 1 [7] forked
这样监控中可以看到只有前面两个核 CPU 达到了 100% 使用率。 2. mem资源限制
docker 默认没有对容器内存进行限制容器可以使用主机提供的所有内存。
不限制内存带来的问题 这是非常危险的事情如果某个容器运行了恶意的内存消耗软件或者代码有内存泄露很可能会导致主机内存耗尽因此导致服务不可用。可以为每个容器设置内存使用的上限一旦超过这个上限容器会被杀死而不是耗尽主机的内存。 限制内存带来的问题 限制内存上限虽然能保护主机但是也可能会伤害到容器里的服务。如果为服务设置的内存上限太小会导致服务还在正常工作的时候就被 OOM 杀死如果设置的过大会因为调度器算法浪费内存。 合理做法 1. 为应用做内存压力测试理解正常业务需求下使用的内存情况然后才能进入生产环境使用 2. 一定要限制容器的内存使用上限尽量保证主机的资源充足一旦通过监控发现资源不足就进行扩容或者对容器进行迁移如果可以内存资源充足的情况 3. 尽量不要使用 swapswap 的使用会导致内存计算复杂对调度器非常不友好 docker 限制容器内存使用量: docker 启动参数中和内存限制有关的包括参数的值一般是内存大小也就是一个正数后面跟着内存单位 b、k、m、g分别对应 bytes、KB、MB、和 GB): -m --memory容器能使用的最大内存大小最小值为 4m 如果限制容器的内存使用为 64M在申请 64M 资源的情况下容器运行正常如果主机上内存非常紧张并不一定能保证这一点
[rootyixuan ~]# docker run --rm -it -m 64m progrium/stress --vm 1 --vm-bytes 64M --vm-hang 0
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] -- hogvm worker 1 [6] forked
stress: dbug: [6] allocating 67108864 bytes ...
stress: dbug: [6] touching bytes in strides of 4096 bytes ...
stress: dbug: [6] sleeping forever with allocated memory容器可以正常运行。
-m 64m限制你这个容器只能使用64M
--vm-bytes 64M将内存撑到64兆是不会报错因为我有64兆内存可用。
hang:就是卡在这里。
--vm生成几个占用内存的进程 而如果申请 150M 内存会发现容器里的进程被 kill 掉了worker 6 got signal 9signal 9 就是 kill 信号
[rootyixuan ~]# docker run --rm -it -m 64m progrium/stress --vm 1 --vm-bytes 150M --vm-hang 0
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] -- hogvm worker 1 [6] forked
stress: dbug: [6] allocating 157286400 bytes ...
stress: dbug: [6] touching bytes in strides of 4096 bytes ...
stress: FAIL: [1] (416) -- worker 6 got signal 9
stress: WARN: [1] (418) now reaping child worker processes
stress: FAIL: [1] (422) kill error: No such process
stress: FAIL: [1] (452) failed run completed in 1s 3. 限制IO 限制bps和iops bps是 byte per second 每秒读写的数量 iops是 io per second 每秒IO的次数 注:目前Block I0限额只对direct IO (不使用文件缓存)有效。 可以同过下面的参数控制容器的bps和iops --device-read-bps:限制读某个设备的bps. --devce-write-bps:限制写某个设备的bps. --device-read-iops:限制读某个设备的iops. --device-write-iops: 限制写某个设备的iops. 限制情况下 [rootnewrain ~]# docker run -it --device-write-bps /dev/sda:30MB ubuntu root10845a98036e:/# time dd if/dev/zero oftest.out bs1M count800 oflagdirect 结果如下图 不限制情况下 [rootnewrain ~]# docker run -it ubuntu root10845a98036e:/# time dd if/dev/zero oftest.out bs1M count800 oflagdirect 结果如下图 二、端口转发 使用端口转发解决容器端口访问问题 -p:创建应用容器的时候一般会做端口映射这样是为了让外部能够访问这些容器里的应用。可以用多个-p指定多个端口映射关系。 mysql应用端口转发
查看本地地址
[rootyixuan ~]# ip a
...
2: ens33: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc pfifo_fast state UP qlen 1000link/ether 00:0c:29:9c:bf:66 brd ff:ff:ff:ff:ff:ffinet 192.168.246.141/24 brd 192.168.246.255 scope global dynamic ens33valid_lft 5217593sec preferred_lft 5217593secinet6 fe80::a541:d470:4d9a:bc29/64 scope link valid_lft forever preferred_lft forever 运行容器使用-p作端口转发把本地3307转发到容器的3306其他参数需要查看发布容器的页面提示
[rootyixuan ~]# docker pull daocloud.io/library/mysql:5.7
[rootyixuan ~]# docker run -d --name mysql1 -p 3307:3306 -e MYSQL_ROOT_PASSWORDQf123! daocloud.io/library/mysql:5.7
a4327dbddf665b4302c549320bff869b8a027c2e1eead363d84ce5d06acf2698-e MYSQL_ROOT_PASSWORD 设置环境变量这里是设置mysql的root用户的密码
通过本地IP192.168.246.141的3307端口访问容器mysql1内的数据库出现如下提示恭喜你
# 1.安装一个mysql客户端
[rootyixuan ~]# yum install -y mysql# 2.登录
[rootyixuan ~]# mysql -uroot -pQf123! -h 192.168.246.141 -P3307
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.26 MySQL Community Server (GPL)Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type help; or \h for help. Type \c to clear the current input statement.MySQL [(none)]
# -P大P:当使用-P标记时Docker 会随机映射一个 32768~49900 的端口到内部容器开放的网络端口。如下[rootyixuan ~]# docker pull daocloud.io/library/redis
[rootyixuan ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
daocloud.io/library/redis latest 598a6f110d01 2months ago 118MB[rootyixuan ~]# docker run --name myredis -P -d daocloud.io/library/redis
ca06a026d84a0605d9a9ce6975389a79f4ab9a9a043a03f088cd909c1fe52e29[rootyixuan ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ca06a026d84a daocloud.io/library/redis docker-entrypoint.s… 22 seconds ago Up 21 seconds 0.0.0.0:32768-6379/tcp myredis 从上面的结果中可以看出本地主机的32768端口被映射到了redis容器的6379端口上也就是说访问本机的32768端口即可访问容器内redis端口。
在别的机器上通过上面映射的端口32768连接这个容器的redis
[rootdocker-server2 ~]# yum install -y redis
[rootdocker-server2 ~]# redis-cli -h 192.168.246.141 -p 32768
192.168.246.141:32768 ping
PONG
192.168.246.141:32768 三、容器卷
把本地宿主机上面的某一个目录挂载到容器里面的目录去。这两个目录都不用提前存在会自动创建
新卷只能在容器创建过程当中挂载
[rootyixuan ~]# docker run -it --name testnginx -v /test:/test2 daocloud.io/library/nginx /bin/bash
root86320e734cd1:/# ls
root86320e734cd1:/# ctrlpq #退出# 测试
[rootyixuan ~]# cd /test/
[rootyixuan test]# ls
[rootyixuan test]# touch a.txt
[rootyixuan test]# cd
[rootyixuan ~]# docker exec -it testnginx /bin/bash
root86320e734cd1:/# cd test2/
root86320e734cd1:/test2# ls
a.txt# 共享文件
[rootyixuan ~]# mkdir /dir
[rootyixuan ~]# vim /dir/a.txt
123
[rootyixuan ~]# docker run -it --name testnginx2 -v /dir/a.txt:/dir1/a.txt daocloud.io/library/nginx /bin/bash
rootf899be627552:/# cat dir1/a.txt
123
rootf899be627552:/#
# 注意如果是共享文件修改宿主机上面的文件内容容器里面的文件不会同步更新如果在容器里面进行修改文件本地会同步。
共享其他容器的卷其他容器用同一个卷
[rootyixuan ~]# docker run -it --name testnginx1 --volumes-from testnginx daocloud.io/library/nginx /bin/bashroot50e6f726335c:/# ls
bin dev home lib64 mnt proc run srv test2 usr
boot etc lib media opt root sbin sys tmp varroot50e6f726335c:/# cd test2/root50e6f726335c:/test2# ls
a.txt
实际应用中可以利用多个-v选项把宿主机上的多个目录同时共享给新建容器
比如
# docker run -it -v /abc:/abc -v /def:/def 1ae9 四、部署centos7容器应用
镜像下载
[rootyixuan ~]# docker pull daocloud.io/library/centos:7
systemd 整合: 因为 systemd 要求 CAPSYSADMIN 权限从而得到了读取到宿主机 cgroup 的能力CentOS7 中已经用 fakesystemd 代替了 systemd 。 但是我们使用systemd可用参考下面的 Dockerfile [rootyixuan ~]# mkdir test
[rootyixuan ~]# cd test/
[rootyixuan test]# vim Dockerfile
FROM daocloud.io/library/centos:7
MAINTAINER soso sosoqq.com
ENV container dockerRUN yum -y swap -- remove fakesystemd -- install systemd systemd-libs
RUN yum -y update; yum clean all; \
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;VOLUME [ /sys/fs/cgroup ]CMD [/usr/sbin/init] 这个Dockerfile删除fakesystemd 并安装了 systemd。然后再构建基础镜像:
[rootyixuan test]# docker build -t local/c7-systemd . 执行没有问题这就生成一个包含 systemd 的应用容器示例
[rootyixuan test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
local/c7-systemd latest a153dcaa642e 6 minutes ago 391MB
为了使用像上面那样包含 systemd 的容器需要创建一个类似下面的Dockerfile
[rootyixuan test]# mkdir http
[rootyixuan test]# cd http/
[rootyixuan http]# vim Dockerfile
FROM local/c7-systemd
RUN yum -y install httpd; yum clean all; systemctl enable httpd.service
EXPOSE 80
CMD [/usr/sbin/init]
构建镜像:
[rootyixuan http]# docker build -t local/c7-systemd-httpd . 运行包含 systemd 的应用容器:
为了运行一个包含 systemd 的容器需要使用--privileged选项 并且挂载主机的 cgroups 文件夹。 下面是运行包含 systemd 的 httpd 容器的示例命令
[rootyixuan http]# docker run --privileged -tid -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 80:80 local/c7-systemd-httpd--privileged:授权提权。让容器内的root用户拥有正真root权限(有些权限是没有的)
注意如果不加会运行在前台(没有用-d)可以用ctrlpq放到后台去
测试可用
[rootyixuan http]# yum install -y elinks
[rootyixuan http]# elinks --dump http://192.168.246.141 #apache的默认页面Testing 123..This page is used to test the proper operation of the [1]Apache HTTPserver after it has been installed. If you can read this page it meansthat this site is working properly. This server is powered by [2]CentOS. 再来个安装openssh-server的例子
[rootyixuan http]# cd ..
[rootyixuan test]# mkdir ssh
[rootyixuan test]# cd ssh/
[rootyixuan ssh]# vim Dockerfile
FROM local/c7-systemd
RUN yum -y install openssh-server; yum clean all; systemctl enable sshd.service
RUN echo 1 | passwd --stdin root
EXPOSE 22
CMD [/usr/sbin/init]
[rootyixuan ssh]# docker build --rm -t local/c7-systemd-sshd .
[rootyixuan ssh]# docker run --privileged -tid -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 2222:22 local/c7-systemd-sshd
[rootyixuan ssh]# ssh 192.168.246.141 -p 2222
[rootce1af52a6f6c ~]#
五、docker数据存储位置
# 查看存储路径
[rootyixuan ~]# docker info | grep RootDocker Root Dir: /var/lib/docker# 修改默认存储位置
在dockerd的启动命令后面追加--data-root参数指定新的位置
[rootyixuan ~]# vim /usr/lib/systemd/system/docker.service
ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock --data-root/data[rootyixuan ~]# systemctl daemon-reload
[rootyixuan ~]# systemctl restart docker# 查看是否生效
[rootyixuan ~]# docker info | grep RootDocker Root Dir: /data[rootyixuan ~]# cd /data/
[rootyixuan data]# ls
builder buildkit containers image network overlay2 plugins runtimes swarm tmp trust volumes
六、docker网络
容器网络分类
查看当前网络
[rootyixuan ~]# docker network list
NETWORK ID NAME DRIVER SCOPE
9b902ee3eafb bridge bridge local
140a9ff4bb94 host host local
d1210426b3b0 none null local
docker安装后默认会创建三种网络类型bridge、host和none以及自定义网络模式
1、bridge:网络桥接 默认情况下启动、创建容器都是用该模式所以每次docker容器重启时会按照顺序获取对应ip地址。 2、none无指定网络 启动容器时可以通过--networknone,docker容器不会分配局域网ip 3、host主机网络 docker容器和主机共用一个ip地址。 使用host网络创建容器 [rootyixuan ~]# docker run -it --name testnginx2 --net host 98ebf73ab [rootyixuan ~]# netstat -lntp | grep 80 tcp6 0 0 :::80 :::* LISTEN 3237/docker-proxy 浏览器访问宿主ip地址 4、固定ip:
创建固定Ip的容器
# 4.1、创建自定义网络类型并且指定网段
[rootyixuan ~]# docker network create --subnet192.168.0.0/16 staticnet
4efd309244c6ad70eda2d047a818a3aec5b162f5ca29fb6024c09a5efbf15854# 通过docker network ls可以查看到网络类型中多了一个staticnet:
[rootyixuan ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
9b902ee3eafb bridge bridge local
140a9ff4bb94 host host local
d1210426b3b0 none null local
4efd309244c6 staticnet bridge local # 4.2、使用新的网络类型创建并启动容器[rootyixuan ~]# docker run -itd --name userserver --net staticnet --ip 192.168.0.2 daocloud.io/library/centos:7# 通过docker inspect可以查看容器ip为192.168.0.2:[rootyixuan ~]# docker inspect userserver | grep -i ipaddressSecondaryIPAddresses: null,IPAddress: ,IPAddress: 192.168.0.2,# 关闭容器并重启发现容器ip并未发生改变 5、自定义网络模式 自定义网络模式Docker 还允许创建自定义网络来实现更灵活的网络配置。在自定义网络模式下可以创建一个独立的网络并将容器连接到该网络中。这样可以在自定义网络中实现容器之间的通信同时也可以通过网络的连接方式将容器连接到宿主机网络或其他网络。