Istio 是 K8s 上的"服务网格"标准
Istio 是 CNCF 毕业项目,2017 年由 Google + IBM + Lyft 联合开源。它在 K8s Pod 里自动注入 Envoy 边车代理,把服务间通信从应用层下沉到基础设施层,实现:
- 流量管理(灰度、A/B、熔断)
- 安全(mTLS 加密 + RBAC 鉴权)
- 可观测性(指标 / 日志 / 链路追踪)
本文部署 Istio 1.20.2(2024-01 发布的稳定版),并跑通官方 demo。
适用版本:Istio 1.20.2 / K8s 1.28.5
1. 9 个内置 Profile
1
2
| istioctl profile list
# ambient / default / demo / empty / external / minimal / openshift / preview / remote
|
| profile | 包含组件 |
|---|
| default | istiod + istio-ingressgateway(生产推荐) |
| demo | default + istio-egressgateway(demo / 学习用) |
| minimal | 仅 istiod |
| preview | 实验性 |
| ambient | 新的无 sidecar 模式(实验) |
生产用 default,学习用 demo。
2. 安装 Istio
2.1 下载
1
| https://github.com/istio/istio/releases/download/1.20.2/istio-1.20.2-linux-amd64.tar.gz
|
1
2
3
4
5
6
7
8
9
10
| cd /data/softs
tar xf istio-1.20.2-linux-amd64.tar.gz
cd istio-1.20.2
# 目录结构
tree -L 2
# ├── bin/istioctl
# ├── manifests/ # 部署 yaml
# ├── samples/ # 示例应用(bookinfo 等)
# ├── tools/
|
2.2 复制 istioctl
1
2
3
4
5
| cp bin/istioctl /usr/local/bin/
istioctl version
# no ready Istio pods in "istio-system"
# 1.20.2
|
2.3 安装 demo profile
1
2
3
4
5
6
7
8
| istioctl install --set profile=demo -y
# 输出
# ✔ Istio core installed
# ✔ Istiod installed
# ✔ Egress gateways installed
# ✔ Ingress gateways installed
# ✔ Installation complete
|
2.4 给 namespace 打自动注入标签
1
| kubectl label namespace default istio-injection=enabled
|
之后再 default 命名空间下创建的 Pod 都会自动注入 Envoy 边车。
2.5 验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| mkdir -p /data/k8scnf/istio
cd /data/k8scnf/istio
# 用 manifest 验证安装
istioctl manifest generate --set profile=demo > generated-manifest.yaml
istioctl verify-install -f generated-manifest.yaml
# ✔ Istio is installed and verified successfully
kubectl get pods -n istio-system
# NAME READY STATUS RESTARTS AGE
# istio-egressgateway-69b6bdb898-2jh2c 1/1 Running 0 7m
# istio-ingressgateway-778f947c84-wspbb 1/1 Running 0 7m
# istiod-7d4d6677c5-qdvrh 1/1 Running 0 8m
kubectl get crds | grep istio
# 应该有 15 个 CRD(VirtualService、DestinationRule、Gateway 等)
|
3. 部署 bookinfo 示例
bookinfo 是 Istio 官方示例,包含 4 个微服务:
- productpage:入口
- details:书籍详情
- reviews:评论(3 个版本 v1/v2/v3)
- ratings:评分
1
2
3
4
5
6
| mv /data/softs/istio-1.20.2/samples /data/k8scnf/istio/
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
# service/details created
# deployment.apps/details-v1 created
# ...
|
1
2
3
4
5
| kubectl get po
# details-v1-698d88b-w292r 2/2 Running 0 77s
# productpage-v1-675fc69cf-wxs9r 0/2 Init:0/1 0 76s ← 等 envoy sidecar
# ratings-v1-6484c4d9bb-8tg8t 0/2 PodInitializing
# reviews-v1-v3 0/2 PodInitializing
|
注意 2/2 表示 1 个应用容器 + 1 个 envoy 边车。
3.1 验证应用启动
1
2
3
| kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- \
curl -s productpage:9080/productpage | grep -o "<title>.*</title>"
# 输出:<title>Simple Bookstore App</title>
|
3.2 创建 Gateway
1
2
3
| kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
# gateway.networking.istio.io/bookinfo-gateway created
# virtualservice.networking.istio.io/bookinfo created
|
1
2
| istioctl analyze
# 可能会警告:default 命名空间下某些 Pod 没注入 envoy,忽略(测试 Pod)
|
3.3 访问入口
1
2
3
| kubectl -n istio-system get svc istio-ingressgateway
# NAME TYPE PORT(S)
# istio-ingressgateway LoadBalancer 80:31824/TCP,443:32488/TCP
|
31824 是 NodePort,从任意 master 节点:
1
2
| # 通过 VIP 访问
http://<vip-internal>:31824/productpage
|
浏览器能看到 bookinfo 应用,刷新几次页面会看到 reviews 三个版本(v1 无评分 / v2 黑色星 / v3 红色星)的随机切换。
4. 安装 Dashboard
K8s 上的 Istio Dashboard 包含 4 个组件:
- Kiali:服务网格拓扑
- Grafana:监控面板
- Prometheus:指标采集
- Jaeger(或 Zipkin):链路追踪
1
2
3
4
5
| kubectl apply -f samples/addons
# 一次性 apply grafana / jaeger / kiali / prometheus
kubectl rollout status deployment/kiali -n istio-system
# deployment "kiali" successfully rolled out
|
4.1 Kiali 面板
1
2
| istioctl dashboard kiali
# http://localhost:20001/kiali
|
外网访问需要改 NodePort:
1
2
3
4
5
6
7
8
| kubectl -n istio-system patch svc kiali -p '{"spec":{"type":"NodePort"}}'
kubectl -n istio-system get svc kiali
# NAME TYPE PORT(S)
# kiali NodePort 20001:32171/TCP
# 浏览器
http://<vip-internal>:32171/kiali
|
Kiali 主页能看到:
- Graph:服务间调用拓扑(不同颜色表示 2xx/3xx/4xx/5xx)
- Applications:应用列表
- Services:服务列表
- Workloads:工作负载(Deployment)列表
4.2 Grafana 面板
1
2
3
4
| kubectl -n istio-system patch svc grafana -p '{"spec":{"type":"NodePort"}}'
# 默认 admin/admin
http://<vip-internal>:31693
|
4.3 触发流量看面板
1
2
3
4
| clusterIP=$(kubectl -n istio-system get svc istio-ingressgateway -ojsonpath='{.spec.clusterIP}')
for i in $(seq 1 100); do
curl -s -o /dev/null "http://$clusterIP:80/productpage"
done
|
Kiali 的 Graph 立即能看到 productpage → details / reviews / ratings 的调用关系,每个箭头带成功率 / 响应时间。
5. 灰度发布:把 reviews 全部切到 v3
默认 bookinfo 的 reviews 3 个版本随机分配(50% v1, 33% v2, 17% v3)。
把流量全部切到 v3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| # samples/bookinfo/networking/virtual-service-reviews-v3.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
|
1
| kubectl apply -f virtual-service-reviews-v3.yaml
|
刷新页面 → 全部红色星(v3)。
5.1 按用户灰度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
|
用户 jason 走 v2,其他用户走 v1。
6. 常见问题
6.1 unable to proxy Istiod pods. Make sure your Kubernetes API server has access to the Istio control plane through 8080 port
istioctl dashboard 依赖 socat 端口转发:
6.2 grafana URL is not set in Kiali configuration
Kiali 找不到 Grafana 入口:
1
| kubectl -n istio-system edit cm/kiali
|
1
2
3
4
5
6
7
| external_services:
grafana:
url: "http://grafana.istio-system:3000"
custom_dashboards:
enabled: true
istio:
root_namespace: istio-system
|
1
2
| # 删 pod 让它重建
kubectl delete po -n istio-system kiali-545878ddbb-shkkn
|
6.3 loki-0 1/2 CrashLoopBackOff
Loki 容器初始化权限不够。加 initContainer:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| initContainers:
- name: fix-permissions
image: busybox:latest
securityContext:
privileged: true
runAsGroup: 0
runAsNonRoot: false
runAsUser: 0
command:
- sh
- -c
- >-
id;
mkdir -p /data/loki;
chown 10001:10001 /data -R;
ls -la /data/
volumeMounts:
- mountPath: /data
name: storage
|
6.4 Pod 没自动注入 envoy
确认 namespace 有 istio-injection=enabled 标签:
1
2
3
4
5
6
7
| kubectl get ns -L istio-injection
# 给 namespace 加
kubectl label namespace <name> istio-injection=enabled
# 已经创建的 Pod 要重启才会注入
kubectl rollout restart deployment <name> -n <ns>
|
6.5 卸载
1
2
3
4
| kubectl delete -f samples/addons
istioctl uninstall -y --purge
kubectl delete namespace istio-system
kubectl label namespace default istio-injection-
|
7. 小结
Istio 让 K8s 集群具备了"微服务治理"能力:
- demo profile 是学习首选(包含所有组件)
- 生产用 default profile(仅核心)
- Kiali / Grafana 是 Istio 可观测性的灵魂
- VirtualService + DestinationRule 是灰度发布 / 流量切分的核心
- sidecar 自动注入 需要 namespace 标签
下一步:Loki + Promtail 日志体系:helm 部署 + yaml 自定义。