许多运维工程师在初学Kubernetes时,往往会在一些相互关联的核心概念上反复“卡壳”。单纯阅读文档常常感到一知半解,真正的理解通常源于动手实践。本文将基于Kubernetes 1.29版本,为具备Linux基础和Docker使用经验的初中级运维工程师,深入剖析那些最容易“绊倒”新手的六个核心概念,并提供可直接上手的命令和排查方法。
概念一:Control Plane 与 Worker Node 的职责边界
1.1 架构概述
一个Kubernetes集群由两部分构成:Control Plane(控制平面)和Worker Node(工作节点)。简单来说,Control Plane是大脑,负责决策和指挥;Worker Node是四肢,负责执行具体的工作负载。
Control Plane的核心组件包括:
- kube-apiserver:集群的统一入口,处理所有RESTful API请求。
- etcd:分布式键值存储,保存集群所有的状态数据。
- kube-scheduler:调度器,负责为新创建的Pod选择最合适的节点。
- kube-controller-manager:运行各种控制器,执行集群级别的管理任务(如副本控制、节点控制)。
- cloud-controller-manager:与云厂商API交互,管理云资源(如负载均衡器、磁盘)。
Worker Node的核心组件包括:
- kubelet:与API Server通信,管理本节点上Pod的生命周期。
- kube-proxy:维护节点上的网络规则,实现Service的通信代理。
- container-runtime:容器运行时,如containerd或CRI-O,负责运行容器。
1.2 常见误解
新手常犯的错误是混淆了这两者的职责。例如,试图在Worker Node上查看etcd的数据或kube-apiserver的日志,这显然是行不通的。区分清楚组件的位置是排障的第一步。
你可以通过以下命令查看Control Plane组件的健康状态:
# 查看 Control Plane 组件健康状态
kubectl get componentstatuses
kubectl get cs
# 完整输出示例
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy {"health":"true","reason":""}
而查看etcd的详细状态,则需要在Control Plane节点上执行(因为它部署在那里):
# 查看 etcd 集群健康状态
sudo etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
endpoint health
# 查看 etcd 成员列表
sudo etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
member list
1.3 kubelet 与 API Server 的通信机制
kubelet与kube-apiserver之间采用双向TLS认证来保证安全通信。kube-apiserver需要验证kubelet的证书,确保请求来自合法的节点;反之,kubelet也需要验证kube-apiserver的证书,确保连接的是真正的控制平面。
查看kubelet的认证配置:
# 查看 kubelet 配置
cat /var/lib/kubelet/config.yaml
# 查看 kubelet 的证书信息
openssl x509 -in /var/lib/kubelet/pki/kubelet.crt -text -noout | grep -E "Subject:|Issuer:|Not Before:|Not After:"
概念二:命名空间与资源隔离
2.1 命名空间的作用
命名空间是Kubernetes中最重要的逻辑隔离机制之一,但新手往往低估了它的作用范围。
命名空间隔离的内容包括:资源对象(如Pod、Service、Deployment)、RBAC权限、网络策略、资源配额。
命名空间不隔离的内容包括:Node、PersistentVolume、CustomResourceDefinition(这些是集群级别的资源)。
查看集群中的命名空间:
kubectl get namespaces
kubectl describe namespace production
关键点: kubectl命令默认操作的是default命名空间。你必须时刻清楚自己操作的是哪个命名空间。
# 默认查看 default 命名空间
kubectl get pods
# 查看特定命名空间
kubectl get pods -n production
# 查看所有命名空间
kubectl get pods -A
# 查看所有命名空间的所有资源
kubectl get all -A
2.2 跨命名空间访问
跨命名空间访问Service是新手另一个容易混淆的地方。Kubernetes的DNS服务遵循固定的规则:
- 同命名空间内访问:直接使用Service名称即可,例如
nginx-service。
- 跨命名空间访问:必须使用Service的完全限定域名(FQDN),格式为:
<service-name>.<namespace-name>.svc.cluster.local。
# 在 default 命名空间中访问 production 命名空间的 nginx-service
# 完整格式
nginx-service.production.svc.cluster.local
# 简写格式(在同一命名空间内)
nginx-service.production
实际测试一下:
# 创建调试 Pod
kubectl run -it --rm debug --image=busybox:1.36 -- sh
# 在 Pod 内测试 DNS 解析
nslookup kubernetes.default
nslookup nginx-service.production.svc.cluster.local
# 测试跨命名空间访问
wget -qO- http://nginx-service.production.svc.cluster.local:80
2.3 资源配额与限制
对于生产环境,为命名空间设置资源配额(ResourceQuota)和默认限制(LimitRange)是必不可少的,它能防止单个应用耗尽集群资源。
定义ResourceQuota:
apiVersion: v1
kind: ResourceQuota
metadata:
name: production-quota
namespace: production
spec:
hard:
requests.cpu: "20"
requests.memory: 40Gi
limits.cpu: "40"
limits.memory: 80Gi
pods: "100"
services: "20"
persistentvolumeclaims: "50"
定义LimitRange来设置容器的默认资源限制:
apiVersion: v1
kind: LimitRange
metadata:
name: production-limits
namespace: production
spec:
limits:
- max:
cpu: "4"
memory: 8Gi
min:
cpu: "50m"
memory: 64Mi
default:
cpu: "500m"
memory: 256Mi
defaultRequest:
cpu: "100m"
memory: 128Mi
type: Container
概念三:Etcd 与数据一致性
3.1 Etcd 的核心地位
可以把etcd看作是Kubernetes集群的“大脑”或“单一事实来源”。所有集群状态——包括节点、Pod、配置、密钥——都存储在这里。如果etcd挂了或者数据不一致,整个集群就会陷入混乱。
etcd基于Raft一致性算法工作,生产环境通常部署3或5个节点以保证高可用。它保证了强一致性,意味着所有节点看到的数据顺序和内容都是一致的。
3.2 常见故障场景
场景一:Etcd 磁盘空间耗尽
这是生产环境最常见的故障。磁盘满了,etcd无法写入新数据,API Server也会随之罢工。
排查方法:
# 在 etcd 节点上查看磁盘使用
df -h /var/lib/etcd
# 查看 etcd 日志
sudo journalctl -u etcd -n 100 | grep -i error
# 查看 etcd 存储使用量
sudo etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
endpoint status
解决方案:
# 压缩 etcd 历史数据(需在每个节点执行)
sudo etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
defrag
# 清理不需要的历史快照
ls -la /var/lib/etcd/member/snap/
ls -la /var/lib/etcd/member/wal/
# 设置自动压缩(编辑 etcd 启动参数)
--auto-compaction-retention=1
--max-snapshots=5
--max-wals=5
场景二:Etcd 证书过期
证书过期会导致etcd节点间或客户端与etcd间无法认证,集群不可用。
检查证书有效期:
# 查看所有 Kubernetes 证书的过期时间
sudo kubeadm certs check-expiration
# 查看特定证书
openssl x509 -in /etc/kubernetes/pki/etcd/server.crt -noout -dates
更新证书:
# 在 Control Plane 节点上执行
sudo kubeadm certs renew all
# 重启相关服务
sudo systemctl restart kubelet
3.3 Etcd 备份与恢复
定期备份etcd是灾难恢复的底线。没有备份,一旦etcd数据彻底损坏,集群将无法恢复。
备份与恢复操作:
# 创建快照
ETCDCTL_API=3 sudo etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save /backup/etcd-snapshot-$(date +%Y%m%d).db
# 查看快照状态
ETCDCTL_API=3 sudo etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot status /backup/etcd-snapshot-$(date +%Y%m%d).db
# 从快照恢复(谨慎操作!)
sudo systemctl stop etcd
ETCDCTL_API=3 sudo etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot restore /backup/etcd-snapshot-20260101.db \
--data-dir=/var/lib/etcd/member
sudo systemctl start etcd
概念四:网络模型与 CNI 插件
4.1 Kubernetes 网络模型原则
Kubernetes对网络提出了几个基本要求:
- 每个Pod都拥有一个独立的IP地址,Pod间通信不需要网络地址转换(NAT)。
- 节点上的代理(如kubelet)能够与该节点上的所有Pod直接通信。
- 在未配置网络策略的情况下,Pod可以与任何其他Pod通信。
这个模型使得应用可以不做任何修改,就能在不同节点甚至不同集群间迁移。
4.2 CNI 插件的作用
Kubernetes自己不实现网络,而是通过CNI(Container Network Interface)标准,让第三方插件来负责。你需要选择一个CNI插件来满足上述网络模型。
常见插件对比:
- Flannel:简单易用,采用Overlay网络(如VXLAN),适合中小型集群。
- Calico:性能更好,采用BGP三层路由,原生支持强大的网络策略。
- Cilium:基于革命性的eBPF技术,提供L7层网络可视化和精细控制。
查看当前集群使用的CNI插件:
# 查看 CNI 配置目录
ls -la /etc/cni/net.d/
# 查看 CNI 插件配置
cat /etc/cni/net.d/10-flannel.conflist
# 查看网桥信息
ip link show type bridge
ip addr show flannel.1
4.3 Pod 网络故障排查
同节点Pod通信异常排查:
# 查看 Pod 的网络命名空间
kubectl exec -it <pod-name> -- ip addr
# 查看 Pod 的路由表
kubectl exec -it <pod-name> -- ip route
# 测试 Pod 之间的连通性
kubectl exec -it <source-pod> -- ping -c 3 <target-pod-ip>
# 查看节点的网桥和 veth 对
ip link show type bridge
ip link show type veth
跨节点Pod通信异常排查:
# 在源节点上测试
ping -I cni0 <target-pod-ip>
# 查看 CNI 插件的 overlay 网络
ip addr show flannel.1 # Flannel
ip addr show calico # Calico
# 查看路由表
route -n
ip route
4.4 DNS 故障排查
DNS问题是Kubernetes中最常见的问题之一。Kubernetes默认使用CoreDNS作为集群内的DNS服务器。
查看CoreDNS状态:
kubectl get pod -n kube-system -l k8s-app=kube-dns
# 查看 CoreDNS 配置
kubectl get configmap coredns -n kube-system -o yaml
创建一个Pod来测试DNS:
# 创建调试 Pod
kubectl run -it --rm dnsutils --image=tutum/dnsutils -- sh
# 测试 DNS 解析
nslookup kubernetes
nslookup kubernetes.default.svc.cluster.local
nslookup <service-name>
nslookup <service-name>.<namespace>
nslookup <service-name>.<namespace>.svc.cluster.local
# 测试 DNS 响应时间
time nslookup kubernetes.default.svc.cluster.local
概念五:存储卷与持久化存储
5.1 存储卷的类型
Kubernetes提供了丰富的存储卷类型以适应不同场景:
- 临时存储:
emptyDir,随Pod生命周期存在。
- 本地存储:
hostPath、local,依赖特定节点。
- 网络存储:NFS、Ceph RBD,可跨节点共享。
- 云存储:AWS EBS、Azure Disk,由云厂商提供高可用性。
5.2 PersistentVolume 与 PersistentVolumeClaim
这是Kubernetes抽象存储资源的两个核心API对象。
- PersistentVolume (PV):由管理员预先配置或由存储类动态提供的存储资源,是集群级别的资源。
- PersistentVolumeClaim (PVC):用户(或应用)发出的存储请求。Pod通过挂载PVC来使用PV。
示例:静态PV和PVC
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteMany
nfs:
server: nfs-server.example.com
path: /exports/pv01
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nfs
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 50Gi
selector:
matchLabels:
type: fast-storage
5.3 存储类与动态供给
StorageClass 可以让你动态地创建PV,无需手动预置,极大简化了存储管理。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-storage
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
fsType: ext4
replication-type: regional-pd
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
当用户创建PVC并指定storageClassName: fast-storage时,Kubernetes会自动调用对应的云厂商API(如AWS EBS)创建一个PV并绑定到该PVC。
5.4 存储故障排查
PVC 一直处于 Pending 状态
# 查看 PVC 详情
kubectl describe pvc <pvc-name>
# 常见原因:
# 1. 没有满足条件的 PV
# 2. StorageClass 不存在
# 3. 存储配额不足
# 排查 StorageClass
kubectl get storageclass
kubectl describe storageclass <sc-name>
# 查看所有 PV
kubectl get pv
Pod 无法挂载存储卷
# 查看 Pod 事件(重点看 Events 部分)
kubectl describe pod <pod-name> | grep -A 10 "Events:"
# 常见错误:
# Unable to attach or mount volumes: timeout expired
# node has pod with unmet topology requirement
# 查看 PV 的节点亲和性设置
kubectl get pv <pv-name> -o yaml | grep -A 5 nodeAffinity
概念六:认证、授权与 RBAC
6.1 Kubernetes 的认证机制
Kubernetes API Server支持多种方式来验证请求者的身份:
- X509客户端证书:最常用、最安全的方式。
- 静态令牌:Bearer Token,简单但需妥善保管。
- ServiceAccount令牌:Pod内部访问API Server的标准方式。
- OIDC:与企业外部身份提供商(如Okta, Azure AD)集成。
6.2 RBAC 权限模型
RBAC(基于角色的访问控制)是Kubernetes默认的授权模式。新手需要理解四个核心对象:
- Role / ClusterRole:定义“能做什么”(权限规则集合)。
- RoleBinding / ClusterRoleBinding:定义“谁有这些权限”(将角色绑定给用户、组或ServiceAccount)。
示例:创建一个只能读取Pod的角色并绑定给用户。
# 定义只读权限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
# 绑定权限到用户
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader-binding
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
6.3 常见权限问题排查
当执行命令遇到 Forbidden 错误时:
# 查看错误信息
kubectl get pods
Error from server (Forbidden): pods is forbidden: User "system:node:worker1" cannot list resource "pods" in API group "" in the namespace "default"
# 1. 确认当前上下文用户
kubectl config current-context
# 2. 查看指定用户拥有的所有权限
kubectl auth can-i --list --as=system:node:worker1
# 3. 测试特定权限
kubectl auth can-i get pods --as=system:node:worker1
kubectl auth can-i delete pods --as=system:node:worker1
6.4 ServiceAccount 的使用
每个Pod都会自动关联一个ServiceAccount(默认为default)。Pod内的进程可以使用该ServiceAccount的令牌与API Server安全通信。
显式指定ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: default
---
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
serviceAccountName: my-app-sa # 指定使用的SA
containers:
- name: my-app
image: my-app:latest
在Pod内部使用令牌访问API:
# 在 Pod 内查看令牌
kubectl exec -it my-app -- cat /var/run/secrets/kubernetes.io/serviceaccount/token
# 使用令牌访问 API Server
kubectl exec -it my-app -- \
curl -k https://kubernetes.default.svc/api/v1/namespaces/default/pods \
--header "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
综合排障流程
当集群出现问题时,遵循一个清晰的排查路径至关重要。
第一步:确认问题范围
# 查看集群所有组件状态
kubectl get componentstatuses
kubectl get nodes
# 查看 Control Plane 组件日志
kubectl logs -n kube-system -l component=kube-apiserver --tail=100
kubectl logs -n kube-system -l component=kube-controller-manager --tail=100
kubectl logs -n kube-system -l component=kube-scheduler --tail=100
# 查看 kubelet 日志
sudo journalctl -u kubelet --tail=100
第二步:逐层排查资源状态
# 1. 检查 Deployment 状态
kubectl get deployment -A
kubectl describe deployment <name> -n <namespace>
# 2. 检查 ReplicaSet 状态
kubectl get rs -A
kubectl describe rs <name> -n <namespace>
# 3. 检查 Pod 状态
kubectl get pods -A
kubectl describe pod <name> -n <namespace>
# 4. 检查 Service 和 Endpoint
kubectl get svc -A
kubectl get endpoints -A
第三步:检查网络连通性
# 1. 测试 DNS 解析
kubectl run -it --rm debug --image=busybox:1.36 -- nslookup kubernetes
# 2. 测试 Service 访问
kubectl run -it --rm debug --image=busybox:1.36 -- wget -qO- http://kubernetes.default:80
# 3. 测试 Pod 间连通性
kubectl exec -it <pod-name> -- ping -c 3 <target-pod-ip>
第四步:检查资源配额
# 检查命名空间资源配额
kubectl describe namespace <namespace> | grep -A 10 "ResourceQuota"
# 检查 LimitRange
kubectl describe limitrange -n <namespace>
# 检查节点资源使用
kubectl describe node <node-name> | grep -A 10 "Allocated resources"
总结与最佳实践
理解这六个核心概念——集群架构、命名空间、etcd、网络、存储和RBAC——是掌握Kubernetes的基石。它们相互关联:控制平面通过etcd协调状态,网络模型实现Pod间通信,存储提供数据持久化,而RBAC则守护着所有的访问入口。
对于运维工程师而言,遇到问题不要慌。按照从控制平面到数据平面、从资源对象到网络、存储的逻辑逐层排查。善用 kubectl describe 和 kubectl logs 命令,仔细查看资源的 Events 字段,这里往往藏着问题的第一线索。
最后,在学习过程中,多动手搭建测试环境,主动“制造”和解决问题,是突破这些概念瓶颈最有效的方法。理论与实践相结合,才能更深入地驾驭Kubernetes这一强大的容器编排平台。如果你想与更多同行交流这些实践心得,云栈社区的运维和云原生板块会是一个不错的去处。