docker · 2024-05-05 0

crictl 命令使用

一、安装 crictl

ctr 是 containerd 的一个客户端工具;crictl 是遵循 CRI 接口规范的一个命令行工具。

从containerd的角度来看启动一个容器:

ctr cli ---grpc---> containerd ---exec---> containerd-shim-runc ---exec---> runc

从 containerd 作为 k8s 的容器运行时来看:

crictl 与 kubelet ---CRI---> containerd ---exec---> containerd-shim-runc ---exec---> runc

1.安装 containerd

1) 安装 containerd

root@ctr-1:~# apt install containerd -y
root@ctr-1:~# ctr -v
ctr github.com/containerd/containerd 1.7.2
root@ctr-1:~# ctr version
Client:
  Version:  1.7.2
  Revision: 
  Go version: go1.20.3

Server:
  Version:  1.7.2
  Revision: 
  UUID: deed1033-a829-419b-b232-fa64b992b077

2) 修改配置文件

若需要修改默认的配置文件,需把默认的配置写入到 /etc/containerd/config.toml

root@ctr-1:~# mkdir -p /etc/containerd/
root@ctr-1:~# containerd config default > /etc/containerd/config.toml

3) 配置国内仓库

以下是 containerd 1.6 之后的配置

3.1) 修改 /etc/containerd/config.toml 中的 config_path

    [plugins."io.containerd.grpc.v1.cri".registry]
      config_path = "/etc/containerd/certs.d"

3.2) 创建 /etc/containerd/certs.d/docker.io 和 hosts.toml 文件

root@ctr-1:/# mkdir -p /etc/containerd/certs.d/docker.io
root@ctr-1:/# touch /etc/containerd/certs.d/docker.io/hosts.toml
root@ctr-1:/etc/containerd/certs.d/docker.io# cat hosts.toml 
server = "https://docker.io"
[host."https://docker.m.daocloud.io"]
  capabilities = ["pull","resolve"]
  # skip_verify = true

3.3) 创建 /etc/containerd/certs.d/registry.k8s.io 和 hosts.toml 文件

root@ctr-1:/# mkdir -p /etc/containerd/certs.d/registry.k8s.io
root@ctr-1:/# touch /etc/containerd/certs.d/registry.k8s.io/hosts.toml
root@ctr-1:/etc/containerd/certs.d/registry.k8s.io# cat hosts.toml 
server = "https://registry.k8s.io"
[host."https://k8s.m.daocloud.io"]
  capabilities = ["pull","resolve"]
  # skip_verify = true

2.安装 crictl

root@ctr-1:~# wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.28.0/crictl-v1.28.0-linux-amd64.tar.gz
root@ctr-1:~# tar -zxvf crictl-v1.28.0-linux-amd64.tar.gz -C /usr/local/bin

执行 crictl version 会报错,报错如下:

root@ctr-1:~# crictl version
WARN[0000] runtime connect using default endpoints: [unix:///var/run/dockershim.sock unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead. 
ERRO[0000] validate service connection: validate CRI v1 runtime API for endpoint "unix:///var/run/dockershim.sock": rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial unix /var/run/dockershim.sock: connect: no such file or directory" 
Version:  0.1.0
RuntimeName:  containerd
RuntimeVersion:  1.7.2
RuntimeApiVersion:  v1

crictl 默认连接到 unix:///var/run/dockershim.sock,对于其他的运行时,可以用多种不同的方法设置端点:

  • 通过设置参数 --runtime-endpoint 和 --image-endpoint
  • 通过设置环境变量 CONTAINER_RUNTIME_ENDPOINT 和 IMAGE_SERVICE_ENDPOINT
  • 通过在配置文件中设置端点 --config=/etc/crictl.yaml

此时,需要配置 crictl 的 runtime-endpoint 和 image-endpoint 为 containerd.sock,如下

root@ctr-1:~# crictl config runtime-endpoint unix:///run/containerd/containerd.sock
root@ctr-1:~# crictl config image-endpoint unix:///run/containerd/containerd.sock
root@ctr-1:~# cat /etc/crictl.yaml
runtime-endpoint: "unix:///run/containerd/containerd.sock"
image-endpoint: "unix:///run/containerd/containerd.sock"
timeout: 0
debug: false
pull-image-on-create: false
disable-pull-on-run: false
root@ctr-1:~# crictl version
Version:  0.1.0
RuntimeName:  containerd
RuntimeVersion:  1.7.2
RuntimeApiVersion:  v1

3.安装 cni

1) 安装 cni

wget https://github.com/containernetworking/plugins/releases/download/v1.4.1/cni-plugins-linux-amd64-v1.4.1.tgz
mkdir -p /opt/cni/bin
mkdir -p /etc/cni/net.d
tar -zxvf cni-plugins-linux-amd64-v1.4.1.tgz -C /opt/cni/bin/

2) 添加配置文件

root@ctr-1:~# touch /etc/cni/net.d/10-mynet.conf
root@ctr-1:~# cat /etc/cni/net.d/10-mynet.conf
{
  "cniVersion": "1.0.0",
  "name": "mynet",
  "type": "bridge",
  "bridge": "cni0",
  "isGateway": true,
  "ipMasq": true,
  "ipam": {
    "type": "host-local",
    "subnet": "10.88.0.0/16",
    "routes": [
      { "dst": "0.0.0.0/0" }
   ]
  }
}

3) 查看 crictl info 的 lastCNILoadStatus 为 OK,则安装成功

root@ctr-1:~# crictl info | grep lastCNILoadStatus
  "lastCNILoadStatus": "OK",
  "lastCNILoadStatus.default": "OK"

4) 安装 iptables

root@ctr-1:~# apt install iptables -y

如何不安装 iptables,创建 pod 时会有提示如下, \"iptables\": executable file not found in $PATH

root@ctr-1:~# crictl runp nginx-pod-config.json 
E1202 23:16:29.267998    3782 remote_runtime.go:193] "RunPodSandbox from runtime service failed" err="rpc error: code = Unknown desc = failed to setup network for sandbox \"e14766673f90a320c5003cadf24e0a19b2ba3d373702a0dc379d17f9311ac311\": plugin type=\"bridge\" name=\"mynet\" failed (add): failed to locate iptables: exec: \"iptables\": executable file not found in $PATH"
FATA[0000] run pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "e14766673f90a320c5003cadf24e0a19b2ba3d373702a0dc379d17f9311ac311": plugin type="bridge" name="mynet" failed (add): failed to locate iptables: exec: "iptables": executable file not found in $PATH 

二、crictl 命令操作镜像

1.拉取镜像

crictl pull 的镜像实际上是在 k8s.io namespace 下,可以使用 ctr -n k8s.io images ls 查看

root@ctr-1:~# crictl pull nginx:1.18.0

Image is up to date for sha256:c2c45d506085d300b72a6d4b10e3dce104228080a2cf095fc38333afe237e2be
root@ctr-1:~# crictl images
IMAGE                       TAG                 IMAGE ID            SIZE
docker.io/library/busybox   1.35.0              6b60752f5966a       2.16MB
docker.io/library/nginx     1.18.0              c2c45d506085d       53.6MB
root@ctr-1:~# ctr -n k8s.io images ls -q
docker.io/library/nginx:1.18.0
docker.io/library/nginx@sha256:e90ac5331fe095cea01b121a3627174b2e33e06e83720e9a934c7b8ccc9c55a0
sha256:c2c45d506085d300b72a6d4b10e3dce104228080a2cf095fc38333afe237e2be

2.查看镜像镜像

root@ctr-1:~# crictl images
IMAGE                       TAG                 IMAGE ID            SIZE
docker.io/library/nginx     1.18.0              c2c45d506085d       53.6MB
root@ctr-1:~# crictl images -q
sha256:c2c45d506085d300b72a6d4b10e3dce104228080a2cf095fc38333afe237e2be

三、crictl 命令操作 pod 沙盒

1.运行 pod

创建 nginx-pod-config.json 文件

{
  "metadata": {
    "name": "nginx-sandbox",
    "namespace": "default",
    "attempt": 1,
    "uid": "hdishd83djaidwnduwk28bcsb"
  },
  "log_directory": "/tmp",
  "linux": {
  }
}

或 nginx-pod-config.yml 文件

metadata:
  name: nginx-sandbox
  namespace: default
  attempt: 1
  uid: hdishd83djaidwnduwk28bcsb
log_directory: /tmp

使用 crictl runp [command options] pod-config.[json|yaml],运行一个 pod

root@ctr-1:~# crictl runp nginx-pod-config.json
3dac30a09776b95f9343daab232f37b6f6817ab1f5e94623e6ff44502ff91636

2.查看 pod

root@ctr-1:~# crictl pods
POD ID              CREATED             STATE               NAME                NAMESPACE           ATTEMPT             RUNTIME
3dac30a09776b       2 minutes ago       Ready               nginx-sandbox       default             1                   (default)

3.停止 pod

root@ctr-1:~# crictl stopp 3dac30a09776b
Stopped sandbox 3dac30a09776b
root@ctr-1:~# crictl pods
POD ID              CREATED             STATE               NAME                NAMESPACE           ATTEMPT             RUNTIME
3dac30a09776b       3 minutes ago       NotReady            nginx-sandbox       default             1                   (default)

4.删除 pod

root@ctr-1:~# crictl rmp 3dac30a09776b
Removed sandbox 3dac30a09776b
root@ctr-1:~# crictl pods
POD ID              CREATED             STATE               NAME                NAMESPACE           ATTEMPT             RUNTIME

四、crictl 命令操作容器

1.创建容器

1) 创建 busybox-pod-config.json 文件

{
  "metadata": {
    "name": "busybox-sandbox",
    "namespace": "default",
    "attempt": 1,
    "uid": "aewi4aeThua7ooShohbo1phoj"
  },
  "log_directory": "/tmp",
  "linux": {
  }
}

或 busybox-pod-config.yml 文件

metadata:
  name: busybox-sandbox
  namespace: default
  attempt: 1
  uid: aewi4aeThua7ooShohbo1phoj
log_directory: /tmp

2) 创建 busybox-container-config.json 配置文件

{
  "metadata": {
    "name": "busybox-container"
  },
  "image":{
    "image": "busybox:1.35.0"
  },
  "command": [
    "top"
  ],
  "log_path":"busybox.log",
  "linux": {
  }
}

或 busybox-container-config.yml 文件

metadata:
  name: busybox-container
image:
  image: busybox:1.35.0
command:
  - top
log_path: busybox.log

3) crictl run

使用 crictl run [command options] container-config.[json|yaml] pod-config.[json|yaml] 运行容器

root@ctr-1:~# crictl run busybox-container-config.json busybox-pod-config.json 
78afc0481a09ab7e4a8267f46144de00f56024d26e9e6c9c23b6562d3f9df26b

2.查看容器

root@ctr-1:~# crictl ps
CONTAINER           IMAGE               CREATED             STATE               NAME                ATTEMPT             POD ID              POD
78afc0481a09a       busybox:1.35.0      48 seconds ago      Running             busybox-container   0                   0ea29c5f1fa3e       unknown
root@ctr-1:~# crictl pods
POD ID              CREATED              STATE               NAME                NAMESPACE           ATTEMPT             RUNTIME
0ea29c5f1fa3e       About a minute ago   Ready               busybox-sandbox     default             1                   (default)

3.停止容器

root@ctr-1:~# crictl stop 78afc0481a09a
78afc0481a09a
root@ctr-1:~# crictl ps -a
CONTAINER           IMAGE               CREATED             STATE               NAME                ATTEMPT             POD ID              POD
78afc0481a09a       busybox:1.35.0      2 minutes ago       Exited              busybox-container   0                   0ea29c5f1fa3e       unknown

4.删除容器

root@ctr-1:~# crictl rm 78afc0481a09a
78afc0481a09a
root@ctr-1:~# crictl ps -a
CONTAINER           IMAGE               CREATED             STATE               NAME                ATTEMPT             POD ID              POD