Featured image of post Istio 1.20 服务网格:bookinfo + Kiali/Grafana 面板

Istio 1.20 服务网格:bookinfo + Kiali/Grafana 面板

Istio 1.20.2 demo profile 部署、bookinfo 示例应用、Kiali/Grafana/Jaeger 可视化、常见故障

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包含组件
defaultistiod + istio-ingressgateway(生产推荐)
demodefault + 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 端口转发:

1
apt install socat -y

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 集群具备了"微服务治理"能力:

  1. demo profile 是学习首选(包含所有组件)
  2. 生产用 default profile(仅核心)
  3. Kiali / Grafana 是 Istio 可观测性的灵魂
  4. VirtualService + DestinationRule 是灰度发布 / 流量切分的核心
  5. sidecar 自动注入 需要 namespace 标签

下一步:Loki + Promtail 日志体系:helm 部署 + yaml 自定义

使用 Hugo 构建
主题 StackJimmy 设计