Kubernetes Cheatsheet

84 阅读8分钟

kubectl 基本操作

命令式操作

# 查看版本
kubectl version

# 获取集群中可以用的 api 信息(可以获取对象名称及简写,再用 explain 具体了解)
kubectl api-resources

# 命名空间 (简写 ns)
# 预设命名空间:default / kube-system / kube-public / kube-node-lease
kubectl get namespaces  # 查看命名空间
kubectl create ns <ns_name>  # 创建命名空间

# 资源配额 ResourceQuota (简写 quota)
kubectl create resourcequota <quota_name>

# 限制范围 LimitRange (简写 limits),不能 create
kubectl get limits
kubectl get limitrange

# 直接运行一个镜像
kubectl run <pod_name> --image=<image_name>  # 会生成一个 pod

# 显示 pod (pod 可以用 po 替代)
kubectl get pod  # 默认仅显示 default 命名空间
kubectl get pod -owide  # 显示更多的列
kubectl get pod -n <namespace>  # 显示指定命名空间的容器
kubectl get pod --all-namespaces  # 显示所有命名空间的 pod
kubectl get pod -w  # -w 阻塞当前终端交互,watch 这个列表

# 删除一个 pod
kubectl delete pod <pod_name>

# 显示节点 (node 可以用 no 替代)
kubectl get node
# 给节点打标签
kubectl label nodes <node_name> <key>=<value>
# 排空一个节点(优雅下线前先手动排空)
kubectl drain <node-name> --ignore-daemonsets --delete-local-data
# drain 重启之后重新纳入这个节点(解除警戒)
kubectl uncordon <node-name>

# 查看日志
kubectl logs <pod_name>

# 通过 decribe 查看详细对象信息,任何类型的对象都适用
kubectl describe pod <pod_name>

# 向 pod 拷贝文件
kubectl cp <host_path> <pod_name>:<pod_path>

# 在 pod 中执行命令
kubectl exec -it <pod_name> -- <command>

# 创建 Job
kubectl create job <job_name> --image=<image_name>

# 创建 CronJob (简写 cj)
kubectl create cj <cron_job_name> --image=<image_name> --schedule=""

# 创建 ConfigMap (简写 cm)
kubectl create cm <cm_name>
kubectl create cm <cm_name> --from-literal=<k=v>  # 如果需要设定多对参数可以多次指定 --from-literal 的参数值,每次一对 Key-Value
kubectl descibe cm <cm_name>  # 查看 ConfigMap 的内容

# 创建 Secret
kubectl create secret generic <secret_name>
kubectl create secret generic <secret_name> --from-literal=<k=v>
echo -n <plaintext> | base64  # 生成明文对应的 base64 编码,与 secret 实际的值适配

# 创建 Deployment (简写 deploy)
kubectl create deloyment <deploy_name> --image=<image_name>

# DaemonSet (简写 ds) 无法创建模板,可以参考:
# https://kubernetes.io/zh/docs/concepts/workloads/controllers/daemonset/

# 创建 Service (简写 svc) 要用 expose 方法
kubectl expose deploy <deploy_name> --port=<port> --target-port=<port>

# 创建 Ingress (简写 ing)
kubectl create ingress <ingress_name> --rule="<domain_name>/<path>=<service_name>:80" --class=<ingress_class>

# IngressClass 的创建需要手动编写 yaml
# 如果用 Nginx Ingress Controller,ingressclass.spec.controller="nginx.org/ingress-controller"
# 还要绑定 Ingress Controller,直接从这里面扒 yaml 执行就好了
# https://github.com/nginxinc/kubernetes-ingress
# https://docs.nginx.com/nginx-ingress-controller/installation/installation-with-manifests/

# 将本地端口映射到指定的 Pod 中
kubectl port-forward -n <namespace> <pod_name> <host_port>:<container_port>

# PersistentVolume / PersitentVolumeClass / StorageClass 不支持 create
# 参照声明式 yaml 例子编写

# StatefulSet (简写 sts) 不支持 create
# 参照声明式 yaml 例子编写

# 自动扩容策略 HorizontalPodAutoscaler (简写 hpa)
kubectl autoscale deploy <hpa_name> --min=<?> --max=<?> --cpu-percent=<?>
特殊命令
# 将 svc/pod 的端口暴露到节点宿主机(调试用)
# 默认会挂在前台,通过 & 来 fork 这个进程
kubectl port-forward svc/ngx-svc 8080:80 &  
kubectl port-forward pod/sts-redis-0 6379:6379 &

# 查看系统 CPU 和内存利用率
# wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl top  # 需要安装 Metrics Server 插件
kubectl top nodes
kubectl top pod -n <namespace>

声明式操作

创建模式:

# 例子:通过命令式生成基础 yaml (--dry-run=client)
kubectl run <pod_name> --image=<image_name> --dry-run=client  # dry-run 为空运行
kubectl run <pod_name> --image=<image_name> --dry-run=client -oyaml  # 直接将yaml 配置内容输出在控制台

# 实际用法:
# 1. 将命令式创建语句,结合 --dry-run=client -oyaml 输出到 yaml 文件
kubectl create <kind> [...args] --dry-run=client -oyaml > out-file.yaml
# 2. 手动调整这个 out-file.yaml,然后通过 kubectl create 或者 kubectl apply 应用
kubectl apply -f out-file.yaml

导出并修改模式:

# 1. 将现有对象输出到配置文件
kubectl get <kind> <name> -oyaml > out-file.yaml
# 2. 根据需要修改 out-file.yaml
# 3. 应用这个配置
kubectl apply -f out-file.yaml

直接修改模式:

# 1. 直接 edit 一个配置:会打开一个编辑器直接编辑 yaml 保存退出后直接 apply
kubectl edit <kind> <name>

常用命令:

# 应用 yaml 配置文件更新对象
kubectl create -f <file.yaml>  # 根据 yaml 声明创建对象
kubectl apply -f <file.yaml>  # 按照 yaml 更新对象
kubectl delete -f <file.yaml>  # 删除 yaml 文件声明的对象

通过 explain 查看具体的属性文档:

# kubectl explain: 查看文档,举几个例子
kubectl explain pod  # 查 pod 的文档
kubectl explain pod.metadata
kubectl explain pod.spec
kubectl explain pod.spec.containers

# pod 的配额管理
kubectl explain pod.spec.containers.resources
kubectl explain pod.spec.containers.resources.requests  # 下限,必需资源
kubectl explain pod.spec.containers.resources.requests.cpu
kubectl explain pod.spec.containers.resources.requests.memory
kubectl explain pod.spec.containers.resources.limits  # 上限,内容同 requests

# 容器探针
kubectl explain pod.spec.containers.startupProbe
kubectl explain pod.spec.containers.livenessProde
kubectl explain pod.spec.containers.readinessProbe
# 探活方式
kubectl explain pod.spec.containers.xxxxProbe.exec.command
kubectl explain pod.spec.containers.xxxxProbe.tcpSocket.port
kubectl explain pod.spec.containers.xxxxProbe.httpGet
kubectl explain pod.spec.containers.xxxxProbe.httpGet.path
kubectl explain pod.spec.containers.xxxxProbe.httpGet.port
# 探活配置
kubectl explain pod.spec.containers.xxxxProbe.initialDelaySeconds # 容器启动多久开始探活,默认0
kubectl explain pod.spec.containers.xxxxProbe.periodSeconds # 探活间隔,默认10,最小1
kubectl explain pod.spec.containers.xxxxProbe.timeoutSeconds # 探活超时时间,默认1,最小1
kubectl explain pod.spec.containers.xxxxProbe.successThreshold # 失败后连续成功多少次才正常,默认/最小1
kubectl explain pod.spec.containers.xxxxProbe.failureThreshold # 连续失败多少次才算挂,默认3最小1

# 优雅中止  preStop -> SIGTERM -> SIGKILL
# 例如: command: [ "/bin/sh", "-c", "nginx -s quit; while killall -0 nginx; do sleep 1; done" ]
kubectl explain pod.spec.containers.lifecycle.preStop
kubectl explain pod.spec.containers.lifecycle.preStop.exec.command
kubectl explain pod.spec.terminationGracePeriodSeconds  # 优雅中止的等待时间,超过就 SIGKILL

# 使用 cm 和 secret 的值
# ---------------------
# 环境变量模式
# 将 env.value 改为 valueFrom,然后装载指定 <name> 的 secret 或者 cm 下面 <key> 的值
kubectl explain pod.spec.containers.env.valueFrom.configMapKeyRef
kubectl explain pod.spec.containers.env.valueFrom.secretKeyRef
# 挂载模式:使用 volumes,指定 name 的 ConfigMap 或者 Secret
kubectl explain pod.spec.volumes.configMap.name
kubectl explain pod.spec.volumes.Secret.secretName
# 指定了之后,要在 pod.containers 里面设置 mount
# 会按照每个 vol 一个目录,下面每个 key 一个文件,内容为 value 的方式加载,secret 也会加载为明文
kubectl explain pod.spec.containers.volumeMounts.mountPath
kubectl explain pod.spec.containers.volumeMounts.name

# 让 Service 对外暴露服务
kubectl explain svc.spec.type  # ClusterIP(默认)/NodePort/LoadBalancer/ExternalName

应用更新管理:

# 扩缩容,修改副本数
kubectl scale --replicas=5 deploy <deploy_name>
# (发起更新)通过 kubectl apply 修改了 deployment 的时候,会自动滚动更新
kubectl apply -f <some-deploy.yaml>
# (配置)通过 minReadySeconds 设定 Pod 就绪等待时间
kubectl explain deploy.spec.minReadySeconds
# (更新中)观测滚动更新的过程
kubectl rollout status deploy <deploy_name>
# (更新中)暂停更新
kubectl rollout pause deploy <deploy_name>
# (更新中)恢复更新
kubectl rollout resume deploy <deploy_name>
# (事后)通过 rollout history 查看更新历史
kubectl rollout history deploy <deploy_name>  # 列出所有历史版本
kubectl rollout history deploy <deploy_name> --revision=<rev_id>  # 查看特定版本详情
# (事后)通过 describe 可以查看更新历史
kubectl describe deploy <deploy_name>
# 回滚
kubectl rollout undo deploy ngx-dep  # 回到上一个版本
kubectl rollout undo deploy ngx-dep --revision=<rev_id>  # 回到指定版本
# 通过 metadata.annotations (kubernetes.io/change-cause) 填写版本说明
kubectl explain deploy.metadata.annotations

对象图例

Job

image.png

CronJob

image.png

ConfigMap / Secret

image.png

image.png

Deployment / DaemonSet

image.png

Service

image.png

type: NodePort

image.png

Ingress / IngressClass

image.png

Ingress Controller

image.png

PersistentVolume / PersistentVolumeClaim / StorageClass

image.png

使用 nfs 的 PV

image.png

加上 nfs-subdir-external-provisioner

image.png

StatefulSet

image.png

sts 绑定 PVC 与 StorageClass / Provisioner

image.png

命名空间与 FQDN

对于 Pods 和 Service,在 kubernetes 内部,有默认的域名解析进行了路由,自动通过一套 FQDN (Fully Qualified Domain Name) 进行解析,我们可以在 pod 内部通过 FQDN 的任意不冲突前缀访问到对应的地址。

官方文档:kubernetes.io/docs/concep…

对于 Service,FQDN 的规则是:

my-svc.<my-namespace>.svc.<cluster-domain.example>

对于 Pod,规则是:

pod-ipv4-address.<my-namespace>.pod.<cluster-domain.example>
pod-name.<my-namespace>.pod.<cluster-domain.example>

Taint / Toleration

污点 / 容忍度是管理一个 Pod 是否能够与一个 Node 产生绑定的关键属性。

官方参考文档:kubernetes.io/zh-cn/docs/…

节点的 Taint (污点)

kubectl get nodes  # 查看节点
kubectl describe node <node_name>  # 指定节点的详细信息,可以看到 Taints

# 去掉 taint(最后的 - 是去掉污点的意思,不要 - 就是添加污点)
kubectl taint nodes <node_name> node-role.kubernetes.io/master:NoSchedule-

# 同时指定 key 和 value
kubectl taint nodes <node_name> key1=value1:NoExecute

Pod 的 Toleration (容忍度)

kuberctl explain pod.spec.tolerations

例如:

spec:
  tolerations:
  - key: node-role.kubernetes.io/master
    effect: NoSchedule
    operator: Exists

又例如:

spec:
  tolerations:
  - key: key1
    operator: Equal
    value: value1
    effect: NoExecute
    tolerationSeconds: 3600

或者:

spec:
  tolerations:
  - key: key1
    operator: Exists
    effect: NoSchedule

effect 的选择

简单说一下,详细还是看官方文档

  • NoExecute 不允许调度,且会影响已调度的 Pod 不满足的驱逐
  • NoSchedule 新的不会调度,但是已调度的不会影响
  • PreferNoSchedule 软性或者偏好的 NoSchedule

内置 Taints

  • node.kubernetes.io/not-ready:节点未准备好。这相当于节点状况 Ready 的值为 "False"。
  • node.kubernetes.io/unreachable:节点控制器访问不到节点. 这相当于节点状况 Ready 的值为 "Unknown"。
  • node.kubernetes.io/memory-pressure:节点存在内存压力。
  • node.kubernetes.io/disk-pressure:节点存在磁盘压力。
  • node.kubernetes.io/pid-pressure:节点的 PID 压力。
  • node.kubernetes.io/network-unavailable:节点网络不可用。
  • node.kubernetes.io/unschedulable:节点不可调度。
  • node.cloudprovider.kubernetes.io/uninitialized:如果 kubelet 启动时指定了一个“外部”云平台驱动, 它将给当前节点添加一个污点将其标志为不可用。在 cloud-controller-manager 的一个控制器初始化这个节点后,kubelet 将删除这个污点。

crictl

crictl 是 k8s 的 CRI 命令行工具,与具体的 CRI 实现无关。

crictl 介绍:
kubernetes.io/zh-cn/docs/…

从 docker CLI 映射到 crictl:
kubernetes.io/zh-cn/docs/…

# 显示 pod
crictl pods
crictl pods --name <pod_name>
crictl pods --label <key>=<value>

# 显示镜像
crictl images
crictl images <image_name>
crictl images -q  # 只打印镜像ID

# 显示容器
crictl ps -a  # 所有容器
crictl ps  # 运行中的容器

# 在容器中执行命令
crictl exec -it <container_name> <command>

# 打印容器日志
crictl logs <container_name>
crictl logs --tail=<n> <container_name>  # 打印最近 n 行日志

# 拉取镜像
crictl pull <image_uri>  # 默认情况是静默的

运行 Pod 沙盒、容器

编写 pod-config.json

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

编写容器配置 container-config.json

{
  "metadata": {
    "name": "busybox"
  },
  "image":{
    "image": "busybox"
  },
  "command": [
    "top"
  ],
  "log_path":"busybox.log",
  "linux": {
  }
}
# 创建沙盒,返回沙盒 ID
crictl runp pod-config.json

# 创建容器
crictl create <pod_id> container-config.json pod-config.json

# 查看容器(状态为 Created,含容器ID)
crictl ps -a

# 启动容器(状态为 Running)
crictl start <container_id>

ctr 工具

ctr 是 containerd 命令行工具,更类似 docker-cli 的层级,如果实际 k8s 的 CRI 用的是 containerd,则可以通过 ctr 来实现一些纯 containerd 层的操作。

参考:github.com/projectatom… 参考:cloud.tencent.com/developer/a…

注意,对于 ctr 来说,crictl 对应的 namespace 是 k8s.io,而默认的 namespace 是 default,所以会出现 ctr image ls 看不到 k8s 的镜像的问题,如果要预下载镜像,也应该在 -n=k8s.io 中指定命名空间。

以下命令均省略 -n=k8s.io,实际使用中,均需要在 ctr 后面加上这个,例如:ctr -n=k8s.io i ls,注意顺序,要紧跟在 ctr 后面。

# 查看命名空间
ctr namespaces ls
ctr ns ls  # 简写

# 查看 task
ctr tasks ls

# 删除 task
ctr tasks delete <>

# 查看容器
ctr containers ls
ctr c ls  # 简写

# 杀掉容器
ctr containers kill --pid <> -signal <>

# 删除容器
ctr containers delete <>

# 在容器中执行
ctr containers exec [command] [arguments...]

# 查看镜像列表
ctr images ls
ctr image ls ... # 简写
ctr i ls ... # 简写

# 用 ctr 工具拉取镜像,并查看进度(注意:路径要写全,连 :latest 都是不可缺少的)
ctr images pull docker.io/library/python:latest

# 删除镜像
ctr images delete <>

# 重新 tag 一个镜像
ctr images tag <old_tag> <new_tag>

# 推送镜像到 Harbor (如果 Harbor 是 http 则加上 --plain-http)
# --platform linux/amd64 指定系统平台,也可以使用--all-platforms指定所有平台镜像。
ctr images push --platform linux/amd64 --plain-http -u <user>:<password> <image_label>

# 导出镜像到文件
ctr images export <image_name.img> <image_label>

# 导入文件到镜像
ctr images import <image_name.img>