- A+
今年来以 Istio 和 Linkderd 为代表的 Service Mesh 蓬勃发展,大有成为下一代语言异构微服务架构的王者之范,今天又碰巧看到了 Red Hat 的 Burr Sutter 提出了8 Steps to Becoming Awesome with Kubernetes,整个PPT一共60多页,很有建设性,点此跳转到我的GitHub上下载,我将其归档到cloud-native-slides-share中了。
自我6月份初接触Istio依赖就发觉service mesh很好的解决了异构语言中的很多问题,而且是kuberentes service 上层不可或缺的服务间代理。关于istio的更多内容请参考 istio中文文档。
快速开始
前置条件
下面的操作说明需要您可以访问 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 或者更高)。
- Google Container Engine
- 使用 kubectl 获取证书 (使用您自己的集群的名字替换 <cluster-name> ,使用集群实际所在的位置替换 <zone> ):
gcloud container clusters get-credentials <cluster-name> --zone <zone> --project <project-name>
- 将集群管理员权限授予当前用户(需要管理员权限才能为Istio创建必要的RBAC规则):
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value core/account)
- IBM Bluemix Container Service
- 使用 kubectl 获取证书 (使用您自己的集群的名字替换):
<cluster-name>
$(bx cs cluster-config <cluster-name>|grep "export KUBECONFIG")
- Openshift Origin 3.7 或者以上版本:
- 默认情况下,Openshift 不允许以 UID 0运行容器。为 Istio 的入口(ingress)和出口(egress)service account 启用使用UID 0运行的容器:
oc adm policy add-scc-to-user anyuid -z istio-ingress-service-account -n istio-system oc adm policy add-scc-to-user anyuid -z istio-egress-service-account -n istio-system oc adm policy add-sc-to-user anyuid -z default -n istio-system
- 运行应用程序 Pod 的 service account 需要特权安全性上下文限制,以此作为 sidecar 注入的一部分:
oc adm policy add-scc-to-user privileged -z default -n <target-namespace>
- 安装或升级 Kubernetes 命令行工具 kubectl 以匹配您的集群版本(1.7或以上版本)。
安装步骤
不论对于哪个 Istio 发行版,都安装到 istio-system namespace 下,即可以管理所有其它 namespace 下的微服务。
- 到 Istio release 页面上,根据您的操作系统下载对应的发行版。如果您使用的是 MacOS 或者 Linux 系统,可以使用下面的额命令自动下载和解压最新的发行版:
curl -L https://git.io/getLatestIstio | sh -
- 解压安装文件,切换到文件所在目录。安装文件目录下包含:
- install/ 目录下是 kubernetes 使用的 .yaml 安装文件
- samples/ 目录下是示例程序
- istioctl 客户端二进制文件在 bin 目录下。istioctl 文件用户手动注入 Envoy sidecar 代理、创建路由和策略等。
- istio.VERSION 配置文件
- 切换到 istio 包的解压目录。例如 istio-0.2.7:
cd istio-0.2.7
- 将 istioctl 客户端二进制文件加到 PATH 中。
例如,在 MacOS 或 Linux 系统上执行下面的命令:
export PATH=$PWD/bin:$PATH
- 安装 Istio 的核心部分。选择面两个 互斥 选项中的之一:
a) 安装 Istio 的时候不启用 sidecar 之间的 TLS 双向认证:
为具有现在应用程序的集群选择该选项,使用 Istio sidecar 的服务需要能够与非 Istio Kubernetes 服务以及使用 liveliness 和 readiness 探针、headless service 和 StatefulSet 的应用程序通信。
kubectl apply -f install/kubernetes/istio.yaml
或者
b) 安装 Istio 的时候启用 sidecar 之间的 TLS 双向认证:
kubectl apply -f install/kubernetes/istio-auth.yaml
这两个选项都会创建 istio-system 命名空间以及所需的 RBAC 权限,并部署 Istio-Pilot、Istio-Mixer、Istio-Ingress、Istio-Egress 和 Istio-CA(证书颁发机构)。
- 可选的:如果您的 kubernetes 集群开启了 alpha 功能,并想要启用 自动注入 sidecar,需要安装 Istio-Initializer:
kubectl apply -f install/kubernetes/istio-initializer.yaml
验证安装
- 确认系列 kubernetes 服务已经部署了: istio-pilot、 istio-mixer、istio-ingress、 istio-egress:
kubectl get svc -n istio-system
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-egress 10.83.247.89 <none> 80/TCP 5h istio-ingress 10.83.245.171 35.184.245.62 80:32730/TCP,443:30574/TCP 5h istio-pilot 10.83.251.173 <none> 8080/TCP,8081/TCP 5h istio-mixer 10.83.244.253 <none> 9091/TCP,9094/TCP,42422/TCP 5h
注意:如果您运行的集群不支持外部负载均衡器(如 minikube), istio-ingress 服务的 EXTERNAL-IP 显示<pending>。你必须改为使用 NodePort service 或者 端口转发方式来访问应用程序。
- 确人对应的 Kubernetes pod 已部署并且所有的容器都启动并运行: istio-pilot-*、 istio-mixer-*、 istio-ingress-*、 istio-egress-*、istio-ca-*, istio-initializer-* 是可以选的。
kubectl get pods -n istio-system
istio-ca-3657790228-j21b9 1/1 Running 0 5h istio-egress-1684034556-fhw89 1/1 Running 0 5h istio-ingress-1842462111-j3vcs 1/1 Running 0 5h istio-initializer-184129454-zdgf5 1/1 Running 0 5h istio-pilot-2275554717-93c43 1/1 Running 0 5h istio-mixer-2104784889-20rm8 2/2 Running 0 5h
部署应用
您可以部署自己的应用或者示例应用程序如 BookInfo。 注意:应用程序必须使用 HTTP/1.1 或 HTTP/2.0 协议来传递 HTTP 流量,因为 HTTP/1.0 已经不再支持。
如果您启动了 Istio-Initializer,如上所示,您可以使用 kubectl create 直接部署应用。Istio-Initializer 会向应用程序的 pod 中自动注入 Envoy 容器:
kubectl create -f <your-app-spec>.yaml
如果您没有安装 Istio-initializer 的话,您必须使用 istioctl kube-inject 命令在部署应用之前向应用程序的 pod 中手动注入 Envoy 容器:
kubectl create -f <(istioctl kube-inject -f <your-app-spec>.yaml)
卸载
- 卸载 Istio initializer:
如果您安装 Isto 的时候启用了 initializer,请卸载它:
kubectl delete -f install/kubernetes/istio-initializer.yaml
- 卸载 Istio 核心组件。对于某一 Istio 版本,删除 RBAC 权限,istio-system namespace,和该命名空间的下的各层级资源。
不必理会在层级删除过程中的各种报错,因为这些资源可能已经被删除的。
a) 如果您在安装 Istio 的时候关闭了 TLS 双向认证:
kubectl delete -f install/kubernetes/istio.yaml
或者
b) 如果您在安装 Istio 的时候启用到了 TLS 双向认证:
kubectl delete -f install/kubernetes/istio-auth.yaml
安装 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:
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)
示例
我们来试一试将 Istio sidecar 注入到 sleep 服务中去。
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)
Kube-inject 子命令将 Istio sidecar 和 init 容器注入到 deployment 配置中,转换后的输出如下所示:
... 略过 ... --- apiVersion: extensions/v1beta1 kind: Deployment metadata: annotations: sidecar.istio.io/status: injected-version-root@69916ebba0fc-0.2.6-081ffece00c82cb9de33cd5617682999aee5298d name: sleep spec: replicas: 1 template: metadata: annotations: sidecar.istio.io/status: injected-version-root@69916ebba0fc-0.2.6-081ffece00c82cb9de33cd5617682999aee5298d labels: app: sleep spec: containers: - name: sleep image: tutum/curl command: ["/bin/sleep","infinity"] imagePullPolicy: IfNotPresent - name: istio-proxy image: docker.io/istio/proxy_debug:0.2.6 args: ... 略过 ... initContainers: - name: istio-init image: docker.io/istio/proxy_init:0.2.6 imagePullPolicy: IfNotPresent args: ... 略过 ... ---
注入 sidecar 的关键在于 initContainers 和 istio-proxy 容器。为了简洁起见,上述输出有所省略。
验证 sleep deployment 中包含 sidecar。injected-version 对应于注入的 sidecar 镜像的版本和镜像的 TAG。在您的设置的可能会有所不同。
echo $(kubectl get deployment sleep -o jsonpath='{.metadata.annotations.sidecar\.istio\.io\/status}')
injected-version-9c7c291eab0a522f8033decd0f5b031f5ed0e126
你可以查看包含注入的容器和挂载的 volume 的完整 deployment 信息。
kubectl get deployment sleep -o yaml
自动注入 sidecar
Istio sidecar 可以在部署之前使用 Kubernetes 中一个名为 Initializer 的 Alpha 功能自动注入到 Pod 中。
注意:Kubernetes InitializerConfiguration没有命名空间,适用于整个集群的工作负载。不要在共享测试环境中启用此功能。
前置条件
Initializer 需要在集群设置期间显示启用,如 此处 所述。 假设集群中已启用RBAC,则可以在不同环境中启用初始化程序,如下所示:
- GKE
gcloud container clusters create NAME \ --enable-kubernetes-alpha \ --machine-type=n1-standard-2 \ --num-nodes=4 \ --no-enable-legacy-authorization \ --zone=ZONE
- IBM Bluemix kubernetes v1.7.4 或更高版本的集群已默认启用 initializer。
- Minikube
Minikube v0.22.1 或更高版本需要为 GenericAdmissionWebhook 功能配置适当的证书。获取最新版本: https://github.com/kubernetes/minikube/releases.
minikube start \ --extra-config=apiserver.Admission.PluginNames="Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,GenericAdmissionWebhook,ResourceQuota" \ --kubernetes-version=v1.7.5
安装
您现在可以从 Istio 安装根目录设置 Istio Initializer。
kubectl apply -f install/kubernetes/istio-initializer.yaml
将会创建下列资源:
- 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。
kubectl apply -f samples/sleep/sleep.yaml
验证 sleep deployment 中包含 sidecar。injected-version 对应于注入的 sidecar 镜像的版本和镜像的 TAG。在您的设置的可能会有所不同。
$ echo $(kubectl get deployment sleep -o jsonpath='{.metadata.annotations.sidecar\.istio\.io\/status}')
injected-version-9c7c291eab0a522f8033decd0f5b031f5ed0e126
你可以查看包含注入的容器和挂载的 volume 的完整 deployment 信息。
kubectl get deployment sleep -o yaml
了解发生了什么
以下是将工作负载提交给 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 必须重新启动以采用新的配置更改。
apiVersion: v1 kind: ConfigMap metadata: name: istio-inject namespace: istio-system data: config: |- policy: "enabled" namespaces: [""] # everything, aka v1.NamepsaceAll, aka cluster-wide # excludeNamespaces: ["ns1", "ns2"] initializerName: "sidecar.initializer.istio.io" params: initImage: docker.io/istio/proxy_init:0.2.6 proxyImage: docker.io/istio/proxy:0.2.6 verbosity: 2 version: 0.2.6 meshConfigMapName: istio imagePullPolicy: IfNotPresent
下面是配置中的关键参数:
- 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。
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: myapp annotations: sidecar.istio.io/inject: "true" spec: replicas: 1 template: ...
这是在包含 Istio 和非 Istio 服务的混合群集中使用自动注入的好方法。
卸载 Initializer
运行下面的命令,删除 Istio initializer:
kubectl delete -f install/kubernetes/istio-initializer.yaml
注意上述命令并不会删除已注入到 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 克隆。
kubectl apply -f install/kubernetes/mesh-expansion.yaml
- 生成要部署到虚拟机上的 Istio cluster.env 配置。该文件中包含要拦截的 cluster IP 地址范围。
export GCP_OPTS="--zone MY_ZONE --project MY_PROJECT"
install/tools/setupMeshEx.sh generateClusterEnv MY_CLUSTER_NAME
该示例生成的文件:
cat cluster.env
ISTIO_SERVICE_CIDR=10.63.240.0/20
- 产生虚拟机使用的 DNS 配置文件。这样可以让虚拟机上的应用程序解析到集群中的服务名称,这些名称将被 sidecar 拦截和转发。
# Make sure your kubectl context is set to your cluster install/tools/setupMeshEx.sh generateDnsmasq
该示例生成的文件:
cat kubedns
server=/svc.cluster.local/10.150.0.7 address=/istio-mixer/10.150.0.8 address=/istio-pilot/10.150.0.6 address=/istio-ca/10.150.0.9 address=/istio-mixer.istio-system/10.150.0.8 address=/istio-pilot.istio-system/10.150.0.6 address=/istio-ca.istio-system/10.150.0.9
设置机器
例如,您可以使用下面的“一条龙”脚本复制和安装配置:
# 检查该脚本看看它是否满足您的需求 # 在 Mac 上,使用 brew install base64 或者 set BASE64_DECODE="/usr/bin/base64 -D" export GCP_OPTS="--zone MY_ZONE --project MY_PROJECT"
install/tools/setupMeshEx.sh machineSetup VM_NAME
或者等效得手动安装步骤如下:
—— 手动安装步骤开始 ——
- 将配置文件和 Istio 的 Debian 文件复制到要加入到集群的每台机器上。重命名为 /etc/dnsmasq.d/kubedns 和/var/lib/istio/envoy/cluster.env。
- 配置和验证 DNS 配置。需要安装 dnsmasq 或者直接将其添加到 /etc/resolv.conf 中,或者通过 DHCP 脚本。验证配置是否有效,检查虚拟机是否可以解析和连接到 pilot,例如:
在虚拟机或外部主机上:
host istio-pilot.istio-system
产生的消息示例:
# Verify you get the same address as shown as "EXTERNAL-IP" in 'kubectl get svc -n istio-system istio-pilot-ilb' istio-pilot.istio-system has address 10.150.0.6
检查是否可以解析 cluster IP。实际地址取决您的 deployment:
host istio-pilot.istio-system.svc.cluster.local.
该示例产生的消息:
istio-pilot.istio-system.svc.cluster.local has address 10.63.247.248
同样检查 istio-ingress:
host istio-ingress.istio-system.svc.cluster.local.
该示例产生的消息:
istio-ingress.istio-system.svc.cluster.local has address 10.63.243.30
- 验证连接性,检查迅即是否可以连接到 Pilot 的端点:
curl 'http://istio-pilot.istio-system:8080/v1/registration/istio-pilot.istio-system.svc.cluster.local|http-discovery'
{ "hosts": [ { "ip_address": "10.60.1.4", "port": 8080 } ] }
# 在虚拟机上使用上面的地址。将直接连接到运行 istio-pilot 的 pod。 curl 'http://10.60.1.4:8080/v1/registration/istio-pilot.istio-system.svc.cluster.local|http-discovery'
- 提取出实话 Istio 认证的 secret 并将它复制到机器上。Istio 的默认安装中包括 CA,即使是禁用了自动 mTLS 设置(她为每个 service account 创建 secret,secret 命名为 istio.<serviceaccount>)也会生成 Istio secret。建议您执行此步骤,以便日后启用 mTLS,并升级到默认启用 mTLS 的未来版本。
# ACCOUNT 默认是 'default',SERVICE_ACCOUNT 是环境变量 # NAMESPACE 默认为当前 namespace,SERVICE_NAMESPACE 是环境变量 # (这一步由 machineSetup 完成) # 在 Mac 上执行 brew install base64 或者 set BASE64_DECODE="/usr/bin/base64 -D" install/tools/setupMeshEx.sh machineCerts ACCOUNT NAMESPACE
生成的文件(key.pem, root-cert.pem, cert-chain.pem)必须拷贝到每台主机的 /etc/certs 目录,并且让 istio-proxy 可读。
- 安装 Istio Debian 文件,启动 istio 和 istio-auth-node-agent 服务。 从 github releases 获取 Debian 安装包:
# 注意:在软件源配置好后,下面的额命令可以使用 'apt-get' 命令替代。 source istio.VERSION # defines version and URLs env var curl -L ${PILOT_DEBIAN_URL}/istio-agent.deb > ${ISTIO_STAGING}/istio-agent.deb curl -L ${AUTH_DEBIAN_URL}/istio-auth-node-agent.deb > ${ISTIO_STAGING}/istio-auth-node-agent.deb curl -L ${PROXY_DEBIAN_URL}/istio-proxy.deb > ${ISTIO_STAGING}/istio-proxy.deb dpkg -i istio-proxy-envoy.deb dpkg -i istio-agent.deb dpkg -i istio-auth-node-agent.deb systemctl start istio systemctl start istio-auth-node-agent
—— 手动安装步骤结束 ——
安装完成后,机器就能访问运行在 Kubernetes 集群上的服务或者其他的 mesh 拓展的机器。
# 假设你已经在 bookinfo namespace 下安装了 'bookinfo' curl productpage.bookinfo.svc.cluster.local:9080
... html content ...
检查进程是否正在运行:
ps aux |grep istio
root 6941 0.0 0.2 75392 16820 ? Ssl 21:32 0:00 /usr/local/istio/bin/node_agent --logtostderr root 6955 0.0 0.0 49344 3048 ? Ss 21:32 0:00 su -s /bin/bash -c INSTANCE_IP=10.150.0.5 POD_NAME=demo-vm-1 POD_NAMESPACE=default exec /usr/local/bin/pilot-agent proxy > /var/log/istio/istio.log istio-proxy istio-p+ 7016 0.0 0.1 215172 12096 ? Ssl 21:32 0:00 /usr/local/bin/pilot-agent proxy istio-p+ 7094 4.0 0.3 69540 24800 ? Sl 21:32 0:37 /usr/local/bin/envoy -c /etc/istio/proxy/envoy-rev1.json --restart-epoch 1 --drain-time-s 2 --parent-shutdown-time-s 3 --service-cluster istio-proxy --service-node sidecar~10.150.0.5~demo-vm-1.default~default.svc.cluster.local
检查 Istio auth-node-agent 是否健康:
sudo systemctl status istio-auth-node-agent
● istio-auth-node-agent.service - istio-auth-node-agent: The Istio auth node agent Loaded: loaded (/lib/systemd/system/istio-auth-node-agent.service; disabled; vendor preset: enabled) Active: active (running) since Fri 2017-10-13 21:32:29 UTC; 9s ago Docs: http://istio.io/ Main PID: 6941 (node_agent) Tasks: 5 Memory: 5.9M CPU: 92ms CGroup: /system.slice/istio-auth-node-agent.service └─6941 /usr/local/istio/bin/node_agent --logtostderr Oct 13 21:32:29 demo-vm-1 systemd[1]: Started istio-auth-node-agent: The Istio auth node agent. Oct 13 21:32:29 demo-vm-1 node_agent[6941]: I1013 21:32:29.469314 6941 main.go:66] Starting Node Agent Oct 13 21:32:29 demo-vm-1 node_agent[6941]: I1013 21:32:29.469365 6941 nodeagent.go:96] Node Agent starts successfully. Oct 13 21:32:29 demo-vm-1 node_agent[6941]: I1013 21:32:29.483324 6941 nodeagent.go:112] Sending CSR (retrial #0) ... Oct 13 21:32:29 demo-vm-1 node_agent[6941]: I1013 21:32:29.862575 6941 nodeagent.go:128] CSR is approved successfully. Will renew cert in 29m59.137732603s
在拓展的 mesh 中的机器上运行服务
- 配置 sidecar 拦截端口。在 /var/lib/istio/envoy/sidecar.env 中通过 ISTIO_INBOUND_PORTS 环境变量配置。
例如(运行服务的虚拟机):
echo "ISTIO_INBOUND_PORTS=27017,3306,8080" > /var/lib/istio/envoy/sidecar.env systemctl restart istio
- 手动配置 selector-less 的 service 和 endpoint。“selector-less” service 用于那些不依托 Kubernetes pod 的 service。
例如,在有权限的机器上修改 Kubernetes 中的 service:
# istioctl register servicename machine-ip portname:port istioctl -n onprem register mysql 1.2.3.4 3306 istioctl -n onprem register svc1 1.2.3.4 http:7000
安装完成后,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 命令部署服务:
kubectl apply -f samples/bookinfo/kube/bookinfo.yaml
如果您使用 手动注入 sidecar 的方式部署的集群,清使用下面的命令:
kubectl apply -f <(istioctl kube-inject -f samples/apps/bookinfo/bookinfo.yaml)
请注意,该 istioctl kube-inject 命令用于在创建部署之前修改 bookinfo.yaml 文件。这将把 Envoy 注入到 Kubernetes 资源。
上述命令启动四个微服务并创建网关入口资源,如下图所示。3 个版本的评论的服务 v1、v2、v3 都已启动。
请注意在实际部署中,随着时间的推移部署新版本的微服务,而不是同时部署所有版本。
- 确认所有服务和 pod 已正确定义并运行:
kubectl get services
这将产生以下输出:
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE details 10.0.0.31 <none> 9080/TCP 6m istio-ingress 10.0.0.122 <pending> 80:31565/TCP 8m istio-pilot 10.0.0.189 <none> 8080/TCP 8m istio-mixer 10.0.0.132 <none> 9091/TCP,42422/TCP 8m kubernetes 10.0.0.1 <none> 443/TCP 14d productpage 10.0.0.120 <none> 9080/TCP 6m ratings 10.0.0.15 <none> 9080/TCP 6m reviews 10.0.0.170 <none> 9080/TCP 6m
而且
kubectl get pods
将产生:
NAME READY STATUS RESTARTS AGE details-v1-1520924117-48z17 2/2 Running 0 6m istio-ingress-3181829929-xrrk5 1/1 Running 0 8m istio-pilot-175173354-d6jm7 2/2 Running 0 8m istio-mixer-3883863574-jt09j 2/2 Running 0 8m productpage-v1-560495357-jk1lz 2/2 Running 0 6m ratings-v1-734492171-rnr5l 2/2 Running 0 6m reviews-v1-874083890-f0qf0 2/2 Running 0 6m reviews-v2-1343845940-b34q5 2/2 Running 0 6m reviews-v3-1813607990-8ch52 2/2 Running 0 6m
确定 ingress IP 和端口
- 如果您的 kubernetes 集群环境支持外部负载均衡器的话,可以使用下面的命令获取 ingress 的IP地址:
kubectl get ingress -o wide
输出如下所示:
NAME HOSTS ADDRESS PORTS AGE gateway * 130.211.10.121 80 1d
Ingress 服务的地址是:
export GATEWAY_URL=130.211.10.121:80
- GKE:如果服务无法获取外部 IP,kubectl get ingress -o wide 会显示工作节点的列表。在这种情况下,您可以使用任何地址以及 NodePort 访问入口。但是,如果集群具有防火墙,则还需要创建防火墙规则以允许TCP流量到NodePort,您可以使用以下命令创建防火墙规则:
export GATEWAY_URL=<workerNodeAddress>:$(kubectl get svc istio-ingress -n istio-system -o jsonpath='{.spec.ports[0].nodePort}') gcloud compute firewall-rules create allow-book --allow tcp:$(kubectl get svc istio-ingress -n istio-system -o jsonpath='{.spec.ports[0].nodePort}')
- IBM Bluemix Free Tier:在免费版的 Bluemix 的 kubernetes 集群中不支持外部负载均衡器。您可以使用工作节点的公共 IP,并通过 NodePort 来访问 ingress。工作节点的公共 IP可以通过如下命令获取:
bx cs workers <cluster-name or id> export GATEWAY_URL=<public IP of the worker node>:$(kubectl get svc istio-ingress -n istio-system -o jsonpath='{.spec.ports[0].nodePort}')
- Minikube:Minikube 不支持外部负载均衡器。您可以使用 ingress 服务的主机 IP 和 NodePort 来访问 ingress:
export GATEWAY_URL=$(kubectl get po -l istio=ingress -o 'jsonpath={.items[0].status.hostIP}'):$(kubectl get svc istio-ingress -o 'jsonpath={.spec.ports[0].nodePort}')
在 Consul 或 Eureka 环境下使用 Docker 运行
- 切换到 Istio 的安装根目录下。
- 启动应用程序容器。
- 执行下面的命令测试 Consul:
docker-compose -f samples/bookinfo/consul/bookinfo.yaml up -d
- 执行下面的命令测试 Eureka:
docker-compose -f samples/bookinfo/eureka/bookinfo.yaml up -d
- 确认所有容器都在运行:
docker ps -a
如果 Istio Pilot 容器终止了,重新执行上面的命令重新运行。
- 设置 GATEWAY_URL:
export GATEWAY_URL=localhost:9081
下一步
使用以下 curl 命令确认 BookInfo 应用程序正在运行:
curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/productpage
200
你也可以通过在浏览器中打开 http://$GATEWAY_URL/productpage 页面访问 Bookinfo 网页。如果您多次刷新浏览器将在 productpage 中看到评论的不同的版本,它们会按照 round robin(红星、黑星、没有星星)的方式展现,因为我们还没有使用 Istio 来控制版本的路由。
现在,您可以使用此示例来尝试 Istio 的流量路由、故障注入、速率限制等功能。要继续的话,请参阅 Istio 指南,具体取决于您的兴趣。智能路由 是初学者入门的好方式。
清理
在完成 BookInfo 示例后,您可以卸载它,如下所示:
卸载 Kubernetes 环境
- 删除路由规则,终止应用程序 pod
samples/bookinfo/kube/cleanup.sh
- 确认关闭
istioctl get routerules #-- there should be no more routing rules kubectl get pods #-- the BookInfo pods should be deleted
卸载 docker 环境
- 删除路由规则和应用程序容器
- 若使用 Consul 环境安装,执行下面的命令:
samples/bookinfo/consul/cleanup.sh
- 若使用 Eureka 环境安装,执行下面的命令:
samples/bookinfo/eureka/cleanup.sh
- 确认清理完成:
istioctl get routerules #-- there should be no more routing rules docker ps -a #-- the BookInfo containers should be deleted
集成虚拟机
该示例跨越 Kubernetes 集群和一组虚拟机上部署 Bookinfo 服务,描述如何使用 Istio service mesh 将此基础架构以单一 mesh 的方式操控。
注意:本文档还在建设中,并且只在 Google Cloud Platform 上进行过测试。 在 IBM Bluemix 或其它平台上,pod 的 overlay 网络跟虚拟机的网络是隔离的。 即使使用 Istio,虚拟机也不能直接与 Kubernetes Pod 进行通信。
概览
开始之前
- 按照 安装指南 上的步骤部署 Istio。
- 部署 BookInfo 示例应用程序(在 bookinfo namespace 下)。
- 在 Istio 集群相同的项目下创建名为 vm-1 的虚拟机,并 加入到 Mesh。
在虚拟机上运行 mysql
我们将首先在虚拟机上安装 mysql,将其配置成评分服务的后台存储。
在虚拟机上执行:
sudo apt-get update && sudo apt-get install -y mariadb-server sudo mysql # 授权 root 用户访问 GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION; quit; sudo systemctl restart mysql
关于 Mysql 的详细配置请见: Mysql。
在虚拟机上执行下面的命令,向 mysql 中添加评分数据库。
# 向 mysql 数据库中添加评分数据库 curl -q https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/src/mysql/mysqldb-init.sql | mysql -u root -ppassword
为了便于直观地查看bookinfo应用程序输出的差异,可以更改使用以下命令生成的评分:
# 查看评分 mysql -u root -ppassword test -e "select * from ratings;" +----------+--------+ | ReviewID | Rating | +----------+--------+ | 1 | 5 | | 2 | 4 | +----------+--------+ # 修改评分 mysql -u root -ppassword test -e "update ratings set rating=1 where reviewid=1;select * from ratings;" +----------+--------+ | ReviewID | Rating | +----------+--------+ | 1 | 1 | | 2 | 4 | +----------+--------+
找出将添加到 mesh 中的虚拟机的 IP 地址
在虚拟机上执行:
hostname -I
将 mysql 服务注册到 mesh 中
在一台可以访问 istioctl 命令的主机上,注册该虚拟机和 mysql db service:
istioctl register -n vm mysqldb <ip-address-of-vm> 3306 # 示例输出 $ istioctl register mysqldb 192.168.56.112 3306 I1015 22:24:33.846492 15465 register.go:44] Registering for service 'mysqldb' ip '192.168.56.112', ports list [{3306 mysql}] I1015 22:24:33.846550 15465 register.go:49] 0 labels ([]) and 1 annotations ([alpha.istio.io/kubernetes-serviceaccounts=default]) W1015 22:24:33.866410 15465 register.go:123] Got 'services "mysqldb" not found' looking up svc 'mysqldb' in namespace 'default', attempting to create it W1015 22:24:33.904162 15465 register.go:139] Got 'endpoints "mysqldb" not found' looking up endpoints for 'mysqldb' in namespace 'default', attempting to create them I1015 22:24:33.910707 15465 register.go:180] No pre existing exact matching ports list found, created new subset {[{192.168.56.112 <nil> nil}] [] [{mysql 3306 }]} I1015 22:24:33.921195 15465 register.go:191] Successfully updated mysqldb, now with 1 endpoints
集群管理
如果你之前在 kubernetes 上运行过 mysql,您需要将 kubernetes 的 mysql service 移除:
kubectl delete service mysql
执行 istioctl 来配置 service(在您的 admin 机器上):
istioctl register mysql IP mysql:PORT
注意:mysqldb 虚拟机不需要也不应该有特别的 kubernetes 权限。
使用 mysql 服务
bookinfo 中的评分服务将使用机器上的数据库。要验证它是否有效,请创建使用虚拟机上的 mysql db 的评分服务的 v2 版本。然后指定强制评论服务使用评分 v2 版本的路由规则。
# 创建使用 mysql 后端的评分服务版本 istioctl kube-inject -n bookinfo -f samples/bookinfo/kube/bookinfo-ratings-v2-mysql-vm.yaml | kubectl apply -n bookinfo -f - # 强制 bookinfo 使用评分后端的路有规则 istioctl create -n bookinfo -f samples/bookinfo/kube/route-rule-ratings-mysql-vm.yaml
您可以验证 bookinfo 应用程序的输出结果,显示来自 Reviewer1 的 1 星级和来自 Reviewer2 的 4 星级,或者更改虚拟机上的评分并查看结果。
同时,您还可以在 RawVM MySQL 的文档中找到一些故障排查和其它信息。
- 安卓客户端下载
- 微信扫一扫
- 微信公众号
- 微信公众号扫一扫