为 Cilium 准备集群:先禁用默认 CNI
Cilium 会完全取代集群的网络,这意味着操作顺序比大多数插件更重要。
大多数 Kubernetes 插件是安装到一个已经正常工作的集群中的。Cilium 则不同:作为 CNI,它就是集群的网络,这意味着集群必须在没有默认 CNI 占据这一角色的情况下创建,否则 Cilium 就没有可接管的对象。本指南介绍这一先后顺序,使用本地的 kind 集群,然后用 Helm 安装 Cilium。
为什么顺序在这里很重要
Kubernetes 集群通常在启动时就已经安装了某个 CNI 来管理 Pod 网络,在 kind 上是 kindnet,在云服务商上则是其自带的默认 CNI。如果在一个已经启用 CNI 的集群上再安装 Cilium,就会出现两个网络插件都试图掌管同一件事的情况,这是行不通的。Cilium 必须是唯一的 CNI,这意味着要在安装 Cilium 之前,而不是之后,禁用原本会占据这一角色的默认 CNI。
创建禁用默认 CNI 的集群
在 kind 上,这是集群的配置项,而不是事后再去禁用的东西:
# kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
disableDefaultCNI: true
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30080
hostPort: 80
- containerPort: 30443
hostPort: 443
- role: worker
kind create cluster --config kind-config.yaml
kubectl get nodes
预期每个节点都显示 NotReady。这是正常现象,并非失败:在尚未安装 CNI 时,节点无法被标记为就绪。这里的 extraPortMappings 对基本安装并非必需;它们是为本系列后面通过 kind 对外暴露服务的指南预先设置的,因为 kind 自身没有云负载均衡器来分配可路由地址。
如果你使用的是托管的云 Kubernetes 服务而不是本地集群,请查阅该服务商自己的文档,了解如何创建不带默认 CNI 的集群;具体机制因服务商而异,但根本要求是一致的:在 Cilium 安装之前,不能有 CNI 占据这一角色。
如果要使用 Gateway API,先于 Cilium 安装 Gateway API CRD
如果你计划在 Cilium 中使用 Kubernetes Gateway API(下一篇指南会介绍),请现在就安装它的 CustomResourceDefinition,然后再在 Cilium 自己的安装中启用 Gateway API 支持。Cilium 的 Gateway API 控制器要求这些 CRD(GatewayClass、Gateway、HTTPRoute 及相关类型)已经存在于集群中:
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/standard-install.yaml
请固定到某个具体的 Gateway API 发布版本,而不是总是拉取最新的。Gateway API 的演进速度快于每个实现的跟进速度,而 Cilium 自己的发布说明会指明某个 Cilium 版本实际测试过的 Gateway API 版本;使用比 Cilium 支持的更新的 CRD 版本,是造成与你自身配置无关的、令人困惑的错误的现实原因之一。
用 Helm 安装 Cilium
helm repo add cilium https://helm.cilium.io
helm repo update
helm show values cilium/cilium --version 1.19.0 > cilium-values.yaml
安装前花几分钟审阅完整的默认 values 文件是值得的;它很长,但它是可配置项的权威清单。对于同时要使用 Gateway API 的集群,最重要的设置是:
# cilium-values.yaml (relevant excerpt)
kubeProxyReplacement: true
gatewayAPI:
enabled: true
gatewayClass:
create: false # create your own GatewayClass explicitly, covered in the next guide
hubble:
enabled: true
relay:
enabled: true
ui:
enabled: true
kubeProxyReplacement: true 让 Cilium 完全接管 Service 路由,以 eBPF 实现(如上一篇指南所述),而不是与 kube-proxy 并行运行。将 gatewayClass.create 设为 false 是有意的选择,而不是你必须沿用的默认值:这意味着由你自己创建并掌管 GatewayClass 资源(如果你通过 Argo CD 或 Flux 等 GitOps 工具管理它,这很有用,它可以与其余配置一样被追踪),而不是让 Helm chart 隐式创建一个。在这里启用 Hubble 及其 UI,可以获得本系列各处提到的可观测性工具,不过 Gateway API 或 BGP 自身的运行并不依赖它。
helm install cilium cilium/cilium \
--version 1.19.0 \
--namespace kube-system \
-f cilium-values.yaml
确认安装
kubectl get pods -n kube-system -l k8s-app=cilium
kubectl get nodes
Cilium 的 Pod 应该进入 Running,而一旦它们就绪,集群刚创建时处于 NotReady 的节点应该会立即变为 Ready;为此无需再做其他事情,正是每个节点上 Cilium 自身的 agent 启动后才解除了这个阻塞。
关于之后可以安全更改的内容
kubeProxyReplacement 以及安装哪个 CNI,都是应该在安装时就设置正确的那类配置;在运行中的集群上更改它们会造成中断,不要随意尝试。其他大多数值,例如资源限制、启用哪些功能、Hubble 配置,都可以之后针对同一个 values 文件通过 helm upgrade 调整,不需要同样程度的谨慎。
热门指南
-
Cilium 如何使用 eBPF:身份、策略与套接字 当一个 Pod 启动、与另一个 Pod 通信,或某个数据包需要策略判定时,内核中究竟发生了什么 —— 以及它为什么快。 -
使用 Cilium 的 Gateway API 支持暴露服务 GatewayClass、Gateway 和 HTTPRoute —— 基于主机名的路由、路径匹配、URL 重写和 TLS,无需单独的 gateway Pod。 -
编写网络策略:从 L3/L4 到 L7 规则 Kubernetes 起初让每个 Pod 都能访问其他所有 Pod —— CiliumNetworkPolicy 就是用来收窄这一点的,必要时甚至可以细到 HTTP 方法。