假如你正在一家典型的企业里工作,需要与多个团队一起工作,并为客户提供一个独立的软件,组成一个应用程序。你的团队遵循微服务架构,并拥有由多个Kubernetes集群组成的广泛基础设施。

由于微服务分布在多个集群中,你需要设计一个解决方案来集中管理所有微服务。幸运的是,你正在使用Istio,提供这个解决方案只不过是另一个配置的变化。

像Istio这样的服务网格技术可以帮助你安全地发现和连接分布在多个集群和环境中的微服务。今天我们来讨论一下使用Istio管理托管在多个Kubernetes集群中的微服务。

架构说明

Istio使用以下组件提供跨集群服务发现:

  • Istio CoreDNS:每个Istio控制平面都有一个CoreDNS。Istio使用它来发现全局范围上定义的服务。例如,如果一个托管在集群1上的微服务需要连接到另一个托管在集群2上的微服务,你需要为运行在集群2上的微服务在Istio CoreDNS上做一个全局条目。

  • Root CA:由于Istio需要在不同集群上运行的服务之间建立mTLS连接,因此需要使用共享的Root CA为两个集群生成中间CA证书。这就在不同集群上运行的微服务之间建立了信任,因为中间CA共享同一个Root CA。

  • Istio Ingress网关:集群间的通信通过Ingress网关进行,服务之间没有直接连接。因此,你要确保Ingress网关是可发现的,并且所有集群都可以连接到它。

服务发现

Istio使用以下步骤来促进服务发现:

  1. 集群上都有相同的控制平面,以促进高可用性。

  2. Kube DNS与Istio CoreDNS为支点,以提供全局服务发现。

  3. 用户通过Istio CoreDNS中的ServiceEntries定义远程服务的路由,格式为name.namespace.global。

  4. 源sidecar使用全局CoreDNS条目将流量路由到目标Istio Ingress网关。

  5. 目标 Istio Ingress 网关将流量路由到正确的微服务 pod。

前期准备

本文假设你已经对Kubernetes以及Istio的工作原理有一个基本的了解。如果你想了解Istio 1.5和1.6的详细内容,点击此处即可查看相关视频。为了能够跟上我们接下来的演示,请确保:

  • 你有至少两个Kubernetes集群,Kubernetes的版本为1.14、1.15或1.16

  • 你拥有在集群内安装和配置Istio的权限

  • 你在两个Kubernetes集群上都有集群管理权限。

  • Ingress网关可通过网络负载均衡器或类似配置连接到其他集群。扁平网络是不必要的。

安装Istio

在两个集群上,使用以下命令安装Istio 1.6.1:

curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.6.1 sh -
cd istio-1.6.1
export PATH=$PWD/bin:$PATH

由于我们需要用共享的根证书生成的中间证书来启动我们的Istio服务网格,所以使用中间证书创建一个secret。

在这个例子中,我们使用提供的样本证书。但是,我不建议你在生产中使用这些证书,因为它们一般都是可轻松获取的,而且是众所周知的。最好是使用你的组织的Root CA来生成中间CA证书。

在两个集群上运行以下命令来使用样本证书。如果你使用的是你的证书,请替换适用的文件路径。

kubectl create namespace 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-chain.pem
secret/cacerts created

由于我们需要安装Istio进行多集群设置,所以在两个集群上使用提供的Istio多集群网关manifest文件。

$ istioctl manifest apply -f install/kubernetes/operator/examples/multicluster/values-istio-multicluster-gateways.yaml
- Applying manifest for component Base...
Finished applying manifest for component Base.
- Applying manifest for component Pilot...
Finished applying manifest for component Pilot.
Waiting for resources to become ready...
- Applying manifest for component AddonComponents...
- Applying manifest for component IngressGateways...
- Applying manifest for component EgressGateways...
Finished applying manifest for component EgressGateways.
Finished applying manifest for component IngressGateways.
Finished applying manifest for component AddonComponents.
Installation complete

配置KubeDNS

下一步是将DNS解析从Kube DNS联邦到Istio CoreDNS。让我们通过为kube-dns定义一个ConfigMap来配置一个存根域。在两个集群上应用以下manifest:

$ kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-dns
namespace: kube-system
data:
stubDomains: |
{"global": ["$(kubectl get svc -n istio-system istiocoredns -o jsonpath={.spec.clusterIP})"]}
EOF configmap/kube-dns configured

设置上下文(context)

由于我们需要为不同得活动连接两个集群,因此获取上下文并将其存储在环境变量中会很有意义。有了这些,我们只要在kubectl命令中加入上下文,就可以在我们选择得集群中运行kubectl命令。

获取上下文:

$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
cluster-1 cluster-1 cluster-1
* cluster-2 cluster-2 cluster-2

设置环境变量以使用上下文:

$ export CTX_CLUSTER1=$(kubectl config view -o jsonpath='{.contexts[0].name}')
$ export CTX_CLUSTER2=$(kubectl config view -o jsonpath='{.contexts[1].name}')
$ echo CTX_CLUSTER1 = ${CTX_CLUSTER1}, CTX_CLUSTER2 = ${CTX_CLUSTER2}
CTX_CLUSTER1 = cluster-1, CTX_CLUSTER2 = cluster-2

部署示例微服务

我们先在集群1的foo命名空间上部署sleep微服务。

$ kubectl create --context=$CTX_CLUSTER1 namespace foo
namespace/foo created
$ kubectl label --context=$CTX_CLUSTER1 namespace foo istio-injection=enabled
namespace/foo labeled
$ kubectl apply --context=$CTX_CLUSTER1 -n foo -f samples/sleep/sleep.yaml
serviceaccount/sleep created
service/sleep created
deployment.apps/sleep created
$ export SLEEP_POD=$(kubectl get --context=$CTX_CLUSTER1 -n foo pod -l app=sleep -o jsonpath={.items..metadata.name})

现在我们在集群2的bar命名空间上部署httpbin微服务:

$ kubectl create --context=$CTX_CLUSTER2 namespace bar
namespace/bar created
$ kubectl label --context=$CTX_CLUSTER2 namespace bar istio-injection=enabled
namespace/bar labeled
$ kubectl apply --context=$CTX_CLUSTER2 -n bar -f samples/httpbin/httpbin.yaml
serviceaccount/httpbin created
service/httpbin created
deployment.apps/httpbin created

创建服务条目

现在我们需要在Istio CoreDNS上创建一个服务条目以便于我们可以从集群1中发现集群2上的服务。由于所有的通信都会通过Ingress 网关,导出集群2 Ingress网关地址。

export CLUSTER2_GW_ADDR=$(kubectl get --context=$CTX_CLUSTER2 svc --selector=app=istio-ingressgateway \
-n istio-system -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')

为了让集群1上的服务能够发现集群2上的httpbin,我们需要在集群1上为httpbin.bar.global创建一个ServiceEntry。这样可以保证集群1上的Istio Core DNS在集群1上的服务到达httpbin.bar.global这个端点时,可以到达集群2的Ingress网关。下面的yaml:

  • 在hosts部分定义服务域名

  • 位置是mesh_INTERNAL,因为我们需要把其他服务当作同一个服务网格的一部分

  • 将服务暴露在8000端口上

  • 我们需要给该服务提供一个独特的IP地址。该IP地址不需要可路由,并且你可以使用240.0.0.0/16范围内的任意地址

  • 我们在端点地址部分上定义集群2 ingress网关地址,以便于请求可以路由给它。端口15443是Ingress网关的SNI识别的Envoy代理端口,用于在目标群集服务的Pod之间路由流量。

应用yaml文件:

$ kubectl apply --context=$CTX_CLUSTER1 -n foo -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin-bar
spec:
hosts:
- httpbin.bar.global
location: MESH_INTERNAL
ports:
- name: http1
number: 8000
protocol: http
resolution: DNS
addresses:
- 240.0.0.2
endpoints:
- address: ${CLUSTER2_GW_ADDR}
ports:
http1: 15443 # Do not change this port value
EOF serviceentry.networking.istio.io/httpbin-bar created

测试服务

现在让我们从sleep微服务中产生一些流量,看看它是否能到达集群2上运行的httpbin微服务。

$ kubectl exec --context=$CTX_CLUSTER1 $SLEEP_POD -n foo -c sleep -- curl -I httpbin.bar.global:8000/headers
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0HTTP/1.1 200 OK
0 519 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
server: envoy
date: Sat, 16 May 2020 23:03:22 GMT
content-type: application/json
content-length: 519
access-control-allow-origin: *
access-control-allow-credentials: true
x-envoy-upstream-service-time: 37

我们得到一个成功的响应!恭喜你,我们已经成功地使用Istio在多个Kubernetes集群之间配置了服务发现。

结 论

感谢你的阅读,希望你能喜欢这篇文章。

这是一个在多个集群上运行的高可用Istio服务网格配置的演示。你也可以有一个共享的控制平面配置,但这并不推荐用于生产——如果你因为中断而失去一个集群,你也会失去对正在运行的集群的控制。

如何使用Istio 1.6管理多集群中的微服务?的更多相关文章

  1. Blazor+Dapr+K8s微服务之基于WSL安装K8s集群并部署微服务

         前面文章已经演示过,将我们的示例微服务程序DaprTest1部署到k8s上并运行.当时用的k8s是Docker for desktop 自带的k8s,只要在Docker for deskto ...

  2. Java高可用集群架构与微服务架构简单分析

    序 可能大部分读者都在想,为什么在这以 dubbo.spring cloud 为代表的微服务时代,我要还要整理这种已经"过时"高可用集群架构? 本人工作上大部分团队都是7-15人编 ...

  3. CentOS7 使用chrony搭建集群中的时间同步服务

    一.集群环境: 系统:CentOS7-minimal 集群中的两台主机ip:10.132.226.103/24  10.132.226.104/24 二.CentOS7中时间相关命令timedatec ...

  4. shipyard 管理swarm集群(附etcd发现服务方法)

    docker swarm集群 第一步:安装swarm集群 192.168.132.131----->(manger1,node) 192.168.132.132----->(manger2 ...

  5. 8分钟学会Consul集群搭建及微服务概念

    Consul介绍: Consul 是由 HashiCorp 公司推出的开源软件,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与 ...

  6. 在Kubernetes集群里安装微服务DevOps平台fabric8

    转载于https://blog.csdn.net/wzp1986/article/details/72128063?utm_source=itdadao&utm_medium=referral ...

  7. 使用Cloudrea Manager在CDH集群中添加kafka服务节点,更改borker.id配置后无法启动

    需要保证meta.properties文件中的broker.id和cloudrea manager的web页面上kafka配置的broker.id一致,最好让server.properties中的br ...

  8. 在 Minecraft 中管理 Kubernetes 集群

    原文链接:在 Minecraft 中管理 Kubernetes 集群 微软 2015 年收购 Minecraft 之后不久开源了一个项目叫 Dockercraft,这个项目当时看起来非常有趣,通过 D ...

  9. 实操教程丨如何在K8S集群中部署Traefik Ingress Controller

    注:本文使用的Traefik为1.x的版本 在生产环境中,我们常常需要控制来自互联网的外部进入集群中,而这恰巧是Ingress的职责. Ingress的主要目的是将HTTP和HTTPS从集群外部暴露给 ...

随机推荐

  1. 【部分】ASP.NET MVC的Controller接收输入详解

    原文:https://blog.csdn.net/lxrj2008/article/details/79455360 ASP.NET mvc的Controller要正确的响应用户发出的请求就要获取到用 ...

  2. pandas | 使用pandas进行数据处理——Series篇

    本文始发于个人公众号:TechFlow,原创不易,求个关注 上周我们关于Python中科学计算库Numpy的介绍就结束了,今天我们开始介绍一个新的常用的计算工具库,它就是大名鼎鼎的Pandas. Pa ...

  3. js统计字符

    问题:    var str1 = "abcdabcabcaabeeeeeee";     var str2 = "fhjdiovjdasklgudsaklfgdaskl ...

  4. .gitkeep文件

    git 默认不会对空文件夹进行追踪: 但某些项目某些文件夹对整体框架是必不可少的,就算是空也得有: 怎么办呢?在这个文件夹下添加一个[.gitkeep]文件,这样就可以同步该文件夹了. (完)

  5. Sharepoint 2013设置customErrors

    原文地址:http://www.cnblogs.com/renzh/archive/2013/03/05/2944309.html#3407239 一.首先设置IIS中的Web.config文件 找到 ...

  6. Oracle Solaris 10下gdb安装(附安装包)

    文章目录 1. 背景说明 2. gdb相关包 3. gdb安装 3.1 上传资源 3.2 解压 3.3 安装 3.4 环境变量 4. 位数确认 5. 验证可用性 1. 背景说明 本文承接Oracle ...

  7. node-koa

    什么是koa 基于node.js 平台的下一代web开发框架 async await npm install --save koa npm install --save koa-router ctx. ...

  8. 在执行 pip install 时遇到错误:python setup.py egg_info ...

    最近重新安装win10 64位专业版, 正好遇到python3.8发布,试了一下.结果jupyter都安装不了...心碎. ERROR: Command errored out with exit s ...

  9. 每日一题 - 剑指 Offer 31. 栈的压入、弹出序列

    题目信息 时间: 2019-06-25 题目链接:Leetcode tag:栈 难易程度:中等 题目描述: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入 ...

  10. 写给.NET开发者的Python教程(一):C# vs Python: 语言特性、Conda和Jupyter Notebook环境

    承接上篇,本文会从语言特性.开发环境和必备工具来带领大家进入Python的世界. 语言特性 首先一起看下C#和Python在语言特性层面的对比,他们作为截然不同的两类面向对象高级语言,在语言层面上有何 ...