1 K8s 核心组件使用指南
K8s集群组件

Kubelet : 每个工作节点上运行的节点代理
kubelet是在每个节点上运行的主要 "节点代理"。
即:
Kubelet是 kubernetes 工作节点 上的一个代理组件 ,运行在每个节点上。

Kubelet是工作节点 上的主要服务 ,定期从kube-apiserver组件接收新的或修改的Pod规范 ,并确保Pod及其容器 在期望规范下运行。同时该组件作为工作节点的监控组件 ,向
kube-apiserver汇报主机的运行状况。

- 它可以使用以下方式之一向 API 服务器注册:
- 主机名(hostname);
- 覆盖主机名的参数;
- 特定于某云驱动的逻辑。
kubelet是基于PodSpec来工作的。
- 每个
PodSpec是一个描述 Pod 的 YAML 或 JSON 对象。kubelet接受通过各种机制(主要是通过apiserver)提供的一组PodSpec,并确保这些PodSpec中描述的容器处于运行状态且运行状况良好。kubelet不管理不是由Kubernetes创建的容器。
- 除了来自 API 服务器的
PodSpec之外,还可以通过以下两种方式将容器清单 (manifest)提供给kubelet。
- 文件(File):利用命令行参数传递路径。kubelet 周期性地监视此路径下的文件是否有更新。 监视周期默认为 20s,且可通过参数进行配置。
- HTTP 端点(HTTP endpoint):利用命令行参数指定 HTTP 端点。 此端点的监视周期默认为 20 秒,也可以使用参数进行配置。
参考文献
Kubeadm : k8s 部署工具
组件简介
Kubeadm是一个提供了kubeadm init和kubeadm join的工具, 作为创建Kubernetes集群的 "快捷途径" 的最佳实践。kubeadm通过执行必要的操作来启动和运行最小可用集群。
按照设计,它只关注启动引导 ,而非配置机器。
同样的, 安装各种 "锦上添花" 的扩展,例如 Kubernetes Dashboard、 监控方案、以及特定云平台的扩展,都不在讨论范围内。
相反,k8s官方希望在
kubeadm之上构建更高级别以及更加合规的工具, 理想情况下,使用kubeadm作为所有部署工作的基准 将会更加易于创建一致性集群。
常用命令
kubeadm init用于搭建控制平面节点kubeadm join用于搭建工作节点并将其加入到集群中
|---|-----------------------------------------------------------------------------------------------------------|
| | kubeadm join 172.16.1.72:6443 --token 67yn2j.pwv6zn6ci59bw8ma \ |
| | --discovery-token-ca-cert-hash sha256:ef39262b36489b6f6e8df35af5d921cdee7a4de01148544e2f28c18f5c3d7d1d |
kubeadm upgrade用于升级 Kubernetes 集群到新版本kubeadm config如果你使用了 v1.7.x 或更低版本的 kubeadm 版本初始化你的集群,则使用 kubeadm upgrade 来配置你的集群kubeadm token用于管理 kubeadm join 使用的令牌
|---|----------------------------------------------------------------------------------------------------------------------------------|
| | # 在kubeadm init后,没有记录kubeadm join 及其token信息,如何查询? 答: 再生成一个token即可: |
| | kubeadm token create --print-join-command |
| | |
| | # 查看历史的token |
| | kubeadm token list |
| | TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS |
| | zlwgj5.3euou24y2rb9b3sh 23h 2026-04-20T02:00:23Z authentication,signing <none> system:bootstrappers:kubeadm:default-node-token |
| | |
| | |
| | # 再生成一个token |
| | kubeadm token create --print-join-command |
kubeadm reset用于恢复通过 kubeadm init 或者 kubeadm join 命令对节点进行的任何变更kubeadm certs用于管理 Kubernetes 证书kubeadm kubeconfig用于管理 kubeconfig 文件kubeadm version用于打印 kubeadm 的版本信息kubeadm alpha用于预览一组可用于收集社区反馈的特性
参考文献
Kubectl : k8s 命令行工具
组件简介
Kubernetes提供kubectl是使用Kubernetes API与Kubernetes集群 的控制面板 进行通信的**【命令行工具】**。
这个工具叫做
kubectl。
- 即:
kubectl作为客户端CLI工具 ,可以让用户 通过命令行 的方式对Kubernetes集群进行操作。
- 针对配置信息,
kubectl在$HOME/.kube目录中查找一个名为config的配置文件。
你可以通过设置
KUBECONFIG环境变量或设置--kubeconfig参数来指定其它kubeconfig文件。
- 有关每个命令的详细信息,包括所有受支持的参数和子命令, 请参阅 kubectl 参考文档。
有关安装说明,请参见安装 kubectl; 如需快速指南,请参见备忘单。
如果你更习惯使用 docker 命令行工具, Docker 用户的 kubectl 介绍了一些 Kubernetes 的等价命令。
kubectl可操作的资源对象类型: ns / svc / rc / ...
| 资源对象的名称 | 缩写 |
|---|---|
| cluster | |
| componentstatuses | cs |
| configmaps | cm |
| daemonsets | ds |
| deployments | deploy |
| endpoints | ep |
| events | ev |
| horizontalpodautoscalers | hpa |
| ingresses | ing |
| Jobs | |
| limitranges | limits |
| nodes | no |
| namespaces | ns |
| networkpolicies | |
| statefulsets | |
| persistentvolumeclaims | pvc |
| persistentvolumes | pv |
| pods | po |
| podsecuritypolicies | psp |
| podtemplate | |
| replicasets | rs |
| replicationcontrollers | rc |
| resourcequotas | quota |
| cronjob | |
| secrets | |
| serviceaccounts | |
| services | svc |
| storageclasses | sc |
| thirdpartyresources |
语法格式
|---|---------------------------------------------|
| | $ kubectl [command] [TYPE] [NAME] [flags] |
(1)command :子命令,指定要对一个或多个资源执行的操作。例如create、delete、describe、get、apply等。
(2)TYPE:资源对象的类型,不区分大小写,能以单数形式、复数形式或者简写形式表示。例如:以下3种TYPE是等价的。
|---|---------------------------|
| | $ kubectl get pod pod1 |
| | $ kubectl get pods pod1 |
| | $ kubectl get po pod1 |
(3)NAME:资源对象的名称,区分大小写。如果不指定名称,则系统将返回属于TYPE的全部对象的列表,例如$ kubectl get pods将返回所有Pod的列表。
在对多个资源执行操作时,你可以按类型和名称指定每个资源,或指定一个或多个文件:
(4)flags :kubectl子命令的可选参数。例如,可使用-s或--server参数指定指定apiserver的URL地址和端口,而不用默认值。
- 在一个命令行 中也可以同时对多个资源对象进行操作,以多个TYPE和NAME的组合表示,示例如下。
|---|--------------------------------------------------------------|
| | $ kubectl get pods pod1 pod2 |
| | |
| | $ kubectl get pod/pod1 rc/rc1 |
| | |
| | $ kubectl get pod -f pod1.yaml -f pod2.yaml |
| | $ kubectl create -f pod1.yaml -f rc1.yaml -f service1.yaml |
- 用一个或多个文件指定资源:
-f file1 -f file2 -f file<#>
- 使用
YAML而不是JSON
因为 YAML 对用户更友好, 特别是对于配置文件。
例子:
kubectl get -f ./pod.yaml
- 注意,从命令行指定的参数 会覆盖默认值和任何相应的环境变量。
- 如果你需要帮助,在终端窗口中运行
kubectl help
kubectl 输出格式
kubectl 的输出格式
| 输出格式 | 说明 |
|---|---|
-o=custom-columns=<spec> |
根据自定义列名进行输出,以逗号分隔 |
-o=custom-colimns-file=<filename> |
从文件中获取自定义列名进行输出 |
-o=json |
以JSON格式显示结果 |
-o=jsonpath=<template> |
输出jsonpath表达式定义的字段信息 |
-o=jsonpath-file=<filename> |
输出jsonpath表达式定义的字段信息,来源于文件 |
-o=name |
仅输出资源对象的名称 |
-o=wide |
输出额外信息。对于Pod资源,将输出Pod所在的Node名 |
-o=yaml |
以yaml格式显示结果 |
常见输出格式:
- 显示Pod的更多信息
|---|----------------------------------------------------------------|
| | $ kubectl get pod <pod-name> -o wide |
| | 或 |
| | $ kubectl get pod <pod-name> --namespace <namespace> -o wide |
- 以yaml格式显示Pod的详细信息
|---|----------------------------------------|
| | $ kubectl get pod <pod-name> -o yaml |
- 以自定义列名显示Pod的信息
|---|-----------------------------------------------------------------------------------------------------|
| | $ kubectl get pod <pod-name> -o=custom-columns=NAME:.metadata.name,RSRC:.metadata.resourceVersion |
- 基于文件的自定义列名输出
|---|---------------------------------------------------------------------|
| | $ kubectl get pods <pod-name> -o=custom-columns-file=template.txt |
- 还可以将输出结果按某个字段排序,通过--sort-by参数以jsonpath表达式进行指定
|---|--------------------------------------------------------------|
| | $ kubectl [command] [TYPE] [NAME] --sort-by=<jsonpath_exp> |
例如,按照名字进行排序
|---|-------------------------------------------------------------|
| | $ kubectl get pods |
| | NAME READY STATUS RESTARTS AGE |
| | chaosfomoney-deployment-64ccd59bdc-h72gh 1/1 Running 0 1d |
| | chaosfomoney-deployment-64ccd59bdc-spnpj 1/1 Running 0 1d |
| | chaosfomoney-deployment-64ccd59bdc-xhnjr 1/1 Running 0 1d |
| | |
| | $ kubectl get pods --sort-by=.metadata.name |
| | NAME READY STATUS RESTARTS AGE |
| | chaosfomoney-deployment-64ccd59bdc-h72gh 1/1 Running 0 1d |
| | chaosfomoney-deployment-64ccd59bdc-spnpj 1/1 Running 0 1d |
| | chaosfomoney-deployment-64ccd59bdc-xhnjr 1/1 Running 0 1d |
常用命令
kubectl create : 创建资源对象
- 根据yaml配置文件一次创建service和rc
|---|-----------------------------------------------------|
| | $ kubectl create -f my-service.yaml -f my-rc.yaml |
- 根据
<directory>目录下所有.yaml、.yml、.json文件的定义进行创建操作
|---|-----------------------------------|
| | $ kubectl create -f <directory> |
kubectl apply : 以文件或标准输入为准应用或更新资源
|---|---------------------------------------------------------------|
| | # 使用 example-service.yaml 中的定义创建 Service。 |
| | kubectl apply -f example-service.yaml |
| | |
| | # 使用 example-controller.yaml 中的定义创建 replication controller。 |
| | kubectl apply -f example-controller.yaml |
| | |
| | # 使用 <directory> 路径下的任意 .yaml、.yml 或 .json 文件 创建对象。 |
| | kubectl apply -f <directory> |
kubectl edit : 直接编辑 K8s 集群的资源对象(Pod/Deployment/Service/...)
- 简要介绍
kubectl edit: 允许直接编辑 Kubernetes 集群中的资源对象(如 Pod、Deployment、Service 等),修改后会立即生效 ,无需手动执行kubectl apply。- 本质流程:拉取资源当前配置 → 打开编辑器修改 → 提交更新到集群。
- 掌握 kubectl edit 可极大提升 Kubernetes 资源管理效率,但需谨慎操作以避免意外影响。
- 使用语法
- 方式1: 编辑指定资源
|---|----------------------------------------------------|
| | kubectl edit <资源类型> <资源名称> -n <命名空间> |
| | |
| | # 示例:编辑名为 "nginx" 的 Deployment |
| | kubectl edit deployment nginx -n default |
| | |
| | kubectl edit daemonset -n kube-system kube-proxy |
- 方式2: 通过文件格式指定资源
|---|-----------------------------------|
| | # 编辑指定 YAML 文件对应的资源 |
| | kubectl edit -f deployment.yaml |
- 核心参数
| 参数 | 说明 |
|---|---|
| -o / --output | 指定编辑格式(如 yaml、json),默认由 KUBE_EDITOR 环境变量决定 |
| --record | 在资源注解中记录本次修改的命令(用于审计) |
| --windows-line-endings | 使用 Windows 换行符(CRLF) |
| --allow-missing-template-keys | 允许模板中缺失字段(默认 true) |
| --field-manager | 指定字段管理器名称(用于 Server-Side Apply) |
| --validate | 修改后验证配置合法性(默认 true,设为 false 可跳过验证) |
- 高级功能与技巧
- 指定编辑器
默认使用 vim,可通过环境变量切换编辑器:
|---|--------------------------------------------------------------------|
| | # 使用 nano 编辑器 |
| | export KUBE_EDITOR="nano" |
| | kubectl edit deploy/nginx |
| | |
| | # 临时指定编辑器(无需修改环境变量) |
| | KUBE_EDITOR="code --wait" kubectl edit deploy/nginx # 使用 VS Code |
- 编辑特定资源版本
|---|--------------------------------------------------------------------|
| | # 显示资源版本、并指定版本编辑 |
| | kubectl get deploy nginx -o yaml | grep resourceVersion # 获取当前版本 |
| | kubectl edit deploy/nginx --resource-version=<版本号> |
- 编辑多个资源
结合标签选择器批量操作
|---|-------------------------------------------|
| | # 编辑所有包含 "app=web" 标签的 Pod |
| | kubectl edit pods -l app=web -n default |
- 快速定位字段
在编辑器中直接搜索关键字(如 replicas、image),快速修改核心参数。
- 常见使用场景
- 实时调整副本数
|---|--------------------------------|
| | kubectl edit deploy/nginx |
| | # 修改 replicas 字段 → 保存退出后立即生效 |
- 更新容器镜像
|---|------------------------------------------------------|
| | kubectl edit deploy/nginx |
| | # 修改 spec.template.spec.containers[0].image → 保存退出 |
- 修改 ConfigMap/Secret
|---|-------------------------------------------------|
| | # 编辑 ConfigMap |
| | kubectl edit cm app-config -n default |
| | |
| | # 编辑 Secret(注意:Base64 编码值需自行处理) |
| | kubectl edit secret db-credentials -n default |
- 调试资源限制
|---|-----------------------------------------------------|
| | kubectl edit deploy/nginx |
| | # 调整 resources.limits 和 resources.requests → 保存退出 |
- 注意事项
- 并发修改冲突
若资源被其他用户或控制器修改,提交时会提示版本冲突(需重新拉取最新版本后编辑)。- 格式校验严格
YAML 格式错误(如缩进错误、键名错误)会导致提交失败,需仔细检查。- 生产环境谨慎使用
直接修改运行中的资源可能引发服务中断,建议在测试环境验证后再操作。- 备份原始配置
重要操作前备份当前配置:
|---|--------------------------------------------------------|
| | kubectl get deploy/nginx -o yaml > nginx-backup.yaml |
- FAQ / 常见问题排查
- 错误:Edit cancelled, no changes made
原因:编辑器未正确保存修改(如直接关闭未保存)。
解决:重新执行命令并确保保存修改。
- 错误:invalid configuration
原因:YAML 格式或字段值不合法。
解决:
|---|----------------------------------------------|
| | # 关闭验证后强制提交(不推荐) |
| | kubectl edit deploy/nginx --validate=false |
- 错误:the object has been modified
原因:资源版本过期(其他人已修改过)。
解决:重新执行 kubectl edit 获取最新版本。
- 替代方案
| 场景 | 替代命令 | 说明 |
|---|---|---|
| 少量字段修改 | kubectl patch | 无需进入编辑器,直接通过 JSON 或 YAML 片段修改 |
| 批量修改 | kubectl apply -f updated.yaml | 通过文件更新配置 |
| 查看历史修改记录 | kubectl rollout history | 查看 Deployment 等资源的修订历史 |
- 参考文献
kubectl get : 列出一个或多个资源(pod/rc/service/ds)
|---|--------------------------------------------------------------------------------|
| | # 获取集群所有的节点 |
| | kubectl get node 或 kubectl get no |
| | |
| | # 查看rc和service列表 |
| | kubectl get rc,service |
| | |
| | # 以纯文本输出格式列出所有 Pod |
| | kubectl get pods |
| | |
| | # 查询指定节点名(如: edge-1)的 所有 pod |
| | kubectl get pod -A -o wide | grep edge-1 |
| | |
| | # 以纯文本输出格式列出所有 Pod,并包含附加信息(如【节点名】)。 |
| | kubectl get pods -o wide |
| | |
| | # 以纯文本输出格式列出具有指定名称的副本控制器。提示:你可以使用别名 'rc' 缩短和替换 'replicationcontroller' 资源类型。 |
| | kubectl get replicationcontroller <rc-name> |
| | |
| | # 以纯文本输出格式列出所有副本控制器和 Service。 |
| | kubectl get rc,services |
| | |
| | # 以纯文本输出格式列出所有守护程序集,包括未初始化的守护程序集。 |
| | kubectl get ds --include-uninitialized |
| | |
| | # 列出在节点 server01 上运行的所有 Pod |
| | kubectl get pods --field-selector=spec.nodeName=server01 |
- 查询pod
|---|-------------------------|
| | kubectl get pod pod1 |
| | kubectl get pods pod1 |
| | kubectl get po pod1 |
- 按命名空间查询pod
|---|---------------------------------------------------|
| | kubectl get pod |
| | # 等效于(命名空间=default): kubectl get pod -n default |
| | |
| | # 查询所有命名空间下的 pod |
| | kubectl get pod --all-namespaces |
| | |
| | # 根据指定命名空间,查询其下的 pod | 不带等同 -n default |
| | kubectl get pods -n kube-system |
示例:



kubectl get pod local-path-provisioner-844bd8758f-mvgr9 --namespace local-path-storage -o wide
kubectl describe pod local-path-provisioner-844bd8758f-mvgr9 -n local-path-storage
kubectl logs local-path-provisioner-844bd8758f-6grj7 --namespace local-path-storage --all-containers
- 查询所有 Pod,并显示 Node 信息(IP / hostname 等)
|---|-------------------------------------------------------------------------------------------------------------------------|
| | [root@k8s-master-1 ~]# kubectl get pods -A -o wide |
| | //等效于: kubectl get pods --all-namespaces -o wide 或 kubectl get pod --all-namespaces -o wide |
| | NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES |
| | kube-flannel kube-flannel-ds-lgrbd 1/1 Running 2 (28h ago) 3d3h 172.12.12.72 k8s-master-1 <none> <none> |
| | kube-flannel kube-flannel-ds-wv2j6 0/1 Init:0/2 0 26h 172.12.12.244 edge-1 <none> <none> |
| | kube-system coredns-c676cc86f-nzj2x 1/1 Running 1 (28h ago) 3d3h 172.10.34.4 k8s-master-1 <none> <none> |
| | kube-system coredns-c676cc86f-s88tw 1/1 Running 1 (28h ago) 3d3h 172.10.34.5 k8s-master-1 <none> <none> |
| | kube-system etcd-k8s-master-1 1/1 Running 1 (28h ago) 3d3h 172.12.12.72 k8s-master-1 <none> <none> |
| | kube-system kube-apiserver-k8s-master-1 1/1 Running 1 (28h ago) 3d3h 172.12.12.72 k8s-master-1 <none> <none> |
| | kube-system kube-controller-manager-k8s-master-1 1/1 Running 1 (28h ago) 3d3h 172.12.12.72 k8s-master-1 <none> <none> |
| | kube-system kube-proxy-c7vf9 0/1 ContainerCreating 0 26h 172.12.12.244 edge-1 <none> <none> |
| | kube-system kube-proxy-l9g4h 1/1 Running 1 (28h ago) 3d3h 172.12.12.72 k8s-master-1 <none> <none> |
| | kube-system kube-scheduler-k8s-master-1 1/1 Running 1 (28h ago) 3d3h 172.12.12.72 k8s-master-1 <none> <none> |
| | kubeedge cloud-iptables-manager-wrdjk 1/1 Running 0 28h 172.12.12.72 k8s-master-1 <none> <none> |
| | kubeedge cloudcore-ffd866959-zblcp 1/1 Running 0 32h 172.12.12.72 k8s-master-1 <none> <none> |
- 查询系统命名空间下的pod
|---|---------------------------------------------------------------------|
| | [root@k8s-master-1 ~]# kubectl get pods -n kube-system |
| | NAME READY STATUS RESTARTS AGE |
| | coredns-c676cc86f-nzj2x 1/1 Running 1 (29h ago) 3d3h |
| | coredns-c676cc86f-s88tw 1/1 Running 1 (29h ago) 3d3h |
| | etcd-k8s-master-1 1/1 Running 1 (29h ago) 3d3h |
| | kube-apiserver-k8s-master-1 1/1 Running 1 (29h ago) 3d3h |
| | kube-controller-manager-k8s-master-1 1/1 Running 1 (29h ago) 3d3h |
| | kube-proxy-c7vf9 0/1 ContainerCreating 0 26h |
| | kube-proxy-l9g4h 1/1 Running 1 (29h ago) 3d3h |
| | kube-scheduler-k8s-master-1 1/1 Running 1 (29h ago) 3d3h |
- 查询系统命名空间下,Status为
ContainerCreating的 pod name
|---|--------------------------------------------------------------------------------------------------------------|
| | [root@k8s-master-1 ~]# kubectl get pods -n kube-system | grep ContainerCreating | awk '{print $1}' | xargs |
| | kube-proxy-c7vf9 |
kubectl delete : 删除资源对象
|---|-----------------------------------------------------|
| | # 删除所有Pod |
| | kubectl delete pods --all |
| | |
| | # 基于pod.yaml定义的名称删除Pod |
| | $ kubectl delete -f pod.yaml |
| | |
| | # 删除所有包含某个label的Pod和Service |
| | $ kubectl delete pod,service -l name=<label-name> |
kubectl exec : 执行容器的命令
- 执行Pod的date命令,默认使用Pod的第1个容器执行
|---|----------------------------------|
| | $ kubectl exec <pod-name> date |
- 指定Pod中某个容器执行date命令
|---|------------------------------------------------------|
| | $ kubectl exec <pod-name> -c <container-name> date |
- 通过bash获得Pod中某个容器的TTY、在Pod 的容器内进行调试,相当于登陆容器 <remark=IMPORTANT>
|---|---------------------------------------------------------------|
| | $ kubectl exec -ti <pod-name> -c <container-name> /bin/bash |
| | |
| | 或者: |
| | kubectl get pod <pod-name> -o wide # 获取节点 |
| | # SSH 到节点后 |
| | crictl pods --name <pod-name> # 找到 Pod ID |
| | crictl ps -p <pod-id> # 查看 Pod 中的容器 |
| | crictl logs <container-id> # 查看日志 |
| | crictl exec -it <container-id> /bin/sh # SSH 到节点后 |
kubectl describe : 显示一个或多个资源的详细状态,默认情况下包括未初始化的资源
|---|--------------------------------------------|
| | # 显示名为 <pod-name> 的 Pod 的详细信息。 |
| | kubectl describe nodes <node-name> |
| | |
| | # 显示名为 <pod-name> 的 Pod 的详细信息。 |
| | kubectl describe pods/<pod-name> |
| | |
| | # 显示由名为 <rc-name> 的副本控制器管理的所有 Pod 的详细信息。 |
| | # 记住:副本控制器创建的任何 Pod 都以副本控制器的名称为前缀。 |
| | kubectl describe pods <rc-name> |
| | |
| | # 描述所有的 Pod |
| | kubectl describe pods |

kubectl logs : 打印 Pod 中容器的日志
|---|-----------------------------------------------------------------------------------------------------------|
| | # 返回 Pod <pod-name> 的日志快照 |
| | kubectl logs <pod-name> |
| | |
| | # 从 Pod <pod-name> 开始流式传输日志。这类似于 'tail -f' Linux 命令 |
| | kubectl logs -f <pod-name> |
| | |
| | # 获取最近一小时内的 Pod 日志 |
| | kubectl logs --since=1h <pod名称> |
| | |
| | # 获取 Pod 的最近 100 行日志 (排查异常Pod的重要命令) |
| | kubectl logs --tail=100 <pod-name> --namespace <namespace> |
| | |
| | # 获取 Pod 内所有容器的日志 (排查异常Pod的重要命令,尤其是 Pod 的 init 容器初始化异常时) <remark=IMPORTANT> |
| | kubectl logs --tail=100 <pod-name> --namespace <namespace> --all-containers |
| | 如: kubectl logs local-path-provisioner-844bd8758f-6grj7 --namespace local-path-storage --all-containers |


典型使用场景
CASE 基于 kubectl 查看指定 pod 内有哪些容器
可以通过以下几种方式查看 Pod 内包含的容器:
实现方式
0. kubectl describe(最常用)
|---|--------------------------------------------------|
| | kubectl describe pod <pod-name> -n <namespace> |
输出中会显示 Containers 部分,列出所有容器名称、镜像、状态等信息。
输出示例:
|---|--------------------------------------------------|
| | $ kubectl describe pod nginx-deployment-abc123 |
| | |
| | Name: nginx-deployment-abc123 |
| | Namespace: default |
| | ... |
| | Containers: |
| | nginx: ← 容器1名称 |
| | Image: nginx:1.21 |
| | Port: 80/TCP |
| | State: Running |
| | ... |
| | sidecar: ← 容器2名称(如果有) |
| | Image: busybox:latest |
| | ... |
| | Init Containers: ← Init 容器(如果有) |
| | init-myservice: |
| | Image: busybox:1.28 |
1. crictl ps -p <pod-id> (最常用)
|---|-----------------------------------------------------------------------------------------------|
| | # 查看指定 Pod 的容器列表 |
| | crictl ps -p <pod-id> |
| | 或 crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock ps -p <pod-id> |
| | 如: crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock ps -p 65908c4e20d60 |
| | CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD |
| | 6f2f81987f223 73deb9a3f7025 8 hours ago Running etcd 3 65908c4e20d60 etcd-vm-a |
2. kubectl get pod -o yaml/json(详细信息)
|---|----------------------------------------------------------------------------------------|
| | # YAML 格式 |
| | kubectl get pod <pod-name> -o yaml |
| | |
| | # JSON 格式(可用 jq 过滤) |
| | kubectl get pod <pod-name> -n <namespace> -o json | jq '.status.containerStatuses[]' |
| | 或 |
| | kubectl get pod <pod-name> -o json | jq '.spec.containers[].name' |
3. kubectl get pod 自定义输出(简洁查看)
|---|--------------------------------------------------------------------------------------------------------|
| | # 只显示容器名称列表 |
| | kubectl get pod <pod-name> -o jsonpath='{range .spec.containers[*]}{.name}{"\n"}{end}' |
| | |
| | # 显示容器名 + 镜像 |
| | kubectl get pod <pod-name> -o jsonpath='{range .spec.containers[*]}{.name}{"\t"}{.image}{"\n"}{end}' |
4. 使用 kubectl 插件/工具
|---|--------------------------------------------------------------|
| | # 使用 kubectl-view-allocations 等插件 |
| | # 或结合 grep |
| | kubectl describe pod <pod-name> | grep -A 20 "Containers:" |
Init 容器 vs 普通容器
| 类型 | 查看方式 |
|---|---|
| 普通容器 | .spec.containers |
| Init 容器 | .spec.initContainers |
| Ephemeral 容器 | .spec.ephemeralContainers |
|---|----------------------------------------------------------------------------------------------|
| | # 查看 Init 容器 |
| | kubectl get pod <pod-name> -o jsonpath='{range .spec.initContainers[*]}{.name}{"\n"}{end}' |
快速命令别名(可选)
添加到 .bashrc 或 .zshrc:
|---|---------------------------------------------------------------------------------------------|
| | # 查看 Pod 容器列表 |
| | alias kpc='kubectl get pod -o jsonpath="{range .spec.containers[*]}{.name}{\"\n\"}{end}"' |
| | |
| | # 使用:kpc <pod-name> |
这些命令适用于任何 Kubernetes 集群,无需额外工具。
参考文献
k9s的部分功能,依赖kubectl/kubectl在 windows 的安装与配置
ctr : containerd 的原生命令行工具(基于具体节点)
- ctr 是 containerd 官方提供的底层命令行工具 ,直接与 containerd 守护进程通信 ,用于管理容器生命周期的各个底层组件。
简言之:*K8s的容器运行时(CRI)组件 := ctr **
核心特点
| 特性 | 说明 |
|---|---|
| 底层原生 | 直接操作 containerd,无抽象层 |
| 功能完整 | 支持完整的容器、镜像、快照、任务管理能力 |
| 学习价值 | 帮助理解容器运行时内部架构 |
| 轻量独立 | 不依赖 Kubernetes,可单独使用 |
架构关系
|---|------------------------------------------------|
| | ┌─────────┐ ┌─────────────┐ ┌─────────────┐ |
| | │ ctr │────→│ containerd │────→│ runc/shim │ |
| | │ (CLI) │ │ (daemon) │ │ (runtime) │ |
| | └─────────┘ └─────────────┘ └─────────────┘ |
| | ↑ |
| | 直接通过 containerd.sock 通信 |
常用操作命令
1. 命名空间(Namespace)
containerd 使用命名空间 隔离资源,Kubernetes 使用 k8s.io 作为默认命名空间。
|---|-------------------------------|
| | # 查看所有命名空间 |
| | ctr ns ls |
| | |
| | # 指定命名空间操作(默认是 default) |
| | ctr -n k8s.io containers ls |
| | ctr -n default images ls |
2. 容器(Containers)
|---|------------------------------------------------|
| | # 列出容器(注意:这是 containerd 层面的容器,不是 Pod) |
| | ctr containers ls |
| | ctr -n k8s.io c ls # 简写形式 |
| | |
| | # 查看容器详情 |
| | ctr containers info <container-id> |
| | ctr -n k8s.io containers info <container-id> |
| | |
| | # 创建/运行容器(底层操作,通常不直接使用) |
| | ctr containers create <image> <container-id> |
| | ctr tasks start <container-id> |
3. 任务(Tasks)------ 实际运行进程
-
containerd 中,容器 是元数据,任务(Task) 才是真正运行的进程。
-
ctr 中 Container 和 Task 是 1:1 关系,Task ID 即 Container ID。
|---|----------------------------------------------------------------------------------------------------------|
| | # 查看运行中的任务 |
| | ctr tasks ls |
| | ctr -n k8s.io t ls |
| | //如: |
| | //TASK PID STATUS |
| | //2b7379cd7e8071a759a5da957a4764dbe9abd033b0473bf57938e05e8397342a 5806 RUNNING |
| | //... |
| | |
| | # 查看任务详情(包含 PID 等) |
| | ctr tasks info <task-id> |
| | 或 ctr -n k8s.io tasks ls | grep -i <container-id / task-id> |
| | //如: ctr -n k8s.io tasks ls | grep -i 2b7379cd7e8071a759a5da957a4764dbe9abd033b0473bf57938e05e8397342a |
| | //TASK PID STATUS |
| | //2b7379cd7e8071a759a5da957a4764dbe9abd033b0473bf57938e05e8397342a 5806 RUNNING |
| | |
| | # 启动/停止/删除任务 |
| | ctr tasks start <container-id> |
| | ctr tasks pause <task-id> |
| | ctr tasks resume <task-id> |
| | ctr tasks kill -9 <task-id> |
| | ctr tasks delete <task-id> |
| | |
| | # 进入容器(类似 docker exec) |
| | ctr tasks exec --exec-id shell1 -t <task-id> /bin/sh |
4. 镜像(Images)
- 列出镜像 / 查看已下载的镜像
|---|--------------------------------------------------|
| | ctr images ls 或: ctr images list 或: ctr i ls |
| | |
| | //查看 k8s containerd 指定命名空间的镜像 |
| | ctr -n k8s.io images list 或 ctr -n k8s.io i ls |
- 拉取镜像
|---|--------------------------------------------------------------------------------------|
| | ctr images pull docker.io/library/nginx:latest |
| | |
| | //下载镜像使用ctr命令拉取镜像时,需要指定配置加速镜像地址 |
| | ctr images pull docker.io/library/nginx:latest --hosts-dir=/etc/containerd/certs.d |
ctr images pull拉取的镜像默认放在default命名空间,而crictl pull和kubelet默认拉取的镜像都在k8s.io命名空间下。
- 修改镜像标签
|---|---------------------------------------------------------------------|
| | ctr images tag nginx docker.io/library/nginx:latest nginx:v1.20.1 |
- 导入/导出镜像
|---|--------------------------------------------------------------------|
| | # 导入镜像 |
| | ctr images import /path/to/image.tar |
| | |
| | # 导出镜像,名字为 nginx-latest.img |
| | ctr images export nginx-lates.img docker.io/library/nginx:latest |
- 导入镜像: 将docker中的镜像导入到k8s的containerd
|---|----------------------------------------------------------------------------------------|
| | //step1 拉取镜像 |
| | docker pull calico/cni:v3.26.1 |
| | docker pull calico/node:v3.26.1 |
| | docker pull calico/kube-controllers:v3.26.1 |
| | |
| | //step2 导入 docker 镜像 到 containerd |
| | ctr -n k8s.io images import <(docker save calico/cni:v3.26.1) |
| | ctr -n k8s.io images import <(docker save calico/node:v3.26.1) |
| | ctr -n k8s.io images import <(docker save calico/kube-controllers:v3.26.1) |
| | |
| | //或: ctr images import --platform linux/amd64 nginx-latest.img # 导入镜像,需要指定平台名字,否则会报错 |
- 挂载镜像
|---|---------------------------------------------------------|
| | # 挂载镜像,方便查看镜像中包含的内容,将镜像挂载到本地 卸载命令: umount /mnt |
| | ctr images mount docker.io/library/nginx:latest /mnt/ |
- 删除镜像
|---|------------------------------------------------|
| | ctr images rm docker.io/library/nginx:latest |
- 查看镜像内容(不提取)
|---|-----------------------------------------------------------------|
| | ctr images mount docker.io/library/nginx:latest /mnt/nginx-fs |
5. 快照(Snapshots)------ 文件系统层
|---|-------------------------------------|
| | # 查看快照 |
| | ctr snapshots ls |
| | |
| | # 查看快照信息(挂载点、层信息) |
| | ctr snapshots info <snapshot-key> |
ctr中镜像、容器、任务、快照的概念与关系?
- ctr 核心概念关系图
Task Layer
Container Layer
Snapshot Layer
Image Layer
基于
引用
绑定
镜像 Image
只读模板
快照 Snapshot
可写文件系统层
容器 Container
元数据对象
任务 Task
运行中的进程
- 四层结构速查
| 层级 | 本质 | 生命周期 | 类比 |
|---|---|---|---|
| Image | 只读模板 | 持久 | 类定义 |
| Snapshot | 可写文件系统 | 随容器创建/删除 | 实例属性 |
| Container | 配置元数据 | 创建后长期存在 | 实例对象 |
| Task | OS 进程 | 启停频繁 | 线程 |
- 关键关系
|---|-----------------------------------------------------------------------------|
| | 创建流程: Image → [unpack] → Snapshot → [create] → Container → [start] → Task |
| | 删除流程: Task [kill] → Container [delete] → Snapshot [remove] → (Image 保留) |
- 状态对比示例
| 命令 | 结果说明 |
|---|---|
ctr images ls |
nginx:1.21(模板,无状态) |
ctr snapshots ls |
nginx:1.21 + 可写层(已挂载) |
ctr containers ls |
my-nginx(配置,可能未运行) |
ctr tasks ls |
my-nginx: PID 1234(运行中进程) |
-
核心要点
-
Image ≠ 运行中的东西 --- 只是 tar+metadata
-
Container 不运行 --- 只有配置,类似
docker create后的状态 -
Task 才是进程 --- 对应 Linux PID,可以
kill但保留 Container 配置- containerd 中,容器 是元数据,任务(Task) 才是真正运行的进程。
- ctr 中 Container 和 Task 是 1:1 关系,Task ID 即 Container ID。
-
Snapshot 隔离写操作 --- 多个 Container 可共享同一 Image 的不同 Snapshot
-
管理镜像的方式对比: docker vs. k8s单机 containerd vs. k8s集群 crictl
-
docker管理镜像: docker使用
docker images管理镜像 -
单机containerd管理镜像:使用
ctr images命令管理镜像,containerd本身的CLI -
k8s集群中containerd管理镜像:使用
crictl images命令管理镜像,k8s社区专用的CLI工具
containerd支持oci标准的镜像,所以可以使用docker官方或者dockerfile构建的镜像
与 crictl 核心对比
| 维度 | ctr | crictl |
|---|---|---|
| 操作对象 | 容器(Container)、任务(Task)、快照(Snapshot) | Pod、CRI 容器 |
| 命名空间 | 必须显式指定 -n k8s.io |
自动使用 CRI 配置 |
| Pod 概念 | ❌ 无 Pod 概念 | ✅ 原生支持 Pod |
| Pause 容器 | 作为独立任务显示 | 自动归类到 Pod 中 |
| 适用场景 | 底层调试、镜像管理、学习原理 | Kubernetes 运维 |
典型使用场景
场景 1:手动运行独立容器(无需 K8s)
|---|-------------------------------------------------------------------|
| | # 1. 拉取镜像 |
| | ctr images pull docker.io/library/redis:latest |
| | |
| | # 2. 创建容器 |
| | ctr containers create docker.io/library/redis:latest redis-demo |
| | |
| | # 3. 创建任务(运行) |
| | ctr tasks start redis-demo |
| | |
| | # 4. 查看运行状态 |
| | ctr tasks ls |
场景 2:排查 Kubernetes 底层问题
|---|------------------------------------------|
| | # 进入节点,查看 containerd 层面 |
| | ctr -n k8s.io tasks ls | grep <pod-id> |
| | |
| | # 对比 crictl(更直观) |
| | crictl ps -p <pod-id> # 直接看到 Pod 关联的容器 |
场景 3:镜像导入导出(离线传输) : 导出指定节点的 containerd 镜像,并导入到另一节点
核心思路:
|---|-------------------------------------------------------------------------------|
| |ctr -n k8s.io images ls|
| | |
| |# 导出节点镜像|
| |ctr -n k8s.io images export nginx-backup.tar docker.io/library/nginx:latest|
| | |
| |# 导入到另一节点|
| |ctr images import nginx-backup.tar|
场景4:导出 docker 指定镜像、并导入到 k8s 的 containerd
- step1 导出 docker 镜像
|---|-------------------------------------------------------------------------------------|
| | # 保存镜像为 tar 包 |
| | docker save -o myimage_tag.tar myimage:tag |
| | //如: docker save -o /root/k8s-my-archive-images/busybox_latest.tar busybox:latest |
| | |
| | # 或: 压缩保存(推荐,节省空间) |
| | docker save myimage:tag | gzip > myimage.tar.gz |
- step2 传输到 k8s 节点 (可选)
|---|------------------------------------------|
| | # 方式1: 直接 scp 到目标节点 |
| | scp myimage.tar.gz user@k8s-node:/tmp/ |
| | |
| | # 方式2: 如果节点无法直接访问,通过跳板机或共享存储 |
- step3 导入到 k8s 的 containerd
在 Kubernetes 节点上执行:
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| | # 解压(如果是 tar.gz 压缩包) |
| | gunzip myimage.tar.gz |
| | |
| | # 使用 ctr 导入镜像(containerd 原生工具) |
| | ctr -n k8s.io images import myimage.tar |
| | //如: |
| | //# ctr -n k8s.io images import /root/k8s-my-archive-images/busybox_latest.tar |
| | //unpacking docker.io/library/busybox:latest (sha256:b0109bc2759f71080904a173fe95ea9d307e7431b114cc9885b55ae98e09e7e5)...done |
| | # 或 批量导入多个镜像到 containerd: |
| | for img in ./dir/*.tar; do |
| | ctr -n k8s.io images import "$img" |
| | done |
| | |
| | |
| | # 验证导入成功 |
| | ctr -n k8s.io images list | grep myimage |
| | //如: |
| | //# ctr -n k8s.io images list | grep busybox |
| | // docker.io/library/busybox:latest application/vnd.oci.image.manifest.v1+json sha256:b0109bc2759f71080904a173fe95ea9d307e7431b114cc9885b55ae98e09e7e5 4.4 MiB linux/amd64 io.cri-containerd.image=managed |
常见操作命令
| 操作 | 命令 |
|---|---|
| 查看containerd版本 | containerd --version "containerd containerd.io 1.6.33 d2d58213f83a351ca8f528a95fbd145f5654e957" |
| 拉取镜像 | ctr -n k8s.io images pull docker.io/library/nginx:latest |
| 查看镜像 | ctr -n k8s.io images list |
| 查看镜像详情 | ctr -n k8s.io images inspect myimage:tag |
| 删除镜像 | ctr -n k8s.io images rm myimage:tag |
| 导出镜像 | ctr -n k8s.io images export myimage.tar myimage:tag |
| 查看容器列表 | ctr -n k8s.io containers ls |
重要概念区分
|---|--------------------------------------------------|
| | ┌─────────────────────────────────────┐ |
| | │ Kubernetes Pod │ |
| | │ ┌─────────────────────────────┐ │ |
| | │ │ Pause Container (sandbox) │ │ ← crictl 能看到 |
| | │ │ ┌─────────────────────────┐ │ │ |
| | │ │ │ App Container 1 │ │ │ ← ctr 能看到(作为独立任务) |
| | │ │ │ (nginx) │ │ │ |
| | │ │ └─────────────────────────┘ │ │ |
| | │ │ ┌─────────────────────────┐ │ │ |
| | │ │ │ App Container 2 │ │ │ ← sidecar,同样独立显示 |
| | │ │ │ (sidecar) │ │ │ |
| | │ │ └─────────────────────────┘ │ │ |
| | │ └─────────────────────────────┘ │ |
| | │ 共享 Network NS │ |
| | └─────────────────────────────────────┘ |
配置文件、调试
|---|-------------------------------------------|
| | # ctr 配置文件 |
| | cat /etc/containerd/config.toml |
| | ... |
| | config_path = "/etc/containerd/certs.d" |
| | ... |
| | |
| | # 查看 ctr 使用的 socket |
| | ctr version # 显示连接信息 |
| | |
| | # 调试模式(查看 gRPC 调用) |
| | ctr -d images ls |
总结建议
| 您的角色 | 推荐工具 |
|---|---|
| Kubernetes 用户/SRE | crictl(更直观) |
| 容器运行时开发者 | ctr(更底层) |
| 学习 containerd 原理 | ctr + 阅读源码 |
| 需要脚本化镜像管理 | ctr(独立性强) |
ctr是理解containerd架构 的钥匙,,而crictl才是 Kubernetes 生产环境的实用工具。
crictl : K8s 的容器运行时命令行工具(基于具体节点)
- crictl 是 Kubernetes 社区开发的容器运行时命令行工具 ,用于与遵循
CRI(Container Runtime Interface,容器运行时接口)规范的容器运行时进行交互。
核心特点
| 特性 | 说明 |
|---|---|
| 标准接口 | 基于 CRI 规范,与容器运行时解耦 |
| 兼容性强 | 支持 containerd、CRI-O 等主流 CRI 运行时 |
| Kubernetes 原生 | 专为 Kubernetes 场景设计,命令风格类似 kubectl |
| 调试利器 | 用于排查 Pod/容器问题,无需直接操作运行时 |
工作原理
|---|-------------------------------------------------|
| | ┌─────────┐ ┌─────────┐ ┌─────────────┐ |
| | │ crictl │────→│ CRI API │────→│ containerd │ |
| | │ (CLI) │ │ (gRPC) │ │ / CRI-O 等 │ |
| | └─────────┘ └─────────┘ └─────────────┘ |
常用操作命令
1. 基础信息查询
|---|-----------------------------------------------------------------------------------------------|
| | # 查看运行时版本信息 |
| | crictl version |
| | 或 crictl --version --runtime-endpoint unix:///var/run/containerd/containerd.sock |
| | 或 crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock version |
| | //crictl version v1.26.0 |
| | |
| | |
| | # 查看运行时状态 |
| | crictl info |
| | 或 crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock info |
| | |
| | # 列出所有镜像 |
| | crictl images |
| | 或 crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock images |
| | |
| | # 查看 Pod 列表 |
| | crictl pods |
| | 或 crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock pods |
| | |
| | # 查看指定 Pod 的容器列表 |
| | crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock ps -p <pod-id> |
| | 如: crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock ps -p 65908c4e20d60 |
| | CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD |
| | 6f2f81987f223 73deb9a3f7025 8 hours ago Running etcd 3 65908c4e20d60 etcd-vm-a |
| | |
| | # 查看容器列表 |
| | crictl ps |
| | 或 crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock ps |
| | |
2. Pod 操作
|---|-------------------------------------------------------------------------------|
| | # 查看所有 Pod(包括已停止的) |
| | crictl pods --all |
| | 或 crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock pods |
| | |
| | # 按标签过滤 Pod |
| | crictl pods --label app=nginx |
| | |
| | # 查看 Pod 详细信息 |
| | crictl inspectp <pod-id> |
| | |
| | # 查看 Pod 日志 |
| | crictl logs <pod-id> |
| | |
| | # 停止 Pod |
| | crictl stopp <pod-id> |
| | |
| | # 删除 Pod |
| | crictl rmp <pod-id> |
3. 容器操作
|---|------------------------------------------|
| | # 查看运行中的容器 |
| | crictl ps |
| | |
| | # 查看所有容器 |
| | crictl ps -a |
| | |
| | # 查看容器详情 |
| | crictl inspect <container-id> |
| | |
| | # 查看容器日志 |
| | crictl logs <container-id> |
| | |
| | # 进入容器执行命令(类似 docker exec) |
| | crictl exec -it <container-id> /bin/sh |
| | |
| | # 停止容器 |
| | crictl stop <container-id> |
| | |
| | # 删除容器 |
| | crictl rm <container-id> |
4. 镜像操作
|---|-----------------------------------------------------------------------------------------------------------|
| | # 拉取镜像 |
| | crictl pull nginx:latest |
| | 或 crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock pull docker.io/library/mysql:8.0 |
| | |
| | # 删除镜像 |
| | crictl rmi nginx:latest |
| | |
| | # 查看镜像列表 |
| | crictl images |
| | 或 crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock images |
| | |
| | # 查看镜像详情 |
| | crictl inspecti nginx:latest |
5. 实用调试技巧
|---|-------------------------------------------------|
| | # 结合 kubectl 使用:找到节点上的容器 |
| | kubectl get pod <pod-name> -o wide # 获取节点 |
| | |
| | # SSH 到节点后 |
| | crictl pods --name <pod-name> # 找到 Pod ID |
| | crictl ps -p <pod-id> # 查看 Pod 中的容器 |
| | crictl logs <container-id> # 查看日志 |
| | crictl exec -it <container-id> /bin/sh # 进入调试 |
等效于:
$ kubectl exec -ti <pod-name> -c <container-name> /bin/bash
crictl vs ctr 对比
| 对比维度 | crictl | ctr |
|---|---|---|
| 定位 | CRI 接口工具,面向 Kubernetes | containerd 原生 CLI,面向底层运维 |
| 适用范围 | 任何 CRI 运行时(containerd、CRI-O) | 仅 containerd |
| 抽象层级 | 高(Pod、Sandbox 概念) | 低(Namespace、Task、Snapshot) |
| 命令风格 | 类似 kubectl/docker,易上手 | 专业底层,学习曲线陡 |
| Kubernetes 集成 | 完美支持,能看到 Pod 结构 | 无法识别 Pod,只能看到独立容器 |
| 调试场景 | 排查 K8s Pod 问题 | 底层运行时调试、镜像管理 |
核心区别详解
1. Pod 概念支持
|---|-----------------------------------------------------|
| | # crictl - 能看到 Kubernetes Pod 结构 |
| | $ crictl pods |
| | POD ID CREATED STATE NAME NAMESPACE |
| | abc123 2 hours ago Ready nginx-pod default |
| | |
| | # ctr - 看不到 Pod,只能看到独立容器 |
| | $ ctr tasks ls |
| | TASK ID IMAGE STATUS |
| | container1 docker.io/library/nginx:latest RUNNING |
2. 容器视角差异
| 场景 | crictl | ctr |
|---|---|---|
| 查看 K8s Pod 容器 | crictl ps -p <pod-id> |
无法直接关联 |
| 查看 Pause 容器 | 自动包含在 Pod 中 | 作为独立容器显示 |
| 容器命名 | 使用 K8s 元数据命名 | 使用 containerd 内部 ID |
3. 配置方式
|---|------------------------------------------------------------|
| | # crictl - 通过 /etc/crictl.yaml 配置 |
| | cat /etc/crictl.yaml |
| | runtime-endpoint: unix:///run/containerd/containerd.sock |
| | image-endpoint: unix:///run/containerd/containerd.sock |
| | |
| | # ctr - 直接使用,或指定 namespace |
| | ctr -n k8s.io containers ls # 必须指定 namespace |
|---|------------------------------------------------------------------------------------------------------------------------------------------------------|
| |//输出样例:|
| |# ctr -n k8s.io containers ls|
| |CONTAINER IMAGE RUNTIME|
| |0ee4af3caa539bf95183f4673f5b446f7fab60dd8b874ac04a24b1ca3f493ad0 registry.aliyuncs.com/google_containers/kube-proxy:v1.28.0 io.containerd.runc.v2|
| |1ae5d5574c03129ad668fa99c0a26f7611d5db3b15888ded91526029da73ac31 registry.aliyuncs.com/google_containers/pause:3.9 io.containerd.runc.v2|
| |1c4d94a7ea153a2eb4ef97a169030f5587d2e46f3c9d788a88de5fca43244e8e docker.io/calico/node:v3.26.1 io.containerd.runc.v2|
| |250db62567abf1ca43e27fe0ab641e8d27f859ade71e548dc1c47c1ef2699682 registry.aliyuncs.com/google_containers/pause:3.9 io.containerd.runc.v2|
| |...|
配置文件: /etc/crictl.yaml
- 为避免每次执行
crictl命令时都需要带上--runtime-endpoint参数,例如:crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock images,则可通过配置来设置:
|---|------------------------------------------------------------|
| | cat <<EOF > /etc/crictl.yaml |
| | runtime-endpoint: unix:///run/containerd/containerd.sock |
| | image-endpoint: unix:///run/containerd/containerd.sock |
| | timeout: 10 |
| | debug: false |
| | EOF |
如果既不配置该文件,也不在命令中带上 endpoint 参数,则会报类似错误:
transport: Error while dialing dial unix /var/run/dockershim.sock: connect: no such file or directory
使用建议
| 场景 | 推荐工具 |
|---|---|
| Kubernetes 日常运维、Pod 调试 | crictl |
| 学习 CRI 接口、跨运行时操作 | crictl |
| containerd 底层原理研究 | ctr |
| 镜像导入导出、快照管理 | ctr |
| 编写自动化脚本(不依赖 K8s) | ctr |
典型工作流程
|---|-----------------------------------------------|
| | # 场景:排查一个 CrashLoopBackOff 的 Pod |
| | |
| | # 1. 找到节点上的 Pod ID |
| | crictl pods --name problematic-pod |
| | |
| | # 2. 查看容器状态 |
| | crictl ps -p <pod-id> --all # 查看历史容器 |
| | |
| | # 3. 查看上次退出日志 |
| | crictl logs --previous <container-id> |
| | |
| | # 4. 进入容器调试 |
| | crictl runp <pod-config.json> # 手动启动 Pod 调试 |
crictl是 Kubernetes 运维人员 的必备工具,它屏蔽了底层运行时(CRI) 的差异,提供了与 kubectl 一致的运维体验。而ctr更适合需要深入理解 containerd 架构的底层开发者。
2 FAQ for K8s 日常使用-镜像篇
Q: 配置镜像加速器?
Docker
Docker 默认配置文件路径是
/etc/docker/daemon.json
阿里云-镜像仓库
- 可以通过修改daemon配置文件
/etc/docker/daemon.json来使用加速器
需登录 阿里云的 容器镜像服务 获取属于自己的镜像地址。
|---|----------------------------------------------------------------|
| | //Linux(Ubuntu / CENTOS) |
| | |
| | //配置 daemon.json#registry-mirrors |
| | sudo mkdir -p /etc/docker |
| | sudo tee /etc/docker/daemon.json <<-'EOF' |
| | { |
| | "registry-mirrors": ["https://umxxx98d.mirror.aliyuncs.com"] |
| | } |
| | EOF |
| | |
| | // 重启 docker 服务进程 |
| | sudo systemctl daemon-reload |
| | sudo systemctl restart docker |
registry-mirrors = [ "https://registry.cn-hangzhou.aliyuncs.com" ]
注意1:阿里云镜像加速器不一定包含所有 Docker Hub 镜像,特别是较新的或小众的镜像。注意2:
403 Forbidden错误是因为 阿里云镜像加速器已关闭匿名访问权限 。从 2024 年开始,阿里云调整了镜像加速器功能 ,仅限 【阿里云用户】在【具备公网访问能力】的相关阿里云云产品资源 上使用,并且只支持拉取限定范围内的容器镜像 。会出现类似错误:(详情参见: 【产品变更】ACR镜像加速器功能调整公告-容器镜像服务-阿里云 )
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |[root@vm-a ~]# kubectl describe pod local-path-provisioner-844bd8758f-mvgr9 -n local-path-storage|
| |Events:|
| |Type Reason Age From Message|
| |---- ------ ---- ---- -------|
| |Normal BackOff 9m16s (x708 over 3h31m) kubelet Back-off pulling image "rancher/local-path-provisioner:v0.0.24"|
| |Warning Failed 4m13s (x37 over 3h31m) kubelet Failed to pull image "rancher/local-path-provisioner:v0.0.24": failed to pull and unpack image "docker.io/rancher/local-path-provisioner:v0.0.24": failed to resolve reference "docker.io/rancher/local-path-provisioner:v0.0.24": unexpected status from HEAD request to https://umxxx98d.mirror.aliyuncs.com/v2/rancher/local-path-provisioner/manifests/v0.0.24?ns=docker.io: 403 Forbidden|
- 配置完镜像加速器后,即可拉取 docker 镜像
|---|----------------------------|
| | docker pull nginx:latest |
m.daocloud.io 等其他镜像仓库
- 如果阿里云镜像仍不可用,使用其他国内源
方式1:直接基于第三方源拉取镜像
|---|------------------------------------------------------------------------------------------------------------------|
| | //拉取镜像 |
| | # docker pull m.daocloud.io/docker.io/calico/cni:v3.26.1 |
| | # docker pull m.daocloud.io/docker.io/calico/node:v3.26.1 |
| | # docker pull m.daocloud.io/docker.io/calico/kube-controllers:v3.26.1 |
| | |
| | //重新打标签为原始路径(这样 Kubernetes 能识别) |
| | # docker tag m.daocloud.io/docker.io/calico/cni:v3.26.1 docker.io/calico/cni:v3.26.1 |
| | # docker tag m.daocloud.io/docker.io/calico/node:v3.26.1 docker.io/calico/node:v3.26.1 |
| | # docker tag m.daocloud.io/docker.io/calico/kube-controllers:v3.26.1 docker.io/calico/kube-controllers:v3.26.1 |
| | |
| | //查看镜像 |
| | # docker images |
| | REPOSITORY TAG IMAGE ID CREATED SIZE |
| | calico/kube-controllers v3.26.1 1919f2787fa7 2 years ago 75.1MB |
| | m.daocloud.io/docker.io/calico/kube-controllers v3.26.1 1919f2787fa7 2 years ago 75.1MB |
| | calico/cni v3.26.1 9dee260ef7f5 2 years ago 210MB |
| | m.daocloud.io/docker.io/calico/cni v3.26.1 9dee260ef7f5 2 years ago 210MB |
| | m.daocloud.io/docker.io/calico/node v3.26.1 8065b798a4d6 2 years ago 246MB |
| | calico/node v3.26.1 8065b798a4d6 2 years ago 246MB |
- 方式2:配置
/etc/docker/daemon.json
|---|--------------------------------------------------------|
| | //Linux(Ubuntu / CENTOS) |
| | |
| | //配置 daemon.json#registry-mirrors |
| | sudo mkdir -p /etc/docker |
| | sudo tee /etc/docker/daemon.json <<-'EOF' |
| | { |
| | "registry-mirrors": ["https://docker.m.daocloud.io"] |
| | } |
| | EOF |
| | |
| | // 重启 docker 服务进程 |
| | sudo systemctl daemon-reload |
| | sudo systemctl restart docker |
K8s 的 Containerd
Containerd 默认配置文件路径是
/etc/containerd/config.toml
|---|----------------------------------------------------------------------------------------------------------------------|
| | rm -rf /etc/containerd/config.toml |
| | |
| | //修改 containerd 配置,添加镜像加速: |
| | // 1) 基于默认配置之上,编辑 containerd 配置 |
| | sudo mkdir -p /etc/containerd |
| | sudo containerd config default | sudo tee /etc/containerd/config.toml |
| | |
| | //修改 /etc/containerd/config.toml : |
| | ... |
| | [plugins."io.containerd.grpc.v1.cri"] |
| | # 修改: 1行配置 |
| | # sandbox_image = "registry.k8s.io/pause:3.6" |
| | sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9" |
| | |
| | [plugins."io.containerd.grpc.v1.cri".registry] |
| | ... |
| | # 新增:3+2行配置(不含注释行或空行) |
| | [plugins."io.containerd.grpc.v1.cri".registry.mirrors] |
| | [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] |
| | # 阿里云镜像加速获取 from https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors |
| | endpoint = ["https://umxxx98d.mirror.aliyuncs.com","https://docker.m.daocloud.io", "https://registry-1.docker.io"] |
| | |
| | [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"] |
| | endpoint = ["https://registry.aliyuncs.com/google_containers", "https://k8s.m.daocloud.io"] |
| | ... |
| | |
| | |
| | systemctl restart containerd |
| | systemctl status containerd |
curl -v https://umxxx98d.mirror.aliyuncs.com/v2/
Q: 查验镜像仓库?
|---|-------------------------------------------------|
| | # docker info | grep -A 10 "Registry Mirrors" |
| | Registry Mirrors: |
| | https://umxxx98d.mirror.aliyuncs.com/ |
| | Live Restore Enabled: false |
Q: 验证加速器/镜像仓库是否真的可用?
|---|----------------------------------------------------|
| | # 测试阿里云镜像连通性 |
| | curl -I https://umxxx98d.mirror.aliyuncs.com/v2/ |
| | |
| | # 尝试拉取一个常见镜像测试 |
| | docker pull nginx:latest |
Q: 向指定镜像仓库中拉取镜像?
- case:
calico/cni
|---|--------------------------------------------------------------------------------------|
| | docker pull m.daocloud.io/docker.io/calico/cni:v3.26.1 |
| | # 新增镜像标签 |
| | docker tag m.daocloud.io/docker.io/calico/cni:v3.26.1 docker.io/calico/cni:v3.26.1 |
- case :
minio/minio
|---|--------------------------------------------------------------------------------------------------------|
| | docker pull quay.io/minio/minio:RELEASE.2024-05-28T17-19-04Z |
| | # 新增镜像标签 |
| | docker tag quay.io/minio/minio:RELEASE.2024-05-28T17-19-04Z minio/minio:RELEASE.2024-05-28T17-19-04Z |
- case :
milvusdb/milvus
|---|---------------------------------------------------------------------------------------------------------------------------|
| | docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/milvusdb/milvus:v2.5.21 |
| | # 新增镜像标签 |
| | docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/milvusdb/milvus:v2.5.21 docker.io/milvusdb/milvus:v2.5.21 |
Q: 登录阿里云镜像服务?
|---|--------------------------------------------------------------------------------------------------------------------|
| | [root@vm-a ~]# sudo docker login --username=xxx@qq.com crpi-tnk462xxx9q8ghps.cn-chengdu.personal.cr.aliyuncs.com |
| | Password: |
| | WARNING! Your password will be stored unencrypted in /root/.docker/config.json. |
| | Configure a credential helper to remove this warning. See |
| | https://docs.docker.com/engine/reference/commandline/login/#credentials-store |
| | |
| | Login Succeeded |
| | |
| | |
| | //如果已过期,先登出再重新登录 |
| | # docker logout crpi-tnk462xxx9q8ghps.cn-chengdu.personal.cr.aliyuncs.com |
| | # docker login crpi-tnk462xxx9q8ghps.cn-chengdu.personal.cr.aliyuncs.com |
| | |
| | [root@vm-a ~]# cat ~/.docker/config.json |
| | { |
| | "auths": { |
| | "crpi-tnk462xxx9q8ghps.cn-chengdu.personal.cr.aliyuncs.com": { |
| | "auth": "MTEyNTQxODU0MExxxxxxxYWx5I2pueSMyMjMwIQ==" |
| | } |
| | } |
| | } |
| | |
| | docker pull crpi-tnk462xxx9q8ghps.cn-chengdu.personal.cr.aliyuncs.com/calico/cni:v3.26.1 |
| | |
| | |
| | [root@vm-a ~]# docker pull calico/cni:v3.26.1 |
| | Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp 108.160.166.9:443: i/o timeout |
Q: 为何在 containerd 的 /etc/containerd/config.toml 中配置如下镜像仓库并有重启 containerd,但 k8s containerd 拉取镜像(ctr -n k8s.io images pull docker.io/library/mysql:8.0)时还是从 docker.io 拉取镜像?
问题描述
为何在 containerd (1.6.x) 的
/etc/containerd/config.toml中配置如下镜像仓库并有重启 containerd,但 k8s containerd 拉取镜像(ctr -n k8s.io images pull docker.io/library/mysql:8.0)时还是从 docker.io 拉取镜像?
|---|--------------------------------------------------------------------------------|
| | /etc/containerd/config.toml |
| | [plugins."io.containerd.grpc.v1.cri".registry] |
| | config_path = "" |
| | //... 略 |
| | |
| | [plugins."io.containerd.grpc.v1.cri".registry.mirrors] |
| | [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] |
| | # 阿里云镜像加速获取 from https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors |
| | endpoint = ["https://docker.m.daocloud.io"] |
| | |
| | [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"] |
| | endpoint = ["https://k8s.m.daocloud.io"] |
原因分析
这是一个非常经典的"配置过期"问题。简单来说,你使用的配置语法属于 CRI 1.x (Legacy) 版本,而较新版本的 Containerd (通常是 v1.5+,尤其是 v2.0+)已经弃用 了这种直接在
config.toml中写mirrors的方式,转而推荐使用 Registry Configuration Path。
此外,你的测试指令ctr也有点"坑",下面开始详细排查。
解决方法
1. 核心原因:配置方式已变更
Containerd 现在的推荐做法是开启 config_path。如果你在配置文件中看到了 config_path = "",那么你写的 [plugins."io.containerd.grpc.v1.cri".registry.mirrors] 很大大概率被忽略了。
推荐的修复方案:
-
修改
config.toml: 定位到[plugins."io.containerd.grpc.v1.cri".registry],将其修改为:|---|--------------------------------------------------|
| |[plugins."io.containerd.grpc.v1.cri".registry]|
| |config_path = "/etc/containerd/certs.d"|注意:此时请删除你之前写的
[plugins...mirrors]那一整段旧配置,避免冲突。 -
创建镜像目录结构 : 你需要为每个 Registry 创建对应的目录,并在其中创建
hosts.toml:|---|------------------------------------------------------------|
| |# 为 docker.io 创建配置|
| |mkdir -p /etc/containerd/certs.d/docker.io|
| | |
| |# 写入加速器地址|
| |cat <<EOF > /etc/containerd/certs.d/docker.io/hosts.toml|
| |server = "https://docker.io"|
| | |
| |[host."https://docker.m.daocloud.io"]|
| |capabilities = ["pull", "resolve"]|
| |EOF| -
重启 Containerd :
systemctl restart containerd
2. 测试工具的陷阱:ctr vs crictl
这是很多开发者最容易忽略的一点:ctr 指令是不走 CRI 配置的。
ctr:是 Containerd 的原生 CLI,它设计得很底层,完全无视[plugins."io.containerd.grpc.v1.cri"]下的配置(因为它不经过 CRI 插件)。crictl:是专门为 Kubernetes 交互设计的工具,它会严格遵循 CRI 配置。
正确的测试指令:
如果你想验证 K8s 镜像加速是否生效,请使用 crictl:
|---|-----------------------------------------------------------------------------------------------------------|
| | # 确保 /etc/crictl.yaml 已配置 runtime-endpoint |
| | crictl pull docker.io/library/mysql:8.0 |
| | 或 crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock pull docker.io/library/mysql:8.0 |
3. 检查 Sandbox 镜像(Pause 镜像)
如果你的 K8s 集群在启动时卡在 registry.k8s.io/pause,即使你配置了镜像加速,有时也会失效。这是因为 sandbox_image 通常是在 config.toml 中硬编码的。
检查 config.toml 中这一行:
|---|-----------------------------------------------|
| | sandbox_image = "registry.k8s.io/pause:3.9" |
建议直接将其修改为加速后的地址(如 k8s.m.daocloud.io/pause:3.9),因为 Sandbox 镜像的拉取逻辑非常特殊。
总结建议
- 优先使用
config_path模式,这是未来的标准。 - 放弃用
ctr测试加速效果 ,改用crictl或直接在 K8s 中部署一个 Pod 观察。 - 检查版本 :如果你的 Containerd 版本非常老(< 1.5),旧语法可能生效,但必须确保没有
config_path的干扰。如果是 1.7 或 2.0,建议立即采用第一种certs.d的方案。
Q: crictl 拉取镜像时报:transport: Error while dialing dial unix /var/run/dockershim.sock: connect: no such file or directory
问题描述
crictl 拉取镜像时报:
transport: Error while dialing dial unix /var/run/dockershim.sock: connect: no such file or directory
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| | [root@vm-a k8s-deployments]# crictl pull docker.io/library/mysql:8.0 |
| | |
| | WARN[0000] image 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. |
| | |
| | E0419 16:58:05.774215 14389 remote_image.go:171] "PullImage from image service failed" err="rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial unix /var/run/dockershim.sock: connect: no such file or directory\"" image="docker.io/library/mysql:8.0" |
| | |
| | FATA[0000] pulling image: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial unix /var/run/dockershim.sock: connect: no such file or directory" |
看报错信息,这其实不是你的镜像加速配置没生效,而是 crictl 工具本身的配置不对。
报错显示 crictl 正在尝试连接 /var/run/dockershim.sock。这是旧版本 Docker 的接口 ,而你目前使用的是纯 Containerd 环境 。由于找不到这个接口,crictl 直接报错退出了,根本还没运行到"拉取镜像"那一步。
1. 修复 crictl 配置
你需要告诉 crictl 去哪里找 Containerd。请执行以下命令:
|---|------------------------------------------------------------|
| | cat <<EOF > /etc/crictl.yaml |
| | runtime-endpoint: unix:///run/containerd/containerd.sock |
| | image-endpoint: unix:///run/containerd/containerd.sock |
| | timeout: 10 |
| | debug: false |
| | EOF |
设置完成后,再次尝试拉取:
Bash
|---|-------------------------------------------|
| | crictl pull docker.io/library/mysql:8.0 |
2. 如何确认加速真的生效了?
因为 crictl 的输出比较简洁,你看不到具体的下载流。为了验证它确实走了 daocloud 的加速器,你可以查看 Containerd 的实时日志:
-
打开一个新终端,运行监控日志命令:
Bash
|---|-------------------------------|
| |journalctl -u containerd -f| -
在原终端执行拉取:
Bash
|---|-------------------------------------------|
| |crictl pull docker.io/library/mysql:8.0| -
观察日志:
如果配置成功,你在日志中会看到类似
resolving或trying to pull...的记录,其中会包含docker.m.daocloud.io这个域名。
3. 常见"暗坑"排查
如果你配置了 certs.d 路径但依然无效,请检查以下两点:
- 配置文件的位置 :确认你的
config.toml是在/etc/containerd/config.toml。 - 配置是否冲突 :打开
/etc/containerd/config.toml,搜索[plugins."io.containerd.grpc.v1.cri".registry]。- 必须有 :
config_path = "/etc/containerd/certs.d" - 不能有 :
mirrors或configs的具体子项(如果有,请全部删掉或注释掉,因为config_path开启后,旧的内联配置会被忽略)。
- 必须有 :
4. 深度验证方案 (如果 crictl 还是拉不动)
如果日志里显示还在连接 registry-1.docker.io,请检查你的 hosts.toml 内容。注意: 目录名必须是 docker.io(对应镜像库的主机名)。
Bash
|---|----------------------------------|
| | # 检查一下你的目录结构是否完全一致: |
| | ls -R /etc/containerd/certs.d/ |
输出应该是:
Plaintext
|---|--------------------------------------|
| | /etc/containerd/certs.d/: |
| | docker.io |
| | |
| | /etc/containerd/certs.d/docker.io: |
| | hosts.toml |
修复完 crictl 的 Endpoint 报错后,拉取测试应该就能跑通了。还有其他报错吗?
3 FAQ for K8s 日常使用-其他
Q: Docker 环境预检?
|---|------------------------------------------------------------------------|
| | #!/bin/bash |
| | # Docker 环境预检脚本 |
| | |
| | echo "=== Docker 基本信息 ===" |
| | docker info | grep -E "Server Version|Storage Driver|Kernel Version" |
| | # out samples: |
| | # Server Version: 26.1.4 |
| | # Storage Driver: overlay2 |
| | # Kernel Version: 3.10.0-1160.el7.x86_64 |
| | |
| | docker info | grep -A 10 "Registry Mirrors" |
| | # out samples: |
| | # Registry Mirrors: |
| | # https://umxxx98d.mirror.aliyuncs.com/ |
| | # Live Restore Enabled: false |
| | |
| | echo "=== 资源使用情况 ===" |
| | docker info | grep -E "Containers|Images|CPUs|Total Memory" |
| | # out samples: |
| | # Containers: 0 |
| | # Images: 3 |
| | # CPUs: 4 |
| | # Total Memory: 7.526GiB |
| | |
| | echo "=== 安全配置检查 ===" |
| | docker info | grep -A5 "Security Options" |
| | # out samples: |
| | # Security Options: |
| | # seccomp |
| | # Profile: builtin |
| | # Kernel Version: 3.10.0-1160.el7.x86_64 |
| | # Operating System: CentOS Linux 7 (Core) |
| | # OSType: linux |
| | |
| | echo "=== 存储检查 ===" |
| | docker info | grep -A3 "Docker Root Dir" |
| | # out samples: |
| | # Docker Root Dir: /var/lib/docker |
| | # Debug Mode: false |
| | # Experimental: false |
| | # Insecure Registries: |
| | df -h $(docker info | grep "Docker Root Dir" | cut -d: -f2) |
| | # out samples: |
| | # Filesystem Size Used Avail Use% Mounted on |
| | # /dev/mapper/centos_vm--a-root 15G 7.3G 7.8G 49% / |
Q: 重启 docker 服务进程?
|---|-----------------------------------------------------------------------|
| | //方法1 |
| | sudo systemctl daemon-reload |
| | sudo systemctl restart docker |
| | |
| | //方法2 |
| | # sudo systemctl stop docker.service |
| | Warning: Stopping docker.service, but it can still be activated by: |
| | docker.socket |
| | # sudo systemctl stop docker.socket |
| | # sudo systemctl daemon-reload |
| | # sudo systemctl start docker.socket |
| | # sudo systemctl start docker.service |