一.什么是Docker?
Docker容器是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架包括系统。
二 .Docker的用途
1)快速交付你的应用程序
Docker可以为你的开发过程提供完美的帮助。Docker允许开发者在本地包含了应用程序和服务的容器进行开发,之后可以集成到连续的一体化和部署工作流中。
举个例子,开发者们在本地编写代码并且使用Docker和同事分享其开发栈。当开发者们准备好了之后,他们可以将代码和开发栈推送到测试环境中,在该环境进行一切所需要的测试。从测试环境中,你可以将Docker镜像推送到服务器上进行部署。
2)开发和拓展更加简单
Docker的以容器为基础的平台允许高度可移植的工作。Docker容器可以在开发者机器上运行,也可以在实体或者虚拟机上运行,也可以在云平台上运行。
Docker的可移植、轻量特性同样让动态地管理负载更加简单。你可以用Docker快速地增加应用规模或者关闭应用程序和服务。Docker的快速意味着变动几乎是实时的。
3)达到高密度和更多负载
Docker轻巧快速,它提供了一个可行的、符合成本效益的替代基于虚拟机管理程序的虚拟机。这在高密度的环境下尤其有用。例如,构建你自己的云平台或者PaaS,在中小的部署环境下同样可以获取到更多的资源性能。
三.Docker的部署与安装
1、安装docker和相关依赖性,并开启 docker
[root@foundation50 ~]# yum install docker-engine-17.03.1.ce-1.el7.centos.x86_64.rpm
[root@foundation50 ~]# yum install docker-engine-selinux-17.03.1.ce-1.el7.centos.noarch.rpm
[root@foundation50 ~]# systemctl start docker
[root@foundation50 ~]# docker info # docker宿主机的信息
[root@foundation50 ~]# cd /tmp/
[root@foundation50 tmp]# cd docker/
[root@foundation50 docker]# docker rm -f `docker ps -aq` ##删除所有的容器镜像
[root@foundation50 docker]# docker ps -a ##查看正在运行的进程
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
在安装好docker后,linux系统会为docker容器分配一个ip,利用ip addr中查看docker0的ip
[root@foundation50 ~]# ip addr
四、现有镜像的导入和容器的使用
[root@foundation50 docker]# docker load -i nginx.tar ##镜像加载
[root@foundation50 docker]# docker run -d --name vm1 nginx ## 运行docker -d打入后台--name表示为这个容器起的名字是vm1
f09c30e415e9d640999699682b2cab34351b9c3765cb2d42971871fa51d17112
[root@foundation50 docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f09c30e415e9 nginx "nginx -g 'daemon ..." 12 seconds ago Up 10 seconds 80/tcp vm1
[root@foundation50 docker]# ls
Dockerfile ssh web yum.repo
[root@foundation50 docker]# docker container attach vm2
[root@foundation50 docker]# docker container exec -it vm1 bash
五.Dockerfile文件的编写
(一)我们利用功能最简化的rhel7镜像进行改造,封装出打开后直接带有httpd服务的v1版本镜像:
1.得到简单的rhel7镜像,我们希望可以得到一个打开后可以直接访问apach发布目录的镜像
2.我们在写Dockerfile文件的时候,可以打开一个rhel7的虚拟机,一边在这敲命令用来验证,一边在文件中编写
[root@foundation50 docker]# docker rm -f `docker ps -aq` ##删除所有,清空环境
[root@foundation50 docker]# cd /tmp/docker/
[root@foundation50 docker]# ls
Dockerfile ssh web yum.repo
[root@foundation50 docker]# pwd
/tmp/docker
[root@foundation50 docker]# vim Dockerfile ##编写文件
FROM rhel7 # 源镜像是rhel7,最好将名为rhel7的镜像放在本地
ENV HOSTNAME server1 # 定义hostname为server1
MAINTAINER jay@2983088484.com # 定义邮箱
EXPOSE 80 # 定义端口为80
COPY dvd.repo /etc/yum.repos.d/dvd.repo # 配置yum源
RUN rpmdb --rebuilddb && yum install -y httpd && yum clean all
# 执行命令安装httpd并清除yum缓存
# rpmdb 命令用于初始化和重建rpm数据库
# --rebuilddb:从已安装的包头文件,反向重建RPM数据库
VOLUME ["/var/www/html"] # 数据卷所在的位置
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
# 打开apach服务
# -D 是全局文件/etc/sysconfig/httpd中的打开参数
[root@foundation50 docker]# ls
Dockerfile ssh web yum.repo
[root@foundation50 docker]# docker build -t rhel7:v1 . ### rhel:v1是自己封装的镜像的名称和版本号
Sending build context to Docker daemon 3.072 kB
从封装过程来看,封装过程被分为了我们Dockerfile文件中的行数,一层一层往下执行,所以我们在编写Dockerfile文件的时候,应该尽量减少行数,加快封装速度…
将dvd.repo放在当前目录
[root@foundation50 docker]# docker cp yum.repo vm1:/etc/yum.repos.d/
(二).封装一个带有ssh服务,可以连接别的主机也可以被别人连接
1.编辑Dockerfile文件
[root@foundation50 ssh]# pwd
/tmp/docker/ssh
[root@foundation50 ssh]# cat Dockerfile
FROM rhel7
ENV HOSTNAME server2
MAINTAINER jay@2983088484.com
EXPOSE 22 # 对外端口是22
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN rpmdb --rebuilddb && yum install -y openssh-server && yum install -y openssh-clients yum clean all && ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" && ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" && ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" && echo root:redhat | chpasswd
CMD ["/usr/sbin/sshd","-D"]
[root@foundation50 docker]# docker build -t rhel7:v2 . ##开始封装
[root@foundation50 ssh]# docker run -it --name vm0 rhel7:v2
[root@foundation50 ssh]# docker inspect vm0
(三)利用supervisord一次封装多个服务
1、编辑Dockerfile文件
[root@foundation50 /]# docker rm -f `docker ps -aq`
[root@foundation50 /]# cd /tmp/docker/
[root@foundation50 docker]# ls
[root@foundation50 docker]# vim Dockerfile ##编辑Dockerfile文件(整合上边的httpd和ssh)
FROM rhel7
EXPOSE 80 22
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN rpmdb --rebuilddb && yum install -y httpd openssh-server openssh-clients supervisor && yum clean all && ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" && ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" && ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" && echo root:westos | chpasswd
# 安装supervisor
COPY supervisord.conf /etc/supervisord.conf
CMD ["/usr/bin/supervisord"]
# 在打开supervisor的时候,将多个服务同时开启(httpd和ssh)
2、修改yum文件
[root@foundation50 ssh]# docker run -it --name vm1 rhel7 bash
bash-4.2# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
bash-4.2# cd /etc/yum.repos.d/
bash-4.2# ls
rhel7.repo yum.repo
bash-4.2# yum install -y httpd openssh-server openssh-clients supervisor
[root@foundation50 docker]# vim yum.repo
[source7.3]
name=source7.3
baseurl=http://172.25.50.250/source7.3
gpgcheck=0
[docker]
name=docker
baseurl=http://172.25.254.250/pub/docker
gpgcheck=0
3、编辑supervisord.conf文件
[root@foundation50 ~]# cd /tmp/docker/
[root@foundation50 docker]# ls
auth certs compose Dockerfile ssh supervisord.conf test web yum.repo
[root@foundation50 docker]# cat supervisord.conf
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
[program:httpd]
command=/usr/sbin/httpd
4、开始封装
[root@foundation50 docker]# docker build -t rhel7:v3 . ##开始封装
Sending build context to Docker daemon 112.7 MB
5.用封装的镜像创建容器
[root@foundation50 docker]# docker run -d --name vm1 -v /tmp/docker/web:/var/www/html rhel7:v3
0042b5dab7b7af336cbf83f65544f5097d2261da8ca4990cc7accb8365ad8b51
[root@foundation50 docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0042b5dab7b7 rhel7:v3 "/usr/bin/supervisord" 4 seconds ago Up 4 seconds 22/tcp, 80/tcp vm1
[root@foundation50 docker]# docker inspect vm1 ##查看vm1容器的ip ,vm1 是名字
[root@foundation50 docker]# curl 172.17.0.2
[root@foundation50 docker]# ssh -l root 172.17.0.2
(四)Dockerfile文件中CMD和EMTRYPOINT的区别
ENTRYPOINT 容器启动后执行的命令,让容器执行表现的像一个可执行程序一样,与CMD 的 区 别 是 不 可 以 被 docker run 覆 盖 , 会 把 docker run 后 面 的 参 数 当 作 传 递 给ENTRYPOINT 指令的参数。Dockerfile 中只能指定一个 ENTRYPOINT,如果指定了很多,只 有 最 后 一 个 有 效 。 docker run 命 令 的 -entrypoint 参 数 可 以 把 指 定 的 参 数 继 续 传 递 给ENTRYPOINT。
1、情况一、
[root@foundation50 docker]# cd /tmp/docker/
[root@foundation50 docker]# ls
Dockerfile ssh supervisord.conf web yum.repo
[root@foundation50 docker]# mkdir test
[root@foundation50 docker]# pwd
/tmp/docker
[root@foundation50 docker]# cd test/
[root@foundation50 test]# ls
[root@foundation50 test]# vim Dockerfile
FROM rhel7
CMD echo "hello world!" ## CMD 可以被覆盖
[root@foundation50 test]# docker build -t rhel7:v4 .
[root@foundation50 test]# docker run --rm rhel7:v4
hello world!
[root@foundation50 test]# docker run --rm rhel7:v4 echo westos
westos
[root@foundation50 test]# vim Dockerfile
FROM rhel7
ENTRYPOINT echo "hello world!"
[root@foundation50 test]# docker build -t rhel7:v4 .
Sending build context to Docker daemon 2.048 kB
Step 1/2 : FROM rhel7
---> 0a3eb3fde7fd
Step 2/2 : ENTRYPOINT echo "hello world!"
---> Running in 259d5a141065
---> 1b34f787ec81
Removing intermediate container 259d5a141065
Successfully built 1b34f787ec81
[root@foundation50 test]# docker run --rm rhel7:v4
hello world!
[root@foundation50 test]# docker run --rm rhel7:v4 westos
hello world!
[root@foundation50 test]# docker run --rm rhel7:v4 echo westos
hello world!
2、情况二、
[root@foundation50 test]# docker rmi rhel7:v4
Untagged: rhel7:v4
Deleted: sha256:1b34f787ec8145e520a5ab5f0949ac45c9bd93063cfea05d971d22836f355a71
[root@foundation50 test]# vim Dockerfile
FROM rhel7
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]
~
[root@foundation50 test]# docker build -t rhel7:v4 .
Sending build context to Docker daemon 2.048 kB
Step 1/3 : FROM rhel7
---> 0a3eb3fde7fd
Step 2/3 : ENTRYPOINT /bin/echo hello
---> Running in 8433105ca37e
---> c111c006ff89
Removing intermediate container 8433105ca37e
Step 3/3 : CMD world
---> Running in be0441d8a9f1
---> 85052b5cc0c6
Removing intermediate container be0441d8a9f1
Successfully built 85052b5cc0c6
[root@foundation50 test]# docker run --rm rhel7:v4
hello world
[root@foundation50 test]# docker run --rm rhel7:v4 westos
hello westos
[root@foundation50 test]# vim Dockerfile
FROM rhel7
ENV name westos
ENTRYPOINT ["/bin/sh","-c","echo $name"]
[root@foundation50 test]# docker build -t rhel7:v4 .
Sending build context to Docker daemon 2.048 kB
Step 1/3 : FROM rhel7
---> 0a3eb3fde7fd
Step 2/3 : ENV name westos
---> Running in 70133ae63cd5
---> 0668c02178df
Removing intermediate container 70133ae63cd5
Step 3/3 : ENTRYPOINT /bin/sh -c echo $name
---> Running in 8c1881bc448e
---> d4ab7c0da34b
Removing intermediate container 8c1881bc448e
Successfully built d4ab7c0da34b
[root@foundation50 test]# docker run --rm rhel7:v4
westos
[root@foundation50 test]#
[root@foundation50 test]# vim Dockerfile
FROM rhel7
ENV name westos
ENTRYPOINT echo "hello $name"
[root@foundation50 test]# docker rmi rhel7:v4
Untagged: rhel7:v4
Deleted: sha256:d4ab7c0da34bc4e9f97e953702716ea7ac7dc2e9e24cf7c697f91cefe83fa16e
Deleted: sha256:0668c02178dffbbfb7e0da5f7327b35777e94056bb21162ec8de6f11a8948ae5
[root@foundation50 test]# docker build -t rhel7:v4 .
Sending build context to Docker daemon 2.048 kB
Step 1/3 : FROM rhel7
---> 0a3eb3fde7fd
Step 2/3 : ENV name westos
---> Running in 5e12d8e3cfff
---> 3504669bc224
Removing intermediate container 5e12d8e3cfff
Step 3/3 : ENTRYPOINT echo "hello $name"
---> Running in 5b4ad268d6df
---> b3480c411fcf
Removing intermediate container 5b4ad268d6df
Successfully built b3480c411fcf
[root@foundation50 test]# docker run --rm rhel7:v4
hello westos
六、Docker的安全机制
[root@foundation50 test]# docker ps -f status=exited
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eb2c7152bd62 2e1188f5153f "/bin/sh -c 'rpmdb..." 2 hours ago Exited (1) 2 hours ago condescending_khorana
[root@foundation50 test]# docker ps -aqf status=exited
eb2c7152bd62
[root@foundation50 test]# docker rm `docker ps -aqf status=exited`
eb2c7152bd62
在docker命令行设置docker的安全机制
1.设置特权级运行的容器:–privileged=true
[root@foundation50 test]# docker run -it --name vm2 ubuntu
root@c1a90a722664:/# ip link set down eth0
RTNETLINK answers: Operation not permitted
root@c1a90a722664:/# exit
[root@foundation50 test]# docker run -it --name vm3 --privileged=true ubuntu
root@d07c338af9d5:/# ip link set down eth0
root@d07c338af9d5:/# ip link set up eth0
root@d07c338af9d5:/# id
uid=0(root) gid=0(root) groups=0(root)
[root@foundation50 test]# docker rm -f `docker ps -aq`
2.设置允许容器占用的内存大小和swap分区大小
针对 内存 memory 权限 用到了 stress 镜像,用来 压测
我们开一个 top 监控
[kiosk@foundation50 ~]$ top
[root@foundation50 docker]# docker run --rm -it --name vm1 -m 100M --memory-swap 100M stress --vm 1 --vm-bytes 90M
最后我们按 Ctrl + c 退出就可以了。
但是,当我们输入 110M 时
[root@foundation50 docker]# docker run --rm -it --name vm1 -m 100M --memory-swap 100M stress --vm 1 --vm-bytes 110M
因为我们的交换空间的大小 = 物理内存大小的 2 倍
(当物理内存大小不够时,就会交换到交换区)
针对 CPU ,我们同样用到了 stress 压测
[root@foundation50 ~]# docker run --rm -it --cpu-shares 512 stress -c 1
[root@foundation50 ~]# docker run --rm -it --cpu-shares 1024 stress -c 1
我们查看监控,发现两个一起,并没有优先级的区分
因为我们的 CPU 有 4 个 ,一边一个,互不影响。为了看到效果,我们将 CPU 的数量 设成 4 ,我们就可以看到1024 的 优先级 比 512 的 优先级 ,高 2 倍 的效果了。
[root@foundation50 ~]# docker run --rm -it --cpu-shares 512 stress -c 4
[root@foundation50 ~]# docker run --rm -it --cpu-shares 1024 stress -c 4
这样,我们就可以看到效果了
七、利用cgroup对docker做权限限制
Linux Cgroup(Control Groups)是Linux内核提供的用于限制、记录、隔离进程组可以使用的资源(cpu、memory、IO等)的一种机制。
1、对memory内存的限制
[root@foundation50 ~]# docker run --rm -it --device-write-bps /dev/sda:10M ubuntu
root@03957e92ef3c:/# dd if=/dev/zero of=testfile bs=1M count=100 oflag=direct
安装cgroup管理工具
[root@server1 ~]# yum install -y libcgroup.x86_64
安装好libcgroup之后,会在根下产生/cgroup,此时该目录下还没有任何东西
/etc/init.d/cgconfig start 打开cgroup(注意不能在当前目录下)
[root@server1 ~]# cd /cgroup/
[root@server1 cgroup]# ls
[root@server1 cgroup]# pwd
/cgroup
[root@server1 cgroup]# /etc/init.d/cgconfig start
Starting cgconfig service: [ OK ]
[root@server1 cgroup]# ls
blkio cpu cpuacct cpuset devices freezer memory net_cls
[root@server1 cgroup]# pwd
/cgroup
[root@server1 cgroup]# pwd
/cgroup
[root@server1 cgroup]# cd memory/
[root@server1 memory]# cat memory.limit_in_bytes
9223372036854775807 ### 此时是对内存的吞吐量为无限大
2.编对资源的限制
[root@server1 memory]# vim /etc/cgconfig.conf
group x1 {
memory {
memory.limit_in_bytes = 209715200; # 限制使用的最大内存数
}
}
[root@server1 ~]# cd /cgroup/memory/
[root@server1 memory]# ls
[root@server1 memory]# cd x1/
[root@server1 x1]# ls
[root@server1 x1]# cat memory.limit_in_bytes
[root@server1 x1]# cd /dev/shm/
[root@server1 shm]# ls
[root@server1 shm]# free -m
[root@server1 shm]# dd if=/dev/zero of=file1 bs=1M count=100
[root@server1 shm]# free -m
[root@server1 shm]# vmstat
[root@server1 shm]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=300
[root@server1 shm]# dd if=/dev/zero of=file1 bs=1M count=300
[root@server1 shm]# cd /cgroup/
[root@server1 cgroup]# cd memory/
[root@server1 memory]# cat memory.memsw.limit_in_bytes
9223372036854775807
[root@server1 memory]# cd
[root@server1 ~]# vim /etc/cgconfig.conf
3.进行压力测试
[root@server1 shm]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=300
[root@server1 shm]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=190
190+0 records in
190+0 records out
199229440 bytes (199 MB) copied, 0.103036 s, 1.9 GB/s
[root@server1 shm]# cgexec -g memory:x1 dd if=/dev/zero of=file1 bs=1M count=210
Killed
[root@server1 ~]# ls
memapp1 memapp2
[root@server1 ~]# chmod +x memapp*
[root@server1 ~]# ls
memapp1 memapp2
[root@server1 ~]# yum install -y /lib/ld-linux.so.2
[root@server1 ~]# ./memapp1
Process ID is: 12755
Grabbing 4096 pages of memory
Success!
Press any key to exit
[root@server1 ~]# ./memapp2
Process ID is: 12756
Grabbing 8192 pages of memory
Success!
Press any key to exit
[root@server1 ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
5000*4*1024
20480000
^C
(interrupt) Exiting bc.
[root@server1 ~]# pwd
/root
[root@server1 ~]# vim /etc/cgconfig.conf
group x1 {
memory {
memory.limit_in_bytes = 20480000;
memory.memsw.limit_in_bytes = 20480000; # 限制内存和交换分区的大小之和,即交换分区的大小为0,可以分别打开交换分区和注释交换分区来做测试
}
}
[root@server1 ~]# ls
memapp1 memapp2
[root@server1 ~]# useradd wxh
[root@server1 ~]# cd /dev/shm/
[root@server1 shm]# ll -d .
drwxrwxrwt 2 root root 60 Aug 21 04:46 .
[root@server1 shm]# su - wxh
[wxh@server1 ~]$ cd /dev/shm/
[wxh@server1 shm]$ ls
file1
[wxh@server1 shm]$ rm -fr file1
rm: cannot remove `file1': Operation not permitted
[wxh@server1 shm]$ ls
file1
[wxh@server1 shm]$ logout
[root@server1 shm]# ls
file1
[root@server1 shm]# rm -fr file1
[root@server1 shm]# ls
[root@server1 shm]# su - wxh
[wxh@server1 ~]$ cd /dev/shm/
[wxh@server1 shm]$ dd if=/dev/zero of=file1 bs=1M count=300
300+0 records in
300+0 records out
314572800 bytes (315 MB) copied, 0.184328 s, 1.7 GB/s
[wxh@server1 shm]$ rm -fr file1
[wxh@server1 shm]$ ls
[wxh@server1 shm]$ logout
[root@server1 shm]# vim /etc/cgrules.conf
wxh:memapp1 memory x1/
wxh:memapp2 memory x1/
(二).对CPU的限制
1.查看系统中默认对CPU的限制
[root@server1 ~]# cd /cgroup/
[root@server1 cgroup]# ls
blkio cpu cpuacct cpuset devices freezer memory net_cls
[root@server1 cgroup]# cd cpu
[root@server1 cpu]# ls
cgroup.event_control cpu.cfs_period_us cpu.rt_period_us cpu.shares notify_on_release tasks
cgroup.procs cpu.cfs_quota_us cpu.rt_runtime_us cpu.stat release_agent
[root@server1 cpu]# pwd
/cgroup/cpu
[root@server1 cpu]# ls
cgroup.event_control cpu.cfs_period_us cpu.rt_period_us cpu.shares notify_on_release tasks
cgroup.procs cpu.cfs_quota_us cpu.rt_runtime_us cpu.stat release_agent
2.编辑/etc/cgconfig.conf文件,对CPU的资源进行限制
在cpu.shares文件中,可以对进程调度程序所处理的进程组设置CPU时间分配的比重。通过修改这个值,就可以在分组间调整CPU时间的比例。默认值为1024。
[root@server1 cpu]# cat cpu.shares
1024
[root@server1 cpu]# cd
[root@server1 ~]# vim /etc/cgconfig.conf
group x2 {
cpu {
cpu.shares = 100;
}
}
3.进行压力测试
cgexec -g cpu:x2 dd if=/dev/zero of=/dev/null &(对CPU的利用率高达99.9%)
[root@server1 ~]# cgexec -g cpu:x2 dd if=/dev/zero of=/dev/null &
[1] 12864
[root@server1 ~]# lscpu
(三)对磁盘空间读写的速度限制
1.Cgroup里每个子系统(SubSystem)对应一种资源,Cgroup blkio子系统用于限制块设备I/O速率。相比IO调度权重,iops和bps限制更加直接和量化,更适合用于限制docker容器磁盘IO上限。
2.编辑文件/etc/cgconfig.conf文件,对块设备的读写速度进行限制
[root@server1 ~]# cd /cgroup/
[root@server1 cgroup]# ls
blkio cpu cpuacct cpuset devices freezer memory net_cls
[root@server1 cgroup]# cd blkio/
[root@server1 blkio]# vim /etc/cgconfig.conf
[root@server1 blkio]# pwd
/cgroup/blkio
group x3 {
blkio {
blkio.throttle.read_bps_device = "252:0 1000000"; ##252:0是/dev/vda这个块设备的信息
}
}
[root@server1 x3]# cat blkio.throttle.read_bps_device
252:0 1000000
[root@server1 x3]# pwd
/cgroup/blkio/x3
3.进行压力测试(发现速度维持在了1000k左右)
[root@server1 x3]# cgexec -g blkio:x3 dd if=/dev/vda of=/dev/null &
[3] 12895
[root@server1 ~]# iotop
[root@server1 x3]# cd
[root@server1 ~]# killall dd
[3]+ Terminated cgexec -g blkio:x3 dd if=/dev/vda of=/dev/null (wd: /cgroup/blkio/x3)
(wd now: ~)
(四)freezer子系统
freezer子系统用于挂起和恢复cgroup中的进程。freezer有一个控制件:freezer.state,将FROZEN写入该文件,可以将cgroup中的进程挂起,将THAWED写入该文件,可以将已挂起的进程恢复。该文件可能读出的值有三种,其中两种就是前面已提到的FROZEN和THAWED,分别代表进程已挂起和已恢复(正常运行),还有一种可能的值为FREEZING,显示该值表示该cgroup中有些进程现在不能被frozen。当这些不能被frozen的进程从该cgroup中消失的时候,FREEZING会变成FROZEN,或者手动将FROZEN或THAWED写入一次。
1.编辑/etc/cgconfig.conf文件,允许对进程的状态进行改变
[root@server1 ~]# cd /cgroup/
[root@server1 cgroup]# ls
blkio cpu cpuacct cpuset devices freezer memory net_cls
[root@server1 cgroup]# cd freezer/
[root@server1 freezer]# ls
cgroup.event_control cgroup.procs notify_on_release release_agent tasks
[root@server1 freezer]# cd
[root@server1 ~]# vim /etc/cgconfig.conf
group x4 {
freezer {}
}
2.当我们利用截取命令之后,发现系统的CPU立即被消耗至大致百分之百
[root@server1 cgroup]# cd freezer/
[root@server1 freezer]# ls
cgroup.event_control cgroup.procs notify_on_release release_agent tasks x4
[root@server1 freezer]# cd x4/
[root@server1 x4]# dd if=/dev/zero of=/dev/null &
[1] 12941
[root@server1 x4]# ps ax
[root@server1 x4]# ls
cgroup.event_control cgroup.procs freezer.state notify_on_release tasks
[root@server1 x4]# echo 12941 > tasks
[root@server1 x4]# cat freezer.state
THAWED
[root@server1 x4]# echo FROZEN > freezer.state
[root@server1 x4]# cat freezer.state
FROZEN
[root@server1 ~]# top
3.在这种情况发生的时候,我们不能立即kill掉该进程,因为它可能和别的 进程共同占用某种资源,如果现在是它在使用资源,一旦kill,它会将资源释放,影响别的进程,最好的解决办法是:我们将该进程“冰冻”,观察其是否对别的进程有影响,再加以决定…..
[root@server1 x4]# ps ax
[root@server1 x4]# pwd
/cgroup/freezer/x4
[root@server1 x4]# ls
cgroup.event_control cgroup.procs freezer.state notify_on_release tasks
[root@server1 x4]# echo THAWED > freezer.state
[root@server1 ~]# top
[root@server1 ~]# ps ax
[root@server1 x4]# killall dd
[1]+ Terminated dd if=/dev/zero of=/dev/null
[root@server1 x4]# cd
[root@server1 ~]# ps ax
八、查看docker的状态
[root@foundation50 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@foundation50 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@foundation50 ~]# docker run -it --name vm1 ubuntu
root@872bef52ad00:/# [root@foundation50 ~]# ##ctrl + pq 退出
可以看到 UP
[root@foundation50 ~]# docker inspect vm1
也可以看到进程数据
[root@foundation50 ~]# brctl show
也存在
[root@foundation50 ~]# docker container unpause vm1 ##恢复
[root@foundation50 ~]# docker stop vm1 ##停止
[root@foundation50 ~]# docker inspect vm1
九 、数据卷
Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中称为数据卷(Data Volume)。
数据卷可以用来存储Docker应用的数据,也可以用来在Docker容器间进行数据共享。
数据卷呈现给Docker容器的形式就是一个目录,支持多个容器间共享,修改也不会影响镜像。使用Docker的数据卷,类似在系统中使用
[root@foundation50 ~]# systemctl start docker
[root@foundation50 ~]# docker ps
[root@foundation50 ~]# docker rm -f registry
[root@foundation50 ~]# mkdir /tmp/docker/data1 建立目录
[root@foundation50 ~]# docker run -it --name vm1 -v /data1 ubuntu
root@195c8320998b:/# df
[root@foundation50 ~]# df
[root@foundation50 ~]# docker inspect vm1 |grep vol ## 过滤逻辑卷组
"Type": "volume",
"Source": "/var/lib/docker/volumes/7ca6e3bfd0b62d6b7090d606b00d985ee4b7a3abd9ee907795dd34972b65fd3e/_data",
[root@foundation50 ~]# cd /var/lib/docker/volumes/7ca6e3bfd0b62d6b7090d606b00d985ee4b7a3abd9ee907795dd34972b65fd3e/_data
[root@foundation50 _data]# ls
[root@foundation50 _data]# cp /etc/passwd . ##可以复制文件到当前目录
[root@foundation50 _data]# ls
passwd
搭建nginx查看数据卷volume
[root@foundation50 ~]# docker run -d --name vm2 -v /usr/share/nginx/html nginx
1c4f221098f33e561f3db0ff821d005a507cf707f5b59330a843dd9b5acb1135
[root@foundation50 ~]# docker inspect vm2 |grep vol
"Type": "volume",
"Source": "/var/lib/docker/volumes/daf4b5079c98520a2b5bb69647fad1705d48fd67cf3f7903133ed7088a918360/_data",
[root@foundation50 ~]# cd /var/lib/docker/volumes/daf4b5079c98520a2b5bb69647fad1705d48fd67cf3f7903133ed7088a918360/_data
[root@foundation50 _data]# ls
50x.html index.html
[root@foundation50 _data]#
[root@foundation50 _data]# cd
[root@foundation50 ~]# docker stop vm2
vm2
[root@foundation50 ~]# docker rm vm2
vm2
[root@foundation50 ~]# docker volume rm daf4b5079c98520a2b5bb69647fad1705d48fd67cf3f7903133ed7088a918360
[root@foundation50 _data]# docker inspect vm1 |grep vol
"Type": "volume",
"Source": "/var/lib/docker/volumes/7ca6e3bfd0b62d6b7090d606b00d985ee4b7a3abd9ee907795dd34972b65fd3e/_data",
[root@foundation50 _data]# cd
[root@foundation50 ~]# docker stop vm1
vm1
[root@foundation50 ~]# docker rm vm1
vm1
[root@foundation50 ~]# docker volume rm 7ca6e3bfd0b62d6b7090d606b00d985ee4b7a3abd9ee907795dd34972b65fd3e
[root@foundation50 ~]# docker volume ls
DRIVER VOLUME NAME
local 13d8c2fe2314235e31da981f9bd85178a329b65ec168db691b803956a76e4d6a
local 4f7851c31ddf8d1b350946001dd36a3e0e1a537dddf11d34639d55029fa18370
local 7ca6e3bfd0b62d6b7090d606b00d985ee4b7a3abd9ee907795dd34972b65fd3e
local 802b4c966d97460fda45bd73349327cf14a90fb428170b221c7f06b5c36b53aa
local c223bd13bd949122226a4efbff171d25856ad0be43d15b6c0d56607d4b96d67e
local d46f8de6085c1b460992d3fb0ee1081d6c63f2b0ecc86d451f99e5d4de61f306
local daf4b5079c98520a2b5bb69647fad1705d48fd67cf3f7903133ed7088a918360
[root@foundation50 ~]# docker volume rm `docker volume ls -q`
13d8c2fe2314235e31da981f9bd85178a329b65ec168db691b803956a76e4d6a
4f7851c31ddf8d1b350946001dd36a3e0e1a537dddf11d34639d55029fa18370
7ca6e3bfd0b62d6b7090d606b00d985ee4b7a3abd9ee907795dd34972b65fd3e
802b4c966d97460fda45bd73349327cf14a90fb428170b221c7f06b5c36b53aa
c223bd13bd949122226a4efbff171d25856ad0be43d15b6c0d56607d4b96d67e
d46f8de6085c1b460992d3fb0ee1081d6c63f2b0ecc86d451f99e5d4de61f306
daf4b5079c98520a2b5bb69647fad1705d48fd67cf3f7903133ed7088a918360
[root@foundation50 ~]# docker volume ls
DRIVER VOLUME NAME