目录
- 1. 开篇:K8s的"血管系统"危机
- 2. CNI:Pod的网络身份证
- 3. Flannel:小集群的贴心管家
- 4. Calico:大厂的BGP网络专家
- 5. Cilium:eBPF加持的安全卫士
- 6. CNI选型实战指南
- 7. CSI:存储界的USB接口
- 8. PersistentVolume与StorageClass
- 9. 文末三件套
开篇:K8s的"血管系统"危机
你是否遇到过Pod之间突然无法通信、CNI插件选错导致网络性能腰斩、有状态应用数据神秘丢失的抓狂时刻?CNI和CSI是Kubernetes的两大血管系统,选错了可是会要命的。本文将给出生产级别的选型指南。
💡效率技巧:很多新手一上来就问"哪个CNI最好",这就像问"宝马和奔驰哪个好"——不看场景谈选型都是耍流氓。
想象一下,你的Kubernetes集群是一座繁华的城市,Pod是城里的居民。没有CNI(Container Network Interface),这些居民就像被关在各自小黑屋里——看得见彼此,却永远无法交流。而CSI(Container Storage Interface)则是城市的供水供电系统,没有它,有状态应用就像没有水电的毛坯房,根本住不了人。
CNI:Pod的网络身份证
什么是CNI?
CNI(Container Network Interface)是CNCF(云原生计算基金会)推出的容器网络标准。你可以把它理解为Pod的"网络身份证发放中心"。
┌─────────────────────────────────────────────────────────────┐ │ Kubernetes 集群 │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Pod A │◄──►│ Pod B │◄──►│ Pod C │◄──►│ Pod D │ │ │ │10.244.1.2│ │10.244.1.3│ │10.244.2.2│ │10.244.2.3│ │ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ │ └──────────────┴──────────────┴──────────────┘ │ │ │ │ │ ┌────┴────┐ │ │ │ CNI │ ← 网络插件(Flannel/Calico/Cilium)│ │ │ 插件 │ │ │ └────┬────┘ │ │ │ │ │ ┌─────────────────┼─────────────────┐ │ │ │ │ │ │ │ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ │ │ │ Node 1 │ │ Node 2 │ │ Node 3 │ │ │ │(Worker) │ │(Worker) │ │(Master) │ │ │ └─────────┘ └─────────┘ └─────────┘ │ └─────────────────────────────────────────────────────────────┘CNI的核心职责:
- 1.IP分配:给每个Pod分配唯一的IP地址(就像给每个居民发身份证)
- 2.网络连通:让Pod之间可以互相通信(同一节点和跨节点)
- 3.网络策略:控制谁能访问谁(保安系统)
⚠️避坑警告:CNI和Service不是一回事!Service是K8s内置的负载均衡机制,而CNI是底层网络实现。没有CNI,Service也巧妇难为无米之炊。
Flannel:小集群的贴心管家
Flannel是什么?
Flannel是CoreOS(被Red Hat收购)开发的轻量级CNI插件,主打一个"简单够用"。它就像你刚毕业时租的小单间——麻雀虽小,五脏俱全。
VXLAN模式工作原理
┌─────────────────────────────────────────────────────────────────────┐ │ Flannel VXLAN 架构 │ │ │ │ Node 1 (10.0.0.1) Node 2 (10.0.0.2) │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ Pod A │ │ Pod B │ │ │ │ 10.244.1.2/24 │ │ 10.244.2.2/24 │ │ │ │ │ │ │ │ │ │ │ │ ▼ │ │ ▼ │ │ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ │ │ │ cni0 │ │ │ │ cni0 │ │ │ │ │ │10.244.1.1│ │ │ │10.244.2.1│ │ │ │ │ └────┬────┘ │ │ └────┬────┘ │ │ │ │ │ │ │ │ │ │ │ │ ┌────┴────┐ │ │ ┌────┴────┐ │ │ │ │ │flannel.1│◄────┼──────────┼─►│flannel.1│ │ │ │ │ │ VTEP │ │ VXLAN │ │ VTEP │ │ │ │ │ └────┬────┘ │ Tunnel │ └────┬────┘ │ │ │ │ │ │ │ │ │ │ │ │ ┌────┴────┐ │ │ ┌────┴────┐ │ │ │ │ │ eth0 │◄────┼──────────┼─►│ eth0 │ │ │ │ │ │10.0.0.1 │ │ │ │10.0.0.2 │ │ │ │ │ └─────────┘ │ │ └─────────┘ │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ │ 数据包流向:Pod A → cni0 → flannel.1 → VXLAN封装 → eth0 ────────► │ │ │ │ │ ▼ │ │ Node 2 eth0 │ │ │ │ │ ▼ │ │ VXLAN解封装 │ │ │ │ │ ▼ │ │ flannel.1 → cni0 → Pod B │ └─────────────────────────────────────────────────────────────────────┘**VXLAN(Virtual Extensible LAN)**是一种网络虚拟化技术,它在UDP之上封装二层以太网帧,实现跨物理网络的虚拟网络。
Flannel部署代码
# flannel-deploy.yaml --- apiVersion: v1 kind: Namespace metadata: name: kube-flannel labels: k8s-app: flannel pod-security.kubernetes.io/enforce: privileged --- apiVersion: v1 kind: ServiceAccount metadata: name: flannel namespace: kube-flannel --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: flannel rules: - apiGroups: [''] resources: ['pods'] verbs: ['get'] - apiGroups: [''] resources: ['nodes'] verbs: ['get', 'list', 'watch'] - apiGroups: [''] resources: ['nodes/status'] verbs: ['patch'] - apiGroups: ['networking.k8s.io'] resources: ['clustercidrs'] verbs: ['list', 'watch'] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: flannel roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: flannel subjects: - kind: ServiceAccount name: flannel namespace: kube-flannel --- apiVersion: v1 kind: ConfigMap metadata: name: kube-flannel-cfg namespace: kube-flannel labels: tier: node k8s-app: flannel app: flannel data: cni-conf.json: | { "name": "cbr0", "cniVersion": "0.3.1", "plugins": [ { "type": "flannel", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] } net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan" } } --- apiVersion: apps/v1 kind: DaemonSet metadata: name: kube-flannel-ds namespace: kube-flannel labels: tier: node app: flannel k8s-app: flannel spec: selector: matchLabels: app: flannel template: metadata: labels: tier: node app: flannel spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/os operator: In values: - linux hostNetwork: true priorityClassName: system-node-critical tolerations: - operator: Exists effect: NoSchedule serviceAccountName: flannel initContainers: - name: install-cni-plugin image: docker.io/flannel/flannel-cni-plugin:v1.1.2 command: - cp args: - -f - /flannel - /opt/cni/bin/flannel volumeMounts: - name: cni-plugin mountPath: /opt/cni/bin - name: install-cni image: docker.io/flannel/flannel:v0.22.0 command: - cp args: - -f - /etc/kube-flannel/cni-conf.json - /etc/cni/net.d/10-flannel.conflist volumeMounts: - name: cni mountPath: /etc/cni/net.d - name: flannel-cfg mountPath: /etc/kube-flannel containers: - name: kube-flannel image: docker.io/flannel/flannel:v0.22.0 command: - /opt/bin/flanneld args: - --ip-masq - --kube-subnet-mgr resources: requests: cpu: "100m" memory: "50Mi" securityContext: privileged: false capabilities: add: ["NET_ADMIN", "NET_RAW"] env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: EVENT_QUEUE_DEPTH value: "5000" volumeMounts: - name: run mountPath: /run/flannel - name: flannel-cfg mountPath: /etc/kube-flannel - name: xtables-lock mountPath: /run/xtables.lock volumes: - name: run hostPath: path: /run/flannel - name: cni-plugin hostPath: path: /opt/cni/bin - name: cni hostPath: path: /etc/cni/net.d - name: flannel-cfg configMap: name: kube-flannel-cfg - name: xtables-lock hostPath: path: /run/xtables.lock type: FileOrCreate部署命令:
kubectl apply -f flannel-deploy.yamlFlannel的优缺点
| 优点 | 缺点 |
|---|---|
| 部署简单,一条命令搞定 | 不支持网络策略(NetworkPolicy) |
| 资源占用低 | 大规模集群性能下降 |
| 社区成熟,文档丰富 | 功能相对单一 |
| 支持多种后端(VXLAN、host-gw等) | 跨节点通信有封装开销 |
💡效率技巧:Flannel VXLAN模式适合500节点以下的中小规模集群。如果你的集群超过500节点,赶紧往下看Calico。
幽默一刻:Flannel就像你大学宿舍的WiFi——能用,但别指望它能承载整个宿舍楼的流量。当你发现Pod之间通信开始"转圈圈"时,就该考虑升级了。
Calico:大厂的BGP网络专家
什么是Calico?
Calico是Tigera公司(后被SUSE收购)开发的企业级CNI插件,主打"高性能+网络策略"。如果说Flannel是经济适用的五菱宏光,那Calico就是能拉货能越野的丰田陆巡。
BGP模式工作原理
┌─────────────────────────────────────────────────────────────────────────────┐ │ Calico BGP 架构 │ │ │ │ ┌─────────────┐ │ │ │ Router │ │ │ │ (ToR/核心) │ │ │ │ AS 64512 │ │ │ └──────┬──────┘ │ │ │ │ │ ┌────────────────────────┼────────────────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Node 1 │ │ Node 2 │ │ Node 3 │ │ │ │ AS 64513 │◄────────►│ AS 64514 │◄────────►│ AS 64515 │ │ │ │ (iBGP/eBGP)│ BGP │ (iBGP/eBGP)│ BGP │ (iBGP/eBGP)│ │ │ └──────┬──────┘ Session └──────┬──────┘ Session └──────┬──────┘ │ │ │ │ │ │ │ ┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐ │ │ │ Pod A │ │ Pod B │ │ Pod C │ │ │ │ 10.244.1.2 │ │ 10.244.2.2 │ │ 10.244.3.2 │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ 核心特点: │ │ 1. 每个Node是一个BGP路由器 │ │ 2. Pod IP直接路由,无需封装 │ │ 3. 支持细粒度的网络策略(NetworkPolicy) │ │ 4. 可对接物理网络,实现Pod与外部直接通信 │ └─────────────────────────────────────────────────────────────────────────────┘**BGP(Border Gateway Protocol)**是互联网的核心路由协议。Calico利用BGP让每个Node成为一个路由器,直接宣告Pod IP段,实现三层路由。
Calico部署代码
# 安装Calico(使用Operator方式) kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/tigera-operator.yaml # 配置Calico安装 kubectl create -f - <<EOF apiVersion: operator.tigera.io/v1 kind: Installation metadata: name: default spec: calicoNetwork: ipPools: - name: default-ipv4-ippool blockSize: 26 cidr: 10.244.0.0/16 encapsulation: VXLANCrossSubnet # 跨子网使用VXLAN,同子网直接路由 natOutgoing: Enabled nodeSelector: all() EOFCalico网络策略示例
# deny-all.yaml - 默认拒绝所有入站流量 apiVersion: projectcalico.org/v3 kind: GlobalNetworkPolicy metadata: name: default-deny spec: selector: all() types: - Ingress --- # allow-frontend.yaml - 只允许frontend访问backend apiVersion: projectcalico.org/v3 kind: NetworkPolicy metadata: name: allow-frontend-to-backend namespace: production spec: selector: app == 'backend' types: - Ingress ingress: - action: Allow protocol: TCP source: selector: app == 'frontend' destination: ports: - 8080 --- # block-external.yaml - 阻止Pod访问外部特定IP apiVersion: projectcalico.org/v3 kind: GlobalNetworkPolicy metadata: name: block-sensitive-ips spec: selector: all() types: - Egress egress: - action: Deny destination: nets: - 10.0.0.100/32 # 敏感数据库IP - action: AllowCalico的优缺点
| 优点 | 缺点 |
|---|---|
| 支持10,000+节点规模 | 配置相对复杂 |
| 原生支持网络策略 | 需要理解BGP概念 |
| 无封装开销(BGP模式) | 某些云厂商不支持BGP |
| 性能优异 | 学习曲线较陡 |
| 可与物理网络集成 | 默认模式需要Node支持IP转发 |
⚠️避坑警告:在AWS、Azure等公有云上使用Calico时,如果开启BGP模式,需要确保云厂商支持BGP路由。否则请使用VXLAN或IPIP模式作为fallback。
幽默一刻:Calico就像公司的IT部门——功能强大但规矩也多。你想让Pod A访问Pod B?先填个网络策略申请表,等Calico审批通过再说。
Cilium:eBPF加持的安全卫士
什么是Cilium?
Cilium是基于eBPF(Extended Berkeley Packet Filter)的下一代CNI插件,主打"可观测性+安全性+高性能"。如果说Calico是丰田陆巡,那Cilium就是特斯拉Cybertruck——科技感拉满,但你需要先学会开它。
eBPF是什么?
eBPF是Linux内核的一项革命性技术,允许在内核中安全地运行沙盒程序。简单说,它让Cilium可以"住"在内核里,直接处理网络流量,而不需要经过传统的网络栈。
┌─────────────────────────────────────────────────────────────────────────────┐ │ Cilium eBPF 架构 │ │ │ │ 传统网络栈 vs eBPF加速 │ │ │ │ 传统方式(Flannel/Calico): │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Pod A │──►│ veth │──►│ Bridge │──►│ Route │──►│ eth0 │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ 用户态 内核态 内核态 内核态 硬件 │ │ │ │ Cilium eBPF方式: │ │ ┌─────────┐ │ │ │ Pod A │──────────────────────────────────────────┐ │ │ └────┬────┘ │ │ │ │ ▼ │ │ │ ┌─────────────┐ │ │ │ │ eBPF Hook │ │ │ │ │ (直接处理) │ │ │ │ └──────┬──────┘ │ │ │ │ │ │ └────────────────────────────────────────────────┘ │ │ 绕过传统网络栈,直接在内核处理 │ │ │ │ 性能提升: │ │ - 网络转发延迟降低 30% │ │ - CPU使用率降低 │ │ - 支持L3/L4/L7层策略 │ │ - 内置可观测性(Hubble) │ └─────────────────────────────────────────────────────────────────────────────┘Cilium部署代码
# 添加Cilium Helm仓库 helm repo add cilium https://helm.cilium.io/ helm repo update # 安装Cilium(使用eBPF替代kube-proxy) helm install cilium cilium/cilium --version 1.14.0 \ --namespace kube-system \ --set kubeProxyReplacement=strict \ --set k8sServiceHost=\"<API_SERVER_IP>\" \ --set k8sServicePort=6443 # 验证安装 kubectl -n kube-system exec ds/cilium -- cilium statusCilium网络策略(L7层!)
# l7-policy.yaml - 限制HTTP API访问 apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: api-restrictions namespace: production spec: endpointSelector: matchLabels: app: backend-api ingress: - fromEndpoints: - matchLabels: app: frontend toPorts: - ports: - port: "80" protocol: TCP rules: http: - method: GET path: "/api/v1/users/.*" - method: POST path: "/api/v1/users" - method: GET path: "/api/v1/products/.*" - fromEndpoints: - matchLabels: app: admin-dashboard toPorts: - ports: - port: "80" protocol: TCP rules: http: - method: ".*" # 管理员可以访问所有API path: "/api/.*"Cilium可观测性(Hubble)
# 启用Hubble helm upgrade cilium cilium/cilium --version 1.14.0 \ --namespace kube-system \ --reuse-values \ --set hubble.enabled=true \ --set hubble.relay.enabled=true \ --set hubble.ui.enabled=true # 查看实时流量 kubectl exec -n kube-system -t ds/cilium -- hubble observe # 输出示例: # May 15 10:23:45.123 [pod-a]:8080 -> [pod-b]:8080 L3-L4 FORWARDED TCP Flags: SYN # May 15 10:23:45.125 [pod-b]:8080 -> [pod-a]:8080 L3-L4 FORWARDED TCP Flags: SYN-ACKCilium的优缺点
| 优点 | 缺点 |
|---|---|
| eBPF性能提升30% | 内核版本要求高(4.19+) |
| 支持L7层策略 | 学习曲线最陡 |
| 内置可观测性(Hubble) | 社区相对年轻 |
| 服务网格集成(Cilium Service Mesh) | 某些旧系统可能不兼容 |
| 安全性最强 | 调试相对复杂 |
💡效率技巧:Cilium最适合对安全性和可观测性要求高的场景,比如金融、医疗等行业。如果你的集群需要"知道"流量在干什么(而不仅仅是通不通),Cilium是不二之选。
幽默一刻:Cilium就像你那个会写代码的健身教练——它不仅能帮你"跑得快"(性能),还能告诉你"怎么跑才对"(可观测性),甚至能阻止你"跑错地方"(安全策略)。唯一的缺点是,你得先学会听懂它说的话(eBPF)。
CNI选型实战指南
决策树
┌─────────────────────────────────────────────────────────────────────────────┐ │ CNI 选型决策树 │ │ │ │ 开始选型 │ │ │ │ │ ▼ │ │ ┌─────────────────────────┐ │ │ │ 集群规模 < 100 节点? │ │ │ └─────────────┬───────────┘ │ │ │ │ │ ┌─────────────┴─────────────┐ │ │ ▼ ▼ │ │ 是 否 │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────────┐ ┌─────────────────────────┐ │ │ │ 需要网络策略? │ │ 需要网络策略? │ │ │ └────────┬────────┘ └───────────┬─────────────┘ │ │ │ │ │ │ ┌───────┴───────┐ ┌───────┴───────┐ │ │ ▼ ▼ ▼ ▼ │ │ 否 是 否 是 │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ ┌──────┐ ┌────────┐ ┌──────┐ ┌────────┐ │ │ │Flannel│ │Calico │ │Calico│ │Cilium │ │ │ │(简单) │ │(功能全)│ │(性能)│ │(安全+) │ │ │ └──────┘ └────────┘ └──────┘ └────────┘ │ │ │ │ 特殊场景: │ │ - 需要服务网格 → Cilium │ │ - 需要L7层策略 → Cilium │ │ - 云厂商托管K8s → 用云厂商默认CNI(如AWS VPC CNI) │ │ - 混合云/多集群 → Calico BGP │ └─────────────────────────────────────────────────────────────────────────────┘选型速查表
| 场景 | 推荐CNI | 理由 |
|---|---|---|
| 测试/开发环境 | Flannel | 部署简单,够用就好 |
| 中小规模生产(<500节点) | Flannel/Calico | Flannel简单,Calico功能全 |
| 大规模生产(>500节点) | Calico/Cilium | BGP性能,eBPF未来 |
| 需要网络策略 | Calico/Cilium | 原生支持 |
| 需要L7层策略 | Cilium | 唯一选择 |
| 需要服务网格 | Cilium | 内置服务网格 |
| 金融/医疗等高安全 | Cilium | 可观测性+安全 |
| 云厂商托管K8s | 云厂商默认 | 与VPC集成最好 |
⚠️避坑警告:不要在一个集群中混用多个CNI!这就像在一台车上装两个方向盘——理论上行得通,实际上会撞墙。
CSI:存储界的USB接口
什么是CSI?
CSI(Container Storage Interface)是Kubernetes的存储标准接口。你可以把它理解为存储界的"USB接口"——不管你的存储后端是AWS EBS、Ceph、NFS还是本地磁盘,CSI都能让K8s"插上去就能用"。
┌─────────────────────────────────────────────────────────────────────────────┐ │ CSI 架构 │ │ │ │ ┌──────────────────────────────────────────────────────────────────┐ │ │ │ Kubernetes Cluster │ │ │ │ │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ Pod A │ │ Pod B │ │ Pod C │ │ Pod D │ │ │ │ │ │(有状态) │ │(有状态) │ │(有状态) │ │(有状态) │ │ │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ │ │ │ │ │ └──────────────┴──────────────┴──────────────┘ │ │ │ │ │ │ │ │ │ ┌──────┴──────┐ │ │ │ │ │ PVC (申请) │ ← "我要10G存储" │ │ │ │ └──────┬──────┘ │ │ │ │ │ │ │ │ │ ┌──────┴──────┐ │ │ │ │ │ PV (实际) │ ← "给你10G存储" │ │ │ │ └──────┬──────┘ │ │ │ │ │ │ │ │ │ ┌────────────┼────────────┐ │ │ │ │ ▼ ▼ ▼ │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │CSI Driver│ │CSI Driver│ │CSI Driver│ │ │ │ │ │(AWS EBS) │ │(Ceph) │ │(NFS) │ │ │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ │ │ │ └─────────────┼────────────┼────────────┼──────────────────────────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │AWS EBS │ │ Ceph │ │ NFS │ │ │ │云盘 │ │分布式存储│ │网络存储 │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ 核心组件: │ │ - CSI Controller:负责创建/删除卷、快照、扩容等控制操作 │ │ - CSI Node:负责在Node上挂载/卸载卷 │ │ - StorageClass:定义存储"模板"(类型、性能、回收策略) │ └─────────────────────────────────────────────────────────────────────────────┘为什么需要CSI?
在CSI出现之前,K8s的存储支持是"写死在代码里"的——想支持新的存储后端?得改K8s源码,等半年发版。CSI把存储驱动从K8s核心解耦出来,让存储厂商可以自己开发驱动,就像USB让外设厂商自己开发驱动一样。
幽默一刻:没有CSI的年代,K8s存储就像老式的打印机接口——每种打印机都需要专门的并口线。CSI就是那个拯救世界的USB接口,终于让存储厂商和K8s可以"和平共处"。
PersistentVolume与StorageClass
核心概念
| 概念 | 类比 | 说明 |
|---|---|---|
| PersistentVolume (PV) | 硬盘 | 集群中的实际存储资源 |
| PersistentVolumeClaim (PVC) | 购买申请 | Pod对存储的申请 |
| StorageClass | 硬盘型号 | 存储的"模板",定义性能、类型等 |
| VolumeSnapshot | 快照 | 存储的时间点备份 |
完整示例:从StorageClass到Pod使用
# 1. 定义StorageClass(管理员配置) # storageclass-fast.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast-ssd annotations: storageclass.kubernetes.io/is-default-class: "true" # 设为默认 provisioner: ebs.csi.aws.com # AWS EBS CSI Driver parameters: type: gp3 # SSD类型 encrypted: "true" # 加密 iops: "3000" # IOPS throughput: "125" # 吞吐量 MiB/s volumeBindingMode: WaitForFirstConsumer # 延迟绑定,优化调度 allowVolumeExpansion: true # 允许扩容 reclaimPolicy: Retain # 保留策略(Delete/Retain) --- # 2. 创建PVC(用户申请) # pvc-app.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: app-data namespace: production spec: accessModes: - ReadWriteOnce # 单节点读写 storageClassName: fast-ssd resources: requests: storage: 50Gi # 申请50GB --- # 3. Pod使用PVC # pod-with-pvc.yaml apiVersion: apps/v1 kind: Deployment metadata: name: postgres namespace: production spec: replicas: 1 selector: matchLabels: app: postgres template: metadata: labels: app: postgres spec: containers: - name: postgres image: postgres:15 env: - name: POSTGRES_DB value: myapp - name: POSTGRES_USER value: dbuser - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: db-credentials key: password ports: - containerPort: 5432 volumeMounts: - name: data mountPath: /var/lib/postgresql/data resources: requests: memory: "512Mi" cpu: "500m" limits: memory: "1Gi" cpu: "1000m" volumes: - name: data persistentVolumeClaim: claimName: app-data动态供给 vs 静态供给
┌─────────────────────────────────────────────────────────────────────────────┐ │ 静态供给 vs 动态供给 │ │ │ │ 静态供给(Pre-provisioned): │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 管理员 │────►│ 创建PV │────►│ 用户PVC │────►绑定 │ │ │ 手动创建 │ │ (NFS等) │ │ 申请 │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ 动态供给(Dynamic Provisioning): │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 管理员 │────►│StorageClass│──►│ 用户PVC │────►│ CSI自动 │────►PV创建 │ │ │ 配置模板 │ │ (模板) │ │ 申请 │ │ 创建PV │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ 推荐:生产环境使用动态供给,按需创建,用完回收 │ └─────────────────────────────────────────────────────────────────────────────┘访问模式详解
# access-modes.yaml - 不同场景的访问模式选择 --- # ReadWriteOnce (RWO) - 单节点读写 # 适用:数据库、单实例应用 apiVersion: v1 kind: PersistentVolumeClaim metadata: name: database-storage spec: accessModes: - ReadWriteOnce resources: requests: storage: 100Gi --- # ReadOnlyMany (ROX) - 多节点只读 # 适用:静态文件、配置文件 apiVersion: v1 kind: PersistentVolumeClaim metadata: name: static-assets spec: accessModes: - ReadOnlyMany resources: requests: storage: 10Gi --- # ReadWriteMany (RWX) - 多节点读写 # 适用:共享存储、内容管理系统 # 注意:需要存储后端支持(NFS、CephFS、GlusterFS等) apiVersion: v1 kind: PersistentVolumeClaim metadata: name: shared-storage spec: accessModes: - ReadWriteMany resources: requests: storage: 500Gi数据保护:快照与恢复
# 创建快照 # snapshot.yaml apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: postgres-snapshot-20240515 namespace: production spec: volumeSnapshotClassName: csi-aws-vsc source: persistentVolumeClaimName: app-data --- # 从快照恢复 # restore-from-snapshot.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: app-data-restored namespace: production spec: storageClassName: fast-ssd dataSource: name: postgres-snapshot-20240515 kind: VolumeSnapshot apiGroup: snapshot.storage.k8s.io accessModes: - ReadWriteOnce resources: requests: storage: 50Gi⚠️避坑警告:使用ReadWriteMany前,务必确认你的存储后端支持!AWS EBS、GCP PD都只支持RWO。需要RWX时,考虑使用NFS、CephFS或AWS EFS。
💡效率技巧:设置volumeBindingMode: WaitForFirstConsumer可以让PVC等到Pod调度后再绑定,这样K8s可以根据Pod的资源需求选择最优的Node,而不是随机分配导致调度失败。
文末三件套
1. 【源码获取】
关注此系列获取后续更新,后台回复'cni'获取本文所有YAML配置文件的完整源码包。
2. 【思考题】
你的集群需要什么样的网络插件?
- • 是追求简单快速的Flannel?
- • 还是功能全面的Calico?
- • 亦或是未来感十足的Cilium?
在评论区分享你的选择理由,点赞最高的三位读者将获得《Kubernetes网络权威指南》电子书一本!
3. 【系列预告】
本系列持续更新中,下一期主题:
- 1.容器编排与调度→ 深度解析Scheduler,让你的Pod去该去的地方
- 2.GitOps实战→ ArgoCD+Flux,声明式持续交付的正确姿势
- 3.Helm进阶→ Chart开发、版本管理、私有仓库搭建
CSDN标签
CNIFlannelCalicoCiliumCSIPVStorageClass网络插件Kubernetes云原生
本文首发于CSDN,转载请注明出处。如有疑问,欢迎在评论区留言交流!