需要对集群状态执行灾难恢复备份。
使用 `etcdctl snapshot save` 命令,并提供正确的 TLS 证书 (`--cacert`, `--cert`, `--key`) 和端点。
原因: etcd 存储整个集群状态。直接快照是备份它的规范方法。在 kubeadm 集群中,TLS 是启用的,因此 certs 对于 `etcdctl` 进行身份验证是强制性的。
CNCF Certified Kubernetes Administrator
最后审核:2026年5月
CKA 考试涉及的架构模式快速参考。从头到尾阅读,或跳转到任意章节。
需要对集群状态执行灾难恢复备份。
使用 `etcdctl snapshot save` 命令,并提供正确的 TLS 证书 (`--cacert`, `--cert`, `--key`) 和端点。
原因: etcd 存储整个集群状态。直接快照是备份它的规范方法。在 kubeadm 集群中,TLS 是启用的,因此 certs 对于 `etcdctl` 进行身份验证是强制性的。
从灾难恢复备份中恢复集群。
使用 `etcdctl snapshot restore` 命令到一个新的数据目录。然后,更新 `etcd.yaml` 静态 Pod 清单,将其 `--data-dir` 卷挂载指向新位置并重启 kubelet。
原因: 恢复会创建一个新的数据目录。必须更新静态 Pod 清单以使用这些新数据,否则 etcd 将使用旧的(或空的)数据目录启动。
对 kubeadm 管理的集群执行版本升级。
1. 在控制平面上:升级 `kubeadm`,运行 `kubeadm upgrade plan`,然后运行 `kubeadm upgrade apply`。 2. 在每个工作节点上:运行 `kubectl drain`,升级 `kubelet`,重启 kubelet 服务,运行 `kubectl uncordon`。
原因: 这个过程是多步骤且顺序执行的。`kubeadm` 只升级控制平面组件;`kubelet` 必须在每个节点上手动升级。排空节点可确保在维护前安全驱逐工作负载。
集群证书即将过期,需要检查或续订。
使用 `kubeadm certs check-expiration` 查看有效期。使用 `kubeadm certs renew all`(或针对特定组件)续订证书。续订后重启控制平面 Pod。
原因: kubeadm 生成的证书有效期为一年。续订是常见的维护任务。必须重启控制平面组件以加载新证书。
需要配置或重启控制平面组件(例如 API server)。
修改 `/etc/kubernetes/manifests/` 中的组件清单。节点上的 kubelet 将自动检测更改并重启 Pod。
原因: kubeadm 中的控制平面组件作为 static pods 运行,由 kubelet 直接管理,而非 API server。所有管理都通过受监控目录中的清单文件进行。
为用户或应用程序定义访问控制。
对于命名空间范围的权限,使用 `Role` 和 `RoleBinding`。对于集群范围的权限,使用 `ClusterRole` 和 `ClusterRoleBinding`。
原因: 这是 RBAC 中的基本区别。`Role` 始终与一个命名空间绑定,而 `ClusterRole` 可以授予对非命名空间资源(如节点)或跨所有命名空间的资源的访问权限。
一个 service account 需要访问所有命名空间中的资源。
创建一个定义权限的 `ClusterRole`。创建一个 `ClusterRoleBinding` 将该 ClusterRole 授予特定的 `ServiceAccount`。
原因: 尽管 ServiceAccount 是命名空间范围的,但 `ClusterRoleBinding` 可以授予它集群范围的权限。`RoleBinding` 仅在其自身的命名空间内授予权限。
在没有云负载均衡器的情况下,将应用程序暴露给外部流量。
使用 `type: NodePort` 的 Service。这会将服务在每个节点的 IP 地址上暴露到一个静态端口(默认范围:30000-32767)。
原因: NodePort 是将外部流量引入集群的简单方法。与 `type: LoadBalancer` 相比,它成本更低且与平台无关,但需要客户端知道节点 IP。
在单个 IP 地址下暴露多个 HTTP/S 服务,并支持基于主机或路径的路由。
部署 Ingress Controller(例如 NGINX)。创建定义从主机/路径到后端 `Services` 的路由规则的 `Ingress` 资源。
原因: Ingress 是 Kubernetes 用于 L7 路由的标准资源。它需要一个单独的控制器来实际实现路由逻辑。这可以将路由规则与代理实现解耦。
通过默认拒绝所有入站流量来保护命名空间。
创建一个 `NetworkPolicy`,选择所有 Pod(`podSelector: {}`)并指定一个空的入站规则(`ingress: []`)。
原因: 一旦 Pod 被任何 NetworkPolicy 选中,所有未明确允许的流量都将被拒绝。一个选择所有 Pod 并带有空入站规则的策略,实际上为该命名空间创建了一个“拒绝所有”防火墙。
允许“frontend”命名空间中的 Pod 访问“backend”命名空间中的 Pod。
在“backend”命名空间中,创建一个 NetworkPolicy。在 `ingress.from` 规则中,使用 `namespaceSelector` 来匹配“frontend” `Namespace` 资源上的标签。
原因: `podSelector` 仅在策略的命名空间内有效。要允许来自其他命名空间的流量,必须使用 `namespaceSelector`。这需要对 `Namespace` 对象本身进行标签。
应用程序需要连接到集群内的另一个服务。
使用服务的内部 DNS 名称:`<service-name>.<namespace>.svc.cluster.local`。如果在同一命名空间中,`<service-name>` 就足够了。
原因: Kubernetes 通过 CoreDNS 提供稳定的基于 DNS 的服务发现。这可以将应用程序与特定的 Pod IP 解耦,因为 Pod IP 是短暂的。
有状态应用程序(例如数据库副本集)需要为每个 Pod 提供直接的网络身份。
为 `StatefulSet` 创建一个无头 `Service`(`clusterIP: None`)。这为每个 Pod 提供了唯一的 DNS A 记录(例如,`pod-0.my-service.my-ns...`)。
原因: 无头服务不进行负载均衡。相反,它为每个 Pod 提供 DNS 记录,允许客户端连接到特定实例,这对于有状态系统中的领导者选举或对等发现至关重要。
面向外部的服务需要查看原始客户端 IP 地址以进行日志记录或基于 IP 的过滤。
在 `NodePort` 或 `LoadBalancer` Service 上设置 `externalTrafficPolicy: Local`。
原因: 默认的 `Cluster` 策略通过 SNAT 隐藏客户端 IP。`Local` 通过仅将流量路由到接收流量的节点上的 Pod 来避免额外的网络跳转,从而保留源 IP。
为了性能或高可用性,将 Pods 放在一起或分散开。
使用 `podAffinity` 将 Pods 调度到与特定其他 Pods 相同的节点/区域。使用 `podAntiAffinity` 避免将它们调度在一起。
原因: 这提供了比节点级亲和性更高级的调度控制。带有 `requiredDuringScheduling...` 的 Anti-affinity 对于将服务副本分散到不同节点或区域以实现 HA 至关重要。
将节点专用于特定工作负载,或阻止某些工作负载在其上运行。
为节点应用一个 `taint`(例如,`gpu=true:NoSchedule`)。为应允许在该节点上运行的 Pods 添加一个匹配的 `toleration`。
原因: Taints 拒绝 Pods,而 tolerations 允许它们。这是专用节点的主要机制。`NoExecute` 效果将驱逐已经运行但没有 toleration 的 Pods。
在集群中的每个节点上部署监控或日志代理。
使用 `DaemonSet`。它确保 Pod 的一个副本在每个符合其调度条件的节点上运行。
原因: DaemonSet 正是为了这个目的而设计的。它会自动部署到新节点,并处理节点级别的 Pod 管理,这对于 Deployment 来说很难做到。
运行一次性批处理任务或定期调度任务。
对于运行一次直到完成的任务,使用 `Job`。对于按重复计划(例如每晚备份)创建 Jobs 的任务,使用 `CronJob`。
原因: Jobs 确保 Pods 运行直到达到指定数量的完成。CronJobs 是一个更高级别的控制器,它根据 cron 计划管理 Jobs。
以零停机时间将应用程序更新到新版本。
使用默认 `RollingUpdate` 策略的 `Deployment`。配置 `maxSurge` 和 `maxUnavailable` 来控制更新速度和可用性。
原因: 滚动更新逐步用新 Pods 替换旧 Pods,确保服务保持可用。`maxUnavailable` 保证最少数量的 Pods 正在运行,而 `maxSurge` 允许在所需副本数之上进行突发,以加快 rollout。
确保 Pods 获得有保障的资源,并且不会在节点上消耗过多资源。
设置 `resources.requests`(CPU/memory)以保证调度的最小值。设置 `resources.limits` 以防止容器超过一定数量。
原因: Requests 被调度器用于放置和保证资源。Limits 由 kubelet 和容器运行时强制执行;超过 memory limit 将导致 OOMKill。
部署一个有状态应用程序,该应用程序需要每个副本具有稳定、唯一的网络标识符和持久存储。
使用带有 `volumeClaimTemplate` 的 `StatefulSet`。这会为每个 Pod 创建唯一的 `PersistentVolumeClaim`,确保数据在重启时重新附加到相同的 Pod 身份。
原因: StatefulSets 提供稳定的 Pod 名称(例如 `web-0`、`web-1`)和每个 Pod 唯一的持久性 PVC。这对于依赖稳定身份和存储的应用程序至关重要。
在不预先配置卷的情况下为应用程序提供持久存储。
创建一个定义存储 provisioner 的 `StorageClass`。然后,创建一个 `PersistentVolumeClaim` (PVC) 从该类请求存储。一个 `PersistentVolume` (PV) 将被动态供应。
原因: 这使应用程序与底层存储基础设施解耦。开发人员通过 PVCs 请求存储,而集群管理员通过 StorageClasses 定义如何供应该存储。
控制持久卷在其 claim 被删除后会发生什么。
在 PV 或 StorageClass 上设置 `persistentVolumeReclaimPolicy`。`Delete` 自动删除底层存储。`Retain` 保留卷和数据完整,需要手动清理。
原因: `Retain` 是生产数据最安全的选择,因为它防止意外数据丢失。`Delete` 对于临时或开发环境很方便。默认值取决于 provisioner。
定义 Pods 如何挂载卷。
使用 `accessModes`:`ReadWriteOnce` (RWO) 用于单节点读写,`ReadOnlyMany` (ROX) 用于多节点只读,`ReadWriteMany` (RWX) 用于多节点读写。
原因: 访问模式必须由底层存储提供商支持。应用程序需求(例如需要 RWX)与存储能力(仅支持 RWO)不匹配是 Pending PVCs 的常见原因。
将配置文件或敏感数据注入到 Pod 中。
将 `ConfigMap` 或 `Secret` 作为卷挂载。数据对象中的每个键都成为挂载路径中的一个文件。
原因: 这是向 Pods 提供配置的标准方式。它允许将配置作为 Kubernetes 对象进行管理,并独立于 Pod 镜像进行更新。
应用程序需要其现有持久卷中更多的存储空间。
确保 `StorageClass` 具有 `allowVolumeExpansion: true`。编辑 `PVC` 以在 `spec.resources.requests.storage` 中请求更大的大小。
原因: 卷扩展是一个可选功能。StorageClass 必须明确允许它,并且底层 CSI driver 必须支持它。Pod 可能需要重启以调整文件系统大小。
Pod 停留在 `Pending` 状态,未被调度。
运行 `kubectl describe pod <pod-name>`。检查 `Events` 部分以获取来自调度器的消息。
原因: `describe` 命令是解决此问题的主要工具。它将显示诸如“Insufficient cpu/memory”、“node(s) had taints the pod didn't tolerate”或“didn't match node selector”之类的原因。
Pod 反复启动并失败,状态为 `CrashLoopBackOff`。
1. `kubectl logs <pod-name> --previous` 查看崩溃容器的日志。 2. `kubectl describe pod <pod-name>` 检查退出代码和原因。
原因: `CrashLoopBackOff` 意味着容器内的应用程序正在退出。前一个实例的日志 (`--previous`) 至关重要,因为当前容器可能尚未记录任何有用的信息。退出代码也可以指示错误的类型。
Pod 启动失败,状态为 `ImagePullBackOff` 或 `ErrImagePull`。
`kubectl describe pod <pod-name>` 查看事件消息。验证镜像名称和标签是否正确。对于私有 registry,确保 `imagePullSecrets` 已配置且 secret 有效。
原因: 这是一个 registry 或镜像名称问题,而不是应用程序问题。常见原因包括拼写错误、不正确的标签或与私有 registry 的身份验证失败。
节点处于 `NotReady` 状态。
SSH 到受影响的节点。使用 `systemctl status kubelet` 检查 kubelet 服务的状态。使用 `journalctl -u kubelet` 查看其日志。
原因: `kubelet` 是负责节点健康报告的代理。如果它停止运行或无法与 API server 通信,节点将被标记为 NotReady。它的日志是首先要查看的地方。
服务存在,但流量未到达后端 Pods。
1. `kubectl describe svc <service-name>` 并验证 `Selector` 是否匹配 Pod 标签。 2. `kubectl get endpoints <service-name>` 并确保它列出了正确的 Pod IPs。如果不正确,则标签不匹配。
原因: Service 与其 Pods 之间的链接是标签选择器。如果选择器错误或 Pods 没有正确的标签,Endpoints 对象将为空,服务将无法路由流量。
Pods 无法解析服务名称或外部主机名。
1. 检查 `kube-system` 中 CoreDNS Pods 是否正在运行。 2. 检查 CoreDNS 日志。 3. 运行一个调试 Pod(例如 `busybox`)并使用 `nslookup` 从集群内部测试解析。
原因: DNS 是关键的集群依赖项。故障通常可以追溯到 CoreDNS 部署本身、其配置(在 ConfigMap 中)或阻止 UDP/TCP 端口 53 上的 DNS 流量的网络策略。
节点必须下线进行维护。
首先,`kubectl cordon <node-name>` 将其标记为不可调度。然后,`kubectl drain <node-name> --ignore-daemonsets` 以安全地驱逐所有用户 Pods。
原因: `cordon` 阻止新 Pods 被调度。`drain` 遵守 PodDisruptionBudgets 并优雅地驱逐 Pods。需要 `--ignore-daemonsets` 是因为 DaemonSet Pods 无法被驱逐。
识别哪些 Pods 或节点消耗了最多的 CPU 或 memory。
使用 `kubectl top pods` 和 `kubectl top nodes`。这需要 `metrics-server` 部署在集群中。
原因: `kubectl top` 提供了资源消耗的快速实时视图,对于识别资源密集型应用程序或节点资源压力至关重要。
Pod 长时间处于 `Terminating` 状态,未被删除。
使用 `kubectl delete pod <pod-name> --grace-period=0 --force` 强制删除 Pod。
原因: 如果 finalizer 卡住或 kubelet 无法清理资源,可能会发生这种情况。强制删除会立即从 API server 中移除 Pod,但应作为最后手段使用,因为它可能在节点上留下孤立资源。