安装和拓展Istio service mesh
安装和拓展 Istio mesh
注意:本文档已失效,请浏览 Istio 官方文档。本书中的 Service Mesh 章节已不再维护,请转到 istio-handbook 中浏览。
前置条件
下面的操作说明需要您可以访问 kubernetes 1.7.3 后更高版本 的集群,并且启用了 RBAC (基于角色的访问控制)。您需要安装了 1.7.3 或更高版本 的 kubectl
命令。如果您希望启用自动注入 sidecar,您需要启用 kubernetes 集群的 alpha 功能。
注意:如果您安装了 Istio 0.1.x,在安装新版本前请先卸载它们(包括已启用 Istio 应用程序 Pod 中的 sidecar)。
取决于您的 kubernetes 提供商:
本地安装 Istio,安装最新版本的 Minikube (version 0.22.1 或者更高)。
使用 kubectl 获取证书 (使用您自己的集群的名字替换
<cluster-name>
,使用集群实际所在的位置替换<zone>
):将集群管理员权限授予当前用户(需要管理员权限才能为Istio创建必要的RBAC规则):
使用 kubectl 获取证书 (使用您自己的集群的名字替换):
Openshift Origin 3.7 或者以上版本:
默认情况下,Openshift 不允许以 UID 0运行容器。为 Istio 的入口(ingress)和出口(egress)service account 启用使用UID 0运行的容器:
运行应用程序 Pod 的 service account 需要特权安全性上下文限制,以此作为 sidecar 注入的一部分:
安装或升级 Kubernetes 命令行工具 kubectl 以匹配您的集群版本(1.7或以上版本)。
安装步骤
不论对于哪个 Istio 发行版,都安装到 istio-system
namespace 下,即可以管理所有其它 namespace 下的微服务。
到 Istio release 页面上,根据您的操作系统下载对应的发行版。如果您使用的是 MacOS 或者 Linux 系统,可以使用下面的额命令自动下载和解压最新的发行版:
解压安装文件,切换到文件所在目录。安装文件目录下包含:
install/
目录下是 kubernetes 使用的.yaml
安装文件samples/
目录下是示例程序istioctl
客户端二进制文件在bin
目录下。istioctl
文件用户手动注入 Envoy sidecar 代理、创建路由和策略等。istio.VERSION
配置文件
切换到 istio 包的解压目录。例如 istio-0.2.7:
将
istioctl
客户端二进制文件加到 PATH 中。例如,在 MacOS 或 Linux 系统上执行下面的命令:
安装 Istio 的核心部分。选择面两个 互斥 选项中的之一:
a) 安装 Istio 的时候不启用 sidecar 之间的 TLS 双向认证:
为具有现在应用程序的集群选择该选项,使用 Istio sidecar 的服务需要能够与非 Istio Kubernetes 服务以及使用 liveliness 和 readiness 探针、headless service 和 StatefulSet 的应用程序通信。
或者
b) 安装 Istio 的时候启用 sidecar 之间的 TLS 双向认证:
这两个选项都会创建
istio-system
命名空间以及所需的 RBAC 权限,并部署 Istio-Pilot、Istio-Mixer、Istio-Ingress、Istio-Egress 和 Istio-CA(证书颁发机构)。可选的:如果您的 kubernetes 集群开启了 alpha 功能,并想要启用自动注入 sidecar,需要安装 Istio-Initializer:
验证安装
确认系列 kubernetes 服务已经部署了:
istio-pilot
、istio-mixer
、istio-ingress
、istio-egress
:注意:如果您运行的集群不支持外部负载均衡器(如 minikube),
istio-ingress
服务的EXTERNAL-IP
显示<pending>
。你必须改为使用 NodePort service 或者 端口转发方式来访问应用程序。确认对应的 Kubernetes pod 已部署并且所有的容器都启动并运行:
istio-pilot-*
、istio-mixer-*
、istio-ingress-*
、istio-egress-*
、istio-ca-*
,istio-initializer-*
是可以选的。
部署应用
您可以部署自己的应用或者示例应用程序如 BookInfo。 注意:应用程序必须使用 HTTP/1.1 或 HTTP/2.0 协议来传输 HTTP 流量,因为 HTTP/1.0 已经不再支持。
如果您启动了 Istio-Initializer,如上所示,您可以使用 kubectl create
直接部署应用。Istio-Initializer 会向应用程序的 pod 中自动注入 Envoy 容器:
如果您没有安装 Istio-initializer 的话,您必须使用 istioctl kube-inject 命令在部署应用之前向应用程序的 pod 中手动注入 Envoy 容器:
卸载
卸载 Istio initializer:
如果您安装 Isto 的时候启用了 initializer,请卸载它:
卸载 Istio 核心组件。对于某一 Istio 版本,删除 RBAC 权限,
istio-system
namespace,和该命名空间的下的各层级资源。不必理会在层级删除过程中的各种报错,因为这些资源可能已经被删除的。
a) 如果您在安装 Istio 的时候关闭了 TLS 双向认证:
或者
b) 如果您在安装 Istio 的时候启用到了 TLS 双向认证:
安装 Istio Sidecar
Pod Spec 需满足的条件
为了成为 Service Mesh 中的一部分,kubernetes 集群中的每个 Pod 都必须满足如下条件:
Service 注解:每个 pod 都必须只属于某一个 Kubernetes Service (当前不支持一个 pod 同时属于多个 service)。
命名的端口:Service 的端口必须命名。端口的名字必须遵循如下格式
<protocol>[-<suffix>]
,可以是http、http2、 grpc、 mongo、 或者 redis 作为<protocol>
,这样才能使用 Istio 的路由功能。例如name: http2-foo
和name: http
都是有效的端口名称,而name: http2foo
不是。如果端口的名称是不可识别的前缀或者未命名,那么该端口上的流量就会作为普通的 TCP 流量(除非使用Protocol: UDP
明确声明使用 UDP 端口)。带有 app label 的 Deployment:我们建议 kubernetes 的
Deploymenet
资源的配置文件中为 Pod 明确指定app
label。每个Deployment 的配置中都需要有个不同的有意义的app
标签。app
label 用于在分布式坠重中添加上下文信息。Mesh 中的每个 pod 里都有一个 Sidecar: 最后,Mesh 中的每个 pod 都必须运行与 Istio 兼容的sidecar。下面部分介绍了将 sidecar 注入到 pod 中的两种方法:使用
istioctl
命令行工具手动注入,或者使用 istio initializer 自动注入。注意 sidecar 不涉及到容器间的流量,因为它们都在同一个 pod 中。
手动注入 sidecar
istioctl
命令行中有一个称为 kube-inject 的便利工具,使用它可以将 Istio 的 sidecar 规范添加到 kubernetes 工作负载的规范配置中。与 Initializer 程序不同,kube-inject
只是将 YAML 规范转换成包含 Istio sidecar 的规范。您需要使用标准的工具如 kubectl
来部署修改后的 YAML。例如,以下命令将 sidecar 添加到 sleep.yaml 文件中指定的 pod 中,并将修改后的规范提交给 kubernetes:
示例
我们来试一试将 Istio sidecar 注入到 sleep 服务中去。
Kube-inject 子命令将 Istio sidecar 和 init 容器注入到 deployment 配置中,转换后的输出如下所示:
注入 sidecar 的关键在于 initContainers
和 istio-proxy 容器。为了简洁起见,上述输出有所省略。
验证 sleep deployment 中包含 sidecar。injected-version 对应于注入的 sidecar 镜像的版本和镜像的 TAG。在您的设置的可能会有所不同。
你可以查看包含注入的容器和挂载的 volume 的完整 deployment 信息。
自动注入 sidecar
Istio sidecar 可以在部署之前使用 Kubernetes 中一个名为 Initializer 的 Alpha 功能自动注入到 Pod 中。
注意:Kubernetes InitializerConfiguration没有命名空间,适用于整个集群的工作负载。不要在共享测试环境中启用此功能。
前置条件
Initializer 需要在集群设置期间显示启用,如 此处 所述。 假设集群中已启用RBAC,则可以在不同环境中启用初始化程序,如下所示:
GKE
IBM Bluemix kubernetes v1.7.4 或更高版本的集群已默认启用 initializer。
Minikube
Minikube v0.22.1 或更高版本需要为 GenericAdmissionWebhook 功能配置适当的证书。获取最新版本: https://github.com/kubernetes/minikube/releases.
安装
您现在可以从 Istio 安装根目录设置 Istio Initializer。
将会创建下列资源:
istio-sidecar
InitializerConfiguration 资源,指定 Istio sidecar 注入的资源。默认情况下 Istio sidecar 将被注入到deployment
、statefulset
、job
和daemonset
中。istio-inject
ConfigMap,initializer 的默认注入策略,一组初始化 namespace,以及注入时使用的模版参数。这些配置的详细说明请参考配置选项。istio-initializer
Deployment,运行 initializer 控制器。istio-initializer-service-account
ServiceAccount,用于istio-initializer
deployment。ClusterRole
和ClusterRoleBinding
在install/kubernetes/istio.yaml
中定义。注意所有的资源类型都需要有initialize
和patch
。正式处于这个原因,initializer 要作为 deployment 的一部分来运行而不是嵌入到其它控制器中,例如 istio-pilot。
验证
为了验证 sidecar 是否成功注入,为上面的 sleep 服务创建 deployment 和 service。
验证 sleep deployment 中包含 sidecar。injected-version 对应于注入的 sidecar 镜像的版本和镜像的 TAG。在您的设置的可能会有所不同。
你可以查看包含注入的容器和挂载的 volume 的完整 deployment 信息。
了解发生了什么
以下是将工作负载提交给 Kubernetes 后发生的情况:
1) kubernetes 将 sidecar.initializer.istio.io
添加到工作负载的 pending initializer 列表中。
2) istio-initializer 控制器观察到有一个新的未初始化的工作负载被创建了。pending initializer 列表中的第一个个将作为 sidecar.initializer.istio.io
的名称。
3) istio-initializer 检查它是否负责初始化 namespace 中的工作负载。如果没有为该 namespace 配置 initializer,则不需要做进一步的工作,而且 initializer 会忽略工作负载。默认情况下,initializer 负责所有的 namespace。
4) istio-initializer 将自己从 pending initializer 中移除。如果 pending initializer 列表非空,则 Kubernetes 不回结束工作负载的创建。错误配置的 initializer 意味着破损的集群。
5) istio-initializer 检查 mesh 的默认注入策略,并检查所有单个工作负载的策略负载值,以确定是否需要注入 sidecar。
6) istio-initializer 向工作负载中注入 sidecar 模板,然后通过 PATCH 向 kubernetes 提交。
7) kubernetes 正常的完成了工作负载的创建,并且工作负载中已经包含了注入的 sidecar。
配置选项
istio-initializer 具有用于注入的全局默认策略以及每个工作负载覆盖配置。全局策略由 istio-inject
ConfigMap 配置(请参见下面的示例)。Initializer pod 必须重新启动以采用新的配置更改。
下面是配置中的关键参数:
policy
off
- 禁用 initializer 修改资源。pending 的sidecar.initializer.istio.io
initializer 将被删除以避免创建阻塞资源。disable
- initializer 不会注入 sidecar 到 watch 的所有 namespace 的资源中。启用 sidecar 注入请将sidecar.istio.io/inject
注解的值设置为true
。enable
- initializer 将会注入 sidecar 到 watch 的所有 namespace 的资源中。禁用 sidecar 注入请将sidecar.istio.io/inject
注解的值设置为false
。namespaces
要 watch 和初始化的 namespace 列表。特殊的
""
namespace 对应于v1.NamespaceAll
并配置初始化程序以初始化所有 namespace。kube-system
、kube-publice
和istio-system
被免除初始化。excludeNamespaces
从 Istio initializer 中排除的 namespace 列表。不可以定义为
v1.NamespaceAll
或者与namespaces
一起定义。initializerName
这必须与 InitializerConfiguration 中 initializer 设定项的名称相匹配。Initializer 只处理匹配其配置名称的工作负载。
params
这些参数允许您对注入的 sidecar 进行有限的更改。更改这些值不会影响已部署的工作负载。
重写自动注入
单个工作负载可以通过使用 sidecar.istio.io/inject
注解重写全局策略。如果注解被省略,则使用全局策略。
如果注解的值是 true
,则不管全局策略如何,sidecar 都将被注入。
如果注解的值是 false
,则不管全局策略如何,sidecar 都不会被注入。
下表显示全局策略和每个工作负载覆盖的组合。
policy | workload annotation | injected |
off | N/A | no |
disabled | omitted | no |
disabled | false | no |
disabled | true | yes |
enabled | omitted | yes |
enabled | false | no |
enabled | true | yes |
例如,即使全局策略是 disable
,下面的 deployment 也会被注入sidecar。
这是在包含 Istio 和非 Istio 服务的混合群集中使用自动注入的好方法。
卸载 Initializer
运行下面的命令,删除 Istio initializer:
注意上述命令并不会删除已注入到 Pod 中的 sidecar。要想删除这些 sidecar,需要在不使用 initializer 的情况下重新部署这些 pod。
拓展 Istio Mesh
将虚拟机或裸机集成到部署在 kubernetes 集群上的 Istio mesh 中的说明。
前置条件
按照安装指南在 kubernetes 集群上安装 Istio service mesh。
机器必须具有到 mesh 端点的 IP 地址连接。这通常需要一个 VPC 或者 VPN,以及一个向端点提供直接路由(没有 NAT 或者防火墙拒绝)的容器网络。及其不需要访问有 Kubernetes 分配的 cluster IP。
虚拟机必须可以访问到 Istio 控制平面服务(如Pilot、Mixer、CA)和 Kubernetes DNS 服务器。通常使用 内部负载均衡器 来实现。
您也可以使用 NodePort,在虚拟机上运行 Istio 的组件,或者使用自定义网络配置,有几个单独的文档会涵盖这些高级配置。
安装步骤
安装过程包括准备用于拓展的 mesh 和安装和配置虚拟机。
install/tools/setupMeshEx.sh :这是一个帮助大家设置 kubernetes 环境的示例脚本。检查脚本内容和支持的环境变量(如 GCP_OPTS)。
install/tools/setupIstioVM.sh:这是一个用于配置主机环境的示例脚本。 您应该根据您的配置工具和DNS要求对其进行自定义。
准备要拓展的 Kubernetes 集群:
为 Kube DNS、Pilot、Mixer 和 CA 安装内部负载均衡器(ILB)。每个云供应商的配置都有所不同,根据具体情况修改注解。
0.2.7 版本的 YAML 文件的 DNS ILB 的 namespace 配置不正确。 使用 这一个 替代。
setupMeshEx.sh
中也有错误。使用上面链接中的最新文件或者从 GitHub.com/istio/istio 克隆。
生成要部署到虚拟机上的 Istio
cluster.env
配置。该文件中包含要拦截的 cluster IP 地址范围。
该示例生成的文件:
产生虚拟机使用的 DNS 配置文件。这样可以让虚拟机上的应用程序解析到集群中的服务名称,这些名称将被 sidecar 拦截和转发。
该示例生成的文件:
设置机器
例如,您可以使用下面的“一条龙”脚本复制和安装配置:
或者等效得手动安装步骤如下:
------ 手动安装步骤开始 ------
将配置文件和 Istio 的 Debian 文件复制到要加入到集群的每台机器上。重命名为
/etc/dnsmasq.d/kubedns
和/var/lib/istio/envoy/cluster.env
。配置和验证 DNS 配置。需要安装
dnsmasq
或者直接将其添加到/etc/resolv.conf
中,或者通过 DHCP 脚本。验证配置是否有效,检查虚拟机是否可以解析和连接到 pilot,例如:
在虚拟机或外部主机上:
产生的消息示例:
检查是否可以解析 cluster IP。实际地址取决您的 deployment:
该示例产生的消息:
同样检查 istio-ingress:
该示例产生的消息:
验证连接性,检查迅即是否可以连接到 Pilot 的端点:
提取出实话 Istio 认证的 secret 并将它复制到机器上。Istio 的默认安装中包括 CA,即使是禁用了自动
mTLS
设置(她为每个 service account 创建 secret,secret 命名为istio.<serviceaccount>
)也会生成 Istio secret。建议您执行此步骤,以便日后启用 mTLS,并升级到默认启用 mTLS 的未来版本。
生成的文件(key.pem
, root-cert.pem
, cert-chain.pem
)必须拷贝到每台主机的 /etc/certs 目录,并且让 istio-proxy 可读。
安装 Istio Debian 文件,启动
istio
和istio-auth-node-agent
服务。 从 github releases 获取 Debian 安装包:
------ 手动安装步骤结束 ------
安装完成后,机器就能访问运行在 Kubernetes 集群上的服务或者其他的 mesh 拓展的机器。
检查进程是否正在运行:
检查 Istio auth-node-agent 是否健康:
在拓展的 mesh 中的机器上运行服务
配置 sidecar 拦截端口。在
/var/lib/istio/envoy/sidecar.env
中通过ISTIO_INBOUND_PORTS
环境变量配置。例如(运行服务的虚拟机):
手动配置 selector-less 的 service 和 endpoint。“selector-less” service 用于那些不依托 Kubernetes pod 的 service。
例如,在有权限的机器上修改 Kubernetes 中的 service:
安装完成后,Kubernetes pod 和其它 mesh 扩展将能够访问集群上运行的服务。
整合到一起
请参阅拓展 BookInfo Mesh 指南。
部署 bookinfo 示例应用
该示例部署由四个单独的微服务组成的简单应用程序,用于演示Istio服务网格的各种功能。
概况
在本示例中,我们将部署一个简单的应用程序,显示书籍的信息,类似于网上书店的书籍条目。在页面上有书籍的描述、详细信息(ISBN、页数等)和书评。
BookInfo 应用程序包括四个独立的微服务:
productpage:productpage(产品页面)微服务,调用 details 和 reviews 微服务来填充页面。
details:details 微服务包含书籍的详细信息。
reviews:reviews 微服务包含书籍的点评。它也调用 ratings 微服务。
ratings:ratings 微服务包含随书评一起出现的评分信息。
有3个版本的 reviews 微服务:
版本v1不调用 ratings 服务。
版本v2调用 ratings ,并将每个评级显示为1到5个黑色星。
版本v3调用 ratings ,并将每个评级显示为1到5个红色星。
应用程序的端到端架构如下所示。
该应用程序是多语言构建的,即这些微服务是用不同的语言编写的。值得注意的是,这些服务与 Istio 没有任何依赖关系,单这是个有趣的 Service Mesh 示例,特别是因为评论服务和众多的语言和版本。
开始之前
如果您还没有这样做,请按照与您的平台安装指南对应的说明安装Istio。
部署应用程序
使用 Istio 运行应用程序示例不需要修改应用程序本身。相反,我们只需要在支持 Istio 的环境中配置和运行服务, Envoy sidecar 将会注入到每个服务中。所需的命令和配置根据运行时环境的不同而有所不同,但在所有情况下,生成的部署将如下所示:
所有的微服务都将与一个 Envoy sidecar 一起打包,拦截这些服务的入站和出站的调用请求,提供通过 Istio 控制平面从外部控制整个应用的路由,遥测收集和策略执行所需的 hook。
要启动该应用程序,请按照以下对应于您的 Istio 运行时环境的说明进行操作。
在 Kubernetes 中运行
注意:如果您使用 GKE,清确保您的集群至少有 4 个标准的 GKE 节点。如果您使用 Minikube,请确保您至少有 4GB 内存。
将目录更改为 Istio 安装目录的根目录。
构建应用程序容器:
如果您使用 自动注入 sidecar 的方式部署的集群,那么只需要使用
kubectl
命令部署服务:如果您使用 手动注入 sidecar 的方式部署的集群,清使用下面的命令:
请注意,该
istioctl kube-inject
命令用于在创建部署之前修改bookinfo.yaml
文件。这将把 Envoy 注入到 Kubernetes 资源。上述命令启动四个微服务并创建网关入口资源,如下图所示。3 个版本的评论的服务 v1、v2、v3 都已启动。
请注意在实际部署中,随着时间的推移部署新版本的微服务,而不是同时部署所有版本。
确认所有服务和 pod 已正确定义并运行:
这将产生以下输出:
而且
将产生:
确定 ingress IP 和端口
如果您的 kubernetes 集群环境支持外部负载均衡器的话,可以使用下面的命令获取 ingress 的IP地址:
输出如下所示:
Ingress 服务的地址是:
GKE:如果服务无法获取外部 IP,
kubectl get ingress -o wide
会显示工作节点的列表。在这种情况下,您可以使用任何地址以及 NodePort 访问入口。但是,如果集群具有防火墙,则还需要创建防火墙规则以允许TCP流量到NodePort,您可以使用以下命令创建防火墙规则:IBM Bluemix Free Tier:在免费版的 Bluemix 的 kubernetes 集群中不支持外部负载均衡器。您可以使用工作节点的公共 IP,并通过 NodePort 来访问 ingress。工作节点的公共 IP可以通过如下命令获取:
Minikube:Minikube 不支持外部负载均衡器。您可以使用 ingress 服务的主机 IP 和 NodePort 来访问 ingress:
在 Consul 或 Eureka 环境下使用 Docker 运行
切换到 Istio 的安装根目录下。
启动应用程序容器。
执行下面的命令测试 Consul:
执行下面的命令测试 Eureka:
确认所有容器都在运行:
docker ps -a
如果 Istio Pilot 容器终止了,重新执行上面的命令重新运行。
设置
GATEWAY_URL
:
下一步
使用以下 curl
命令确认 BookInfo 应用程序正在运行:
你也可以通过在浏览器中打开 http://$GATEWAY_URL/productpage
页面访问 Bookinfo 网页。如果您多次刷新浏览器将在 productpage 中看到评论的不同的版本,它们会按照 round robin(红星、黑星、没有星星)的方式展现,因为我们还没有使用 Istio 来控制版本的路由。
现在,您可以使用此示例来尝试 Istio 的流量路由、故障注入、速率限制等功能。要继续的话,请参阅 Istio 指南,具体取决于您的兴趣。智能路由 是初学者入门的好方式。
清理
在完成 BookInfo 示例后,您可以卸载它,如下所示:
卸载 Kubernetes 环境
删除路由规则,终止应用程序 pod
确认关闭
卸载 docker 环境
删除路由规则和应用程序容器
若使用 Consul 环境安装,执行下面的命令:
若使用 Eureka 环境安装,执行下面的命令:
确认清理完成:
Last updated