K8S组件与容器引擎
一、服务管理
如果是kubeadm安装,相关服务管理如下:
# 1、系统服务
systemctl enable containerd # 老版本是docker
systemctl enable kubelet
systemctl restart containerd # 老版本是docker
systemctl restart kubelet
# 2、静态pod
# 注意:kube-proxy是daemonset,而不是静态pod(静态pod由kubelet单独管理)。
[root@k8s-master-01 ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-6d58d46f65-2bm7z 1/1 Running 0 37h
coredns-6d58d46f65-f492h 1/1 Running 0 37h
etcd-node 1/1 Running 452 37h
kube-apiserver-node 1/1 Running 443 37h
kube-controller-manager-node 1/1 Running 5 37h
kube-proxy-kztlj 1/1 Running 0 37h
kube-proxy-tlwtt 1/1 Running 0 37h
kube-proxy-wrtjn 1/1 Running 0 37h
kube-scheduler-node 1/1 Running 5 37h
[root@k8s-master-01 ~]#
### 1.3 总结与归纳
系统服务(所有节点上都有):
- 容器引擎:负责容器创建,镜像加速
- kubelet:kubelet汇报自己的节点的状态,负责调度容器引擎管理容器。
master节点:(两个系统服务,4个静态pod)
- apiserver
- scheduler
- controller-mananger
- etcd
worker节点:(两个系统服务,一个kube-proxy,kube-proxy不是静态pod,而是由daemonset控制器启动的pod)
- kube-proxy ---> 用于管理svc
- 业务pod
- coredns
- 网络组件如 flannel
静态pod的yaml配置
# 静态pod由kubelet管理,kubelet会定期扫描这些文件并加载配置,所以修改后不需要重启kubelet
[root@k8s-master-01 ~]# ll /etc/kubernetes/manifests/
total 16
-rw------- 1 root root 2432 Jun 23 04:05 etcd.yaml
-rw------- 1 root root 3407 Jun 23 04:05 kube-apiserver.yaml
-rw------- 1 root root 2913 Jun 23 04:05 kube-controller-manager.yaml
-rw------- 1 root root 1499 Jun 23 04:05 kube-scheduler.yaml
kubectl 怎么连接apiserver
[root@k8s-master-01 ~]# ll ~/.kube/
total 8
drwxr-x--- 4 root root 35 Jun 23 04:07 cache
-rw------- 1 root root 5657 Jun 23 04:06 config # 就靠这个配置文件
(了解即可)如果你采用的是二进制部署,那相关服务管理如下:
# worker node
systemctl enable containerd # 老版本是docker
systemctl enable kubelet
systemctl enable flannel
systemctl enable kube-proxy
systemctl restart containerd # 老版本是docker
systemctl restart kubelet
systemctl restart flannel
systemctl restart kube-proxy
# master node
systemctl enable etcd
systemctl enable kube-controller-manager
systemctl enable kube-scheduler
systemctl restart etcd
systemctl restart kube-controller-manager
systemctl restart kube-scheduler
注意: 删除docker0网桥,如果cni0隧道网卡与docker0网桥ip地址冲突,会导致网络问题,此时我们应该删掉docker0,因为我们用的是cni0,删除命令如下:
yum -y install bridge-utils
ifconfig docker0 down
brctl delbr docker0
二、容器引擎客户端命令
2.1 containerd介绍
对比着来看,作为k8s容器运行时,containerd跟docker的对比
2.1.1 调用链路的区别
在V1.24起的版本的 kubelet 就彻底移除了dockershim,改为默认使用Containerd了,当然也使用 cri-dockerd 适配器来将 Docker Engine 与 Kubernetes 集成。可以参考官方文档:https://kubernetes.io/zh-cn/docs/setup/production-environment/container-runtimes/#docker

kubelet --> dockershim(k8s功能) --> docker --> containerd --> container
kubelet --> cri-containerd(containerd功能) --> containerd --> container
2.1.2 标准输出日志路径的区别
容器有两种日志:业务日志和标准输出日志
- 业务日志直接丢到程序自定义的日志文件中
- 标准输出日志则会被保存到宿主机的一个json文件中(跟容器不同,宿主机自己的标准输出是直接丢掉的)
针对容器内的标准输出日志, 即容器应用直接打印到终端的内容,有/dev/stdout与/dev/stderr两种,默认情况下会将二者统一存入宿主机上的一个json文件中。
- docker引擎用docker logs可以直接查看该json日志里的内容
- containerd引擎可以用crictl查看。
容器日志及相关参数如下:
| 对比项 | docker | containerd |
|---|---|---|
| 存储路径 | 如果 Kubernetes 使用 Docker 作为容器运行时,容器日志的落盘由docker来完成,日志通常存储在 /var/lib/docker/containers/<container-id>/<container-id>-json.log |
如果 Kubernetes 使用 containerd 作为容器运行时,容器日志的落盘由kubelet来完成,路径 /var/log/pods/<namespace>_<pod-name>_<pod-uid>/<container-name>/<container-id>.log,同时在/var/log/containers目录下创建软链接,指向日志文件 |
| 配置参数 | 在docker配置文件中指定:"log-driver": "json-file","log-opts": {"max-size": "100m","max-file": "5"} |
方法一:在kubelet参数中指定: --container-log-max-files=5 --container-log-max-size=100Mi方法二:在KubeletConfiguration中指定: "containerLogMaxSize": "100Mi", "containerLogMaxFiles": 5 |
| 把容器日志保存到数据盘 | 把数据盘挂载到"data-root"(缺省是/var/lib/docker)即可 | 创建一个软链接/var/log/pods指向数据盘挂载点下的某个目录。在TKE中选择"将容器日志保存到数据盘",会自动创建软链接/var/log/pods |
示例:k8s采用containerd作为容器运行时查看标准输出日志
[root@k8s-master-01 study]# cat test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: registry.cn-shanghai.aliyuncs.com/egon-k8s-test/busybox:v1.0
name: nginx
command: ["sh","-c","while true;do echo 111 ;sleep 1;done"]
status: {}
[root@k8s-master-01 study]# kubectl apply -f test.yaml
deployment.apps/web created
[root@k8s-node-01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-587b6775f8-jhfqh 1/1 Running 0 38m
[root@k8s-node-01 ~]# ll /var/log/containers/web-587b6775f8-jhfqh_default_nginx-309b96044a4dbcdbdef7dce0ac72eb09aabb2ad449a8738a9dad07d123c8e99e.log
lrwxrwxrwx 1 root root 91 8月 6 19:54 /var/log/containers/web-587b6775f8-jhfqh_default_nginx-309b96044a4dbcdbdef7dce0ac72eb09aabb2ad449a8738a9dad07d123c8e99e.log -> /var/log/pods/default_web-587b6775f8-jhfqh_3dc50a3d-fdcf-4fc2-bc51-fb0e29050072/nginx/0.log
日志切割实验:
1、了解kubelet的配置(前面我们了解到以containerd为runc时,容器的标准输出日志是由kubelet控制的)
先登录到需要做日志切割的那台机器上,然后执行systemctl status kubelet查看kubelet当前系统服务配置路径,发现为/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
可以看到,k8s启动参数解读
# 用于集群初建立时kubelet与apiserver临时通信凭证,完成集群搭建后已经自动删掉了。
--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf
# kubelet 与 apiserver 通信用的正式身份认证凭证(kubeconfig)
--kubeconfig=/etc/kubernetes/kubelet.conf
# kubelet 的核心配置文件
--config=/var/lib/kubelet/config.yaml
# 使用 containerd 作为容器运行时,通过本地 Unix Socket 通信
--container-runtime-endpoint=unix:///var/run/containerd/containerd.sock
# 指定 Pod 基础容器(pause 容器 / sandbox 容器)镜像
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9
10-kubeadm.conf 由kubeadm安装时生成,用于告诉systemd怎么启动kubelet。

2、配置日志轮转参数
配置文件:vim /var/lib/kubelet/kubeadm-flags.env
新增参数:--container-log-max-files=5 --container-log-max-size='5Ki'
KUBELET_KUBEADM_ARGS="--container-runtime-endpoint=unix:///var/run/containerd/containerd.sock --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9 --container-log-max-files=5 --container-log-max-size='5Ki'"
3、测试日志轮转
在default名称空间下创建一个测试pod
[root@k8s-master-01 study]# cat test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: registry.cn-shanghai.aliyuncs.com/egon-k8s-test/busybox:v1.0
name: nginx
command: ["sh","-c","while true;do echo 111 ;sleep 1;done"]
status: {}
[root@k8s-master-01 study]# kubectl apply -f test.yaml
deployment.apps/web created
[root@k8s-master-01 study]# kubectl get pod -n default
NAME READY STATUS RESTARTS AGE
web-587b6775f8-nf92f 1/1 Running 0 7s
[root@k8s-master-01 study]#

2.1.3 配置文件路径
containerd配置文件/etc/containerd/config.toml
# 默认配置中还有两个关于存储的配置路径:
# 1、保存持久化数据,包括 Snapshots, Content, Metadata 以及各种插件的数据
root = "/var/lib/containerd"
# 2、保存运行时的临时数据的,包括 sockets、pid、挂载点、运行时状态以及不需要持久化的插件数据。
state = "/run/containerd"
2.1.4 stream server
kubectl exec/logs等命令需要在apiserver跟容器运行时之间建立流转发通道。
docker API本身提供stream服务,kubelet内部的docker-shim会通过docker API做流转发。
containerd的stream服务需要单独配置:

在k8s 1.11之前,kubelet并不会做stream proxy, 只会做redirect。也就是把containerd暴露的stream server地址告诉apiserver, 让apiserver直接来访问containerd的stream server。这种情况下,需要给stream server使能tls认证来做安全防护。
从k8s1.11引入了kubelet stream proxy (https://github.com/kubernetes/kubernetes/pull/64006),从而使得containerd stream server只需要监听本地地址即可。
2.1.5 CNI网络
| 对比项 | docker | containerd |
|---|---|---|
| 谁负责调用CNI | kubelet内部的docker-shim | containerd内置的cri-plugin(containerd 1.1以后) |
| 如何配置CNI | kubelet参数 --cni-bin-dir 和 --cni-conf-dir |
containerd配置文件(toml): plugins."io.containerd.grpc.v1.cri".cnibin_dir = "/opt/cni/bin"conf_dir = "/etc/cni/net.d" |
2.2 containerd客户端命令介绍
2.2.1 crictl、ctr命令
更换 Containerd 后,以往我们常用的 docker 命令也不再使用,取而代之的分别是 crictl 和 ctr 两个命令客户端。
# 1、crictl 命令(k8s提供)
crictl 是遵循 CRI 接口规范的一个命令行工具,通常用它来检查和管理kubelet节点上的容器运行时和镜像。
# 2、ctr 命令(containerd提供)
ctr 是 containerd 的一个客户端工具。
crictl与ctr二者的区别总结:
`ctr -v` 输出的是 containerd 的版本
`crictl -v` 输出的是当前 k8s 的版本,从结果显而易见你可以认为 crictl 是用于 k8s 的。
使用crictl命令之前,需要先配置/etc/crictl.yaml如下(不配置的话,你用该命令会一直报warn警告):
cat > /etc/crictl.yaml << 'EOF'
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
也可以通过命令进行设置(会自动生成/etc/crictl.yaml):
crictl config runtime-endpoint unix:///run/containerd/containerd.sock
crictl config image-endpoint unix:///run/containerd/containerd.sock
简单操作:
# 1、
[root@k8s-node-01 ~]# ctr ns ls
NAME LABELS
default
k8s.io
moby
[root@k8s-node-01 ~]# ctr -n k8s.io image ls
# 2、crictl 没有-n参数,操作都在`k8s.io`命名空间下。
crictl images
crictl pods
2.2.2 nerdctl命令
前面我们介绍了可以使用 ctr 操作管理 containerd 镜像容器,但是大家都习惯了使用 docker cli,ctr 使用起来可能还是不太顺手,为了能够让大家更好的转到 containerd 上面来,社区提供了一个新的命令行工具:nerdctl。nerdctl 是一个与 docker cli 风格兼容的 containerd 客户端工具,而且直接兼容 docker compose 的语法的,这就大大提高了直接将 containerd 作为本地开发、测试或者单机容器部署使用的效率。
安装:
# 如果没有安装 containerd,则可以下载 nerdctl-full-<VERSION>-linux-amd64.tar.gz 包进行安装
wget https://github.com/containerd/nerdctl/releases/download/v1.7.6/nerdctl-1.7.6-linux-amd64.tar.gz
mkdir -p /usr/local/containerd/bin/ && tar -zxvf nerdctl-1.7.6-linux-amd64.tar.gz nerdctl && mv nerdctl /usr/local/containerd/bin/
ln -s /usr/local/containerd/bin/nerdctl /usr/local/bin/nerdctl
[root@k8s-node-01 ~]# nerdctl version # 报错warn,提示buildkit未安装
WARN[0000] unable to determine buildctl version: exec: "buildctl": executable file not found in $PATH
Client:
Version: v1.7.6
安装buildkit(参考: https://zhuanlan.zhihu.com/p/366671300 ):
wget https://github.com/moby/buildkit/releases/download/v0.13.2/buildkit-v0.13.2.linux-amd64.tar.gz
# 解压后得到一个bin目录,把这个bin目录放到 $PATH 里去
简单使用:
[root@k8s-node-01 ~]# nerdctl ns ls
NAME CONTAINERS IMAGES VOLUMES LABELS
default 0 1 0
k8s.io 8 24 0
moby 0 0 0
[root@k8s-node-01 ~]# nerdctl -n k8s.io images
容器客户端命令无法操作镜像与容器两种东西,说到镜像,拉取时就涉及到配置镜像加速的问题,所以这些客户端命令暂且不着急详细介绍使用,先来看下配置镜像加速的问题。
注意: 镜像加速不是关键。镜像加速不是关键,镜像加速不是什么重要知识点。配置镜像加速无非是想从一些开源镜像仓库里拿镜像,这种完全你可以利用阿里云海外服务器的方法来构建,真正在公司中我们使用的是私有镜像仓库。所以镜像加速的问题并不需要纠结。
2.3 containerd配置镜像加速
2.3.1 储备知识
注意: 网上大多数配置containerd镜像加速的文章都是直接修改:`/etc/containerd/config.toml`配置文件,这种方式在较新版本的contaienrd中已经被废弃,将来肯定会被移除,只不过现在还可以使用而已。另外,这种方式有一个不好的地方就是,每次修改`/etc/containerd/config.toml`配置文件,都需要执行`systemctl restart containerd.service`命令重启containerd。
新版本的containerd镜像仓库配置都是建议放在一个单独的文件夹当中,并且在`/etc/containerd/config.toml`配置文件当中打开`config_path`配置,指向镜像仓库配置目录即可。这种方式只需要在第一次修改`/etc/containerd/config.toml`文件打开`config_path`配置时需要重启containerd,后续我们增加镜像仓库配置都无需重启containerd,非常方便。
若我们在/etc/containerd/config.toml配置文件中指定config_path = /etc/containerd/certs.d,那么containerd镜像仓库的格式如下:
$ tree /etc/containerd/certs.d
/etc/containerd/certs.d
/etc/containerd/certs.d/
├── 192.168.11.20
│ └── hosts.toml
└── docker.io
└── hosts.toml
可以看到,第一级目录为镜像仓库的域名或者IPADDR,第二级为hosts.toml文件。
hosts.toml文件中的内容仅支持: server, capabilities, ca, client, skip_verify, [header], override_path
hosts.toml文件示例如下(了解一下):
[host."https://mirror.registry"]
capabilities = ["pull"]
ca = "/etc/certs/mirror.pem"
skip_verify = false
[host."https://mirror.registry".header]
x-custom-2 = ["value1", "value2"]
[host."https://mirror-bak.registry/us"]
capabilities = ["pull"]
skip_verify = true
[host."http://mirror.registry"]
capabilities = ["pull"]
[host."https://test-1.registry"]
capabilities = ["pull", "resolve", "push"]
ca = ["/etc/certs/test-1-ca.pem", "/etc/certs/special.pem"]
client = [["/etc/certs/client.cert", "/etc/certs/client.key"],["/etc/certs/client.pem", ""]]
[host."https://test-2.registry"]
client = "/etc/certs/client.pem"
[host."https://test-3.registry"]
client = ["/etc/certs/client-1.pem", "/etc/certs/client-2.pem"]
[host."https://non-compliant-mirror.registry/v2/upstream"]
capabilities = ["pull"]
override_path = true
配置私有镜像harbor:
新建目录,以实际配置的私有域名为准,如这里私有镜像地址为harbor.node.com,则需要新建这个域名的目录:
mkdir -p /etc/containerd/certs.d/harbor.node.com
在/etc/containerd/certs.d/harbor.node.com创建hosts.toml:
server = "https://harbor.node.com"
[host."https://harbor.node.com"]
capabilities = ["pull", "resolve"]
skip_verify = true # 跳过证书验证
2.3.2 为docker.io配置镜像加速
1、首先配置指定config_path,只配置一次即可,后续为其他库配置镜像加速都无需再次指定了:
$ vim /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d" # 原来config_path = ""
systemctl daemon-reload
systemctl restart containerd
2、然后为docker.io配置镜像加速:
# docker hub镜像加速
mkdir -p /etc/containerd/certs.d/docker.io
cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF
server = "https://docker.io"
[host."https://registry-1.docker.io"]
capabilities = ["pull", "resolve"]
[host."https://docker.211678.top"]
capabilities = ["pull", "resolve"]
[host."https://docker.1panel.live"]
capabilities = ["pull", "resolve"]
[host."https://hub.rat.dev"]
capabilities = ["pull", "resolve"]
[host."https://docker.m.daocloud.io"]
capabilities = ["pull", "resolve"]
[host."https://do.nark.eu.org"]
capabilities = ["pull", "resolve"]
[host."https://dockerpull.com"]
capabilities = ["pull", "resolve"]
[host."https://dockerproxy.cn"]
capabilities = ["pull", "resolve"]
[host."https://docker.awsl9527.cn"]
capabilities = ["pull", "resolve"]
EOF
验证(强调:对于nerdctl命令来说,会自动使用/etc/containerd/certs.d目录下的配置镜像加速,但是对于ctr命令,需要指定--hosts-dir=/etc/containerd/certs.d):
$ ctr image pull docker.io/library/centos:7 --hosts-dir=/etc/containerd/certs.d
$ nerdctl pull docker.io/library/centos:7
$ nerdctl pull docker.io/library/ubuntu:20.04
2.3.3 为其他库配置镜像加速(了解)
注意,下面镜像仓库都是使用了daocloud的镜像仓库,daocloud镜像仓库并非支持所有镜像的下载,其支持的镜像列表可以参考:daocloud镜像仓库支持列表( https://github.com/DaoCloud/public-image-mirror/blob/main/mirror.txt )gitee版本( https://gitee.com/daocloud/public-image-mirror )
# registry.k8s.io镜像加速
mkdir -p /etc/containerd/certs.d/registry.k8s.io
tee /etc/containerd/certs.d/registry.k8s.io/hosts.toml << 'EOF'
server = "https://registry.k8s.io"
[host."https://k8s.m.daocloud.io"]
capabilities = ["pull", "resolve", "push"]
EOF
# docker.elastic.co镜像加速
mkdir -p /etc/containerd/certs.d/docker.elastic.co
tee /etc/containerd/certs.d/docker.elastic.co/hosts.toml << 'EOF'
server = "https://docker.elastic.co"
[host."https://elastic.m.daocloud.io"]
capabilities = ["pull", "resolve", "push"]
EOF
# gcr.io镜像加速
mkdir -p /etc/containerd/certs.d/gcr.io
tee /etc/containerd/certs.d/gcr.io/hosts.toml << 'EOF'
server = "https://gcr.io"
[host."https://gcr.m.daocloud.io"]
capabilities = ["pull", "resolve", "push"]
EOF
# ghcr.io镜像加速
mkdir -p /etc/containerd/certs.d/ghcr.io
tee /etc/containerd/certs.d/ghcr.io/hosts.toml << 'EOF'
server = "https://ghcr.io"
[host."https://ghcr.m.daocloud.io"]
capabilities = ["pull", "resolve", "push"]
EOF
# k8s.gcr.io镜像加速
mkdir -p /etc/containerd/certs.d/k8s.gcr.io
tee /etc/containerd/certs.d/k8s.gcr.io/hosts.toml << 'EOF'
server = "https://k8s.gcr.io"
[host."https://k8s-gcr.m.daocloud.io"]
capabilities = ["pull", "resolve", "push"]
EOF
# mcr.microsoft.com镜像加速
mkdir -p /etc/containerd/certs.d/mcr.microsoft.com
tee /etc/containerd/certs.d/mcr.microsoft.com/hosts.toml << 'EOF'
server = "https://mcr.microsoft.com"
[host."https://mcr.m.daocloud.io"]
capabilities = ["pull", "resolve", "push"]
EOF
# nvcr.io镜像加速
mkdir -p /etc/containerd/certs.d/nvcr.io
tee /etc/containerd/certs.d/nvcr.io/hosts.toml << 'EOF'
server = "https://nvcr.io"
[host."https://nvcr.m.daocloud.io"]
capabilities = ["pull", "resolve", "push"]
EOF
# quay.io镜像加速
mkdir -p /etc/containerd/certs.d/quay.io
tee /etc/containerd/certs.d/quay.io/hosts.toml << 'EOF'
server = "https://quay.io"
[host."https://quay.m.daocloud.io"]
capabilities = ["pull", "resolve", "push"]
EOF
# registry.jujucharms.com镜像加速
mkdir -p /etc/containerd/certs.d/registry.jujucharms.com
tee /etc/containerd/certs.d/registry.jujucharms.com/hosts.toml << 'EOF'
server = "https://registry.jujucharms.com"
[host."https://jujucharms.m.daocloud.io"]
capabilities = ["pull", "resolve", "push"]
EOF
# rocks.canonical.com镜像加速
mkdir -p /etc/containerd/certs.d/rocks.canonical.com
tee /etc/containerd/certs.d/rocks.canonical.com/hosts.toml << 'EOF'
server = "https://rocks.canonical.com"
[host."https://rocks-canonical.m.daocloud.io"]
capabilities = ["pull", "resolve", "push"]
EOF
查看目录结构:
$ tree /etc/containerd/certs.d/
/etc/containerd/certs.d/
├── docker.elastic.co
│ └── hosts.toml
├── docker.io
│ └── hosts.toml
├── gcr.io
│ └── hosts.toml
├── ghcr.io
│ └── hosts.toml
├── k8s.gcr.io
│ └── hosts.toml
├── mcr.microsoft.com
│ └── hosts.toml
├── nvcr.io
│ └── hosts.toml
├── quay.io
│ └── hosts.toml
├── registry.jujucharms.com
│ └── hosts.toml
├── registry.k8s.io
│ └── hosts.toml
└── rocks.canonical.com
└── hosts.toml
各个镜像仓库加速验证操作如下:
注意:
1、对于nerdctl命令来说,会自动使用/etc/containerd/certs.d目录下的配置镜像加速,但是对于ctr命令,需要指定--hosts-dir=/etc/containerd/certs.d。举个栗子:ctr i pull --hosts-dir=/etc/containerd/certs.d registry.k8s.io/sig-storage/csi-provisioner:v3.5.0,如果要确定此命令是否真的使用了镜像加速,可以增加--debug=true参数,譬如:ctr --debug=true i pull --hosts-dir=/etc/containerd/certs.d registry.k8s.io/sig-storage/csi-provisioner:v3.5.0
2、测试不同的仓库加速
# 1、registry.k8s.io镜像仓库验证
nerdctl --debug=true image pull registry.k8s.io/sig-storage/csi-provisioner:v3.5.0
# 2、k8s.gcr.io镜像仓库验证
nerdctl --debug=true image pull k8s.gcr.io/kube-apiserver:v1.17.3
# 3、docker.io镜像仓库验证
nerdctl --debug=true image pull docker.io/library/ubuntu:20.04
2.4 客户端命令
储备知识:镜像与容器存放的名称空间
可以用-n指定名称空间,可以将镜像或者容器分散到不同的空间内,但并非所有命令都支持。
| 事项 | docker | ctr(containerd) | crictl(kubernetes) | nerdctl |
|---|---|---|---|---|
| 是否支持 | 不支持 | 支持 | 不支持 | 支持 |
| 示例 | ctr ns lsctr -n k8s.io image ls # 查看指定名称空间下的镜像ctr -n k8s.io container ls # 查看指定名称空间下的容器 |
默认所有操作都在k8s.io名称空间下 | nerdctl -n k8s.io image lsnerdctl -n k8s.io container ls |
再次强调:上面说的名称空间的概念适用于镜像以及容器。
2.4.1 镜像相关命令
| 命令 | docker | ctr(containerd) | crictl(kubernetes) | nerdctl |
|---|---|---|---|---|
| 查看本地镜像列表 | docker images |
ctr image ls |
crictl images |
同docker命令 |
| 下载/拉取镜像 | docker pull |
ctr image pull |
crictl pull |
同docker命令 |
| 给镜像打标签 | docker tag |
ctr image tag |
无 | 同docker命令 |
| 上传/推送镜像 | docker push |
ctr image push |
无 | 同docker命令 |
| 删除本地镜像 | docker rmi |
ctr image rm |
crictl rmi |
同docker命令 |
| 查看镜像详情 | docker inspect |
无 | crictl inspecti # 注意末尾是小写字母i |
同docker命令 |
| 导出镜像 | docker save |
ctr image export |
无 | 同docker命令 |
| 导入镜像 | docker load |
ctr image import xx.tar docker.io/library/nginx:alpine |
无 | 同docker命令 |
| 登录镜像仓库 | docker login |
不支持,理由:ctr 工具主要是用于底层的容器操作和管理,而不是直接与镜像仓库进行交互如推拉镜像等。 | 不支持,理由:主要用于管理 Pod 和容器,而非直接与镜像仓库交互。 | 支持 |
1、ctr(containerd)
# 1、查看
ctr image ls # 分字段展示
ctr image ls -q # 展示一个地址,如docker.io/library/nginx:alpine
ctr image check # 检测default名称空间下所有镜像的可用性,主要看STATUS为complete代表可用
# 2、拉取 Docker Hub 官方镜像 nginx:alpine,需要注意的是镜像地址需要加上 docker.io Host 地址
ctr images pull docker.io/library/nginx:alpine
# 3、重新打标签
ctr image tag docker.io/library/nginx:alpine harbor.k8s.local/course/nginx:alpine
# 4、上传镜像
ctr images push docker.io/library/nginx:alpine --user xxx
# 5、删除镜像
ctr image rm harbor.k8s.local/course/nginx:alpine
# 6、查看镜像详情
无
# 7、将镜像导出为压缩包
ctr image export nginx.tar.gz docker.io/library/nginx:alpine
ctr -n k8s.io image export a.tar.gz registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.11.1
# 8、从压缩包导入镜像
ctr image import nginx.tar.gz
ctr -n default image import a.tar.gz
直接导入可能会出现类似于 `ctr: content digest sha256:xxxxxx not found` 的错误,要解决这个办法需要 pull 可以通用/适用所有平台的镜像:
➜ ctr i pull --all-platforms docker.io/library/nginx:alpine
➜ ctr i export --all-platforms nginx.tar.gz docker.io/library/nginx:alpine
➜ ctr i rm docker.io/library/nginx:alpine
➜ ctr i import nginx.tar.gz
# 9、将镜像挂载到主机目录
ctr image mount docker.io/library/nginx:alpine /mnt
ctr image unmount /mnt
# 10、命名空间:Containerd 也有 namespaces 的概念,镜像或容器可以分散到不同的空间,对于多租户的场景十分有用
ctr ns ls
ctr ns create test
ctr ns rm test
ctr -n test image ls
说明:
- Docker 其实也是默认调用的 containerd,事实上 Docker 使用的 containerd 下面的命名空间默认是 moby,而不是 default
- Kubernetes 下使用的 containerd 默认命名空间是 k8s.io
2、crictl(kubernetes)
crictl操作的均在k8s.io命名空间,且crictl 是只有一个k8s.io命名空间,但是没有-n 参数。
# 1、crictl 没有-n参数,操作都在`k8s.io`命名空间下。
# crictl image list 等同于 ctr -n=k8s.io image list
# crictl image ls 等同于 ctr -n=k8s.io image ls
# crictl images 等同于 ctr -n=k8s.io image list
# crictl images 等同于 ctr -n=k8s.io image ls
【温馨提示】
1、ctr images pull 拉取的镜像默认放在default
2、而 crictl pull 和 kubelet 默认拉取的镜像都在 k8s.io 命名空间下。
所以通过ctr导入镜像的时候特别注意一点,最好指定命名空间。
3、nerdctl
# 镜像管理
nerdctl images
nerdctl pull docker.io/library/busybox:latest
nerdctl login --username=egonlinhaifeng --password xxx registry.cn-shanghai.aliyuncs.com # nerdctl logout
nerdctl tag centos:7 registry.cn-shanghai.aliyuncs.com/egon/test:v1.0
nerdctl push registry.cn-shanghai.aliyuncs.com/egon/test:v1.0
nerdctl save -o busybox.tar.gz busybox:latest
nerdctl load -i busybox.tar.gz
nerdctl rmi busybox
ctr不能build镜像,我们可以用nerdctl:
# 1、Dockerfile文件如下
FROM centos:7
CMD sleep 1000
# 2、构建镜像
nerdctl build -t test:v1.0 -f Dockerfile .
可以看到有一个错误提示,需要我们安装 `buildctl` 并运行 `buildkitd`,这是因为 `nerdctl build` 需要依赖 `buildkit` 工具。
buildkit项目也是 Docker 公司开源的一个构建工具包,支持 OCI 标准的镜像构建。它主要包含以下部分:
1. 服务端 `buildkitd`:当前支持 runc 和 containerd 作为 worker,默认是 runc,我们这里使用 containerd
2. 客户端 `buildctl`:负责解析 Dockerfile,并向服务端 buildkitd 发出构建请求
buildkit 是典型的 C/S 架构,客户端和服务端是可以不在一台服务器上,而 `nerdctl` 在构建镜像的时候也作为 `buildkitd` 的客户端,所以需要我们安装并运行 `buildkitd`。
安装buildkit:
wget https://github.com/moby/buildkit/releases/download/v0.13.2/buildkit-v0.13.2.linux-amd64.tar.gz
tar -zxvf buildkit-v0.13.2.linux-amd64.tar.gz -C /usr/local/containerd/
ln -s /usr/local/containerd/bin/buildkitd /usr/local/bin/buildkitd
ln -s /usr/local/containerd/bin/buildctl /usr/local/bin/buildctl
cat > /etc/systemd/system/buildkit.service << "EOF"
[Unit]
Description=BuildKit
Documentation=https://github.com/moby/buildkit
[Service]
ExecStart=/usr/local/bin/buildkitd --oci-worker=false --containerd-worker=true
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable buildkit --now
systemctl status buildkit.service
然后重新构建镜像:
如果不用-f制定构建文件,默认找的不是dockerfile而是Containerfile,-f之后可以是任意名字。
[root@k8s-node-01 test]# nerdctl build -t test:v1.0 -f Dockerfile .
FATA[0000] lstat /test/Containerfile: no such file or directory
[root@k8s-node-01 test]# ls
dockerfile
[root@k8s-node-01 test]# mv dockerfile Containerfile
[root@k8s-node-01 test]# nerdctl build -t test:v1.0 -f Dockerfile .
[root@k8s-node-01 test]# nerdctl images
REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZE BLOB SIZE
test v1.0 b1dd8c2e8f41 33 seconds ago linux/amd64 239.6 MiB 79.7 MiB
启动测试:
nerdctl run -d --name=test test:v1.0
nerdctl container ls
nerdctl exec -ti test sh
2.4.2 容器相关命令
| 命令 | docker | ctr(containerd) | crictl(kubernetes) | nerdctl |
|---|---|---|---|---|
| 显示本地运行的容器列表 | docker ps |
ctr task ls/ctr container ls |
crictl ps |
同docker命令 |
| 创建一个新的容器 | docker create |
ctr container create |
crictl create |
同docker命令 |
| 运行一个新的容器 | docker run |
ctr run |
无(最小单元为 pod) | 同docker命令 |
| 启动容器 | docker start |
ctr task start |
crictl start |
同docker命令 |
| 关闭容器 | docker stop |
ctr task kill |
crictl stop |
同docker命令 |
| 删除容器 | docker rm |
ctr container rm |
crictl rm |
同docker命令 |
| 查看容器详情 | docker inspect |
ctr container info |
crictl inspect |
同docker命令 |
| 查看容器日志 | docker logs |
无 | crictl logs |
同docker命令 |
| 查看容器资源 | docker stats |
无 | crictl stats |
同docker命令 |
| 登录或在容器内部执行命令 | docker exec |
无 | crictl exec |
同docker命令 |
| 清空不用的容器 | docker image prune |
无 | crictl rmi --prune |
同docker命令 |
1、ctr(containerd)
# 9、容器操作
# 9.1 创容器
ctr image pull docker.io/library/nginx:alpine --hosts-dir=/etc/containerd/certs.d
ctr container create docker.io/library/nginx:alpine nginx
# 9.2 查看
ctr container ls
ctr container ls -q
ctr container info nginx
# 9.3 删除
ctr container rm nginx
# 9.4 任务
## (1)任务介绍
# 上面用container create只是创建了一个静态的容器对象,把运行容器需要的资源及配置数据例如namespaces、rootfs和容器的配置都初始化完毕了,但是容器内的进程还没有启动,即容器尚未处于运行状态
## (2) 启动任务(激活容器)
ctr task start -d nginx # nginx是你创建的容器名字
## (3)查看
[root@k8s-node-01 ~]# ctr task ls
TASK PID STATUS
nginx 113846 RUNNING
## (4)进入容器
# 注意必须要指定 --exec-id 参数,这个 id 可以随便写,只要唯一就行。
ctr task exec --exec-id 0 -t nginx sh
## (5)暂停容器
ctr task pause nginx # 可以查看容器ctr task ls发现状态变成PAUSED
## (6)恢复容器
ctr task resume nginx
## (7)ctr无法stop容器,只能暂停或杀死
ctr task kill nginx # 可以查看容器ctr task ls发现状态变成STOPPED
## (8)删掉
ctr task rm nginx
## (9)获取容器cgroup相关信息(内存、CPU 和 PID 的限额与使用量。)
ctr task metrics nginx # 记得要先启动才能看:ctr task start -d nginx
## (10)看容器中所有进程在宿主机中的 PID
ctr task ps nginx # 第一行的就对应容器内的1号进程
2、crictl(略)
3、nerdctl
# 1、容器管理
nerdctl run -d -p 80:80 --name=nginx --restart=always nginx:alpine
nerdctl exec -it nginx /bin/sh
nerdctl ps
nerdctl ps -a
nerdctl inspect nginx
nerdctl logs
nerdctl logs -f
nerdctl stop nginx
nerdctl rm nginx
nerdctl rm -f nginx
2.4.3 pod相关命令
了解即可,主要通过k8s启停管理pod。
| 命令 | docker | ctr(containerd) | crictl(kubernetes) | nerdctl |
|---|---|---|---|---|
| 显示POD列表 | 无 | 无 | crictl pods |
无 |
| 查看POD详情 | 无 | 无 | crictl inspectp pod的id号 |
无 |
更多命令操作,可以直接在命令行输入命令查看帮助:
docker --help
ctr --help
crictl --help

浙公网安备 33010602011771号