集群生命周期管理
Kubernetes 集群的日常运维管理,包括节点维护、证书管理、kubeconfig 配置以及集群 addons 管理。
概述
集群生命周期管理涵盖节点维护、证书续期、kubeconfig 配置管理以及 addons 部署等日常运维操作。这是 CKA 考试的重点领域,涉及集群的持续运行和维护。
1. 节点管理
1.1 cordon / uncordon
将节点标记为不可调度(SchedulingDisabled),已运行的 Pod 不受影响。
# 将节点标记为不可调度
kubectl cordon node-1
# 验证节点状态(STATUS 显示 Ready,SchedulingDisabled)
kubectl get nodes
# 恢复节点为可调度
kubectl uncordon node-1
# 检查节点调度状态
kubectl describe node node-1 | grep "Taints"
1.2 drain -- 节点维护
优雅地将节点上的 Pod 驱逐到其他节点,并标记节点不可调度。
# 基本 drain 操作
kubectl drain node-1
# 忽略 DaemonSet 管理的 Pod(常用)
kubectl drain node-1 --ignore-daemonsets
# 强制驱逐(即使有非镜像 Pod 未被管理)
kubectl drain node-1 --ignore-daemonsets --force
# 删除本地数据的 Pod(如 emptyDir)
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
# 设置驱逐超时时间(默认 5 分钟)
kubectl drain node-1 --ignore-daemonsets --grace-period=120
# 完整的节点维护流程
kubectl cordon node-1 # 1. 禁止调度新 Pod
kubectl drain node-1 --ignore-daemonsets # 2. 驱逐现有 Pod
# ... 执行节点维护 ...
kubectl uncordon node-1 # 3. 恢复调度
1.3 删除节点
# 先从集群中移除节点
kubectl delete node worker-1
# 然后在该节点上重置
sudo kubeadm reset -f
sudo rm -rf /etc/kubernetes/
sudo rm -rf /var/lib/kubelet/
sudo rm -rf /var/lib/etcd/
# 验证节点已移除
kubectl get nodes
1.4 节点标签与污点
# 添加标签
kubectl label node node-1 disktype=ssd
# 删除标签
kubectl label node node-1 disktype-
# 添加污点
kubectl taint node node-1 key=value:NoSchedule
kubectl taint node node-1 key=value:PreferNoSchedule
kubectl taint node node-1 key=value:NoExecute
# 删除污点
kubectl taint node node-1 key:NoSchedule-
# 查看节点污点
kubectl describe node node-1 | grep Taints
2. 证书管理
2.1 查看证书信息
# 查看证书过期时间
kubeadm certs check-expiration
# 输出示例:
[check-expiration] Reading configuration from /etc/kubernetes/admin.conf
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
admin.conf May 25, 2027 18:27 UTC 364d no
apiserver May 25, 2027 18:27 UTC 364d ca no
apiserver-kubelet-client May 25, 2027 18:27 UTC 364d ca no
controller-manager.conf May 25, 2027 18:27 UTC 364d no
scheduler.conf May 25, 2027 18:27 UTC 364d no
front-proxy-client May 25, 2027 18:27 UTC 364d front-proxy-ca no
CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
ca May 23, 2035 18:22 UTC 9y no
front-proxy-ca May 23, 2035 18:22 UTC 9y no
2.2 证书续期
# 续期所有证书
kubeadm certs renew all
# 续期特定证书
kubeadm certs renew apiserver
kubeadm certs renew admin.conf
kubeadm certs renew etcd-healthcheck-client
# 证书续期后需要重启相关组件
# 如果使用静态 Pod
docker run --rm -v /etc/kubernetes:/etc/kubernetes \
k8s.gcr.io/kube-apiserver:v1.31.0 \
kube-apiserver --help
# 更简单的方式:重启 kubelet(静态 Pod 会自动重启)
sudo systemctl restart kubelet
2.3 手动更新 kubeconfig
# 证书续期后更新用户的 kubeconfig
kubeadm kubeconfig user --client-name=my-user
# 更新 admin.conf
kubeadm kubeconfig admin
2.4 CSRs 管理与批准
# 查看待处理的证书签名请求
kubectl get csr
kubectl get certificatesigningrequests
# 查看 CSR 详情
kubectl describe csr <csr-name>
# 批准 CSR
kubectl certificate approve <csr-name>
# 拒绝 CSR
kubectl certificate deny <csr-name>
# 删除已完成的 CSR
kubectl delete csr <csr-name>
3. kubeconfig 与 Context 管理
3.1 kubectl config 命令
# 查看当前配置
kubectl config view
# 查看完整的 kubeconfig
kubectl config view --raw
# 查看当前 context
kubectl config current-context
# 列出所有 context
kubectl config get-contexts
# 设置默认 context
kubectl config use-context <context-name>
# 创建新 context
kubectl config set-context my-context \
--cluster=my-cluster \
--user=my-user \
--namespace=my-namespace
# 修改 context 的默认命名空间
kubectl config set-context $(kubectl config current-context) --namespace=my-namespace
3.2 多集群管理
# 合并多个 kubeconfig
export KUBECONFIG=/path/to/config1:/path/to/config2
kubectl config view --flatten > ~/.kube/config
# 列出合并后的 context
kubectl config get-contexts
# 切换集群
kubectl config use-context cluster-1
kubectl get nodes
kubectl config use-context cluster-2
kubectl get nodes
3.3 kubeconfig 结构说明
apiVersion: v1
kind: Config
# 集群列表
clusters:
- cluster:
certificate-authority-data: <base64-ca-cert>
server: https://192.168.1.10:6443
name: kubernetes
# 用户列表
users:
- name: admin
user:
client-certificate-data: <base64-cert>
client-key-data: <base64-key>
# context 列表
contexts:
- context:
cluster: kubernetes
user: admin
namespace: default
name: admin@kubernetes
# 当前使用的 context
current-context: admin@kubernetes
3.4 手动创建 kubeconfig
# 为 ServiceAccount 创建 kubeconfig
# 1. 创建 ServiceAccount
kubectl create serviceaccount my-sa
kubectl create clusterrolebinding my-sa-binding --clusterrole=view --serviceaccount=default:my-sa
# 2. 获取令牌
TOKEN=$(kubectl create token my-sa)
# 3. 配置 kubeconfig
kubectl config set-credentials my-sa-user --token=$TOKEN
kubectl config set-cluster my-cluster --server=https://<api-server>:6443 --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true
kubectl config set-context my-sa-context --cluster=my-cluster --user=my-sa-user
kubectl config use-context my-sa-context
4. 集群 Addons 管理
4.1 CoreDNS
# 查看 CoreDNS 状态
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 查看 CoreDNS 配置
kubectl get configmap -n kube-system coredns -o yaml
# 修改 CoreDNS 配置(如自定义 DNS 解析)
kubectl edit configmap -n kube-system coredns
# 查看 CoreDNS 日志
kubectl logs -n kube-system -l k8s-app=kube-dns
# 扩容 CoreDNS 副本
kubectl scale deployment -n kube-system coredns --replicas=3
# 测试 DNS 解析
kubectl run dns-test --image=busybox:1.28 --rm -it --restart=Never -- nslookup kubernetes.default
4.2 metrics-server
# 安装 metrics-server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 验证 metrics-server 运行
kubectl get pods -n kube-system -l k8s-app=metrics-server
# 查看 metrics-server 日志
kubectl logs -n kube-system -l k8s-app=metrics-server
# 使用 metrics-server 查看资源使用
kubectl top nodes
kubectl top pods
kubectl top pods --all-namespaces
kubectl top pod <pod-name> -n <namespace>
4.3 Kubernetes Dashboard
# 安装 Dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
# 创建访问用户
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
EOF
# 获取访问令牌
kubectl -n kubernetes-dashboard create token admin-user
# 启动代理
kubectl proxy
# 访问:http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
4.4 安装与卸载 Addons
# 安装系统必需插件
kubectl apply -f <manifest-url>
# 查看插件运行状态
kubectl get pods --all-namespaces
# 更新插件
kubectl apply -f <updated-manifest-url>
# 删除插件
kubectl delete -f <manifest-url>
5. 集群组件日志查看
# kubelet 日志
sudo journalctl -u kubelet -f
sudo journalctl -u kubelet --since "5 min ago"
sudo journalctl -u kubelet -n 50 --no-pager
# 容器运行时日志
sudo journalctl -u containerd -n 50 --no-pager
sudo journalctl -u crio -n 50 --no-pager
# API Server 日志(静态 Pod)
kubectl logs -n kube-system kube-apiserver-<node-name>
kubectl logs -n kube-system kube-scheduler-<node-name>
kubectl logs -n kube-system kube-controller-manager-<node-name>
kubectl logs -n kube-system etcd-<node-name>
CKA 考试要点
- drain 必须加
--ignore-daemonsets-- DaemonSet Pod 无法被驱逐,不忽略会报错 - 证书续期后重启 kubelet --
kubeadm certs renew all执行后需要重启 kubelet - 配置 context 的命名空间 --
kubectl config set-context --namespace=xxx在考试中很实用 - apt-mark hold -- 考试中禁止 kubeadm/kubelet/kubectl 版本自动升级
- 节点维护三件套:
cordon -> drain -> uncordon
🧪 完整操作实例:对工作节点进行维护操作
场景描述
对 worker 节点 worker-1 进行计划内维护:先标记为不可调度,优雅驱逐所有 Pod,完成维护后恢复调度。
前置条件
- 一个运行中的 Kubernetes 集群(至少 1 个控制平面 + 2 个工作节点)
- 集群中运行着非 DaemonSet 的 Pod,且其他节点有足够资源接收被驱逐的 Pod
操作步骤
Step 1: Cordon 节点(标记为不可调度)
kubectl cordon worker-1
# node/worker-1 cordoned
# 验证节点状态
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# control-plane-1 Ready control-plane 1h v1.31.0
# worker-1 Ready,SchedulingDisabled <none> 1h v1.31.0 <-- 注意状态变化
# worker-2 Ready <none> 1h v1.31.0
Step 2: Drain 节点(驱逐 Pod)
# 驱逐所有非 DaemonSet Pod
kubectl drain worker-1 --ignore-daemonsets --delete-emptydir-data
# node/worker-1 already cordoned
# evicting pod default/nginx-deploy-xxxxxxxxx-xxxxx
# evicting pod kube-system/metrics-server-xxxxxxxxx-xxxxx
# ...
# node/worker-1 drained
# 如果驱逐卡住,可以设置优雅期
kubectl drain worker-1 --ignore-daemonsets --grace-period=120 --force
Step 3: 执行节点维护(模拟操作)
# 此时可以在 worker-1 上执行系统升级、内核更新、硬件更换等操作
# 示例:查看节点上剩余的 Pod(应只有 DaemonSet)
kubectl get pods --field-selector spec.nodeName=worker-1 --all-namespaces
# NAMESPACE NAME READY STATUS RESTARTS AGE
# kube-system kube-proxy-xxxxx 1/1 Running 0 1h
# calico-system calico-node-xxxxx 1/1 Running 0 1h
# 执行维护操作(模拟)
# ssh worker-1 "sudo apt-get update && sudo apt-get upgrade -y linux-image"
Step 4: Uncordon 节点(恢复调度)
# 维护完成后恢复节点调度
kubectl uncordon worker-1
# node/worker-1 uncordoned
# 验证节点状态
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# control-plane-1 Ready control-plane 1h v1.31.0
# worker-1 Ready <none> 1h v1.31.0 <-- SchedulingDisabled 已移除
# worker-2 Ready <none> 1h v1.31.0
验证结果
# 验证新 Pod 已调度到恢复后的节点
kubectl get pods -o wide
# NAME READY STATUS RESTARTS AGE NODE
# nginx-deploy-xxxxxxxxx-xxxxx 1/1 Running 0 1m worker-1 <-- 新 Pod 已调度回来
# nginx-deploy-xxxxxxxxx-xxxxx 1/1 Running 0 5m worker-2
考试提示
- Drain 必须加
--ignore-daemonsets-- DaemonSet Pod 无法被驱逐,不加此参数 drain 会卡住 - Cordon 不影响已有 Pod -- 只阻止新 Pod 调度到该节点
- 完整维护三件套:
cordon->drain->uncordon,顺序不能乱 - 如果 drain 遇到
cannot delete DaemonSet managed Pod报错,加--ignore-daemonsets - 如果 drain 遇到
Pod has local data (emptyDir)报错,加--delete-emptydir-data - 考试中 uncordon 后检查
kubectl get nodes是否已移除SchedulingDisabled