对于docker的底层原理三段话
docker的安装
一、docker的安装
1.安装必要的一些系统工具
[root@docker ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
2.添加软件源信息
[root@docker ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3.更新查看版本并安装docker
[root@docker ~]# yum makecache fast
[root@docker ~]# yum list docker-ce.x86_64 --showduplicates | sort -r
[root@docker ~]# yum -y install docker-ce-18.09.0 docker-ce-cli-18.09.0
4.开启docker服务
[root@docker ~]# systemctl start docker
[root@docker ~]# systemctl enable docker
5.设置docker镜像加速器
阿里巴巴网址:https://developer.aliyun.com/mirror/
–个人主页–产品与服务–容器镜像服务–镜像加速器
在阿里云平台即可找到镜像加速器配置步骤。
[root@docker ~]# mkdir -p /etc/docker
[root@docker ~]# sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://szvvaomn.mirror.aliyuncs.com"]
}
EOF
[root@docker ~]# systemctl daemon-reload
[root@docker ~]# systemctl restart docker
6.配置路由转发给功能
[root@docker ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
[root@docker ~]# sysctl -p
docker的底层原理
如果虚拟机内服务对内核版本有要求,这个服务就不太适合用docker来实
现了。
Busybox: 欺骗层(模拟不同系统的根目录)。
解耦:解除耦合、冲突。
耦合:冲突现象。
普通虚拟化:完全型解耦。
Docker: 半解耦。
run------> Centos系统(nginx、web)。
Namespace(名称空间):
逻辑空间-------> 隔离。
用来隔离容器。
/proc /sys : 虚拟文件系统。伪目录文件 -----> 内存。
[root@docker01 ns]# pwd
/proc/1791/ns
namespace六项隔离
namespec六项隔离,实现了容器与宿主机、容器与容器之间的隔离。
IPC : 共享内存、消息列队
MNT : 挂载点、文件系统
NET : 网络栈
PID:进程编号
USER : 用户、组
UTS : 主机名、域名
Cgroup(控制组):
作用:限制docker容器对宿主机资源的使用。
[root@docker01 cpu]# pwd
/sys/fs/cgroup/cpu
[root@docker01 cpu]# cat tasks
// tasks这个文件内的数字,记录的是进程编号。PID
权重比
四大功能:
1)资源限制:cgroup可以对进程组使用的资源总额进行限制。
2)优先级分配:通过分配的cpu时间片数量以及硬盘IO带宽大小,实际上相当于控制了进程运行的优先级别。
3)资源统计:cgroup可以统计系统资源使用量,比如cpu使用时间,内存使用量等,用于按量计费。同时,还支持挂起动能,也就是说通过cgroup把所有资源限制起来,对资源都不能使用,注意着并不是说我们的程序不能使用了,只是不能使用资源,处于等待状态。
4)进程控制:可以对进程组执行挂起、恢复等操作。
内存限额
容器内存包括两个部分:物理内存和swap
可以通过参数控制容器内存的使用量:
-m 或者–memory: 设置内存的使用限额
–memory-swap: 设置内存+ swap的使用限额
举个栗子:
运行一个容器,并且限制该容器最多使用200M内存和100M的swap。
[root@docker01 ~]# docker run -itd --name container1 -m 200MB --memory-swap 300MB centos:7
Status: Downloaded newer image for centos:7
d7635241a3619f1e67822513be9a22954f002fe6acb09f8c2196d17542697c48
[root@docker01 d7635241a3619f1e67822513be9a22954f002fe6acb09f8c2196d17542697c48]# pwd
/sys/fs/cgroup/memory/docker/d7635241a3619f1e67822513be9a22954f002fe6acb09f8c2196d17542697c48
[root@docker01 d7635241a3619f1e67822513be9a22954f002fe6acb09f8c2196d17542697c48]# cat memory.limit_in_bytes
209715200
//内存+swap限制
[root@docker01 d7635241a3619f1e67822513be9a22954f002fe6acb09f8c2196d17542697c48]# cat memory.memsw.limit_in_bytes
314572800
对比一个没有限制的容器,我们会发现,如果运行容器之后不限制内存的话,以为着没有限制
CPU使用
通过-c或者–cpu-shares设置容器使用cpu的权重。如果不设置默认为1024
举个栗子:
[root@docker01 ~]# docker run -itd --name container2 -c 512 centos:7
ab473959378d97545a11679bea43b4c958dd9f4b4fab1028e539828b4414c8d7
[root@docker01 ab473959378d97545a11679bea43b4c958dd9f4b4fab1028e539828b4414c8d7]# pwd
/sys/fs/cgroup/cpu/docker/ab473959378d97545a11679bea43b4c958dd9f4b4fab1028e539828b4414c8d7
[root@docker01 ab473959378d97545a11679bea43b4c958dd9f4b4fab1028e539828b4414c8d7]# cat cpu.shares
512
对比一个没有做CPU权重限制的容器。
[root@docker01 ~]# docker run -itd --name container3 centos:7
59a3a75020f6f380c5a0e17286d7944b3965807f376497c9303bdfc92a9b3e1b
[root@docker01 59a3a75020f6f380c5a0e17286d7944b3965807f376497c9303bdfc92a9b3e1b]# pwd
/sys/fs/cgroup/cpu/docker/59a3a75020f6f380c5a0e17286d7944b3965807f376497c9303bdfc92a9b3e1b
[root@docker01 59a3a75020f6f380c5a0e17286d7944b3965807f376497c9303bdfc92a9b3e1b]# cat cpu.shares
1024
容器的Block IO
磁盘的读写。
docker中可以通过设置权重,限制bps和iops的方式控制容器读写磁盘的IO
bps: 每秒读写的数据量 byte per second
iops: 每秒IO的次数 io per second。
默认情况下,所有容器都能够平等的读写磁盘,也可以通过–blkio-weight参数改变容器的blockIO 的优先级。
–device-read-bps: 显示读取某个设备的bps。
–device-write-bps: 显示写入某个设备的bps。
–device-read-iops: 显示读取某个设备的iops。
–device-write-iops: 显示写入某个设备的iops。
//限制testA这个容器,写入/dev/sda这块磁盘的bps为30MB.
[root@docker01 ~]# docker run -itd --name test1 --device-write-bps /dev/sda:30MB centos:7
//从/dev/zero输入,然后输出到test.out文件中,每次大小为1M,总共800次,oflag=direct 用来指定directIO方式写文件,这样才会使–device-write-bps生效。
[root@docker01 ~]# docker exec -it test1 /bin/bash
[root@8cfac0cdecf0 /]# time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
800+0 records in
800+0 records out
838860800 bytes (839 MB) copied, 26.7639 s, 31.3 MB/s
real 0m26.766s
user 0m0.000s
sys 0m0.960s
再运行一个不做限制testB容器,对比一下速率
[root@docker01 ~]# docker run -itd --name test2 centos:7
828c8e9e4a30fbc692d2574f3f3965a5feee7e389f697e3d455016f8929cd622
[root@docker01 ~]# docker exec -it test2 /bin/bash
[root@828c8e9e4a30 /]# time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
800+0 records in
800+0 records out
838860800 bytes (839 MB) copied, 1.84629 s, 454 MB/s
real 0m1.848s
user 0m0.000s
sys 0m1.518s
基本操作命令
镜像基本操作命令
//查找镜像
[root@docker01 ~]# docker search busybox
//拉取镜像
[root@docker01 ~]# docker pull busybox
//查看本地镜像
[root@docker01 ~]# docker images
注意:一个完整的镜像,由镜像名称和TAG组成。如果只看到一个镜像
的名称,没有接标签,意思是默认标签:latest。
虽然我们查看到的镜像标签为latest(最新的),但并不表示它一定是最新
的。
//把镜像导出到本地
[root@docker01 ~]# docker save -o busybox.tar busybox:latest
或者
[root@docker01 ~]# docker save > busybox.tar busybox:latest
//根据本地镜像包导入镜像
[root@docker01 ~]# docker load -i busybox.tar
或者
[root@docker01 ~]# docker load < busybox.tar
//删除镜像
[root@docker01 ~]# docker rmi busybox:latest
容器基本操作命令
//查看容器-正在运行的
[root@docker01 ~]# docker ps
//查看所有容器,包括正在运行和没有运行的容器
[root@docker01 ~]# docker ps -a
//删除容器
[root@docker1 ~]# docker rm container1
注意: 强制删除正在运行的容器可以加上: -f 选项。
//创建容器
[root@docker1 ~]# docker create -it --name test centos:7
注意·:创建完成之后,容器是created的状态。
//启动容器
[root@docker1 ~]# docker start test
//停止容器运行
[root@docker1 ~]# docker stop test
//重启容器
[root@docker1 ~]# docker restart test
//挂起容器
[root@docker1 ~]# docker pause test
恢复状态
[root@docker1 ~]# docker unpause test
//强制删除所有容器(生产环境严禁使用)
[root@docker1 ~]# docker ps -a -q | xargs docker rm -f
强制启动所有容器
[root@docker1 ~]# docker ps -a -q | xargs docker start
同理,还可以有强制停止、重启、挂起等操作。
//运行一个容器
[root@docker01 ~]# docker run -itd --name test centos:7
参数:
-i : 可交互
-t: 伪终端
-d: 后台运行
–name: 给容器命名
–restart=always : 始终保持运行(随着docker开启而运行)
–rm :会随着退出容器的操作而删除容器
//进入一个容器
[root@docker1 ~]# docker exec -it test1 /bin/bash
或者
[root@docker1 ~]# docker attach test1
区别:
进入方式:
exec 进入的方式需要添加-i -t选项,后边还需要给容器一个shell环境。
但attach就不需要这么麻烦,可以直接进入。
退出状态:
exec 进入的方式: 如果执行exit退出,容器仍然保持运行。
attach : 如果执行exit退出,容器会被关闭。如果想要保持容器不被关
闭,可以使用键盘: Ctrl + p Ctrl + q 可以实现。
本质上去区别:
exec 进入的方法,会生产新的进程。
attach不会生产新进程。
//宿主机和容器之前,相互传东西
[root@docker1 ~]# docker cp nginx-1.16.0.tar.gz webapp:/root
//将容器制作成镜像
[root@docker1 ~]# docker commit webapp myweb
基本操作逻辑
小实验:
基于centos:7镜像运行一个容器,并且,在这个容器内部署Nginx服务。
1)下载镜像
[root@docker01 ~]# docker pull centos:7
2)运行容器
[root@docker01 ~]# docker run -itd --name webapp --restart=always centos:7
3)进入容器,开始部署nginx服务。
//将nginx包导入到容器内
[root@docker01 ~]# docker cp nginx-1.12.0.tar.gz webapp:/root
[root@docker01 ~]# docker exec -it webapp /bin/bash
[root@ee3a8e2528f2 ~]# tar zxf nginx-1.12.0.tar.gz
[root@ee3a8e2528f2 ~]# cd nginx-1.12.0
[root@ee3a8e2528f2 nginx-1.12.0]# yum -y install gcc pcre pcre-devel openssl opessl-devel zlib zlib-devel
[root@ee3a8e2528f2 nginx-1.12.0]# useradd -M -s /sbin/nologin nginx
[root@ee3a8e2528f2 nginx-1.12.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
[root@ee3a8e2528f2 nginx-1.12.0]# make && make install
[root@ee3a8e2528f2 nginx-1.12.0]# ln -s /usr/local/nginx/sbin/* /usr/local/sbin/
[root@ee3a8e2528f2 nginx-1.12.0]# nginx
[root@ee3a8e2528f2 nginx-1.12.0]# cd /usr/local/nginx/html/
[root@ee3a8e2528f2 html]# echo This is a testweb in container > index.html
[root@ee3a8e2528f2 html]# curl 127.0.0.1
This is a testweb in container
//把容器制作成镜像
[root@docker01 ~]# docker commit webapp myweb:12-10