Qingular

集群生命周期管理

·CKAk8s练习

Kubernetes 集群的日常运维管理,包括节点维护、证书管理、kubeconfig 配置以及集群 addons 管理。

← 返回 CKA 练习目录

概述

集群生命周期管理涵盖节点维护、证书续期、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 考试要点

  1. drain 必须加 --ignore-daemonsets -- DaemonSet Pod 无法被驱逐,不忽略会报错
  2. 证书续期后重启 kubelet -- kubeadm certs renew all 执行后需要重启 kubelet
  3. 配置 context 的命名空间 -- kubectl config set-context --namespace=xxx 在考试中很实用
  4. apt-mark hold -- 考试中禁止 kubeadm/kubelet/kubectl 版本自动升级
  5. 节点维护三件套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

官方文档