030、實現容器的底層技術(2019-01-25 週五)

三角形發表於2019-01-29
 
 
為了更好的理解容器的特性,本節我們將討論容器的底層實現技術。
 
cgroup 和 namespace 是最重要的兩種技術。cgroup 實現資源限額namespace 實現資源隔離
 
cgroup
 
全程 Control Group 。Linux作業系統通過 cgroup 可以設定程式使用CPU、MEM 和 IO 資源的限額。就是我們前面學習的引數
    --cpu-shares
    -m
    --device-write-bps
 
root@docker-lab:~# docker run -it --cpu-shares 512 progrium/stress -c 1    #    啟動容器,設定cpu.shares 512
stress: info: [1] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogcpu worker 1 [7] forked
 
 
root@docker-lab:~# docker ps    #    檢視容器ID
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
980b3b38e444        progrium/stress     "/usr/bin/stress --v…"   About a minute ago   Up About a minute                       vigilant_mahavira
root@docker-lab:~# ls /sys/fs/cgroup/cpu/docker/    #    在cgroup目錄中查詢容器對應的目錄,容器長ID命名
980b3b38e44419fca0df8681101274a16a75a2bf426f7cfb6354a73953a42cfe  cgroup.procs  cpuacct.usage         cpu.cfs_period_us  cpu.shares  notify_on_release
cgroup.clone_children                                             cpuacct.stat  cpuacct.usage_percpu  cpu.cfs_quota_us   cpu.stat    tasks
root@docker-lab:~# cat /sys/fs/cgroup/cpu/docker/980b3b38e44419fca0df8681101274a16a75a2bf426f7cfb6354a73953a42cfe/cpu.shares    #    檢視cgroup中設定的 cpu.shares 值
512
root@docker-lab:~#
 
 
root@docker-lab:~# ll /sys/fs/cgroup/    #    檢視cgroup 中的所有內容
total 0
drwxr-xr-x 13 root root 340 Jun 14  2018 ./
drwxr-xr-x  9 root root   0 Jun 14  2018 ../
dr-xr-xr-x  6 root root   0 Jun 14  2018 blkio/
lrwxrwxrwx  1 root root  11 Jun 14  2018 cpu -> cpu,cpuacct/
lrwxrwxrwx  1 root root  11 Jun 14  2018 cpuacct -> cpu,cpuacct/
dr-xr-xr-x  6 root root   0 Jun 14  2018 cpu,cpuacct/
dr-xr-xr-x  3 root root   0 Jun 14  2018 cpuset/
dr-xr-xr-x  6 root root   0 Jun 14  2018 devices/
dr-xr-xr-x  3 root root   0 Jun 14  2018 freezer/
dr-xr-xr-x  3 root root   0 Jun 14  2018 hugetlb/
dr-xr-xr-x  6 root root   0 Jun 14  2018 memory/
lrwxrwxrwx  1 root root  16 Jun 14  2018 net_cls -> net_cls,net_prio/
dr-xr-xr-x  3 root root   0 Jun 14  2018 net_cls,net_prio/
lrwxrwxrwx  1 root root  16 Jun 14  2018 net_prio -> net_cls,net_prio/
dr-xr-xr-x  3 root root   0 Jun 14  2018 perf_event/
dr-xr-xr-x  6 root root   0 Jun 14  2018 pids/
dr-xr-xr-x  6 root root   0 Jun 14  2018 systemd/
root@docker-lab:~# ll /sys/fs/cgroup/cpu/docker/980b3b38e44419fca0df8681101274a16a75a2bf426f7cfb6354a73953a42cfe/    #    檢視容器 cgroup cpu 相關內容
total 0
drwxr-xr-x 2 root root 0 Jan 29 09:28 ./
drwxr-xr-x 3 root root 0 Jan 29 09:20 ../
-rw-r--r-- 1 root root 0 Jan 29 09:26 cgroup.clone_children
-rw-r--r-- 1 root root 0 Jan 29 09:20 cgroup.procs
-r--r--r-- 1 root root 0 Jan 29 09:22 cpuacct.stat
-rw-r--r-- 1 root root 0 Jan 29 09:22 cpuacct.usage
-r--r--r-- 1 root root 0 Jan 29 09:22 cpuacct.usage_percpu
-rw-r--r-- 1 root root 0 Jan 29 09:22 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 Jan 29 09:22 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 Jan 29 09:20 cpu.shares
-r--r--r-- 1 root root 0 Jan 29 09:22 cpu.stat
-rw-r--r-- 1 root root 0 Jan 29 09:26 notify_on_release
-rw-r--r-- 1 root root 0 Jan 29 09:26 tasks
root@docker-lab:~# ll /sys/fs/cgroup/memory/docker/980b3b38e44419fca0df8681101274a16a75a2bf426f7cfb6354a73953a42cfe/    #    檢視容器 cgroup memory 相關內容
total 0
drwxr-xr-x 2 root root 0 Jan 29 09:28 ./
drwxr-xr-x 3 root root 0 Jan 29 09:20 ../
-rw-r--r-- 1 root root 0 Jan 29 09:27 cgroup.clone_children
--w--w--w- 1 root root 0 Jan 29 09:20 cgroup.event_control
-rw-r--r-- 1 root root 0 Jan 29 09:20 cgroup.procs
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.failcnt
--w------- 1 root root 0 Jan 29 09:27 memory.force_empty
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.kmem.failcnt
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.kmem.max_usage_in_bytes
-r--r--r-- 1 root root 0 Jan 29 09:27 memory.kmem.slabinfo
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.kmem.tcp.failcnt
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.kmem.tcp.max_usage_in_bytes
-r--r--r-- 1 root root 0 Jan 29 09:27 memory.kmem.tcp.usage_in_bytes
-r--r--r-- 1 root root 0 Jan 29 09:27 memory.kmem.usage_in_bytes
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.memsw.failcnt
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.memsw.limit_in_bytes
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.memsw.max_usage_in_bytes
-r--r--r-- 1 root root 0 Jan 29 09:27 memory.memsw.usage_in_bytes
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.move_charge_at_immigrate
-r--r--r-- 1 root root 0 Jan 29 09:27 memory.numa_stat
-rw-r--r-- 1 root root 0 Jan 29 09:20 memory.oom_control
---------- 1 root root 0 Jan 29 09:27 memory.pressure_level
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 Jan 29 09:27 memory.stat
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.swappiness
-r--r--r-- 1 root root 0 Jan 29 09:27 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 Jan 29 09:27 memory.use_hierarchy
-rw-r--r-- 1 root root 0 Jan 29 09:27 notify_on_release
-rw-r--r-- 1 root root 0 Jan 29 09:27 tasks
root@docker-lab:~# ll /sys/fs/cgroup/devices/docker/980b3b38e44419fca0df8681101274a16a75a2bf426f7cfb6354a73953a42cfe/    #    檢視容器 cgroup devices  相關內容
total 0
drwxr-xr-x 2 root root 0 Jan 29 09:29 ./
drwxr-xr-x 3 root root 0 Jun 14  2018 ../
-rw-r--r-- 1 root root 0 Jan 29 09:29 cgroup.clone_children
-rw-r--r-- 1 root root 0 Jan 29 09:20 cgroup.procs
--w------- 1 root root 0 Jan 29 09:20 devices.allow
--w------- 1 root root 0 Jan 29 09:20 devices.deny
-r--r--r-- 1 root root 0 Jan 29 09:29 devices.list
-rw-r--r-- 1 root root 0 Jan 29 09:29 notify_on_release
-rw-r--r-- 1 root root 0 Jan 29 09:29 tasks
root@docker-lab:~# ll /sys/fs/cgroup/blkio/docker/980b3b38e44419fca0df8681101274a16a75a2bf426f7cfb6354a73953a42cfe/    #    檢視容器 cgroup blkio 相關內容
total 0
drwxr-xr-x 2 root root 0 Jan 29 09:29 ./
drwxr-xr-x 3 root root 0 Jan 29 09:20 ../
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.io_merged
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.io_merged_recursive
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.io_queued
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.io_queued_recursive
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.io_service_bytes
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.io_service_bytes_recursive
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.io_serviced
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.io_serviced_recursive
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.io_service_time
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.io_service_time_recursive
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.io_wait_time
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.io_wait_time_recursive
-rw-r--r-- 1 root root 0 Jan 29 09:29 blkio.leaf_weight
-rw-r--r-- 1 root root 0 Jan 29 09:29 blkio.leaf_weight_device
--w------- 1 root root 0 Jan 29 09:29 blkio.reset_stats
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.sectors
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.sectors_recursive
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.throttle.io_service_bytes
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.throttle.io_serviced
-rw-r--r-- 1 root root 0 Jan 29 09:29 blkio.throttle.read_bps_device
-rw-r--r-- 1 root root 0 Jan 29 09:29 blkio.throttle.read_iops_device
-rw-r--r-- 1 root root 0 Jan 29 09:29 blkio.throttle.write_bps_device
-rw-r--r-- 1 root root 0 Jan 29 09:29 blkio.throttle.write_iops_device
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.time
-r--r--r-- 1 root root 0 Jan 29 09:29 blkio.time_recursive
-rw-r--r-- 1 root root 0 Jan 29 09:29 blkio.weight
-rw-r--r-- 1 root root 0 Jan 29 09:29 blkio.weight_device
-rw-r--r-- 1 root root 0 Jan 29 09:29 cgroup.clone_children
-rw-r--r-- 1 root root 0 Jan 29 09:20 cgroup.procs
-rw-r--r-- 1 root root 0 Jan 29 09:29 notify_on_release
-rw-r--r-- 1 root root 0 Jan 29 09:29 tasks
 
 
 
namespace
 
在每個容器中,我們都可以看到檔案系統、網路卡等資源,這些資源看上去是容器自己的。拿網路卡來說,每個容器都會認為自己有一塊獨立的網路卡,及時docker host上只有一個塊物理網路卡。這種方式非常好,他使得容器更像一個獨立的計算機。
 
Linux實現這種方式的技術是namespace,namespace管理著docker host中全域性唯一的資源,並可以讓每個容器都覺得只有自己在使用他。換句話說,namespace實現了容器間的資源隔離
 
Linux使用了六種namespace,分別對應六種資源: mount、UTS、IPC、PID、Network、User。
 
Mount namespace
 
它使得容器看上去擁有整個檔案系統
 
容器有自己的 / 目錄,可以執行mount 和 unmount命令。當然我們知道這些作業系統只在當前容器中生效,不會影響到 docker host 和其他容器。
 
UTS namespace
 
簡單的說,UTS namespace讓容器有自己的hostname 。預設情況下,容器的hostname 是他的短ID,可以通過 -h 或者 --hostname 引數設定
 
IPC namespace
 
它可以讓容器擁有自己的共享記憶體和訊號量(semaphore)來實現程式間通訊,而不會與docker host和其他容器的IPC混在一起。
 
下面例子可以看到所有容器的程式都掛載 dockerd 程式下面,同時也可以看到容器自己的子程式。如果我們進入到容器中,使用ps命令只能看到自己的程式
 
root@docker-lab:~# docker run -d httpd
48ec7932db1c5c27a194b15b3a3c1349a5d43d9260661b381d1563092ed941b6
root@docker-lab:~#
root@docker-lab:~# docker run -d nginx
37a75b3a9bd9ad07fb07bff04b6df16e3cb693e47ffb87a1184d1b8f975e8b6d
 
root@docker-lab:~# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
37a75b3a9bd9        nginx               "nginx -g 'daemon of…"   25 seconds ago      Up 25 seconds       80/tcp              compassionate_chatterjee
48ec7932db1c        httpd               "httpd-foreground"       32 seconds ago      Up 32 seconds       80/tcp              amazing_banach
root@docker-lab:~# ps axf
 
24323 ?        Ssl   71:17 /usr/bin/dockerd -H fd:// -H tcp://0.0.0.0
24336 ?        Ssl  149:45  \_ docker-containerd --config /var/run/docker/containerd/containerd.toml
27680 ?        Sl     0:00      \_ docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/48ec7932db1c5c27a194b15b3a3c1349a5d4
27712 ?        Ss     0:00      |   \_ httpd -DFOREGROUND
27759 ?        Sl     0:00      |       \_ httpd -DFOREGROUND
27760 ?        Sl     0:00      |       \_ httpd -DFOREGROUND
27761 ?        Sl     0:00      |       \_ httpd -DFOREGROUND
27954 ?        Sl     0:00      \_ docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/37a75b3a9bd9ad07fb07bff04b6df16e3cb6
27989 ?        Ss     0:00          \_ nginx: master process nginx -g daemon off;
28033 ?        S      0:00              \_ nginx: worker process
 
 
Network namespace
 
Network namespace 讓容器擁有自己的獨立的網路卡、IP、路由等資源。
 
User namespace
 
他讓容器能夠管理自己的使用者,docker host 不能看到容器中建立的使用者
 

 
容器常用命令總結
 
create        建立
run             建立+啟動
pause         暫停
unpause    恢復
stop           停止
kill             殺掉
start          啟動
restart       重啟
start          啟動
attach       進入容器啟動的終端
exec          在容器中啟動新的程式,通常使用 -it
logs           顯示容器啟動程式的控制檯輸出 用-f 持續列印
rm             刪除
 

相關文章