当前位置: 首页 > article >正文

Istio1.6官方文档中文版

目 录
致谢概念
Istio 是什么? 流量管理
扩展性安全
可观察性
安装
开始
平台安装
阿里云
Azure

Docker Desktop

使用 Google Kubernetes Engine 快速开始
IBM Cloud 快速开始
kind

Kubernetes Gardener 快速开始
MicroK8s Minikube OpenShift
Oracle Cloud Infrastructure

安装
使用 Istioctl 安装
使用 Helm 自定义安装安装独立 Operator [实验] 多集群安装
简化地多集群安装[实验性] 控制平面副本集
共享控制平面(单一网络) 共享的控制平面(多网络)
升级
使用 istioctl 命令升级Istio [实验中]
使用 Helm 升级更多指南
安装配置 设置 Sidecar
安装Istio CNI 插件
任务
流量管理
配置请求路由故障注入
流量转移 TCP 流量转移设置请求超时熔断
镜像
Ingress

Ingress Gateway

安全网关(文件挂载)
使用SDS 为 Gateway 提供HTTPS 加密支持无 TLS 终止的Ingress Gateway
Egress

访问外部服务
Egress TLS Origination Egress Gateway
Egress 网关的TLS 发起过程
Wildcard 主机的egress
TLS Egress 监控和策略配置使用外部HTTPS 代理Kubernetes Egress 流量服务
安全
认证
自动双向TLS
认证策略
通过HTTPS 进行TLS
双向TLS 迁移
Citadel 配置授权
HTTP 流量授权TCP 流量的授权基于JWT 授权
授权策略信任域迁移插入外部CA 证书
Istio DNS 证书管理
策略
启用策略检查功能启用速率限制
请求头和路由控制
Denials 和黑白名单可观察性
指标度量
采集指标
收集TCP 服务指标
通过Prometheus 查询度量指标使用Grafana 可视化指标
日志
收集日志
获取Envoy 访问日志
使用Fluentd 进行日志收集分布式追踪
概述
Zipkin Jaeger LightStep
网络可视化
远程访问遥测插件
示例
Bookinfo 应用虚拟机
单个网络网格中的虚拟机多网络网格中的虚拟机
在虚拟机上部署Bookinfo 应用程序使用Kubernetes 和 Istio 学习微服务
前提条件
设置Kubernetes 集群设置本地计算机
本地运行微服务
在 Docker 中运行ratings 服务使用Kubernetes 运行Bookinfo 生产测试
运维
部署
架构
部署模型
性能和可扩展性
Pod 和 Service
配置
网格配置
动态准入 Webhook 概述
Sidecar 自动注入
创建服务账号 Secret Istio 服务的健康检查
流量管理
协议选择
地域负载均衡
安全
加固 Docker 容器镜像延长自签名证书的寿命
可观测性
Envoy 的统计信息
不使用 Mixer 生成 Istio 指标 [Alpha]
最佳实践
Deployment 最佳实践流量管理最佳实践 安全最佳实践
常见问题
流量管理问题安全问题
可观测性问题 Sidecar 自动注入问题配置验证的问题
诊断工具
使用Istioctl 命令行工具调试Envoy 和 Pilot
通过Istioctl Describe 理解您的网格使用Istioctl Analyze 诊断配置
组件自检
组件日志记录
集成
cert-manager
参考
配置

Service Mesh Operator Installation
安装选项(Helm)
IstioOperator Options Resource Annotations
流量管理
Destination Rule Envoy Filter Gateway
Virtual Service Sidecar Service Entry
Security
JWTRule RequestAuthentication PeerAuthentication Authentication Policy Authorization Policy 授权策略
RBAC (deprecated)

RBAC 约束和属性(不建议使用)
Telemetry V2

Istio 标准度量指标
使用Wasm 运行时的Telemetry V2(实验性) 可配置指标(实验性)
配置分析消息
Analyzer Message Format ConflictingMeshGatewayVirtualServiceHosts ConflictingSidecarWorkloadSelectors Deprecated
GatewayPortNotOnWorkload InternalError IstioProxyImageMismatch
JwtFailureDueToInvalidServicePortPrefix MisplacedAnnotation MTLSPolicyConflict
MultipleSidecarsWithoutWorkloadSelectors NamespaceNotInjected VirtualServiceDestinationPortSelectorRequired UnknownAnnotation
SchemaValidationError ReferencedResourceNotFound PortNameIsNotUnderNamingConvention PodMissingProxy
Mixer 策略和遥测
Mixer Client Rules
Mixer 配置模型
属性词汇 表达式语言适配器
Apache SkyWalking Apigee
App Identity and Access Circonus
CloudMonitor CloudWatch Datadog Zipkin
Denier Fluentd
Kubernetes Env List
Memory quota New Relic
Wavefront by VMware Stdio
StatsD Stackdriver SolarWinds Redis Quota Prometheus OPA
模板
Analytics API Key Authorization
Check Nothing Edge Kubernetes List Entry
Log Entry Metric Trace Span
Report Nothing Quota
默认监控指标
命令

galley istio_ca istioctl mixs
sidecar-injector pilot-discovery pilot-agent operator node_agent
术语表

概念

一些概念,理解它们有助于您更好地了解 Istio 系统的不同部分及其使用的抽象。

Istio 是什么?

介绍 Istio,它要解决的问题,高层面的架构和设计目标。

流量管理

描述 Istio 多样的流量路由和控制特性。

扩展性

讲述 Istio 的 WebAssembly 插件系统。

安全

描述 Istio 的授权与认证功能。

可观察性

描述 Istio 提供的遥测和监控特性。

Istio 是什么?

云平台令使用它们的公司受益匪浅。但不可否认的是,上云会给 DevOps 团队带来压力。为了可移植性,开发人员必须使用微服务来 应用,同时运维人员也正在管理着极端庞大的混合云和多云的部署环境。 Istio 允许您连接、保
护、控制和观察服务。

从较高的层面来说,Istio 有助于降低这些部署的复杂性,并减轻开发团队的压力。它是一个完全开源的服务网格, 作为透明的一层接入到现有的分布式应用程序里。它也是一个平台,拥有可以集成任何日志、遥测和策略系统的 API 接口。Istio 多样化的特性使您能够成功且高效地运行分布式微服务架构,并提供保护、连接和监控微服务的统一方法。

服务网格是什么?

Istio 解决了开发人员和运维人员所面临的从单体应用向分布式微服务架构转变的挑战。了解它是如何做到这一点的可以让我们更详细地理解 Istio 的服务网格。

术语服务网格用来描述组成这些应用程序的微服务网络以及它们之间的交互。随着服务网格的规模和复杂性不断的增长,它将会变得越来越难以理解和管理。它的需求包括服务发现、负载均衡、故障恢复、度量和监控等。服务网格通常还有更复杂的运维需求,比如 A/B 测试、金丝雀发布、速率限制、访问控制和端到端认证。

Istio 提供了对整个服务网格的行为洞察和操作控制的能力,以及一个完整的满足微服务应用各种需求的解决方案。

为什么使用 Istio?

通过负载均衡、服务间的身份验证、监控等方法,Istio 可以轻松地创建一个已经部署了服务的网络,而服务的代码只需很少更改甚至无需更改。通过在整个环境中部署一个特殊的 sidecar 代理为服务添加 Istio 的支持,而代理会拦截微服务之间的所有网络通信,然后使用其控制平面的功能来配置和管理 Istio,这包括:

为 HTTP、gRPC、WebSocket 和 TCP 流量自动负载均衡。

通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制。

可插拔的策略层和配置 API,支持访问控制、速率限制和配额。

集群内(包括集群的入口和出口)所有流量的自动化度量、日志记录和追踪。

在具有强大的基于身份验证和授权的集群中实现安全的服务间通信。
Istio 为可扩展性而设计,可以满足不同的部署需求。

核心特性

Istio 以统一的方式提供了许多跨服务网络的关键功能:

流量管理

Istio 简单的规则配置和流量路由允许您控制服务之间的流量和 API 调用过程。Istio 简化了服务级属性(如熔断器、超时和重试)的配置,并且让它轻而易举的执行重要的任务(如 A/B 测试、金丝雀发布和按流量百分比划分的分阶段发布)。

有了更好的对流量的可视性和开箱即用的故障恢复特性,您就可以在问题产生之前捕获它们,无论面对什么情况都可以使调用更可靠,网络更健壮。

请参考流量管理文档获取更多细节。

安全

Istio 的安全特性解放了开发人员,使其只需要专注于应用程序级别的安全。Istio 提供了底层的安全通信通道, 并为大规模的服务通信管理认证、授权和加密。有了 Istio,服务通信在默认情况下就是受保护的,可以让您在跨不同协议和运行时的情况下实施一致的策略——而所有这些都只需要很少甚至不需要修改应用程序。

Istio 是独立于平台的,可以与 Kubernetes(或基础设施)的网络策略一起使用。但它更强大,能够在网络和应用层面保护pod到 pod 或者服务到服务之间的通信。

请参考安全文档获取更多细节。

可观察性

Istio 健壮的追踪、监控和日志特性让您能够深入的了解服务网格部署。通过 Istio 的监控能力,可以真正的了解到服务的性能是如何影响上游和下游的;而它的定制 Dashboard 提供了对所有服务性能的可视化能力,并让您看到它如何影响其他进程。

Istio 的 Mixer 组件负责策略控制和遥测数据收集。它提供了后端抽象和中介,将一部分 Istio 与后端的基础设施实现细节隔离开来,并为运维人员提供了对网格与后端基础实施之间交互的细粒度控制。

所有这些特性都使您能够更有效地设置、监控和加强服务的 SLO。当然,底线是您可以快速有效地检测到并修复出现的问题。

请参考可观察性文档获取更多细节。

平台支持

Istio 独立于平台,被设计为可以在各种环境中运行,包括跨云、内部环境、Kubernetes、Mesos 等等。您可以在 Kubernetes 或是装有 Consul 的 Nomad 环境上部署 Istio。Istio 目前支持:

Kubernetes 上的服务部署

基于 Consul 的服务注册

服务运行在独立的虚拟机上

整合和定制

Istio 的策略实施组件可以扩展和定制,与现有的 ACL、日志、监控、配额、审查等解决方案集成。

流量管理

Istio 的流量路由规则可以让您很容易的控制服务之间的流量和 API 调用。Istio 简化了服务级别属性的配置, 比如熔断器、超时和重试,并且能轻松的设置重要的任务,如 A/B 测试、金丝雀发布、基于流量百分比切分的概率发布等。它还提供了开箱即用的故障恢复特性,有助于增强应用的健壮性,从而更好地应对被依赖的服务或网络发生故障的情况。

Istio 的流量管理模型源于和服务一起部署的 Envoy 代理。网格内服务发送和接收的所有流量(data plane流量)都经由 Envoy 代理,这让控制网格内的流量变得异常简单,而且不需要对服务做任何的更改。

本节中描述的功能特性,如果您对它们是如何工作的感兴趣的话,可以在架构概述中找到关于 Istio 的流量管理实现的更多信息。本部分只介绍 Istio 的流量管理特性。

Istio 流量管理介绍

为了在网格中导流,Istio 需要知道所有的 endpoint 在哪和属于哪个服务。为了定位到service registry(服务注册中心),Istio 会连接到一个服务发现系统。例如,如果您在 Kubernetes 集群上安装了 Istio,那么它将自动检测该集群中的服务和 endpoint。

使用此服务注册中心,Envoy 代理可以将流量定向到相关服务。大多数基于微服务的应用程序,每个服务的工作负载都有多个实例来处理流量,称为负载均衡池。默认情况下,Envoy 代理基于轮询调度模型在服务的负载均衡池内分发流量,按顺序将请求发送给池中每个成员,一旦所有服务实例均接收过一次请求后,重新回到第一个池成员。

Istio 基本的服务发现和负载均衡能力为您提供了一个可用的服务网格,但它能做到的远比这多的多。在许多情况下,您可能希望对网格的流量情况进行更细粒度的控制。作为 A/B 测试的一部分,您可能想将特定百分比的流量定向到新版本的服务,或者为特定的服务实例子集应用不同的负载均衡策略。您可能还想对进出网格的流量应用特殊的规则,或者将网格的外部依赖项添加到服务注册中心。通过使用 Istio 的流量管理 API 将流量配置添加到Istio,就可以完成所有这些甚至更多的工作。

和其他 Istio 配置一样,这些 API 也使用 Kubernetes 的自定义资源定义(CRDs)来声明,您可以像示例中看到的那样使用 YAML 进行配置。
本章节的其余部分将分别介绍每个流量管理 API 以及如何使用它们。这些资源包括: 虚拟服务
目标规则网关
服务入口
Sidecar

指南也对 在 API 资源内的网络弹性和测试做了概述。

虚拟服务

虚拟服务(Virtual Service) 和目标规则(Destination Rule) 是 Istio 流量路由功能的关键拼图。虚拟服务让您配置如何在服务网格内将请求路由到服务,这基于 Istio 和平台提供的基本的连通性和服务发现能力。

每个虚拟服务包含一组路由规则,Istio 按顺序评估它们,Istio 将每个给定的请求匹配到虚拟服务指定的实际目标地址。您的网格可以有多个虚拟服务,也可以没有,取决于您的使用场景。

为什么使用虚拟服务?

虚拟服务在增强 Istio 流量管理的灵活性和有效性方面,发挥着至关重要的作用,通过对客户端请求的目标地址与真实响应请求的目标工作负载进行解耦来实现。虚拟服务同时提供了丰富的方式,为发送至这些工作负载的流量指定不同的路由规则。

为什么这如此有用?就像在介绍中所说,如果没有虚拟服务,Envoy 会在所有的服务实例中使用轮询的负载均衡策略分发请求。您可以用您对工作负载的了解来改善这种行为。例如,有些可能代表不同的版本。这在 A/B 测试中可能有用,您可能希望在其中配置基于不同服务版本的流量百分比路由,或指引从内部用户到特定实例集的流量。

使用虚拟服务,您可以为一个或多个主机名指定流量行为。在虚拟服务中使用路由规则,告诉 Envoy 如何发送虚拟服务的流量到适当的目标。路由目标地址可以是同一服务的不同版本,也可以是完全不同的服务。

一个典型的用例是将流量发送到被指定为服务子集的服务的不同版本。客户端将虚拟服务视为一个单一实体,将请求发送至虚拟服务主机,然后 Envoy 根据虚拟服务规则把流量路由到不同的版本。例如,“20% 的调用转到新版
本”或“将这些用户的调用转到版本 2”。这允许您创建一个金丝雀发布,逐步增加发送到新版本服务的流量百分比。流量路由完全独立于实例部署,这意味着实现新版本服务的实例可以根据流量的负载来伸缩,完全不影响流量路由。相比之下,像 Kubernetes 这样的容器编排平台只支持基于实例缩放的流量分发,这会让情况变得复杂。您可以在使用 Istio 进行金丝雀部署的文章里阅读到更多用虚拟服务实现金丝雀部署的内容。

虚拟服务可以让您:

通过单个虚拟服务处理多个应用程序服务。如果您的网格使用 Kubernetes,可以配置一个虚拟服务处理特定命名空间中的所有服务。映射单一的虚拟服务到多个“真实”服务特别有用,可以在不需要客户适应转换的情况下,将单体应用转换为微服务 的复合应用系统。您的路由规则可以指定为“对这些 monolith.com 的 URI
调用转到 ”等等。您可以在下面的一个示例看到它是如何工作的。
microservice A
和网关整合并配置流量规则来控制出入流量。

在某些情况下,您还需要配置目标规则来使用这些特性,因为这是指定服务子集的地方。在一个单独的对象中指定服务子集和其它特定目标策略,有利于在虚拟服务之间更简洁地重用这些规则。在下一章节您可以找到更多关于目标规则的内容。

虚拟服务示例

下面的虚拟服务根据请求是否来自特定的用户,把它们路由到服务的不同版本。

  1. apiVersion: networking.istio.io/v1alpha3

  2. kind: VirtualService

  3. metadata:

  4. name: reviews

  5. spec:

  6. hosts:

    • reviews
  7. http:

    • match:
    • headers:
  8. end-user:

  9. exact: jason

  10. route:

    • destination:
  11. host: reviews

  12. subset: v2

    • route:
    • destination:
  13. host: reviews

  14. subset: v3

hosts 字段

使用 字段列举虚拟服务的主机——即用户指定的目标或是路由规则设定的目标。这是客户端向服务发送请求
hosts
时使用的一个或多个地址。

  1. hosts:
    • reviews

虚拟服务主机名可以是 IP 地址、DNS 名称,或者依赖于平台的一个简称(例如 Kubernetes 服务的短名称), 隐式或显式地指向一个完全限定域名(FQDN)。您也可以使用通配符(“*”)前缀,让您创建一组匹配所有服务的路
由规则。虚拟服务的 字段实际上不必是 Istio 服务注册的一部分,它只是虚拟的目标地址。这让您可以
hosts
为没有路由到网格内部的虚拟主机建模。

路由规则

在 字段包含了虚拟服务的路由规则,用来描述匹配条件和路由行为,它们把 HTTP/1.1、HTTP2 和 gRPC
http
等流量发送到 hosts 字段指定的目标(您也可以用 和 片段为 TCP 和未终止的 TLS 流量设置路
tcp
tls
由规则)。一个路由规则包含了指定的请求要流向哪个目标地址,具有 0 或多个匹配条件,取决于您的使用场景。

匹配条件

示例中的第一个路由规则有一个条件,因此以 match 字段开始。在本例中,您希望此路由应用于来自 ”jason“
headers
exact

用户的所有请求,所以使用
、 end-user 和
字段选择适当的请求。

    • match:
    • headers:
  1. end-user:
  2. exact: jason

Destination

route 部分的
字段指定了符合此条件的流量的实际目标地址。与虚拟服务的
不同,
destination 的 host 必须是存在于 Istio 服务注册中心的实际目标地址,否则 Envoy 不知道该将请求发送到哪里。可以是一个有代理的服务网格,或者是一个通过服务入口被添加进来的非网格服务。本示例运行在Kubernetes 环境中,host 名为一个 Kubernetes 服务名:
destination
hosts

  1. route:
    • destination:
  2. host: reviews
  3. subset: v2

请注意,在该示例和本页其它示例中,为了简单,我们使用 Kubernetes 的短名称设置 destination 的
host。在评估此规则时,Istio 会添加一个基于虚拟服务命名空间的域后缀,这个虚拟服务包含要获取主机的完全限定名的路由规则。在我们的示例中使用短名称也意味着您可以复制并在任何喜欢的命名空间中尝试它们。

只有在目标主机和虚拟服务位于相同的 Kubernetes 命名空间时才可以使用这样的短名称。因为使用 Kubernetes
的短名称容易导致配置出错,我们建议您在生产环境中指定完全限定的主机名。
destination 片段还指定了 Kubernetes 服务的子集,将符合此规则条件的请求转入其中。在本例中子集名称是
v2。您可以在目标规则章节中看到如何定义服务子集。

路由规则优先级

路由规则按从上到下的顺序选择,虚拟服务中定义的第一条规则有最高优先级。本示例中,不满足第一个路由规则的流量均流向一个默认的目标,该目标在第二条规则中指定。因此,第二条规则没有 match 条件,直接将流量导向v3 子集。

    • route:
    • destination:
  1. host: reviews
  2. subset: v3

我们建议提供一个默认的“无条件”或基于权重的规则(见下文)作为每一个虚拟服务的最后一条规则,如案例所示, 从而确保流经虚拟服务的流量至少能够匹配一条路由规则。

路由规则的更多内容

正如上面所看到的,路由规则是将特定流量子集路由到指定目标地址的强大工具。您可以在流量端口、header 字段、URI 等内容上设置匹配条件。例如,这个虚拟服务让用户发送请求到两个独立的服务:ratings 和

reviews,就好像它们是
http://bookinfo.com/
指向适当服务的请求匹配流量。
这个更大的虚拟服务的一部分。虚拟服务规则根据请求的 URI 和

  1. apiVersion: networking.istio.io/v1alpha3

  2. kind: VirtualService

  3. metadata:

  4. name: bookinfo

  5. spec:

  6. hosts:

    • bookinfo.com
  7. http:

    • match:
    • uri:
  8. prefix: /reviews

  9. route:

    • destination:
  10. host: reviews

    • match:
    • uri:
  11. prefix: /ratings

  12. route:

    • destination:
  13. host: ratings 21. …

  14. http:

    • match:
  15. sourceLabels:

  16. app: reviews

  17. route: 28. …

有些匹配条件可以使用精确的值,如前缀或正则。

您可以使用 AND 向同一个
块添加多个匹配条件,或者使用 OR 向同一个规则添加多个
块。对
于任何给定的虚拟服务也可以有多个路由规则。这可以在单个虚拟服务中使路由条件变得随您所愿的复杂或简单。匹
match
match
配条件字段和备选值的完整列表可以在 参考中找到。
HTTPMatchRequest

另外,使用匹配条件您可以按百分比”权重“分发请求。这在 A/B 测试和金丝雀发布中非常有用:

  1. spec:
  2. hosts:
    • reviews
  3. http:
    • route:
    • destination:
  4. host: reviews
  5. subset: v1
  6. weight: 75
    • destination:
  7. host: reviews
  8. subset: v2
  9. weight: 25

您也可以使用路由规则在流量上执行一些操作,例如:

添加或删除 header。重写 URL。
为调用这一目标地址的请求设置重试策略。

想了解如何利用这些操作,查看 参考。
HTTPRoute

目标规则

与虚拟服务一样,目标规则也是 Istio 流量路由功能的关键部分。您可以将虚拟服务视为将流量如何路由到给定目

标地址,然后使用目标规则来配置该目标的流量。在评估虚拟服务路由规则之后,目标规则将应用于流量的“真实”目标地址。

特别是,您可以使用目标规则来指定命名的服务子集,例如按版本为所有给定服务的实例分组。然后可以在虚拟服务的路由规则中使用这些服务子集来控制到服务不同实例的流量。

目标规则还允许您在调用整个目的地服务或特定服务子集时定制 Envoy 的流量策略,比如您喜欢的负载均衡模型、
TLS 安全模式或熔断器设置。在目标规则参考中可以看到目标规则选项的完整列表。

负载均衡选项

默认情况下,Istio 使用轮询的负载均衡策略,实例池中的每个实例依次获取请求。Istio 同时支持如下的负载均
衡模型,可以在 中为流向某个特定服务或服务子集的流量指定这些模型。
DestinationRule

随机:请求以随机的方式转到池中的实例。权重:请求根据指定的百分比转到实例。 最少请求:请求被转到最少被访问的实例。

查看 Envoy 负载均衡文档获取这部分的更多信息。

目标规则示例

在下面的示例中,目标规则为 目标服务配置了 3 个具有不同负载均衡策略的子集:
my-svc

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: DestinationRule
  3. metadata:
  4. name: my-destination-rule
  5. spec:
  6. host: my-svc
  7. trafficPolicy:
  8. loadBalancer:
  9. simple: RANDOM
  10. subsets:
    • name: v1
  11. labels:
  12. version: v1
    • name: v2
  13. labels:
  14. version: v2
  15. trafficPolicy:
  16. loadBalancer:
  17. simple: ROUND_ROBIN
    • name: v3
  18. labels:
  19. version: v3

每个子集都是基于一个或多个 定义的,在 Kubernetes 中它是附加到像 Pod 这种对象上的键/值对。
labels
这些标签应用于 Kubernetes 服务的 Deployment 并作为 来识别不同的版本。
metadata

除了定义子集之外,目标规则对于所有子集都有默认的流量策略,而对于该子集,则有特定于子集的策略覆盖它。定

v3
v2

义在 上的默认策略,为 和
subsets
v1
子集设置了一个简单的随机负载均衡器。在
策略中,

轮询负载均衡器被指定在相应的子集字段上。

网关

使用网关为网格来管理入站和出站流量,可以让您指定要进入或离开网格的流量。网关配置被用于运行在网格边界的独立 Envoy 代理,而不是服务工作负载的 sidecar 代理。

与 Kubernetes Ingress API 这种控制进入系统流量的其他机制不同,Istio 网关让您充分利用流量路由的强大能力和灵活性。您可以这么做的原因是 Istio 的网关资源可以配置 4-6 层的负载均衡属性,如对外暴露的端
口、TLS 设置等。作为替代应用层流量路由(L7)到相同的 API 资源,您绑定了一个常规的 Istio 虚拟服务到网关。这让您可以像管理网格中其他数据平面的流量一样去管理网关流量。

网关主要用于管理进入的流量,但您也可以配置出口网关。出口网关让您为离开网格的流量配置一个专用的出口节 点,这可以限制哪些服务可以或应该访问外部网络,或者启用出口流量安全控制为您的网格添加安全性。您也可以使用网关配置一个纯粹的内部代理。

Istio 提供了一些预先配置好的网关代理部署( 和 )供您使用——如
istio-ingressgateway
istio-egressgateway
果使用我们的演示安装它们都已经部署好了;如果使用默认或 sds 配置文件则只部署了入口网关。可以将您自己的网关配置应用到这些部署或配置您自己的网关代理。

Gateway 示例

下面的示例展示了一个外部 HTTPS 入口流量的网关配置:

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: Gateway
  3. metadata:
  4. name: ext-host-gwy
  5. spec:
  6. selector:
  7. app: my-gateway-controller
  8. servers:
    • port:
  9. number: 443
  10. name: https
  11. protocol: HTTPS
  12. hosts:
    • ext-host.example.com
  13. tls:
  14. mode: SIMPLE
  15. serverCertificate: /tmp/tls.crt
  16. privateKey: /tmp/tls.key

这个网关配置让 HTTPS 流量从 通过 443 端口流入网格,但没有为请求指定任何路由规
ext-host.example.com
则。为想要工作的网关指定路由,您必须把网关绑定到虚拟服务上。正如下面的示例所示,使用虚拟服务的字段进行设置:
gateways

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: VirtualService
  3. metadata:
  4. name: virtual-svc
  5. spec:
  6. hosts:
    • ext-host.example.com
  7. gateways:
    • ext-host-gwy

然后就可以为出口流量配置带有路由规则的虚拟服务。

服务入口

使用服务入口(Service Entry) 来添加一个入口到 Istio 内部维护的服务注册中心。添加了服务入口后, Envoy 代理可以向服务发送流量,就好像它是网格内部的服务一样。配置服务入口允许您管理运行在网格外的服务的流量,它包括以下几种能力:

为外部目标 redirect 和转发请求,例如来自 web 端的 API 调用,或者流向遗留老系统的服务。为外部目标定义重试、超时和故障注入策略。
添加一个运行在虚拟机的服务来扩展您的网格。
从逻辑上添加来自不同集群的服务到网格,在 Kubernetes 上实现一个多集群 Istio 网格。

您不需要为网格服务要使用的每个外部服务都添加服务入口。默认情况下,Istio 配置 Envoy 代理将请求传递给未知服务。但是,您不能使用 Istio 的特性来控制没有在网格中注册的目标流量。

服务入口示例

下面示例的 mesh-external 服务入口将 外部依赖项添加到 Istio 的服务注册中心:
ext-resource

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: ServiceEntry
  3. metadata:
  4. name: svc-entry
  5. spec:
  6. hosts:
    • ext-svc.example.com
  7. ports:
    • number: 443
  8. name: https
  9. protocol: HTTPS
  10. location: MESH_EXTERNAL
  11. resolution: DNS

您指定的外部资源使用 字段。可以使用完全限定名或通配符作为前缀域名。
hosts

您可以配置虚拟服务和目标规则,以更细粒度的方式控制到服务入口的流量,这与网格中的任何其他服务配置流量的
方式相同。例如,下面的目标规则配置流量路由以使用双向 TLS 来保护到 外部服务的连
ext-svc.example.com

接,我们使用服务入口配置了该外部服务:

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: DestinationRule
  3. metadata:
  4. name: ext-res-dr
  5. spec:
  6. host: ext-svc.example.com
  7. trafficPolicy:
  8. tls:
  9. mode: MUTUAL
  10. clientCertificate: /etc/certs/myclientcert.pem
  11. privateKey: /etc/certs/client_private_key.pem
  12. caCertificates: /etc/certs/rootcacerts.pem

查看服务入口参考获取更多可能的配置项。

Sidecar

默认情况下,Istio 让每个 Envoy 代理都可以访问来自和它关联的工作负载的所有端口的请求,然后转发到对应的工作负载。您可以使用 sidecar 配置去做下面的事情:

微调 Envoy 代理接受的端口和协议集。限制 Envoy 代理可以访问的服务集合。

您可能希望在较庞大的应用程序中限制这样的 sidecar 可达性,配置每个代理能访问网格中的任意服务可能会因为高内存使用量而影响网格的性能。

您可以指定将 sidecar 配置应用于特定命名空间中的所有工作负载,或者使用 选择特定的工
workloadSelector
作负载。例如,下面的 sidecar 配置将 命名空间中的所有服务配置为仅能访问运行在相同命名空间和
bookinfo
Istio 控制平面中的服务(目前需要使用 Istio 的策略和遥测功能):

  1. apiVersion: networking.istio.io/v1alpha3

  2. kind: Sidecar

  3. metadata:

  4. name: default

  5. namespace: bookinfo

  6. spec:

  7. egress:

    • hosts:
    • “./*”
    • “istio-system/*”

查阅 Sidecar 参考获取详细信息。

网络弹性和测试

除了为您的网格导流之外,Istio 还提供了可选的故障恢复和故障注入功能,您可以在运行时动态配置这些功能。使

用这些特性可以让您的应用程序运行稳定,确保服务网格能够容忍故障节点,并防止局部故障级联影响到其他节点。

超时

超时是 Envoy 代理等待来自给定服务的答复的时间量,以确保服务不会因为等待答复而无限期的挂起,并在可预测的时间范围内调用成功或失败。HTTP 请求的默认超时时间是 15 秒,这意味着如果服务在 15 秒内没有响应,调用将失败。

对于某些应用程序和服务,Istio 的缺省超时可能不合适。例如,超时太长可能会由于等待失败服务的回复而导致过度的延迟;而超时过短则可能在等待涉及多个服务返回的操作时触发不必要地失败。为了找到并使用最佳超时设置, Istio 允许您使用虚拟服务按服务轻松地动态调整超时,而不必修改您的业务代码。下面的示例是一个虚拟服务,它对 ratings 服务的 v1 子集的调用指定 10 秒超时:

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: VirtualService
  3. metadata:
  4. name: ratings
  5. spec:
  6. hosts:
    • ratings
  7. http:
    • route:
    • destination:
  8. host: ratings
  9. subset: v1
  10. timeout: 10s

重试

重试设置指定如果初始调用失败,Envoy 代理尝试连接服务的最大次数。通过确保调用不会因为临时过载的服务或网络等问题而永久失败,重试可以提高服务可用性和应用程序的性能。重试之间的间隔(25ms+)是可变的,并由 Istio 自动确定,从而防止被调用服务被请求淹没。默认情况下,在第一次失败后,Envoy 代理不会重新尝试连接服务。

与超时一样,Istio 默认的重试行为在延迟方面可能不适合您的应用程序需求(对失败的服务进行过多的重试会降低速度)或可用性。您可以在虚拟服务中按服务调整重试设置,而不必修改业务代码。您还可以通过添加每次重试的超 时来进一步细化重试行为,并指定每次重试都试图成功连接到服务所等待的时间量。下面的示例配置了在初始调用失 败后最多重试 3 次来连接到服务子集,每个重试都有 2 秒的超时。

  1. apiVersion: networking.istio.io/v1alpha3

  2. kind: VirtualService

  3. metadata:

  4. name: ratings

  5. spec:

  6. hosts:

    • ratings
  7. http:

    • route:
    • destination:

host: ratings subset: v1
retries: attempts: 3
perTryTimeout: 2s

熔断器

熔断器是 Istio 为创建具有弹性的微服务应用提供的另一个有用的机制。在熔断器中,设置一个对服务中的单个主机调用的限制,例如并发连接的数量或对该主机调用失败的次数。一旦限制被触发,熔断器就会“跳闸”并停止连接到该主机。使用熔断模式可以快速失败而不必让客户端尝试连接到过载或有故障的主机。

熔断适用于在负载均衡池中的“真实”网格目标地址,您可以在目标规则中配置熔断器阈值,让配置适用于服务中的每
个主机。下面的示例将 v1 子集的 服务工作负载的并发连接数限制为 100:
reviews

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: DestinationRule
  3. metadata:
  4. name: reviews
  5. spec:
  6. host: reviews
  7. subsets:
    • name: v1
  8. labels:
  9. version: v1
  10. trafficPolicy:
  11. connectionPool:
  12. tcp:
  13. maxConnections: 100

您可以在熔断中查看更多相关信息。

故障注入

在配置了网络,包括故障恢复策略之后,可以使用 Istio 的故障注入机制来为整个应用程序测试故障恢复能力。故障注入是一种将错误引入系统以确保系统能够承受并从错误条件中恢复的测试方法。使用故障注入特别有用,能确保故障恢复策略不至于不兼容或者太严格,这会导致关键服务不可用。

与其他错误注入机制(如延迟数据包或在网络层杀掉 Pod)不同,Istio 允许在应用层注入错误。这使您可以注入更多相关的故障,例如 HTTP 错误码,以获得更多相关的结果。

您可以注入两种故障,它们都使用虚拟服务配置:

延迟:延迟是时间故障。它们模拟增加的网络延迟或一个超载的上游服务。

终止:终止是崩溃失败。他们模仿上游服务的失败。终止通常以 HTTP 错误码或 TCP 连接失败的形式出现。

例如,下面的虚拟服务为千分之一的访问 服务的请求配置了一个 5 秒的延迟:
ratings

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: VirtualService
  3. metadata:
  4. name: ratings
  5. spec:
  6. hosts:
    • ratings
  7. http:
    • fault:
  8. delay:
  9. percentage:
  10. value: 0.1
  11. fixedDelay: 5s
  12. route:
    • destination:
  13. host: ratings
  14. subset: v1

有关如何配置延迟和终止的详细信息请参考故障注入。

和您的应用程序一起运行

Istio 故障恢复功能对应用程序来说是完全透明的。在返回响应之前,应用程序不知道 Envoy sidecar 代理是否正在处理被调用服务的故障。这意味着,如果在应用程序代码中设置了故障恢复策略,那么您需要记住这两个策略都 是独立工作的,否则会发生冲突。例如,假设您设置了两个超时,一个在虚拟服务中配置,另一个在应用程序中配
置。应用程序为服务的 API 调用设置了 2 秒超时。而您在虚拟服务中配置了一个 3 秒超时和重试。在这种情况下,应用程序的超时会先生效,因此 Envoy 的超时和重试尝试会失效。

虽然 Istio 故障恢复特性提高了网格中服务的可靠性和可用性,但应用程序必须处理故障或错误并采取适当的回退
操作。例如,当负载均衡中的所有实例都失败时,Envoy 返回一个 代码。应用程序必须实现回退逻辑来处
HTTP 503
理 错误代码。
HTTP 503

相关内容

使用 Admiral 管理 Istio 多集群的配置和服务发现
为 Istio deployment(cluster)提供自动化 Istio 配置,并让其像单个网格一样工作。把 Istio 作为外部服务的代理
把 Istio 入口网关配置为外部服务的代理。用于隔离和边界保护的多网格部署
将需要隔离的环境部署到单独的网格中,并通过网格联邦启用网格间通信。
Istio 中安全管控出口流量,第三部分
管控出口流量的备选方案比较,包括性能因素。

Istio 中的安全管控出口流量,第二部分
使用 Istio 的出口流量管控来阻止相关出口流量攻击。
Istio 中的安全管控出口流量,第一部分涉及出口流量攻击和出口流量管控要求。

扩展性

WebAssembly 是一种沙盒技术,可以用于扩展 Istio 代理(Envoy)的能力。Proxy-Wasm 沙盒 API 取代了
Mixer 作为 Istio 主要的扩展机制。在 Istio 1.6 中将会为 Proxy-Wasm 插件提供一种统一的配置 API。WebAssembly 沙盒的目标:
效率 - 这是一种低延迟,低 CPU 和内存开销的扩展机制。
功能 - 这是一种可以执行策略,收集遥测数据和执行有效荷载变更的扩展机制。隔离 - 一个插件中程序的错误或是崩溃不会影响其它插件。
配置 - 插件使用与其它 Istio API 一致的 API 进行配置。可以动态的配置扩展。运维 - 扩展可以以仅日志,故障打开或者故障关闭的方式进行访问和部署。
扩展开发者 - 可以用多种编程语言编写。
这个演讲视频是关于 WebAssembly 集成架构的介绍。

高级架构

Istio 扩展(Proxy-Wasm 插件)有几个组成部分:

过滤器服务提供商接口 用于为过滤器 Proxy-Wasm 插件。沙盒 在 Envoy 中嵌入 V8 Wasm 运行时。
主机 **API **用于处理请求头,尾和元数据。调出 **API **针对 gRPC 和 HTTP 请求。统计和记录 **API **用于度量统计和监控。

扩展 Istio/Envoy

例子

这里是用 C++ 为过滤器实现 Proxy-Wasm 插件的例子。为过滤器实现一个 Proxy-Wasm 插件需要:
实现一个继承了 base context 类的 root context 类。实现一个继承了 base context 类的 流 context 类。
重写 context API 的方法,以此处理来自主机的相应初始化和流事件。
注册 这个 和流 。
root context
stream context

SDK

C++ SDK 的详细说明见这里。

生态

Proxy-Wasm ABI 说明

Proxy-Wasm C++ SDK Proxy-Wasm Rust SDK
Proxy-Wasm AssemblyScript SDK WebAssembly Hub
网络代理的 WebAssembly 扩展(视频)

相关内容

在 Istio 中进行 WebAssembly 声明式部署
以声明方式为 Envoy 和 Istio 配置 Wasm 扩展。
重新定义代理的扩展性:Envoy 和 Istio 引入 WebAssembly Istio 的扩展中使用 WASM 的前景。

安全

将单一应用程序分解为微服务可提供各种好处,包括更好的灵活性、可伸缩性以及服务复用的能力。但是,微服务也有特殊的安全需求:

为了抵御中间人攻击,需要流量加密。
为了提供灵活的服务访问控制,需要双向 TLS 和细粒度的访问策略。要确定谁在什么时候做了什么,需要审计工具。

Istio Security 尝试提供全面的安全解决方案来解决所有这些问题。本页概述了如何使用 Istio 的安全功能来保护您的服务,无论您在何处运行它们。特别是 Istio 安全性可以缓解针对您的数据、端点、通信和平台的内部和外部威胁。

安全概述

Istio 安全功能提供强大的身份,强大的策略,透明的 TLS 加密,认证,授权和审计(AAA)工具来保护你的服务和数据。Istio 安全的目标是:

默认安全:应用程序代码和基础设施无需更改
深度防御:与现有安全系统集成以提供多层防御零信任网络:在不受信任的网络上 安全解决方案

请访问我们的双向 TLS 迁移相关文章,开始在已部署的服务中使用 Istio 安全功能。 请访问我们的安全任务,以获取有关使用安全功能的详细说明。

高级架构

Istio 中的安全性涉及多个组件:

用于密钥和证书管理的证书颁发机构(CA)

配置 API 服务器分发给代理:

认证策略授权策略
安全命名信息

Sidecar 和边缘代理作为 Policy Enforcement Points(PEPs) 以保护客户端和服务器之间的通信安全.

一组 Envoy 代理扩展,用于管理遥测和审计
控制面处理来自 API server 的配置,并且在数据面中配置 PEPs。PEPs 用 Envoy 实现。下图显示了架构。

安全架构
在下面的部分中,我们将详细介绍 Istio 安全功能。

Istio 身份

身份是任何安全基础架构的基本概念。在工作负载间通信开始时,双方必须交换包含身份信息的凭证以进行双向验 证。在客户端,根据安全命名信息检查服务器的标识,以查看它是否是该服务的授权运行程序。在服务器端,服务器可以根据授权策略确定客户端可以访问哪些信息,审计谁在什么时间访问了什么,根据他们使用的工作负载向客户收费,并拒绝任何未能支付账单的客户访问工作负载。

Istio 身份模型使用 (服务身份)来确定一个请求源端的身份。这种模型有极好的灵活性和粒
service identity
度,可以用服务身份来标识人类用户、单个工作负载或一组工作负载。在没有服务身份的平台上,Istio 可以使用其它可以对服务实例进行分组的身份,例如服务名称。

下面的列表展示了在不同平台上可以使用的服务身份:

Kubernetes: Kubernetes service account GKE/GCE: GCP service account
GCP: GCP service account
AWS: AWS IAM user/role account
本地(非 Kubernetes):用户帐户、自定义服务帐户、服务名称、Istio 服务帐户或 GCP 服务帐户。自定义服务帐户引用现有服务帐户,就像客户的身份目录管理的身份一样。

公钥基础设施 (PKI)

Istio PKI 使用 X.509 证书为每个工作负载都提供强大的身份标识。可以大规模进行自动化密钥和证书轮换,伴
随每个 Envoy 代理都运行着一个 负责证书和密钥的供应。下图显示了这个机制的运行流程。
istio-agent

译者注:这里用 来表述,是因为下图及对图的相关解读中反复用到了 “Istio agent” 这个术语,
istio-agent
istio-agent
pilot-agent

这样的描述更容易理解。 另外,在实现层面,
是指 sidecar 容器中的
进程,它有

很多功能,这里不表,只特别提一下:它通过 Unix socket 的方式在本地提供 SDS 服务供 Envoy 使用,这个信息对了解 Envoy 与 SDS 之间的交互有意义。

身份供应
Istio 供应身份是通过 secret discovery service(SDS)来实现的,具体流程如下:

  1. CA 提供 gRPC 服务以接受证书签名请求(CSRs)。
  2. Envoy 通过 Envoy 秘密发现服务(SDS)API 发送证书和密钥请求。
  3. 在收到 SDS 请求后, 创建私钥和 CSR,然后将 CSR 及其凭据发送到 Istio CA 进行签名。

istio-agent

  1. CA 验证 CSR 中携带的凭据并签署 CSR 以生成证书。
  2. 通过 Envoy SDS API 将私钥和从 Istio CA 收到的证书发送给 Envoy。

Istio-agent

  1. 上述 CSR 过程会周期性地重复,以处理证书和密钥轮换。

认证

Istio 提供两种类型的认证:

Peer authentication:用于服务到服务的认证,以验证进行连接的客户端。Istio 提供双向 TLS 作为传

输认证的全栈解决方案,无需更改服务代码就可以启用它。这个解决方案:

为每个服务提供强大的身份,表示其角色,以实现跨群集和云的互操作性。保护服务到服务的通信。
提供密钥管理系统,以自动进行密钥和证书的生成,分发和轮换。

Request authentication:用于最终用户认证,以验证附加到请求的凭据。 Istio 使用 JSON Web Token(JWT)验证启用请求级认证,并使用自定义认证实现或任何 OpenID Connect 的认证实现(例如下面列举的)来简化的开发人员体验。

ORY Hydra Keycloak Auth0 Firebase Auth Google Auth

在所有情况下,Istio 都通过自定义 Kubernetes API 将认证策略存储在 。Istiod 使每
Istio config store
个代理保持最新状态,并在适当时提供密钥。此外,Istio 的认证机制支持宽容模式(permissive mode),以帮助您了解策略更改在实施之前如何影响您的安全状况。

双向 TLS 认证

Istio 通过客户端和服务器端 PEPs 建立服务到服务的通信通道,PEPs 被实现为Envoy 代理。当一个工作负载使用双向 TLS 认证向另一个工作负载发送请求时,该请求的处理方式如下:

  1. Istio 将出站流量从客户端重新路由到客户端的本地 sidecar Envoy。
  2. 客户端 Envoy 与服务器端 Envoy 开始双向 TLS 握手。在握手期间,客户端 Envoy 还做了安全命名检查,以验证服务器证书中显示的服务帐户是否被授权运行目标服务。
  3. 客户端 Envoy 和服务器端 Envoy 建立了一个双向的 TLS 连接,Istio 将流量从客户端 Envoy 转发到服务器端 Envoy。
  4. 授权后,服务器端 Envoy 通过本地 TCP 连接将流量转发到服务器服务。
宽容模式

Istio 双向 TLS 具有一个宽容模式(permissive mode),允许服务同时接受纯文本流量和双向 TLS 流量。这个功能极大的提升了双向 TLS 的入门体验。

在运维人员希望将服务移植到启用了双向 TLS 的 Istio 上时,许多非 Istio 客户端和非 Istio 服务端通信时会产生问题。通常情况下,运维人员无法同时为所有客户端安装 Istio sidecar,甚至没有这样做的权限。即使在服务端上安装了 Istio sidecar,运维人员也无法在不中断现有连接的情况下启用双向 TLS。

启用宽容模式后,服务可以同时接受纯文本和双向 TLS 流量。这个模式为入门提供了极大的灵活性。服务中安装的Istio sidecar 立即接受双向 TLS 流量而不会打断现有的纯文本流量。因此,运维人员可以逐步安装和配置客户端 Istio sidecar 发送双向 TLS 流量。一旦客户端配置完成,运维人员便可以将服务端配置为仅 TLS 模式。更多信息请访问双向 TLS 迁移向导。

安全命名

服务器身份(Server identities)被编码在证书里,但服务名称(service names)通过服务发现或 DNS 被

检索。安全命名信息将服务器身份映射到服务名称。身份

A
到服务名称
的映射表示“授权
运行服务

“。控制平面监视

B

A

B
apiserver
命名对身份验证至关重要。
,生成安全命名映射,并将其安全地分发到 PEPs。 以下示例说明了为什么安全

假设运行服务
的合法服务器仅使用
身份。恶意用户拥有 test-team 身份的证书和密
钥。恶意用户打算模拟服务以检查从客户端发送的数据。恶意用户使用证书和 test-team 身份的密钥部署伪造服务
datastore
infra-team
器。假设恶意用户成功攻击了发现服务或 DNS,以将 服务名称映射到伪造服务器。
datastore

当客户端调用 datastore 服务时,它从服务器的证书中提取 test-team 身份,并用安全命名信息检查
test-
是否被允许运行 datastore 。客户端检测到 test-team 不允许运行 服务,认证失败。
team
datastore

安全命名能够防止 HTTPS 流量受到一般性网络劫持,除了 DNS 欺骗外,它还可以保护 TCP 流量免受一般网络劫持。如果攻击者劫持了 DNS 并修改了目的地的 IP 地址,它将无法用于 TCP 通信。这是因为 TCP 流量不包含主机名信息,我们只能依靠 IP 地址进行路由,而且甚至在客户端 Envoy 收到流量之前,也可能发生 DNS 劫持。

认证架构

您可以使用 peer 和 request 认证策略为在 Istio 网格中接收请求的工作负载指定认证要求。网格运维人员使
用 文件来指定策略。部署后,策略将保存在 Istio 配置存储中。Istio 控制器监视配置存储。
.yaml

一有任何的策略变更,新策略都会转换为适当的配置,告知 PEP 如何执行所需的认证机制。控制平面可以获取公共密钥,并将其附加到配置中以进行 JWT 验证。或者,Istiod 提供了 Istio 系统管理的密钥和证书的路径,并将它们安装到应用程序 pod 用于双向 TLS。您可以在 PKI 部分中找到更多信息。

Istio 异步发送配置到目标端点。代理收到配置后,新的认证要求会立即生效。

发送请求的客户端服务负责遵循必要的认证机制。对于 peer authentication,应用程序负责获取 JWT 凭证并将其附加到请求。对于双向 TLS,Istio 会自动将两个 PEPs 之间的所有流量升级为双向 TLS。如果认证策略禁用了双向 TLS 模式,则 Istio 将继续在 PEPs 之间使用纯文本。要覆盖此行为,请使用 destination rules 显式禁用双向 TLS 模式。您可以在双向 TLS 认证 中找到有关双向 TLS 如何工作的更多信息。

认证架构
Istio 将两种类型的身份验证以及凭证中的其他声明(如果适用)输出到下一层:授权。

认证策略

本节中提供了更多 Istio 认证策略方面的细节。正如认证架构中所说的,认证策略是对服务收到的请求生效的。要
DetinationRule
TLSSettings

在双向 TLS 中指定客户端认证策略,需要在多这方面的信息。
中设置
。TLS 设置参考文档中有更

和其他的 Istio 配置一样,可以用 .yaml 文件的形式来编写认证策略。部署策略使用
kubectl
中的认证策略要求:与带有 app:reviews 标签的工作负载的传输层认证,必须使用双向 TLS:
。 下面例子

  1. apiVersion: “security.istio.io/v1beta1”
  2. kind: “PeerAuthentication”
  3. metadata:
  4. name: “example-peer-policy”
  5. namespace: “foo”
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: reviews
  10. mtls:
  11. mode: STRICT
策略存储

Istio 将网格范围的策略存储在根命名空间。这些策略使用一个空的 selector 适用于网格中的所有工作负载。具有名称空间范围的策略存储在相应的名称空间中。它们仅适用于其命名空间内的工作负载。如果你配置了
selector
字段,则认证策略仅适用于与您配置的条件匹配的工作负载。

Peer 和 request 认证策略用 kind 字段区分,分别是 和 。
PeerAuthentication
RequestAuthentication

Selector 字段

Peer 和 request 认证策略使用 字段来指定该策略适用的工作负载的标签。以下示例显示适用于带有
selector
标签的工作负载的策略的 selector 字段:
app:product-page

  1. selector:
  2. matchLabels:
  3. app: product-page

如果您没有为 selector 字段提供值,则 Istio 会将策略与策略存储范围内的所有工作负载进行匹配。因此, selector 字段可帮助您指定策略的范围:

网格范围策略:为根名称空间指定的策略,不带或带有空的 字段。
selector
命名空间范围的策略:为非root命名空间指定的策略,不带有或带有空的 selector 字段。特定于工作负载的策略:在常规名称空间中定义的策略,带有非空 selector 字段。

Peer 和 request 认证策略对和应用它们。
selector
字段遵循相同的层次结构原则,但是 Istio 以略有不同的方式组合

只能有一个网格范围的 Peer 认证策略,每个命名空间也只能有一个命名空间范围的 Peer 认证策略。当您为同一网格或命名空间配置多个网格范围或命名空间范围的 Peer 认证策略时,Istio 会忽略较新的策略。当多个特定于工作负载的 Peer 认证策略匹配时,Istio 将选择最旧的策略。

Istio 按照以下顺序为每个工作负载应用最窄的匹配策略:

  1. 特定于工作负载的
  2. 命名空间范围
  3. 网格范围

Istio 可以将所有匹配的 request 认证策略组合起来,就像它们来自单个 request 认证策略一样。因此,您可以在网格或名称空间中配置多个网格范围或命名空间范围的策略。但是,避免使用多个网格范围或命名空间范围的request 认证策略仍然是一个好的实践。

Peer authentication

Peer 认证策略指定 Istio 对目标工作负载实施的双向 TLS 模式。支持以下模式:

PERMISSIVE:工作负载接受双向 TLS 和纯文本流量。此模式在迁移因为没有 sidecar 而无法使用双向TLS 的工作负载的过程中非常有用。一旦工作负载完成 sidecar 注入的迁移,应将模式切换为 STRICT。STRICT: 工作负载仅接收双向 TLS 流量。
DISABLE:禁用双向 TLS。 从安全角度来看,除非您提供自己的安全解决方案,否则请勿使用此模式。

如果未设置模式,将继承父作用域的模式。未设置模式的网格范围的 peer 认证策略默认使用 模式。
PERMISSIVE

下面的 peer 认证策略要求命名空间 中的所有工作负载都使用双向 TLS:
foo

  1. apiVersion: “security.istio.io/v1beta1”
  2. kind: “PeerAuthentication”
  3. metadata:
  4. name: “example-policy”
  5. namespace: “foo”
  6. spec:
  7. mtls:
  8. mode: STRICT

对于特定于工作负载的 peer 认证策略,可以为不同的端口指定不同的双向 TLS 模式。您只能将工作负载声明过的

端口用于端口范围的双向 TLS 配置。以下示例为
app:example-app
有其他端口使用名称空间范围的 peer 认证策略的双向 TLS 设置:
工作负载禁用了端口80上的双向TLS,并对所

  1. apiVersion: “security.istio.io/v1beta1”

  2. kind: “PeerAuthentication”

  3. metadata:

  4. name: “example-workload-policy”

  5. namespace: “foo”

  6. spec:

  7. selector:

  8. matchLabels:

  9. app: example-app

  10. portLevelMtls: 11. 80:

  11. mode: DISABLE

上面的 peer 认证策略仅在有如下 Service 定义时工作,将流向 服务的请求绑定到
example-service
工作负载的 端口
example-app

80

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: example-service
  5. namespace: foo
  6. spec:
  7. ports:
    • name: http 9. port: 8000
  8. protocol: TCP
  9. targetPort: 80
  10. selector:
  11. app: example-app
Request authentication

Request 认证策略指定验证 JSON Web Token(JWT)所需的值。 这些值包括:

token 在请求中的位置请求的 issuer
公共 JSON Web Key Set(JWKS)

Istio 会根据 request 认证策略中的规则检查提供的令牌(如果已提供),并拒绝令牌无效的请求。当请求不带有令牌时,默认情况下将接受它们。要拒绝没有令牌的请求,请提供授权规则,该规则指定对特定操作(例如,路径或操作)的限制。

如果 Request 认证策略使用唯一的位置,则它们可以指定多个JWT。当多个策略与工作负载匹配时,Istio 会将所有规则组合起来,就好像它们被指定为单个策略一样。此行为对于开发接受来自不同 JWT 提供者的工作负载时很有用。但是,不支持具有多个有效 JWT 的请求,因为此类请求的输出主体未定义。

Principals

使用 peer 认证策略和双向 TLS 时,Istio 将身份从 peer 认证提取到 source.principal 中。同样,当您使用 request 认证策略时,Istio 会将 JWT 中的身份赋值给 request.auth.principal 。使用这些 principals 设置授权策略和作为遥测的输出。

更新认证策略

您可以随时更改认证策略,Istio 几乎实时将新策略推送到工作负载。但是,Istio 无法保证所有工作负载都同时收到新政策。以下建议有助于避免在更新认证策略时造成干扰:

将 peer 认证策略的模式从
更改为
时,请使用
模式来过渡,反之亦然。

当所有工作负载成功切换到所需模式时,您可以将策略应用于最终模式。您可以使用 Istio 遥测技术来验证工作负载已成功切换。
DISABLE
STRICT
PERMISSIVE
将 request 认证策略从一个 JWT 迁移到另一个 JWT 时,将新 JWT 的规则添加到该策略中,而不删除旧规则。这样,工作负载接受两种类型的 JWT,当所有流量都切换到新的 JWT 时,您可以删除旧规则。但是, 每个 JWT 必须使用不同的位置。

授权

Istio 的授权功能为网格中的工作负载提供网格、命名空间和工作负载级别的访问控制。这种控制层级提供了以下优点:

工作负载间和最终用户到工作负载的授权。
一个简单的 API:它包括一个单独的并且很容易使用和维护的

CRD。

灵活的语义:运维人员可以在 Istio 属性上定义自定义条件,并使用 DENY 和 ALLOW 动作。高性能:Istio 授权是在 Envoy 本地强制执行的。
AuthorizationPolicy
高兼容性:原生支持 HTTP、HTTPS 和 HTTP2,以及任意普通 TCP 协议。

授权架构

每个 Envoy 代理都运行一个授权引擎,该引擎在运行时授权请求。当请求到达代理时,授权引擎根据当前授权策略
ALLOW
DENY
.yaml

评估请求上下文,并返回授权结果
或 。 运维人员使用
文件指定 Istio 授权策略。

授权架构

隐式启用

您无需显式启用 Istio 的授权功能。只需将授权策略应用于工作负载即可实施访问控制。对于未应用授权策略的工作负载,Istio 不会执行访问控制,放行所有请求。

授权策略支持 和 动作。 拒绝策略优先于允许策略。如果将任何允许策略应用于工作负载,则默
ALLOW
DENY
认情况下将拒绝对该工作负载的访问,除非策略中的规则明确允许。当您将多个授权策略应用于相同的工作负载时,
Istio 会累加地应用它们。

授权策略

要配置授权策略,请创建一个
AuthorizationPolicy
(action) 和一个规则(rules)列表:
自定义资源。 一个授权策略包括选择器(selector),动作

selector 字段指定策略的目标action 字段指定允许还是拒绝请求rules 指定何时触发动作
rules 下的 from 字段指定请求的来源

rules 下的 to 字段指定请求的操作
rules 下的 when 字段指定应用规则所需的条件

以下示例显示了一个授权策略,该策略允许两个源(服务帐号 cluster.local/ns/default/sa/sleep 和命名空间dev ),在使用有效的 JWT 令牌发送请求时,可以访问命名空间 foo 中的带有标签 app: httpbin 和version: v1 的工作负载。

  1. apiVersion: security.istio.io/v1beta1

  2. kind: AuthorizationPolicy

  3. metadata:

  4. name: httpbin

  5. namespace: foo

  6. spec:

  7. selector:

  8. matchLabels:

  9. app: httpbin

  10. version: v1

  11. action: ALLOW

  12. rules:

    • from:
    • source:
  13. principals: [“cluster.local/ns/default/sa/sleep”]

    • source:
  14. namespaces: [“dev”]

  15. to:

    • operation:
  16. methods: [“GET”]

  17. when:

    • key: request.auth.claims[iss]
  18. values: [“https://accounts.google.com”]

下例显示了一个授权策略,如果请求来源不是命名空间 ,请求将被拒绝。
foo

  1. apiVersion: security.istio.io/v1beta1
  2. kind: AuthorizationPolicy
  3. metadata:
  4. name: httpbin-deny
  5. namespace: foo
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: httpbin
  10. version: v1
  11. action: DENY
  12. rules:
    • from:
    • source:
  13. notNamespaces: [“foo”]

拒绝策略优先于允许策略。如果请求同时匹配上允许策略和拒绝策略,请求将被拒绝。Istio 首先评估拒绝策略,以确保允许策略不能绕过拒绝策略

策略目标

您可以通过
字段和可选的
字段来指定策略的范围或目标。

告诉该策略适用于哪个命名空间。如果将其值设置为根名称空间,则该策略将应用于网格中的所有名称空间。根命名
metadata/namespace
selector
metadata/namespace
istio-system

空间的值是可配置的,默认值为间。
。如果设置为任何其他名称空间,则该策略仅适用于指定的名称空

您可以使用 selector 字段来进一步限制策略以应用于特定工作负载。 使用标签选择目标工作负
selector
载。 slector 包含 {key: value} 对的列表,其中 是标签的名称。如果未设置,则授权策略将应用于与
key

授权策略相同的命名空间中的所有工作负载。
default
app: products
“GET”

以下示例策略
allow-read
访问。
“HEAD”
允许对
命名空间中带有标签
的工作负载的 和

  1. apiVersion: security.istio.io/v1beta1
  2. kind: AuthorizationPolicy
  3. metadata:
  4. name: allow-read
  5. namespace: default
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: products
  10. action: ALLOW
  11. rules:
    • to:
    • operation:
  12. methods: [“GET”, “HEAD”]
值匹配

授权策略中的大多数字段都支持以下所有匹配模式:

完全匹配:即完整的字符串匹配。
前缀匹配: “" 结尾的字符串。例如, "test.abc.” 匹配

“test.abc.com” 、 、 “test.abc.org” 等等。
“test.abc.com.cn”
后缀匹配: “" 开头的字符串。例如, ".abc.com” 匹配 “eng.abc.com” 、 “test.eng.abc.com” 等等。 存在匹配: * 用于指定非空的任意内容。您可以使用格式 fieldname: [“*”] 指定必须存在的字段。这意味着该字段可以匹配任意内容,但是不能为空。请注意这与不指定字段不同,后者意味着包括空的任意内容。
有一些例外。 例如,以下字段仅支持完全匹配:

when 部分下的 key 字段source 部分下 的 ipBlocks to 部分下的 ports 字段
*/info

以下示例策略允许访问前缀为
/test/*
或后缀为
的路径。

  1. apiVersion: security.istio.io/v1beta1

  2. kind: AuthorizationPolicy

  3. metadata:

  4. name: tester

  5. namespace: default

  6. spec:

  7. selector:

  8. matchLabels:

  9. app: products

  10. action: ALLOW

  11. rules:

    • to:
  • operation:
    paths: [“/test/", "/info”]
排除匹配

为了匹配诸如
字段中的
, 字段中的
, 字段中的

之类的否定条件,Istio 支持排除匹配。
when
notValues
source
notIpBlocks
to
notPorts
以下示例:如果请求路径不是 /healthz ,则要求从请求的 JWT 认证中导出的主体是有效的。 因此,该策略从
JWT 身份验证中排除对 /healthz 路径的请求:

  1. apiVersion: security.istio.io/v1beta1
  2. kind: AuthorizationPolicy
  3. metadata:
  4. name: disable-jwt-for-healthz
  5. namespace: default
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: products
  10. action: ALLOW
  11. rules:
    • to:
    • operation:
  12. notPaths: [“/healthz”]
  13. from:
    • source:
  14. requestPrincipals: [“*”]

下面的示例拒绝到 路径且不带请求主体的请求:
/admin

  1. apiVersion: security.istio.io/v1beta1
  2. kind: AuthorizationPolicy
  3. metadata:
  4. name: enable-jwt-for-admin
  5. namespace: default
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: products
  10. action: DENY
  11. rules:
    • to:
    • operation:
  12. paths: [“/admin”]
  13. from:
    • source:
  14. notRequestPrincipals: [“*”]
全部允许和默认全部拒绝授权策略

以下示例显示了一个简单的
allow-all
授权策略,该策略允许完全访问
命名空间中的所有工作负载。

default

  1. apiVersion: security.istio.io/v1beta1

  2. kind: AuthorizationPolicy

  3. metadata:

  4. name: allow-all

  5. namespace: default

  6. spec:

  7. action: ALLOW

  8. rules:

    • {}

以下示例显示了一个策略,该策略不允许任何对 命名空间工作负载的访问。
admin

  1. apiVersion: security.istio.io/v1beta1
  2. kind: AuthorizationPolicy
  3. metadata:
  4. name: deny-all
  5. namespace: admin
  6. spec: 7. {}
自定义条件

您还可以使用 when 部分指定其他条件。 例如,下面的 定义包括以下条
AuthorizationPolicy
件: request.headers [version] 是 或 。 在这种情况下,key 是 ,它

v1
v2
request.headers [version]
是 Istio 属性 request.headers (是个字典)中的一项。

  1. apiVersion: security.istio.io/v1beta1
  2. kind: AuthorizationPolicy
  3. metadata:
  4. name: httpbin
  5. namespace: foo
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: httpbin
  10. version: v1
  11. action: ALLOW
  12. rules:
    • from:
    • source:
  13. principals: [“cluster.local/ns/default/sa/sleep”]
  14. to:
    • operation:
  15. methods: [“GET”]
  16. when:
    • key: request.headers[version] 21. values: [“v1”, “v2”]

条件页面中列出了支持的条件 值。
key

认证与未认证身份

如果要使工作负载可公开访问,则需要将作负载的源,例如:
source
部分留空。这允许来自所有(经过认证和未经认证)的用户和工

  1. apiVersion: security.istio.io/v1beta1
  2. kind: AuthorizationPolicy
  3. metadata:
  4. name: httpbin
  5. namespace: foo
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: httpbin
  10. version: v1
  11. action: ALLOW
  12. rules:
    • to:
    • operation:
  13. methods: [“GET”, “POST”]

要仅允许经过认证的用户,请将
principal
设置为
,例如:

“*”

  1. apiVersion: security.istio.io/v1beta1
  2. kind: AuthorizationPolicy
  3. metadata:
  4. name: httpbin
  5. namespace: foo
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: httpbin
  10. version: v1
  11. action: ALLOW
  12. rules:
    • from:
    • source:
  13. principals: [“*”]
  14. to:
    • operation:
  15. methods: [“GET”, “POST”]

在普通 TCP 协议上使用 Istio 授权

Istio 授权支持工作负载使用任意普通 TCP 协议,如 MongoDB。 在这种情况下,您可以按照与 HTTP 工作负载相同的方式配置授权策略。 不同之处在于某些字段和条件仅适用于 HTTP 工作负载。 这些字段包括:

授权策略对象 部分中的 字段
source
request_principals

授权策略对象
operation
部分中的 、
和 字段

条件页面中列出了支持的条件。
hosts
methods
paths
如果您在授权策略中对 TCP 工作负载使用了任何只适用于 HTTP 的字段,Istio 将会忽略它们。
假设您在端口 27017 上有一个 MongoDB 服务,下例配置了一个授权策略,只允许 Istio 网格中的
bookinfo-ratings-v2 服务访问该 MongoDB 工作负载。

  1. apiVersion: “security.istio.io/v1beta1”

  2. kind: AuthorizationPolicy

  3. metadata:

  4. name: mongodb-policy

  5. namespace: default

  6. spec:

  7. selector:

  8. matchLabels:

  9. app: mongodb

  10. action: ALLOW

  11. rules:

    • from:
    • source:
  12. principals: [“cluster.local/ns/default/sa/bookinfo-ratings-v2”]

  13. to:

    • operation:
  14. ports: [“27017”]

对双向 TLS 的依赖

Istio 使用双向 TLS 将某些信息从客户端安全地传递到服务器。在使用授权策略中的以下任何字段之前,必须先启用双向 TLS:

source 部分下的 字段
principals

namespaces
source 部分下的 字段source.principal 自定义条件source.namespace 自定义条件connection.sni 自定义条件

如果您不使用授权策略中的上述任何字段,则双向 TLS 不是必须的。

相关内容

HTTP 流量授权
展示如何设置基于角色的 HTTP 流量访问控制。
TCP 流量的授权
展示如何设置 TCP 流量的访问控制。

授权策略信任域迁移
阐述如何在不更改授权策略的前提下从一个信任域迁移到另一个。基于 Istio 授权的 Micro-Segmentation
描述 Istio 的授权功能以及如何在各种用例中使用它。
Istio v1beta1 授权策略概述
Istio v1beta1 授权策略的设计原则、基本概述及迁移操作。
APP 身份和访问适配器
使用 Istio 实现零代码改动保护多云 Kubernetes 应用。

可观察性

Istio 为网格内所有的服务通信生成详细的遥测数据。这种遥测技术提供了服务行为的可观察性,使运维人员能够排查故障、维护和优化应用程序,而不会给服务的开发人员带来任何额外的负担。通过 Istio,运维人员可以全面了解到受监控的服务如何与其他服务以及 Istio 组件进行交互。

Istio 生成以下类型的遥测数据,以提供对整个服务网格的可观察性:

指标。Istio 基于 4 个监控的黄金标识(延迟、流量、错误、饱和)生成了一系列服务指标。Istio 还为网格控制平面提供了更详细的指标。除此以外还提供了一组默认的基于这些指标的网格监控仪表板。
分布式追踪。Istio 为每个服务生成分布式追踪 span,运维人员可以理解网格内服务的依赖和调用流程。访问日志。当流量流入网格中的服务时,Istio 可以生成每个请求的完整记录,包括源和目标的元数据。此信息使运维人员能够将服务行为的审查控制到单个工作负载实例的级别。

指标

指标(Metric)提供了一种以聚合的方式监控和理解行为的方法。

为了监控服务行为,Istio 为服务网格中所有出入的服务流量都生成了指标。这些指标提供了关于行为的信息,例如总流量数、错误率和请求响应时间。

除了监控网格中服务的行为外,监控网格本身的行为也很重要。Istio 组件可以导出自身内部行为的指标,以提供对网格控制平面的功能和健康情况的洞察能力。

Istio 指标收集由运维人员配置来驱动。运维人员决定如何以及何时收集指标,以及指标本身的详细程度。这使得它能够灵活地调整指标收集来满足个性化需求。

代理级别指标

Istio 指标收集从 sidecar 代理(Envoy)开始。每个代理为通过它的所有流量(入站和出站)生成一组丰富的指标。代理还提供关于它本身管理功能的详细统计信息,包括配置信息和健康信息。

Envoy 生成的指标提供了资源(例如监听器和集群)粒度上的网格监控。因此,为了监控 Envoy 指标,需要了解网格服务和 Envoy 资源之间的连接。

Istio 允许运维人员在每个工作负载实例上选择生成和收集哪个 Envoy 指标。默认情况下,Istio 只支持Envoy 生成的统计数据的一小部分,以避免依赖过多的后端服务,还可以减少与指标收集相关的 CPU 开销。然而, 运维人员可以在需要时轻松地扩展收集到的代理指标集。这支持有针对性地调试网络行为,同时降低了跨网格监控的 总体成本。

Envoy 文档包括了 Envoy 统计信息收集的详细说明。Envoy 统计里的操作手册提供了有关控制代理级别指标生成的更多信息。

代理级别指标的例子:

  1. envoy_cluster_internal_upstream_rq{response_code_class=“2xx”,cluster_name=“xds-grpc”} 7163 2.

  2. envoy_cluster_upstream_rq_completed{cluster_name=“xds-grpc”} 7164 4.

  3. envoy_cluster_ssl_connection_error{cluster_name=“xds-grpc”} 0 6.

  4. envoy_cluster_lb_subsets_removed{cluster_name=“xds-grpc”} 0 8.

  5. envoy_cluster_internal_upstream_rq{response_code=“503”,cluster_name=“xds-grpc”} 1

服务级别指标

除了代理级别指标之外,Istio 还提供了一组用于监控服务通信的面向服务的指标。这些指标涵盖了四个基本的服务监控需求:延迟、流量、错误和饱和情况。Istio 带有一组默认的仪表板,用于监控基于这些指标的服务行为。

默认的 Istio 指标由 Istio 提供的配置集定义并默认导出到 Prometheus。运维人员可以自由地修改这些指标的形态和内容,更改它们的收集机制,以满足各自的监控需求。

收集指标任务为定制 Istio 指标生成提供了更详细的信息。
服务级别指标的使用完全是可选的。运维人员可以选择关闭指标的生成和收集来满足自身需要。服务级别指标的例子:

  1. istio_requests_total{
  2. connection_security_policy=“mutual_tls”,
  3. destination_app=“details”,
  4. destination_principal=“cluster.local/ns/default/sa/default”,
  5. destination_service=“details.default.svc.cluster.local”,
  6. destination_service_name=“details”,
  7. destination_service_namespace=“default”,
  8. destination_version=“v1”,
  9. destination_workload=“details-v1”,
  10. destination_workload_namespace=“default”,
  11. reporter=“destination”,
  12. request_protocol=“http”,
  13. response_code=“200”,
  14. response_flags=“-”,
  15. source_app=“productpage”,
  16. source_principal=“cluster.local/ns/default/sa/default”,
  17. source_version=“v1”,
  18. source_workload=“productpage-v1”,
  19. source_workload_namespace=“default” 20. } 214

控制平面指标

每一个 Istio 的组件(Pilot、Galley、Mixer)都提供了对自身监控指标的集合。这些指标容许监控 Istio
自己的行为(这与网格内的服务有所不同)。
有关这些被维护指标的更多信息,请查看每个组件的参考文档:

Pilot Galley Mixer Citadel

分布式追踪

分布式追踪通过监控流经网格的单个请求,提供了一种监控和理解行为的方法。追踪使网格的运维人员能够理解服务的依赖关系以及在服务网格中的延迟源。

Istio 支持通过 Envoy 代理进行分布式追踪。代理自动为其应用程序生成追踪 span,只需要应用程序转发适当的请求上下文即可。

Istio 支持很多追踪系统,包括 Zipkin、Jaeger、LightStep、Datadog。运维人员控制生成追踪的采样率
(每个请求生成跟踪数据的速率)。这允许运维人员控制网格生成追踪数据的数量和速率。更多关于 Istio 分布式追踪的信息可以在分布式追踪 FAQ 中找到。
Istio 为一个请求生成的分布式追踪数据:

Distributed Trace for a single request

访问日志

访问日志提供了一种从单个工作负载实例的角度监控和理解行为的方法。

Istio 可以以一组可配置的格式集生成服务流量的访问日志,为运维人员提供日志记录的方式、内容、时间和位置的完全控制。Istio 向访问日志机制暴露了完整的源和目标元数据,允许对网络通信进行详细的审查。

访问日志可以在本地生成,或者导出到自定义的后端基础设施,包括 Fluentd。更多关于访问日志的内容在收集日志和获取 Envoy 服务日志任务中提供。Istio 访问日志例子(JSON 格式):

{“level”:“info”,“time”:“2019-06-11T20:57:35.424310Z”,“instance”:“accesslog.instance.istio- control”,“connection_security_policy”:“mutual_tls”,“destinationApp”:“productpage”,“destinationIp”:“10.44.2.15”," pvsnd",“destinationNamespace”:“default”,“destinationOwner”:“kubernetes://apis/apps/v1/namespaces/default/deploym v1”,“destinationPrincipal”:“cluster.local/ns/default/sa/default”,“destinationServiceHost”:“productpage.default.s v1”,“httpAuthority”:“35.202.6.119”,“latency”:“35.076236ms”,“method”:“GET”,“protocol”:“http”,“receivedBytes”:917, 5642-434d-ae75-233a05b06158",“requestSize”:0,“requestedServerName”:"outbound_.9080_._.productpage.default.svc.cl ",“responseSize”:4183,“responseTimestamp”:“2019-06-11T20:57:35.459150Z”,“sentBytes”:4328,“sourceApp”:“istio- ingressgateway”,“sourceIp”:“10.44.0.8”,“sourceName”:“ingressgateway-7748774cbf-bvf4j”,“sourceNamespace”:“istio- control”,“sourceOwner”:“kubernetes://apis/apps/v1/namespaces/istio-control/deployments/ingressgateway”,"sourcePr

  1. control/sa/default",“sourceWorkload”:“ingressgateway”,“url”:“/productpage”,“userAgent”:“curl/7.54.0”,"xForwarded

相关内容

Mixer 配置模型
描述 Istio 策略执行和遥测机制的配置模型。
Mixer 和 SPOF 神话提高可用,降低延迟。Mixer 适配器模型
概要说明 Mixer 的插件架构。
TLS Egress 监控和策略配置
描述如何在 TLS Egress 上配置 SNI 监控和策略。
APP 身份和访问适配器
使用 Istio 实现零代码改动保护多云 Kubernetes 应用。
Denials 和黑白名单
描述如何使用简单的 denials 或黑白名单来控制对服务的访问。

安装

关于如何在 Kubernetes 集群中安装 Istio 控制平面和添加虚拟机到 mesh 中的说明。

开始

下载、安装并学习如何快速使用 Istio 的基本特性。

平台安装

在安装 Istio 之前如何准备各种 Kubernetes 平台。

安装指南

选择最适合您的需求和平台的指南。

升级

选择与您先前用于安装 Istio 的方法相对应的升级指南。

更多指南

有关其他设置任务的更多信息。

开始

本指南面向 Istio 的新用户,让您通过安装 配置文件快速评估 Istio。
demo

如果您已经熟悉 Istio 或对安装其他配置文件或更高级的部署模型感兴趣, 请遵循使用 istioctl 的安装说明文档。

此 demo 配置文件不适用于性能评估。它旨在展示 Istio 高水平跟踪和访问日志的功能。要开始使用 Istio,只需遵循以下三个步骤:

  1. 搭建平台
  2. 下载 Istio
  3. 安装 Istio

搭建平台

在安装 Istio 之前,需要一个运行着 Kubernetes 的兼容版本的 cluster。Istio 1.6 已经在 Kubernetes 版本 1.15, 1.16, 1.17, 1.18 中测试过。
通过选择合适的 platform-specific setup instructions 来创建一个集群。

有些平台提供了 managed control plane,您可以使用它来代替手动安装 Istio。如果您选择的平台支持这种方式,并且您选择使用它,那么,在创建完集群后,您将完成 Istio 的安装。因此,可以跳过以下说明。

下载 Istio

下载 Istio,下载内容将包含:安装文件、示例和 istioctl 命令行工具。

  1. 访问 Istio release 页面下载与您操作系统对应的安装文件。在 macOS 或 Linux 系统中,也可以通过以下命令下载最新版本的 Istio:

  2. $ curl -L https://istio.io/downloadIstio | sh -

  3. 切换到 Istio 包所在目录下。例如:Istio 包名为 ,则:

istio-1.6.0

  1. $ cd istio-1.6.0

安装目录包含如下内容:

install/kubernetes 目录下,有 Kubernetes 相关的 YAML 安装文件
samples/ 目录下,有示例应用程序
istioctl
istioctl
bin/ 目录下,包含理。
的客户端文件。
工具用于手动注入 Envoy sidecar 代

  1. 将 客户端路径增加到 path 环境变量中,macOS 或 Linux 系统的增加方式如下:

istioctl

  1. $ export PATH= P W D / b i n : PWD/bin: PWD/bin:PATH

  2. 在使用 bash 或 ZSH 控制台时,可以选择启动 auto-completion option。

安装 Istio

请按照以下步骤在您所选的平台上使用 配置文件安装 Istio。
demo

  1. 安装 配置

demo

  1. $ istioctl manifest apply --set profile=demo

  2. 为了验证是否安装成功,需要先确保以下 Kubernetes 服务正确部署,然后验证除 服务外

jaeger-agent
的其他服务,是否均有正确的 :

  1. $ kubectl get svc -n istio-system
    15020:31831/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:30318/TCP,15030:32645/TCP,15031:31933/TCP

  2. 2m

istio-pilot ClusterIP 172.21.105.205 15010/TCP,15011/TCP,8080/TCP,15014/TCP

  1. 2m

istio-policy

  1. 2m

istio-sidecar-injector

  1. 2m

istio-telemetry
ClusterIP
172.21.14.236
9091/TCP,15004/TCP,15014/TCP
ClusterIP
172.21.155.47

443/TCP,15014/TCP
ClusterIP
172.21.196.79

9091/TCP,15004/TCP,15014/TCP,42422/TCP
11. 2m
CLUSTER-IP

| NAME

2. AGETYPECLUSTER-IPEXTERNAL-IPPORT(S)
grafanaClusterIP172.21.211.1233000/TCP
3. 2m
istio-citadelClusterIP172.21.177.2228060/TCP,15014/TCP
4. 2m
istio-egressgatewayClusterIP172.21.113.2480/TCP,443/TCP,15443/TCP
5. 2m
istio-galleyClusterIP172.21.132.247443/TCP,15014/TCP,9901/TCP
6. 2m
istio-ingressgatewayLoadBalancer172.21.144.25452.116.22.242
jaeger-agentClusterIPNone5775/UDP,6831/UDP,6832/UDP
12. 2m
jaeger-collectorClusterIP172.21.135.5114267/TCP,14268/TCP
13. 2m
jaeger-queryClusterIP172.21.26.18716686/TCP
14. 2m
kialiClusterIP172.21.155.20120001/TCP
15. 2m
prometheusClusterIP172.21.63.1599090/TCP
16. 2m
tracingClusterIP172.21.2.24580/TCP
17. 2m
zipkinClusterIP172.21.182.2459411/TCP
18. 2m

如果集群运行在一个不支持外部负载均衡器的环境中(例如:minikube), 的
istio-ingressgateway

NodePort

将显示为
EXTERNAL-IP
状态。请使用服务的
或 端口转发来访问网关。

请确保关联的 Kubernetes pod 已经部署,并且 为 :
STATUS
Running

1. $ kubectl get pods -n istio-system
2. NAMEREADYSTATUSRESTARTSAGE
3. grafana-f8467cc6-rbjlg1/1Running01m
4. istio-citadel-78df5b548f-g5cpw1/1Running01m
5. istio-egressgateway-78569df5c4-zwtb51/1Running01m
6. istio-galley-74d5f764fc-q7nrk1/1Running01m
7. istio-ingressgateway-7ddcfd665c-dmtqz1/1Running01m
8. istio-pilot-f479bbf5c-qwr281/1Running01m
9. istio-policy-6fccc5c868-xhblv1/1Running21m
10. istio-sidecar-injector-78499d85b8-x44m61/1Running01m
11. istio-telemetry-78b96c6cb6-ldm9q1/1Running21m
12. istio-tracing-69b5f778b7-s2zvw1/1Running01m
13. kiali-99f7467dc-6rvwp1/1Running01m
14. prometheus-67cdb66cbb-9w2hm1/1Running01m

后续步骤

安装 Istio 后,就可以部署您自己的服务,或部署安装程序中系统的任意一个示例应用。应用程序必须使用 HTTP/1.1 或 HTTP/2.0 协议用于 HTTP 通信;HTTP/1.0 不支持。
kubectl apply
istio-injection=enabled

当使用
来部署应用时,如果 pod 启动在标有
的命名空间中,那么,

Istio sidecar 注入器将自动注入 Envoy 容器到应用的 pod 中:
istioctl kube-inject

  1. $ kubectl label namespace istio-injection=enabled
  2. $ kubectl create -n -f .yaml

在没有
istio-injection
动注入到应用的 pod 中:
标记的命名空间中,在部署前可以使用
命令将 Envoy 容器手

  1. $ istioctl kube-inject -f .yaml | kubectl apply -f -

如果您不确定要从哪开始,可以先部署 Bookinfo 示例,它会让您体验到 Istio 的流量路由、故障注入、速率限制等功能。 然后您可以根据您的兴趣浏览各种各样的 Istio 任务。

下列任务都是初学者开始学习的好入口:

请求路由 故障注入 流量转移 查询指标 可视化指标

日志收集速率限制
Ingress 网关访问外部服务 可视化您的网格

下一步,可以定制 Istio 并部署您自己的应用。在您开始自定义 Istio 来适配您的平台或者其他用途之前,请查看以下资源:

部署模型
部署最佳实践
Pod 需求
常规安装说明
使用 Istio 过程中有任何问题,请来信告知我们,并欢迎您加入我们的社区。

卸载

卸载程序将删除 RBAC 权限、它们可能已经被删除掉了。
istio-system
命名空间和所有相关资源。可以忽略那些不存在的资源的报错,因为

  1. $ istioctl manifest generate --set profile=demo | kubectl delete -f -

相关内容

Helm 变更
关于 Istio 1.1 和 Istio 1.2 之间的 Helm chart 安装选项的变更。
Helm 安装参数变动表
本文详细介绍了 Istio 1.0 系列到 Istio 1.1 系列之间的安装参数变化详情。
Helm 安装参数变动表
本文详细介绍了 Istio 1.2 系列到 Istio 1.3 系列之间的安装参数变化详情。
DNS 证书管理
在 Istio 中配置和管理 DNS 证书。
Istio Operator 简介
关于 Istio 基于 operator 的安装和控制平面管理特性的介绍。安全管理 Webhook
一种更安全管理 Istio webhook 的方法。

平台安装

在安装 Istio 之前如何准备各种 Kubernetes 平台。

阿里云

对阿里云 Kubernetes 集群进行配置以便安装运行 Istio。

Azure

为 Istio 设置一个 Azure 集群的指令。

Docker Desktop

在 Docker Desktop 中运行 Istio 的设置说明。

使用 Google Kubernetes Engine 快速开始

在 Google Kubernetes Engine (GKE) 上快速搭建 Istio 服务。

IBM Cloud 快速开始

在 IBM 公有云或私有云上快速搭建 Istio 服务。

kind

为 Istio 设置 kind 的说明。

Kubernetes Gardener 快速开始

使用 Gardener 快速搭建 Istio 服务。

MicroK8s

配置 MicroK8s 以便使用 Istio。

Minikube

在 Minikube 上配置 Istio。

OpenShift

对 OpenShift 集群进行配置以便安装运行 Istio。

Oracle Cloud Infrastructure

为 Istio 配置 OKE 集群环境的说明。
Istio 1.6 已在以下 Kubernetes 发现版下测试:1.15, 1.16, 1.17, 1.18。

阿里云

按照以下说明配置 阿里云 Kubernetes 容器服务 集群以便安装运行 Istio。 你可以在阿里云的 容器服务管理控制台 中快速简单的部署一个完全支持 Istio 的 Kubernetes 集群。

你也可以按照 阿里云应用目录说明 在阿里云 Kubernetes 容器服务中使用 应用目录 服务来安装配置 Istio。

前置条件

  1. 按照阿里云说明启用以下服务:容器服务、资源编排服务(ROS)和 RAM。

步骤

  1. 登陆 容器服务管理控制台 ,点击左边导航栏中 **Kubernetes **下的 集群 进入到 集群列表 页面。
  2. 点击右上角的 创建 **Kubernetes **集群 按钮。
  3. 输入集群名称。集群名称可以是长度为 1–63 个字符,可以包含数字、中文字符、英文字母和连字符 (-) 。
  4. 选择集群所在到 **region **和 zone
  5. 设置集群网络类型。Kubernetes 集群现在只支持 VPC 的网络类型。
  6. 配置节点类型。支持按量付费和包年包月。
  7. 配置主节点。为主节点选择实例规格。
  8. 配置工作节点。选择是否创建工作节点或添加现有 ECS 实例作为工作节点。
  9. 配置登录模式,配置 POD 网络 CIDR 和 Service CIDR 。下图显示了完成前面所有步骤的界面:

Console

Azure

跟随这些指令来为 Istio 准备一个 Azure 集群。
你可以通过完全支持 Istio 的 AKS 或者 AKS-Engine,部署一个 Kubernetes 集群到 Azure 上。

AKS

你可以通过 the az cli 或者 the Azure portal 创建一个 AKS 集群。

对于 cli 的选项,完成 认证或者使用 cloud shell,然后运行下面的命令。
az
az login

  1. 确定支持 AKS 的期望 region 名

$ az provider list --query "[?namespace==‘Microsoft.ContainerService’].resourceTypes[] | [?

  1. resourceType==‘managedClusters’].locations[]" -o tsv

  2. 证实对于期望的 region 有支持的 Kubernetes 版本

使用从上面步骤中期望的 region 值替换 ,然后执行:
my location

  1. $ az aks get-versions --location “my location” --query “orchestrators[].orchestratorVersion”

确保最小值 被列出。
1.10.5

  1. 创建 resource group 和部署 AKS 集群

使用期望的名字替换
和 ,使用第一步中的名字替换
,替换
如果其在 region 中不被支持,然后执行:
myResourceGroup
myAKSCluster
mylocation
1.10.5

  1. $ az group create --name myResourceGroup --location “my location”

$ az aks create --resource-group myResourceGroup --name myAKSCluster --node-count 3 --kubernetes-version

  1. 1.10.5 --generate-ssh-keys

  2. 取得 AKS 证书

kubeconfig

使用从之前步骤中获得的名字替换 和 并且执行:
myResourceGroup
myAKSCluster

  1. $ az aks get-credentials --resource-group myResourceGroup --name myAKSCluster

AKS-Engine

  1. 跟随这些命令来获取和安装 的二进制版本。

aks-engine

  1. 下载支持部署 Istio 的 API 模型定义:

aks-engine

Docker Desktop

  1. 如果你想在 Docker Desktop 下运行 Istio,则需要安装受支持的 Kubernetes 版本 (1.15, 1.16, 1.17, 1.18)。

  2. 如果你想在 Docker Desktop 内置的 Kubernetes 下运行 Istio,你可能需要在 Docker 首选项的

Advanced 面板下增加 Docker 的内存限制。设置可用的内存资源为 8.0 以及 4 核心 .

GB
CPUs

Docker Preferences

最低内存的要求不尽相同。8 足以运行 Istio 和 Bookinfo 实例。如果你没有足够的内存用于
GB
Docker Desktop, 则可能发生以下错误:

镜像拉取失败
健康检查超时失败
宿主上 kubectl 运行失败虚拟机管理程序的网络不稳定

为 Docker Desktop 释放出更多可用资源:

  1. $ docker system prune

使用 Google Kubernetes Engine 快速开始

Google 为 GKE 提供了一个插件, 您可以使用它来代替手动安装 Istio。 要确定该插件是否适合您,请参阅
Istio on GKE 以获得更多信息。
依照以下操作指南为安装 Istio 准备一个 GKE 集群。
需要在 Istio 中启用秘钥发现服务(SDS),请使用 Kubernetes 1.13 或更高版本。

  1. 创建一个新集群。

  2. $ gcloud container clusters create \

  3. –cluster-version latest \

  4. –machine-type=n1-standard-2 \

  5. –num-nodes 4 \

  6. –zone \

  7. –project

默认安装 Mixer 要求节点的 vCPU 大于 1。 如果您要使用演示配置文件, 您可以删除
–machine-type
参数,以使用较小 机器配置代替。
n1-standard-1
–enable-

如果需要使用 Istio CNI 功能, 需要在
gcloud container clusters create
参数, 以启用 GKE 集群的 network-policy 功能。
network-policy
命令中加入

  1. 为 获取认证凭据。

kubectl

  1. $ gcloud container clusters get-credentials \

  2. –zone \

  3. –project

  4. 为了给 Istio 创建 RBAC 规则,需要给当前用户赋予集群管理员(admin)权限,因此这里进行授权操作。

  5. $ kubectl create clusterrolebinding cluster-admin-binding \

  6. –clusterrole=cluster-admin \

  7. –user=$(gcloud config get-value core/account)

IBM Cloud 快速开始

依照以下说明 在 IBM Cloud Kubernetes Service 公有云上搭建 Istio 服务集群。 在 Istio on IBM Cloud Private 私有云上搭建 Istio 服务集群。

IBM 为 IBM Cloud Kubernetes Service 提供了 managed control plane 插件, 您可以使用它代替手动安装 Istio。 请参阅 Istio on IBM Cloud Kubernetes Service 有关详细信息和说明。

要在手动安装 Istio 之前准备群集,请按照下列步骤操作:

  1. 安装 IBM Cloud CLI,IBM Cloud Kubernetes Service 插件和 Kubernetes CLI.

<zone-

  1. 使用以下命令创建标准的 Kubernetes 集群。 将替换为可用区。
name> 替换为您用于集群的名称,将

您可以通过运行
ibmcloud ks zones
介绍可用区域以及如何指定它们。
来显示可用区。 IBM Cloud Kubernetes Service 位置参考指南

  1. $ ibmcloud ks cluster-create --zone --machine-type b3c.4x16 \
  2. –workers 3 --name

如果已经有专用和公用 VLAN,您可以在上面的命令中指定使用 --private-vlan 和 选项。 否则, 将自动为您创建。您可以通过运行 ibmcloud ks vlans --zone 来查看可用的 VLAN。
–public-vlan
KUBECONFIG

  1. 运行以下命令下载您的

kubectl
集群配置,然后按照命令输出的说明来设置
环境变量。

  1. $ ibmcloud ks cluster-config

确保使用与集群的 Kubernetes 版本匹配的 CLI 版本。
kubectl

kind

kind 是一种使用 Docker 容器 运行本地 Kubernetes 集群的工具。 kind 主要是为了测试
nodes
Kubernetes 自身而设计的,但它也可用于本地开发或 CI。 请按照以下说明为 Istio 安装准备好 kind 集群。

准备

请使用最新的 Go 版本,最好是 Go 1.13 或更新版本。为了使用 kind,还需要安装 docker。
安装最新版本的 kind。

安装步骤

  1. 使用下列命令创建一个集群:

  2. $ kind create cluster --name istio-testing

用于为集群指定一个名字。默认情况下,该集群将会名为 。
–name
kind

  1. 使用下列命令查看 kind 集群列表:

  2. $ kind get clusters

  3. istio-testing

  4. 使用下列命令查看本地 Kubernetes 环境:

  5. $ kubectl config get-contexts

  6. CURRENT NAME CLUSTER

    • kind-istio-testing kind-istio-testing
  7. minikube minikube

AUTHINFO
kind-istio-testing minikube
NAMESPACE

会作为前缀加到环境和集群名上,如:
kind
kind-istio-testing

  1. 如果运行了多套集群,还需要选择 将要操作哪一套。 可以在 Kubernetes kubeconfig 文件

kubectl
中设置当前环境来指定一个默认集群。 另外,还可以运行下列命令来为 设置当前环境:
kubectl

  1. $ kubectl config use-context kind-istio-testing
  2. Switched to context “kind-istio-testing”.

kind 集群设置完成后,就可以开始在它上面安装 Istio 了。

  1. 当体验过后,想删除集群时,可以使用以下命令:

  2. $ kind delete cluster --name istio-testing

  3. Deleting cluster “istio-testing” …

为 kind 设置操作界面

kind 不像 minikube 一样内置了操作界面。但仍然可以设置一个基于网页的 Kubernetes 界面,以查看集群。参考以下说明来为 kind 设置操作界面。

  1. 运行以下命令以部署操作界面:

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-

  1. beta8/aio/deploy/recommended.yaml

  2. 验证操作界面已经部署并且正在运行。

1. $ kubectl get pod -n kubernetes-dashboard
2. NAMEREADYSTATUSRESTARTSAGE
3. dashboard-metrics-scraper-76585494d8-zdb661/1Running039s
4. kubernetes-dashboard-b7ffbc8cb-zl8zg1/1Running039s
  1. 创建 以提供对新创建的集群的管理权限访问。

ClusterRoleBinding

$ kubectl create clusterrolebinding default-admin --clusterrole cluster-admin –

  1. serviceaccount=default:default

  2. 需要用 Bearer Token 来登录到操作界面。使用以下命令将 token 保存到变量。

$ token=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes.io/service-

  1. account.name’]==‘default’)].data.token}"|base64 -d)

使用 命令显示 token 并复制它,以用于登录到操作界面。
echo

  1. $ echo $token

  2. 使用 kubectl 命令行工具运行以下命令以访问操作界面:

  3. $ kubectl proxy

  4. Starting to serve on 127.0.0.1:8001

点击 Kubernetes Dashboard 来查看部署和服务。
最好将 token 保存起来,不然每次登录到操作界面需要 token 时都得重新运行上述步骤 4.

Kubernetes Gardener 快速开始

Gardener 引导

使用 Gardener 建立自己的集群, 可以查看 文档, 也可以查看 landscape-setup-template 项目。 要了解
有关此开源项目的更多信息,请阅读 博客.
kubernetes.io

安装并且配置 kubectl

v1.10

  1. 如果您已经有本。 如果您的

CLI,请运行
较旧,请按照下一步安装新版本。
kubectl

kubectl
kubectl version --short
来检查版本。您需要
或更高版

  1. 安装 CLI.

kubectl

访问 Gardener

  1. 在 Gardener 仪表板中创建一个项目。这实际上将创建一个名为命名空间。

garden-
的 Kubernetes

  1. 配置对您的 Gardener 项目的访问权限 使用 kubeconfig,如果您还不是 Gardener 管理员,则可以在Gardener 仪表板中创建一个用户:转到 “Members” 部分并添加服务帐户。 然后,您可以为您的项目下载kubeconfig。如果使用用户界面创建集群,则可以跳过此步骤。 只有通过程序访问才需要它,请确保在您的

shell 中设置 。
export KUBECONFIG=garden-my-project.yaml

创建 Kubernetes 集群

您可以通过提供集群规范 yaml 文件,使用 cli 创建集群。您可以在这博客里找到关于 GCP 的示
kubectl
kubectl

例。 确保名称空间与您的项目名称空间匹配。然后只需将准备好的 “shoot” 群集 CRD 与用:
配合使

  1. $ kubectl apply --filename my-cluster.yaml

更简单的替代方法是按照 Gardener 仪表板中的集群创建向导来创建集群:

为集群配置 kubectl

现在,您可以在 Gardener 仪表板中或通过 cli 为新创建的集群下载 kubeconfig,如下所示:

$ kubectl --namespace shoot–my-project–my-cluster get secret kubecfg --output jsonpath={.data.kubeconfig} |

  1. base64 --decode > my-cluster.yaml

此 kubeconfig 文件具有管理员对您群集的完全访问权限。对于本指南的其余部分,请确保已设置
export

KUBECONFIG=my-cluster.yaml

删除

kubectl

使用 Gardener 仪表板删除集群,或者使用指向您的行以下操作:
garden-my-project.yaml
kubeconfig 的 执

$ kubectl --kubeconfig garden-my-project.yaml --namespace garden–my-project annotate shoot my-cluster

  1. confirmation.garden.sapcloud.io/deletion=true
  2. $ kubectl --kubeconfig garden-my-project.yaml --namespace garden–my-project delete shoot my-cluster

MicroK8s

请按照如下说明准备 MicroK8s 以便使用 Istio。运行 MicroK8s 需要管理员权限。

  1. 使用如下命令安装最新版本的 MicroK8s

  2. $ sudo snap install microk8s --classic

  3. 使用如下命令启用 Istio。

  4. $ microk8s.enable istio

  5. 当提示出现时,您需要选择是否在 sidecars 之间强制进行双向 TLS 认证。 如果您有不支持 Istio 和支持 Istio 服务的混合部署,或者您不确定,请选择 No。

请运行以下命令来检查部署进度:

  1. $ watch microk8s.kubectl get all --all-namespaces

Minikube

按照文档安装 minikube,为 Istio 与一些基础应用准备足够的系统资源。

前提条件

运行 minikube 需要管理员权限。

如果要启用秘钥发现服务(SDS),需要为 Kubernetes deployment 添加额外的配置。 访问参考文档查看最新的可选参数。
api-
server

安装步骤

  1. 安装最新的 minikube,版本 **1.1.1 **或更高,以及 minikube 虚拟机驱动。
  2. 如果你没有使用默认的驱动,需要配置 minikube 虚拟机驱动。

比如,如果你安装了 KVM 虚拟机,使用如下命令设置 minikube 的 配置:
vm-driver

  1. $ minikube config set vm-driver kvm2

  2. 以 16384 MB 内存和 4 启动 minikube。这个例子使用了 Kubernetes 1.14.2。 你可以

CPUs
设置 --kubernetes-version 的值以指定任意 Istio 支持的 Kubernetes 版本:

  1. $ minikube start --memory=16384 --cpus=4 --kubernetes-version=v1.14.2

取决于你使用的虚拟机版本以及所运行的平台,最小内存要求也不同。16384 bookinfo。
MB

如果你没有足够的内存分配给 minikube 虚拟机,可能出现如下报错:
足够运行 Istio 和

image pull failures healthcheck timeout failures kubectl failures on the host
general network instability of the virtual machine and the host complete lock-up of the virtual machine
host NMI watchdog reboots

minikube 中有一个不错的方法查看内存占用:

  1. $ minikube ssh

  2. $ top

  3. GiB Mem : 12.4/15.7

这里显示虚拟机内全部的 15.7G 内存已占用了 12.4G。这个数据是在一个 16G 内存的 Macbook Pro

13” 中运行着 Istio 1.2 和 bookinfo 的 VMWare Fusion 虚拟机中生成的。

  1. (可选,推荐)如果你希望 minikube 提供一个负载均衡给 Istio,你可以使用 minikube tunnel。 在另一个终端运行这个命令,因为 minikube tunnel 会阻塞的你的终端用于显示网络诊断信息:

  2. $ minikube tunnel

有时 minikube 不会正确清理 tunnel network。强制清理使用如下命令:

  1. $ minikube tunnel --cleanup

OpenShift

proxy-init

OpenShift 4.1 及以上版本使用的替。
nftables
与 Istio 的
容器不兼容。请使用 CNI 插件代

依照本指南对 OpenShift 集群进行配置以便安装运行 Istio。
默认情况下,OpenShift 不允许容器使用 User ID(UID)0 来运行。通过以下命令可以让 Istio 的服务账户
(Service Accounts)以 UID 0 来运行容器 (如果你将 Istio 部署到其它命名空间,请注意替换
istio-
):
system

  1. $ oc adm policy add-scc-to-group anyuid system:serviceaccounts -n istio-system

现在你可以按照 CNI 的操作来安装 Istio。
安装完成后,为 ingress 网关暴露一个 OpenShift 路由。

  1. $ oc -n istio-system expose svc/istio-ingressgateway --port=80

自动 sidecar 注入

如果你使用的是 OpenShift 4.1 或更高的版本,以下配置不是必须的,可以跳到下一章节。

要使自动注入能正常工作必须启用 Webhook 和证书签名请求(CSR)的支持。 请按以下说明在集群 master 节点修改 master 配置文件。

默认情况下,master 配置文件的路径是 。
/etc/origin/master/master-config.yaml

在 master 配置文件相同目录下创建文件 ,内容如下:
master-config.patch

  1. admissionConfig:
  2. pluginConfig:
  3. MutatingAdmissionWebhook:
  4. configuration:
  5. apiVersion: apiserver.config.k8s.io/v1alpha1
  6. kubeConfigFile: /dev/null
  7. kind: WebhookAdmission
  8. ValidatingAdmissionWebhook:
  9. configuration:
  10. apiVersion: apiserver.config.k8s.io/v1alpha1
  11. kubeConfigFile: /dev/null
  12. kind: WebhookAdmission

然后在该目录下执行:

  1. $ cp -p master-config.yaml master-config.yaml.prepatch

  2. $ oc ex config patch master-config.yaml.prepatch -p “$(cat master-config.patch)” > master-config.yaml

  3. $ master-restart api

  4. $ master-restart controllers

Sidecar 应用的专用安全上下文约束(SCC)

OpenShift 默认是不允许 Istio sidecar 注入到每个应用 Pod 中以 ID 为 1377 的用户运行的。要允许使
用该 UID 运行,需要执行以下命令(注意替换 为适当的命名空间):

  1. $ oc adm policy add-scc-to-group privileged system:serviceaccounts -n
  2. $ oc adm policy add-scc-to-group anyuid system:serviceaccounts -n

当需要移除应用时,请按以下操作移除权限:

  1. $ oc adm policy remove-scc-from-group privileged system:serviceaccounts -n
  2. $ oc adm policy remove-scc-from-group anyuid system:serviceaccounts -n

Oracle Cloud Infrastructure

根据如下介绍,为 Istio 配置 OKE 集群环境。

  1. 在您的 OCI 租户中,创建一个新的 OKE 集群。最简单的方式就是使用 web 控制台中的 ‘Quick Cluster’ 选项。您也可以使用下面的 OCI cli 命令:

  2. $ oci ce cluster create --name oke-cluster1 \

  3. –kubernetes-version \

  4. –vcn-id \

  5. –service-lb-subnet-ids [] \ 5. …

  6. 使用 OCI cli 为您的 获取凭据:

kubectl

  1. $ oci ce cluster create-kubeconfig \

  2. –file <path/to/config> \

  3. –cluster-id

  4. 向当前用户授予集群管理员(admin)权限。要为 Istio 创建必要的 RBAC 规则,当前用户需要拥有管理员权限。

  5. $ kubectl create clusterrolebinding cluster-admin-binding \

  6. –clusterrole=cluster-admin \

  7. –user=<user_ocid>

安装指南

选择最适合您的需求和平台的指南。

使用 Istioctl 安装

安装和自定义任何 Istio 配置文件以进行深入评估或用于生产。

使用 Helm 自定义安装

安装和配置 Istio 以进行深入评估或用于生产。

安装独立 Operator [实验]

使用 Istio operator 在 Kubernetes 集群中安装 Istio 指南。

多集群安装

配置跨越多个 Kubernetes 集群的 Istio 服务网格。
Istio 1.6 已通过这些 Kubernetes 发行版测试:1.15, 1.16, 1.17, 1.18.

使用 Istioctl 安装

请按照本指南安装和配置 Istio 网格,以进行深入评估或用于生产。 如果您刚接触 Istio 或者只是要简单试用,请参考开始文档进行操作。

本指南使用可以高度自定义 Istio 控制平面和数据平面的校验功能,可以防止错误的安装和自定义选项。
istioctl
命令行工具。 该命令行工具具有用户输入

使用这些命令说明,您可以选择 Istio 的任何内置配置文件然后 根据您的特定需求进一步自定义配置。

前提条件

开始之前,请检查以下前提条件:

  1. 下载 Istio 发行版本。
  2. 执行任何必要的特定于平台的设置。
  3. 检查 Pods 和 Services 的要求。

使用默认配置文件安装 Istio

最简单的选择是安装 Istio 配置文件使用以下命令:
default

  1. $ istioctl manifest apply

此命令将在您配置的 Kubernetes 集群上安装 default 配置文件。
default
起点,这与旨在评估广泛的 Istio 功能特性的较大的 demo 配置文件不同。
如果要在 default 配置文件之上启用 Grafana dashboard,用下面的命令设置
addonComponents.grafana.enabled 配置参数:
配置文件建立生产环境的良好

  1. $ istioctl manifest apply --set addonComponents.grafana.enabled=true

通常,您可以像使用 helm 一样在
中配置
标志。 唯一的区别是必须为配置路径增加

前缀,因为这是 Helm 透传 API 的路径,如下所述。
istioctl
–set
values.

从外部 Chart 安装

通常, istioctl 使用内置 Chart 生成安装清单。这些 Chart 与 一起发布,用于审核和自定义,
istioctl
它们 放置在 install/kubernetes/operator/charts 目录下。 除了使用内置 Chart 外, 还可以使用外
istioctl
部 Chart 生成安装清单。要选择外部 Chart ,请配置 参数(接收本地文件系统路径):
installPackagePath

$ istioctl manifest apply --set installPackagePath=< base directory where installed >/istio-releases/istio-

  1. 1.6.0/install/kubernetes/operator/charts

如果使用

  1. 二进制文件,该命令执行结果与通过

安装相同,因为它指

向的 Chart 与内置 Chart 相同。 除了试验或测试新特性之外,我们建议使用内置 Chart 而不是外部提供,以
istioctl
istioctl manifest apply
确保 二进制文件与 Chart 的兼容性。
istioctl

安装其他配置文件

可以通过在命令行上设置配置文件名称安装其他 Istio 配置文件到群集中。 例如,可以使用以下命令,安装配置文件:
demo

  1. $ istioctl manifest apply --set profile=demo

显示可用配置文件的列表

您可以使用以下 命令来列出 Istio 配置文件名称:
istioctl

  1. $ istioctl profile list
  2. Istio configuration profiles:
  3. remote
  4. separate
  5. default
  6. demo
  7. empty
  8. minimal

显示配置文件的配置

您可以查看配置文件的配置设置。例如,通过以下命令查看 配置文件的设置:
default

  1. $ istioctl profile dump demo

  2. addonComponents:

  3. grafana:

  4. enabled: true

  5. kiali:

  6. enabled: true

  7. prometheus:

  8. enabled: true

  9. tracing:

  10. enabled: true

  11. components:

  12. egressGateways:

    • enabled: true
  13. k8s:

  14. resources:

  15. requests:

  16. cpu: 10m

  17. memory: 40Mi

  18. name: istio-egressgateway

要查看整个配置的子集,可以使用 标志,该标志仅选择部分给定路径下的配置:
–config-path

  1. $ istioctl profile dump --config-path components.pilot demo

  2. enabled: true

  3. k8s:

  4. env:

    • name: POD_NAME
  5. valueFrom:

  6. fieldRef:

  7. apiVersion: v1

  8. fieldPath: metadata.name

    • name: POD_NAMESPACE
  9. valueFrom:

  10. fieldRef:

  11. apiVersion: v1

  12. fieldPath: metadata.namespace

    • name: GODEBUG
  13. value: gctrace=1

    • name: PILOT_TRACE_SAMPLING
  14. value: “100”

    • name: CONFIG_NAMESPACE
  15. value: istio-config 21. …

显示配置文件中的差异

子命令可用于显示配置文件之间的差异,在将更改应用于集群之前,这对于检查自定义的效果很有
profile diff
用。

您可以使用以下命令显示 default 和 demo 配置文件之间的差异:

  1. $ istioctl profile diff default demo

  2. gateways:

  3. egressGateways:

      • enabled: false
      • enabled: true 6. …
  4. k8s:

  5. requests: 9. - cpu: 100m

    • memory: 128Mi
    • cpu: 10m
    • memory: 40Mi
  6. strategy: 14. …

安装前生成清单

您可以在安装 Istio 之前使用
子命令生成清单,而不是
。 例如,使用以

下命令为 配置文件生成清单:
manifest generate
manifest apply
default

  1. $ istioctl manifest generate > $HOME/generated-manifest.yaml

根据需要检查清单,然后使用以下命令应用清单:

  1. $ kubectl apply -f $HOME/generated-manifest.yaml

由于集群中的资源不可用,此命令可能显示暂时错误。

显示清单差异

您可以使用以下命令显示默认配置文件和自定义安装之间生成的清单中的差异:

  1. $ istioctl manifest generate > 1.yaml

  2. $ istioctl manifest generate -f samples/operator/pilot-k8s.yaml > 2.yaml

  3. $ istioctl manifest diff 1.yam1 2.yaml

  4. Differences of manifests are:

  5. Object Deployment:istio-system:istio-pilot has diffs:

  6. spec:

  7. template:

  8. spec:

  9. containers:

  10. ‘[0]’:

  11. resources:

  12. requests:

  13. cpu: 500m -> 1000m

  14. memory: 2048Mi -> 4096Mi

  15. nodeSelector: -> map[master:true]

  16. tolerations: -> [map[effect:NoSchedule key:dedicated operator:Exists] map[key:CriticalAddonsOnly

  17. operator:Exists]] 20.

  18. Object HorizontalPodAutoscaler:istio-system:istio-pilot has diffs: 23.

  19. spec:

  20. maxReplicas: 5 -> 10

  21. minReplicas: 1 -> 2

验证安装成功

您可以使用 命令检查 Istio 安装是否成功,它将集群上的安装与您指定的清单进行比较。
verify-install

如果未在部署之前生成清单,请运行以下命令以现在生成它:

  1. $ istioctl manifest generate > $HOME/generated-manifest.yaml

然后运行以下 命令以查看安装是否成功:
verify-install

  1. $ istioctl verify-install -f $HOME/generated-manifest.yaml

定制配置

除了安装 Istio 的任何内置组件配置文件, 提供了用于自定义配置的完整 API。
istioctl manifest

The API
IstioOperator

可以使用命令上的
选项分别设置此 API 中的配置参数。例如,要在
配置文件之上启用控制

面安全特性,请使用以下命令:
–set
default

  1. $ istioctl manifest apply --set values.global.controlPlaneSecurityEnabled=true

或者,可以在 YAML 文件中指定
IstioOperator
配置,并使用
选项将其传给 :

  1. $ istioctl manifest apply -f samples/operator/pilot-k8s.yaml

为了向后兼容,还完全支持 Helm 安装。 若要在命令行中设置它们,请在选项名称前面加上 “ “。 如下
-f
istioctl
values.
所示,下面命令就重写了 Helm 的 配置选项:
pilot.traceSampling

  1. $ istioctl manifest apply --set values.pilot.traceSampling=0.1

如 Customize Istio settings using the Helm API 所述,Helm 值也可以在置。
IstioOperator
定义中设

标识 Istio 功能或组件

API 定义的 components 如下表所示:
IstioOperator

Components
base
pilot
proxy
sidecarInjector
telemetry
policy
citadel
nodeagent
galley
ingressGateways
egressGateways
cni

除了核心的 Istio 组件之外,还提供了第三方附加功能和组件。它们可以通过配置
IstioOperator
spec,或者使用 Helm 透传 API 来启动。
addonComponents
API 的

  1. apiVersion: install.istio.io/v1alpha1

  2. kind: IstioOperator

  3. spec:

  4. addonComponents:

  5. grafana:

  6. enabled: true

  7. apiVersion: install.istio.io/v1alpha1

  8. kind: IstioOperator

  9. spec:

  10. values:

  11. grafana:

  12. enabled: true

配置功能或组件设置

从上表中识别功能部件或组件的名称后,可以使用 API 设置值 使用 标志,或创建一个覆盖文件并使用
–set
–filename
–set

置更改。
标志。
标志自定义一些参数的效果很好。 覆盖文件旨在进行更广泛的自定义,或者跟踪配

最简单的自定义是从配置配置文件默认值打开或关闭功能或组件。要在默认配置配置文件中禁用遥测功能,请使用以下命令:

  1. $ istioctl manifest apply --set components.telemetry.enabled=false

或者,您可以使用配置覆盖文件禁用遥测功能:

     1. 创建一个文件	文件并且写入以下内容:

telemetry_off.yaml

  1. apiVersion: install.istio.io/v1alpha1

  2. kind: IstioOperator

  3. spec:

  4. components:

  5. telemetry:

  6. enabled: false


  7. telemetry_off.yaml
    manifest apply
    覆盖文件与
    命令一起使用:

  8. $ istioctl manifest apply -f telemetry_off.yaml

另一个定制是为功能部件和组件选择不同的命名空间。 以下是一个定制命名空间的例子:

  1. apiVersion: install.istio.io/v1alpha1
  2. kind: IstioOperator
  3. metadata:
  4. namespace: istio-system
  5. spec:
  6. components:
  7. citadel:
  8. namespace: istio-citadel

安装此文件将应用默认配置文件,并将组件安装到以下命名空间中:

Citadel 组件 将被安装到 命名空间
istio-citadel
剩余的 Istio 组件安装到 istio-system 命名空间

自定义 Kubernetes 设置

API 允许以一致的方式自定义每个组件的 Kubernetes 设置。
IstioOperator

每一个组件都有一个允许修改配置的 ,使用此列表来标识要自定义的设置:
KubernetesResourceSpec

  1. Resources
  2. Readiness probes
  3. Replica count 4.

HorizontalPodAutoscaler

PodDisruptionBudget
5.

  1. Pod annotations
  2. Service annotations 8.

ImagePullPolicy

  1. Priority class name
  2. Node selector
  3. Affinity and anti-affinity
  4. Service
  5. Toleration
  6. Strategy
  7. Env

所有这些 Kubernetes 设置都使用 Kubernetes API 定义,因此 Kubernetes 文档可以用作参考。以下示例覆盖文件调整了 Pilot 的 resource 和 pod 水平自动伸缩的设置:

  1. apiVersion: install.istio.io/v1alpha1

  2. kind: IstioOperator

  3. spec:

  4. components:

pilot: k8s:
resources: requests:
cpu: 1000m # override from default 500m memory: 4096Mi # … default 2048Mi
hpaSpec:
maxReplicas: 10 # … default 5
minReplicas: 2 # … default 1 nodeSelector:
master: “true” tolerations:

  • key: dedicated operator: Exists effect: NoSchedule
  • key: CriticalAddonsOnly

operator: Exists

使用 将修改后的设置应用于集群:
manifest apply

  1. $ istioctl manifest apply -f samples/operator/pilot-k8s.yaml

使用 Helm API 自定义 Istio 设置

API 使用 字段直接调用 Helm API 的接口对字段进行设值。
IstioOperator
values

下面的 YAML 文件可以通过 Helm API 配置全局和 Pilot 配置:

  1. apiVersion: install.istio.io/v1alpha1
  2. kind: IstioOperator
  3. spec:
  4. values:
  5. pilot:
  6. traceSampling: 0.1 # override from 1.0
  7. global:
  8. monitoringPort: 15050

一些参数将在 Helm 和 IstioOperator API 中暂时存在,包括 Kubernetes 资源, 命名空间和启用设置。
Istio 社区建议使用 IstioOperator API,因为它更专一,经过验证并遵循社区毕业流程。

卸载 Istio

可以使用以下命令来卸载 Istio:

  1. $ istioctl manifest generate | kubectl delete -f -

相关内容

使用 Istioctl Analyze 诊断配置
演示如何使用 istioctl analyze 来识别配置中的潜在问题。通过 Istioctl Describe 理解您的网格
向您展示如何使用 istioctl describe 来验证您的网格中的 pod 的配置。
DNS 证书管理
在 Istio 中配置和管理 DNS 证书。
Istio Operator 简介
关于 Istio 基于 operator 的安装和控制平面管理特性的介绍。
istioctl analyze 介绍
通过分析 Istio 配置来发现潜在问题和一般问题。安全管理 Webhook
一种更安全管理 Istio webhook 的方法。

使用 Helm 自定义安装

Helm 的安装方法已被弃用。 请改用使用 istioctl 安装。
请按照本指南安装和配置 Istio 网格,以进行深入评估或用于生产。
这种安装方式使用 Helm charts 自定义 Istio 控制平面和 Istio 数据平面的 sidecar。 你只需使用
helm
kubectl apply
helm install

生成配置并使用全管理安装。
template
命令安装它, 或者你可以选择使用
让 Tiller 来完

通过这些说明, 您可以选择 Istio 内置的任何一个 配置文件 并根据的特定的需求进行进一步的自定义配置。

先决条件

  1. 下载 Istio 发行版。
  2. 完成必要的 Kubernetes 平台设置。
  3. 检查 Pod 和服务的要求。
  4. 安装高于 2.10 版本的 Helm 客户端。

请使用 2.x 版本的 Helm。不支持 Helm 3。

添加 Helm chart 仓库

本指南的以下命令使用了包含 Istio 发行版镜像的 Helm charts。 如果要使用 Istio 发行版 Helm chart
,建议使用下面的命令添加 Istio 发行版仓库:

  1. $ helm repo add istio.io https://storage.googleapis.com/istio-release/releases/1.6.0/charts/

安装步骤

将目录切换到 Istio 发行版的根目录,然后在以下两个互斥选项选择一种安装:

  1. 如果您不使用 Tiller 部署 Istio,请查看方案 1。
  2. 如果您使用 Helm 的 Tiller pod 来管理 Istio 发行版, 请查看方案 2。

默认情况下,Istio 使用 服务类型。而有些平台是不支持 LoadBalancer 服务的。对于不支持
LoadBalancer
LoadBalancer 服务类型的平台, 执行下面的步骤时,可以在 Helm 命令中加入 --set gateways.istio-
ingressgateway.type=NodePort 选项,使用 来替代 LoadBalancer 服务类型。
NodePort

方案 1: 使用 helm template 命令安装

在您的集群没有按照 Tiller 而且您也不想安装它的情况下,选择此方案安装。

  1. 为 Istio 组件创建命名空间 :

istio-system

  1. $ kubectl create namespace istio-system

  2. 使用 安装所有 Istio 的 自定义资源 (CRDs) :

kubectl apply

$ helm template install/kubernetes/helm/istio-init --name istio-init --namespace istio-system | kubectl

  1. apply -f -

  2. 等待所有的 Istio CRD 创建完成:

  3. $ kubectl -n istio-system wait --for=condition=complete job --all

  4. 选择一个配置文件 接着部署与您选择的配置文件相对应的 Istio 核心组件。 我们建议在生产环境使用默认的配置文件:

您可以添加一个或多个 来进一步自定义 helm 命令的安装选项 。
–set =

  1. $ helm template install/kubernetes/helm/istio --name istio --namespace istio-system | kubectl apply -f -

  2. $ helm template install/kubernetes/helm/istio --name istio --namespace istio-system \

  3. –values install/kubernetes/helm/istio/values-istio-demo.yaml | kubectl apply -f -

  4. $ helm template install/kubernetes/helm/istio --name istio --namespace istio-system \

  5. –values install/kubernetes/helm/istio/values-istio-minimal.yaml | kubectl apply -f -

  6. $ helm template install/kubernetes/helm/istio --name istio --namespace istio-system \

  7. –values install/kubernetes/helm/istio/values-istio-sds-auth.yaml | kubectl apply -f -

安装 Istio CNI 组件:

$ helm template install/kubernetes/helm/istio-cni --name=istio-cni --namespace=kube-system | kubectl apply -f 1. -


–set istio_cni.enabled=true
文件为例:
设置追加到 helm 命令上,来启用 Istio CNI 插件。 以 Istio 默认配置

  1. $ helm template install/kubernetes/helm/istio --name istio --namespace istio-system \
  2. –set istio_cni.enabled=true | kubectl apply -f -

方案 2: 在 Helm 和 Tiller 的环境中使用 helm install 命令安装

这个方案使用 Helm 和 Tiller 来对 Istio 的生命周期进行管理。
本文档中介绍如何使用带 Tiller 的 Helm 不使用安全默认值。 有关基于 Tiller 安全安装的进一步步骤请参考

安全安装 Helm。

  1. 请确保您的集群的 Tiller 设置了行下面命令创建:

cluster-admin

Zip
角色的 Service Account。 如果还没有定义,请执

  1. $ kubectl apply -f @manifests/UPDATING-CHARTS.md@

  2. 使用 Service Account 在集群上安装 Tiller:

  3. $ helm init --service-account tiller

  4. 安装 chart,来启动 Istio CRD 的安装过程:

istio-init

  1. $ helm install install/kubernetes/helm/istio-init --name istio-init --namespace istio-system

  2. 等待所有的 Istio CRD 创建完成:

  3. $ kubectl -n istio-system wait --for=condition=complete job --all

  4. 选择一个配置文件 接着部署与您选择的配置文件相对应的中使用默认配置文件:

istio
的核心组件。 我们建议在生成环境部署

您可以添加一个或多个 来进一步定义 Helm 命令的 安装选项。
–set =

  1. $ helm install install/kubernetes/helm/istio --name istio --namespace istio-system

  2. $ helm install install/kubernetes/helm/istio --name istio --namespace istio-system \

  3. –values install/kubernetes/helm/istio/values-istio-demo.yaml

  4. $ helm install install/kubernetes/helm/istio --name istio --namespace istio-system \

  5. –values install/kubernetes/helm/istio/values-istio-minimal.yaml

  6. $ helm install install/kubernetes/helm/istio --name istio --namespace istio-system \

  7. –values install/kubernetes/helm/istio/values-istio-sds-auth.yaml

安装 Istio CNI chart:

  1. $ helm install install/kubernetes/helm/istio-cni --name istio-cni --namespace kube-system


–set istio_cni.enabled=true
文件为例:
设置追加到 helm 命令上,来启用 Istio CNI 插件。 以 Istio 默认配置

$ helm install install/kubernetes/helm/istio --name istio --namespace istio-system --set

  1. istio_cni.enabled=true

验证安装

  1. 查询配置文件的组件表,验证是否已部署了与您选择的配置文件相对应的 Kubernetes 服务

  2. $ kubectl get svc -n istio-system

  3. 确保相应的 Kubernetes Pod 已部署并且 是 :

STATUS
Running

  1. $ kubectl get pods -n istio-system

卸载

如果你使用 命令安装的 Istio,使用如下命令卸载:
helm template

  1. $ helm template install/kubernetes/helm/istio --name istio --namespace istio-system | kubectl delete -f -

  2. $ kubectl delete namespace istio-system

  3. $ helm template install/kubernetes/helm/istio --name istio --namespace istio-system \

  4. –values install/kubernetes/helm/istio/values-istio-demo.yaml | kubectl delete -f -

  5. $ kubectl delete namespace istio-system

  6. $ helm template install/kubernetes/helm/istio --name istio --namespace istio-system \

  7. –values install/kubernetes/helm/istio/values-istio-minimal.yaml | kubectl delete -f -

  8. $ kubectl delete namespace istio-system

  9. $ helm template install/kubernetes/helm/istio --name istio --namespace istio-system \

  10. –values install/kubernetes/helm/istio/values-istio-sds-auth.yaml | kubectl delete -f -

  11. $ kubectl delete namespace istio-system

  12. $ helm template install/kubernetes/helm/istio --name istio --namespace istio-system \

  13. –set istio_cni.enabled=true | kubectl delete -f -

$ helm template install/kubernetes/helm/istio-cni --name=istio-cni --namespace=kube-system | kubectl delete -f 1. -

如果您使用的 Helm 和 Tiller 安装的 Istio, 使用如下命令卸载:

  1. $ helm delete --purge istio

  2. $ helm delete --purge istio-init

  3. $ helm delete --purge istio-cni

  4. $ kubectl delete namespace istio-system

删除 CRD 和 Istio 配置

Istio 的设计中,其自定义资源以 CRD 的形式存在于 Kubernetes 环境之中。CRD 中包含了运维过程中产生的运行时配置。正因如此,我们建议运维人员应该显式的对其进行删除,从而避免意外操作。

CRD 的删除,意味着删掉所有的用户配置。

istio-init Chart 包含了 目录中的所有原始 CRD。下载该 Chart 之后,可以简单的使用
istio-init/files
kubectl 删除 CRD。要永久删除 Istio 的 CRD 以及所有 Istio 配置, 请运行如下命令

  1. $ kubectl delete -f install/kubernetes/helm/istio-init/files

相关内容

Helm 变更
关于 Istio 1.1 和 Istio 1.2 之间的 Helm chart 安装选项的变更。
Helm 安装参数变动表
本文详细介绍了 Istio 1.0 系列到 Istio 1.1 系列之间的安装参数变化详情。
Helm 安装参数变动表
本文详细介绍了 Istio 1.2 系列到 Istio 1.3 系列之间的安装参数变化详情。安装 Istio CNI 插件
安装并使用 Istio CNI 插件,可以让运维人员用更低的权限来部署服务。安装选项(Helm)
描述使用 Helm chart 安装 Istio 时的可选项。
DNS 证书管理
在 Istio 中配置和管理 DNS 证书。

安装独立 Operator [实验]

以下信息描述了一个实验性功能,仅用于评估。

该指南将会指引您使用独立的 Istio operator 来安装 Istio。 唯一的依赖就是一个 Kubernetes 集群和命令行工具。
kubectl

如果要安装生产环境的 Istio,我们还是建议您参考使用 istioctl 安装。

前提条件

  1. 执行必要的平台特定设置。

  2. 检查 Pods 和 Services 需求。

  3. 部署 Istio operator:

  4. $ kubectl apply -f https://preliminary.istio.io/operator.yaml

这条命令会在 命名空间中创建以下资源并运行 Istio operator :
istio-operator

operator 自定义资源operator 控制器 deployment operator 指标信息 service operator 必要的 RBAC 规则

安装

运行以下命令用 operator 安装 Istio 配置文件:
demo

  1. $ kubectl create ns istio-system
  2. $ kubectl apply -f - <<EOF
  3. apiVersion: install.istio.io/v1alpha1
  4. kind: IstioControlPlane
  5. metadata:
  6. namespace: istio-operator
  7. name: example-istiocontrolplane
  8. spec:
  9. profile: demo
  10. EOF

控制器会检测
IstioControlPlane
资源,然后按照指定的(
)配置安装 Istio 组件。

您可以使用以下命令来确认 Istio 控制面板服务是否部署:
demo

  1. $ kubectl get svc -n istio-system


15020:31831/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:30318/TCP,15030:32645/TCP,15031:31933/TCP,15032

  1. 2m

istio-pilot ClusterIP 172.21.105.205 15010/TCP,15011/TCP,8080/TCP,15014/TCP

  1. 2m

istio-policy

  1. 2m

istio-sidecar-injector

  1. 2m

istio-telemetry
ClusterIP
172.21.14.236
9091/TCP,15004/TCP,15014/TCP
ClusterIP
172.21.155.47

443/TCP,15014/TCP
ClusterIP
172.21.196.79

9091/TCP,15004/TCP,15014/TCP,42422/TCP
11. 2m

| NAME

2. AGETYPECLUSTER-IPEXTERNAL-IPPORT(S)
grafanaClusterIP172.21.211.1233000/TCP
3. 2m
istio-citadelClusterIP172.21.177.2228060/TCP,15014/TCP
4. 2m
istio-egressgatewayClusterIP172.21.113.2480/TCP,443/TCP,15443/TCP
5. 2m
istio-galleyClusterIP172.21.132.247443/TCP,15014/TCP,9901/TCP
6. 2m
istio-ingressgatewayLoadBalancer172.21.144.25452.116.22.242
jaeger-agentClusterIPNone5775/UDP,6831/UDP,6832/UDP
12. 2m
jaeger-collectorClusterIP172.21.135.5114267/TCP,14268/TCP
13. 2m
jaeger-queryClusterIP172.21.26.18716686/TCP
14. 2m
kialiClusterIP172.21.155.20120001/TCP
15. 2m
prometheusClusterIP172.21.63.1599090/TCP
16. 2m
tracingClusterIP172.21.2.24580/TCP
17. 2m
zipkinClusterIP172.21.182.2459411/TCP
18. 2m
2. NAMEREADYSTATUSRESTARTSAGE
3. grafana-f8467cc6-rbjlg1/1Running01m
4. istio-citadel-78df5b548f-g5cpw1/1Running01m
5. istio-egressgateway-78569df5c4-zwtb51/1Running01m
6. istio-galley-74d5f764fc-q7nrk1/1Running01m
7. istio-ingressgateway-7ddcfd665c-dmtqz1/1Running01m
8. istio-pilot-f479bbf5c-qwr281/1Running01m
9. istio-policy-6fccc5c868-xhblv1/1Running21m
10. istio-sidecar-injector-78499d85b8-x44m61/1Running01m
11. istio-telemetry-78b96c6cb6-ldm9q1/1Running21m
12. istio-tracing-69b5f778b7-s2zvw1/1Running01m
13. kiali-99f7467dc-6rvwp1/1Running01m
14. prometheus-67cdb66cbb-9w2hm1/1Running01m

更新

  1. $ kubectl get pods -n istio-system

现在,控制器已经在运行了,您可以通过编辑或替换会检测该变化,并对应的更新 Istio 的安装。
IstioControlPlane

例如,您可以运行以下命令将安装切换为
default

配置:
资源来改变 Istio 的配置。 控制器将

  1. $ kubectl apply -f - <<EOF
  2. apiVersion: install.istio.io/v1alpha1
  3. kind: IstioControlPlane
  4. metadata:
  5. namespace: istio-operator
  6. name: example-istiocontrolplane
  7. spec:
  8. profile: default
  9. EOF

您还可以启用或禁用指定的特性或组件。 例如,禁用遥测特性:

  1. $ kubectl apply -f - <<EOF
  2. apiVersion: install.istio.io/v1alpha1
  3. kind: IstioControlPlane
  4. metadata:
  5. namespace: istio-operator
  6. name: example-istiocontrolplane
  7. spec:
  8. profile: default
  9. telemetry:
  10. enabled: false
  11. EOF

参考 接口获取完整的配置项。
IstioControlPlane

卸载

删除 Istio operator 和 Istio 部署:

$ kubectl -n istio-operator get IstioControlPlane example-istiocontrolplane -o=json | jq '.metadata.finalizers

  1. = null’ | kubectl delete -f -

  2. $ kubectl delete ns istio-operator --grace-period=0 --force

  3. $ kubectl delete ns istio-system --grace-period=0 --force

相关内容

介绍 istiod:简化控制平面
Istiod 将 Istio 控制平面组件合并为一个二进制文件。在 Istio 中进行 WebAssembly 声明式部署

以声明方式为 Envoy 和 Istio 配置 Wasm 扩展。
重新定义代理的扩展性:Envoy 和 Istio 引入 WebAssembly Istio 的扩展中使用 WASM 的前景。
Istio 2020——为了商用
Istio 在 2020 年的愿景声明及路线图。
DNS 证书管理
在 Istio 中配置和管理 DNS 证书。
Istio Operator 简介
关于 Istio 基于 operator 的安装和控制平面管理特性的介绍。

多集群安装

配置跨越多个 Kubernetes 集群的 Istio 服务网格。

简化地多集群安装[实验性]

配置一个跨多个 Kubernetes 集群的 Istio 网格。

控制平面副本集

通过控制平面副本集实例,在多个 Kubernetes 集群上安装 Istio 网格。

共享控制平面(单一网络)

安装一个跨多个 Kubernetes 集群的 Istio 网格,多集群共享控制平面,并且集群间通过 VPN 互连。

共享的控制平面(多网络)

跨多个 Kubernetes 集群安装一个 Istio 网格,使互不联通的集群网络共享同一个控制平面。

请注意,这些说明不是互斥的。 在由两个以上集群组成的大型多集群部署中,可以使用这些方法的组合。 例如,两个集群可能共享一个控制平面,而第三个集群拥有自己的控制平面。

欲获取更多信息请参考多集群部署模型。

简化地多集群安装[实验性]

以下信息描述了一个实验性功能,仅用于评估。

本指南描述了如何使用一种简化的实验性方式来配置一个跨多个 Kubernetes 集群的 Istio 网格。 我们希望在将来的版本中继续开发这项功能,因此非常期待您对这个流程进行反馈。

在此我们集中讨论如何连接多集群网格的细节,有关其它背景信息,请参考多集群部署模型。 我们将展示如何将同一网络上的两个集群与另一个网络上的第三个集群连接起来。

使用本指南中展示的方法会导致 Istio 控制平面的实例部署在网格中的每个集群中。 尽管这是一种常见配置,但其他更复杂的拓扑也是可能的,只是需要使用一些手动的过程来完成,此处不再赘述。

开始之前

此处我们描述的过程主要针对相对干净的未部署过 Istio 的集群。 我们在将来能将支持扩展到现有集群。为了便于说明,本指南假定您已经创建了三个 Kubernetes 集群:
network-east network-east
network-west
cluster-east-1 cluster-east-2
cluster-west-1

一个在一个在一个在
网络上的名为网络上的名为网络上的名为
的集群。的集群。的集群。

这些集群应当尚未安装 Istio。前两个集群在同一个网络,并可直连,而第三个集群在另一个网络。 请查看平台设置说明,以了解针对您的特定环境的任何特殊说明。

初步准备

您需要执行一些一次性步骤才能设置多集群网格:

  1. 确保您的所有集群都被包含在您的 Kubernetes 配置文件中,并为它们创建了上下文配置。完成后,您的配置文件应该包含类似如下内容:

  2. kind: Config

  3. apiVersion: v1

  4. clusters:

    • cluster:
  5. name: cluster-east-1

    • cluster:
  6. name: cluster-east-2

    • cluster:
  7. name: cluster-west-1

  8. contexts:

    • context:
  9. cluster: cluster-east-1

  10. name: context-east-1

    • context:
  11. cluster: cluster-east-2

  12. name: context-east-2

    • context:
  13. cluster: cluster-west-1

  14. name: context-west-1

  15. 决定您的多集群网格的名字。推荐使用一些短小好记的:

  16. $ export MESH_ID=mymeshname

  17. 决定组织名以用于创建用来让集群互相通信的根证书和中间证书。这通常可以从您的组织的 DNS 名中得来:

  18. $ export ORG_NAME=mymeshname.mycompanyname.com

  19. 创建一个工作目录,用于存储在集群启动过程中产生的若干文件:

  20. $ export WORKDIR=mydir

  21. $ mkdir -p ${WORKDIR}

  22. $ cd ${WORKDIR}

  23. 下载设置脚本到您的工作目录。 该脚本负责创建必要的证书以启用跨集群通信,它为您准备了默认配置文件, 并将在每个集群中部署和配置 Istio。

  24. 最后,运行下载的脚本以准备网格。这会创建一个将用于保护网格中群集之间的通信安全的根密钥和证书,以及

用于控制所有群集上部署的 Istio 的配置的 文件:
base.yaml

  1. $ ./setup-mesh.sh prep-mesh

请注意此步骤不会对集群产生任何影响,它只是在您的工作目录里创建了若干文件。

定制 Istio

上面的网格准备工作在您的工作目录里创建了一个名为 的文件。 这个文件定义了基本的
base.yaml
配置,它用于将 Istio 部署到您的集群中(下面就会提到)。 您可以定制 文件,以精确控制 Istio 将被如何部署到所有的集群中。
IstioControlPlane
base.yaml
只有这些值不应该被修改:

  1. values.gateway.istio-ingressgateway.env.ISTIO_MESH_NETWORK
  2. values.global.controlPlaneSecurityEnabled
  3. values.global.multiCluster.clusterName
  4. values.global.network
  5. values.global.meshNetworks
  6. values.pilot.meshNetworks=

这些值是通过以下步骤自动设置的,任何手动设置都会导致数据丢失。

创建网格

通过编辑在您的工作目录中的条目,使文件如下所示:
topology.yaml
文件来指定哪些集群将被包含在网格中。 为这三个集群都添加一个

  1. mesh_id: mymeshname
  2. contexts:
  3. context-east-1:
  4. network: network-east
  5. context-east-2:
  6. network: network-east
  7. context-west-1:
  8. network: network-west

该拓扑文件保存了网格的名字,以及网络的上下文映射。当文件保存后,您就可以开始创建网格了。 这将部署
Istio 到每个集群,并配置每个势力以互相安全通信:

  1. $ ./setup-mesh.sh apply

想要往网格中添加或删除集群,只需要对应地更新该拓扑文件并重新应用这些更改。

每当您使用 时,都会在您的工作目录中创建一些 secret 文件,尤其是与不同证书关联的一
setup-mesh.sh apply
些私钥。 您应该存储并保护好这些 secrets。需要保护的这些文件是:

  1. certs/root-key.pem - 根私钥
  2. certs/intermediate-*/ca-key.pem - 中间私钥

清理

您可以使用以下命令从所有的已知集群中删除 Istio:

  1. $ ./setup-mesh.sh teardown

相关内容

共享控制平面(单一网络)
安装一个跨多个 Kubernetes 集群的 Istio 网格,多集群共享控制平面,并且集群间通过 VPN 互连。共享的控制平面(多网络)
跨多个 Kubernetes 集群安装一个 Istio 网格,使互不联通的集群网络共享同一个控制平面。控制平面副本集
通过控制平面副本集实例,在多个 Kubernetes 集群上安装 Istio 网格。

使用 Admiral 管理 Istio 多集群的配置和服务发现
为 Istio deployment(cluster)提供自动化 Istio 配置,并让其像单个网格一样工作。
DNS 证书管理
在 Istio 中配置和管理 DNS 证书。安全管理 Webhook
一种更安全管理 Istio webhook 的方法。

控制平面副本集

请参照本指南安装具有副本集控制平面实例的 Istio 多集群部署,并在每个群集中使用 gateway 来提供跨集群连接服务。

在此配置中,每个集群都使用它自己的 Istio 控制平面来完成安装,并管理自己的 endpoint, 而不是使用共享的 Istio 控制平面来管理网格。 出于以下目的,所有群集都在共同的管理控制下,执行策略与安全行为

通过共享服务副本及命名空间,并在所有群集中使用公共的根证书,可以在群集中实现一个 Istio 服务网格。 跨集群通信基于各个集群的 Istio gateway。

使用 Istio Gateway 跨越多个基于 Kubernetes 集群的 Istio 网格并最终到达远端 pod

前提条件

两个以上 Kubernetes 集群,且版本为:1.15, 1.16, 1.17, 1.18。

有权限在 每个 Kubernetes 集群上,部署 Istio 控制平面。

每个集群 服务的 IP 地址,必须允许其它集群访问,最好使用 4 层负载均衡
istio-ingressgateway
(NLB)。 有些云服务商不支持负载均衡或者需要特别注明才能使用。所以,请查阅您的云服务商的文档,为负载均衡类型的服务对象启用 NLB。 在不支持负载均衡的平台上部署时,可能需要修改健康检查,使得负载均衡对象可以注册为 ingress gateway。

一个 根 CA。跨集群的服务通信必须使用双向 TLS 连接。 为了在集群之间使用双向 TLS 通信,每个集群的
Citadel 都将由共享的根 CA 生成中间 CA 凭据。 为方便演示,您在安装 Istio 时,可以使用

目录下的一个根 CA 证书样本。
samples/certs

在每个集群中部署 Istio 控制平面

  1. 从组织的根 CA 为每个集群的 Citadel 生成中间 CA 证书。 共享的根 CA 支持跨集群的双向 TLS 通信。

为方便演示,后面两个集群的演示都将使用 Istio 样本目录下的证书。 在实际部署中,一般会使用一个公共根 CA 为每个集群签发不同的 CA 证书。

  1. 想要在 每个集群 上部署相同的 Istio 控制平面,请运行下面的命令:

请确保当前用户拥有集群的管理员( 台下,可以使用以下命令授权:
cluster-admin
)权限。 如果没有权限,请授权给它。例如,在 GKE 平

$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user="$(gcloud

  1. config get-value core/account)"

使用类似于下面的命令,为生成的 CA 证书创建 Kubernetes secret。了解详情,请参见 CA 证书。

示例目录中的根证书和中间证书已被广泛分发和知道。 千万不要 在生成环境中使用这些证书,这样集群就容易受到安全漏洞的威胁和破坏。

ZipZipZipZip

  1. $ kubectl create namespace istio-system
  2. $ kubectl create secret generic cacerts -n istio-system \
  3. –from-file=@samples/certs/ca-cert.pem@ \
  4. –from-file=@samples/certs/ca-key.pem@ \
  5. –from-file=@samples/certs/root-cert.pem@ \
  6. –from-file=@samples/certs/cert-chain.pem@

安装 Istio:

  1. $ istioctl manifest apply \

-f install/kubernetes/operator/examples/multicluster/values-istio-multicluster-gateways.yaml

  1. 想了解更多细节和自定义选项,请参考使用 Istioctl 安装。

配置 DNS

应用一般需要通过他们的 DNS 解析服务名然后访问返回的 IP,为远端集群中的服务提供 DNS 解析,将允许已有的应用不做修改就可以正常运行。 Istio 本身不会为两个服务之间的请求使用 DNS。集群本地的服务共用一个通用的
DNS 后缀(例如, )。Kubernetes DNS 为这些服务提供了 DNS 解析。
svc.cluster.local

要为远端集群的服务提供类似的配置,远端集群内的服务需要以 的格式命名。 Istio
..global

还附带了一个名为 CoreDNS 的服务,它可以为这些服务提供 DNS 解析。 想要使用 CoreDNS,Kubernetes
DNS 的 必须配置为 。
.global
stub a domain

一些云提供商的 Kubernetes 服务可能有不同的、特殊的 程序和功能。 请参考云提供商的文
DNS domain stub
stub DNS domains
53
.global

档,以确定如何为不同环境的
。 这个 bash 的目的是为
端口上的
存根域
引用或代理 Istio 的 service namespace 中的 服务。
istiocoredns

在每个要调用远端集群中服务的集群中(通常是所有集群), 选择并创建下面这些 ConfigMaps 中的一个,或直接使用现有的做修改。

  1. $ kubectl apply -f - <<EOF

  2. apiVersion: v1

  3. kind: ConfigMap

  4. metadata:

  5. name: kube-dns

  6. namespace: kube-system

  7. data:

  8. stubDomains: |

  9. {“global”: [“$(kubectl get svc -n istio-system istiocoredns -o jsonpath={.spec.clusterIP})”]}

  10. EOF

  11. $ kubectl apply -f - <<EOF

  12. apiVersion: v1

  13. kind: ConfigMap

  14. metadata:

  15. name: coredns

  16. namespace: kube-system

  17. data:

  18. Corefile: |

  19. .:53 {

  20. errors

  21. health

  22. kubernetes cluster.local in-addr.arpa ip6.arpa {

  23. pods insecure

  24. upstream

  25. fallthrough in-addr.arpa ip6.arpa

  26. }

  27. prometheus :9153

  28. proxy . /etc/resolv.conf

  29. cache 30

  30. loop

  31. reload

  32. loadbalance

  33. }

  34. global:53 {

  35. errors

  36. cache 30

  37. forward . $(kubectl get svc -n istio-system istiocoredns -o jsonpath={.spec.clusterIP}):53

  38. }

  39. EOF

  40. $ kubectl apply -f - <<EOF

  41. apiVersion: v1

  42. kind: ConfigMap

  43. metadata:

  44. name: coredns

  45. namespace: kube-system

  46. data:

  47. Corefile: |

  48. .:53 {

  49. errors

  50. health

  51. ready

  52. kubernetes cluster.local in-addr.arpa ip6.arpa {

  53. pods insecure

  54. upstream

  55. fallthrough in-addr.arpa ip6.arpa

  56. }

  57. prometheus :9153

  58. forward . /etc/resolv.conf

  59. cache 30

  60. loop

  61. reload

  62. loadbalance

  63. }

  64. global:53 {

  65. errors

  66. cache 30

  67. forward . $(kubectl get svc -n istio-system istiocoredns -o jsonpath={.spec.clusterIP}):53

  68. }

  69. EOF

  70. $ kubectl apply -f - <<EOF

  71. apiVersion: v1

  72. kind: ConfigMap

  73. metadata:

  74. name: coredns

  75. namespace: kube-system

  76. data:

  77. Corefile: |

  78. .:53 {

  79. errors

  80. health

  81. kubernetes cluster.local in-addr.arpa ip6.arpa {

  82. pods insecure

  83. upstream

  84. fallthrough in-addr.arpa ip6.arpa

  85. }

  86. prometheus :9153

  87. forward . /etc/resolv.conf

  88. cache 30

  89. loop

  90. reload

  91. EOF
    loadbalance
    }
    global:53 {
    errors cache 30
    forward . $(kubectl get svc -n istio-system istiocoredns -o jsonpath={.spec.clusterIP})
    }

应用服务的配置

一个集群中所有需要被其它远端集群访问的服务,都需要在远端集群中配置 。 service entry 使
ServiceEntry
..global

用的 host 应该采用如下格式: 空间。
。 其中 name 和 namespace 分别对应服务名和命名

为了演示跨集群访问,需要配置: 在第一个集群中运行的 sleep service 并调用 在第二个集群中运行的
httpbin service。 开始之前:

选择两个 Istio 集群,分别称之为 和 。
cluster1
cluster2

你可以使用 kubectl 命令带上 --context 参数去访问集群 和
cluster1
cluster2
kubectl get pods --context cluster1 。 使用如下命令列出你的上下文:
, 例如

2. CURRENTNAMECLUSTERAUTHINFONAMESPACE
3. *cluster1cluster1user@foo.comdefault
4.cluster2cluster2user@foo.comdefault

保存集群的上下文到环境变量:

  1. $ kubectl config get-contexts

  2. $ export CTX_CLUSTER1=$(kubectl config view -o jsonpath=‘{.contexts[0].name}’)

  3. $ export CTX_CLUSTER2=$(kubectl config view -o jsonpath=‘{.contexts[1].name}’)

  4. $ echo CTX_CLUSTER1 = ${CTX_CLUSTER1}, CTX_CLUSTER2 = ${CTX_CLUSTER2}

  5. CTX_CLUSTER1 = cluster1, CTX_CLUSTER2 = cluster2

如果你有超过两个集群的上下文并且你想要使用前两个以外的集群配置你的网格,你需要手动将环境变量设置为你需要的上下文名称。

示例服务的配置

sleep

cluster1
上部署
服务。

Zip

  1. $ kubectl create --context=$CTX_CLUSTER1 namespace foo
  2. $ kubectl label --context=$CTX_CLUSTER1 namespace foo istio-injection=enabled
  3. $ kubectl apply --context=$CTX_CLUSTER1 -n foo -f @samples/sleep/sleep.yaml@

$ export SLEEP_POD= ( k u b e c t l g e t − − c o n t e x t = (kubectl get --context= (kubectlgetcontext=CTX_CLUSTER1 -n foo pod -l app=sleep -o jsonpath=
4. {.items…metadata.name})

cluster2
上部署
服务。

Zip
httpbin

  1. $ kubectl create --context=$CTX_CLUSTER2 namespace bar

  2. $ kubectl label --context=$CTX_CLUSTER2 namespace bar istio-injection=enabled

  3. $ kubectl apply --context=$CTX_CLUSTER2 -n bar -f @samples/httpbin/httpbin.yaml@

  4. 暴露 的 gateway 地址:

cluster2

$ export CLUSTER2_GW_ADDR= ( k u b e c t l g e t − − c o n t e x t = (kubectl get --context= (kubectlgetcontext=CTX_CLUSTER2 svc --selector=app=istio-ingressgateway 1.
2. -n istio-system -o jsonpath=‘{.items[0].status.loadBalancer.ingress[0].ip}’)

该命令使用了 gateway 的公网 IP,如果您有域名的话,您也可以直接使用域名。

如果 运行在一个不支持对外负载均衡的环境下,您需要使用 nodePort 访问 gateway。 有关
cluster2
获取使用 IP 的说明,请参见教程:控制 Ingress 流量。 在后面的步骤中,您还需要将 service entry
的 endpoint 的端口从 15443 修改为其对应的 nodePort (例如, kubectl --context=$CTX_CLUSTER2 get
svc -n istio-system istio-ingressgateway -o=jsonpath=‘{.spec.ports [?(@.port==15443)].nodePort}’ )。

  1. 在 中为 服务创建一个 service entry。

cluster1
httpbin

为了让 cluster1 中的 访问 中的 ,我们需要在 cluster1 中为
sleep
cluster2
httpbin
httpbin 服务创建一个 service entry。 service entry 的 host 命名应采用 .
.global 的格式。 其中 name 和 namespace 分别与远端服务的 name 和 namespace 对应。

为了让 DNS 解析 域下的服务,您需要给这些服务分配一个 IP 地址。
*.global

每个( 域下的)服务都必须有一个在其所属集群内唯一的 IP 地址。
.global

如果 global service 需要使用虚拟 IP,您可以使用,但除此之外,我们建议使用范围在
240.0.0.0/4
的 E 类 IP 地址。 使用这类 IP 地址的应用的流量将被 sidecar 捕获,并路由至适当的远程服务。
组播地址 (224.0.0.0 ~ 239.255.255.255) 不应该被使用,因为这些地址默认不会被路由。 环路地址
(127.0.0.0/8) 不应该被使用,因为 sidecar 可能会将其重定向至 sidecar 的某个监听端口。

  1. $ kubectl apply --context=$CTX_CLUSTER1 -n foo -f - <<EOF

  2. apiVersion: networking.istio.io/v1alpha3

  3. kind: ServiceEntry

  4. metadata:

  5. name: httpbin-bar

  6. spec:

  7. hosts:

  8. must be of form name.namespace.global

    • httpbin.bar.global
  9. Treat remote cluster services as part of the service mesh

  10. as all clusters in the service mesh share the same root of trust.

  11. location: MESH_INTERNAL

  12. ports:

    • name: http1
  13. number: 8000

  14. protocol: http

  15. resolution: DNS

  16. addresses:

  17. the IP address to which httpbin.bar.global will resolve to

  18. must be unique for each remote service, within a given cluster.

  19. This address need not be routable. Traffic for this IP will be captured

  20. by the sidecar and routed appropriately. 23. - 240.0.0.2

  21. endpoints:

  22. This is the routable address of the ingress gateway in cluster2 that

  23. sits in front of sleep.foo service. Traffic from the sidecar will be

  24. routed to this address.

    • address: ${CLUSTER2_GW_ADDR}
  25. ports:

  26. http1: 15443 # Do not change this port value

  27. EOF

上面的配置会基于双向 TLS 连接,将cluster1 中对httpbin.bar.global的 任意端口 的访问,路由
至 :15443endpoint。

gateway 的 15443 端口是一个特殊的 SNI-aware Envoy,当您在集群中部署 Istio 控制平面时,它会自动安装。 进入 15443 端口的流量会为目标集群内适当的服务的 pods 提供负载均衡(在这个例子中
是, 集群中的 服务)。
cluster2
httpbin.bar

不要手动创建一个使用 15443 端口的 。
Gateway

  1. 验证 是否可以访问 。

sleep
httpbin

$ kubectl exec --context=$CTX_CLUSTER1 $SLEEP_POD -n foo -c sleep – curl -I

  1. httpbin.bar.global:8000/headers

通过 egress gateway 发送远程流量

如果您想在 中通过一个专用的 egress gateway 路由流量,而不是从 sidecars 直连。 使用下面
cluster1
的 service entry 替换前面一节对 使用的配置。
httpbin.bar

该配置中使用的 egress gateway 依然不能处理其它的、非 inter-cluster 的 egress 流量。
如果 $CLUSTER2_GW_ADDR 是 IP 地址,请使用 $CLUSTER2_GW_ADDR - IP address 选项。如果
$CLUSTER2_GW_ADDR 是域名,请使用 $CLUSTER2_GW_ADDR - hostname 选项。

暴露 egress gateway 地址:
cluster1

  1. $ export CLUSTER1_EGW_ADDR= ( k u b e c t l g e t − − c o n t e x t = (kubectl get --context= (kubectlgetcontext=CTX_CLUSTER1 svc --selector=app=istio-egressgateway \
  2. -n istio-system -o yaml -o jsonpath=‘{.items[0].spec.clusterIP}’)

使 httpbin-bar 服务的 entry 生效:

  1. $ kubectl apply --context=$CTX_CLUSTER1 -n foo -f - <<EOF

  2. apiVersion: networking.istio.io/v1alpha3

  3. kind: ServiceEntry

  4. metadata:

  5. name: httpbin-bar

  6. spec:

  7. hosts:

  8. must be of form name.namespace.global

    • httpbin.bar.global
  9. location: MESH_INTERNAL

  10. ports:

    • name: http1
  11. number: 8000

  12. protocol: http

  13. resolution: STATIC

  14. addresses:

    • 240.0.0.2
  15. endpoints:

    • address: ${CLUSTER2_GW_ADDR}
  16. network: external

  17. ports:

  18. http1: 15443 # Do not change this port value

    • address: ${CLUSTER1_EGW_ADDR}
  19. ports:

  20. http1: 15443

  21. EOF

如果 是域名,您也可以使用 实现 endpoint 解析。
${CLUSTER2_GW_ADDR}
resolution: DNS

  1. $ kubectl apply --context=$CTX_CLUSTER1 -n foo -f - <<EOF

  2. apiVersion: networking.istio.io/v1alpha3

  3. kind: ServiceEntry

  4. metadata:

  5. name: httpbin-bar

  6. spec:

  7. hosts:

  8. must be of form name.namespace.global

    • httpbin.bar.global
  9. location: MESH_INTERNAL

  10. ports:

    • name: http1
  11. number: 8000

  12. protocol: http

  13. resolution: DNS

  14. addresses:

    • 240.0.0.2
  15. endpoints:

    • address: ${CLUSTER2_GW_ADDR}
  16. network: external

  17. ports:

  18. http1: 15443 # Do not change this port value

    • address: istio-egressgateway.istio-system.svc.cluster.local
  19. ports:

  20. http1: 15443

  21. EOF

示例的清理

运行下面的命令清理示例中的服务。

清理 :
cluster1

Zip

  1. $ kubectl delete --context=$CTX_CLUSTER1 -n foo -f @samples/sleep/sleep.yaml@
  2. $ kubectl delete --context=$CTX_CLUSTER1 -n foo serviceentry httpbin-bar
  3. $ kubectl delete --context=$CTX_CLUSTER1 ns foo

清理 :
cluster2

Zip

  1. $ kubectl delete --context=$CTX_CLUSTER2 -n bar -f @samples/httpbin/httpbin.yaml@
  2. $ kubectl delete --context=$CTX_CLUSTER2 ns bar

Version-aware 路由到远端服务

如果远端服务有多个版本,您可以为 service entry endpoint 添加标签。比如:

  1. $ kubectl apply --context=$CTX_CLUSTER1 -n foo -f - <<EOF

  2. apiVersion: networking.istio.io/v1alpha3

  3. kind: ServiceEntry

  4. metadata:

  5. name: httpbin-bar

  6. spec:

  7. hosts:

  8. must be of form name.namespace.global

    • httpbin.bar.global
  9. location: MESH_INTERNAL

  10. ports:

    • name: http1
  11. number: 8000

  12. protocol: http

  13. resolution: DNS

  14. addresses:

  15. the IP address to which httpbin.bar.global will resolve to

  16. must be unique for each service.

    • 240.0.0.2
  17. endpoints:

    • address: ${CLUSTER2_GW_ADDR}
  18. labels:

  19. cluster: cluster2

  20. ports:

  21. http1: 15443 # Do not change this port value

  22. EOF

然后您就可以使用适当的 gateway 标签选择器,创建虚拟服务和目标规则去定义 的子集。
httpbin.bar.global
这些指令与路由到本地服务使用的指令相同。 完整的例子,请参考 multicluster version routing。

卸载

若要卸载 Istio,请在 每个集群 上执行下面的命令:

  1. $ kubectl delete -f $HOME/istio.yaml
  2. $ kubectl delete ns istio-system

总结

使用 Istio gateway、公共的根 CA 和 service entry,您可以配置一个跨多个 Kubernetes 集群的单Istio 服务网格。 经过这种方式配置后,应用无需任何修改,即可将流量路由到远端的集群内。 尽管此方法需要手动配置一些访问远端服务的选项,但 service entry 的创建过程可以自动化。

相关内容

使用 Admiral 管理 Istio 多集群的配置和服务发现
为 Istio deployment(cluster)提供自动化 Istio 配置,并让其像单个网格一样工作。用于隔离和边界保护的多网格部署
将需要隔离的环境部署到单独的网格中,并通过网格联邦启用网格间通信。共享控制平面(单一网络)
安装一个跨多个 Kubernetes 集群的 Istio 网格,多集群共享控制平面,并且集群间通过 VPN 互连。共享的控制平面(多网络)
跨多个 Kubernetes 集群安装一个 Istio 网格,使互不联通的集群网络共享同一个控制平面。简化地多集群安装[实验性]
配置一个跨多个 Kubernetes 集群的 Istio 网格。
DNS 证书管理

在 Istio 中配置和管理 DNS 证书。

共享控制平面(单一网络)

按照该指南安装一个 Istio 多集群服务网格以让每个 Kubernetes 集群的服务和应用能够将他们的内部
Kubernetes 网络暴露至其它集群。

在这个配置中,多个 Kubernetes 集群运行一份可以连接到一个共享 Istio 控制平面的远程配置。 一旦一个或多个远程 Kubernetes 集群连接到该 Istio 控制平面,Envoy 就会形成一个跨多集群的网格网络。


跨多 Kubernetes 集群的 Istio 网格可通过 VPN 直接访问远程 Pod

前提条件

两个或更多运行受支持的 Kubernetes 版本(1.15, 1.16, 1.17, 1.18)的集群。

能够在多集群中的一个上部署 Istio 控制平面。

满足下列要求的 RFC1918 网络、VPN、或其它更高级的网络技术:

各集群的 Pod CIDR 范围和服务 CIDR 范围在多群集环境中必须唯一,并且不能重叠。

每个集群中的所有 pod CIDRs 必须互相可路由。

所有 Kubernetes 控制平面 API 服务必须互相可路由。
本指南介绍如何使用 Istio 提供的远程配置文件安装多群集 Istio 拓扑。

部署本地控制平面

在 Kubernetes 集群之一上安装 Istio 控制平面。

设置环境变量

在执行本节中的步骤之前,请等待 Istio 控制平面完成初始化。

您必须在 Istio 控制平面集群上执行这些操作,以获取 Istio 控制平面服务端点,例如,Pilot 和 Policy Pod IP 端点。

运行以下命令设置环境变量:

  1. $ export PILOT_POD_IP=$(kubectl -n istio-system get pod -l istio=pilot -o jsonpath=‘{.items[0].status.podIP}’)

$ export POLICY_POD_IP=$(kubectl -n istio-system get pod -l istio-mixer-type=policy -o

  1. jsonpath=‘{.items[0].status.podIP}’)

$ export TELEMETRY_POD_IP=$(kubectl -n istio-system get pod -l istio-mixer-type=telemetry -o

  1. jsonpath=‘{.items[0].status.podIP}’)

通常,在远程集群上自动 sidecar 注入已经启用。 要执行手动 sidecar 注入,请参考手动 sidecar 示例。

安装 Istio 远程组件

您必须在每个远程 Kubernetes 集群上都部署 组件。 您可以用下面两种方式之一来安装该组件:
istio-remote

  1. 在远程集群上使用下列命令来安装 Istio 控制平面服务端点:

  2. $ istioctl manifest apply \

  3. –set profile=remote \

  4. –set values.global.controlPlaneSecurityEnabled=false \

  5. –set values.global.createRemoteSvcEndpoints=true \

  6. –set values.global.remotePilotCreateSvcEndpoint=true \

  7. –set values.global.remotePilotAddress=${PILOT_POD_IP} \

  8. –set values.global.remotePolicyAddress=${POLICY_POD_IP} \

  9. –set values.global.remoteTelemetryAddress=${TELEMETRY_POD_IP} \

  10. –set gateways.enabled=false \

  11. –set autoInjection.enabled=true

所有集群的 Istio 组件都必须具有相同的命名空间。 只要所有集群中所有 Istio 组件的命名空间都相同,
就可以在主集群上覆盖 名称。
istio-system

  1. 下列命令示例标记了群的命名空间。

default
命名空间。使用类似的命令标记所有需要自动进行 sidecar 注入的远程集

  1. $ kubectl label namespace default istio-injection=enabled

为所有需要设置自动 sidecar 注入的 Kubernetes 命名空间重复以上命令。

  1. $ CA_DATA=$(kubectl get secret ${SECRET_NAME} -n ${NAMESPACE} -o jsonpath=“{.data[‘ca.crt’]}”)

$ TOKEN=$(kubectl get secret ${SECRET_NAME} -n ${NAMESPACE} -o jsonpath=“{.data[‘token’]}” | base64 –

  1. decode)

在许多系统上, 可以替代 。
openssl enc -d -base64 -A
base64 --decode
kubeconfig

  1. 在工作目录中,用以下命令创建

istio-reader-service-account
服务账号对应的
文件:

  1. $ cat < ${KUBECFG_FILE}

  2. apiVersion: v1

  3. clusters:

    • cluster:
  4. certificate-authority-data: ${CA_DATA}

  5. server: ${SERVER}

  6. name: ${CLUSTER_NAME}

  7. contexts:

    • context:
  8. cluster: ${CLUSTER_NAME}

  9. user: ${CLUSTER_NAME}

  10. name: ${CLUSTER_NAME}

  11. current-context: ${CLUSTER_NAME}

  12. kind: Config

  13. preferences: {}

  14. users:

    • name: ${CLUSTER_NAME}
  15. user:

  16. token: ${TOKEN}

  17. EOF

  18. (可选) 创建环境变量文件以创建远程集群的 secret:

  19. $ cat < remote_cluster_env_vars

  20. export CLUSTER_NAME=${CLUSTER_NAME}

  21. export KUBECFG_FILE=${KUBECFG_FILE}

  22. export NAMESPACE=${NAMESPACE}

  23. EOF

至此,您已在当前目录中创建了远程集群的同。
kubeconfig

实例化凭证

文件。
文件的文件名与原始集群名称相

在运行 Istio 控制平面的集群上执行这一步骤。 该步骤使用了来自上一节的 、 和环境变量以及为远程集群的 secret 创建的文件。
kubeconfig
WORK_DIR
CLUSTER_NAME
NAMESPACE

如果您已经为远程集群的 secret 创建了环境变量文件,运行以下命令加载该文件:

  1. $ source remote_cluster_env_vars

您可以将 Istio 安装到不同的命名空间。 本步骤使用了 命名空间。
istio-system

不要为运行 Istio 控制平面的本地集群存储和标记 secrets。 Istio 始终可以感知到本地集群的 Kubernetes
凭据。
创建一个 secret 并为每个远程集群正确标记:

  1. $ kubectl create secret generic ${CLUSTER_NAME} --from-file ${KUBECFG_FILE} -n ${NAMESPACE}
  2. $ kubectl label secret ${CLUSTER_NAME} istio/multiCluster=true -n ${NAMESPACE}

Kubernetes secret 数据密钥必须符合
DNS-1123 subdomain
文件名使其符合格式,即可解决文件名的任何问题。

卸载远程集群

格式。 例如,文件名不能含有下划线。 只需更改

运行下列命令以卸载远程集群:

  1. $ istioctl manifest generate \
  2. –set profile=remote \
  3. –set values.global.controlPlaneSecurityEnabled=false \
  4. –set values.global.createRemoteSvcEndpoints=true \
  5. –set values.global.remotePilotCreateSvcEndpoint=true \
  6. –set values.global.remotePilotAddress=${PILOT_POD_IP} \
  7. –set values.global.remotePolicyAddress=${POLICY_POD_IP} \
  8. –set values.global.remoteTelemetryAddress=${TELEMETRY_POD_IP} \
  9. –set gateways.enabled=false \
  10. –set autoInjection.enabled=true | kubectl delete -f -

手动 sidecar 注入示例

下列例子展示了如何使用 istioctl manifest 命令来为禁用自动 sidecar 注入的远程集群生成清单。 另外,这
个例子还展示了如何通过 istioctl kube-inject 命令使用远程集群的清单。
configmaps
对远程集群执行下列步骤。
在开始之前,请按照设置环境变量部分中的说明设置端点 IP 环境变量。

  1. 安装 Istio 远程配置文件:

来为远程集群生成任意应用的

  1. $ istioctl manifest apply \

  2. –set profile=remote \

  3. –set values.global.controlPlaneSecurityEnabled=false \

  4. –set values.global.createRemoteSvcEndpoints=true \

  5. –set values.global.remotePilotCreateSvcEndpoint=true \

  6. –set values.global.remotePilotAddress=${PILOT_POD_IP} \

  7. –set values.global.remotePolicyAddress=${POLICY_POD_IP} \

  8. –set values.global.remoteTelemetryAddress=${TELEMETRY_POD_IP} \

  9. –set gateways.enabled=false \

  10. –set autoInjection.enabled=false

  11. 为每个远程集群生成 配置文件。

kubeconfig

  1. 为每个远程集群实例化凭证。

手动将 sidecars 注入到应用程序清单

以下示例
命令将 sidecar 注入到应用程序清单中。 在为远程集群设置了
上下文的

shell 中运行以下命令。
istioctl
kubeconfig

  1. $ ORIGINAL_SVC_MANIFEST=mysvc-v1.yaml

$ istioctl kube-inject --injectConfigMapName istio-sidecar-injector --meshConfigMapName istio -f

  1. ${ORIGINAL_SVC_MANIFEST} | kubectl apply -f -

从不同的集群中访问服务

Kubernetes 基于集群解析 DNS。 由于 DNS 解析与集群有关,因此无论服务端点的位置在哪,您都必须在运行客
户端的每个集群中定义服务对象。 为确保这种情况,请使用 将服务对象复制到每个集群。 复制可确保
kubectl
Kubernetes 可以解析任何集群中的服务名称。 由于服务对象是在命名空间中定义的,如果该命名空间不存在,您必须定义它,并将其包含在所有集群的服务定义中。

部署注意事项

前面的步骤提供了一个简单且按部就班的部署多集群环境的指导。 一个生产环境需要更多的步骤或更复杂的部署选
项。 本节收集 Istio 服务的端点 IPs 并使用它们来调用 。 这个过程会在远程集群上创建 Istio
istioctl
kube-dns

服务。 作为在远程集群中创建那些服务和端口的一部分,Kubernetes 会往目。
配置对象中添加 DNS 条

这让远程集群上的 配置对象可以为那些远程集群中的所有 Envoy sidecars 解析 Istio 服务名。
kube-dns
因为 Kubernetes pods 没有固定的 IPs,控制平面中的任意 Istio 服务 pod 的重启都会导致它的端点变化。因此,任何从远程集群到那个端点的连接都会断开。 这个行为记录在 Istio 问题 #4822。
有几个选项可以避免或解决这个情况。本节概述了这些选项:

更新 DNS 条目
使用负载均衡服务类型
通过网关暴露这些 Istio 服务

更新 DNS 条目

本地 Istio 控制平面发生任何故障或重新启动时,必须使用 Istio 服务的正确端点映射更新远程集群上的
。 有许多方法可以做到这一点。 最明显的是在控制平面集群上的 Istio 服务重新启动后,在远程集群
kube-dns
中重新运行 命令。
istioctl

使用负载均衡服务类型

在 Kubernetes 中,您可以声明一个服务的服务类型为服务类型。
LoadBalancer
。 更多信息请参考 Kubernetes 文档的

Pod 重启问题的一个简单的解决方案就是为 Istio 服务使用负载均衡器。 然后,您可以使用负载均衡器的 IPs
作为 Istio 服务的端点 IPs 来配置远程集群。 您可能需要下列 Istio 服务的负载均衡器 IPs:

目前,Istio 安装没有提供用于为 Istio 服务指定服务类型的选项。 您可以在 Istio 清单中手动指定服务类型。
istio-pilot
istio-telemetry istio-policy

通过网关暴露这些 Istio 服务

这个方法使用了 Istio ingress 网关功能。 远程集群需要 、 和
istio-pilot
istio-telemetry
istio-
服务指向 Istio ingress 网关的负载均衡器 IP。 然后,所有的服务指向相同的 IP。 您必须接着创建
policy
destination rules 以在 ingress 网关的主集群中访问到对应的 Istio 服务。此方法提供了两种选择:
重用提供的清单所创建的默认 Istio ingress 网关。您只需要添加正确的 destination rules。

为多集群创建另外一个 Istio ingress 网关。

安全性

Istio 支持在控制平面组件之间以及注入到应用的 pods 的 sidecar 之间部署双向 TLS。

控制平面安全性

按照这些步骤启用控制平面安全性:

  1. 部署 Istio 控制平面集群需要:

启用控制平面安全性。

禁用 证书自签名。
citadel

Istio 控制平面命名空间中具有证书颁发机构(CA)证书的名为 的 secret。
cacerts

  1. 部署 Istio 远程集群需要:

启用控制平面安全性。

禁用 证书自签名。
citadel

Istio 控制平面命名空间中具有 CA 证书的名为 的 secret。 主集群的证书颁发机构
cacerts

(CA)或根 CA 必须也为远程集群签名 CA 证书。

Istio pilot 服务主机名可被 DNS 解析。 DNS 解析是必需的,因为 Istio 将 sidecar 配置为
使用 主题名称格式来验证证书主题名称。
istio-pilot.

设置控制平面 IPs 或可解析的主机名。

应用 pods 间的双向 TLS

按照这些步骤以为所有应用 pods 启用双向 TLS:

| 1. 部署 | Istio 控制平面集群需要:
启用全局双向 TLS。
禁用 Citadel 证书自签名。 | | | |
| — | — | — | — | — |
|
| Istio 控制平面命名空间中具有 | CA 证书的名为 |

cacerts | 的 secret。 |
| 2. 部署 | Istio 远程集群需要: | | | |
|
| 启用全局双向 TLS。 | | | |
|
| 禁用 Citadel 证书自签名。 | | | |
|
| Istio 控制平面命名空间中具有 | CA 证书的名为 |

cacerts | 的 secret。 主集群的 CA 或根 CA |

必须也为远程集群签名 CA 证书。
对于控制平面安全性和应用 pod 安全性步骤,CA 证书的步骤相同。

部署示例

这个示例过程将在同时启用控制平面双向 TLS 和应用 pod 双向 TLS 的情况下安装 Istio。 该过程用无选择器的服务和端点来设置远程集群。 Istio Pilot 用该服务和端点以让远程 sidecars 可以通过 Istio 的本地

Kubernetes DNS 解析
istio-pilot.istio-system

主集群:部署控制平面集群

cacerts
主机名。

  1. 使用

istio-system
命名空间中的 Istio 证书示例创建
secret:

  1. $ kubectl create ns istio-system

$ kubectl create secret generic cacerts -n istio-system --from-file=samples/certs/ca-cert.pem --from- file=samples/certs/ca-key.pem --from-file=samples/certs/root-cert.pem --from-file=samples/certs/cert-

  1. chain.pem

  2. 部署 Istio 控制平面,并为控制平面和应用程序容器启用安全性:

  3. $ istioctl manifest apply \

  4. –set values.global.mtls.enabled=true \

  5. –set values.security.selfSigned=false

远程集群:部署 Istio 组件

cacerts

  1. 使用

istio-system
命名空间中的 Istio 证书示例创建
secret:

  1. $ kubectl create ns istio-system

$ kubectl create secret generic cacerts -n istio-system --from-file=samples/certs/ca-cert.pem --from- file=samples/certs/ca-key.pem --from-file=samples/certs/root-cert.pem --from-file=samples/certs/cert-

  1. chain.pem

  2. 按照设置环境变量部分中的说明设置端点 IP 环境变量。

  3. 以下命令部署远程集群的组件,并为控制平面和应用程序 pod 启用安全性,并启用 Istio Pilot 无选择器服务和端点的创建,以在远程集群中获取 DNS 条目。

  4. $ istioctl manifest apply \

  5. –set profile=remote \

  6. –set values.global.mtls.enabled=true \

  7. –set values.security.selfSigned=false \

  8. –set values.global.createRemoteSvcEndpoints=true \

  9. –set values.global.remotePilotCreateSvcEndpoint=true \

  10. –set values.global.remotePilotAddress=${PILOT_POD_IP} \

  11. –set values.global.remotePolicyAddress=${POLICY_POD_IP} \

  12. –set values.global.remoteTelemetryAddress=${TELEMETRY_POD_IP} \

  13. –set gateways.enabled=false \

  14. –set autoInjection.enabled=true

  15. 要为远程集群生成 配置文件,请遵循 Kubernetes 配置部分中的步骤。

kubeconfig

主集群:实例化凭证

您必须为每个远程集群都实例化凭证。请按照实例化凭证过程完成部署。

恭喜

您已将所有群集中的所有 Istio 组件都配置为在应用 sidecars、控制平面组件和其他应用 sidecars 之间使用双向 TLS。

相关内容

共享的控制平面(多网络)
跨多个 Kubernetes 集群安装一个 Istio 网格,使互不联通的集群网络共享同一个控制平面。控制平面副本集
通过控制平面副本集实例,在多个 Kubernetes 集群上安装 Istio 网格。简化地多集群安装[实验性]

配置一个跨多个 Kubernetes 集群的 Istio 网格。使用 Admiral 管理 Istio 多集群的配置和服务发现
为 Istio deployment(cluster)提供自动化 Istio 配置,并让其像单个网格一样工作。
DNS 证书管理
在 Istio 中配置和管理 DNS 证书。安全管理 Webhook
一种更安全管理 Istio webhook 的方法。

共享的控制平面(多网络)

遵循本指南配置一个多集群网格,使用共享的 控制平面,并通过网关连通彼此网络隔离的集群。 Istio 位置感知的服务路由特性,可以根据请求源所在的位置将请求路由至不同的 endpoints。

遵循本指南中的说明,将安装一个两集群网格,如下图所示:

Shared Istio control plane topology spanning multiple Kubernetes clusters using gateways

主集群
运行全部的 Istio 控制平面组件集,而
只运行 Istio Citadel、Sidecar

注入器以及 Ingress 网关。 不同集群的工作负载之间既不要求 VPN 连接也不要求直接网络访问。
cluster1
cluster2

前提条件

两个或多个 Kubernetes 集群,版本为:1.15, 1.16, 1.17, 1.18。

有权限部署 Istio 控制平面

两个 Kubernetes 集群(称为 和 )。
cluster1
cluster2

为了运行本配置,
cluster1
必须能够访问
的 Kubernetes API server。

你可以使用 kubectl 命令带上 --context 参数去访问集群 和
cluster2
cluster1
cluster2
kubectl get pods --context cluster1 。 使用如下命令列出你的上下文:
, 例如

2. CURRENTNAMECLUSTERAUTHINFONAMESPACE
3. *cluster1cluster1user@foo.comdefault
4.cluster2cluster2user@foo.comdefault

保存集群的上下文到环境变量:

  1. $ kubectl config get-contexts

  2. $ export CTX_CLUSTER1=$(kubectl config view -o jsonpath=‘{.contexts[0].name}’)

  3. $ export CTX_CLUSTER2=$(kubectl config view -o jsonpath=‘{.contexts[1].name}’)

  4. $ echo CTX_CLUSTER1 = ${CTX_CLUSTER1}, CTX_CLUSTER2 = ${CTX_CLUSTER2}

  5. CTX_CLUSTER1 = cluster1, CTX_CLUSTER2 = cluster2

如果你有超过两个集群的上下文并且你想要使用前两个以外的集群配置你的网格,你需要手动将环境变量设置为你需要的上下文名称。

安装多集群网格

在本配置中,安装 Istio 时同时开启控制平面和应用 pods 的双向 TLS。 对于共享的根 CA,使用 Istio 示例
cluster2
cacerts

目录下相同的 Istio 证书,在 和
cluster1
中都创建相同的
secret。

下文命令安装 cluster2 时,创建一个无 selector 的服务,并为 创建一个
istio-pilot.istio-system
endpoint,其地址为 cluster1 的 Istio ingress gateway。 它们用于通过 ingress gateway 安全地访问 cluster1 中的 pilot,无需双向 TLS 终端。

安装集群 1(主集群)

  1. 在 中部署 Istio:

cluster1

当启用多集群所需的附加组件时,Istio 控制平面的资源占用量可能会增长,甚至超过 Kubernetes 集群安装平台安装步骤中的默认容量。 如果因 CPU 或内存资源不足导致 Istio 服务无法调度,可以考虑在集群中添加更多节点,或按需升级为更大内存容量的实例。

  1. $ kubectl create --context=$CTX_CLUSTER1 ns istio-system

$ kubectl create --context=$CTX_CLUSTER1 secret generic cacerts -n istio-system --from- file=samples/certs/ca-cert.pem --from-file=samples/certs/ca-key.pem --from-file=samples/certs/root-

  1. cert.pem --from-file=samples/certs/cert-chain.pem
  2. $ istioctl manifest apply --context=$CTX_CLUSTER1 \
  3. -f install/kubernetes/operator/examples/multicluster/values-istio-multicluster-primary.yaml

注意网关地址设置为
0.0.0.0
的网关公网 IP。
cluster2
。这些是临时的占位值,在下文章节集群部署后,将被更新为 和

等待 中的 Istio pods 就绪:
cluster1
cluster1

1. $ kubectl get pods --context=$CTX_CLUSTER1 -n istio-system
2. NAME READY STATUSRESTARTSAGE
3. istio-citadel-55d8b59798-6hnx4 1/1 Running083s
4. istio-galley-c74b77787-lrtr5 2/2 Running082s
5. istio-ingressgateway-684f5df677-shzhm1/1Running083s
6. istio-pilot-5495bc8885-2rgmf2/2Running082s
7. istio-policy-69cdf5db4c-x4sct2/2Running283s
8. istio-sidecar-injector-5749cf7cfc-pgd951/1Running082s
9. istio-telemetry-646db5ddbd-gvp6l2/2Running183s
10. prometheus-685585888b-4tvf71/1Running083s
  1. 创建一个 ingress 网关访问 中的服务:

cluster2

  1. $ kubectl apply --context=$CTX_CLUSTER1 -f - <<EOF
  2. apiVersion: networking.istio.io/v1alpha3
  3. kind: Gateway
  4. metadata:
  5. name: cluster-aware-gateway
  6. namespace: istio-system
  7. spec:
  8. selector:
  9. istio: ingressgateway
  10. servers:
    • port:
  11. number: 443
  12. name: tls
  13. protocol: TLS
  14. tls:
  15. mode: AUTO_PASSTHROUGH
  16. hosts:
    • “*.local”
  17. EOF

本例 配置 443 端口来将流经的入口流量导向请求 SNI 头中指明的目标服务,其中 SNI 的顶级
Gateway
域名为 local(譬如:Kubernetes DNS 域名)。 从源至目标 sidecar,始终使用双向 TLS 连接。

尽管应用于
cluster1
,该网关实例也会影响
,因为两个集群通过同一个 Pilot 通信。

  1. 确定 的 ingress IP 和端口。

cluster2
cluster1

  1. 设置 的当前上下文为

kubectl
CTX_CLUSTER1

  1. $ export ORIGINAL_CONTEXT=$(kubectl config current-context)

  2. $ kubectl config use-context $CTX_CLUSTER1

    1. 按照确定 ingress IP 和端口中的说明,设置环境变量 及 。

INGRESS_HOST
SECURE_INGRESS_PORT

  1. 恢复之前的 上下文:

kubectl

  1. $ kubectl config use-context $ORIGINAL_CONTEXT

  2. $ unset ORIGINAL_CONTEXT

    1. 打印 及 :

INGRESS_HOST
SECURE_INGRESS_PORT

  1. $ echo The ingress gateway of cluster1: address= I N G R E S S H O S T , p o r t = INGRESS_HOST, port= INGRESSHOST,port=SECURE_INGRESS_PORT

  2. 更新网格网络配置中的网关地址。编辑 :

istio
ConfigMap

  1. $ kubectl edit cm -n istio-system --context=$CTX_CLUSTER1 istio

将网关地址和 的端口分别更新为 cluster1 的 ingress 主机和端口,然后保存并退出。注
network1
意该地址在配置文件中出现两次,第二次位于 values.yaml: 下方。
一旦保存,Pilot 将自动读取更新后的网络配置。

安装集群 2

  1. 输出 的网关地址:

cluster1

  1. $ export LOCAL_GW_ADDR= ( k u b e c t l g e t − − c o n t e x t = (kubectl get --context= (kubectlgetcontext=CTX_CLUSTER1 svc --selector=app=istio-ingressgateway \

-n istio-system -o jsonpath=‘{.items[0].status.loadBalancer.ingress[0].ip}’) && echo

  1. ${LOCAL_GW_ADDR}

该命令将网关地址设置为网关的公共 IP 并显示。
若负载均衡配置没有设置 IP 地址,命令将执行失败。DNS 域名支持尚未实现,亟待解决。

  1. 在 中部署 Istio:

cluster2

  1. $ kubectl create --context=$CTX_CLUSTER2 ns istio-system

$ kubectl create --context=$CTX_CLUSTER2 secret generic cacerts -n istio-system --from- file=samples/certs/ca-cert.pem --from-file=samples/certs/ca-key.pem --from-file=samples/certs/root-

  1. cert.pem --from-file=samples/certs/cert-chain.pem

$ CLUSTER_NAME= ( k u b e c t l − − c o n t e x t = (kubectl --context= (kubectlcontext=CTX_CLUSTER2 config view --minify=true -o

  1. jsonpath=‘{.clusters[].name}’)
  2. $ istioctl manifest apply --context=$CTX_CLUSTER2 \
  3. –set profile=remote \
  4. –set values.global.mtls.enabled=true \
  5. –set values.gateways.enabled=true \
  6. –set values.security.selfSigned=false \
  7. –set values.global.createRemoteSvcEndpoints=true \
  8. –set values.global.remotePilotCreateSvcEndpoint=true \
  9. –set values.global.remotePilotAddress=${LOCAL_GW_ADDR} \
  10. –set values.global.remotePolicyAddress=${LOCAL_GW_ADDR} \
  11. –set values.global.remoteTelemetryAddress=${LOCAL_GW_ADDR} \
  12. –set values.gateways.istio-ingressgateway.env.ISTIO_META_NETWORK=“network2” \
  13. –set values.global.network=“network2” \
  14. –set values.global.multiCluster.clusterName=${CLUSTER_NAME} \
  15. –set autoInjection.enabled=true

等待 中的 Istio pods 就绪, 除外。
cluster2
istio-ingressgateway

  1. $ kubectl get pods --context=$CTX_CLUSTER2 -n istio-system -l istio!=ingressgateway
  2. NAME READY STATUS RESTARTS AGE
3. istio-citadel-55d8b59798-nlk2z1/1Running026s
4. istio-sidecar-injector-5749cf7cfc-s6r7p1/1Running025s

下一节执行该操作。
istio-ingressgateway
cluster1
cluster2
无法就绪,直到在
的 Istio 控制面板中配置好 watch 。

  1. 确定 的 ingress IP 和口。

cluster2

  1. 设置 的当前上下文为

kubectl
CTX_CLUSTER2

  1. $ export ORIGINAL_CONTEXT=$(kubectl config current-context)

  2. $ kubectl config use-context $CTX_CLUSTER2

    1. 按照确定 ingress IP 和端口中的说明,设置环境变量 和 。

INGRESS_HOST
SECURE_INGRESS_PORT

  1. 恢复之前的 上下文:

kubectl

  1. $ kubectl config use-context $ORIGINAL_CONTEXT

  2. $ unset ORIGINAL_CONTEXT

    1. 打印 和 :

INGRESS_HOST
SECURE_INGRESS_PORT

  1. $ echo The ingress gateway of cluster2: address= I N G R E S S H O S T , p o r t = INGRESS_HOST, port= INGRESSHOST,port=SECURE_INGRESS_PORT

  2. 更新网格网络配置中的网关地址。编辑 :

istio
ConfigMap

  1. $ kubectl edit cm -n istio-system --context=$CTX_CLUSTER1 istio

将 的网关地址和端口分别更新为 cluster2 的 ingress 主机和端口,然后保存并退出。注
network2
意该地址在配置文件中出现两次,第二次位于 values.yaml: 下方。

一旦保存,Pilot 将自动读取更新后的网络配置。

  1. 准 备环境变量, 服务账户 istio-reader-service-account 的配置文件 n2-k8s-config :

$ CLUSTER_NAME= ( k u b e c t l − − c o n t e x t = (kubectl --context= (kubectlcontext=CTX_CLUSTER2 config view --minify=true -o

  1. jsonpath=‘{.clusters[].name}’)

$ SERVER= ( k u b e c t l − − c o n t e x t = (kubectl --context= (kubectlcontext=CTX_CLUSTER2 config view --minify=true -o

  1. jsonpath=‘{.clusters[].cluster.server}’)

$ SECRET_NAME= ( k u b e c t l − − c o n t e x t = (kubectl --context= (kubectlcontext=CTX_CLUSTER2 get sa istio-reader-service-account -n istio-system -o

  1. jsonpath=‘{.secrets[].name}’)

$ CA_DATA= ( k u b e c t l g e t − − c o n t e x t = (kubectl get --context= (kubectlgetcontext=CTX_CLUSTER2 secret ${SECRET_NAME} -n istio-system -o jsonpath=" 4. {.data[‘ca.crt’]}“)
$ TOKEN= ( k u b e c t l g e t − − c o n t e x t = (kubectl get --context= (kubectlgetcontext=CTX_CLUSTER2 secret ${SECRET_NAME} -n istio-system -o jsonpath=”
5. {.data[‘token’]}" | base64 --decode)

在许多系统中, 可以替换为 。
base64 --decode
openssl enc -d -base64 -A

  1. 在工作目录中创建文件 :

n2-k8s-config

  1. $ cat < n2-k8s-config
  2. apiVersion: v1
  3. kind: Config
  4. clusters:
    • cluster:
  5. certificate-authority-data: ${CA_DATA}
  6. server: ${SERVER}
  7. name: ${CLUSTER_NAME}
  8. contexts:
    • context:
  9. cluster: ${CLUSTER_NAME}
  10. user: ${CLUSTER_NAME}
  11. name: ${CLUSTER_NAME}
  12. current-context: ${CLUSTER_NAME}
  13. users:
    • name: ${CLUSTER_NAME}
  14. user:
  15. token: ${TOKEN}
  16. EOF

启动 watching 集群 2{start-watching-cluster-2}

  1. 执行下面命令,添加并标记 Kubernetes cluster2 的 secret。 执行完这些命令, 中的

cluster1
Istio Pilot 将开始 watching cluster2 的服务和实例,如同对待 一样。
cluster1

$ kubectl create --context=$CTX_CLUSTER1 secret generic n2-k8s-secret --from-file n2-k8s-config -n

  1. istio-system

  2. $ kubectl label --context=$CTX_CLUSTER1 secret n2-k8s-secret istio/multiCluster=true -n istio-system

  3. 等待 就绪:

istio-ingressgateway

2. NAMEREADYSTATUSRESTARTSAGE
3. istio-ingressgateway-5c667f4f84-bscff1/1Running016m

现在, 和 均已安装完成,可以部署一个案例服务。

  1. $ kubectl get pods --context=$CTX_CLUSTER2 -n istio-system -l istio=ingressgateway
    cluster1
    cluster2

部署案例服务

cluster1
cluster2

如上图所示,部署两个区别是
helloworld
helloworld
服务,一个运行在镜像的版本不同。
中,另一个运行在
中。 二者的

在集群 2 中部署 helloworld v2

  1. 创建一个 命名空间,用 label 标识开启 sidecar 自动注入:

sample

  1. $ kubectl create --context=$CTX_CLUSTER2 ns sample

  2. $ kubectl label --context=$CTX_CLUSTER2 namespace sample istio-injection=enabled

  3. 部署 :

helloworld v2

ZipZip

$ kubectl create --context=$CTX_CLUSTER2 -f @samples/helloworld/helloworld.yaml@ -l app=helloworld -n

  1. sample

  2. $ kubectl create --context=$CTX_CLUSTER2 -f @samples/helloworld/helloworld.yaml@ -l version=v2 -n sample

  3. 确认 正在运行:

  4. $ kubectl get po --context=$CTX_CLUSTER2 -n sample
    helloworld v2

2. NAMEREADYSTATUSRESTARTSAGE
3. helloworld-v2-7dd57c44c4-f56gq2/2Running035s

在集群 1 中部署 helloworld v1

  1. 创建一个 命名空间,用 label 标识开启 sidecar 自动注入:

sample

  1. $ kubectl create --context=$CTX_CLUSTER1 ns sample

  2. $ kubectl label --context=$CTX_CLUSTER1 namespace sample istio-injection=enabled

  3. 部署 :

helloworld v1

ZipZip

$ kubectl create --context=$CTX_CLUSTER1 -f @samples/helloworld/helloworld.yaml@ -l app=helloworld -n

  1. sample

  2. $ kubectl create --context=$CTX_CLUSTER1 -f @samples/helloworld/helloworld.yaml@ -l version=v1 -n sample

  3. 确认 正在运行:

  4. $ kubectl get po --context=$CTX_CLUSTER1 -n sample
    helloworld v1

2. NAMEREADYSTATUSRESTARTSAGE
3. helloworld-v1-d4557d97b-pv2hr2/2Running040s

跨集群路由实践

为了演示访问
helloworld

服务。
helloworld
sleep
服务的流量如何跨两个集群进行分发,我们从网格内的另一个
服务请求

  1. 在两个集群中均部署 服务:

sleep

ZipZip

  1. $ kubectl apply --context=$CTX_CLUSTER1 -f @samples/sleep/sleep.yaml@ -n sample

  2. $ kubectl apply --context=$CTX_CLUSTER2 -f @samples/sleep/sleep.yaml@ -n sample

  3. 等待 服务启动:

sleep

  1. $ kubectl get po --context=$CTX_CLUSTER1 -n sample -l app=sleep

  2. sleep-754684654f-n6bzf 2/2 Running 0 5s

  3. $ kubectl get po --context=$CTX_CLUSTER2 -n sample -l app=sleep

  4. sleep-754684654f-dzl9j 2/2 Running 0 5s

  5. 从 请求 服务若干次:

cluster1
helloworld.sample

$ kubectl exec --context=$CTX_CLUSTER1 -it -n sample -c sleep ( k u b e c t l g e t p o d − − c o n t e x t = (kubectl get pod --context= (kubectlgetpodcontext=CTX_CLUSTER1

  1. -n sample -l app=sleep -o jsonpath=‘{.items[0].metadata.name}’) – curl helloworld.sample:5000/hello

  2. 从 请求 服务若干次:

cluster2
helloworld.sample

$ kubectl exec --context=$CTX_CLUSTER2 -it -n sample -c sleep ( k u b e c t l g e t p o d − − c o n t e x t = (kubectl get pod --context= (kubectlgetpodcontext=CTX_CLUSTER2

  1. -n sample -l app=sleep -o jsonpath=‘{.items[0].metadata.name}’) – curl helloworld.sample:5000/hello

如果设置正确,访问
的流量将在 和
之间分发,返回的响应结果或

者为 或者为
helloworld.sample
v2 :
cluster1
cluster2
v1

  1. Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8
  2. Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv

也可以通过打印 sleep 的 容器日志,验证访问 endpoints 的 IP 地址。
istio-proxy

$ kubectl logs --context=$CTX_CLUSTER1 -n sample ( k u b e c t l g e t p o d − − c o n t e x t = (kubectl get pod --context= (kubectlgetpodcontext=CTX_CLUSTER1 -n sample -l

  1. app=sleep -o jsonpath=‘{.items[0].metadata.name}’) istio-proxy
    [2018-11-25T12:37:52.077Z] “GET /hello HTTP/1.1” 200 - 0 60 190 189 “-” “curl/7.60.0” “6e096efe-f550-4dfa-
    8c8c-ba164baf4679” “helloworld.sample:5000” “192.23.120.32:15443”
  2. outbound|5000||helloworld.sample.svc.cluster.local - 10.20.194.146:5000 10.10.0.89:59496 -
    [2018-11-25T12:38:06.745Z] “GET /hello HTTP/1.1” 200 - 0 60 171 170 “-” “curl/7.60.0” “6f93c9cc-d32a-4878-
    b56a-086a740045d2” “helloworld.sample:5000” “10.10.0.90:5000”
  3. outbound|5000||helloworld.sample.svc.cluster.local - 10.20.194.146:5000 10.10.0.89:59646 -

在 cluster1 中,当请求分发给 v2
时, cluster2
10.10.0.90:5000
给 v1 时, cluster1 的实例 IP(
的网关 IP(
)被记录。
)被记录,当请求分发

$ kubectl logs --context=$CTX_CLUSTER2 -n sample ( k u b e c t l g e t p o d − − c o n t e x t = (kubectl get pod --context= (kubectlgetpodcontext=CTX_CLUSTER2 -n sample -l

  1. app=sleep -o jsonpath=‘{.items[0].metadata.name}’) istio-proxy
    [2019-05-25T08:06:11.468Z] “GET /hello HTTP/1.1” 200 - “-” 0 60 177 176 “-” “curl/7.60.0” “58cfb92b-b217-4602-
    af67-7de8f63543d8” “helloworld.sample:5000” “192.168.1.246:15443”
  2. outbound|5000||helloworld.sample.svc.cluster.local - 10.107.117.235:5000 10.32.0.10:36840 -
    [2019-05-25T08:06:12.834Z] “GET /hello HTTP/1.1” 200 - “-” 0 60 181 180 “-” “curl/7.60.0” “ce480b56-fafd-468b-
    9996-9fea5257cb1e” “helloworld.sample:5000” “10.32.0.9:5000”
  3. outbound|5000||helloworld.sample.svc.cluster.local - 10.107.117.235:5000 10.32.0.10:36886 -

在 cluster2 中,当请求分发给 v1
192.23.120.32:15443
时, cluster1
10.32.0.9:5000
192.168.1.246:15443
给 v2 时, cluster2 的网关 IP(
的网关 IP (
)被记录。
)被记录,当请求分发

清除

执行如下命令清除示例服务以及 Istio 组件。

清除集群 :
cluster2

  1. $ istioctl manifest generate --context=$CTX_CLUSTER2 \
  2. –set profile=remote \
  3. –set values.global.mtls.enabled=true \
  4. –set values.gateways.enabled=true \
  5. –set values.security.selfSigned=false \
  6. –set values.global.createRemoteSvcEndpoints=true \
  7. –set values.global.remotePilotCreateSvcEndpoint=true \
  8. –set values.global.remotePilotAddress=${LOCAL_GW_ADDR} \
  9. –set values.global.remotePolicyAddress=${LOCAL_GW_ADDR} \
  10. –set values.global.remoteTelemetryAddress=${LOCAL_GW_ADDR} \
  11. –set values.gateways.istio-ingressgateway.env.ISTIO_META_NETWORK=“network2” \
  12. –set values.global.network=“network2” \
  13. –set autoInjection.enabled=true | kubectl --context=$CTX_CLUSTER2 delete -f -
  14. $ kubectl delete --context=$CTX_CLUSTER2 ns sample
  15. $ rm n2-k8s-config

$ unset CTX_CLUSTER2 CLUSTER_NAME SERVER SECRET_NAME CA_DATA TOKEN INGRESS_HOST SECURE_INGRESS_PORT

  1. INGRESS_PORT LOCAL_GW_ADDR

清除集群 :
cluster1

  1. $ istioctl manifest generate --context=$CTX_CLUSTER1 \

-f install/kubernetes/operator/examples/multicluster/values-istio-multicluster-primary.yaml | kubectl –

  1. context=$CTX_CLUSTER1 delete -f -
  2. $ kubectl delete --context=$CTX_CLUSTER1 ns sample
  3. $ unset CTX_CLUSTER1
  4. $ rm n2-k8s-config

相关内容

共享控制平面(单一网络)
安装一个跨多个 Kubernetes 集群的 Istio 网格,多集群共享控制平面,并且集群间通过 VPN 互连。控制平面副本集
通过控制平面副本集实例,在多个 Kubernetes 集群上安装 Istio 网格。简化地多集群安装[实验性]
配置一个跨多个 Kubernetes 集群的 Istio 网格。使用 Admiral 管理 Istio 多集群的配置和服务发现
为 Istio deployment(cluster)提供自动化 Istio 配置,并让其像单个网格一样工作。

DNS 证书管理
在 Istio 中配置和管理 DNS 证书。安全管理 Webhook
一种更安全管理 Istio webhook 的方法。

升级

选择与您先前用于安装 Istio 的方法相对应的升级指南。

使用 istioctl 命令升级 Istio [实验中]

使用 istioctl 命令来升级或降级 Istio。

使用 Helm 升级

升级 Istio 控制平面,可以选择使用 Helm 升级 CNI 插件。

使用 istioctl 命令升级 Istio [实验中]

以下信息描述了一个实验性功能,仅用于评估。

命令可为 Istio 进行升级。在进行升级之前,升级命令首先检查已安装的 Istio
istioctl experimental upgrade
是否符合升级要求。此外,如果升级命令检测到 Istio 版本间,配置中有任何默认值发生变化,都将及时提醒用户。

升级命令也可为 Istio 降级。

查看 升级参考来获取 命令的更多功能。
istioctl
istioctl experimental upgrade

升级前置条件

确保您在开始升级之前满足以下要求:

已安装 Istio 1.3.3 或更高版本。

Istio 是使用 istioctl 命令安装的。

升级步骤

升级过程中可能发生流量中断。为了缩短流量中断时间,请确保每个组件(Citadel 除外)至少运行有两个副本。同
时,确保 配置最小可用性为 1。
PodDisruptionBudgets

本节中的命令应该使用新版本的
istioctl
命令运行,可以在下载包的
目录中找到该命令。

  1. 下载新版本 Istio 并切换目录为新版本目录。

bin/

  1. 查看支持的版本列表,验证 命令是否支持从当前版本升级

istoctl

  1. $ istioctl manifest versions

  2. 确保 Kubernetes 配置指向要升级的集群:

  3. $ kubectl config view

  4. 运行以下命令开始升级:

  5. $ istioctl experimental upgrade -f <your-custom-configuration-file>

是 IstioControlPlane API Custom Resource Definition 文件,该文件用于自定义安装当前运行版本的 Istio。

如果您安装 Istio 时,使用了 选项,例如:
-f
istioctl manifest apply -f <IstioControlPlane-custom-

,那么
resource-definition-file>
istioctl upgrade
命令也必须使用相同的
选项参数值。

命令不支持 选项。因此,如果您的 Istio 是使用 --set 选项安装的,请
-f
istioctl upgrade
–set
istioctl upgrade

创建一个与配置项等效的配置文件,并将其传递给件。
命令。使用 -f 选项来加载配置文

如果省略了 选项,Istio 将使用默认配置升级。
-f

在执行多个步骤的检查后, 将要求您确认是否继续。
istioctl

  1. 将安装新版本的 Istio 控制平面,并显示完成状态。

istioctl

  1. 在使用 命令升级完成后,必须手动重启包含 Istio sidecar 的 pod 来更新数据平面:

istioctl

  1. $ kubectl rollout restart deployment

降级前置条件

确保您在开始升级之前满足以下要求:

已安装 Istio 1.4 或更高版本。

Istio 是使用 istioctl 命令安装的。

降级命令 的版本需要与要降级到的 Istio 版本相对应。例如:要将 Istio 从版本 1.4 降级
istioctl
到 1.3.3,需要使用 1.3.3 版本的 命令。
istioctl

降级到 Istio 1.4 或更高版本的步骤

您也可以使用 istioctl upgrade 命令降级 Istio 版本。步骤与前一部分提到的升级步骤相同,即使用低版本
Istio 配套的 istioctl 命令来降级。降级完成后,Istio 将会恢复到运行命令以前的安装版本。
istioctl experimental upgrade

降级到 Istio 1.3.3 或更低版本的步骤

istioctl experimental upgrade 命令在 Istio 1.3.3 及更低版本中是不可用的。因此,降级必须使用
istioctl
experimental manifest apply 命令。

该命令与 命令安装的 Istio 控制平面相同,但不会进行任何检查。例如:配置文
istioctl experimental upgrade
件中使用的默认值如果发生变化,将不会提醒用户。

相关内容

使用 Helm 升级
升级 Istio 控制平面,可以选择使用 Helm 升级 CNI 插件。

DNS 证书管理
在 Istio 中配置和管理 DNS 证书。安全管理 Webhook
一种更安全管理 Istio webhook 的方法。揭开 Istio Sidecar 注入模型的神秘面纱
揭秘 Istio 是如何将其数据平面组件添加到现有 deployment。Docker Desktop
在 Docker Desktop 中运行 Istio 的设置说明。
Helm 变更
关于 Istio 1.1 和 Istio 1.2 之间的 Helm chart 安装选项的变更。

使用 Helm 升级

请参阅本指南,以升级使用 Helm 安装的 Istio 控制平面和 sidecar 代理。升级过程可能会安装新的二级制文件,并可能修改配置和 API schema。升级过程可能导致服务停机。为了减少停机时间,请确保 Istio 控制平面组件和应用程序是多副本高可用的。

在将 Istio 版本升级到 1.6 之前,请务必查看[升级说明]。

Istio 不支持 跨版本升级。仅支持从 1.5 版本升级到 1.6 版本。如果您使用的是旧版本,请先升级到 1.5 版本。

升级步骤

下载新版本 Istio,并切换目录到新版本的目录下。

Istio CNI 升级

如果您已经安装或计划安装 Istio CNI,请选择以下 互斥 选项之一,检查 Istio CNI 是否已经安装并进行升级:

您可以使用 Kubernetes 的滚动更新机制来升级 Istio CNI 组件。这适用于使用
kubectl apply
CNI 的情况。
kube-
部署 Istio

  1. 检查是否已安装 istio-cni 。找到

istio-cni-node
或 istio-system ):
system
pod 以及它们运行的命名空间(通常是

  1. $ kubectl get pods -l k8s-app=istio-cni-node --all-namespaces

$ NAMESPACE=$(kubectl get pods -l k8s-app=istio-cni-node --all-namespaces --output='jsonpath=

  1. {.items[0].metadata.namespace}')

  2. 如果

istio-cni


cni
安装在
以外的命名空间(例如:
),请删除

$ helm template install/kubernetes/helm/istio-cni --name=istio-cni --namespace=$NAMESPACE | kubectl

  1. delete -f -

  2. 在 命名空间中安装或升级 :

kube-system
istio-system
istio-
kube-system
istio-cni

$ helm template install/kubernetes/helm/istio-cni --name=istio-cni --namespace=kube-system | kubectl

  1. apply -f -

如果您已使用 Helm and Tiller 安装 Istio CNI,请优先使用 Helm 升级 Istio CNI。

  1. 检查 是否已安装,并检查安装在哪个命名空间:

istio-cni

  1. $ helm status istio-cni

  2. 根据下面几种情况来安装或升级 :

istio-cni

如您尚未安装 ,并决定安装它,则运行以下命令:
istio-cni
kube-system
istio-system

  1. $ helm install install/kubernetes/helm/istio-cni --name istio-cni --namespace kube-system

如果
istio-cni
行以下命令删除:
已被安装到
以外的命名空间(例如:
)中,请先运

  1. $ helm delete --purge istio-cni

然后,将其安装到 命名空间中:
kube-system

  1. $ helm install install/kubernetes/helm/istio-cni --name istio-cni --namespace kube-system

如果 已被安装到命名空间 中,则运行以下命令升级:
istio-cni
kube-system

  1. $ helm upgrade istio-cni install/kubernetes/helm/istio-cni --namespace kube-system

控制平面升级

Pilot, Galley, 策略, 遥测和 Sidecar 注入器。 选择下列 互斥 选项中的一种升级控制平面:

您可以使用 Kubernetes 的滚动升级机制来升级控制平面组件。这适用于使用件的情况,包括使用 Helm template 生成的配置。
kubectl apply
部署 Istio 组

  1. 使用 命令升级所有 Istio 的 CRD。等待 Kubernetes API 服务器提交升级的 CRD:

kubectl apply

  1. $ kubectl apply -f install/kubernetes/helm/istio-init/files/

  2. 等待所有的 Istio CRD 创建完成:

  3. $ kubectl -n istio-system wait --for=condition=complete job --all

  4. 应用更新模板:

  5. $ helm template install/kubernetes/helm/istio --name istio \

  6. –namespace istio-system | kubectl apply -f -

您必须使用与首次安装 Istio 相同的配置。

滚动更新进程会将所有的部署组件和 configmap 升级到新版本。当此进程执行完毕后,您的 Istio 控制平面将会升级到新版本。

您现有的应用程序无需任何更改,可以继续运行。如果新的控制平面有任何严重的问题,您可以通过应用旧版本的

yaml 文件来回滚此次变更。

如果您使用 Helm and Tiller 安装 Istio,推荐的方式是使用 Helm 来进行升级。

  1. 升级 chart 来更新所有 Istio 用户资源定义(CRD)。

istio-init

  1. $ helm upgrade --install istio-init install/kubernetes/helm/istio-init --namespace istio-system

  2. 等待所有的 Istio CRD 创建完成:

  3. $ kubectl -n istio-system wait --for=condition=complete job --all

  4. 升级 chart:
    istio

  5. $ helm upgrade istio install/kubernetes/helm/istio --namespace istio-system

如果安装了 Istio CNI,则通过添加 配置项来启用它。
–set istio_cni.enabled=true

Sidecar 升级

在升级控制平面后,已运行 Istio 的应用仍将使用旧的 sidecar。要升级 sidecar,您需要重新注入它。

如果您使用自动的 sidecar 注入方式,可以滚动更新所有 pod 来升级 sidecar。这样,新版本的 sidecar 将被自动重新注入。

要运行以下命令, 的版本需要 >= 1.15,必要时请进行升级。
kubectl

  1. $ kubectl rollout restart deployment --namespace default

如果使用手动注入,可以通过以下命令升级 sidecar:

  1. $ kubectl apply -f <(istioctl kube-inject -f $ORIGINAL_DEPLOYMENT_YAML)

如果 sidecar 之前使用了一些定制的配置文件注入,则需要将配置文件中的版本更改为新版本,并通过以下命令重新注入:

  1. $ kubectl apply -f <(istioctl kube-inject \
  2. –injectConfigFile inject-config.yaml \
  3. –filename $ORIGINAL_DEPLOYMENT_YAML)

相关内容

使用 istioctl 命令升级 Istio [实验中]
使用 istioctl 命令来升级或降级 Istio。

DNS 证书管理
在 Istio 中配置和管理 DNS 证书。安全管理 Webhook
一种更安全管理 Istio webhook 的方法。揭开 Istio Sidecar 注入模型的神秘面纱
揭秘 Istio 是如何将其数据平面组件添加到现有 deployment。Docker Desktop
在 Docker Desktop 中运行 Istio 的设置说明。
Helm 变更
关于 Istio 1.1 和 Istio 1.2 之间的 Helm chart 安装选项的变更。

更多指南

有关其他设置任务的更多信息。

安装配置

描述 Istio 内置的安装配置文件。

设置 Sidecar

在应用程序 Pod 中使用 sidecar injector webhook 自动安装或使用 istioctl CLI 手动安装 Istio sidecar。

安装 Istio CNI 插件

安装并使用 Istio CNI 插件,可以让运维人员用更低的权限来部署服务。

安装配置

Istio 提供了两个附加的内置配置文件,被专门用于配置多集群部署 :

  1. remote: 用于配置通过共享控制平面搭建的多集群网格里的远程集群。
  2. multicluster-gateways: 用于配置通过多控制平面搭建的多集群网格里的集群。

**remote **配置文件仅安装两个 Istio 核心组件: 1.
istio-citadel
2.
istio-sidecar-injector

**multicluster-gateways **配置文件除了安装和 **default **配置文件相同的组件外,还增加了两个额外组件:

  1. 核心组件。

istio-egressgateway

  1. 插件。

coredns

参考多集群安装说明获取更多详细信息。

相关内容

Helm 变更
关于 Istio 1.1 和 Istio 1.2 之间的 Helm chart 安装选项的变更。
Helm 安装参数变动表
本文详细介绍了 Istio 1.0 系列到 Istio 1.1 系列之间的安装参数变化详情。
Helm 安装参数变动表
本文详细介绍了 Istio 1.2 系列到 Istio 1.3 系列之间的安装参数变化详情。
Istio Operator 简介
关于 Istio 基于 operator 的安装和控制平面管理特性的介绍。使用 Helm 自定义安装
安装和配置 Istio 以进行深入评估或用于生产。安装 Istio CNI 插件
安装并使用 Istio CNI 插件,可以让运维人员用更低的权限来部署服务。

设置 Sidecar

注入

为了充分利用 Istio 的所有特性,网格中的 pod 必须运行一个 Istio sidecar 代理。

下面的章节描述了向 pod 中注入 Istio sidecar 的两种方法:使用名空间的 Istio sidecar 注入器自动注入。
istioctl

手动注入直接修改配置,如 deployment,并将代理配置注入其中。
手动注入或启用 pod 所属命

当 pod 所属命名空间启用自动注入后,自动注入器会使用准入控制器在创建 Pod 时自动注入代理配置。

通过应用 ConfigMap 中定义的模版进行注入。
istio-sidecar-injector

手动注入 sidecar

要手动注入 deployment,请使用 :
istioctl kube-inject

Zip

  1. $ istioctl kube-inject -f @samples/sleep/sleep.yaml@ | kubectl apply -f -

默认情况下将使用集群内的配置,或者使用该配置的本地副本来完成注入。

$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath=‘{.data.config}’ > inject-

  1. config.yaml

$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath=‘{.data.values}’ > inject-

  1. values.yaml
  2. $ kubectl -n istio-system get configmap istio -o=jsonpath=‘{.data.mesh}’ > mesh-config.yaml

指定输入文件,运行 并部署。
kube-inject

Zip

  1. $ istioctl kube-inject \
  2. –injectConfigFile inject-config.yaml \
  3. –meshConfigFile mesh-config.yaml \
  4. –valuesFile inject-values.yaml \
  5. –filename @samples/sleep/sleep.yaml@ \
  6. | kubectl apply -f -

验证 sidecar 已经被注入到 READY 列下 的 sleep pod 中。
2/2

1. $ kubectl get pod -l app=sleep
2. NAME READYSTATUSRESTARTSAGE
3. sleep-64c6f57bc8-f5n4x 2/2Running024s

自动注入 sidecar

使用 Istio 提供的准入控制器变更 webhook,可以将 sidecar 自动添加到可用的 Kubernetes pod 中。

虽然准入控制器默认情况下是启动的,但一些 Kubernetes 发行版会禁用他们。如果出现这种情况,根据说明来启用准入控制器。

当你在一个命名空间中设置了
istio-injection=enabled
pod 都有将在创建时自动添加 sidecar。
标签,且 injection webhook 被启用后,任何新的

请注意,区别于手动注入,自动注入发生在 pod 层面。你将看不到 deployment 本身有任何更改。取而代之,需

要检查单独的 pod(使用
kubectl describe

禁用或更新注入 webhook

)来查询被注入的代理。

Sidecar 注入 webhook 是默认启用的。如果你希望禁用 webhook,可以使用 Helm 将
设置为 。
sidecarInjectorWebhook.enabled
false

还有很多其他选项可以配置。

部署应用

部署 sleep 应用。验证 deployment 和 pod 只有一个容器。

Zip

  1. $ kubectl apply -f @samples/sleep/sleep.yaml@
  2. $ kubectl get deployment -o wide
3. NAMEDESIREDCURRENTUP-TO-DATEAVAILABLEAGECONTAINERSIMAGESSELECTOR
4. sleep111112msleeptutum/curlapp=sleep
1. $ kubectl get pod
2. NAMEREADYSTATUSRESTARTSAGE
3. sleep-776b7bcdcd-7hpnk1/1Running04

将 namespace 标记为 。
default
istio-injection=enabled

3. NAMESTATUSAGEISTIO-INJECTION
4. defaultActive1henabled
5. istio-systemActive1h
6. kube-publicActive1h
7. kube-systemActive1h

注入发生在 pod 创建时。杀死正在运行的 pod 并验证新创建的 pod 是否注入 sidecar。原来的 pod 具有

  1. $ kubectl label namespace default istio-injection=enabled
  2. $ kubectl get namespace -L istio-injection

READY 为 1/1 的容器,注入 sidecar 后的 pod 则具有 READY 为 2/2 的容器。

|

  1. $ kubectl delete pod -l app=sleep
  2. $ kubectl get pod -l app=sleep
    | | | |
    | — | — | — | — |
    | 3. NAME READY | STATUS | RESTARTS | AGE |
    | 4. sleep-776b7bcdcd-7hpnk 1/1 | Terminating | 0 | 1m |
    | 5. sleep-776b7bcdcd-bhn9m 2/2 | Running | 0 | 7s |

查看已注入 pod 的详细状态。你应该看到被注入的
istio-proxy
pod 的名称替换以下命令。
Running
容器和对应的卷。请确保使用状态为

  1. $ kubectl describe pod -l app=sleep

禁用 namespace 注入,并确认新的 pod 在创建时没有 sidecar。
default

4. NAMEREADYSTATUSRESTARTSAGE
5. sleep-776b7bcdcd-bhn9m2/2Terminating02m
6. sleep-776b7bcdcd-gmvnr1/1Running02s
理解原理
  1. $ kubectl label namespace default istio-injection-
  2. $ kubectl delete pod -l app=sleep
  3. $ kubectl get pod

当 Kubernetes 调用 webhook 时, 配置被应用。默认配置将 sidecar 注入到所有拥
admissionregistration
有 标签的 namespace 下的 pod 中。 配置字典指定了注入
istio-injection=enabled
istio-sidecar-injector
sidecar 的配置。如需更改指定哪些 namespace 被注入,你可以使用以下命令编辑

MutatingWebhookConfiguration

  1. $ kubectl edit mutatingwebhookconfiguration istio-sidecar-injector

修改 之后,您应该重启 sidecar 注入器的 pod。
MutatingWebhookConfiguration

例如,你可以修改 使 sidecar 注入到所有不具有某个标签的 namespace 中。
MutatingWebhookConfiguration
MutatingWebhookConfiguration

编辑这项配置是更高阶的操作。更多有关信息,请参考 Kubernetes 的档。
API 文

策略

  • 默认情况下不会将 sidecar 注入到 pod 中。在 pod 模板规范中添加的值为 true 来覆盖默认值并启用注入。
    disabled
    sidecar.istio.io/inject

  • Sidecar 将默认注入到 pod 中。在 pod 模板规范中添加
    enabled
    sidecar.istio.io/inject
    false 来覆盖默认值并禁用注入。
    的值为

下面的示例使用 注解来禁用 sidecar 注入。
sidecar.istio.io/inject

  1. apiVersion: apps/v1

  2. kind: Deployment

  3. metadata:

  4. name: ignored

  5. spec:

  6. template:

  7. metadata:

  8. annotations:

  9. sidecar.istio.io/inject: “false”

  10. spec:

  11. containers:

    • name: ignored
  12. image: tutum/curl

  13. command: [“/bin/sleep”,“infinity”]

模版

Sidecar 注入模板使用 https://golang.org/pkg/text/template,当解析和执行时,将解码成下面的结构体,包含需要注入到 pod 中的容器和卷。

  1. type SidecarInjectionSpec struct {
  2. }
    RewriteAppHTTPProbe bool
    InitContainers Containers Volumes DNSConfig
    ImagePullSecrets
    []corev1.Container []corev1.Container []corev1.Volume
    *corev1.PodDNSConfig
    yaml:"rewriteAppHTTPProbe"
    yaml:"initContainers"
    yaml:"containers"
    yaml:"volumes"
    yaml:"dnsConfig"
    []corev1.LocalObjectReference yaml:"imagePullSecrets"

该模板在运行时应用于以下数据结构。

  1. type SidecarTemplateData struct {

DeploymentMeta *metav1.ObjectMeta
ObjectMeta
Spec ProxyConfig
*metav1.ObjectMeta
*corev1.PodSpec
*meshconfig.ProxyConfig // Defined by https://istio.io/docs/reference/config/service-
5. mesh.html#proxyconfig
MeshConfig
*meshconfig.MeshConfig // Defined by https://istio.io/docs/reference/config/service-
6. mesh.html#meshconfig
7. }

ObjectMeta 和
来源于 pod。 和
来源于
namespace

下 istio 的 ConfigMap。模版可以使用这些数据有条件地定义被注入的卷和容器。
Spec
ProxyConfig
MeshConfig
istio-system
例如下面的模版。

  1. containers:

    • name: istio-proxy
  2. image: istio.io/proxy:0.5.0

  3. args:

    • proxy
    • sidecar
    • –configPath
    • {{ .ProxyConfig.ConfigPath }}
    • –binaryPath
    • {{ .ProxyConfig.BinaryPath }}
    • –serviceCluster
  4. {{ if ne “” (index .ObjectMeta.Labels “app”) -}}

    • {{ index .ObjectMeta.Labels “app” }}
  5. {{ else -}}

    • “istio-proxy” 16. {{ end -}}

将在使用模版 定义的 pod 被应用时变为
samples/sleep/sleep.yaml

  1. containers:
    • name: istio-proxy
  2. image: istio.io/proxy:0.5.0
  3. args:
    • proxy
    • sidecar
    • –configPath
    • /etc/istio/proxy
    • –binaryPath
    • /usr/local/bin/envoy
    • –serviceCluster
    • sleep
更多控制:添加例外

有些情况下用户无法控制 pod 的创建,例如,这些用户是被其他人创建的。因此他们无法在 pod 中添加注解,来明确是否安装 sidecar。
sidecar.istio.io/inject

考虑在部署应用程序时创建辅助 pod 作为中间步骤。例如 OpenShift Source to Image Builds,创建这样的pod 用于 应用程序的源代码。构建二进制工件后,应用程序 pod 就可以运行了,而用于辅助的 pod 则被丢弃。这些中间 pod 不应该有 Istio sidecar,即使策略被设置为 enabled ,并且名称空间被正确标记为自动注入。

对于这种情况,你可以根据 pod 上的标签,指示 Istio 不要在那些 pod 中注入 sidecar。可以通过编辑
istio-sidecar-injector 的 ConfigMap 并添加 neverInjectSelector 条目来实现。它是一个 Kubernetes 标签选择器数组,使用 OR’d ,在第一次匹配成功后则停止。看一个例子:

  1. apiVersion: v1

  2. kind: ConfigMap

  3. metadata:

  4. name: istio-sidecar-injector

  5. data:

  6. config: |-

  7. policy: enabled

  8. neverInjectSelector:

    • matchExpressions:
    • {key: openshift.io/build.name, operator: Exists}
    • matchExpressions:
    • {key: openshift.io/deployer-pod-for.name, operator: Exists}
  9. template: |-

  10. initContainers: 15. …

上面声明的意思是:永远不要注入带有 或者 标签
openshift.io/build.name
openshift.io/deployer-pod-for.name
的 pod —— 标签的值无关紧要,我们只检查键是否存在。添加了这个规则之后,就涵盖了上面所说的 OpenShift
的 用例,也就是说辅助 pod 不会被注入 sidecar(因为 source-to-image 工具产生的辅助 pod 明确包含这些标签)。

完整起见,您还可以使用一个名为
alwaysInjectSelector
配标签选择器的 pod 中,而忽略全局策略。
的字段,它具有类似的语法,总是将 sidecar 注入匹

使用标签选择器的方法在表达这些例外时提供了很大的灵活性。查看这些文档看看可以用它们来做什么!

值得注意的是,pod 中的注解具有比标签选择器更高的优先级。如果一个 pod 有的标记那么它将先被履行。因此,优先级的顺序为:
sidecar.istio.io/inject:
“true/false”

Pod Annotations → NeverInjectSelector → AlwaysInjectSelector → Default Policy

卸载 sidecar 自动注入器
  1. $ kubectl delete mutatingwebhookconfiguration istio-sidecar-injector
  2. $ kubectl -n istio-system delete service istio-sidecar-injector
  3. $ kubectl -n istio-system delete deployment istio-sidecar-injector
  4. $ kubectl -n istio-system delete serviceaccount istio-sidecar-injector-service-account
  5. $ kubectl delete clusterrole istio-sidecar-injector-istio-system
  6. $ kubectl delete clusterrolebinding istio-sidecar-injector-admin-role-binding-istio-system

上面的命令不会从 pod 中移除注入的 sidecar。需要进行滚动更新或者直接删除 pod,并强制 deployment 创建它们。

此外,还可以清理在此任务中修改过的其他资源。

  1. $ kubectl label namespace default istio-injection-

相关内容

Pod 和 Service
在启用了 Istio 的集群中运行 Kubernetes 的 Pod 和 Service,您需要做些准备。揭开 Istio Sidecar 注入模型的神秘面纱
揭秘 Istio 是如何将其数据平面组件添加到现有 deployment。安装 Istio CNI 插件

安装并使用 Istio CNI 插件,可以让运维人员用更低的权限来部署服务。
DNS 证书管理
在 Istio 中配置和管理 DNS 证书。安全管理 Webhook
一种更安全管理 Istio webhook 的方法。

Docker Desktop

在 Docker Desktop 中运行 Istio 的设置说明。

安装 Istio CNI 插件

pullPolicyAlwaysinstall-cni 镜像的拉取策略。

logLevel | panic , fatal , error , warn , info , debug |

warn |

CNI 程序的日志级别。 |
|

excludeNamespaces |

[]string | [ istio-system
] | 排除 Istio pod 检查的命名空间列表。 |
|

cniBinDir | |

/opt/cni/bin | 必须与集群中的 —cni-bin-dir ( kubelet
参数)值一样。 |
|

cniConfDir | |

/etc/cni/net.d | 必须与集群中的 —cni-conf-dir ( kubelet
参数)值一样。 |
|

cniConfFileName | | | 不设置会自动查找 cni-conf-dir 目录的第一个文件(与 kubelet 一致)。主要用来测试 install-cni 的插件配置。如果设置了, install-cni 将会把插件配置注入到cni-conf-dir 目录的该文件里面。 |
|

psp_cluster_role | | | 该值指的是一个 ClusterRole 并被用于在istio-cni 的命名空间中创建一个 RoleBinding 。当您使用 Pod 安全策略并且希望让 istio-cni 作为 priviliged Pods 运行时,这会非常有用。 |
| podAnnotations | | {} | pod 级别自定义的附加注解。 |

这些选项可以在
命令中通过
来访问,可以作为 的参

数,或者作为自定义覆盖文件中的相应路径。
istioctl manifest
values.cni.
–set

排除特定的 Kubernetes 命名空间

本例使用 Helm 来执行以下任务:

安装 Istio CNI 插件。配置其日志级别。
忽略以下命名空间中的 pods:
istio-system foo_ns
bar_ns

参考使用 Helm 进行自定义安装中的完整说明。

使用以下命令来渲染并应用 Istio CNI 组件,并覆盖 的 和 参数的默认配置:
istio-cni
logLevel
excludeNamespaces

  1. $ istioctl manifest apply \

–set
–set cni.enabled=true
–set cni.components.cni.enabled=true
–set values.cni.logLevel=info
–set values.cni.excludeNamespaces={“istio-system,kube-system,foo_ns,bar_ns”}

““ ,会对所有流重定向。
逗号分隔的 CIDR 范围内的 IP 不定向。该选项仅在
includeOutbound
取值为 “_“ _时
逗号分隔的入站端这些流量会被重定Sidecar,取值为时会重定向所有端
逗号分隔的入站端列表中的端口不会到 Istio Side 仅在
includeInboundP
值为 “*” 时生
逗号分隔的出站端列表中的端口流量向到 Envoy 中。
逗号分隔的虚拟接列表中的虚拟接口量(来自 VM)将站流量。

,
,…

traffic.sidecar.istio.io/kubevirtInterfaces

,
,…

traffic.sidecar.istio.io/excludeOutboundPorts

,
,…

traffic.sidecar.istio.io/excludeInboundPorts
Pod 的
containerPorts
列表

,
,…

traffic.sidecar.istio.io/includeInboundPorts

,
,…

traffic.sidecar.istio.io/excludeOutboundIPRanges
,…

日志

Istio CNI 插件在容器运行时的进程空间内运行。因此 进程会将插件的日志记到它的日志中。
kubelet

和应用的初始化容器的兼容性

kubelet

Istio CNI 插件可能会导致与应用以下步骤启动一个注入的 pod:
initContainers
的网络连通性。 使用 Istio CNI 时,
会通过

  1. Istio CNI 插件在 pod 内设置流量重定向到 Istio sidecar。
  2. 等待所有的初始化容器成功执行完毕。
  3. Istio sidecar 跟随 pod 的其它容器一起启动。

初始化容器在 sidecar 启动之前执行,这会导致在它们执行期间会有流量丢失。 可以用以下的一种或所有设置来防止流量丢失:

设置CIDRs。设置
traffic.sidecar.istio.io/excludeOutboundIPRanges
traffic.sidecar.istio.io/excludeOutboundPorts
注解来禁止重定向流量到任何与初始化容器有通信的注解来禁止重定向流量到初始化容器所用到的出站端口。

和其它 CNI 插件的兼容性

Istio CNI 插件维护着和当前的 容器同样的兼容性。
NET_ADMIN
istio-init

Istio CNI 插件作为一个链式 CNI 插件存在。也就是说它的配置会作为一个新的配置列表元素被加入到现存 CNI

插件。Istio CNI 插件只会把应用 Pod 的流量重定向到 Sidecar 中(通过在 Pod 的网络命名空间中使用完成)。
iptables
Istio CNI 插件应该不会与设置 Pod 网络的基本 CNI 插件有冲突,但并不是所有的 CNI 插件都经过了验证。

相关内容

Helm 变更
关于 Istio 1.1 和 Istio 1.2 之间的 Helm chart 安装选项的变更。
Helm 安装参数变动表
本文详细介绍了 Istio 1.0 系列到 Istio 1.1 系列之间的安装参数变化详情。
Helm 安装参数变动表
本文详细介绍了 Istio 1.2 系列到 Istio 1.3 系列之间的安装参数变化详情。
Pod 和 Service
在启用了 Istio 的集群中运行 Kubernetes 的 Pod 和 Service,您需要做些准备。使用 Helm 自定义安装
安装和配置 Istio 以进行深入评估或用于生产。安装选项(Helm)
描述使用 Helm chart 安装 Istio 时的可选项。

如何用 Istio 系统实现特定目标的行为。

流量管理

演示 Istio 的流量路由功能的任务。

安全

演示如何保护网格。

策略

演示策略执行功能。

可观察性

演示如何从网格收集遥测信息。

流量管理

演示 Istio 的流量路由功能的任务。

配置请求路由

此任务将展示如何将请求动态路由到微服务的多个版本。

故障注入

此任务说明如何注入故障并测试应用程序的弹性。

流量转移

展示如何将流量从旧版本迁移到新版本的服务。

TCP 流量转移

展示如何将一个服务的 TCP 流量从旧版本迁移到新版本。

设置请求超时

本任务用于示范如何使用 Istio 在 Envoy 中设置请求超时。

熔断

本任务展示如何为连接、请求以及异常检测配置熔断。

镜像

此任务演示了 Istio 的流量镜像/影子功能。

Ingress

控制 Istio 服务网格的入口流量。

Egress

控制 Istio 服务网格的出口流量。

配置请求路由

此任务将展示如何将请求动态路由到微服务的多个版本。

开始之前

按照安装指南中的说明安装 Istio。

部署 Bookinfo 示例应用程序。

查看流量管理的概念文档。在尝试此任务之前,您应该熟悉一些重要的术语,例如 destination rule
、_virtual service _和 _subset _。

关于这个任务

Istio Bookinfo 示例包含四个独立的微服务,每个微服务都有多个版本。 其中一个微服务 reviews 的三个不同版本已经部署并同时运行。 为了说明这导致的问题,在浏览器中访问 Bookinfo 应用程序的 /productpage 并刷新几次。 您会注意到,有时书评的输出包含星级评分,有时则不包含。 这是因为没有明确的默认服务版本路由, Istio 将以循环方式请求路由到所有可用版本。

此任务的最初目标是应用将所有流量路由到微服务的求 header 的值路由流量。
v1

应用 virtual service

(版本 1)的规则。稍后,您将应用规则根据 HTTP 请

要仅路由到一个版本,请应用为微服务设置默认版本的 virtual service。在这种情况下,virtual service
将所有流量路由到每个微服务的 版本。
v1

如果您还没有应用 destination rule,请先应用默认目标规则。

  1. 运行以下命令以应用 virtual services: Zip

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

由于配置传播是最终一致的,因此请等待几秒钟以使 virtual services 生效。

  1. 使用以下命令显示已定义的路由:

  2. $ kubectl get virtualservices -o yaml

  3. apiVersion: networking.istio.io/v1alpha3

  4. kind: VirtualService

  5. metadata:

  6. name: details

  7. spec:

  8. hosts:

    • details
  9. http:

    • route:
    • destination:
  10. host: details

  11. subset: v1 15. —

  12. apiVersion: networking.istio.io/v1alpha3

  13. kind: VirtualService

  14. metadata:

  15. name: productpage 20. …

  16. spec:

  17. gateways:

    • bookinfo-gateway
    • mesh
  18. hosts:

    • productpage
  19. http:

    • route:
    • destination:
  20. host: productpage

  21. subset: v1 32. —

  22. apiVersion: networking.istio.io/v1alpha3

  23. kind: VirtualService

  24. metadata:

  25. name: ratings 37. …

  26. spec:

  27. hosts:

    • ratings
  28. http:

    • route:
    • destination:
  29. host: ratings

  30. subset: v1 46. —

  31. apiVersion: networking.istio.io/v1alpha3

  32. kind: VirtualService

  33. metadata:

  34. name: reviews 51. …

  35. spec:

  36. hosts:

    • reviews
  37. http:

    • route:
    • destination:
  38. host: reviews


subset: v1

  1. 您还可以使用以下命令显示相应的 定义:

subset
reviews

  1. $ kubectl get destinationrules -o yaml

您已将 Istio 配置为路由到 Bookinfo 微服务的
v1

测试新的路由配置

版本,最重要的是
服务的版本 1。

您可以通过再次刷新 Bookinfo 应用程序的 轻松测试新配置。
/productpage
$GATEWAY_URL

  1. 在浏览器中打开 Bookinfo 站点。网址为
    http://$GATEWAY_URL/productpage
    的入口 IP 地址,如 Bookinfo 文档中所述。
    ,其中
    是外部

请注意,无论您刷新多少次,页面的评论部分都不会显示评级星标。这是因为您将 Istio 配置为 将评论服务
的所有流量路由到版本 ,而此版本的服务不访问星级评分服务。
reviews:v1

您已成功完成此任务的第一部分:将流量路由到服务的某一个版本。

基于用户身份的路由

接下来,您将更改路由配置,以便将来自特定用户的所有流量路由到特定服务版本。在这,来自名为 Jason 的用户
的所有流量将被路由到服务 。
reviews:v2

请注意,Istio 对用户身份没有任何特殊的内置机制。事实上,
服务在所有到
服务的
HTTP 请求中都增加了一个自定义的 请求头,从而达到了本例子的效果。
productpage
reviews
end-user

请记住, 是包含星级评分功能的版本。
reviews:v2

  1. 运行以下命令以启用基于用户的路由:

Zip

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

  2. 确认规则已创建:

  3. $ kubectl get virtualservice reviews -o yaml

  4. apiVersion: networking.istio.io/v1alpha3

  5. kind: VirtualService

  6. metadata:

  7. name: reviews 6. …

  8. spec:

  9. hosts:

    • reviews
  10. http:

    • match:
    • headers:
  11. end-user:

  12. exact: jason

  13. route:

    • destination:
  14. host: reviews

  15. subset: v2

    • route:
    • destination:
  16. host: reviews

  17. subset: v1

  18. 在 Bookinfo 应用程序的

/productpage
上,以用户
身份登录。

刷新浏览器。你看到了什么?星级评分显示在每个评论旁边。
jason

  1. 以其他用户身份登录(选择您想要的任何名称)。

刷新浏览器。现在星星消失了。这是因为除了 Jason 之外,所有用户的流量都被路由到 。
reviews:v1

您已成功配置 Istio 以根据用户身份路由流量。

理解原理

在此任务中,您首先使用 Istio 将 100% 的请求流量都路由到了 Bookinfo 服务的 v1 版本。 然后设置了一条
productpage
服务的 v2
end-user

路由规则,它根据由到了
reviews
服务发起的请求中的版本。
自定义请求头内容,选择性地将特定的流量路

请注意,Kubernetes 中的服务,如本任务中使用的 Bookinfo 服务,必须遵守某些特定限制,才能利用到
Istio 的 L7 路由特性优势。 参考 Pods 和 Services 需求了解详情。

在流量转移任务中,您将按照在此处学习到的相同的基本模式来配置路由规则,以逐步将流量从服务的一个版本迁移到另一个版本。

清除

  1. 删除应用程序的 virtual service: Zip

  2. $ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@

  3. 如果您不打算探索任何后续任务,请参阅 Bookinfo 清理的说明关闭应用程序。

相关内容

使用 Admiral 管理 Istio 多集群的配置和服务发现
为 Istio deployment(cluster)提供自动化 Istio 配置,并让其像单个网格一样工作。把 Istio 作为外部服务的代理
把 Istio 入口网关配置为外部服务的代理。用于隔离和边界保护的多网格部署
将需要隔离的环境部署到单独的网格中,并通过网格联邦启用网格间通信。
Istio 中安全管控出口流量,第三部分
管控出口流量的备选方案比较,包括性能因素。
Istio 中的安全管控出口流量,第二部分
使用 Istio 的出口流量管控来阻止相关出口流量攻击。
Istio 中的安全管控出口流量,第一部分涉及出口流量攻击和出口流量管控要求。

故障注入

此任务说明如何注入故障并测试应用程序的弹性。

开始之前

按照安装指南中的说明设置 Istio 。

部署示例应用程序 Bookinfo,并应用 默认目标规则。

在流量管理概念文档中查看有关故障注入的讨论。

通过执行配置请求路由任务或运行以下命令来初始化应用程序版本路由:

ZipZip

  1. $ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
  2. $ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@

经过上面的配置,下面是请求的流程:
jason


productpage

productpage
reviews:v2

reviews:v1

注入 HTTP 延迟故障


(其他用户)
ratings
(针对
用户)

为了测试微服务应用程序 Bookinfo 的弹性,我们将为用户 在 和 服务之间
jason
reviews:v2
ratings
注入一个 7 秒的延迟。 这个测试将会发现一个故意引入 Bookinfo 应用程序中的 bug。

注意 服务对 服务的调用具有 10 秒的硬编码连接超时。 因此,尽管引入了 7 秒的延
reviews:v2
ratings
迟,我们仍然期望端到端的流程是没有任何错误的。

  1. 创建故障注入规则以延迟来自测试用户 的流量:

jason

Zip

  1. $ kubectl apply -f @samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml@

  2. 确认规则已经创建:

  3. $ kubectl get virtualservice ratings -o yaml

  4. apiVersion: networking.istio.io/v1alpha3

  5. kind: VirtualService

  6. metadata:

  7. name: ratings 6. …

  8. spec:

  9. hosts:

    • ratings
  10. http:

    • fault:
  11. delay:

  12. fixedDelay: 7s

  13. percentage:

  14. value: 100

  15. match:

    • headers:
  16. end-user:

  17. exact: jason

  18. route:

    • destination:
  19. host: ratings

  20. subset: v1

    • route:
    • destination:
  21. host: ratings

  22. subset: v1

新的规则可能需要几秒钟才能传播到所有的 pod 。

测试延迟配置

  1. 通过浏览器打开 Bookinfo 应用。

  2. 使用用户

jason
登陆到
页面。

你期望 Bookinfo 主页在大约 7 秒钟加载完成并且没有错误。 但是,出现了一个问题:Reviews 部分显示了错误消息:
/productpage

  1. Error fetching product reviews!

  2. Sorry, product reviews are currently unavailable for this book.

  3. 查看页面的响应时间:

    1. 打开浏览器的 开发工具 菜单
    2. 打开 网络 标签
    3. 重新加载 页面。你会看到页面加载实际上用了大约 6s。

productpage

理解原理

你发现了一个 bug。微服务中有硬编码超时,导致 服务失败。
reviews

按照预期,我们引入的 7 秒延迟不会影响到 reviews 服务,因为 和 服务间的超时被硬
reviews
ratings
编码为 10 秒。 但是,在 productpage 和 reviews 服务之间也有一个 3 秒的硬编码的超时,再加 1 次重试,一共 6 秒。 结果, productpage 对 reviews 的调用在 6 秒后提前超时并抛出错误了。

这种类型的错误可能发生在典型的由不同的团队独立开发不同的微服务的企业应用程序中。 Istio 的故障注入规则可以帮助您识别此类异常,而不会影响最终用户。

请注意,此次故障注入限制为仅影响用户 。如果您以任何其他用户身份登录,则不会遇到任何延迟。
jason

错误修复

这种问题通常会这么解决:

  1. 增加

与 服务之间的超时或降低
与 的超时

  1. 终止并重启修复后的微服务

productpage
reviews
reviews
ratings

  1. 确认 页面正常响应且没有任何错误

/productpage

但是, 服务的 v3 版本已经修复了这个问题。 reviews:v3 服务已将 与 的
reviews
reviews
ratings
超时时间从 10 秒降低为 2.5 秒,因此它可以兼容(小于)下游的 productpage 的请求。

如果您按照流量转移任务所述将所有流量转移到
reviews:v3
值,例如 2 秒,然后确认端到端的流程没有任何错误。

注入 HTTP abort 故障

, 您可以尝试修改延迟规则为任何低于 2.5 秒的数

测试微服务弹性的另一种方法是引入 HTTP abort 故障。 这个任务将给引入一个 HTTP abort。
ratings

在这种情况下,我们希望页面能够立即加载,同时显示
Ratings service is currently unavailable
微服务为测试用户

这样的消息。
jason

  1. 为用户 创建一个发送 HTTP abort 的故障注入规则:

jason

Zip

  1. $ kubectl apply -f @samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml@

  2. 确认规则已经创建:

  3. $ kubectl get virtualservice ratings -o yaml

  4. apiVersion: networking.istio.io/v1alpha3

  5. kind: VirtualService

  6. metadata:

  7. name: ratings 6. …

  8. spec:

  9. hosts:

    • ratings
  10. http:

    • fault:
  11. abort:

  12. httpStatus: 500

  13. percentage:

  14. value: 100

  15. match:

    • headers:
  16. end-user:

  17. exact: jason

  18. route:

    • destination:
  19. host: ratings

  20. subset: v1

    • route:
    • destination:
  21. host: ratings

  22. subset: v1

测试中止配置

  1. 用浏览器打开 Bookinfo 应用。

  2. 使用用户

jason
登陆到
页面。

如果规则成功传播到所有的 pod,您应该能立即看到页面加载并看到消息。
/productpage
Ratings service is currently
unavailable

  1. 如果您注销用户 jason 或在匿名窗口(或其他浏览器)中打开 Bookinfo 应用程序, 您将看到

reviews:v1
ratings
为除 jason 以外的其他用户调用了您不会看到任何错误消息。
/productpage

清理

(完全不调用
)。 因此,

  1. 删除应用程序路由规则:

Zip

  1. $ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@

  2. 如果您不打算探索任何后续任务,请参阅 Bookinfo 清理说明以关闭应用程序。

相关内容

使用 Admiral 管理 Istio 多集群的配置和服务发现
为 Istio deployment(cluster)提供自动化 Istio 配置,并让其像单个网格一样工作。把 Istio 作为外部服务的代理
把 Istio 入口网关配置为外部服务的代理。用于隔离和边界保护的多网格部署

将需要隔离的环境部署到单独的网格中,并通过网格联邦启用网格间通信。
Istio 中安全管控出口流量,第三部分
管控出口流量的备选方案比较,包括性能因素。
Istio 中的安全管控出口流量,第二部分
使用 Istio 的出口流量管控来阻止相关出口流量攻击。
Istio 中的安全管控出口流量,第一部分涉及出口流量攻击和出口流量管控要求。

流量转移

本任务将向您展示如何逐步将流量从一个版本的微服务迁移到另一个版本。例如,您可以将流量从旧版本迁移到新版本。

一个常见的用例是将流量从一个版本的微服务逐渐迁移到另一个版本。在 Istio 中,您可以通过配置一系列规则来实现此目标, 这些规则将一定百分比的流量路由到一个或另一个服务。在本任务中,您将会把 50% 的流量发送到
reviews:v1
reviews:v3
reviews:v3

迁移。
,另外 50% 的流量发送到
。然后,再把 100% 的流量发送到
来完成

开始之前

按照安装指南中的说明安装 Istio。

部署 Bookinfo 示例应用程序。

查看流量管理概念文档。

应用基于权重的路由

如果尚未应用目标规则,请按照应用默认目标规则中的说明进行操作。

  1. 首先,运行此命令将所有流量路由到各个微服务的 版本。

v1

Zip

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

  2. 在浏览器中打开 Bookinfo 站点。网址为

http://$GATEWAY_URL/productpage
ingress 的外部 IP 地址,其描述参见 Bookinfo 文档。
,其中 是

请注意,不管刷新多少次,页面的评论部分都不会显示评级星号。 这是因为 Istio 被配置为将 reviews
$GATEWAY_URL
服务的的所有流量都路由到了 版本, 而该版本的服务不会访问带星级的 ratings 服务。
reviews:v1

  1. 使用下面的命令把 50% 的流量从 转移到 :

reviews:v1
reviews:v3

Zip

  1. $ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml@

等待几秒钟以让新的规则传播到代理中生效。

  1. 确认规则已被替换:

  2. $ kubectl get virtualservice reviews -o yaml

  3. apiVersion: networking.istio.io/v1alpha3

  4. kind: VirtualService

  5. metadata:

  6. name: reviews 6. …

  7. spec:

  8. hosts:

    • reviews
  9. http:

    • route:
    • destination:
  10. host: reviews

  11. subset: v1

  12. weight: 50

    • destination:
  13. host: reviews

  14. subset: v3

  15. weight: 50

  16. 刷新浏览器中的 /productpage 页面,大约有 50% 的几率会看到页面中出带 红色 星级的评价内容。这是

ratings
v1
因为 版本的 reviews 访问了带星级评级的
v3
服务,但
版本却没有。

在目前的 Envoy sidecar 实现中,可能需要刷新 /productpage 很多次–可能 15 次或更多–才能看到正确的流量分发的效果。您可以通过修改规则将 90% 的流量路由到 v3 ,这样能看到更多带红色星级的评
价。

  1. 如果您认为 reviews:v3 微服务已经稳定,你可以通过应用此 virtual service 规则将 100% 的流量路由到 reviews:v3 :

Zip

  1. $ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-v3.yaml@

现在,当您刷新 时,您将始终看到带有 红色 星级评分的书评。
/productpage

理解原理

在这项任务中,我们使用 Istio 的权重路由功能将流量从旧版本的 服务迁移到新版本。 请注意,这和
reviews
使用容器编排平台的部署功能来进行版本迁移完全不同,后者使用了实例扩容来对流量进行管理。

使用 Istio,两个版本的发。
reviews
服务可以独立地进行扩容和缩容,而不会影响这两个服务版本之间的流量分

如果想了解支持自动伸缩的版本路由的更多信息,请查看使用 Istio 进行金丝雀部署 。

清理

  1. 删除应用程序路由规则。

Zip

  1. $ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@

  2. 如果您不打算探索任何后续任务,请参阅 Bookinfo 清理中的说明来关闭应用程序。

相关内容

使用 Admiral 管理 Istio 多集群的配置和服务发现
为 Istio deployment(cluster)提供自动化 Istio 配置,并让其像单个网格一样工作。把 Istio 作为外部服务的代理
把 Istio 入口网关配置为外部服务的代理。用于隔离和边界保护的多网格部署
将需要隔离的环境部署到单独的网格中,并通过网格联邦启用网格间通信。
Istio 中安全管控出口流量,第三部分
管控出口流量的备选方案比较,包括性能因素。
Istio 中的安全管控出口流量,第二部分
使用 Istio 的出口流量管控来阻止相关出口流量攻击。
Istio 中的安全管控出口流量,第一部分涉及出口流量攻击和出口流量管控要求。

TCP 流量转移

本任务展示了如何逐步将 TCP 流量从微服务的一个版本迁移到另一个版本。例如,将 TCP 流量从旧版本迁移到新版本。

在 Istio 中,您可以通过配置一系列规则来实现此目标,这些规则按指定的百分比将流量路由到不同的服务。在此
任务 中,将先把 100% 的 TCP 流量分配到 ,然后,再通过配置 Istio 路由权重把 20% 的 TCP
tcp-echo:v1
流量分 配到 。
tcp-echo:v2

开始之前

按照安装指南中的说明安装 Istio。

回顾流量管理概念文档。

应用基于权重的 TCP 路由

  1. 首先,部署微服务 的 版本。

tcp-echo
v1

第一步,为测试 TCP 流量转移创建命名空间

  1. $ kubectl create namespace istio-io-tcp-traffic-shifting

如果使用手动注入 sidecar,请使用下面命令: Zip

$ kubectl apply -f <(istioctl kube-inject -f @samples/tcp-echo/tcp-echo-services.yaml@) -n istio-

  1. io-tcp-traffic-shifting

命令用于在创建 deployments 之前 修改 文件。
istioctl kube-inject
tcp-echo-services.yaml

如果您使用的是启用了自动注入 sidecar 的集群,可以将
istio-io-tcp-traffic-shifting
namespace 标记为 。
istio-injection=enabled

  1. $ kubectl label namespace istio-io-tcp-traffic-shifting istio-injection=enabled

然后,只需使用 部署服务即可。
kubectl

Zip
v1

  1. $ kubectl apply -f @samples/tcp-echo/tcp-echo-services.yaml@ -n istio-io-tcp-traffic-shifting

  2. 接下来, 将目标为微服务

tcp-echo
的 TCP 流量全部路由到
版本。

Zip

  1. $ kubectl apply -f @samples/tcp-echo/tcp-echo-all-v1.yaml@ -n istio-io-tcp-traffic-shifting

  2. 确认 服务已启动并开始运行。

tcp-echo

下面的 $INGRESS_HOST 变量是 ingress 的外部 IP 地址,可参考 Ingress Gateways 文档。要获取
$INGRESS_PORT 变量的值,请使用以下命令。

$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o

  1. jsonpath=‘{.spec.ports[?(@.name==“tcp”)].port}’)

向微服务 发送一些 TCP 流量。
tcp-echo

4. oneMonNov1223:24:57UTC2018
5. oneMonNov1223:25:00UTC2018
6. oneMonNov1223:25:02UTC2018
7. oneMonNov1223:25:05UTC2018
8. oneMonNov1223:25:07UTC2018
9. oneMonNov1223:25:10UTC2018
10. oneMonNov1223:25:12UTC2018
11. oneMonNov1223:25:15UTC2018
12. oneMonNov1223:25:17UTC2018
13. oneMonNov1223:25:19UTC2018

可能需要通过 执行 命令,这取决于您的 Docker 安装。

  1. $ for i in {1…10}; do
    docker run -e INGRESS_HOST= I N G R E S S H O S T − e I N G R E S S P O R T = INGRESS_HOST -e INGRESS_PORT= INGRESSHOSTeINGRESSPORT=INGRESS_PORT -it --rm busybox sh -c "(date;

  2. sleep 1) | nc $INGRESS_HOST $INGRESS_PORT"; \

  3. done

sudo
docker
v1

您应该注意到,所有时间戳的前缀都是 _one _,这意味着所有流量都被路由到了版本。
tcp-echo
服务的

  1. 使用以下命令将 20% 的流量从 转移到 :

tcp-echo:v1
tcp-echo:v2

Zip

  1. $ kubectl apply -f @samples/tcp-echo/tcp-echo-20-v2.yaml@ -n istio-io-tcp-traffic-shifting

等待几秒钟,以使新规则在集群中传播和生效。

  1. 确认规则配置已替换完成:

  2. $ kubectl get virtualservice tcp-echo -o yaml -n istio-io-tcp-traffic-shifting

  3. apiVersion: networking.istio.io/v1alpha3

  4. kind: VirtualService

  5. metadata:

  6. name: tcp-echo 6. …

  7. spec:

  8. tcp:

    • match:
    • port: 31400
  9. route:

    • destination:
  10. host: tcp-echo

  11. port:

  12. number: 9000

  13. subset: v1

  14. weight: 80

    • destination:
  15. host: tcp-echo

  16. port:

  17. number: 9000

  18. subset: v2

  19. weight: 20

  20. 向 服务发送更多 TCP 流量。

tcp-echo

4. oneMonNov1223:38:45UTC2018
5. twoMonNov1223:38:47UTC2018
6. oneMonNov1223:38:50UTC2018
7. oneMonNov1223:38:52UTC2018
8. oneMonNov1223:38:55UTC2018
9. twoMonNov1223:38:57UTC2018
10. oneMonNov1223:39:00UTC2018
11. oneMonNov1223:39:02UTC2018
12. oneMonNov1223:39:05UTC2018
13. oneMonNov1223:39:07UTC2018

可能需要通过 执行 命令,这取决于您的 Docker 安装。

  1. $ for i in {1…10}; do
    docker run -e INGRESS_HOST= I N G R E S S H O S T − e I N G R E S S P O R T = INGRESS_HOST -e INGRESS_PORT= INGRESSHOSTeINGRESSPORT=INGRESS_PORT -it --rm busybox sh -c "(date;

  2. sleep 1) | nc $INGRESS_HOST $INGRESS_PORT"; \

  3. done

sudo
docker

现在应该发现,有大约 20% 的流量时间戳前缀是 _two _,这意味着有 80% 的 TCP 流量路由到了
tcp-

v1
v2

服务的
echo

理解原理

版本,与此同时有 20% 流量路由到了
版本。

这个任务中,使用 Istio 路由权重特性将 服务的 TCP 流量从旧版本迁移到了新版本。请注意,这与
tcp-echo
使用容 器编排平台的 deployment 进行版本迁移非常不同,后者(容器编排平台)是通过对特定组别的实例进行伸缩实现的。

在 Istio 中可以对配。
tcp-echo
服务的两个版本进行独立扩容和缩容,这个过程不会影响服务版本之间的流量分

有关不同版本间流量管理及自动伸缩的更多信息,请查看博客文章使用 Istio 进行金丝雀部署。

清理

  1. 删除 应用程序和路由规则。
    tcp-echo

ZipZip

  1. $ kubectl delete -f @samples/tcp-echo/tcp-echo-all-v1.yaml@ -n istio-io-tcp-traffic-shifting
  2. $ kubectl delete -f @samples/tcp-echo/tcp-echo-services.yaml@ -n istio-io-tcp-traffic-shifting
  3. $ kubectl delete namespace istio-io-tcp-traffic-shifting

相关内容

使用 Admiral 管理 Istio 多集群的配置和服务发现
为 Istio deployment(cluster)提供自动化 Istio 配置,并让其像单个网格一样工作。把 Istio 作为外部服务的代理
把 Istio 入口网关配置为外部服务的代理。用于隔离和边界保护的多网格部署
将需要隔离的环境部署到单独的网格中,并通过网格联邦启用网格间通信。
Istio 中安全管控出口流量,第三部分
管控出口流量的备选方案比较,包括性能因素。
Istio 中的安全管控出口流量,第二部分
使用 Istio 的出口流量管控来阻止相关出口流量攻击。
Istio 中的安全管控出口流量,第一部分涉及出口流量攻击和出口流量管控要求。

设置请求超时

本任务用于示范如何使用 Istio 在 Envoy 中设置请求超时。

开始之前

按照安装指南中的说明安装 Istio。

部署示例应用程序 Bookinfo,并应用默认目标规则。

运行以下命令初始化应用的版本路由:

Zip

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

请求超时

http 请求的超时可以用路由规则的 _timeout _字段来指定。 默认情况下,超时是禁用的,本任务中,会把
ratings

服务的超时设置为 1 秒。 为了观察效果,还需要在对
reviews
迟。
ratings
服务的调用上人为引入 2 秒的延

  1. 将请求路由到

reviews
服务的 v2 版本,它会发起对
服务的调用:

  1. $ kubectl apply -f - <<EOF

  2. apiVersion: networking.istio.io/v1alpha3

  3. kind: VirtualService

  4. metadata:

  5. name: reviews

  6. spec:

  7. hosts:

    • reviews
  8. http:

    • route:
    • destination:
  9. host: reviews

  10. subset: v2

  11. EOF

  12. 给对 服务的调用添加 2 秒的延迟:

ratings

  1. $ kubectl apply -f - <<EOF

  2. apiVersion: networking.istio.io/v1alpha3

  3. kind: VirtualService

  4. metadata:

  5. name: ratings

  6. spec:

  7. hosts:

    • ratings
  8. http:

    • fault:
  9. delay:

  10. percent: 100

  11. fixedDelay: 2s

  12. route:

    • destination:
  13. host: ratings

  14. subset: v1

  15. EOF

  16. 在浏览器中打开 Bookinfo 的网址 。

http://$GATEWAY_URL/productpage

这时可以看到 Bookinfo 应用运行正常(显示了评级的星型符号),但是每次刷新页面,都会有 2 秒的延迟。

  1. 现在给对 服务的调用增加一个半秒的请求超时:

reviews

  1. $ kubectl apply -f - <<EOF

  2. apiVersion: networking.istio.io/v1alpha3

  3. kind: VirtualService

  4. metadata:

  5. name: reviews

  6. spec:

  7. hosts:

    • reviews
  8. http:

    • route:
    • destination:
  9. host: reviews

  10. subset: v2

  11. timeout: 0.5s

  12. EOF

  13. 刷新 Bookinfo 页面。

这时候应该看到 1 秒钟就会返回,而不是之前的 2 秒钟,但 是不可用的。
reviews

即使超时配置为半秒,响应仍需要 1 秒,是因为 服务中存在硬编码重试,因此它在返回之前
productpage
调用 服务超时两次。
reviews

理解原理

本任务中,使用 Istio 为对 微服务的调用配置了半秒的请求超时。默认情况下请求超时是禁用的。
reviews
ratings
ratings

服务在处理请求时会接着调用
reviews
服务,用 Istio 在对
的调用中注入了两秒钟的

延迟,这样就让 服务要花费超过半秒的时间来完成调用,因此可以观察到超时。
reviews

可以观察到,Bookinfo 的页面(调用 服务来生成页面)没显示评论,而是显示了消息: Sorry,
reviews
**product reviews are currently unavailable for this book. **这就是它收到了来自 服务的超时错误信息。
reviews

如果看过故障注入任务,就会发现
微服务在调用
微服务时,还有它自己的应用级的超时

(3 秒)设置。 注意在本任务中使用 Istio 路由规则设置了半秒的超时。 如果将超时设置为大于 3 秒(比如 4
productpage
reviews
秒),则超时将不会有任何影响,因为这两个超时的限制性更强。 更多细节可以参考这里。
还有一点关于 Istio 中超时控制方面的补充说明,除了像本文一样在路由规则中进行超时设置之外,还可以进行请
x-envoy-upstream-rq-timeout-ms

求一级的设置,只需在应用的对外请求中加入设置单位是毫秒而不是秒。

清理

请求头即可。在这个请求头中的超时

删除应用程序的路由规则:

Zip

  1. $ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@

如果您不打算探索任何后续任务,请参阅 Bookinfo 清理的说明关闭应用程序。

相关内容

使用 Admiral 管理 Istio 多集群的配置和服务发现
为 Istio deployment(cluster)提供自动化 Istio 配置,并让其像单个网格一样工作。把 Istio 作为外部服务的代理
把 Istio 入口网关配置为外部服务的代理。用于隔离和边界保护的多网格部署
将需要隔离的环境部署到单独的网格中,并通过网格联邦启用网格间通信。
Istio 中安全管控出口流量,第三部分
管控出口流量的备选方案比较,包括性能因素。
Istio 中的安全管控出口流量,第二部分
使用 Istio 的出口流量管控来阻止相关出口流量攻击。
Istio 中的安全管控出口流量,第一部分涉及出口流量攻击和出口流量管控要求。

熔断

本任务展示如何为连接、请求以及异常检测配置熔断。

熔断,是创建弹性微服务应用程序的重要模式。熔断能够使您的应用程序具备应对来自故障、潜在峰值和其他 未知网络因素影响的能力。

这个任务中,你将配置熔断规则,然后通过有意的使熔断器“跳闸”来测试配置。

开始之前

跟随安装指南安装 Istio。

启动 httpbin 样例程序。

如果您启用了 sidecar 自动注入,通过以下命令部署 服务:
httpbin

Zip

  1. $ kubectl apply -f @samples/httpbin/httpbin.yaml@

否则,您必须在部署 应用程序前进行手动注入,部署命令如下:
httpbin

Zip

  1. $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@)

应用程序 作为此任务的后端服务。
httpbin

配置熔断器

  1. 创建一个目标规则,在调用 服务时应用熔断设置:

httpbin

如果您的 Istio 启用了双向 TLS 身份验证,则必须在应用目标规则之前将 TLS 流量策略
mode:
添加到 。否则请求将产生 503 错误,如这里所述。
ISTIO_MUTUAL
DestinationRule

  1. $ kubectl apply -f - <<EOF

  2. apiVersion: networking.istio.io/v1alpha3

  3. kind: DestinationRule

  4. metadata:

  5. name: httpbin

  6. spec:

  7. host: httpbin

  8. trafficPolicy:

  9. connectionPool:

  10. tcp:

  11. maxConnections: 1

  12. http:

  13. http1MaxPendingRequests: 1

  14. maxRequestsPerConnection: 1

  15. outlierDetection:

  16. consecutiveErrors: 1

  17. interval: 1s

  18. baseEjectionTime: 3m

  19. maxEjectionPercent: 100

  20. EOF

  21. 验证目标规则是否已正确创建:

  22. $ kubectl get destinationrule httpbin -o yaml

  23. apiVersion: networking.istio.io/v1alpha3

  24. kind: DestinationRule

  25. metadata:

  26. name: httpbin 6. …

  27. spec:

  28. host: httpbin

  29. trafficPolicy:

  30. connectionPool:

  31. http:

  32. http1MaxPendingRequests: 1

  33. maxRequestsPerConnection: 1

  34. tcp:

  35. maxConnections: 1

  36. outlierDetection:

  37. baseEjectionTime: 180.000s

  38. consecutiveErrors: 1

  39. interval: 1.000s

  40. maxEjectionPercent: 100

增加一个客户

创建客户端程序以发送流量到 服务。这是一个名为 Fortio 的负载测试客户的,其可以控制连接数、并
httpbin
发数及发送 HTTP 请求的延迟。通过 Fortio 能够有效的触发前面 在 中设置的熔断策略。
DestinationRule

  1. 向客户端注入 Istio Sidecar 代理,以便 Istio 对其网络交互进行管理:

Zip
-curl

  1. $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/sample-client/fortio-deploy.yaml@)

  2. 登入客户端 Pod 并使用 Fortio 工具调用

httpbin
服务。
参数表明发送一次调用:

  1. $ FORTIO_POD=$(kubectl get pod | grep fortio | awk ‘{ print $1 }’)

  2. $ kubectl exec -it $FORTIO_POD -c fortio /usr/bin/fortio – load -curl http://httpbin:8000/get

  3. HTTP/1.1 200 OK

  4. server: envoy

  5. date: Tue, 16 Jan 2018 23:47:00 GMT

  6. content-type: application/json

  7. access-control-allow-origin: *

  8. access-control-allow-credentials: true

  9. content-length: 445

  10. x-envoy-upstream-service-time: 36 11.

  11. {

  12. “args”: {},

  13. “headers”: {

  14. “Content-Length”: “0”,

  15. “Host”: “httpbin:8000”,

  16. “User-Agent”: “istio/fortio-0.6.2”,

  17. “X-B3-Sampled”: “1”,

  18. “X-B3-Spanid”: “824fbd828d809bf4”,

  19. “X-B3-Traceid”: “824fbd828d809bf4”,

  20. “X-Ot-Span-Context”: “824fbd828d809bf4;824fbd828d809bf4;0000000000000000”,

  21. “X-Request-Id”: “1ad2de20-806e-9622-949a-bd1d9735a3f4”

  22. },

  23. “origin”: “127.0.0.1”,

  24. “url”: “http://httpbin:8000/get”

  25. }

可以看到调用后端服务的请求已经成功!接下来,可以测试熔断。

触发熔断器

在 配置中,您定义了 maxConnections: 1 和 。 这些规则意味
DestinationRule
http1MaxPendingRequests: 1
着,如果并发的连接和请求数超过一个,在 istio-proxy 进行进一步的请求和连接时,后续请求或 连接将被阻止。

  1. 发送并发数为 2 的连接( ),请求 20 次( ):

-c 2
-n 20

$ kubectl exec -it $FORTIO_POD -c fortio /usr/bin/fortio – load -c 2 -qps 0 -n 20 -loglevel Warning

  1. http://httpbin:8000/get
  2. Fortio 0.6.2 running at 0 queries per second, 2->2 procs, for 5s: http://httpbin:8000/get
  3. Starting at max qps with 2 thread(s) [gomax 2] for exactly 20 calls (10 per thread + 0)
  4. 23:51:10 W http.go:617> Parsed non ok code 503 (HTTP/1.1 503) 5. Ended after 106.474079ms : 20 calls. qps=187.84

Aggregated Function Time : count 20 avg 0.010215375 +/- 0.003604 min 0.005172024 max 0.019434859 sum
6. 0.204307492
7. # range, mid point, percentile, count
8. >= 0.00517202 <= 0.006 , 0.00558601 , 5.00, 1
9. > 0.006 <= 0.007 , 0.0065 , 20.00, 3
10. > 0.007 <= 0.008 , 0.0075 , 30.00, 2
11. > 0.008 <= 0.009 , 0.0085 , 40.00, 2
12. > 0.009 <= 0.01 , 0.0095 , 60.00, 4
13. > 0.01 <= 0.011 , 0.0105 , 70.00, 2
14. > 0.011 <= 0.012 , 0.0115 , 75.00, 1

  1. 0.012 <= 0.014 , 0.013 , 90.00, 3

  2. 0.016 <= 0.018 , 0.017 , 95.00, 1

  3. 0.018 <= 0.0194349 , 0.0187174 , 100.00, 1

  4. target 50% 0.0095

  5. target 75% 0.012

  6. target 99% 0.0191479

  7. target 99.9% 0.0194062

  8. Code 200 : 19 (95.0 %)

  9. Code 503 : 1 (5.0 %)

  10. Response Header Sizes : count 20 avg 218.85 +/- 50.21 min 0 max 231 sum 4377

  11. Response Body/Total Sizes : count 20 avg 652.45 +/- 99.9 min 217 max 676 sum 13049

  12. All done 20 calls (plus 0 warmup) 10.215 ms avg, 187.8 qps

有趣的是,几乎所有的请求都完成了! 确实允许存在一些误差。
istio-proxy

  1. Code 200 : 19 (95.0 %)

  2. Code 503 : 1 (5.0 %)

  3. 将并发连接数提高到 3 个:

$ kubectl exec -it $FORTIO_POD -c fortio /usr/bin/fortio – load -c 3 -qps 0 -n 30 -loglevel Warning

  1. http://httpbin:8000/get

  2. Fortio 0.6.2 running at 0 queries per second, 2->2 procs, for 5s: http://httpbin:8000/get

  3. Starting at max qps with 3 thread(s) [gomax 2] for exactly 30 calls (10 per thread + 0)

  4. Ended after 71.05365ms : 30 calls. qps=422.22
    Aggregated Function Time : count 30 avg 0.0053360199 +/- 0.004219 min 0.000487853 max 0.018906468 sum

  5. 0.160080597

  6. range, mid point, percentile, count

  7. = 0.000487853 <= 0.001 , 0.000743926 , 10.00, 3

  8. 0.009 <= 0.01 , 0.0095 , 93.33, 2

  9. 0.014 <= 0.016 , 0.015 , 96.67, 1

  10. 0.018 <= 0.0189065 , 0.0184532 , 100.00, 1

  11. target 50% 0.00525

4. 23:51:51Whttp.go:617>Parsednonokcode503(HTTP/1.1503)
5. 23:51:51Whttp.go:617>Parsednonokcode503(HTTP/1.1503)
6. 23:51:51Whttp.go:617>Parsednonokcode503(HTTP/1.1503)
7. 23:51:51Whttp.go:617>Parsednonokcode503(HTTP/1.1503)
8. 23:51:51Whttp.go:617>Parsednonokcode503(HTTP/1.1503)
9. 23:51:51Whttp.go:617>Parsednonokcode503(HTTP/1.1503)
10. 23:51:51Whttp.go:617>Parsednonokcode503(HTTP/1.1503)
11. 23:51:51Whttp.go:617>Parsednonokcode503(HTTP/1.1503)
12. 23:51:51Whttp.go:617>Parsednonokcode503(HTTP/1.1503)
13. 23:51:51Whttp.go:617>Parsednonokcode503(HTTP/1.1503)
14. 23:51:51Whttp.go:617>Parsednonokcode503(HTTP/1.1503)
19. >0.001<=0.002, 0.0015, 30.00,6
20. >0.002<=0.003, 0.0025, 33.33,1
21. >0.003<=0.004, 0.0035, 40.00,2
22. >0.004<=0.005, 0.0045, 46.67,2
23. >0.005<=0.006, 0.0055, 60.00,4
24. >0.006<=0.007, 0.0065, 73.33,4
25. >0.007<=0.008, 0.0075, 80.00,2
26. >0.008<=0.009, 0.0085, 86.67,2
  1. target 75% 0.00725

  2. target 99% 0.0186345

  3. target 99.9% 0.0188793

  4. Code 200 : 19 (63.3 %)

  5. Code 503 : 11 (36.7 %)

  6. Response Header Sizes : count 30 avg 145.73333 +/- 110.9 min 0 max 231 sum 4372

  7. Response Body/Total Sizes : count 30 avg 507.13333 +/- 220.8 min 217 max 676 sum 15214

  8. All done 30 calls (plus 0 warmup) 5.336 ms avg, 422.2 qps

现在,您将开始看到预期的熔断行为,只有 63.3% 的请求成功,其余的均被熔断器拦截:

  1. Code 200 : 19 (63.3 %)

  2. Code 503 : 11 (36.7 %)

  3. 查询 状态以了解更多熔断详情:

istio-proxy

  1. $ kubectl exec $FORTIO_POD -c istio-proxy – pilot-agent request GET stats | grep httpbin | grep pending
  2. cluster.outbound|80||httpbin.springistio.svc.cluster.local.upstream_rq_pending_active: 0
  3. cluster.outbound|80||httpbin.springistio.svc.cluster.local.upstream_rq_pending_failure_eject: 0
  4. cluster.outbound|80||httpbin.springistio.svc.cluster.local.upstream_rq_pending_overflow: 12
  5. cluster.outbound|80||httpbin.springistio.svc.cluster.local.upstream_rq_pending_total: 39

可以看到
upstream_rq_pending_overflow

清理

值 ,这意味着,目前为止已有 12 个调用被标记为熔断。

  1. 清理规则:

12

  1. $ kubectl delete destinationrule httpbin

  2. 下线 httpbin 服务和客户端:

  3. $ kubectl delete deploy httpbin fortio-deploy

  4. $ kubectl delete svc httpbin

相关内容

使用 Admiral 管理 Istio 多集群的配置和服务发现
为 Istio deployment(cluster)提供自动化 Istio 配置,并让其像单个网格一样工作。把 Istio 作为外部服务的代理
把 Istio 入口网关配置为外部服务的代理。用于隔离和边界保护的多网格部署

将需要隔离的环境部署到单独的网格中,并通过网格联邦启用网格间通信。
Istio 中安全管控出口流量,第三部分
管控出口流量的备选方案比较,包括性能因素。
Istio 中的安全管控出口流量,第二部分
使用 Istio 的出口流量管控来阻止相关出口流量攻击。
Istio 中的安全管控出口流量,第一部分涉及出口流量攻击和出口流量管控要求。

镜像

此任务演示了 Istio 的流量镜像功能。

流量镜像,也称为影子流量,是一个以尽可能低的风险为生产带来变化的强大的功能。镜像会将实时流量的副本发送到镜像服务。镜像流量发生在主服务的关键请求路径之外。
v2

在此任务中,首先把流量全部路由到
v1

开始之前

版本的测试服务。然后,执行规则将一部分流量镜像到
版本。

按照安装指南中的说明设置 Istio。

首先部署两个版本的 httpbin 服务,httpbin 服务已开启访问日志:

httpbin-v1:

  1. $ cat <<EOF | istioctl kube-inject -f - | kubectl create -f -
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: httpbin-v1
  6. spec:
  7. replicas: 1
  8. selector:
  9. matchLabels:
  10. app: httpbin
  11. version: v1
  12. template:
  13. metadata:
  14. labels:
  15. app: httpbin
  16. version: v1
  17. spec:
  18. containers:
    • image: docker.io/kennethreitz/httpbin
  19. imagePullPolicy: IfNotPresent
  20. name: httpbin
  21. command: [“gunicorn”, “–access-logfile”, “-”, “-b”, “0.0.0.0:80”, “httpbin:app”]
  22. ports:
    • containerPort: 80
  23. EOF

httpbin-v2:

  1. $ cat <<EOF | istioctl kube-inject -f - | kubectl create -f -

  2. apiVersion: apps/v1

  3. kind: Deployment

  4. metadata:

  5. name: httpbin-v2

  6. spec:

  7. replicas: 1

  8. selector:

  9. matchLabels:

  10. app: httpbin

  11. version: v2

  12. template:

  13. metadata:

  14. labels:

  15. app: httpbin

  16. version: v2

  17. spec:

  18. containers:

    • image: docker.io/kennethreitz/httpbin
  19. imagePullPolicy: IfNotPresent

  20. name: httpbin

  21. command: [“gunicorn”, “–access-logfile”, “-”, “-b”, “0.0.0.0:80”, “httpbin:app”]

  22. ports:

    • containerPort: 80
  23. EOF

httpbin Kubernetes service:

  1. $ kubectl create -f - <<EOF

  2. apiVersion: v1

  3. kind: Service

  4. metadata:

  5. name: httpbin

  6. labels:

  7. app: httpbin

  8. spec:

  9. ports:

    • name: http
  10. port: 8000

  11. targetPort: 80

  12. selector:

  13. app: httpbin

  14. EOF

启动 服务,这样就可以使用 来提供负载了:
sleep
curl

sleep service:

  1. $ cat <<EOF | istioctl kube-inject -f - | kubectl create -f -

  2. apiVersion: apps/v1

  3. kind: Deployment

  4. metadata:

  5. name: sleep

  6. spec:

  7. replicas: 1

  8. selector:

  9. matchLabels:

  10. app: sleep

  11. template:

  12. metadata:

  13. labels:

  14. app: sleep

  15. spec:

  16. containers:

    • name: sleep
  17. image: tutum/curl

  18. command: [“/bin/sleep”,“infinity”]

  19. imagePullPolicy: IfNotPresent

  20. EOF

创建一个默认路由策略

默认情况下,Kubernetes 在 服务的两个版本之间进行负载均衡。在此步骤中会更改该行为,把所有流
httpbin
量都路由到 。
v1

  1. 创建一个默认路由规则,将所有流量路由到服务的 :

v1

如果安装/配置 Istio 的时候开启了 TLS 认证,在应用 之前必须将 TLS 流量策略
DestinationRule
mode: ISTIO_MUTUAL
DestinationRule

503 错误所述。
添加到
。否则,请求将发生 503 错误,如设置目标规则后出现

  1. $ kubectl apply -f - <<EOF

  2. apiVersion: networking.istio.io/v1alpha3

  3. kind: VirtualService

  4. metadata:

  5. name: httpbin

  6. spec:

  7. hosts:

    • httpbin
  8. http:

    • route:
    • destination:
  9. host: httpbin

  10. subset: v1

  11. weight: 100 15. —

  12. apiVersion: networking.istio.io/v1alpha3

  13. kind: DestinationRule

  14. metadata:

  15. name: httpbin

  16. spec:

  17. host: httpbin

  18. subsets:

    • name: v1
  19. labels:

  20. version: v1

    • name: v2
  21. labels:

  22. version: v2

  23. EOF

现在所有流量都转到 服务。
httpbin:v1

  1. 向服务发送一下流量:

  2. $ export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items…metadata.name})

$ kubectl exec -it $SLEEP_POD -c sleep – sh -c ‘curl http://httpbin:8000/headers’ | python -m

  1. json.tool 3. {

  2. “headers”: {

  3. “Accept”: “/”,

  4. “Content-Length”: “0”,

  5. “Host”: “httpbin:8000”,

  6. “User-Agent”: “curl/7.35.0”,

  7. “X-B3-Sampled”: “1”,

  8. “X-B3-Spanid”: “eca3d7ed8f2e6a0a”,

  9. “X-B3-Traceid”: “eca3d7ed8f2e6a0a”,

  10. “X-Ot-Span-Context”: “eca3d7ed8f2e6a0a;eca3d7ed8f2e6a0a;0000000000000000”

  11. }

  12. }

  13. 分别查看 服务 两个 pods 的日志,您可以看到访问日志进入 ,而

httpbin
v1 和


v2
v1
中没有日志,显示为 :
v2

  1. $ export V1_POD=$(kubectl get pod -l app=httpbin,version=v1 -o jsonpath={.items…metadata.name})

  2. $ kubectl logs -f $V1_POD -c httpbin

  3. 127.0.0.1 - - [07/Mar/2018:19:02:43 +0000] “GET /headers HTTP/1.1” 200 321 “-” “curl/7.35.0”

  4. $ export V2_POD=$(kubectl get pod -l app=httpbin,version=v2 -o jsonpath={.items…metadata.name})

  5. $ kubectl logs -f $V2_POD -c httpbin

镜像流量到 v2

  1. 改变流量规则将流量镜像到 v2:

  2. $ kubectl apply -f - <<EOF

  3. apiVersion: networking.istio.io/v1alpha3

  4. kind: VirtualService

  5. metadata:

  6. name: httpbin

  7. spec:

  8. hosts:

    • httpbin
  9. http:

    • route:
    • destination:
  10. host: httpbin

  11. subset: v1

  12. weight: 100

  13. mirror:

  14. host: httpbin

  15. subset: v2

  16. mirror_percent: 100

  17. EOF

这个路由规则发送 100% 流量到 v1 。最后一段表示你将镜像流量到时,请求将发送到镜像服务中,并在 headers 中的
Host/Authority
变为 cluster-1-shadow 。
cluster-1

httpbin:v2
属性值上追加
服务。当流量被镜像
。例如
-shadow

此外,重点注意这些被镜像的流量是『 即发即弃』 的,就是说镜像请求的响应会被丢弃。

您可以使用 属性来设置镜像流量的百分比,而不是镜像全部请求。为了兼容老版本,如果这
mirror_percent
个属性不存在,将镜像所有流量。

  1. 发送流量:

$ kubectl exec -it $SLEEP_POD -c sleep – sh -c ‘curl http://httpbin:8000/headers’ | python -m

  1. json.tool

现在就可以看到 和实际目标是 v1。
v1
v2
中都有了访问日志。v2 中的访问日志就是由镜像流量产生的,这些请求的

  1. $ kubectl logs -f $V1_POD -c httpbin

  2. 127.0.0.1 - - [07/Mar/2018:19:02:43 +0000] “GET /headers HTTP/1.1” 200 321 “-” “curl/7.35.0”

  3. 127.0.0.1 - - [07/Mar/2018:19:26:44 +0000] “GET /headers HTTP/1.1” 200 321 “-” “curl/7.35.0”

  4. $ kubectl logs -f $V2_POD -c httpbin

  5. 127.0.0.1 - - [07/Mar/2018:19:26:44 +0000] “GET /headers HTTP/1.1” 200 361 “-” “curl/7.35.0”

  6. 如果要检查流量内部,请在另一个控制台上运行以下命令:

{.items..metadata.name}) $ export V1_POD_IP=$(kubectl get pod -l app=httpbin,version=v1 -o jsonpath={.items..status.podIP}) $ export V2_POD_IP=$(kubectl get pod -l app=httpbin,version=v2 -o jsonpath=
{.items..status.podIP}) $ kubectl exec -it $SLEEP_POD -c istio-proxy — sudo tcpdump -A -s 0 host $V1_POD_IP or host $V2_POD_IP tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 05:47:50.159513 IP sleep-7b9f8bfcd- 2djx5.38836 > 10-233-75-11.httpbin.default.svc.cluster.local.80: Flags [P.], seq 4039989036:4039989832, ack 3139734980, win 254, options [nop,nop,TS val 77427918 ecr 76730809], length 796: HTTP: GET /headers HTTP/1.1 E..P2.X.X.X. .K.


.K….P..W,.$…….+….. ..t…..GET /headers HTTP/1.1 host: httpbin:8000 user-agent: curl/7.35.0 accept: _/ _x-forwarded-proto: http x-request-id: 571c0fd6-98d4-4c93- af79-6a2fe2945847 x-envoy-decorator-operation: httpbin.default.svc.cluster.local:8000/* x-b3-traceid: 82f3e0a76dcebca2 x-b3- spanid: 82f3e0a76dcebca2 x-b3-sampled: 0 x-istio-attributes: Cj8KGGRlc3RpbmF0aW9uLnNlcnZpY2UuaG9zdBIjEiFodHRwYmluLmRlZmF1bHQuc3ZjLmNsdXN0ZXIub G9jYWwKPQoXZGVzdGluYXRpb24uc2VydmljZS51aWQSIhIgaXN0aW86Ly9kZWZhdWx0L3NlcnZpY2VzL2 h0dHBiaW4KKgodZGVzdGluYXRpb24uc2VydmljZS5uYW1lc3BhY2USCRIHZGVmYXVsdAolChhkZXN0aW5 hdGlvbi5zZXJ2aWNlLm5hbWUSCRIHaHR0cGJpbgo6Cgpzb3VyY2UudWlkEiwSKmt1YmVybmV0ZXM6Ly9z bGVlcC03YjlmOGJmY2QtMmRqeDUuZGVmYXVsdAo6ChNkZXN0aW5hdGlvbi5zZXJ2aWNlEiMSIWh0dHBia W4uZGVmYXVsdC5zdmMuY2x1c3Rlci5sb2NhbA== content-length: 0

05:47:50.159609 IP sleep-7b9f8bfcd-2djx5.49560 > 10-233-71-7.httpbin.default.svc.cluster.local.80: Flags [P.], seq 296287713:296288571, ack 4029574162, win 254, options [nop,nop,TS val 77427918 ecr 76732809], length 858:

   1. HTTP: GET /headers HTTP/1.1

2. E.....X.X...
3. .K.
4. .G....P......l......e.....

1. ..t.....GET /headers HTTP/1.1
2. host: httpbin-shadow:8000
3. user-agent: curl/7.35.0
4. accept: */*
5. x-forwarded-proto: http

10. x-request-id: 571c0fd6-98d4-4c93-af79-6a2fe2945847

1. x-envoy-decorator-operation: httpbin.default.svc.cluster.local:8000/*
2. x-b3-traceid: 82f3e0a76dcebca2
3. x-b3-spanid: 82f3e0a76dcebca2
4. x-b3-sampled: 0

x-istio-attributes:

1. Cj8KGGRlc3RpbmF0aW9uLnNlcnZpY2UuaG9zdBIjEiFodHRwYmluLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwKPQoXZGVzdGluYXRpb24uc2Vy
2. x-envoy-internal: true

17. x-forwarded-for: 10.233.75.12
18. content-length: 0 19.
20.

05:47:50.166734 IP 10-233-75-11.httpbin.default.svc.cluster.local.80 > sleep-7b9f8bfcd-2djx5.38836: Flags [P.], seq 1:472, ack 796, win 276, options [nop,nop,TS val 77427925 ecr 77427918], length 471: HTTP: HTTP/1.1
21. 200 OK
22. E....3X.?...
23. .K.
24. .K..P...$....ZH...........
25. ..t...t.HTTP/1.1 200 OK
26. server: envoy
27. date: Fri, 15 Feb 2019 05:47:50 GMT

1. content-type: application/json
2. content-length: 241
3. access-control-allow-origin: *
4. access-control-allow-credentials: true
5. x-envoy-upstream-service-time: 3 33.

34. {
35.	"headers": {

![](https://img-blog.csdnimg.cn/img_convert/86dbe142a94e1ee7ca4598c0132af0fc.png)![](https://img-blog.csdnimg.cn/img_convert/b3ca4a6000d0cfe33ace1fb630ae58d2.png)![](https://img-blog.csdnimg.cn/img_convert/de2117dc5af1a79252d2bf5378e63254.png)
36.	"Accept": "*/*",

1. "Content-Length": "0",
2. "Host": "httpbin:8000",

39.	"User-Agent": "curl/7.35.0",
40.	"X-B3-Sampled": "0",

1. "X-B3-Spanid": "82f3e0a76dcebca2",
2. "X-B3-Traceid": "82f3e0a76dcebca2"

43.	}
44. } 45.
05:47:50.166789 IP sleep-7b9f8bfcd-2djx5.38836 > 10-233-75-11.httpbin.default.svc.cluster.local.80: Flags [.],
46. ack 472, win 262, options [nop,nop,TS val 77427925 ecr 77427925], length 0
47. E..42.X.X.\.
48. .K.
49. .K....P..ZH.$.............
50. ..t	t.
05:47:50.167234 IP 10-233-71-7.httpbin.default.svc.cluster.local.80 > sleep-7b9f8bfcd-2djx5.49560: Flags [P.],
51. seq 1:512, ack 858, win 280, options [nop,nop,TS val 77429926 ecr 77427918], length 511: HTTP: HTTP/1.1 200 OK
52. E..3..X.>...
53. .G.
54. .K..P....l....;...........
55. ..|...t.HTTP/1.1 200 OK
56. server: envoy
57. date: Fri, 15 Feb 2019 05:47:49 GMT

1. content-type: application/json
2. content-length: 281
3. access-control-allow-origin: *
4. access-control-allow-credentials: true
5. x-envoy-upstream-service-time: 3 63.

64. {
65.	"headers": {
66.	"Accept": "*/*",

1. "Content-Length": "0",
2. "Host": "httpbin-shadow:8000",

69.	"User-Agent": "curl/7.35.0",
70.	"X-B3-Sampled": "0",

1. "X-B3-Spanid": "82f3e0a76dcebca2",
2. "X-B3-Traceid": "82f3e0a76dcebca2",
3. "X-Envoy-Internal": "true"

74.	}
75. } 76.
05:47:50.167253 IP sleep-7b9f8bfcd-2djx5.49560 > 10-233-71-7.httpbin.default.svc.cluster.local.80: Flags [.],
77. ack 512, win 262, options [nop,nop,TS val 77427926 ecr 77429926], length 0
78. E..4..X.X...
79. .K.
80. .G....P...;..n............
81. ..t	|.
82. ```83.
84. 您可以看到流量 的请求和响应内容。

## 清理

1. 删除规则:


1. $ kubectl delete virtualservice httpbin
2. $ kubectl delete destinationrule httpbin

1. 关闭 [httpbin ](https://github.com/istio/istio/tree/release-1.6/samples/httpbin)服务和客户端:


1. $ kubectl delete deploy httpbin-v1 httpbin-v2 sleep
2. $ kubectl delete svc httpbin

## 相关内容

[用于在生产环境进行测试的 Istio 流量镜像功能](https://istio.io/zh/blog/2018/traffic-mirroring/)介绍更安全,低风险的部署和发布到生产。
[使用 Admiral 管理 Istio 多集群的配置和服务发现](https://istio.io/zh/blog/2020/multi-cluster-mesh-automation/)
为 Istio deployment(cluster)提供自动化 Istio 配置,并让其像单个网格一样工作。[把 Istio 作为外部服务的代理](https://istio.io/zh/blog/2019/proxy/)
把 Istio 入口网关配置为外部服务的代理。[用于隔离和边界保护的多网格部署](https://istio.io/zh/blog/2019/isolated-clusters/)
将需要隔离的环境部署到单独的网格中,并通过网格联邦启用网格间通信。
[Istio 中安全管控出口流量,第三部分](https://istio.io/zh/blog/2019/egress-traffic-control-in-istio-part-3/)
管控出口流量的备选方案比较,包括性能因素。
[Istio 中的安全管控出口流量,第二部分](https://istio.io/zh/blog/2019/egress-traffic-control-in-istio-part-2/)
使用 Istio 的出口流量管控来阻止相关出口流量攻击。



# Ingress


控制 Istio 服务网格的入口流量。

### Ingress Gateway

描述如何配置 Istio gateway,以将服务暴露至服务网格之外。

### 安全网关(文件挂载)

使用文件挂载的证书并通过 TLS 或 mTLS 将服务暴露至服务网格之外。

### 使用 SDS 为 Gateway 提供 HTTPS 加密支持

使用 Secret 发现服务(SDS) 通过 TLS 或者 mTLS 把服务暴露给服务网格外部。

### 无 TLS 终止的 Ingress Gateway

说明了如何为一个 ingress gateway 配置 SNI 透传。



# Ingress Gateway


在 Kubernetes 环境中,使用 [Kubernetes Ingress 资源](https://kubernetes.io/docs/concepts/services-networking/ingress/)来指定需要暴露到集群外的服务。 在 Istio 服务网格中,更好的选择(同样适用于 Kubernetes 及其他环境)是使用一种新的配置模型,名为 Istio Gateway。
允许应用一些诸如监控和路由规则的 Istio 特性来管理进入集群的流量。
Gateway

本任务描述了如何配置 Istio,以使用 Istio	来将服务暴露至服务网格之外。
Gateway

## 开始之前

遵照安装指南中的指令,安装 Istio。

确定当前目录路径为	目录。
istio

启动 [httpbin ](https://github.com/istio/istio/tree/release-1.6/samples/httpbin)样例程序。

如果您启用了 sidecar 自动注入,通过以下命令部署	服务:
httpbin

[Zip](https://raw.githubusercontent.com/istio/istio/release-1.6/samples/httpbin/httpbin.yaml)


1. $ kubectl apply -f @samples/httpbin/httpbin.yaml@

否则,您必须在部署	应用程序前进行手动注入,部署命令如下:
httpbin

[Zip](https://raw.githubusercontent.com/istio/istio/release-1.6/samples/httpbin/httpbin.yaml)


1. $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@)

根据下文描述,确定 ingress IP 和端口。

### 确定 ingress IP 和端口

执行如下指令,明确自身 Kubernetes 集群环境支持外部负载均衡:

1. $ kubectl get svc istio-ingressgateway -n istio-system
NAME
2. AGE
istio-ingressgateway
TYPE
CLUSTER-IP
EXTERNAL-IP	PORT(S)
LoadBalancer
172.21.109.129
130.211.10.121
3. 80:31380/TCP,443:31390/TCP,31400:31400/TCP	17h

已设置,说明环境正在使用外部负载均衡,可以用其为 ingress gateway 提供服务。 如
如果	EXTERNAL-IP	值
果	EXTERNAL-IP	值为
(或持续显示	),说明环境没有提供外部负载均衡,无法使用
<none>
<pending>
ingress gateway。 在这种情况下,你可以使用服务的 [node port ](https://kubernetes.io/docs/concepts/services-networking/service/#nodeport)访问网关。
选择符合自身环境的指令执行:


若已确定自身环境使用了外部负载均衡器,执行如下指令。设置 ingress IP 和端口:

$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o
1. jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?
2. (@.name=="http2")].port}')
$ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o
3. jsonpath='{.spec.ports[?(@.name=="https")].port}')

在特定的环境下,可能会使用主机名指代负载均衡器,而不是 IP 地址。 此时,ingress 网关的
EXTERNAL-IP
INGRESS_HOST

值将不再是 IP 地址,而是主机名。前文设置
值:
INGRESS_HOST
环境变量的命令将执行失败。 使用下面的命令更正




$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o
1. jsonpath='{.status.loadBalancer.ingress[0].hostname}')

若自身环境未使用外部负载均衡器,需要通过 node port 访问。执行如下命令。设置 ingress 端口:

$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?

1. (@.name=="http2")].nodePort}')

$ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o

1. jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')

基于集群供应商,设置 ingress IP:

1. _GKE_:


1. $ export INGRESS_HOST=<workerNodeAddress>

需要创建防火墙规则,允许 TCP 流量通过 _ingressgateway _服务的端口。 执行下面的命令,设置允许流量通过 HTTP 端口、HTTPS 安全端口,或均可:


1. $ gcloud compute firewall-rules create allow-gateway-http --allow tcp:$INGRESS_PORT
2. $ gcloud compute firewall-rules create allow-gateway-https --allow tcp:$SECURE_INGRESS_PORT

1. _Minikube_:


1. $ export INGRESS_HOST=$(minikube ip)

1. _Docker For Desktop_:


1. $ export INGRESS_HOST=127.0.0.1

1. 其他环境(如:_IBM Cloud Private _等):





$ export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o
1. jsonpath='{.items[0].status.hostIP}')

## 使用 Istio Gateway 配置 ingress

Ingress Gateway 描述运行在网格边界的负载均衡器,负责接收入口 HTTP/TCP 连接。 其中配置了对外暴露的端口、协议等。 但是,不像 [Kubernetes Ingress 资源](https://kubernetes.io/docs/concepts/services-networking/ingress/),ingress Gateway 不包含任何流量路由配置。Ingress 流量的路由使用 Istio 路由规则来配置,和内部服务请求完全一样。

让我们一起来看如何为 HTTP 流量在 80 端口上配置	。
Gateway

1. 创建 Istio	:

Gateway


1. $ kubectl apply -f - <<EOF
2. apiVersion: networking.istio.io/v1alpha3
3. kind: Gateway
4. metadata:
5. name: httpbin-gateway
6. spec:
7. selector:
8. istio: ingressgateway # use Istio default gateway implementation
9. servers:
10. - port:
11. number: 80
12. name: http
13. protocol: HTTP
14. hosts:
15. - "httpbin.example.com"
16. EOF

1. 为通过	的入口流量配置路由:

Gateway


1. $ kubectl apply -f - <<EOF
2. apiVersion: networking.istio.io/v1alpha3
3. kind: VirtualService
4. metadata:
5. name: httpbin
6. spec:
7. hosts:
8. - "httpbin.example.com"
9. gateways:
10. - httpbin-gateway
11. http:
12. - match:
13. - uri:
14. prefix: /status
15. - uri:
16. prefix: /delay
17. route:
18. - destination:



19.
20.
21.
22. EOF
port:
number: 8000 host: httpbin

已为	httpbin	服务创建了虚拟服务配置,包含两个路由规则,允许流量流向路径	和
/status
/delay 。


gateways 列表规约了哪些请求允许通过响应。
httpbin-gateway
网关。 所有其他外部请求均被拒绝并返回 404

来自网格内部其他服务的内部请求无需遵循这些规则,而是默认遵守轮询调度路由规则。   你可以为
列表添加特定的	mesh	值,将这些规则同时应用到内部请求。 由于服务的内部主机名可能与外部主机名不一致(譬如: httpbin.default.svc.cluster.local ),你需要同时将内部主机名添加到
gateways
hosts
列表中。 详情请参考操作指南。

1. 使用 _curl _访问 _httpbin _服务:


1. $ curl -I -HHost:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/status/200 2. HTTP/1.1 200 OK
3. server: envoy
4. date: Mon, 29 Jan 2018 04:45:49 GMT

1. content-type: text/html; charset=utf-8
2. access-control-allow-origin: *
3. access-control-allow-credentials: true
4. content-length: 0
5. x-envoy-upstream-service-time: 48


注意上文命令使用
-H
须操作,因为 ingress
标识将 HTTP 头部参数 _Host _设置为 “httpbin.example.com”。 该操作为必已被配置用来处理 “httpbin.example.com” 的服务请求,而在测试

环境中并没有为该主机绑定 DNS 而是简单直接地向 ingress IP 发送请求。
Gateway

1. 访问其他没有被显式暴露的 URL 时,将看到 HTTP 404 错误:


1. $ curl -I -HHost:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/headers
2. HTTP/1.1 404 Not Found

3. date: Mon, 29 Jan 2018 04:45:49 GMT

1. server: envoy
2. content-length: 0

## 通过浏览器访问 ingress 服务


在浏览器中输入
服务的 URL 不能获得有效的响应,因为无法像
那样,将请求头部参数 _Host_
传给浏览器。在现实场景中,这并不是问题,因为你需要合理配置被请求的主机及可解析的 DNS,从而在 URL 中使
httpbin
curl
用主机的域名,譬如:	。
[https://httpbin.example.com/status/200](https://httpbin.example.com/status/200)
![](https://img-blog.csdnimg.cn/img_convert/ad36fd63fb091e8895662c1f7ee0602c.png)
*


为了在简单的测试和演示中绕过这个问题,请在	和修改 ingress 配置如下:
Gateway
VirtualService
配置中使用通配符
。譬如,





   1. $ kubectl apply -f - <<EOF
   2. apiVersion: networking.istio.io/v1alpha3
   3. kind: Gateway
   4. metadata:
   5. name: httpbin-gateway
   6. spec:
   7. selector:
   8. istio: ingressgateway # use Istio default gateway implementation
   9. servers:
   10. - port:
   11. number: 80
   12. name: http
   13. protocol: HTTP
   14. hosts:

15.	- "*"
16. ---

1. apiVersion: networking.istio.io/v1alpha3
2. kind: VirtualService
3. metadata:
4. name: httpbin
5. spec:
6. hosts:

23.	- "*"

1. gateways:
2. - httpbin-gateway
3. http:
4. - match:
5. - uri:
6. prefix: /headers
7. route:
8. - destination:
9. port:
10. number: 8000
11. host: httpbin
12. EOF


此时,便可以在浏览器中输入包含	$INGRESS_HOST:$INGRESS_PORT	的 URL。譬如,输
入 http://$INGRESS_HOST:$INGRESS_PORT/headers ,将显示浏览器发送的所有 headers 信息。

## 理解原理

配置资源允许外部流量进入 Istio 服务网格,并对边界服务实施流量管理和 Istio 可用的策略特性。事先,在服务网格中创建一个服务并向外部流量暴露该服务的 HTTP 端点。
Gateway
## 问题排查
INGRESS_PORT


1. 检查环境变量

INGRESS_HOST
and
。确保环境变量的值有效,命令如下:




1. $ kubectl get svc -n istio-system
2. $ echo INGRESS_HOST=$INGRESS_HOST, INGRESS_PORT=$INGRESS_PORT

1. 检查没有在相同的端口上定义其它 Istio ingress gateways:


1. $ kubectl get gateway --all-namespaces

1. 检查没有在相同的 IP 和端口上定义 Kubernetes Ingress 资源:


1. $ kubectl get ingress --all-namespaces

1. 如果使用了外部负载均衡器,该外部负载均衡器无法正常工作,尝试通过 node port 访问 gateway。

## 清除

删除	和	配置,并关闭服务 [httpbin](https://github.com/istio/istio/tree/release-1.6/samples/httpbin):
Gateway
VirtualService

[Zip](https://raw.githubusercontent.com/istio/istio/release-1.6/samples/httpbin/httpbin.yaml)


1. $ kubectl delete gateway httpbin-gateway
2. $ kubectl delete virtualservice httpbin
3. $ kubectl delete --ignore-not-found=true -f @samples/httpbin/httpbin.yaml@

## 相关内容

[把 Istio 作为外部服务的代理](https://istio.io/zh/blog/2019/proxy/)
把 Istio 入口网关配置为外部服务的代理。
[使用 Cert-Manager 部署一个自定义 Ingress 网关](https://istio.io/zh/blog/2019/custom-ingress-gateway/)
如何使用 cert-manager 手工部署一个自定义 Ingress 网关。[使用 AWS NLB 配置 Istio Ingress](https://istio.io/zh/blog/2018/aws-nlb/)
描述如何在 AWS 上使用网络负载均衡器配置 Istio Ingress。使用 SDS 为 Gateway 提供 HTTPS 加密支持
使用 Secret 发现服务(SDS) 通过 TLS 或者 mTLS 把服务暴露给服务网格外部。安全网关(文件挂载)
使用文件挂载的证书并通过 TLS 或 mTLS 将服务暴露至服务网格之外。无 TLS 终止的 Ingress Gateway
说明了如何为一个 ingress gateway 配置 SNI 透传。



# 安全网关(文件挂载)

控制 Ingress 流量任务描述了如何配置一个 ingress 网关以将 HTTP 服务暴露给外部流量。本任务则展示了如何使用简单或双向 TLS 暴露安全 HTTPS 服务。

TLS 所必需的私钥、服务器证书和根证书使用基于文件挂载的方式进行配置。

## 开始之前

1. 执行开始之前任务和控制 Ingress 流量任务中的确认 ingress 的 IP 和端口小节中的步骤。执行完毕

后,Istio 和 [httpbin ](https://github.com/istio/istio/tree/release-1.6/samples/httpbin)服务都已经部署完毕。环境变量	和	也已经设置。
INGRESS_HOST
SECURE_INGRESS_PORT

1. 对于 macOS 用户,确认您的 _curl _使用了 [LibreSSL ](http://www.libressl.org/)库来编译:


1. $ curl --version | grep LibreSSL
2. curl 7.54.0 (x86_64-apple-darwin17.0) libcurl/7.54.0 LibreSSL/2.0.20 zlib/1.2.11 nghttp2/1.24.0

如果以上输出打印了 _LibreSSL _的版本,则 _curl _应该可以按照此任务中的说明正常工作。否则,请尝试另一种 _curl _版本,例如运行于 Linux 计算机的版本。

## 生成服务器证书和私钥

此任务您可以使用您喜欢的工具来生成证书和私钥。下列命令使用了 [openssl](https://man.openbsd.org/openssl.1)

1. 创建一个根证书和私钥以为您的服务所用的证书签名:


$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -
1. keyout example.com.key -out example.com.crt

1. 为	创建一个证书和私钥:

httpbin.example.com


$ openssl req -out httpbin.example.com.csr -newkey rsa:2048 -nodes -keyout httpbin.example.com.key -subj

1. "/CN=httpbin.example.com/O=httpbin organization"

$ openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in

1. httpbin.example.com.csr -out httpbin.example.com.crt

## 基于文件挂载的方式配置 TLS ingress 网关

本节中,您将配置一个使用 443 端口的 ingress 网关,以处理 HTTPS 流量。 首先使用证书和私钥创建一个

secret。该 secret 将被挂载为
/etc/istio/ingressgateway-certs
关定义,它将配置一个运行于端口 443 的服务。
路径下的一个文件。 然后您可以创建一个网


1. 创建一个 Kubernetes secret 以保存服务器的证书和私钥。使用	在命名空间

kubectl
istio-system

下创建 secret	。Istio 网关将会自动加载该 secret。
istio-ingressgateway-certs


该 secret 必须在
命名空间下,且名为
,以与此任务中使用

的 Istio 默认 ingress 网关的配置保持一致。
istio-system
istio-ingressgateway-certs


$ kubectl create -n istio-system secret tls istio-ingressgateway-certs --key httpbin.example.com.key --

1. cert httpbin.example.com.crt
2. secret "istio-ingressgateway-certs" created

请注意,默认情况下,	命名空间下的所有 pod 都能挂载这个 secret 并访问该私钥。您可
istio-system
以将 ingress 网关部署到一个单独的命名空间中,并在那创建 secret,这样就只有这个 ingress 网关
pod 才能挂载它。

验证	和	是否都已经挂载到 ingress 网关 pod 中:
tls.crt
tls.key


$ kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingressgateway -o
1. jsonpath='{.items[0].metadata.name}') -- ls -al /etc/istio/ingressgateway-certs

1. 为 443 端口定义	并设置	。

Gateway
server

证书和私钥必须位于	,否则网关将无法加载它们。
/etc/istio/ingressgateway-certs


1. $ kubectl apply -f - <<EOF
2. apiVersion: networking.istio.io/v1alpha3
3. kind: Gateway
4. metadata:
5. name: httpbin-gateway
6. spec:
7. selector:
8. istio: ingressgateway # use istio default ingress gateway
9. servers:
10. - port:
11. number: 443
12. name: https
13. protocol: HTTPS
14. tls:
15. mode: SIMPLE
16. serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
17. privateKey: /etc/istio/ingressgateway-certs/tls.key
18. hosts:
19. - "httpbin.example.com"
20. EOF

1. 配置路由以让流量从	进入。定义与控制 Ingress 流量任务中相同的	:

Gateway
VirtualService


1. $ kubectl apply -f - <<EOF
2. apiVersion: networking.istio.io/v1alpha3
3. kind: VirtualService
4. metadata:
5. name: httpbin



1. spec:
2. hosts:
3. - "httpbin.example.com"
4. gateways:
5. - httpbin-gateway
6. http:
7. - match:
8. - uri:
9. prefix: /status
10. - uri:
11. prefix: /delay
12. route:
13. - destination:
14. port:
15. number: 8000
16. host: httpbin
17. EOF


1. 使用 _curl _发送一个

https
请求到
以通过 HTTPS 访问
服务。

--resolve	标志让 _curl _在通过 TLS 访问网关 IP 时支持 [SNI ](https://en.wikipedia.org/wiki/Server_Name_Indication)值	。
SECURE_INGRESS_PORT
httpbin
httpbin.example.com
![](https://img-blog.csdnimg.cn/img_convert/e0e873daa72606d7b0ece1a843f3d725.png)
--
cacert	选项则让 _curl _使用您创建的证书来验证服务器。


-HHost:httpbin.example.com	标志也包含了,但只有当
SECURE_INGRESS_PORT
(例如,您通过映射的	NodePort	来访问服务)时才真正需要。
与实际网关端口(443)不同



通过发送请求到
URL 路径,您可以很好地看到您的
服务确实已被访问。

服务将返回 [418 I’m a Teapot ](https://tools.ietf.org/html/rfc7168#section-2.3.3)代码。
/status/418
httpbin
httpbin

$ curl -v -HHost:httpbin.example.com --resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST --
1. cacert example.com.crt https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418 2. ...

1. Server certificate:
2. subject: CN=httpbin.example.com; O=httpbin organization
3. start date: Oct 27 19:32:48 2019 GMT
4. expire date: Oct 26 19:32:48 2020 GMT
5. common name: httpbin.example.com (matched)
6. issuer: O=example Inc.; CN=example.com
7. SSL certificate verify ok.
8. SSL certificate verify ok. 11. ...

12. HTTP/2 418 13. ...
14. -=[ teapot ]=- 15.
16.	_...._
17.  .' _ _ `.
18. | ."` ^ `". _, 19. \_;`"---"`|//
20.
21.
22.
|
\_
;/
_/
`"""`


网关定义传播需要时间,因此您可能会得到以下报错:
Failed to connect to httpbin.example.com port <your
。请稍后重新执行 _curl _命令。
secure port>: Connection refused
在 _curl _的输出中寻找 _Server certificate _部分,尤其是找到与 _common name _匹配的行:
common
。 输出中的
name: httpbin.example.com (matched)
SSL certificate verify ok
成功。 如果一切顺利,您还应该看到返回的状态 418,以及精美的茶壶图。

## 配置双向 TLS ingress 网关
这一行表示服务端的证书验证




本节中您将您的网关的定义从上一节中扩展为支持外部客户端和网关之间的[双向   TLS](https://en.wikipedia.org/wiki/Mutual_authentication)。

1. 创建一个 Kubernetes	以保存服务端将用来验证它的客户端的 [CA ](https://en.wikipedia.org/wiki/Certificate_authority)证书。使用	在命

Secret
kubectl
名空间
istio-system
secret。
该 secret 必须在
中创建 secret


命名空间下,且名为
istio-ingressgateway-ca-certs
istio-system
。Istio 网关将会自动加载该

,以与此任务中使
istio-ingressgateway-ca-certs

用的 Istio 默认 ingress 网关的配置保持一致。


$ kubectl create -n istio-system secret generic istio-ingressgateway-ca-certs --from-

1. file=example.com.crt
2. secret "istio-ingressgateway-ca-certs" created


1. 重新定义之前的

Gateway
,修改 TLS 模式为
,并指定	:


证书必须位于	/etc/istio/ingressgateway-ca-certs ,否则网关将无法加载它们。 证书的(短)文件名必须与您创建 secret 的名称相同,在本例中为	example.com.crt 。
MUTUAL
caCertificates


1. $ kubectl apply -f - <<EOF
2. apiVersion: networking.istio.io/v1alpha3
3. kind: Gateway
4. metadata:
5. name: httpbin-gateway
6. spec:
7. selector:
8. istio: ingressgateway # use istio default ingress gateway
9. servers:
10. - port:
11. number: 443
12. name: https
13. protocol: HTTPS
14. tls:
15. mode: MUTUAL
16. serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
17. privateKey: /etc/istio/ingressgateway-certs/tls.key
18. caCertificates: /etc/istio/ingressgateway-ca-certs/example.com.crt
19. hosts:
20. - "httpbin.example.com"
21. EOF


1. 像上一节中一样通过 HTTPS 访问	服务:

httpbin


$ curl -HHost:httpbin.example.com --resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST --

1. cacert example.com.crt https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418
2. curl: (35) error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure

网关定义传播需要时间,因此您可能会仍然得到 _418 _状态码。请稍后重新执行 _curl _命令。

这次您将得到一个报错,因为服务端拒绝接受未认证的请求。您需要传递 _curl _客户端证书和私钥以将请求签名。
httpbin-client.example.com


1. 为

httpbin.example.com
端,或使用其它 URI。
--key
服务创建客户端证书。您可以使用
URI 来指定客户




$ openssl req -out httpbin-client.example.com.csr -newkey rsa:2048 -nodes -keyout httpbin-

1. client.example.com.key -subj "/CN=httpbin-client.example.com/O=httpbin's client organization"

$ openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in httpbin-

1. client.example.com.csr -out httpbin-client.example.com.crt


1. 重新用 _curl _发送之前的请求,这次通过参数传递客户端证书(添加选项):

--cert
选项)和您的私钥(



$ curl -HHost:httpbin.example.com --resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST -- cacert example.com.crt --cert httpbin-client.example.com.crt --key httpbin-client.example.com.key
1. https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418 2.
3. -=[ teapot ]=- 4.
5.	_...._
6.  .' _ _ `.
7. | ."` ^ `". _, 8. \_;`"---"`|//
9.
10.
11.
|
\_
;/
_/
`"""`

这次服务器成功执行了客户端身份验证,您再次收到了漂亮的茶壶图。

## 为多主机配置 TLS ingress 网关

本节中您将为多个主机(	和	)配置 ingress 网关。 Ingress 网关将向客
httpbin.example.com
bookinfo.com
户端提供与每个请求的服务器相对应的唯一证书。

与之前的小节不同,Istio 默认 ingress 网关无法立即使用,因为它仅被预配置为支持一个安全主机。 您需要先使用另一个 secret 配置并重新部署 ingress 网关服务器,然后才能使用它来处理第二台主机。

### 为 bookinfo.com 创建服务器证书和私钥




$ openssl req -out bookinfo.com.csr -newkey rsa:2048 -nodes -keyout bookinfo.com.key -subj

1. "/CN=bookinfo.com/O=bookinfo organization"

$ openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in bookinfo.com.csr -

1. out bookinfo.com.crt

使用新证书重新部署 istio-ingressgateway

1. 创建一个新的 secret 以保存	的证书:

bookinfo.com


$ kubectl create -n istio-system secret tls istio-ingressgateway-bookinfo-certs --key bookinfo.com.key -

1. -cert bookinfo.com.crt
2. secret "istio-ingressgateway-bookinfo-certs" created

1. 更新	istio-ingressgateway	deployment 以挂载新创建的 secret。创建如下	文件以更新		istio-ingressgateway		deployment:

gateway-patch.json
















| 19. |  | } |
| --- | --- | --- |
| 20. | } |  |
| 21. | }] |  |
| 22. | EOF |  |


1. 使用以下命令应用	deployment 更新:

1. $ cat > gateway-patch.json <<EOF 2. [{
3.	"op": "add",

1. "path": "/spec/template/spec/containers/0/volumeMounts/0",
2. "value": {
3. "mountPath": "/etc/istio/ingressgateway-bookinfo-certs",
4. "name": "ingressgateway-bookinfo-certs",
5. "readOnly": true

9.	}
10. },
11. {
12.	"op": "add",

1. "path": "/spec/template/spec/volumes/0",
2. "value": {
3. "name": "ingressgateway-bookinfo-certs",
4. "secret": {
5. "secretName": "istio-ingressgateway-bookinfo-certs",
6. "optional": true

istio-ingressgateway


1. $ kubectl -n istio-system patch --type=json deploy istio-ingressgateway -p "$(cat gateway-patch.json)"

1. 验证	pod 已成功加载私钥和证书:

istio-ingressgateway


$ kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingressgateway -o
1. jsonpath='{.items[0].metadata.name}') -- ls -al /etc/istio/ingressgateway-bookinfo-certs

和	应该出现在文件夹之中。
tls.crt
tls.key


### 配置 bookinfo.com 主机的流量

1. 部署 Bookinfo 示例应用,但不要部署网关:

[Zip](https://raw.githubusercontent.com/istio/istio/release-1.6/samples/bookinfo/platform/kube/bookinfo.yaml)


1. $ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo.yaml@

1. 为	定义网关:

bookinfo.com


1. $ kubectl apply -f - <<EOF
2. apiVersion: networking.istio.io/v1alpha3
3. kind: Gateway
4. metadata:
5. name: bookinfo-gateway
6. spec:
7. selector:
8. istio: ingressgateway # use istio default ingress gateway
9. servers:
10. - port:
11. number: 443
12. name: https-bookinfo
13. protocol: HTTPS
14. tls:
15. mode: SIMPLE
16. serverCertificate: /etc/istio/ingressgateway-bookinfo-certs/tls.crt
17. privateKey: /etc/istio/ingressgateway-bookinfo-certs/tls.key
18. hosts:
19. - "bookinfo.com"
20. EOF

1. 配置	bookinfo.com	的路由。定义类似	的

[samples/bookinfo/networking/bookinfo-gateway.yaml](https://raw.githubusercontent.com/istio/istio/release-1.6/samples/bookinfo/networking/bookinfo-gateway.yaml)
VirtualService :


1. $ kubectl apply -f - <<EOF
2. apiVersion: networking.istio.io/v1alpha3
3. kind: VirtualService
4. metadata:
5. name: bookinfo
6. spec:
7. hosts:
8. - "bookinfo.com"
9. gateways:
10. - bookinfo-gateway
11. http:
12. - match:
13. - uri:
14. exact: /productpage
15. - uri:
16. exact: /login
17. - uri:



1. exact: /logout
2. - uri:
3. prefix: /api/v1/products
4. route:
5. - destination:
6. host: productpage
7. port:
8. number: 9080
9. EOF

1. 发送到 _Bookinfo	_的请求:

productpage


$ curl -o /dev/null -s -v -w "%{http_code}\n" -HHost:bookinfo.com --resolve bookinfo.com:$SECURE_INGRESS_PORT:$INGRESS_HOST --cacert example.com.crt -HHost:bookinfo.com
1. https://bookinfo.com:$SECURE_INGRESS_PORT/productpage 2. ...

1. Server certificate:
2. subject: CN=bookinfo.com; O=bookinfo organization
3. start date: Oct 27 20:08:32 2019 GMT
4. expire date: Oct 26 20:08:32 2020 GMT
5. common name: bookinfo.com (matched)
6. issuer: O=example Inc.; CN=example.com
7. SSL certificate verify ok. 10. ...

11. 200

1. 验证	像之前一样可访问。发送一个请求给它,您会再次看到您喜爱的茶壶:

httbin.example.com

$ curl -HHost:httpbin.example.com --resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST -- cacert example.com.crt --cert httpbin-client.example.com.crt --key httpbin-client.example.com.key
1. https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418 2. ...
3. -=[ teapot ]=- 4.
5.	_...._
6.  .' _ _ `.
7. | ."` ^ `". _, 8. \_;`"---"`|//
9.
10.
11.
|
\_
;/
_/
`"""`

## 问题排查

检查环境变量	和	的值。通过下列命令的输出确保它们都有有效值:
INGRESS_HOST
SECURE_INGRESS_PORT


1. $ kubectl get svc -n istio-system
2. $ echo INGRESS_HOST=$INGRESS_HOST, SECURE_INGRESS_PORT=$SECURE_INGRESS_PORT


验证	pod 已经成功加载了私钥和证书:
istio-ingressgateway


$ kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingressgateway -o
1. jsonpath='{.items[0].metadata.name}') -- ls -al /etc/istio/ingressgateway-certs

和	应存在于文件夹之中。
tls.crt
tls.key

如果您已经创建了	secret,但是私钥和证书未加载,删掉 ingress 网关
istio-ingressgateway-certs
pod 以强行重启 ingress 网关 pod 并重新加载私钥和证书。


1. $ kubectl delete pod -n istio-system -l istio=ingressgateway

验证 ingress 网关的证书的	是正确的:
Subject


$ kubectl exec -i -n istio-system $(kubectl get pod -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}') -- cat /etc/istio/ingressgateway-certs/tls.crt | openssl x509 -

1. text -noout | grep 'Subject:'
2. Subject: CN=httpbin.example.com, O=httpbin organization

验证 ingress 网关的代理是否知道证书:


$ kubectl exec -ti $(kubectl get po -l istio=ingressgateway -n istio-system -o
1. jsonpath='{.items[0].metadata.name}') -n istio-system -- pilot-agent request GET certs 2. {
3.	"ca_cert": "",
"cert_chain": "Certificate Path: /etc/istio/ingressgateway-certs/tls.crt, Serial Number: 100212, Days
4. until Expiration: 370" 5. }

检查	的日志看是否有错误消息:
istio-ingressgateway


1. $ kubectl logs -n istio-system -l istio=ingressgateway

对于 macOS 用户,验证您是否使用的是用 [LibreSSL ](http://www.libressl.org/)库编译的	,如[开始之前](#_bookmark45)部分中所述。
curl

### 双向 TLS 问题排查

除了上一节中的步骤之外,请执行以下操作:

验证	pod 已经加载了 CA 证书:
istio-ingressgateway


$ kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingressgateway -o
1. jsonpath='{.items[0].metadata.name}') -- ls -al /etc/istio/ingressgateway-ca-certs

应存在于文件夹之中。
example.com.crt


如果您已经创建了
istio-ingressgateway-ca-certs
pod 以强行重新加载证书:
secret,但是 CA 证书未加载,删掉 ingress 网关


If you created the	secret, but the CA certificate is not
istio-ingressgateway-ca-certs
loaded, delete the ingress gateway pod and force it to reload the certificate:


1. $ kubectl delete pod -n istio-system -l istio=ingressgateway

验证 ingress 网关的 CA 证书的	是正确的:
Subject


$ kubectl exec -i -n istio-system $(kubectl get pod -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}') -- cat /etc/istio/ingressgateway-ca-certs/example.com.crt |

1. openssl x509 -text -noout | grep 'Subject:'
2. Subject: O=example Inc., CN=example.com

## 清理
VirtualService


1. 删除

Gateway
配置、
和 secrets:




1. $ kubectl delete gateway --ignore-not-found=true httpbin-gateway bookinfo-gateway
2. $ kubectl delete virtualservice httpbin

$ kubectl delete --ignore-not-found=true -n istio-system secret istio-ingressgateway-certs istio-

1. ingressgateway-ca-certs
2. $ kubectl delete --ignore-not-found=true virtualservice bookinfo

1. 删除证书目录和用于生成证书的存储库:


$ rm -rf example.com.crt example.com.key httpbin.example.com.crt httpbin.example.com.key httpbin.example.com.csr httpbin-client.example.com.crt httpbin-client.example.com.key httpbin-
1. client.example.com.csr bookinfo.com.crt bookinfo.com.key bookinfo.com.csr

1. 删除用于重新部署	的更新文件:

istio-ingressgateway


1. $ rm -f gateway-patch.json

1. 关闭 [httpbin ](https://github.com/istio/istio/tree/release-1.6/samples/httpbin)服务:

[Zip](https://raw.githubusercontent.com/istio/istio/release-1.6/samples/httpbin/httpbin.yaml)


1. $ kubectl delete --ignore-not-found=true -f @samples/httpbin/httpbin.yaml@

## 相关内容

[把 Istio 作为外部服务的代理](https://istio.io/zh/blog/2019/proxy/)
把 Istio 入口网关配置为外部服务的代理。
[使用 Cert-Manager 部署一个自定义 Ingress 网关](https://istio.io/zh/blog/2019/custom-ingress-gateway/)
如何使用 cert-manager 手工部署一个自定义 Ingress 网关。


[使用 AWS NLB 配置 Istio Ingress](https://istio.io/zh/blog/2018/aws-nlb/)
描述如何在 AWS 上使用网络负载均衡器配置 Istio Ingress。Ingress Gateway
描述如何配置 Istio gateway,以将服务暴露至服务网格之外。使用 SDS 为 Gateway 提供 HTTPS 加密支持
使用 Secret 发现服务(SDS) 通过 TLS 或者 mTLS 把服务暴露给服务网格外部。无 TLS 终止的 Ingress Gateway
说明了如何为一个 ingress gateway 配置 SNI 透传。



# 使用 SDS 为 Gateway 提供 HTTPS 加密支持

控制 Ingress 流量任务中描述了如何进行配置, 通过 Ingress Gateway 把服务的 HTTP 端点暴露给外部。这里更进一步,使用单向或者双向 TLS 来完成开放服务的任务。

双向 TLS 所需的私钥、服务器证书以及根证书都由 Secret 发现服务(SDS)完成配置。

## 开始之前

1. 首先执行 Ingress 任务的初始化步骤,然后执行 Ingress 流量控制部分中获取 Ingress 的地址和端

口,在完成这些步骤之后,也就是完成了 Istio 和 [httpbin ](https://github.com/istio/istio/tree/release-1.6/samples/httpbin)的部署,并设置了	和两个环境变量的值。
INGRESS_HOST
SECURE_INGRESS_PORT

1. macOS 用户应该检查一下本机的	是否是使用 [LibreSSL ](http://www.libressl.org/)库进行编译的:

curl


1. $ curl --version | grep LibreSSL
2. curl 7.54.0 (x86_64-apple-darwin17.0) libcurl/7.54.0 LibreSSL/2.0.20 zlib/1.2.11 nghttp2/1.24.0

如果上面的命令输出了一段 LibreSSL 的版本信息,就说明你的	命令可以完成本任务的内容。否则
curl
就要想办法换一个不同的	了,例如可以换用一台运行 Linux 的工作站。
curl

如果使用基于文件安装的方法配置了 ingress gateway ,并且想要迁移 ingress gateway 使用 SDS 方法。无需其他步骤。

## 为服务器和客户端生成证书

可以使用各种常用工具来生成证书和私钥。这个例子中用了一个来自
[https://github.com/nicholasjackson/mtls-go-example ](https://github.com/nicholasjackson/mtls-go-example)的[脚本](https://github.com/nicholasjackson/mtls-go-example/blob/master/generate.sh)来完成工作。

1. 克隆[示例代码库](https://github.com/nicholasjackson/mtls-go-example):


1. $ git clone https://github.com/nicholasjackson/mtls-go-example

1. 进入代码库文件夹:


1. $ pushd mtls-go-example


1. 为

httpbin.example.com
生成证书。注意要把下面命令中的
替换为其它值。




1. $ ./generate.sh httpbin.example.com <password>

看到提示后,所有问题都输入	Y	即可。这个命令会生成四个目
password
![](https://img-blog.csdnimg.cn/img_convert/19bb417ae520b266cfc29b6778f9b5a7.png)
录:	、   2_intermediate 、	以及	。这些目录中包含了后续过程所需的客
1_root
3_application
4_client
户端和服务端证书。


1. 把证书移动到	目录之中:

httpbin.example.com


1. $ mkdir ../httpbin.example.com && mv 1_root 2_intermediate 3_application 4_client ../httpbin.example.com

1. 返回之前的目录:

1. $ popd

## 使用 SDS 配置 TLS Ingress Gateway

可以配置 TLS Ingress Gateway ,让它从 Ingress Gateway 代理通过 SDS 获取凭据。Ingress Gateway
代理和 Ingress Gateway 在同一个 Pod 中运行,监视 Ingress Gateway 所在命名空间中新建的
。在 Ingress Gateway 中启用 SDS 具有如下好处:
Secret

Ingress Gateway 无需重启,就可以动态的新增、删除或者更新密钥/证书对以及根证书。


无需加载
卷。创建了
之后,这个
就会被 Gateway 代理捕

获,并以密钥/证书对和根证书的形式发送给 Ingress Gateway 。
Secret
kubernetes
Secret
Secret


Gateway 代理能够监视多个密钥/证书对。只需要为每个主机名创建以了。
Secret
并更新 Gateway 定义就可


1. 在 Ingress Gateway 上启用 SDS,并部署 Ingress Gateway 代理。 这个功能缺省是禁用的,因此需

[istio-ingressgateway.sds.enabled](https://github.com/istio/istio/blob/release-1.6/manifests/UPDATING-CHARTS.md)
istio-ingressgateway.yaml
要在 Helm 中打开
[开关](https://github.com/istio/istio/blob/release-1.6/manifests/UPDATING-CHARTS.md),然后生成
文件:



1. $ istioctl manifest generate \
2. --set values.gateways.istio-egressgateway.enabled=false \
3. --set values.gateways.istio-ingressgateway.sds.enabled=true > \
4. $HOME/istio-ingressgateway.yaml
5. $ kubectl apply -f $HOME/istio-ingressgateway.yaml

1. 设置两个环境变量:	和	:

INGRESS_HOST
SECURE_INGRESS_PORT


1. $ export SECURE_INGRESS_PORT=$(kubectl -n istio-system \
2. get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
3. $ export INGRESS_HOST=$(kubectl -n istio-system \
4. get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

### 为单一主机配置 TLS Ingress Gateway

1. 启动	样例:

httpbin


1. $ cat <<EOF | kubectl apply -f -
2. apiVersion: v1
3. kind: Service
4. metadata:
5. name: httpbin



1. labels:
2. app: httpbin
3. spec:
4. ports:
5. - name: http

11.	port: 8000

1. selector:
2. app: httpbin 14. ---
3. apiVersion: apps/v1
4. kind: Deployment
5. metadata:
6. name: httpbin
7. spec:
8. replicas: 1
9. selector:
10. matchLabels:
11. app: httpbin
12. version: v1
13. template:
14. metadata:
15. labels:
16. app: httpbin
17. version: v1
18. spec:
19. containers:
20. - image: docker.io/citizenstig/httpbin
21. imagePullPolicy: IfNotPresent
22. name: httpbin
23. ports:
24. - containerPort: 8000
25. EOF

1. 为 Ingress Gateway 创建

Secret:


1. $ kubectl create -n istio-system secret generic httpbin-credential \
2. --from-file=key=httpbin.example.com/3_application/private/httpbin.example.com.key.pem \
3. --from-file=cert=httpbin.example.com/3_application/certs/httpbin.example.com.cert.pem


secret name 不能 以	或者
istio
prometheus
为开头, 且 secret 不能 包含
字段。

1. 创建一个 Gateway ,其	servers:	字段的端口为 443,设置	credentialName	的值为

token
httpbin-
。这个值就是	Secret	的名字。TLS 模式设置为	SIMPLE 。
credential


1. $ cat <<EOF | kubectl apply -f -
2. apiVersion: networking.istio.io/v1alpha3
3. kind: Gateway
4. metadata:
5. name: mygateway
6. spec:
7. selector:



1. istio: ingressgateway # use istio default ingress gateway
2. servers:
3. - port:
4. number: 443
5. name: https
6. protocol: HTTPS
7. tls:
8. mode: SIMPLE
9. credentialName: "httpbin-credential" # must be the same as secret
10. hosts:
11. - "httpbin.example.com"
12. EOF

1. 配置 Gateway 的 Ingress 流量路由,并配置对应的	:

VirtualService


1. $ cat <<EOF | kubectl apply -f -
2. apiVersion: networking.istio.io/v1alpha3
3. kind: VirtualService
4. metadata:
5. name: httpbin
6. spec:
7. hosts:
8. - "httpbin.example.com"
9. gateways:
10. - mygateway
11. http:
12. - match:
13. - uri:
14. prefix: /status
15. - uri:
16. prefix: /delay
17. route:
18. - destination:
19. port:
20. number: 8000
21. host: httpbin
22. EOF

1. 用 HTTPS 协议访问	服务:

httpbin


1. $ curl -v -HHost:httpbin.example.com \
2. --resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST \
3. --cacert httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem \
4. https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418

服务会返回 [418 I’m a Teapot](https://tools.ietf.org/html/rfc7168#section-2.3.3)。
httpbin

1. 删除 Gateway 的	,并新建另外一个,然后修改 Ingress Gateway 的凭据:

Secret


1. $ kubectl -n istio-system delete secret httpbin-credential




1. $ pushd mtls-go-example
2. $ ./generate.sh httpbin.example.com <password>

$ mkdir ../httpbin.new.example.com && mv 1_root 2_intermediate 3_application 4_client

1. ../httpbin.new.example.com
2. $ popd
3. $ kubectl create -n istio-system secret generic httpbin-credential \
4. --from-file=key=httpbin.new.example.com/3_application/private/httpbin.example.com.key.pem \
5. --from-file=cert=httpbin.new.example.com/3_application/certs/httpbin.example.com.cert.pem

1. 使用	访问	服务:

curl
httpbin

1. $ curl -v -HHost:httpbin.example.com \
2. --resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST \
3. --cacert httpbin.new.example.com/2_intermediate/certs/ca-chain.cert.pem \
4. https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418 5. ...

6. HTTP/2 418
7. ...
8. -=[ teapot ]=- 9.
10.	_...._
11.  .' _ _ `.
12. | ."` ^ `". _, 13. \_;`"---"`|//
14.
15.
16.
|
\_
;/
_/
`"""`

1. 如果尝试使用之前的证书链来再次访问	,就会得到失败的结果:

httpbin


1. $ curl -v -HHost:httpbin.example.com \
2. --resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST \
3. --cacert httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem \
4. https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418 5. ...
5. * TLSv1.2 (OUT), TLS handshake, Client hello (1):
6. * TLSv1.2 (IN), TLS handshake, Server hello (2):
7. * TLSv1.2 (IN), TLS handshake, Certificate (11):
8. * TLSv1.2 (OUT), TLS alert, Server hello (2):
9. * SSL certificate problem: unable to get local issuer certificate

### 为 TLS Ingress Gateway 配置多个主机名

可以把多个主机名配置到同一个 Ingress Gateway 上,例如	httpbin.example.com	和
helloworld-
。Ingress Gateway 会为每个	credentialName	获取一个唯一的凭据。
v1.example.com

1. 要恢复 “httpbin” 的凭据,请删除对应的 secret 并重新创建。


1. $ kubectl -n istio-system delete secret httpbin-credential
2. $ kubectl create -n istio-system secret generic httpbin-credential \



1. --from-file=key=httpbin.example.com/3_application/private/httpbin.example.com.key.pem \
2. --from-file=cert=httpbin.example.com/3_application/certs/httpbin.example.com.cert.pem

1. 启动	示例:

hellowworld-v1

   1. $ cat <<EOF | kubectl apply -f -
   2. apiVersion: v1
   3. kind: Service
   4. metadata:
   5. name: helloworld-v1
   6. labels:
   7. app: helloworld-v1
   8. spec:
   9. ports:
   10. - name: http

11.	port: 5000

1. selector:
2. app: helloworld-v1 14. ---
3. apiVersion: apps/v1
4. kind: Deployment
5. metadata:
6. name: helloworld-v1
7. spec:
8. replicas: 1
9. selector:
10. matchLabels:
11. app: helloworld-v1
12. version: v1
13. template:
14. metadata:
15. labels:
16. app: helloworld-v1
17. version: v1
18. spec:
19. containers:
20. - name: helloworld
21. image: istio/examples-helloworld-v1
22. resources:
23. requests:

36.	cpu: "100m"

1. imagePullPolicy: IfNotPresent #Always
2. ports:
3. - containerPort: 5000
4. EOF



1. 为 Ingress Gateway 创建一个 Secret。如果已经创建了

httpbin-credential
Secret 了。
helloworld-credential

,就可以创建




1. $ pushd mtls-go-example
2. $ ./generate.sh helloworld-v1.example.com <password>



$ mkdir ../helloworld-v1.example.com && mv 1_root 2_intermediate 3_application 4_client ../helloworld-

1. v1.example.com
2. $ popd
3. $ kubectl create -n istio-system secret generic helloworld-credential \
4. --from-file=key=helloworld-v1.example.com/3_application/private/helloworld-v1.example.com.key.pem \
5. --from-file=cert=helloworld-v1.example.com/3_application/certs/helloworld-v1.example.com.cert.pem

1. 定义一个 Gateway ,其中包含了两个	server ,都开放了 443 端口。两个	credentialName	字段分别

赋值为	和	helloworld-credential 。设置 TLS 的 mode 为	SIMPLE	。
httpbin-credential


1. $ cat <<EOF | kubectl apply -f -
2. apiVersion: networking.istio.io/v1alpha3
3. kind: Gateway
4. metadata:
5. name: mygateway
6. spec:
7. selector:
8. istio: ingressgateway # use istio default ingress gateway
9. servers:
10. - port:
11. number: 443
12. name: https-httpbin
13. protocol: HTTPS
14. tls:
15. mode: SIMPLE
16. credentialName: "httpbin-credential"
17. hosts:
18. - "httpbin.example.com"
19. - port:
20. number: 443
21. name: https-helloworld
22. protocol: HTTPS
23. tls:
24. mode: SIMPLE
25. credentialName: "helloworld-credential"
26. hosts:
27. - "helloworld-v1.example.com"
28. EOF

1. 配置 Gateway 的流量路由,配置	:

VirtualService


1. $ cat <<EOF | kubectl apply -f -
2. apiVersion: networking.istio.io/v1alpha3
3. kind: VirtualService
4. metadata:
5. name: helloworld-v1
6. spec:
7. hosts:
8. - "helloworld-v1.example.com"
9. gateways:
10. - mygateway
11. http:



1. - match:
2. - uri:
3. exact: /hello
4. route:
5. - destination:
6. host: helloworld-v1
7. port:
8. number: 5000
9. EOF

1. 向	发送 HTTPS 请求:

helloworld-v1.example.com


1. $ curl -v -HHost:helloworld-v1.example.com \
2. --resolve helloworld-v1.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST \
3. --cacert helloworld-v1.example.com/2_intermediate/certs/ca-chain.cert.pem \
4. https://helloworld-v1.example.com:$SECURE_INGRESS_PORT/hello 5. HTTP/2 200

1. 发送 HTTPS 请求到	,还是会看到茶壶:

httpbin.example.com

1. $ curl -v -HHost:httpbin.example.com \
2. --resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST \
3. --cacert httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem \
4. https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418

5.
6.

7.
8.
9.
10.
11.
12.
13.
-=[ teapot ]=-
_...._
.' _ _ `.
| ."` ^ `". _,
\_;`"---"`|//
|
\_
;/
_/
`"""`

### 配置双向 TLS Ingress Gateway

可以对 Gateway 的定义进行扩展,加入[双向 TLS ](https://en.wikipedia.org/wiki/Mutual_authentication)的支持。要修改 Ingress Gateway 的凭据,就要删除并重建
Secret
cacert

对应的
。服务器会使用 CA 证书对客户端进行校验,因此需要使用
字段来保存 CA 证书:




1. $ kubectl -n istio-system delete secret httpbin-credential
2. $ kubectl create -n istio-system secret generic httpbin-credential \
3. --from-file=key=httpbin.example.com/3_application/private/httpbin.example.com.key.pem \
4. --from-file=cert=httpbin.example.com/3_application/certs/httpbin.example.com.cert.pem \
5. --from-file=cacert=httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem

1. 修改 Gateway 定义,设置 TLS 的模式为	:

MUTUAL


1. $ cat <<EOF | kubectl apply -f -
2. apiVersion: networking.istio.io/v1alpha3



1. kind: Gateway
2. metadata:
3. name: mygateway
4. spec:
5. selector:
6. istio: ingressgateway # use istio default ingress gateway
7. servers:
8. - port:
9. number: 443
10. name: https
11. protocol: HTTPS
12. tls:
13. mode: MUTUAL
14. credentialName: "httpbin-credential" # must be the same as secret
15. hosts:
16. - "httpbin.example.com"
17. EOF

1. 使用前面的方式尝试发出 HTTPS 请求,会看到失败的过程:


1. $ curl -v -HHost:httpbin.example.com \
2. --resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST \
3. --cacert httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem \
4. https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418
5. * TLSv1.3 (OUT), TLS handshake, Client hello (1):
6. * TLSv1.3 (IN), TLS handshake, Server hello (2):
7. * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
8. * TLSv1.3 (IN), TLS handshake, Request CERT (13):
9. * TLSv1.3 (IN), TLS handshake, Certificate (11):
10. * TLSv1.3 (IN), TLS handshake, CERT verify (15):
11. * TLSv1.3 (IN), TLS handshake, Finished (20):
12. * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
13. * TLSv1.3 (OUT), TLS handshake, Certificate (11):
14. * TLSv1.3 (OUT), TLS handshake, Finished (20):
15. * TLSv1.3 (IN), TLS alert, unknown (628):

* OpenSSL SSL_read: error:1409445C:SSL routines:ssl3_read_bytes:tlsv13 alert certificate required, errno
16. 0


1. 在为

命令中加入客户端证书和私钥的参数,重新发送请求。(客户端证书参数为
)
curl

--key
,私钥参数


--cert

1. $ curl -v -HHost:httpbin.example.com \
2. --resolve httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST \
3. --cacert httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem \
4. --cert httpbin.example.com/4_client/certs/httpbin.example.com.cert.pem \
5. --key httpbin.example.com/4_client/private/httpbin.example.com.key.pem \
6. https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418 7.

8.
9.

10.
11.
-=[ teapot ]=-
_...._
.' _ _ `.




| 14. | &#124; | ;/ |
| --- | --- | --- |
| 15. | \\_ | _/ |


1. 如果不想用	secret 来存储所有的凭据, 可以创建两个单独的 secret :

12.
13.
| ."` ^ `". _,
\_;`"---"`|//
httpbin-credential

httpbin-credential	用来存储服务器的秘钥和证书
httpbin-credential-cacert	用来存储客户端的 CA 证书且一定要有	后缀
-cacert

使用以下命令创建两个单独的 secret :


1. $ kubectl -n istio-system delete secret httpbin-credential
2. $ kubectl create -n istio-system secret generic httpbin-credential \
3. --from-file=key=httpbin.example.com/3_application/private/httpbin.example.com.key.pem \
4. --from-file=cert=httpbin.example.com/3_application/certs/httpbin.example.com.cert.pem
5. $ kubectl create -n istio-system secret generic httpbin-credential-cacert \
6. --from-file=cacert=httpbin.example.com/2_intermediate/certs/ca-chain.cert.pem

## 故障排查


查看	和
INGRESS_HOST
SECURE_INGRESS_PORT
的值:
环境变量。根据下面的输出内容,确认其中是否包含了有效




1. $ kubectl get svc -n istio-system
2. $ echo INGRESS_HOST=$INGRESS_HOST, SECURE_INGRESS_PORT=$SECURE_INGRESS_PORT

检查	控制器的日志,搜寻其中的错误信息:
istio-ingressgateway


1. $ kubectl logs -n istio-system $(kubectl get pod -l istio=ingressgateway \
2. -n istio-system -o jsonpath='{.items[0].metadata.name}') -c istio-proxy

如果使用的是 macOS,检查其编译信息,确认其中包含 [LibreSSL](http://www.libressl.org/),具体步骤在[开始之前](#_bookmark46)一节中有具体描述。

校验在	命名空间中是否成功创建了	:
istio-system
Secret


1. $ kubectl -n istio-system get secrets

和	都应该出现在列表之中。
httpbin-credential
helloworld-credential

检查日志,看 Ingress Gateway 代理是否已经成功的把密钥和证书对推送给了 Ingress Gateway :


1. $ kubectl logs -n istio-system $(kubectl get pod -l istio=ingressgateway \
2. -n istio-system -o jsonpath='{.items[0].metadata.name}') -c ingress-sds

正常情况下,日志中应该显示	已经成功创建。如果使用的是双向 TLS,还应该看到
httpbin-credential
。通过对日志的查看,能够验证 Ingress Gateway 代理从 Ingress
httpbin-credential-cacert


Gateway 收到了 SDS 请求,资源名称是	,Ingress Gateway 最后得到了应有的密
httpbin-credential
钥/证书对。如果使用的是双向 TLS,日志会显示出密钥/证书对已经发送给 Ingress Gateway ,Gateway
httpbin-credential-cacert

代理接收到了资源名为
证书。

## 清理
的 SDS 请求,Ingress Gateway 用这种方式获取根




1. 删除 Gateway 配置、	以及	:

VirtualService
Secret


1. $ kubectl delete gateway mygateway
2. $ kubectl delete virtualservice httpbin
3. $ kubectl delete --ignore-not-found=true -n istio-system secret httpbin-credential \
4. helloworld-credential
5. $ kubectl delete --ignore-not-found=true virtualservice helloworld-v1

1. 删除证书目录以及用于生成证书的代码库:


1. $ rm -rf httpbin.example.com helloworld-v1.example.com mtls-go-example

1. 删除用于重新部署 Ingress Gateway 的文件:


1. $ rm -f $HOME/istio-ingressgateway.yaml

1. 关闭	和	服务:

httpbin
helloworld-v1


1. $ kubectl delete service --ignore-not-found=true helloworld-v1
2. $ kubectl delete service --ignore-not-found=true httpbin

## 相关内容

[把 Istio 作为外部服务的代理](https://istio.io/zh/blog/2019/proxy/)
把 Istio 入口网关配置为外部服务的代理。
[使用 Cert-Manager 部署一个自定义 Ingress 网关](https://istio.io/zh/blog/2019/custom-ingress-gateway/)
如何使用 cert-manager 手工部署一个自定义 Ingress 网关。[使用 AWS NLB 配置 Istio Ingress](https://istio.io/zh/blog/2018/aws-nlb/)
描述如何在 AWS 上使用网络负载均衡器配置 Istio Ingress。Ingress Gateway
描述如何配置 Istio gateway,以将服务暴露至服务网格之外。安全网关(文件挂载)


使用文件挂载的证书并通过 TLS 或 mTLS 将服务暴露至服务网格之外。无 TLS 终止的 Ingress Gateway
说明了如何为一个 ingress gateway 配置 SNI 透传。



# 无 TLS 终止的 Ingress Gateway

安全网关说明了如何为 HTTP 服务配置 HTTPS 访问入口。 而本示例将说明如何为 HTTPS 服务配置 HTTPS 访问入口,即配置 Ingress Gateway 以执行 SNI 透传,而不是对传入请求进行 TLS 终止。

本任务中的 HTTPS 示例服务是一个简单的 [NGINX ](https://www.nginx.com/)服务。 在接下来的步骤中,你会先在你的 Kubernetes 集群
中创建一个 NGINX 服务。 然后,通过网关给这个服务配置一个域名是	的访问入口。
nginx.example.com

## 生成客户端和服务端的证书和密钥

对于此任务,您可以使用自己喜欢的工具来生成证书和密钥。以下命令使用   [openssl](https://man.openbsd.org/openssl.1)

1. 创建根证书和私钥来为您的服务签名证书:


$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -
1. keyout example.com.key -out example.com.crt

1. 为	创建证书和私钥:

nginx.example.com


$ openssl req -out nginx.example.com.csr -newkey rsa:2048 -nodes -keyout nginx.example.com.key -subj

1. "/CN=nginx.example.com/O=some organization"

$ openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in

1. nginx.example.com.csr -out nginx.example.com.crt

## 部署一个 NGINX 服务

1. 创建一个 Kubernetes 的 [Secret ](https://kubernetes.io/docs/concepts/configuration/secret/)资源来保存服务的证书:


1. $ kubectl create secret tls nginx-server-certs --key nginx.example.com.key --cert nginx.example.com.crt

1. 为 NGINX 服务创建一个配置文件:


1. $ cat <<EOF > ./nginx.conf
2. events { 3. }

4.

1. http {
2. log_format main '$remote_addr - $remote_user [$time_local] $status '
3. '"$request" $body_bytes_sent "$http_referer" '
4. '"$http_user_agent" "$http_x_forwarded_for"';
5. access_log /var/log/nginx/access.log main;
6. error_log /var/log/nginx/error.log; 11.
7. server {
8. listen 443 ssl; 14.



15.
16.
17.
root /usr/share/nginx/html;
index index.html;
18.
19.
20.
21.
22. }
server_name nginx.example.com;
ssl_certificate /etc/nginx-server-certs/tls.crt; ssl_certificate_key /etc/nginx-server-certs/tls.key;
}
23. EOF

1. 创建一个 Kubernetes 的 [ConfigMap ](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/)资源来保存 NGINX 服务的配置:


1. $ kubectl create configmap nginx-configmap --from-file=nginx.conf=./nginx.conf

1. 部署 NGINX 服务

   1. $ cat <<EOF | istioctl kube-inject -f - | ku

http://www.kler.cn/a/233800.html

相关文章:

  • 新版 idea 编写 idea 插件时,启动出现 ClassNotFound
  • 【121. 买卖股票的最佳时机】——贪心算法/动态规划
  • Node.js笔记
  • Springboot 日志处理(非常详细)
  • 使用 start-local 脚本在本地运行 Elasticsearch
  • DOM 规范 — MutationObserver 接口
  • C++2024寒假J312实战班2.5
  • 正点原子--STM32通用定时器学习笔记(2)
  • 速盾:海外服务器用了cdn还是卡怎么办
  • 【CSS】什么是BFC?BFC有什么作用?
  • Android 11 webview webrtc无法使用问题
  • cool 框架 node 后端封装三方Api post请求函数
  • NLP_Bag-Of-Words(词袋模型)
  • 如何进行游戏服务器的负载均衡和扩展性设计?
  • VUE学习——事件参数
  • 每天一个数据分析题(一百五十六)
  • moduleID的使用
  • 【学习笔记】【内核】offsetof 的用法
  • 算法学习——LeetCode力扣二叉树篇1
  • c# 时间帮助类
  • 2.6:冒泡、简选、直插、快排,递归,宏
  • VMware虚拟机安装openEuler系统(一)(2024)
  • Idea里自定义封装数据警告解决 Spring Boot Configuration Annotation Processor not configured
  • Qt QML学习(一):Qt Quick 与 QML 简介
  • 【资料分享】基于单片机大气压监测报警系统电路方案设计、基于飞思卡尔的无人坚守点滴监控自动控制系统设计(程序,原理图,pcb,文档)
  • MySQL-SQL优化