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
CronJob
ConfigMap / Secret
Deployment / DaemonSet
Service
type: NodePort
Ingress / IngressClass
Ingress Controller
PersistentVolume / PersistentVolumeClaim / StorageClass
使用 nfs 的 PV
加上 nfs-subdir-external-provisioner
StatefulSet
sts 绑定 PVC 与 StorageClass / Provisioner
命名空间与 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>