docker基础学习总结

docker基础学习总结

抽时间从网上找资料学习了docker基本知识,做了这个总结,总结有点乱,仅作为啥时忘了什么操作看看这篇文章温习一下之目的。

一:容器基本知识
1 容器隔离:UTS隔离,mount隔离,IPC隔离,PID隔离,用户用户组隔离,网络隔离。容器里边的进程PID彼此也是隔离的。容器IPC在内核里实现,容器里边的进程可以彼此通信,容器与容器之前的进程不能同喜。这些隔离通过namespace实现,setns()这个系统调用,把内核的线程放到容器里

2 LXC:linux container,容器引擎,把完整的容器技术用一组简易工具和模板,极大简化了容器使用的一个方案,否则得手动执行serns()进行UTS隔离,mount隔离,IPC隔离,PID隔离,用户用户组隔离,网络隔离,LXC把这些全做了

3 LXC 有个缺点,把容器迁移到其他宿主机上很难,批量部署容器也很难。早期docker的出现为了弥补这个缺点,是LXC的二次封装(1-52),把一个容器需要文件系统打包成镜像,直接使用,基于镜像启动容器,docker极大简化了容器的使用难度。大部分用到的容器镜像在docker仓库都有,直接下载,run就能用。一个容器只运行一个业务进程,LXC把一个容器当成一个独立的用户空间

4 容器就是启动一个进程,容器停止了,进程就没了,容器不需要持久

5 新版的容器引擎是libcontainer,即runC ,遵循容器运行时的标准,OCI

二:容器安装

下载 docker ce开源版
yum repolist 看到的extras 这个仓库中有docker

vim /etc/yum.repos.ddocker-ce.repo
%s@https://download.docker.com/@https://mirrors.tuna.tsinghua.edu.cn/docker-ce/@
dokcer默认下载源替换为清华大学yum源,加快下载速度

修改完后 yum repolist可以看到
docker-ce-stable/x86_64 Docker CE Stable - x86_64 79
之后运行yum install docker-ce一次性自动安装完成了
docker-ce.x86_64 3:19.03.12-3.el7
container-selinux.noarch 2:2.119.2-1.911c772.el7_8
containerd.io.x86_64 0:1.2.13-3.2.el7
docker-ce-cli.x86_64 1:19.03.12-3.el7

下载完成后,执行systemctl start docker.service 启动docker服务

手动下载安装的话,登录,非常麻烦,破事特别多
https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/Packages/docker-ce-17.12.1.ce-1.el7.centos.x86_64.rpm

为了提高从docker hub来去镜像的速度,要用镜像加速器 docker cn
/etc/docker/ daemon.json 文件"registry-mirrors":必须是空格,否则导致systemctl start docker失败
{
“registry-mirrors”: [“https://registry.docker-cn.com”,“http://hub-mirror.c.163.com”]
}
配置 https://registry.docker-cn.com 这样从docker官网拉镜像网速很快

codker hub上docker tag有alpine,说明这是精简的docker镜像

三:docker基本操作命令

docker search busybox 搜索docker官网的busybox容器
docker image pull busybox 拉最新镜像
docker image pull busybox:1.14 指定版本
docker image ls 显示当前已有的镜像
docker image rm busybox
docker image ls --no-trunc 显示docker镜像的完整sha值

docker container 创建/删除/启动/停止/运行/查看/暂停 容器

docker run –-name busybox_hu -it -rm busybox 启动busybox容器,it交互模式

docker ps 查看运行的容器
docker inspect busybox_hu 查看容器更详细的信息
exit 停止容器
docker ps –a 查看停止的busybox容器
docker start -i –a busybox_hu 启动停止的容器
docker kill busybox_hu 强制容器停止,沙雕,stop退出容器
docker rm busybox_hu 彻底删除容器

docker image pull redis:5.0.9-alpine
docker run --name redis_hu -d redis:5.0.9-alpine 后台运行redis容器里的redis_server,这种容器没有shell吧,所以不能直接-it指定交互???,reids容器只是一个简单的进程,没有shell,需要指定shell才能交互。

docker inspect busybox 后可以看到容器的启动命令

“Cmd”:
[
“sh”
],
docker inspect redis
“Cmd”:
[
“/bin/sh”,
“-c”,
“$STI_SCRIPTS_PATH/usage”
],

docker exec -it redis_hu /bin/sh 与正在运行的redis容器开始交互,交互shell是/bin/sh
docker rm redis_hu //删除容器后才能重新run
docker run --name redis_hu -d redis:5.0.9-alpine
docker logs redis_hu 查看容器运行日志

四:容器文件系统

容器最底层的文件系统称为bootfs,lxc、aufs、averlayfs,devicemapper,bootfs引导完容器会被卸载移除系统

在bootfs之上,是rootfs,这个就是容器的根文件系统。容器的根文件系统始终只读,可以通过联合挂载额外挂载一个读写层。好像Centos启动时,先是把rootfs挂载成只读,自检后重新挂载成读写吧。

容器里文件系统分了多层,最上一层的可写层,才允许写。为了支持多层文件系统,必须用分层文件系统,多用overlay2fs,这是一个抽象文件系统,需要建立在ext4之上。

除了docker hub,还有其他的站点下载docker镜像,比如quay,此时需要特别指明站点,因为默认站点是docker hub

Docker pull quay.io/coreos/flannel:v0.10.0-armd64
quay.io: redistry站点
coreos:命名空间
flannel:仓库

五:制作容器镜像

启动进去busybox那个docker,然后mkdir /data/hu –p和touch /data/hu/test,

busybox_hu 要保持运行,不能停止
Docker commit -p busybox_hu制作新镜像
docker image ls
Docker tag 51c3a825e088 busybox/tag:0.1.1 打标签
Docker tag busybox/tag:0.1.1 busybox/tag:latest 再打标签
如果标签错了,还可以docker image rm busybox/tag:latest 然后再重新制作

docker run --name busybox_b2 -it busybox/tag:latest 运行自己制作的镜像,即可看到自己创建的目录,注意

docker comit –c ‘CMD [“/bin/http”,”-f”,”/data/test”]’ –p busybox_hu
这样制作的容器,默认的启动命令CMD不再是shell
Docker container ls 可以查看每个容器的CMD,即默认启动命令

镜像制作后,可以传到网上
在docker hub创建于新的容器一致的标签,标签要一致
Docker login -u mag…
Docker push busybox:… 把镜像推送到了仓库

还可以镜像的导入和导出
docker save -o image.gz busybox/tag:v1.1.0 busybox:latest
把过个容器打包压缩,拷贝到另外的机器上
docker load –i image.gz
docker image ls 就可以看到导入的两个镜像

六:容器存储卷

docker run --name busybox_hu --rm -it -v /data busybox
-v指定docker运行时的一个目录,–rm指定docker运行停止后就删除,一定要这样操作
并且busybox 一定要放到最后边,否则会报错docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused “exec: “-v”: executable file not found in $PATH”: unknown. 也是服了

docker image rm -f busybox_hu 容器有关联关系时,强制删除

之后容器与物理机共享目录,是docker自动在物理机上创建的,如这个宿主机目录
/var/lib/docker/volumes/d81d8bdb34dd24ebc3331c46053b147c24b465d8d9bbf92ef86c480897da9bef/_data/

docker inspect busybox_hu “Mounts” 能看到容器和物理目录映射的详细信息

这是特别指定物理机和容器的绑定目录
docker run --name busybox_hu --rm -it -v /home/docker_test/:/data busybox

这是新创建一个容器,但是存储卷复制了busybox_hu的
docker run --name busybox_hu2 -it --rm --volumes-from busybox_hu busybox

这是新创建一个容器,但是网络和存储卷都复制了busybox_hu的
docker run --name busybox_hu3 -it --rm --network container:busybox_hu --volumes-from busybox_hu busybox

docker ps –a 退出的容器也能看到

docker inspect 只查看一项信息
[root@localhost _data]# docker inspect -f {{.Mounts}} busybox_hu
[{bind /home/docker_test /data true rprivate}]
ocalhost _data]# docker inspect -f {{.NetworkSettings.IPAddress}} busybox_hu
172.17.0.2

七:存储卷的补充
Docker存储卷,说白了就是容器中的一个或者多个目录,绕开docker本身根文件系统,与宿主机之上的目录建立绑定关系。
Docker 存储卷,默认在容器删除时,实现数据持久化。但是通过特定的命令,也可以删除data valume

Docker存储卷有两种类型:
与物理机目录bind形成的volume, 如docker run –it --name busybox –v /home/test:data busybox;
docker manage volume,由docker自动管理的,只用指定容器中的目录,dockker自动在/var/lib/docker/指定一个随机目录,用户无法指定目录,docker run –it --name busybox –v data busybox. /var/lib/docker/volumes/4e2086eafe9894b489d69f74cc0580c32a3cc7062cce2ffc3e77322b584927ee/_data busybox 就是docker随机选择的,4e2086eafe9894b489d69f74cc0580c32a3cc7062cce2ffc3e77322b584927ee 是卷ID

“Mounts”: [
{
“Type”: “volume”,
“Name”: “4e2086eafe9894b489d69f74cc0580c32a3cc7062cce2ffc3e77322b584927ee”,
“Source”: “/var/lib/docker/volumes/4e2086eafe9894b489d69f74cc0580c32a3cc7062cce2ffc3e77322b584927ee/_data”,
“Destination”: “data”,
“Driver”: “local”,
“Mode”: “”,
“RW”: true,
“Propagation”: “”
}
],

[root@localhost ~]# docker inspect -f {{.Mounts}} ea367ab53172
[{volume 4e2086eafe9894b489d69f74cc0580c32a3cc7062cce2ffc3e77322b584927ee /var/lib/docker/volumes/4e2086eafe9894b489d69f74cc0580c32a3cc7062cce2ffc3e77322b584927ee/_data data local true }]
直接查看mount信息
06-40

docker inspect -f {{.NetworkSetting.IPAddress}} ea367ab53172
docker inspect只接获取IP地址
Joined Containers,一个基础容器,其他容器在它基础上赋值基础容器的存储卷,网络
docker run –it --name busybox –network container:busybox_hu --volumes-from busybox_hu busybox
赋值busybox_hu的网络和存储卷

八:设置容器中进程cpu使用率

–cpu-shared 两个进程1024:512分配一个 CPU,按照2:1的比例分配,在两个进程争抢CPU时才按照2:1的比例分配一个CPU,如果后一个进程不用CPU了,另一个进程则可以使用100%的CPU。如果有2个核心,则这个进程可以使用200%的CPU。Cpu-shared只有进程争抢CPU时才生效。总的CPU资源要看分配的CPU个数,2个CPU,就是把200%的CPU按照比例分配。

–cpus 指定容器最多使用的CPU个数,可以半个CPU

–cpuset-cpus 0,1 限制容器只能在CPU0和CPU1上运行

docker pull lorel/docker-stress-ng //获取stresss CPU性能测试工具
docker run lorel/docker-stress-ng -–help //这样直接获取容器的帮助
docker top busybox_hu //查看容器资源
docker stats //查看所有容器资源使用
docker run --name stress -it --rm -m 256m lorel/docker-stress-ng stress -vm 5 //内存使用进行压测
//限制只有两个CPU,256M内存,但是stress使用8个进程,6*256M的虚拟内存,这样使CPU和内存使用超出限制
docker run --name stress -it --rm -m 256m --cpus 2 lorel/docker-stress-ng stress --cpu 8 --vm 6

找到压测进程ID是13048
13048 root 20 0 6908 996 256 R 57.1 0.0 0:38.71 stress-ng-cpu

cat /proc/13048/cgroup 找到 容器ID,也可以inspect看到

4:memory:/docker/bb4cf4e4b2238ff9c24eaaacdacfea711cc92f2fe6abce97a70b16f2e063fc9e
3:cpuset:/docker/bb4cf4e4b2238ff9c24eaaacdacfea711cc92f2fe6abce97a70b16f2e063fc9e
2:cpuacct,cpu:/docker/bb4cf4e4b2238ff9c24eaaacdacfea711cc92f2fe6abce97a70b16f2e063fc9e   

根据容器ID找出容器的内存限制
cat /sys/fs/cgroup/memory/docker/bb4cf4e4b2238ff9c24eaaacdacfea711cc92f2fe6abce97a70b16f2e063fc9e/memory.limit_in_bytes

根据容器ID找出容器cgroup限制的进程
cat /sys/fs/cgroup/cpuset/docker/bb4cf4e4b2238ff9c24eaaacdacfea711cc92f2fe6abce97a70b16f2e063fc9e/tasks

docker run -it --name stress --cpus 1 lorel/docker-stress-ng stress --cpu 6 启动CPU测试,只使用一个核,6个线程
stress的CPU使用率是50%
根据进入容器ID cpuset目录

cd /sys/fs/cgroup/cpuset/docker/ca3720b10d18b47ab618a9846ffd504db44b7c51f16712b74fa11ed4a06986fc/
cat cpuset.cpus
    0-3
echo 0-1 >  cpuset.cpus
  0-1

[root@localhost ca3720b10d18b47ab618a9846ffd504db44b7c51f16712b74fa11ed4a06986fc]# cat  cpu.cfs_period_us 
100000
[root@localhost ca3720b10d18b47ab618a9846ffd504db44b7c51f16712b74fa11ed4a06986fc]# cat cpu.cfs_quota_us 
100000

cpu.cfs_period_us是运行周期(微秒),默认为100000,即百毫秒,即100ms。cpu.cfs_quota_us就是在这期间内可使用的cpu时间(微秒),默认-1,即无限制。现在是100ms。

echo 50000 >cpu.cfs_quota_us 后
stress 容器 CPU使用率变为50%
echo 200000 > cpu.cfs_quota_us
stress容器 CPU使用率变为200%

echo 200000 > cpu.cfs_period_us
stress容器 CPU使用率变为100%
echo 100000 > cpu.cfs_quota_us
stress容器 CPU使用率变为50%
echo 500000 > cpu.cfs_period_us
echo 500000 > cpu.cfs_quota_us
stress容器 CPU使用率变为200%,看来最多只能使用两个CPU

top显示stress里的容器均分这200%的CPU,容器中的进程均分分配的总的CPU资源

8775 root      20   0    6908   2144    252 R  33.2  0.1  36:23.54 stress-ng-cpu                                                                                                        
 8776 root      20   0    6908   2144    252 R  33.2  0.1  36:29.90 stress-ng-cpu                                                                                                        
 8777 root      20   0    6908   2144    252 R  33.2  0.1  35:44.76 stress-ng-cpu                                                                                                        
 8778 root      20   0    6908   2144    252 R  33.2  0.1  35:49.92 stress-ng-cpu                                                                                                        
 8779 root      20   0    6908   2144    252 R  33.2  0.1  36:19.20 stress-ng-cpu                                                                                                        
 8780 root      20   0    6908   2144    252 R  33.2  0.1  35:21.24 stress-ng-cpu

echo 0 > /sys/fs/cgroup/cpuset/docker/ca3720b10d18b47ab618a9846ffd504db44b7c51f16712b74fa11ed4a06986fc/cpuset.cpus
设置只能使用1个CPU后,stress容器CPU使用率是100%,毕竟限制了最多只能使用1个CPU,最多只有100%

如果我想让stress容器CPU使用率大于200%,该怎么设置

docker run -it --name stress2 --cpus 2 lorel/docker-stress-ng stress --cpu 6
设置可以最大2核,6个线程

[root@localhost 225097c88d3bd08c6d52950f04c2fba3218969d1dffc7295837864e5489e4c19]# top
top - 16:37:41 up  5:30,  7 users,  load average: 1.59, 3.18, 3.81
Tasks: 236 total,   8 running, 228 sleeping,   0 stopped,   0 zombie
%Cpu0  : 47.2 us,  0.9 sy,  0.0 ni, 51.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  : 48.1 us,  0.9 sy,  0.0 ni, 50.0 id,  0.0 wa,  0.0 hi,  0.9 si,  0.0 st
%Cpu2  : 47.2 us,  0.9 sy,  0.0 ni, 50.9 id,  0.0 wa,  0.0 hi,  0.9 si,  0.0 st
%Cpu3  : 48.1 us,  0.0 sy,  0.0 ni, 51.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

由于没有cpuset限制在哪些CPU上,所以是4个CPU集合下来总CPU达到200%
有一个更神奇的发现

cd  /sys/fs/cgroup/cpu,cpuacct/docker/a4310e21800ec7f6fa2f888fa06d5b79fbfee86e124034b0826cce17a0ec3d0b
cat cpu.cfs_period_us 
100000
cat cpu.cfs_quota_us 
200000

如果运行busybox不设置cpuset和cpus,那cpu.cfs_quota_us是-1。如果只指定cpus=1,那cpu.cfs_quota_us是100000,如果cpus=2,则cpu.cfs_quota_us就是现在看到的200000。原来docker cpus=2 这些是通过cpu.cfs_quota_us 实现的使用多少个CPU呀?

docker run -it --rm --name stress3 --cpus 3 lorel/docker-stress-ng stress --cpu 6 指定3个cpu
[root@localhost a61d822725900f8e196d1c2067eb0f10b143bb5ac5e31d23211690293ad9857f]# cat cpu.cfs_period_us
100000
[root@localhost a61d822725900f8e196d1c2067eb0f10b143bb5ac5e31d23211690293ad9857f]# cat cpu.cfs_quota_us
300000
看来真是这样了

top
top - 16:49:26 up  5:42,  7 users,  load average: 3.19, 2.80, 3.30
Tasks: 237 total,   7 running, 230 sleeping,   0 stopped,   0 zombie
%Cpu0  : 72.9 us,  0.3 sy,  0.0 ni, 26.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  : 74.9 us,  0.0 sy,  0.0 ni, 25.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  : 74.5 us,  0.7 sy,  0.0 ni, 24.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  : 74.0 us,  0.3 sy,  0.0 ni, 25.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  3871288 total,  2871840 free,   469328 used,   530120 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.  3097544 avail Mem 
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                              
15114 root      20   0    6908   3924    252 R  66.8  0.1   1:42.18 stress-ng-cpu                                                                                                        
15113 root      20   0    6908   3924    252 R  52.5  0.1   1:39.64 stress-ng-cpu                                                                                                        
15109 root      20   0    6908   3924    252 R  49.8  0.1   1:35.08 stress-ng-cpu                                                                                                        
15110 root      20   0    6908   3924    252 R  49.2  0.1   1:40.63 stress-ng-cpu                                                                                                        
15111 root      20   0    6908   3924    252 R  41.2  0.1   1:40.43 stress-ng-cpu                                                                                                        
15112 root      20   0    6908   3924    252 R  40.2  0.1   1:42.55 stress-ng-cpu
echo 100000 > cpu.cfs_quota_us 
echo 200000 > cpu.cfs_quota_us   
echo 300000 > cpu.cfs_quota_us  
echo 400000 > cpu.cfs_quota_us

设置不同的cpu.cfs_quota_us,docker stress的CPU使用率跟着变化。
[root@localhost a61d822725900f8e196d1c2067eb0f10b143bb5ac5e31d23211690293ad9857f]# cat cpuset.cpus
0-3
echo 400000 > cpu.cfs_quota_us 后
[root@localhost a61d822725900f8e196d1c2067eb0f10b143bb5ac5e31d23211690293ad9857f]# echo 0-2 > cpuset.cpus
Docker stress的CPU使用率由400%变为300%,因为最多只能使用3个CPU
[root@localhost a61d822725900f8e196d1c2067eb0f10b143bb5ac5e31d23211690293ad9857f]# echo 0-1 > cpuset.cpus
Docker stress的CPU使用率由300%变为200%,因为最多只能使用2个CPU

总结
1 cpuset.cpus 限制容器总的CPU个数,配置3个CPU,那容器最多进程使用率只有300%
2 cpu.cfs_period_us 设置容器进程总的运行周期,一般是100000,即100ms。cpu.cfs_quota_us 是容器进程实际运行时间,可以大于cfs_period_us,如果200000,那容器进程CPU使用率达到200%。
3 如果cpuset.cpus配置2个CPU,cfs_period_us是300000,那容器进程CPU使用率是200%,最多两个CPU。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值