重学容器10: 容器仅仅是一种特殊的进程
2021-06-03
前面学习了容器运行时containerd的基本使用,containerd的架构,namespace, cgroup, rootfs等容器背后的技术。 本节做一个阶段性的小节。此时,如果有人问"容器是什么?",我们可能会给出以下的回答:
- 容器实际上是一种特殊的进程。它使用namespace进行隔离,使用cgroup进行资源限制,并且它还以联合文件系统的形式挂载了单独的rootfs。
- 为了更方便的准备运行容器所需的资源和管理容器的生命周期,还需要容器引擎如containerd。
- 容器镜像实际上就是一种特殊的文件系统,它包含容器运行所需的程序、库、资源配置等所有内容,构建后内容保持不变。在启动容器时镜像会挂载为容器的rootfs。
既然容器仅仅是一种特殊的进程,下面我们实际去探索一下它的存在。继续前面启动的redis容器为例,可以使用nerdctl inspect <container id>
和ctr c info <container id>
查看一下容器的信息。
下面的命令可以打印出容器在宿主机上的进程id:
1nerdctl inspect 8102f | grep Pid
2 "Pid": 27582,
容器作为一种特殊的操作系统进程,可以在系统的/proc/<process-id>
中感受它的存在:
1ls /proc/27582
2attr auxv clear_refs comm cpuset environ fd gid_map limits map_files mem mounts net numa_maps oom_score pagemap projid_map sched sessionid smaps stat status task uid_map
3autogroup cgroup cmdline coredump_filter cwd exe fdinfo io loginuid maps mountinfo mountstats ns oom_adj oom_score_adj personality root schedstat setgroups stack statm syscall timers wchan
/proc/27582/ns
目录下对应了容器的各个namespace:
1ll /proc/27582/ns
2total 0
3lrwxrwxrwx 1 ipc -> ipc:[4026532172]
4lrwxrwxrwx 1 mnt -> mnt:[4026532170]
5lrwxrwxrwx 1 net -> net:[4026532175]
6lrwxrwxrwx 1 pid -> pid:[4026532173]
7lrwxrwxrwx 1 user -> user:[4026531837]
8lrwxrwxrwx 1 uts -> uts:[4026532171]
/proc/27582/cgroup
文件对应了容器的11种cgroup:
1cat /proc/27582/cgroup
211:hugetlb:/default/8102f7fbee26792830e54e80b3488714ac559e092c59beb2e311cf8e88f475d6
310:perf_event:/default/8102f7fbee26792830e54e80b3488714ac559e092c59beb2e311cf8e88f475d6
49:devices:/default/8102f7fbee26792830e54e80b3488714ac559e092c59beb2e311cf8e88f475d6
58:memory:/default/8102f7fbee26792830e54e80b3488714ac559e092c59beb2e311cf8e88f475d6
67:freezer:/default/8102f7fbee26792830e54e80b3488714ac559e092c59beb2e311cf8e88f475d6
76:cpuacct,cpu:/default/8102f7fbee26792830e54e80b3488714ac559e092c59beb2e311cf8e88f475d6
85:blkio:/default/8102f7fbee26792830e54e80b3488714ac559e092c59beb2e311cf8e88f475d6
94:pids:/default/8102f7fbee26792830e54e80b3488714ac559e092c59beb2e311cf8e88f475d6
103:net_prio,net_cls:/default/8102f7fbee26792830e54e80b3488714ac559e092c59beb2e311cf8e88f475d6
112:cpuset:/default/8102f7fbee26792830e54e80b3488714ac559e092c59beb2e311cf8e88f475d6
121:name=systemd:/default/8102f7fbee26792830e54e80b3488714ac559e092c59beb2e311cf8e88f475d6
而对于rootfs
,容器是使用mount namespace实现的。mount namespace与挂载操作结合使用,处于不同mount namespace中的进程看到的是不同的挂载点视图。
这样容器进程的rootfs
就和宿主机系统以及其他容器进程隔离区分开来了。