CRI-O 是一个开源的、社区驱动的容器引擎。 其主要目标是取代 Docker 服务作为 Kubernetes 实施的容器引擎。随着 Kubernetes v1.24 对 dockershim 的弃用,CRI-O 将成为 Kubernetes 容器引擎的不二之选。
CRI-O 容器引擎为运行与开放容器标准 (OCI) 兼容的运行时提供了一个稳定、更安全和高性能的平台。使用 CRI-O 容器引擎可以借助使用符合 OCI 的运行时(如 runc、默认 OCI 运行时或 Kata Containers)来启动容器和 Pod。
CRI-O 的稳定性来自于它是与 Kubernetes 的主要和次要版本同步开发、测试和发布的,而且它遵循 OCI 标准。例如,CRI-O 1.24 与 Kubernetes 1.24 保持一致。CRI-O 的适用范围与容器运行时接口(CRI)相关联(参见:What is the scope of CRI-O?)。CRI 准确地提取和标准化了 Kubernetes 服务(kubelet)从其容器引擎中所需的支撑。随着多种容器引擎开始被相继开发,CRI 团队这样做是为了帮助稳定 Kubernetes 容器引擎的要求。
操控 CRI-O 的常用命令行工具包括:
crictl - 用于排除故障和直接与 CRI-O 容器引擎一起工作(需安装 cri-tools,较常用)
runc - 用于运行容器镜像(CRI-O 自带,几乎不用)
podman - 用于在容器引擎之外管理 pod 和容器镜像(run, stop, start, ps, attach, exec 等,需安装 podman,经常用。podman 的详细使用方式见:Podman构建和管理容器)
一些 Docker 功能被包含在其他工具中,而不是 CRI-O 中。例如,podman提供了与许多 docker 命令功能完全兼容的命令行,并将这些功能也扩展到管理 pod 上。使用 podman 运行容器或 pod 不需要容器引擎。
不支持 CRI-O 作为独立的容器引擎运行。必须使用 CRI-O 作为 Kubernetes 安装的容器引擎,要在没有 Kubernetes 的情况下运行容器,请使用 podman。
安装 CRI - O(参考:容器运行时 | Kubernetes)
说明:如果 Kubernetes 的网络代理组件(如 calico)使用的是 eBPF 模式,则不要依照 Kubernetes 官方文档在 /etc/modules-load.d/crio.conf 中配置 br_netfilter 内核模块,只需保留其中的 overlay 模块。还可以直接删除用于转发桥接流量到 iptables 链的配置文件 /etc/sysctl.d/99-kubernetes-cri.conf
要查询和调试 CRI-O 容器运行时,请运行 crictl 命令直接与 CRI-O 通信。crictl 使用的 CRI-O 实例在 /etc/crictl.yaml 文件中标识。
说明:旧版 /etc/crictl.yaml 中的 image-endpoint 已从 v1.21.0 移除。
详见:fix: Don't set `image-endpoint` in crictl config · cri-o/cri-o@4bca0bb · GitHub
cat /etc/crictl.yaml
# 显示如下内容
runtime-endpoint: "unix:///var/run/crio/crio.sock"
默认情况下,crictl.yaml 文件使 crictl 指向本地系统上的 CRI-O socket。要查看 crictl 可用的选项,请不带参数直接运行 crictl。要获得特定选项的帮助,请添加 --help。例如:
crictl run --help
# 显示如下内容
NAME:
crictl run - Run a new container inside a sandbox
USAGE:
crictl run [command options] container-config.[json|yaml] pod-config.[json|yaml]
OPTIONS:
--auth AUTH_STRING Use AUTH_STRING for accessing the registry. AUTH_STRING is a base64 encoded 'USERNAME[:PASSWORD]'
--creds USERNAME[:PASSWORD] Use USERNAME[:PASSWORD] for accessing the registry
--no-pull Do not pull the image (overrides disable-pull-on-run=false in config) (default: false)
--runtime value, -r value Runtime handler to use. Available options are defined by the container runtime.
--timeout value, -t value Seconds to wait for a container create request before cancelling the request (default: 0s)
--with-pull Pull the image (overrides disable-pull-on-run=true in config) (default: false)
--help, -h show help (default: false)
配置国内容器镜像加速器,执行以下命令。
vi /etc/containers/registries.conf
说明:registries.conf 现已全部使用 V2 配置格式,如果你的文件中混合了 V1 和 V2 的配置格式,请将 V1 版的配置格式全部删除,只保留 V2 版配置格式。
详见:image/containers-registries.conf.5.md at main · containers/image · GitHub
删除 registries.conf 中的默认配置,替换为以下内容。
注:mirror.ccs.tencentyun.com 镜像加速器只有在腾讯云上才能使用。请根据实际环境配置。
unqualified-search-registries = ["docker.io", "k8s.gcr.io", "registry.fedoraproject.org", "registry.access.redhat.com", "registry.centos.org"]
[[registry]]
prefix = "docker.io"
location = "mirror.ccs.tencentyun.com"
[[registry]]
prefix = "k8s.gcr.io/coredns/coredns"
location = "registry.aliyuncs.com/google_containers/coredns"
[[registry]]
prefix = "*.gcr.io"
location = "registry.aliyuncs.com/google_containers"
各配置项解释如下:
unqualified-search-registries: 按顺序拉取不匹配的镜像时需要尝试的 host[:port] 镜像注册表数组。
[[registry]]: 镜像注册表,用于反向代理到国内镜像。
insecure: true 或 false。默认 false,表示容器运行时在从镜像注册表检索镜像时需要 TLS 连接。
如果将 insecure 设置为 true,则允许使用未加密的 HTTP 以及具有不受信任的证书的 TLS 连接。
blocked true 或 false。默认 false。如果为 true,则表示阻止本地系统 pull、search 自 [[registry]] 块中已定义的 prefix、location 镜像地址。
prefix 镜像名称前缀,可以是具体的镜像注册表,如 docker.io。还可以包含格式为 *.example.com 的通配符子域。
通配符应仅出现在开头第一个字符,其他格式将不起作用(甚至会导致 crio 无法启动)。
例如:*.example.com 有效,但 example.*.com、*.example.com/foo 和 *.example.com:5000/foo/bar:baz 都无效。
请注意:* 匹配任意数量的子域。*.example.com 将匹配 bar.example.com、foo.bar.example.com 等。
location: 接受与 prefix 字段相同的格式,但不能用通配符。配合 prefix 使用时表示将所有以 prefix 为根命名空间的镜像都反向代理到指定的 location 镜像。
检查 crio.service 日志,执行如下命令。
journalctl -xeu crio
列出其中一个容器的日志,执行如下命令。
crictl logs $(container_id)
开启 CRI-O 调试,编辑 /etc/crio/crio.conf 修改如下。
# 可选日志级别:fatal, panic, error, warn, info (default), debug, trace
[crio.runtime]
log_level = "debug"
重新加载配置文件,并重新启动服务,命令如下。
systemctl daemon-reload
systemctl restart crio
通过 crictl 命令,你可以直接与 CRI-O 容器引擎对接,检查和操作与该容器引擎相关的容器、镜像和 pod。runc 容器运行时是与 CRI-O 交互的另一种方式。如果你想在 CRI-O 容器引擎之外运行容器,例如在一个节点上运行支持工具,你可以使用 podman 命令。
首先,你可以使用 crictl info 和 crictl version 命令检查 CRI-O 服务的一般状态。
crictl info
# 显示如下内容
{
"status": {
"conditions": [
{
"type": "RuntimeReady",
"status": true,
"reason": "",
"message": ""
},
{
"type": "NetworkReady",
"status": true,
"reason": "",
"message": ""
}
]
}
}
crictl version
# 显示如下内容
Version: 0.1.0
RuntimeName: cri-o
RuntimeVersion: 1.23.2
RuntimeApiVersion: v1alpha2
查看已经拉取到本地 CRI-O 节点的镜像。
crictl images
查看当前在CRI-O环境中已激活的(Ready)pod。
crictl pods
查看当前正在运行的容器。
crictl ps
查看所有容器,包括正在运行、已停止和已退出的容器。
crictl ps -a
如果你的 CRI-O 服务被停止或出现故障,你可以使用 runc 命令列出在 CRI-O 中运行的容器。这个例子搜索了一个 CRI-O 运行和不运行的容器的存在。然后它显示你可以用 runc 来调查那个容器,即使是在 CRI-O 停止的时候。
crictl ps | grep d36a99a9a40ec
d36a99a9a40ec 062cd20609d3895658e54e5f367b9d70f42db4f86ca14bae7309512c7e0777fd
11 hours ago CONTAINER_RUNNING sync 2
sudo systemctl stop crio
sudo crictl ps | grep d36a99a9a40ec
2022/04/14 11:22:16 grpc: addrConn.resetTransport failed to create client transport:
connection error: desc = "transport: dial unix /var/run/crio/crio.sock: connect:
no such file or directory"; Reconnecting to {/var/run/crio/crio.sock <nil>}
FATA[0000] listing containers failed: rpc error: code = Unavailable desc = grpc:
the connection is unavailable
sudo runc list | grep d36a99a9a40ec
d36a99a9a40ecc4c830f10ed2d5bb3ce1c6deadcb1a4879ff342e315051a71ed 19477 running
/run/containers/storage/overlay-containers/d36a99a9a40ecc4c830f10ed2d5bb3ce1c6deadcb1a4879ff342e315051a71ed/userdata
2022-04-14T04:44:29.47950187Z root
ls /run/containers/storage/overlay-containers/d36*/userdata/
attach config.json ctl pidfile run
less /run/containers/storage/overlay-containers/d36*/userdata/config.json
{
"ociVersion": "1.0.0",
"process": {
"user": {
"uid": 0,
"gid": 0
},
"args": [
"/bin/bash",
"-c",
"#!/bin/bash\nset -euo pipefail\n\n# set by the node
image\nunset KUBECONFIG\n\ntrap 'kill $(jobs -p);
exit 0' TERM\n\n# track the current state of the ...
sudo systemctl start crio
如你所见,即使关闭了 CRI-O 服务,runc 也会显示容器的存在和它在文件系统中的位置,以备进一步调查。
进入容器内并查看容器的操作系统名称和版本
crictl exec bcaee950b412 cat /etc/os-release
# 显示如下内容
NAME="Anolis OS"
VERSION="8.4"
查看在容器内运行的进程列表,运行如下命令。
crictl exec -ti bcaee950b412 ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:36 ? 00:00:00 /usr/sbin/init
root 20 1 0 07:36 ? 00:00:00 /usr/lib/systemd/systemd-journald
root 21 1 0 07:36 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 22 21 0 07:36 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 23 21 0 07:36 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 24 21 0 07:36 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 25 21 0 07:36 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
dbus 26 1 0 07:36 ? 00:00:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --n
root 244 0 0 08:32 pts/1 00:00:00 ps -ef
作为一种选择,你还可以使用 runc 命令 "exec" 进入一个容器。
runc exec -t e47b3a837aa3023c748c4c31a090266f014afba641a8ab9cfca31b065b4f2ddd ps -ef
UID PID PPID C STIME TTY TIME CMD
1000130+ 1 0 0 Oct17 ? 00:38:16 /usr/bin/origin-web-console --audit-log-path=- -v=0 --config=/var/webconsole-config/webc
1000130+ 16541 0 0 15:48 pts/0 00:00:00 ps -ef
1000130+ 17518 1 0 Oct23 ? 00:00:00 [curl] <defunct>
如果容器内没有 ps 命令,runc 有 ps 选项,它具有显示容器内运行的进程的相同效果。
sudo runc ps e47b3a837aa3023c748c4c31a090266f014afba641a8ab9cfca31b065b4f2ddd
注意,runc 需要完整的容器 ID,而 crictl 只需要开头的几个唯一字符。
有了pod sandbox (沙箱) ID(从 crictl pods 输出),运行crictl inspectp来显示该pod沙箱的信息。
sudo crictl pods | grep 5a60ac777aaa0
5a60ac777aaa0 8 days ago SANDBOX_READY registry-console-1-vktl6 default 0
sudo crictl inspectp 5a60ac777aaa0
{
"status": {
"id": "5a60ac777aaa055f14b998a9f2ced3e146b3cddbe270154abb75decd583bf879",
"metadata": {
"attempt": 0,
"name": "registry-console-1-vktl6",
"namespace": "default",
"uid": "6af860cc-d20b-11e8-b094-525400535ba1"
},
"state": "SANDBOX_READY",
"createdAt": "2022-04-14T08:53:22.828511516-04:00",
"network": {
"ip": "10.128.0.6"
要查看本地系统上 CRI-O 可用的镜像状态信息,请运行 crictl inspecti
crictl inspecti 25f8c7f3da61c
{
"status": {
"id": "25f8c7f3da61c2a810effe5fa779cf80ca171afb0adf94c7cb51eb9a8546629d",
"repoTags": [
"k8s.gcr.io/etcd:3.5.1-0"
],
"repoDigests": [
"k8s.gcr.io/etcd@sha256:05c1a3be66823dcaca55ebe17c3c9a60de7ceb948047da3e95308348325ddd5a",
"k8s.gcr.io/etcd@sha256:64b9ea357325d5db9f8a723dcf503b5a449177b17ac87d69481e126bb724c263"
],
"size": "293920249",
"uid": {
"value": "0"
},
"username": "",
"spec": null
}
}