istioctl install 是当前 Istio 官方唯一主推的安装方式,支持自动处理 CRD、RBAC、证书签发与配置校验;Helm 自 1.16 起已弃用,强行使用易导致 istiod 启动失败或证书异常。

直接用 istioctl 安装是最可控、最贴近生产环境的方式;helm 安装虽可行,但自 Istio 1.16 起官方已弃用 Helm chart,后续版本不再维护,强行使用容易卡在 istiod 启动失败或证书签发异常上。
用 istioctl install 部署 istiod 控制面
这是当前唯一被 Istio 官方主推的安装路径,能自动处理 CRD、RBAC、证书签发和默认配置校验。
- 下载并解压对应版本(如 1.20.4):
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.20.4 sh - - 把
istioctl加入 PATH:export PATH=$PWD/istio-1.20.4/bin:$PATH - 执行安装(推荐 demo 配置起步):
istioctl install --set profile=demo -y - 验证控制面 Pod 状态:
kubectl get pods -n istio-system,重点关注istiod是否为Running,且无 CrashLoopBackOff
注意:若集群未启用 ServiceAccount token 自动挂载(如旧版 kubeadm 集群),istiod 会因无法访问 kube-apiserver 而反复重启——需手动 patch:kubectl patch serviceaccount -n istio-system istiod -p '{"automountServiceAccountToken": true}'
启用命名空间自动注入 sidecar
sidecar 注入不是“开个开关就完事”,它依赖两个条件同时满足:命名空间打了 label,且该命名空间下 Pod 的 template 没显式禁用 injection。
- 打 label(以
default为例):kubectl label namespace default istio-injection=enabled - 确认 label 已生效:
kubectl get namespace default -o yaml | grep istio-injection,输出应为istio-injection: enabled - 部署应用后检查 Pod 是否含两个容器:
kubectl get pod xxx -o jsonpath='{.spec.containers[*].name}',正常应看到类似app envoy
常见坑:Deployment 中若设置了 template.spec.containers[0].env 但没写全字段(比如漏了 valueFrom),会导致 webhook 注入失败且不报错,Pod 卡在 Pending;此时查 kubectl describe pod 可见 warning:FailedCreatePodSandBox 或 injector.istio.io failed
评估 Kubernetes 集群安全态势,覆盖 RBAC、工作负载安全、网络策略、基础设施即代码(IaC)、运行时监控和密钥管理等 30 项控制项……
暴露服务:istio-ingressgateway 不是 Ingress 资源
istio-ingressgateway 是一个 Deployment + Service 类型的网关实例,和 Kubernetes 原生 Ingress 资源完全无关。它不解析 ingress.networking.k8s.io 对象,只响应 Gateway 和 VirtualService。
- 确认网关 Pod 运行:
kubectl get pods -n istio-system -l app=istio-ingressgateway - 获取入口地址(NodePort 场景):
kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}' - 必须配套定义
Gateway(绑定端口/协议)和VirtualService(路由规则),否则流量进不来;单独改 Service 类型为NodePort或LoadBalancer只是开放了端口,没定义任何路由逻辑
典型错误:把 VirtualService 的 host 写成 example.com,但没配 DNS 或 Hosts,浏览器直连 IP 就 404;正确做法是先用 curl -H "Host: example.com" http://$INGRESS_HOST:$INGRESS_PORT 测试
验证流量是否真经过 Envoy
光看 Pod 有两个容器、网关 Pod Running,并不能证明流量进了数据面——得看 Envoy 是否实际劫持了连接。
- 进 Pod exec:
kubectl exec -it deploy/productpage -c productpage -- sh - 查本地监听端口:
netstat -tlnp | grep :9080,正常只显示productpage进程监听;Envoy 在 15090(健康检查)、15021(sidecar 自检)等端口监听,但业务端口由 Envoy 接管,应用进程并不直接 bind - 更直接的方式:查 Envoy 访问日志:
kubectl logs -n istio-system -l app=istio-ingressgateway -c istio-proxy | tail -5,有 access log 行说明外部请求已进入数据面
最容易被忽略的一点:如果应用容器用了 hostNetwork: true 或 networkPolicy 显式放行了非 15090/15021 端口的流量,Envoy 的 iptables 规则可能被绕过,导致 sidecar 形同虚设

















