找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3224

积分

0

好友

431

主题
发表于 1 小时前 | 查看: 2| 回复: 0

许多运维工程师在初学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 的通信机制

kubeletkube-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对网络提出了几个基本要求:

  1. 每个Pod都拥有一个独立的IP地址,Pod间通信不需要网络地址转换(NAT)。
  2. 节点上的代理(如kubelet)能够与该节点上的所有Pod直接通信。
  3. 在未配置网络策略的情况下,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生命周期存在。
  • 本地存储hostPathlocal,依赖特定节点。
  • 网络存储: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 describekubectl logs 命令,仔细查看资源的 Events 字段,这里往往藏着问题的第一线索。

最后,在学习过程中,多动手搭建测试环境,主动“制造”和解决问题,是突破这些概念瓶颈最有效的方法。理论与实践相结合,才能更深入地驾驭Kubernetes这一强大的容器编排平台。如果你想与更多同行交流这些实践心得,云栈社区的运维和云原生板块会是一个不错的去处。




上一篇:人工智能拟人化互动新规解读:AI伴侣、乙女游戏与行业合规挑战
下一篇:海底捞CEO道歉背后:员工自费买礼暴露餐饮管理深层危机
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-15 06:17 , Processed in 0.781627 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表