Istio 作为一款强大的服务网格工具,能有效管理微服务间的通信,提供流量管理、安全加固和可观测性等功能。Bookinfo 示例应用是学习和体验 Istio 核心功能的经典案例。下面我会为你介绍 Istio 的安装部署、Bookinfo 应用的部署演示,以及一些基本操作。

🛠️ Istio 安装部署与 Bookinfo 应用演示

基于之前的博客K8S集群部署(国内网络)的环境中实践的

🔍 Istio 与 Bookinfo 应用简介

Istio 是一个开源的服务网格(Service Mesh),它为微服务架构提供通信基础。通过侧边车模式(Sidecar) 将 Envoy 代理注入到每个微服务 Pod 中,Istio 实现了对服务间通信的精细控制,且对应用代码透明。其核心功能包括流量管理(如金丝雀发布、故障注入)、安全(如双向 TLS、认证授权)和可观测性(如监控、追踪、日志)。

Bookinfo 应用 是一个由四个独立微服务组成的示例应用,用于模拟在线书店的一个图书条目:

  • productpage:调用 details 和 reviews 服务生成页面。
  • details:提供书籍的基本信息。
  • reviews:提供书籍的评论信息,会调用 ratings 服务。它有三个版本:
    • v1:不调用 ratings 服务。
    • v2:调用 ratings 服务,并使用 1 到 5 个黑色星形图标显示评分。
    • v3:调用 ratings 服务,并使用 1 到 5 个红色星形图标显示评分。
  • ratings:提供评分数据。

📦 Istio 安装部署

Istio 的安装有多种方式,以下是基于 istioctl 的常用方法,适用于快速学习和测试:

前提条件

  • 一个正常运行 Kubernetes 集群(比如我的k8sV1.28版本)。
  • 配置好 kubectl 命令行工具,确保其可管理目标集群。

安装步骤

  1. 下载 Istio
    从 Istio 官网下载最新版本或指定版本的发行包,并解压。
    curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.20.7 TARGET_ARCH=x86_64 sh -
    cd istio-1.20.7
    export PATH=$PWD/bin:$PATH
    
    这一步因为网络原因会失败(除非你科学上网并且开启允许局域网连接然后再虚拟机内部指定代理)
    这里我建议自己提前下载好包 上传到虚拟机。至于为什么选择1.20.7是因为我的k8s1.28兼容性的问题,详情参考istio官网
    这里放张图片
    在这里插入图片描述

选择开始使用sidecar模式(基础的)

在这里插入图片描述

然后点击istio发布页 会跳转到github 选择下载的版本即可

在这里插入图片描述

这网站有时候不科学上网也能打开 看运气 不稳定

在这里插入图片描述

  1. 安装 Istio 到集群
    使用默认配置文件安装,它包含了 Istio 的基础核心组件istiod和istio-ingressgateway,适合演示和学习。
    istioctl install 
    
    。通过 istioctl install 命令不显式指定任何配置参数(如 --set profile=...)时,安装的是 default 配置文件

📊 Istio 内置配置 Profiles 对比

为了让你更清楚地了解 default 和其他配置文件的区别,下表列出了 Istio 主要内置配置文件的特点:

配置文件 (Profile) 核心特点 包含的常见组件 适用场景
default 生产环境的推荐起点,启用了核心功能。资源消耗适中,平衡了功能与资源占用。 Istiod, Ingress Gateway 生产环境、多集群 Mesh 中的主集群
demo 旨在展示 Istio 的所有功能。资源消耗较高 Istiod, Ingress Gateway, Egress Gateway, 可观测性组件 评估和学习 Istio(如运行 Bookinfo)
minimal 只安装控制平面组件(Istiod)。 Istiod 需要高度自定义数据平面(如 Gateway)的场景
empty 不部署任何组件 作为完全自定义配置的起点
preview 包含实验性功能,不保证稳定性、安全性和性能。 包含当前处于预览阶段的组件和功能 探索 Istio 的新特性

🔍 验证当前安装的配置

要确认你当前集群中安装的 Istio 使用了哪些组件,可以检查 istio-system 命名空间中的 Pod:

kubectl get pods -n istio-system

如果是通过 default profile 安装,你通常会看到以下核心组件:

  • istiod-*:Istio 的核心控制平面,整合了 Pilot、Citadel、Galley 的功能。
  • istio-ingressgateway-*:处理入站流量的网关。

💡 如何更改配置 Profile

如果你希望安装其他配置 Profile(例如功能更全面的 demo),可以使用 istioctl install 命令并指定 profile:

# 安装 demo profile(包含所有组件,适用于演示和测试)
istioctl install --set profile=demo

# 安装 minimal profile(仅安装控制平面组件Istiod)
istioctl install --set profile=minimal

请注意:在已安装 Istio 的集群上再次运行 istioctl install 会尝试根据新的配置更新现有的安装。生产环境中操作前请务必谨慎评估

🤔 选择建议

  • 对于生产环境,通常从 default profile 开始,然后根据实际需求进行自定义增量安装。
  • 对于只是想快速体验和测试 Istio 的全部功能,demo profile 更合适,但要注意其资源消耗较高。
  • 如果你需要完全控制组件的部署和配置,例如使用单独的 Gateway,minimalempty profile 可能是不错的起点。

希望这些信息能帮你更好地理解 Istio 的配置!

  1. 验证控制平面安装
    检查 istio-system 命名空间中的 Pod 是否全部运行成功。
    kubectl get pods -n istio-system
    
    在这里插入图片描述

这一步如果pod起不来大概率是网络问题拉不到镜像 上面说了我们使用的是默认的default配置找到自己的安装目录
在这里插入图片描述

修改default.yaml文件 (记得先备份)中的镜像image地址 (自己寻找可用的国内镜像地址)
配置文件中,proxyv2pilot 镜像的用途及对应组件如下:


1. 镜像作用说明

镜像名称 对应组件 功能说明
proxyv2 数据平面(Data Plane) 包含 Envoy 代理,用于 Sidecar(Pod 容器)和 Ingress/Egress Gateway
- 处理微服务间的流量(路由、负载均衡、安全等)
- 通过 values.global.proxy.image 配置
pilot 控制平面(Control Plane) Istiod 的核心组件(原名为 Pilot)
- 负责服务发现、配置分发(XDS API)
- 通过 components.pilot.image 配置

2. 组件与镜像的对应关系

组件 使用的镜像 配置位置
istiod pilot spec.components.pilot.image
istio-ingressgateway proxyv2 values.global.proxy.image

关键配置解析

(1) istiod 使用 pilot 镜像
components:
  pilot:
    enabled: true
    image: pilot  # istiod 使用此镜像
(2) istio-ingressgateway 使用 proxyv2 镜像
values:
  global:
    proxy:
      image: proxyv2  # Gateway 使用此镜像
(3) Sidecar 代理同样使用 proxyv2

所有注入到业务 Pod 的 Sidecar(如 Bookinfo 的 productpage、reviews 等)均使用 proxyv2 镜像:

values:
  global:
    proxy:
      image: proxyv2  # Sidecar 使用此镜像

镜像拉取地址

镜像的完整路径由 spec.hub + spec.tag + 镜像名 构成:

  • istiod 镜像docker.io/istio/pilot:1.20.7
  • istio-ingressgateway 和 Sidecar 镜像docker.io/istio/proxyv2:1.20.7

总结

组件 镜像名称 完整镜像地址
istiod pilot docker.io/istio/pilot:1.20.7
istio-ingressgateway proxyv2 docker.io/istio/proxyv2:1.20.7
Sidecar 代理 proxyv2 docker.io/istio/proxyv2:1.20.7

💡 提示:所有组件共用同一个版本标签 (1.20.7),确保兼容性。若需升级 Istio,需同时更新 spec.tag

  1. 启用自动 Sidecar 注入
    为计划部署应用的命名空间(例如 istio)添加标签,以便 Istio 自动注入 Envoy Sidecar 代理。
    kubectl label namespace istio istio-injection=enabled
    

🚀 Bookinfo 应用部署与演示

部署 Bookinfo 应用(同样需要修改配置文件中的image地址)

以我的1.20.7版本istioctl来说 为你整理了 Bookinfo 应用各服务的国内镜像地址表格。

📦 Bookinfo 应用国内镜像地址参考

服务名称 (Service) 版本 国内镜像地址示例 (华为云 SWR)
details v1 swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/istio/examples-bookinfo-details-v1:1.18.0
ratings v1 swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/istio/examples-bookinfo-ratings-v1:1.18.0
reviews v1 swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/istio/examples-bookinfo-reviews-v1:1.18.0
reviews v2 swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/istio/examples-bookinfo-reviews-v2:1.18.0 (需替换版本号)
reviews v3 swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/istio/examples-bookinfo-reviews-v3:1.18.0 (需替换版本号)
productpage v1 swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/istio/examples-bookinfo-productpage-v1:1.18.0 (需替换版本号)

⚠️ 重要提示

  1. 版本一致性:部署时,务必确保所有服务的镜像版本相互兼容。混合使用不兼容的版本(如 details-v1:1.18.0 搭配 reviews-v2:1.16.2)可能导致应用运行异常。

  2. 修改 YAML:获取有效镜像地址后,你需要修改 bookinfo.yaml 文件(通常位于 samples/bookinfo/platform/kube/ 目录下),将每个 Deployment 中 spec.template.spec.containers[*].image 字段的值替换为对应的国内镜像地址。

希望这份表格能帮助你顺利完成部署。

  1. 部署应用
    使用 kubectl 部署 Bookinfo 应用的所有服务。由于已启用自动 Sidecar 注入,每个 Pod 将自动包含一个 Envoy 代理容器。
    kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n istio
    
    需要在正确的目录执行也就是你的安装目录(注意目录层级)
    在这里插入图片描述
  2. 验证应用部署
    检查 Bookinfo 的 Pod 和 Service 是否创建成功并运行。每个 Pod 应显示为 2/2 Ready,表示应用容器和 Sidecar 代理均已就绪。
    kubectl get pods
    kubectl get services
    

这里我操作完检查发现pod起不来

在这里插入图片描述
查看容器内部日志
在这里插入图片描述
istio-init 容器因 iptables 的 nat 表初始化问题而失败。这通常与系统底层的内核模块支持或权限有关。

🔍 问题根源

istio-init 容器的主要任务,是在你的应用容器(如 details)和 Sidecar 容器(如 istio-proxy)启动之前,通过 iptables-restore 命令设置好一系列的 iptables 规则。这些规则的核心作用是拦截并转发进出 Pod 的网络流量,使其经过 Sidecar 代理(Envoy),从而实现服务网格的各项功能。

从你提供的日志看,错误 xtables parameter problem: iptables-restore: unable to initialize table 'nat' 发生在规则注入的最开始阶段,这意味着 nat 表本身无法被初始化,后续的所有规则都无法添加。

⚙️ 解决方案

下面是每个步骤的具体操作命令和说明:

1. 检查并加载内核模块

nat 表功能依赖于 Linux 内核的一系列模块。首先需要检查这些模块是否已加载。

  • 检查相关模块状态:在 Pod 所在节点上执行:

    sudo lsmod | grep -E 'nf_nat|nf_conntrack|xt_MASQUERADE|iptable_nat|iptable_filter'
    

    如果输出为空或缺少某些模块,你需要手动加载它们。

  • 加载缺失的模块:通常需要加载 iptable_nat 及其依赖模块:

    sudo modprobe -v nf_conntrack
    sudo modprobe -v iptable_nat
    sudo modprobe -v nf_nat
    sudo modprobe -v xt_MASQUERADE
    

    注意iptable_nat 模块依赖于 nf_natnf_conntrack 等模块。modprobe 命令会自动处理依赖关系,但明确列出有助于理解。

  • 确保模块持久化:为了避免重启后模块失效,将需要加载的模块添加到持久化配置中:

    echo 'nf_conntrack' | sudo tee -a /etc/modules-load.d/99-istio-modules.conf
    echo 'iptable_nat' | sudo tee -a /etc/modules-load.d/99-istio-modules.conf
    echo 'nf_nat' | sudo tee -a /etc/modules-load.d/99-istio-modules.conf
    echo 'xt_MASQUERADE' | sudo tee -a /etc/modules-load.d/99-istio-modules.conf
    

    中提到了类似的方法,但模块列表可能更全面,请根据你的系统情况进行调整。

2. 删除失败的 Pod

无论你采取了哪种修复措施,最后通常都需要删除当前失败的 Pod,让 Kubernetes 重建一个新的。重建过程会重新尝试初始化容器。(以自己实际的pod名替换)

kubectl delete pod details-v1-698d88b-9w6x5 -n istio

💎 总结与建议

istio-init 启动失败问题,核心是 nat 表所需的底层内核模块未正确加载

  1. 首先尝试在问题 Pod 所在的节点上检查并加载必要的内核模块(如 iptable_nat, nf_nat),并确保配置持久化。

  2. 同时,强烈建议检查并考虑启用 Istio CNI 插件。这不仅能解决当前的权限和模块加载问题,也是 Istio 更推荐的生产环境部署方式,因为它更安全、更可靠。

  3. 完成上述操作后,删除失败的 Pod 让其自动重建

    您也可以通过从集群内部发送请求来测试应用是否正常工作:

    kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
    

配置外部访问

默认情况下,Bookinfo 应用只能在集群内部访问。要提供外部访问,需要配置 Istio Ingress Gateway。

  1. 应用 Gateway 配置
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -n istio
    
    这条命令会创建gateway和virtualservice资源 ,Istio 通常通过 ​IstioOperator​ 自定义资源(CR)或 ​Helm Values​ 文件来定义其组件的部署参数,包括 istio-ingressgateway的服务类型。
    在这里插入图片描述
    默认的配置中service类型是LoadBalancer 我们本地集群需要修改为nodeport 你可以通过
    kubectl get iop -A kubectl describe iop installed-state -n istio-system 查看该资源对于ingressgateway的定义。

在这里插入图片描述
如果不修改 istio-ingressgateway 服务的 EXTERNAL-IP 处于 <pending> 状态。这是因为在你的本地或裸金属 Kubernetes 环境(没有云提供商)中,无法自动分配外部负载均衡器

为了能让外部流量访问到你的 Istio 服务,建议你将 istio-ingressgateway 的类型从 LoadBalancer 修改为 NodePort。这样你就可以通过集群中任何节点的 IP 地址和分配的 NodePort 端口来访问服务了。

以下是修改的步骤和后续操作:

🔧 修改为 NodePort 及访问方法

  1. 修改 Service 类型:使用 kubectl patch 命令将 istio-ingressgateway 的服务类型修改为 NodePort

    kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec":{"type":"NodePort"}}'
    
  2. 查看新的 NodePort 端口:修改完成后,再次查看服务,你会发现类型已变为 NodePort,并分配了新的 NodePort 端口(通常在 30000-32767 范围内)。

    kubectl get svc istio-ingressgateway -n istio-system
    
[root@master kube]# kubectl get svc istio-ingressgateway -n istio-system
NAME                   TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
istio-ingressgateway   NodePort   10.101.158.87   <none>        15021:31307/TCP,80:31544/TCP,443:32352/TCP   2d

`istio-ingressgateway` 服务原来映射的端口是 `80:31544/TCP,443:32352/TCP`。修改为 NodePort 后,**`80` 端口可能会映射到一个新的随机端口**(例如 `31544`),**`443` 端口也类似**(例如 `32352`)。请以命令实际输出为准。
  1. 确定访问地址:获取到 NodePort 后,你可以通过以下方式访问:
    • 通过任意节点 IP:使用集群中任意节点的 IP 地址加上上述的 NodePort 端口(例如 31544)来访问。
    • 获取并设置环境变量(更方便):你可以使用以下命令获取 HTTP 端口和网关所在的节点 IP,并设置为环境变量:
      export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
      export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
      export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
      echo "访问地址: http://$INGRESS_HOST:$INGRESS_PORT"
      echo "安全访问地址: https://$INGRESS_HOST:$SECURE_INGRESS_PORT"
      
      之后就可以通过 http://$INGRESS_HOST:$INGRESS_PORT/productpage 来访问 Bookinfo 应用了。

在这里插入图片描述

📊 LoadBalancer 与 NodePort 对比

特性 LoadBalancer NodePort
适用环境 公有云(如 AWS, GCP, Azure) 本地环境、裸金属、私有云
外部IP 自动分配 使用节点IP
端口 通常映射到80/443 分配30000-32767范围的高端口
配置复杂度 简单(云平台自动集成) 需手动配置或获取端口
成本 可能产生费用 无额外费用

⚠️ 注意事项

  • 端口冲突:如果你的环境有严格的安全策略或端口限制,请确保分配的 NodePort 是可访问的。
  • 生产环境考虑:对于生产环境,如果处于不支持外部负载均衡器的环境中,除了使用 NodePort,还可以考虑集成 MetalLB 这样的工具来提供负载均衡器功能,或者使用 Ingress Controller(例如 Nginx Ingress)来代理 Istio Ingress Gateway。
  • 持久化配置:当前通过 kubectl patch 的修改是临时的。如果你希望永久性地将 Istio Ingress Gateway 配置为 NodePort 类型,建议在 Helm values 配置文件或 IstioOperator 自定义资源(取决于你的安装方式)中进行设置并重新部署。

💎 总结

对于你的当前环境,istio-ingressgateway 服务类型修改为 NodePort 是必要且实用的。这样你就能通过节点的 IP 和端口顺利访问部署在 Istio 中的服务(如 Bookinfo)了。

修改后,如果之前已经按照 Bookinfo 示例配置了 Gateway 和 VirtualService,现在就可以使用上述方法确定的 INGRESS_HOSTINGRESS_PORT 来访问 productpage 了。

希望这些说明能帮助你顺利解决问题!

  1. 设置访问网关的地址和端口
    根据您的 Kubernetes 环境设置访问网关的地址 (INGRESS_HOST) 和端口 (INGRESS_PORT)。如果您在 Minikube 或没有外部负载均衡器的环境中,命令通常如下:

    export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
    export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
    export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
    echo "http://$GATEWAY_URL/productpage"
    
  2. 通过浏览器访问应用
    将上述命令输出的 URL(如 http://192.168.49.2:32194/productpage)粘贴到浏览器中即可访问 Bookinfo 应用。多次刷新页面,会看到** reviews 部分在不同版本(无星、黑星、红星)间随机切换**,这是因为此时还没有配置任何路由规则。

应用默认目标规则

在使用 Istio 控制流量路由之前,需要定义目标规则(Destination Rule)来指定可用的服务版本(子集)。

kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

🧪 体验 Istio 功能

1. 流量管理:按版本路由

所有流量路由到 v1 版本

kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

应用此配置后,无论刷新多少次页面,reviews 服务将始终显示 v1 版本的内容(无评分星级)。

基于用户身份的路由

kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml

此规则规定,如果请求头中包含 end-user: jason,则流量路由到 reviews v2;否则路由到 v1。登录后以 “jason” 用户身份访问,即可看到黑色星级。

流量镜像(金丝雀发布)
您还可以配置流量百分比,例如将 70% 的流量分配到 v1,30% 的流量分配到 v3,实现金丝雀发布。

2. 安全加固:启用双向 TLS (mTLS)

您可以在特定命名空间或整个网格中启用严格的双向 TLS 加密,确保服务间通信的安全。

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: default
spec:
  mtls:
    mode: STRICT

应用此 PeerAuthentication 策略后,default 命名空间中的所有服务间的通信将被加密。

3. 可观测性:查看监控仪表板

Istio 集成了多种遥测工具,如 Kiali(服务拓扑)、Prometheus(指标收集)、Grafana(指标可视化)和 Jaeger(分布式追踪)。

部署插件

kubectl apply -f samples/addons
kubectl rollout status deployment/kiali -n istio-system # 等待Kiali就绪

访问 Kiali 仪表板
使用端口转发临时访问 Kiali:

kubectl port-forward -n istio-system svc/kiali 20001:20001

然后在浏览器中访问 http://localhost:20001。为了生成监控数据,您可以运行以下命令向应用发送大量请求:

for i in {1..100}; do curl -s -o /dev/null "http://$GATEWAY_URL/productpage"; done

随后在 Kiali 中即可观察到服务的拓扑图、流量流向等可视化信息。

📋 常用命令一览

功能说明 命令 参考
验证 Istio 安装 istioctl verify-install
查看已安装的 Istio 组件 kubectl get pods -n istio-system
启用自动 sidecar 注入 kubectl label namespace <命名空间> istio-injection=enabled
手动注入 sidecar 并部署 kubectl apply -f <(istioctl kube-inject -f <您的应用yaml文件>)
查看 VirtualService kubectl get virtualservices
查看 DestinationRule kubectl get destinationrules
卸载 Bookinfo 应用 samples/bookinfo/platform/kube/cleanup.sh
完全卸载 Istio istioctl uninstall -y --purge

🧹 清理环境

完成实验后,如需释放资源,可按顺序清理:

  1. 删除 Bookinfo 应用

    samples/bookinfo/platform/kube/cleanup.sh
    
  2. 删除 Istio 配置和网关

    kubectl delete -f samples/bookinfo/networking/bookinfo-gateway.yaml
    kubectl delete -f samples/bookinfo/networking/destination-rule-all.yaml
    # 如果配置了其他VirtualService,也请删除
    
  3. 卸载 Istio 控制平面

    istioctl uninstall -y --purge
    
  4. 删除命名空间标签(可选)

    kubectl label namespace default istio-injection-
    
  5. 删除 istio-system 命名空间(可选)

    kubectl delete namespace istio-system
    

希望以上内容能帮助你顺利完成 Istio 的安装和 Bookinfo 示例应用的体验。通过这个示例,你可以直观地感受到 Istio 在流量管理、安全性和可观测性方面带来的强大能力。

记录学习

记录成长

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐