Docker
对Docker来说,负责响应这个请求的就是一个叫作 dockershim 的组件,它把 CRI 请求里的内容拿出来,然后组装成 Docker API 请求发给 Docker Daemon。对于别的容器项目来说,扮演shim角色的组件统称为CRI-shim,可见,CRI-shim就是实现CRI中定义的每一个接口,然后把具体的 CRI 请求“翻译”成对后端容器项目的请求或者操作。
注意一点的是,我们在部署docker时并没有部署这个docker-shim组件,docker-shim代码是包含在kubelet中的,但是其它的容器项目,就需要在hosts中部署自己的CRI-shim了。
Docker项目是C/S架构,Docker client端发送请求给docker daemon采用root用户运行在host上,通过socket进行通信,docker daemon接收创建容器的请求再发送给containerd,容器进程是docker daemon的子进程,而不是dockerCLI的子进程。
可以通过查看进程树
# pstree -p
systemd(1)-+-agetty(3596)
|-crond(25481)
|-dbus-daemon(3498)
|-dhclient(3744)
|-dockerd(8050)-+-containerd(8062)-+-containerd-shim(7104)-+-pause(7123)
| | | |-{containerd-shim}(7105)
| | | |-{containerd-shim}(7106)
| | | |-{containerd-shim}(7107)
| | | |-{containerd-shim}(7108)
| | | |-{containerd-shim}(7109)
| | | |-{containerd-shim}(7110)
| | | |-{containerd-shim}(7111)
| | | |-{containerd-shim}(7112)
| | | |-{containerd-shim}(7152)
| | | `-{containerd-shim}(8816)
| | |-containerd-shim(7327)-+-containerd(17056)-+-{containerd}(17061)
| | | | |-{containerd}(17062)
| | | | |-{containerd}(17063)
| | | | |-{containerd}(17064)
| | | | |-{containerd}(17067)
| | | | `-{containerd}(17068)
CRI-containerd
CNCF的containerd就是充当了CRI-shim的角色,kubelet调用CRI,containerd响应CRI请求,进而调用runc创建容器,runc才是真正通过设置namesapce,cgroup,chroot的创建容易的幕后英雄。
CRI-O的范围
CRI-O的目的是提供一种在OCI一致的运行时和kubelet之间的集成方式,它实现了kubelet容器运行时的接口,CRI-O的范围与CRI的范围相关。
从更高的角度来看,CRI-O能够在一下功能发展的更加严格规范:
- 支持更多image的格式包括目前使用的docker image的格式;
- 支持更多的方式来下载image包括对image的可信和验证;
- 容器镜像管理(管理image的层,文件系统);
- 容器进程的生命周期管理;
- CRI所需求的monitoring和logging;
- CRI需求的资源隔离
CRI-O不关心的事情
- building和singing和pushing容器镜像到不同的镜像库中;
- 一个通用的用户可使用的CLI来与CRI-O进行交互,任何CLI工具的开发都是用来测试使用的,在此项目中不进行维护。
实战篇
如何安装CRI-O
root@cri-o-1:~# sudo apt-add-repository ppa:projectatomic/ppa
More info: https://launchpad.net/~projectatomic/+archive/ubuntu/ppa
Press [ENTER] to continue or ctrl-c to cancel adding it
gpg: keyring `/tmp/tmp2p9fajjs/secring.gpg' created
gpg: keyring `/tmp/tmp2p9fajjs/pubring.gpg' created
gpg: requesting key 7AD8C79D from hkp server keyserver.ubuntu.com
gpg: /tmp/tmp2p9fajjs/trustdb.gpg: trustdb created
gpg: key 7AD8C79D: public key "Launchpad PPA for Project Atomic" imported
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
OK
root@cri-o-1:~# sudo apt-get update -qq
root@cri-o-1:~# sudo apt-get install cri-o-1.15
CRI-O 目前支持的功能
- Pod和container的lifecycle
- Image lifecycle
- CNI网络集成
- Logging
- Exec(sync/streaming)
- Attach/Detach
- Port forwarding
- OOM 检测和汇报
- daemon 重启
- 支持多种存储插件(overlay,devicemapper,aufs,btrfs)
- Selinux
- Seccomp
13.清除容器 - 支持runc
- Gpg check on image pull
- Mixed runtimes (runc and Clear Containers)
如何调试container
使用runc list
可以列出当前环境中所有的container,ID表示containerID PID表示容器的进程ID,其中stopped的容器进程ID为0。
[root@master0 ~]# runc list
ID PID STATUS BUNDLE CREATED OWNER
000d9eb1fd510da73ce8c5cd12223c9bfcc343f465b8b9a04028c59b85b2f8a9 0 stopped /run/containers/storage/overlay-containers/000d9eb1fd510da73ce8c5cd12223c9bfcc343f465b8b9a04028c59b85b2f8a9/userdata 2019-11-11T08:53:39.787606019Z root
016e7b606545ed6479b45cc111b58a20f54f6c0064cdb34ba0e56da6715ae6be 0 stopped /run/containers/storage/overlay-containers/016e7b606545ed6479b45cc111b58a20f54f6c0064cdb34ba0e56da6715ae6be/userdata 2019-11-12T06:14:14.549141586Z root
03ff0c15e16ae3a23ab657e60ff567041e58d3430c24d679378b850e6a94ba27 31456 running /run/containers/storage/overlay-containers/03ff0c15e16ae3a23ab657e60ff567041e58d3430c24d679378b850e6a94ba27/userdata 2019-11-11T08:59:08.850697068Z root
042ed31210e8d51c514e93d08f353c5165064d78367e099998b2e5d3bd59b986 0 stopped /run/containers/storage/overlay-containers/042ed31210e8d51c514e93d08f353c5165064d78367e099998b2e5d3bd59b986/userdata 2019-11-11T08:52:59.286627769Z root
05303f0aa04026cad3d216389278ce12d4e5cbb44141703e8e2cb54c7850e628 39237 running /run/containers/storage/overlay-containers/05303f0aa04026cad3d216389278ce12d4e5cbb44141703e8e2cb54c7850e628/userdata 2019-11-12T06:13:43.119771581Z root
058a9282710ed7cd2aac5647648530b42fa084496e850f0ba1e1dab15432d7bc 0 stopped /run/containers/storage/overlay-containers/058a9282710ed7cd2aac5647648530b42fa084496e850f0ba1e1dab15432d7bc/userdata 2019-11-11T08:55:57.856985896Z root
072fc279b2a9bc7f5b3f62412b32b96860f49e9641f308a2da4d3303a2607ba7 26299 running /run/containers/storage/overlay-containers/072fc279b2a9bc7f5b3f62412b32b96860f49e9641f308a2da4d3303a2607ba7/userdata 2019-11-12T03:55:27.859988398Z root
07542e2fd225ce3faa757a22edf8a62bc90befe521fa93ac2d7a4b65121e946d 1868 running /run/containers/storage/overlay-containers/07542e2fd225ce3faa757a22edf8a62bc90befe521fa93ac2d7a4b65121e946d/userdata 2019-11-11T08:51:47.300206259Z root
通过containerID我们可以查看container的监控进程:
[root@master0 ~]# ps -ef | grep f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381
root 27881 1 0 Nov11 ? 00:00:00 /usr/libexec/crio/conmon -s -c f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381 -n k8s_node-exporter_node-exporter-cbkqp_openshift-monitoring_5b772849-0461-11ea-9404-00000a100c0b_0 -u f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381 -r /usr/bin/runc -b /var/run/containers/storage/overlay-containers/f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381/userdata -p /var/run/containers/storage/overlay-containers/f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381/userdata/pidfile -l /var/log/pods/openshift-monitoring_node-exporter-cbkqp_5b772849-0461-11ea-9404-00000a100c0b/node-exporter/0.log --exit-dir /var/run/crio/exits --socket-dir-path /var/run/crio --log-level error
root 94094 49040 0 02:52 pts/0 00:00:00 grep --color=auto f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381
conmon会负责为每一个container起一个进程来监控容器额定运行,从它的启动参数我们可以看出,它会监控容器的log,socket信息,退出信息,还可以通过pidfile查看监控进程所监控的容器的服务进程ID:
#cat /var/run/containers/storage/overlay-containers/f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381/userdata/pidfile
27913
查看容器的服务进程:
[root@master0 ~]# ps -ef | grep 27913
nobody 27913 27881 0 Nov11 ? 00:22:00 /bin/node_exporter --web.listen-address=127.0.0.1:9100 --path.procfs=/host/proc --path.sysfs=/host/sys --path.rootfs=/host/root --collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/docker/.+)($|/) --collector.filesystem.ignored-fs-types=^(autofs|binfmt_misc|cgroup|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|mqueue|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|sysfs|tracefs)$ --no-collector.wifi
root 116492 49040 0 03:03 pts/0 00:00:00 grep --color=auto 27913
查看cri-o 的状态,cri-o是一个daemon进程
[root@master0 ~]# systemctl status crio
● crio.service - Open Container Initiative Daemon
Loaded: loaded (/usr/lib/systemd/system/crio.service; disabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/crio.service.d
└─10-default-env.conf
Active: active (running) since Mon 2019-11-11 08:47:57 UTC; 2 days ago
Docs: https://github.com/cri-o/cri-o
Main PID: 1083 (crio)
Tasks: 38
Memory: 540.2M
CPU: 3h 42min 56.238s
CGroup: /system.slice/crio.service
├─ 1083 /usr/bin/crio --enable-metrics=true --metrics-port=9537
├─121183 /usr/libexec/crio/conmon -c 6b02031122564f9410db50e61f4694b4c429a89cb16c5bf0f1c136ba4177a14a -n k8s_guard_etcd-quorum-guard-845d699494-sqvn9_openshift-machine-config-operator_c8ba4b6d-0460-11ea-a0f4-00000a1006c9_0 -r /usr/bin/runc -p /tmp/pidfil>
└─121184 /usr/bin/runc exec -d --pid-file /tmp/pidfile770198600 --process /tmp/exec-process-355304634 6b02031122564f9410db50e61f4694b4c429a89cb16c5bf0f1c136ba4177a14a
Nov 12 04:12:40 master0.gzhifangha.os.fyre.ibm.com crio[1083]: 2019-11-12T04:12:40Z [verbose] Del: openshift-kube-apiserver:installer-9-master0.gzhifangha.os.fyre.ibm.com:openshift-sdn:eth0 {"cniVersion":"0.3.1","name":"openshift-sdn","type":"openshift-sdn"}
Nov 12 04:13:06 master0.gzhifangha.os.fyre.ibm.com crio[1083]: 2019-11-12T04:13:06Z [verbose] Add: openshift-kube-apiserver:revision-pruner-9-master0.gzhifangha.os.fyre.ibm.com:openshift-sdn:eth0 {"cniVersion":"0.3.1","interfaces":[{"name":"eth0","sandbox":"/proc/6>
Nov 12 04:13:07 master0.gzhifangha.os.fyre.ibm.com crio[1083]: 2019-11-12T04:13:07Z [verbose] Del: openshift-kube-apiserver:revision-pruner-9-master0.gzhifangha.os.fyre.ibm.com:openshift-sdn:eth0 {"cniVersion":"0.3.1","name":"openshift-sdn","type":"openshift-sdn"}
Nov 12 06:13:50 master0.gzhifangha.os.fyre.ibm.com crio[1083]: 2019-11-12T06:13:50Z [verbose] Add: kube-system:metering-reader-7rg8z:openshift-sdn:eth0 {"cniVersion":"0.3.1","interfaces":[{"name":"eth0","sandbox":"/proc/39237/ns/net"}],"ips":[{"version":"4","interf>
Nov 12 08:39:28 master0.gzhifangha.os.fyre.ibm.com crio[1083]: 2019-11-12T08:39:28Z [verbose] Add: openshift-kube-apiserver:installer-10-master0.gzhifangha.os.fyre.ibm.com:openshift-sdn:eth0 {"cniVersion":"0.3.1","interfaces":[{"name":"eth0","sandbox":"/proc/65636/>
Nov 12 08:39:39 master0.gzhifangha.os.fyre.ibm.com crio[1083]: 2019-11-12T08:39:39Z [verbose] Del: openshift-controller-manager:controller-manager-rd987:openshift-sdn:eth0 {"cniVersion":"0.3.1","name":"openshift-sdn","type":"openshift-sdn"}
Nov 12 08:40:46 master0.gzhifangha.os.fyre.ibm.com crio[1083]: 2019-11-12T08:40:46Z [verbose] Del: openshift-kube-apiserver:installer-10-master0.gzhifangha.os.fyre.ibm.com:openshift-sdn:eth0 {"cniVersion":"0.3.1","name":"openshift-sdn","type":"openshift-sdn"}
Nov 12 08:41:17 master0.gzhifangha.os.fyre.ibm.com crio[1083]: 2019-11-12T08:41:17Z [verbose] Add: openshift-kube-apiserver:revision-pruner-10-master0.gzhifangha.os.fyre.ibm.com:openshift-sdn:eth0 {"cniVersion":"0.3.1","interfaces":[{"name":"eth0","sandbox":"/proc/>
Nov 12 08:41:18 master0.gzhifangha.os.fyre.ibm.com crio[1083]: 2019-11-12T08:41:18Z [verbose] Del: openshift-kube-apiserver:revision-pruner-10-master0.gzhifangha.os.fyre.ibm.com:openshift-sdn:eth0 {"cniVersion":"0.3.1","name":"openshift-sdn","type":"openshift-sdn"}
Nov 12 08:41:27 master0.gzhifangha.os.fyre.ibm.com crio[1083]: 2019-11-12T08:41:27Z [verbose] Add: openshift-controller-manager:controller-manager-8dnc7:openshift-sdn:eth0 {"cniVersion":"0.3.1","interfaces":[{"name":"eth0","sandbox":"/proc/70871/ns/net"}],"ips":[{">
[root@master0 ~]# runc state f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381
{
"ociVersion": "1.0.1-dev",
"id": "f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381",
"pid": 27913,
"status": "running",
"bundle": "/run/containers/storage/overlay-containers/f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381/userdata",
"rootfs": "/var/lib/containers/storage/overlay/d814fa5be7bbf3b659162caa399fc52ec9bacf3b0e02997c99592d0d3c6922dc/merged",
"created": "2019-11-11T08:58:15.914588316Z",
"annotations": {
"io.kubernetes.container.hash": "a08e7c7d",
"io.kubernetes.container.name": "node-exporter",
"io.kubernetes.container.restartCount": "0",
"io.kubernetes.container.terminationMessagePath": "/dev/termination-log",
"io.kubernetes.container.terminationMessagePolicy": "File",
"io.kubernetes.cri-o.Annotations": "{\"io.kubernetes.container.hash\":\"a08e7c7d\",\"io.kubernetes.container.restartCount\":\"0\",\"io.kubernetes.container.terminationMessagePath\":\"/dev/termination-log\",\"io.kubernetes.container.terminationMessagePolicy\":\"File\",\"io.kubernetes.pod.terminationGracePeriod\":\"30\"}",
"io.kubernetes.cri-o.ContainerID": "f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381",
"io.kubernetes.cri-o.ContainerType": "container",
"io.kubernetes.cri-o.Created": "2019-11-11T08:58:15.422124413Z",
"io.kubernetes.cri-o.IP": "10.16.12.11",
"io.kubernetes.cri-o.Image": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:fb559dae37782e6cccb56ffbec74104989979ad6e8b34b1803bb630b4431b3b6",
"io.kubernetes.cri-o.ImageName": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:fb559dae37782e6cccb56ffbec74104989979ad6e8b34b1803bb630b4431b3b6",
"io.kubernetes.cri-o.ImageRef": "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:fb559dae37782e6cccb56ffbec74104989979ad6e8b34b1803bb630b4431b3b6",
"io.kubernetes.cri-o.Labels": "{\"io.kubernetes.container.name\":\"node-exporter\",\"io.kubernetes.pod.name\":\"node-exporter-cbkqp\",\"io.kubernetes.pod.namespace\":\"openshift-monitoring\",\"io.kubernetes.pod.uid\":\"5b772849-0461-11ea-9404-00000a100c0b\"}",
"io.kubernetes.cri-o.LogPath": "/var/log/pods/openshift-monitoring_node-exporter-cbkqp_5b772849-0461-11ea-9404-00000a100c0b/node-exporter/0.log",
"io.kubernetes.cri-o.Metadata": "{\"name\":\"node-exporter\"}",
"io.kubernetes.cri-o.MountPoint": "/var/lib/containers/storage/overlay/d814fa5be7bbf3b659162caa399fc52ec9bacf3b0e02997c99592d0d3c6922dc/merged",
"io.kubernetes.cri-o.Name": "k8s_node-exporter_node-exporter-cbkqp_openshift-monitoring_5b772849-0461-11ea-9404-00000a100c0b_0",
"io.kubernetes.cri-o.ResolvPath": "/var/run/containers/storage/overlay-containers/99d5ee6dd67aed5d4d5cbc476cff80f079a8dd18a8c78baafe3ba4625276a6ac/userdata/resolv.conf",
"io.kubernetes.cri-o.SandboxID": "99d5ee6dd67aed5d4d5cbc476cff80f079a8dd18a8c78baafe3ba4625276a6ac",
"io.kubernetes.cri-o.SandboxName": "k8s_POD_node-exporter-cbkqp_openshift-monitoring_5b772849-0461-11ea-9404-00000a100c0b_0",
"io.kubernetes.cri-o.SeccompProfilePath": "",
"io.kubernetes.cri-o.Stdin": "false",
"io.kubernetes.cri-o.StdinOnce": "false",
"io.kubernetes.cri-o.TTY": "false",
"io.kubernetes.cri-o.Volumes": "[{\"container_path\":\"/host/proc\",\"host_path\":\"/proc\",\"readonly\":false},{\"container_path\":\"/host/sys\",\"host_path\":\"/sys\",\"readonly\":false},{\"container_path\":\"/host/root\",\"host_path\":\"/\",\"readonly\":true},{\"container_path\":\"/etc/hosts\",\"host_path\":\"/var/lib/kubelet/pods/5b772849-0461-11ea-9404-00000a100c0b/etc-hosts\",\"readonly\":false},{\"container_path\":\"/dev/termination-log\",\"host_path\":\"/var/lib/kubelet/pods/5b772849-0461-11ea-9404-00000a100c0b/containers/node-exporter/d61b4508\",\"readonly\":false},{\"container_path\":\"/var/run/secrets/kubernetes.io/serviceaccount\",\"host_path\":\"/var/lib/kubelet/pods/5b772849-0461-11ea-9404-00000a100c0b/volumes/kubernetes.io~secret/node-exporter-token-7lbm8\",\"readonly\":true}]",
"io.kubernetes.pod.name": "node-exporter-cbkqp",
"io.kubernetes.pod.namespace": "openshift-monitoring",
"io.kubernetes.pod.terminationGracePeriod": "30",
"io.kubernetes.pod.uid": "5b772849-0461-11ea-9404-00000a100c0b"
},
"owner": ""
[root@master0 ~]# runc exec f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381 ps
PID TTY TIME CMD
27913 ? 00:22:02 node_exporter
28674 ? 00:00:27 kube-rbac-proxy
43479 ? 00:00:00 startup.sh
43535 ? 00:00:00 npm
43571 ? 00:01:08 nginx
43572 ? 00:00:00 nginx
43588 ? 00:04:15 node
126089 ? 00:00:00 ps
[root@master0 ~]# systemctl status crio-f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381.scope
● crio-f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381.scope - libcontainer container f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381
Loaded: loaded (/run/systemd/transient/crio-f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381.scope; transient)
Transient: yes
Active: active (running) since Mon 2019-11-11 08:58:15 UTC; 2 days ago
Tasks: 18 (limit: 1024)
Memory: 19.7M
CPU: 22min 2.475s
CGroup: /kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod5b772849_0461_11ea_9404_00000a100c0b.slice/crio-f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381.scope
└─27913 /bin/node_exporter --web.listen-address=127.0.0.1:9100 --path.procfs=/host/proc --path.sysfs=/host/sys --path.rootfs=/host/root --collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/docker/.+)($|/) --collector.filesystem.ignored-fs->
Nov 11 08:58:15 master0.gzhifangha.os.fyre.ibm.com systemd[1]: Started libcontainer container f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381.
[root@master0 ~]# systemctl status crio-conmon-f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381.scope
● crio-conmon-f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381.scope
Loaded: loaded (/run/systemd/transient/crio-conmon-f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381.scope; transient)
Transient: yes
Active: active (running) since Mon 2019-11-11 08:58:15 UTC; 2 days ago
Tasks: 2 (limit: 26213)
Memory: 1.0M
CPU: 61ms
CGroup: /kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod5b772849_0461_11ea_9404_00000a100c0b.slice/crio-conmon-f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381.scope
└─27881 /usr/libexec/crio/conmon -s -c f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381 -n k8s_node-exporter_node-exporter-cbkqp_openshift-monitoring_5b772849-0461-11ea-9404-00000a100c0b_0 -u f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16>
Nov 11 08:58:15 master0.gzhifangha.os.fyre.ibm.com systemd[1]: Started crio-conmon-f784bca78cbfc88ac0a1aa11ac87e70d5bee8cdecc5b16845658fd04afa0b381.scope.
Podman
Podman是Redhat公司推出的容器管理工具,Podman起初是CRI-O的一部分,后来单独分离出来叫做libpod,使用Podman的命令几乎和docker类似(我想这是Redhat公司大力推举Podman替换Docker的同时又不是用户体验的诡计),你可以通过alias docker=podman
来替换Docker。
Podman在结构上与Docker不同,Podman没有使用daemon的方式去创建容器,而是直接调用OCI runtime,比如runc,Podman由两部分组成,Podman CLI 和conmon,Podman CLI方便用户交互,conmon负责container runtime,主要包括监控,日志,TTY分配等,简而言之,conmon是所有容器进程的父进程。
[root@cephrook-cephMater ~]# pstree -p
systemd(1)-+-agetty(1299)
|-conmon(1954)-+-nginx(1975)---nginx(1988)
| `-{conmon}(1956)
基本常用命令:
podman info
podman version
podman images
podman rmi
podman ps
# podman info
host:
BuildahVersion: 1.9.0
Conmon:
package: podman-1.4.4-4.el7.x86_64
path: /usr/libexec/podman/conmon
version: 'conmon version 0.3.0, commit: unknown'
Distribution:
distribution: '"rhel"'
version: "7.7"
MemFree: 15117926400
MemTotal: 16656146432
OCIRuntime:
package: runc-1.0.0-65.rc8.el7.x86_64
path: /usr/bin/runc //创建容器的后端runc
version: 'runc version spec: 1.0.1-dev'
SwapFree: 8455712768
SwapTotal: 8455712768
arch: amd64
cpus: 8
hostname: cephrook-cephMater.fyre.ibm.com
kernel: 3.10.0-1062.el7.x86_64
os: linux
rootless: false
uptime: 23h 8m 52.84s (Approximately 0.96 days)
registries:
blocked: null
insecure: null
search:
- registry.access.redhat.com //拉取镜像的仓库顺序
- docker.io
- registry.fedoraproject.org
- quay.io
- registry.centos.org
store:
ConfigFile: /etc/containers/storage.conf
ContainerStore:
number: 6
GraphDriverName: overlay
GraphOptions: null
GraphRoot: /var/lib/containers/storage //存储容器的metadata
GraphStatus:
Backing Filesystem: xfs
Native Overlay Diff: "true"
Supports d_type: "true"
Using metacopy: "false"
ImageStore:
number: 5
RunRoot: /var/run/containers/storage
VolumePath: /var/lib/containers/storage/volumes
查看某个镜像的详细信息:
cat /var/lib/containers/storage/overlay-images/images.json | python -m json.tool
启动一个容器:
# podman run -p 80:80 --name=web -d nginx
416c3f3964a0ac6731a7864090131c44baead4f251ab914b718cb66ce1089bfa
# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
416c3f3964a0 docker.io/library/nginx:latest nginx -g daemon o... 5 seconds ago Up 5 seconds ago 0.0.0.0:80->80/tcp web
# ps -ef | grep nginx
root 23477 23465 0 00:51 ? 00:00:00 nginx: master process nginx -g daemon off;
101 23491 23477 0 00:51 ? 00:00:00 nginx: worker process
root 23541 8898 0 00:52 pts/2 00:00:00 grep --color=auto nginx
# pstree -H 23477
systemd-+-agetty
|-conmon-+-nginx---nginx
| `-{conmon}
可见nginx进程ID是23477,它的父进程是23465,也就是conmon进程,conmon进程的父进程是systemd,
ps -ef | grep 23465
root 23465 1 0 00:51 ? 00:00:00 /usr/libexec/podman/conmon -s -c 416c3f3964a0ac6731a7864090131c44baead4f251ab914b718cb66ce1089bfa -u 416c3f3964a0ac6731a7864090131c44baead4f251ab914b718cb66ce1089bfa -n web -r /usr/bin/runc -b /var/lib/containers/storage/overlay-containers/416c3f3964a0ac6731a7864090131c44baead4f251ab914b718cb66ce1089bfa/userdata -p /var/run/containers/storage/overlay-containers/416c3f3964a0ac6731a7864090131c44baead4f251ab914b718cb66ce1089bfa/userdata/pidfile --exit-dir /var/run/libpod/exits --exit-command /usr/bin/podman --exit-command-arg --root --exit-command-arg /var/lib/containers/storage --exit-command-arg --runroot --exit-command-arg /var/run/containers/storage --exit-command-arg --log-level --exit-command-arg error --exit-command-arg --cgroup-manager --exit-command-arg systemd --exit-command-arg --tmpdir --exit-command-arg /var/run/libpod --exit-command-arg --runtime --exit-command-arg runc --exit-command-arg --storage-driver --exit-command-arg overlay --exit-command-arg container --exit-command-arg cleanup --exit-command-arg 416c3f3964a0ac6731a7864090131c44baead4f251ab914b718cb66ce1089bfa --socket-dir-path /var/run/libpod/socket -l k8s-file:/var/lib/containers/storage/overlay-containers/416c3f3964a0ac6731a7864090131c44baead4f251ab914b718cb66ce1089bfa/userdata/ctr.log --log-level error
root 23477 23465 0 00:51 ? 00:00:00 nginx: master process nginx -g daemon off;
root 23642 8898 0 00:54 pts/2 00:00:00 grep --color=auto 23465
Podman不使用CRL直接通信,Podman使用runc创建容器,使用storage管理镜像的存储。实际上Podman使用conmon创建容器,conmon使用runc创建容器,并且监控runc。Podman能够退出然后再重新连接上conmon与容器进行通信,当容器启动之后,runc就停止运行。
Podman does not communicate with using the CRI protocol. Instead, Podman creates containers using runc, and manages storage using containers/storage. Technically, Podman launches conmon which launches and monitors the OCI Runtime (runc). Podman can exit and later reconnect to conmon to talk to the container. Runc stops running once the container starts.
https://blog.openshift.com/crictl-vs-podman/
和Docker不同,Podman不依赖容器运行引擎(Docker,CRI-O),Podman在磁盘上直接创建容器进程并做必要的修改。Podman依赖containers/images库来从镜像仓库拉取镜像,使用containers/storage来在磁盘上管理镜像。CRI-O也是如此,所以通过Podman拉取的镜像也可以通过CRI-O读取到。
最重要的是,Podman完全独立于CRI-O,但可以管理CRI-O的存储后端。最终,它将能够完全处理CRI-O数据,并能够管理后台的内容。关于使用Podman诊断CRI-O问题的一件好事是,即使kubelet或CRI-O出现问题,它也可以工作。只要CRI-O正在运行,Crictl实用程序就可以帮助您诊断和理解CRI协议。
两种工具都是管理员在容器工具库中的绝佳补充。
Podman 创建Pod
# podman pod create -n podtest
3a4525137b6a114d1bfd94513bbdff4a0875615e515cebcca01b2ef3d70760d2
容器相关的概念
要理解容器相关的术语,首先要从技术的角度正确的理解什么是容器。一个容器实际上
是两个不同的东西。像普通的Linux进程,容器实际上有两个状态-rest ,running。当一
个容器处于rest状态,它呈现的形式是一个保存在磁盘上的文件,这涉及到我们所说容器
Image和容器Repository。当你启动一个容器之后,容器引擎解压所需要的文件和metadata
把这些数据交给Linux kernel。启动一个容器非常像启动一个普通的Linux进程,并且这个过程
也需要制定一系列API,通过API来调用Linux kernel。这些API调用通常会启动额外的隔离,并
挂载容器镜像中文件的副本。一旦容器运行起来,容器的表现就是一个Linux 进程。
启动容器的过程以及磁盘上的映像格式是有一系列的标准定义和控制的。
有一系列的容器镜像格式(Docker,Appc,LXD),但是工业上制定了一些列的标准来规范镜像
的格式,这个规范就叫做Open Container Initiative(OCI),OCI包含了什么呢?它包含了
容器镜像的格式的详细定义,包括存储在磁盘上的容器镜像的格式和原数据(类似定义硬件的架构
和操作系统类型)。
也有一系列的容器引擎例如Docker,CRI-O,LXC。容器引擎把容器镜像变成容器,这是一个什么
过程呢?这是由OCI中容器运行时规范定义的,是由RunC这个项目实现的
Container runtime(容器运行时)
在OCI标准下实现的Container Runtime是runc,也有其它的container runtime比如:crun,katacontainers
Docker CRI-O 容器引擎都依赖runc来创建容器。
容器运行时的作用:
- 使用容器引擎提供的挂载点(可以是一个空目录)
- 使用容器引擎提供的原数据(config.json)
- 与kernel进行通信来启动容器进程(clone 系统调用)
- 设置cgroups
- 设置SELinux Policy
- 设置啊App Armor 规则
以下讲一些历史信息,起初创建Docker引擎时,它依赖LXC作为容器运行时。后来,Docker团队开发
了自己的名为libcontainer的库来启动容器。该库是用Golang编写的,并已编译为原始Docker引擎。
最终,在创建OCI时,Docker捐赠了libcontainer代码并将其转变为一个名为runc的独立实用程序。
现在,runc是参考实现,并被其他容器引擎(例如CRI-O)使用。在最低级别上,无论容器引擎如何,
这都可以始终启动容器。 Runc是一个非常简洁实用的程序,希望为其提供挂载点(目录)
和元数据(config.json)。
Container engine(容器引擎)
容器引擎是一种软件,它接受用户请求,包括命令行选项,提取图像,并从终端用户的角度运行容器。
有很多容器引擎,包括docker,RKT,CRI-O和LXD。此外,许多云提供商,平台即服务(PaaS)和
容器平台都有自己的内置容器引擎,这些引擎使用Docker或OCI兼容的容器镜像。
具有行业标准的容器镜像格式可以在所有这些不同平台之间实现互操作性。
更深入地讲,大多数容器引擎实际上并不运行容器,它们依赖于与OCI兼容的容器运行时,例如runc。
通常,容器运行时负责:
- 处理用户输入
- 通过容器编排API处理输入
- 使用图形驱动程序(块或文件,取决于驱动程序)扩展解压缩并扩展磁盘上的容器映像
- 准备容器挂载点,通常在写时复制存储上(再次取决于驱动程序还是块或文件)
- 准备将传递到容器Container Runtime的元数据以正确启动Container
- 调用容器运行时
以下讲一些历史信息,起初创建Docker引擎时,它依赖LXC作为容器运行时。后来,Docker团队开发
了自己的名为libcontainer的库来启动容器。该库是用Golang编写的,并已编译为原始Docker引擎。
最终,在创建OCI时,Docker捐赠了libcontainer代码并将其转变为一个名为runc的独立实用程序。
现在,runc是参考实现,并被其他容器引擎(例如CRI-O)使用。在最低级别上,无论容器引擎如何,
这都可以始终启动容器。 Runc是一个非常简洁实用的程序,希望为其提供挂载点(目录)
和元数据(config.json)。
Conmon
conmon(container monitorring)是一个监控程序,用来作为每个容器的容器引擎(podman ,cri-o)和OCI运行时(runc)之间通信的工具。
当conmon启动时,它会进行两次fork以使其与启动它的父进程进行守护和分离。然后,它将运行时作为其子进程运行。这允许管理进程在前台消失,但仍然能够监视并连接到子进程(容器)。
当容器运行时,conmon做两件事情:
- 提供一个用于连接到容器的socket,保持容器的标准流打开并通过套接字转发它们;
- 将容器流的内容写入日志文件(或系统日志),以便在容器死亡后可以读取它们。
最后,一旦容器死亡,conmon将记录其退出时间和推出码,以供管理程序读取。
conmon用C语言编写,旨在减少内存占用,旨在由容器管理库运行。本质上,conmon是容器可以拥有的最小守护程序。