用 IstioOperator 定制安装,用 revision 升级
一句话总结
Istio 安装用一份名为 IstioOperator 的文档来表达,profile 是这份文档的默认值集合,MeshConfig 则是适用于整个网格的配置。升级默认采用把 revision 并排部署的 canary 方式,原地升级风险更高,所以附带了不少条件。
为什么需要它
只要 istioctl install 一行命令就能让 Istio 跑起来,看上去就大功告成了。但在生产环境中,很快就会有“要开访问日志”“要加 egress gateway”“要把外部目的地改成默认阻断”之类的需求。这时如果一个个加 --set 标志,就没人记得改过什么。Istio 文档指出,--set 和 -f 的作用相同,但在生产环境中强烈推荐用 -f 传文件的方式。因为安装状态必须留在一个文件里,升级时才能再次使用同一个文件。
升级同理。在原地替换控制平面的原地升级方式,会让所有 sidecar 一次性改看新的 istiod,出了问题整个网格都会受影响。所以 Istio 推荐在旁边再部署一个新的控制平面,按命名空间逐步迁移的 canary 方式。ICA 考试的 Install/Upgrade/Config 领域(20%)问的正是这两点:用什么来定制安装以及何时选择两种升级方式。
工作原理
IstioOperator——不会应用到集群的配置文档
传给 istioctl install -f 的文件是 install.istio.io/v1alpha1 的 IstioOperator 资源。官方参考文档把这个资源说明为“格式类似 Kubernetes 对象,但并不会应用到集群,而是 istioctl 的文件输入”。也就是说,它不是用 kubectl apply 提交的,而是 istioctl 读取后生成清单的原料。
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
profile: default # 기본값 묶음. 비우면 default
revision: 1-31-0 # canary 업그레이드용 식별자. '.' 은 쓸 수 없다
meshConfig: # 메시 전체 설정
accessLogFile: /dev/stdout
outboundTrafficPolicy:
mode: REGISTRY_ONLY
components: # 어떤 구성요소를 켜고 끌지, k8s 리소스 설정
egressGateways:
- name: istio-egressgateway
enabled: true
values: {} # Helm values 로 바로 넘기는 통로(검증됨)
该代码块中的韩文注释依次说明:profile 是默认值的集合,留空则为 default;revision 是 canary 升级用的标识符,其中不能使用点号;meshConfig 是网格整体配置;components 决定启用或关闭哪些组件以及 Kubernetes 资源设置;values 是直接传给 Helm values 的通道(已验证)。
spec 的主要字段有 profile、hub/tag(镜像位置)、revision、meshConfig、components(base、pilot、cni、ztunnel、istiodRemote、ingressGateways、egressGateways)、values。文档说明,values 是经过验证的、传给 Helm 模板的通道,IstioOperatorSpec 中已有的项目,应当写在上层字段里,而不是 values 中。要把旧的 Helm values 路径作为 --set 使用,需要加上 values. 前缀。
profile——带名称的 Helm values 集合
profile 是内置于 Helm Chart 中的带名称的 values 覆盖集合。所以 helm 和 istioctl 两边可以用同样的名称。部署 profile 如下。
| profile | 用途 | istioctl 同时安装的组件 |
|---|---|---|
| default | 推荐用于生产环境与多集群 primary | istiod, istio-ingressgateway |
| demo | 功能演示用。把跟踪、访问日志开得很高,不适合性能测试 | istiod, ingress, egress gateway |
| minimal | 与 default 相同,但只有控制平面 | istiod |
| ambient | ambient 模式入门用 | istiod, CNI, ztunnel |
| remote / empty / preview | 用于外部控制平面 / 什么都不安装的底板 / 实验功能 | — |
这里有一个考试爱考的区别。istioctl 的 profile 还包含要安装哪些组件的列表,而 Helm 的 profile 只是一组值,所以每个组件都要用 helm install 逐个部署。并且,像 --set profile=default --set values.global.platform=gke 这样,把平台 profile(gke、eks、openshift、k3s 等)与部署 profile 一起传入,是被推荐的做法。
MeshConfig——适用于整个网格的值
meshConfig 是“网格整体配置”。accessLogFile 为空时关闭访问日志,给出 /dev/stdout 则开启。accessLogEncoding 默认为 TEXT,可以改为 JSON。outboundTrafficPolicy 的默认值是 ALLOW_ANY,所以未注册的外部目的地也可以访问。enableTracing 会开启 span 生成,但代理配置中必须有收集器。有一个例外是 defaultConfig(ProxyConfig)。文档写道,这个值在 sidecar 注入时只应用一次,在 Pod 存活期间不会改变,其余的 MeshConfig 则在运行中也会动态下发。所以修改代理配置后如果没有生效,就要重启 Pod。
istioctl 与 Helm 安装路径的区别
Helm 安装要按顺序部署三个 Chart:包含集群范围 CRD 的 base、部署 istiod 的 istiod,以及可选的 gateway。做 revision 安装时,必须给 base Chart 传 --set defaultRevision=<revision>,资源验证 Webhook 才会工作。用 Helm 卸载后 CRD 也会保留,这是有意的设计。因为删除 CRD 会连带删除 VirtualService、DestinationRule 这类用户资源。把 istioctl 安装的环境交给 Helm 时,可以用 --take-ownership 接管已有资源。文档明确指出,Helm 指南中的 Chart 与 istioctl 使用的 Chart 相同,只有 gateway Chart 不同。
canary 升级——并排部署 revision
像 istioctl install --set revision=1-31-0 这样给出 revision,istiod Deployment、Service 和 sidecar 注入 Webhook 就会带着 revision 名称再多出一套。已有的 sidecar 不受任何影响。要迁移工作负载,就删除命名空间的 istio-injection=enabled 标签,加上 istio.io/rev=<revision>,然后重启 Pod。istio-injection 标签为了向下兼容优先于 istio.io/rev,所以必须删除。
与其逐个命名空间去改标签,不如使用 revision tag。用 istioctl tag set prod-stable --revision 1-30-1 创建 tag,并给命名空间加上 istio.io/rev=prod-stable,之后只需一次 istioctl tag set prod-stable --revision 1-31-0 --overwrite,使用该 tag 的所有命名空间就都会迁移到新的 revision。default tag 比较特殊,负责 istio-injection=enabled 注入、资源验证、leader 锁。验证结束后,用 istioctl uninstall --revision 1-30-1 删除旧的控制平面。revision 方式支持跨越两个次版本(1.15 → 1.17)。
原地升级——条件很多
istioctl upgrade 会原地替换控制平面和 gateway。文档写明的条件如下:已安装的版本只能比新版本低不超过一个次版本;不能用于以 --revision 安装的环境;并且如果不原样传入安装时使用的 -f 文件或 --set 值,定制配置会回到默认值。结束后,必须用 kubectl rollout restart deployment 亲自重启数据平面。为了减少中断,建议部署两个以上的 istiod,并把 PodDisruptionBudget 的最小可用设为 1。
在现场相遇的样子
曾有一个团队,把用五个 --set 安装的网格用 istioctl upgrade 升级后,访问日志消失了,outboundTrafficPolicy 也回到了 ALLOW_ANY。原因是升级命令里没有传入同样的 --set,找原因花了一整天。如果把 IstioOperator 文件放在仓库里,安装和升级都用 -f 传入同一个文件,这种事就不会发生。
另一件事发生在回退 canary 时。在 default profile 中,gateway 不会按 revision 单独运行,而是原地升级到新的 revision。所以把 canary revision 删掉,gateway 也不会指向旧的控制平面。文档写道,在删除 canary 之前,要先用旧的 istioctl 重新安装 gateway,并确认其正常运行。顺序一旦颠倒,ingress 就会中断。
下一项测验要确认什么
测验会问:各个 profile 下 istioctl 安装的组件,只有 defaultConfig 需要重启的原因,istio-injection 与 istio.io/rev 的优先级,移动 revision tag 的命令,以及原地升级失败或丢失配置的条件。参考:Install with Istioctl、Installation Configuration Profiles、Canary Upgrades、In-place Upgrades、Install with Helm。