服务网格ASM为应用服务提供了跨地域流量分布和跨地域故障转移能力。跨地域流量分布功能可以将流量按照设定的权重路由至多个集群,实现多地域负载均衡。跨地域故障转移功能可以在某地域服务发生故障时,将该地域流量转移至其他地域,实现跨地域容灾。本文以Bookinfo应用为例,介绍如何使用跨地域故障转移和流量分布能力实现跨地域容灾和流量负载均衡。
网络规划
在进行操作前,您需要对vSwitch、VPC和集群的网段、名称等信息进行规划,本文规划如下:
关于数据平面多集群地址规划的详细介绍,请参见多集群网络规划。
vSwich和VPC的网络规划
vSwitch网络规划
重要为了避免使用CEN打通VPC网络后产生路由冲突,两个vSwitch不能使用相同的网段。
对象
vSwitch名称
VPC
IPv4网段
集群
vpc-hangzhou-switch-1
vpc-hangzhou
20.0.0.0/16
vpc-shanghai-switch-1
vpc-shanghai
21.0.0.0/16
服务网格
vpc-hangzhou-switch-2
vpc-hangzhou2
192.168.0.0/24
VPC网络规划
对象
VPC名称
Region
IPv4网段
集群
vpc-hangzhou
cn-hangzhou
20.0.0.0/8
vpc-shanghai
cn-shanghai
21.0.0.0/8
服务网格
vpc-hangzhou2
cn-hangzhou
192.168.0.0/16
集群的Pod和Service网络规划
集群名称
Region
VPC
Pod CIDR
Service CIDR
ack-hangzhou
cn-hangzhou
vpc-hangzhou
10.0.0.0/16
172.16.0.0/16
ack-shanghai
cn-shanghai
vpc-shanghai
10.1.0.0/16
172.17.0.0/16
步骤一:创建不同地域的集群
按照以上规划创建2个杭州和上海地域vSwitch,然后使用vSwitch创建VPC。具体操作,请参见创建交换机和创建专有网络和交换机。
使用上文创建的VPC和网络规划创建杭州和上海地域的集群。具体操作,请参见创建Kubernetes托管版集群。
根据以上规划创建1个杭州地域的ASM实例。具体操作,请参见创建ASM实例。
步骤二:使用CEN实现跨地域VPC网络互通
使用CEN,打通集群之间的VPC网络,以及集群和服务网格之间的VPC网络。
创建CEN实例。
说明本文使用旧版云企业网控制台创建CEN实例,您可以在云企业网控制台右上角单击回到旧版,使用旧版云企业网控制台。
登录云企业网控制台。
在云企业网实例页面,单击创建云企业网实例。
在创建云企业网实例面板设置参数,然后单击确定。
参数
描述
名称
输入实例名称。
名称长度为2~128个字符,以英文字母或中文开头,可包含数字、下划线(_)和短划线(-)。
描述
输入实例描述信息。
实例类型
实例类型,本文选择专有网络(VPC)。
地域
选择所选实例的地域,本文选择华东1(杭州)。
网络实例
选择要加载的实例,选择上文创建的杭州地域的VPC。
加载网络实例。
添加上海地域集群的VPC。
在企业网实例页面,找到上文创建的云企业网实例,单击实例ID。
在网络实例管理页签,单击加载网络实例。
在加载网络实例面板同账号页签下设置参数,然后单击确定。
参数
描述
实例类型
实例类型,本文选择专有网络(VPC)
地域
选择所选实例的地域,本文选择华东2(上海)。
网络实例
选择要加载的实例,选择上文创建的上海地域的VPC。
添加杭州地域服务网格的VPC。
在网络实例管理页签,单击加载网络实例。
在加载网络实例面板同账号页签下设置参数,然后单击确定。
参数
描述
实例类型
实例类型,本文选择专有网络(VPC)
地域
选择所选实例的地域,本文选择华东1(杭州)。
网络实例
选择要加载的实例,选择上文创建的杭州地域的服务网格VPC。
购买带宽包,具体操作,请参见购买带宽包。
设置跨地域互通带宽。
在企业网实例页面,找到上文创建的云企业网实例,单击实例ID。
单击跨地域互通带宽管理页签,然后单击设置跨地域带宽。
在设置跨地域带宽面板设置带宽包为上文购买的带宽包,互通地域为华东2(上海)到华东1(杭州),然后单击确定。
添加安全组规则。
在两个集群的安全组内添加对方集群的Pod网络CIDR,允许对方集群的Pod网段地址访问本机。
- 登录容器服务管理控制台。
在集群列表页面单击ack-shanghai集群右侧操作列下的详情。
在集群信息页面单击基本信息页签。
查看ack-shanghai集群的Pod网络CIDR,然后返回集群列表页面。
在集群列表页面单击ack-hangzhou集群右侧操作列下的详情。
在集群信息页面单击集群资源页签,然后单击安全组右侧的安全组ID。
在安全组详情页签入方向下单击手动添加。
设置协议类型为全部,源为ack-shanghai集群的Pod网络CIDR,其他为默认值,然后单击操作列下的保存。
重复执行以上步骤,查看ack-hangzhou集群的Pod网络CIDR,然后在ack-shanghai集群的安全组中,添加ack-hangzhou集群的Pod网络CIDR。
步骤三:将Pod路由信息发布至CEN
- 登录容器服务管理控制台。
在集群列表页面单击ack-hangzhou集群右侧操作列下的详情。
在集群信息页面单击集群资源页签,然后单击虚拟专有网络VPC右侧VPC ID。
在VPC的详情页面路由器基本信息区域查看路由器ID。
在专有网络控制台左侧导航栏单击路由表。
在路由表页面找到上文获取的路由器ID的路由实例名称,然后单击路由实例名称。
在路由条目列表页签下单击自定义。
单击Pod CIDR网段的子网段右侧的发布,本文为10.45.0.0/16的子网段。
在发布路由的对话框单击确定。
重复执行以上步骤,将ack-shanghai集群的Pod路由信息发布至CEN。
验证ack-hangzhou和ack-shanghai集群Pod路由信息是否都发布至CEN。
在杭州地域路由表详情页面路由条目列表页签下单击动态。可以看到ack-shanghai集群PodCIDR的路由信息和vpc-shanghai-switch-1的IPv4网段的路由信息。在上海地域路由表详情页面也可以看到ack-hangzhou集群PodCIDR的路由信息和vpc-hangzhou-switch-1的IPv4网段的路由信息。说明ack-hangzhou和ack-shanghai集群Pod路由信息都发布至CEN。
步骤四:添加集群到ASM实例
添加杭州地域和上海地域的集群到同一个ASM实例中。
登录ASM控制台。
在左侧导航栏,选择 。
在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
在网格详情页面左侧导航栏,选择 ,然后在右侧页面,单击添加。
在添加集群面板,选中杭州地域的集群,然后单击确定。
在重要提示对话框中单击确定。
重复执行以上步骤,将上海地域的集群添加到该ASM实例中。
步骤五:在ASM中配置入口网关
查看ack-shanghai集群的ID。
- 登录容器服务管理控制台。
在集群列表页面单击ack-shanghai集群右侧操作列下的详情。
在集群信息页面单击基本信息页签。
在基本信息区域查看集群ID。
登录ASM控制台。
在左侧导航栏,选择 。
在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
- 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 。
设置部署集群为ack-hangzhou集群,负载均衡类型为公网访问,选择负载均衡类型,其他采用默认设置。然后单击创建。
在入口网关页面单击ingressgateway右侧的查看YAML。
在编辑面板补充ack-shanghai集群的ID,然后单击确定。
spec: clusterIds: - ack-hangzhou cluster-id - ack-shanghai cluster-id
步骤六:部署演示应用BookInfo
使用kubectl连接到ack-hangzhou集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群。
使用以下内容,创建ack-hangzhou-k8s.yaml。
# Details service apiVersion: v1 kind: Service metadata: name: details labels: app: details service: details spec: ports: - port: 9080 name: http selector: app: details --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-details labels: account: details --- apiVersion: apps/v1 kind: Deployment metadata: name: details-v1 labels: app: details version: v1 spec: replicas: 1 selector: matchLabels: app: details version: v1 template: metadata: labels: app: details version: v1 spec: serviceAccountName: bookinfo-details containers: - name: details image: docker.io/istio/examples-bookinfo-details-v1:1.16.2 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 securityContext: runAsUser: 1000 --- # Ratings service apiVersion: v1 kind: Service metadata: name: ratings labels: app: ratings service: ratings spec: ports: - port: 9080 name: http selector: app: ratings --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-ratings labels: account: ratings --- apiVersion: apps/v1 kind: Deployment metadata: name: ratings-v1 labels: app: ratings version: v1 spec: replicas: 1 selector: matchLabels: app: ratings version: v1 template: metadata: labels: app: ratings version: v1 spec: serviceAccountName: bookinfo-ratings containers: - name: ratings image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 securityContext: runAsUser: 1000 --- # Reviews service apiVersion: v1 kind: Service metadata: name: reviews labels: app: reviews service: reviews spec: ports: - port: 9080 name: http selector: app: reviews --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-reviews labels: account: reviews --- apiVersion: apps/v1 kind: Deployment metadata: name: reviews-v1 labels: app: reviews version: v1 spec: replicas: 1 selector: matchLabels: app: reviews version: v1 template: metadata: labels: app: reviews version: v1 spec: serviceAccountName: bookinfo-reviews containers: - name: reviews image: docker.io/istio/examples-bookinfo-reviews-v1:1.16.2 imagePullPolicy: IfNotPresent env: - name: LOG_DIR value: "/tmp/logs" ports: - containerPort: 9080 volumeMounts: - name: tmp mountPath: /tmp - name: wlp-output mountPath: /opt/ibm/wlp/output securityContext: runAsUser: 1000 volumes: - name: wlp-output emptyDir: {} - name: tmp emptyDir: {} --- # Productpage services apiVersion: v1 kind: Service metadata: name: productpage labels: app: productpage service: productpage spec: ports: - port: 9080 name: http selector: app: productpage --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-productpage labels: account: productpage --- apiVersion: apps/v1 kind: Deployment metadata: name: productpage-v1 labels: app: productpage version: v1 spec: replicas: 1 selector: matchLabels: app: productpage version: v1 template: metadata: labels: app: productpage version: v1 spec: serviceAccountName: bookinfo-productpage containers: - name: productpage image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 volumeMounts: - name: tmp mountPath: /tmp securityContext: runAsUser: 1000 volumes: - name: tmp emptyDir: {} ---
执行以下命令,在ack-hangzhou集群部署BookInfo应用。
kubectl apply -f ack-hangzhou-k8s.yaml
使用kubectl连接到ack-shanghai集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群。
说明使用kubectl连接到ack-shanghai集群时,您需要将ack-hangzhou集群的kubeconfig切换成ack-shanghai集群的kubeconfig。
使用以下内容,创建ack-shanghai.yaml。
# Details service apiVersion: v1 kind: Service metadata: name: details labels: app: details service: details spec: ports: - port: 9080 name: http selector: app: details --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-details labels: account: details --- apiVersion: apps/v1 kind: Deployment metadata: name: details-v1 labels: app: details version: v1 spec: replicas: 1 selector: matchLabels: app: details version: v1 template: metadata: labels: app: details version: v1 spec: serviceAccountName: bookinfo-details containers: - name: details image: docker.io/istio/examples-bookinfo-details-v1:1.16.2 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 securityContext: runAsUser: 1000 --- # Ratings service apiVersion: v1 kind: Service metadata: name: ratings labels: app: ratings service: ratings spec: ports: - port: 9080 name: http selector: app: ratings --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-ratings labels: account: ratings --- apiVersion: apps/v1 kind: Deployment metadata: name: ratings-v1 labels: app: ratings version: v1 spec: replicas: 1 selector: matchLabels: app: ratings version: v1 template: metadata: labels: app: ratings version: v1 spec: serviceAccountName: bookinfo-ratings containers: - name: ratings image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 securityContext: runAsUser: 1000 --- # Reviews service apiVersion: v1 kind: Service metadata: name: reviews labels: app: reviews service: reviews spec: ports: - port: 9080 name: http selector: app: reviews --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-reviews labels: account: reviews --- apiVersion: apps/v1 kind: Deployment metadata: name: reviews-v2 labels: app: reviews version: v2 spec: replicas: 1 selector: matchLabels: app: reviews version: v2 template: metadata: labels: app: reviews version: v2 spec: serviceAccountName: bookinfo-reviews containers: - name: reviews image: docker.io/istio/examples-bookinfo-reviews-v2:1.16.2 imagePullPolicy: IfNotPresent env: - name: LOG_DIR value: "/tmp/logs" ports: - containerPort: 9080 volumeMounts: - name: tmp mountPath: /tmp - name: wlp-output mountPath: /opt/ibm/wlp/output securityContext: runAsUser: 1000 volumes: - name: wlp-output emptyDir: {} - name: tmp emptyDir: {} --- # Productpage services apiVersion: v1 kind: Service metadata: name: productpage labels: app: productpage service: productpage spec: ports: - port: 9080 name: http selector: app: productpage --- apiVersion: v1 kind: ServiceAccount metadata: name: bookinfo-productpage labels: account: productpage --- apiVersion: apps/v1 kind: Deployment metadata: name: productpage-v1 labels: app: productpage version: v1 spec: replicas: 1 selector: matchLabels: app: productpage version: v1 template: metadata: labels: app: productpage version: v1 spec: serviceAccountName: bookinfo-productpage containers: - name: productpage image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 volumeMounts: - name: tmp mountPath: /tmp securityContext: runAsUser: 1000 volumes: - name: tmp emptyDir: {} ---
执行以下命令,在ack-shanghai集群部署BookInfo应用。
kubectl apply -f ack-shanghai.yaml
使用kubectl连接到ASM。具体操作,请参见通过控制面kubectl访问Istio资源。
说明使用kubectl连接到ASM时,您需要将ack-shanghai集群的kubeconfig切换成ASM的kubeconfig。
使用以下内容,创建asm.yaml。
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: bookinfo-gateway spec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: bookinfo spec: hosts: - "*" gateways: - bookinfo-gateway http: - match: - uri: exact: /productpage - uri: prefix: /static - uri: exact: /login - uri: exact: /logout - uri: prefix: /api/v1/products route: - destination: host: productpage port: number: 9080 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: productpage spec: host: productpage subsets: - name: v1 labels: version: v1 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: reviews spec: host: reviews subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 - name: v3 labels: version: v3 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: ratings spec: host: ratings subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 - name: v2-mysql labels: version: v2-mysql - name: v2-mysql-vm labels: version: v2-mysql-vm --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: details spec: host: details subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 ---
执行以下命令,在ASM创建路由规则。
kubectl apply -f asm.yaml
验证Bookinfo应用是否部署成功。
- 登录容器服务管理控制台。
- 在控制台左侧导航栏,单击集群。
在集群列表页面单击ack-hangzhou集群右侧操作列下的详情。
- 在集群管理页左侧导航栏,选择 。
在服务页面顶部设置命名空间为Istio-system,查看istio-ingressgateway右侧外部端点下端口为80的IP地址。
在浏览器地址栏中输入入口网关IP地址/productpage。
多次刷新页面,可以看到以下图片轮流出现。
步骤七:使用跨地域流量分布和跨地域故障转移
设置跨地域流量分布
登录ASM控制台。
在左侧导航栏,选择 。
在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
在网格详情页面左侧导航栏,选择 ,然后在右侧页面,单击功能设置。
在基本信息页面单击跨地域负载均衡右侧的启用跨地域流量分布。
说明如果您已经启用跨地域故障转移,您需要禁用跨地域故障转移后,才能启用跨地域流量分布。
在跨地域流量分布对话框设置策略为cn-hangzhou,然后单击新建策略。
单击
图标,然后单击
图标,设置目标为cn-hangzhou,权重为90%。
单击
图标,设置目标为cn-shanghai,权重为10%,单击确认。
执行以下命令,循环请求10次BookInfo应用,验证跨地域流量分布是否成功。
for ((i=1;i<=10;i++));do curl http://<ack-hangzhou集群中80端口的入口网关地址>/productpage 2>&1|grep full.stars;done
预期输出:
<!-- full stars: --> <!-- full stars: -->
可以看到访问10次,输出2行
full stars
,说明10次请求中9次路由到了ack-hangzhou集群的v1版本reviews服务,1次路由到了ack-shanghai集群的v2版本reviews服务,流量按照权重路由到多个集群成功。
设置跨地域故障转移
停用ack-hangzhou集群的review。
- 登录容器服务管理控制台。
- 在控制台左侧导航栏,单击集群。
- 在集群管理页左侧导航栏,选择 。
在无状态页面设置命名空间为default,单击reviews-v1右侧操作列下的伸缩。
在伸缩页面设置所需容器组数量为0,然后单击确定。
配置DestinationRule。
配置DestinationRule,当1s内无法请求到reviews服务,该reviews服务将被移除1min。
登录ASM控制台。
在左侧导航栏,选择 。
在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
在网格详情页面左侧导航栏,选择 。
在目标规则页面单击reviews右侧操作列下的YAML。
在编辑面板增加以下内容,然后单击确定。
spec: ...... trafficPolicy: connectionPool: http: maxRequestsPerConnection: 1 outlierDetection: baseEjectionTime: 1m consecutive5xxErrors: 1 interval: 1s
maxRequestsPerConnection:最大连接数量。
baseEjectionTime:最小的移除时间长度。
consecutive5xxErrors:连续错误数量。
interval:移除检测的时间间隔。
启用跨地域故障转移。
在网格详情页面左侧导航栏,选择 。
在基本信息页面单击跨地域负载均衡右侧的启用跨地域故障转移。
说明如果您已经启用跨地域流量分布,您需要禁用跨地域流量分布后,才能启用跨地域故障转移。
在跨地域故障转移对话框中设置当策略源是cn-shanghai,源故障转移至cn-hangzhou,当策略源是cn-hangzhou,源故障转移至cn-shanghai,然后单击确认。
执行以下命令,循环请求10次BookInfo应用,并对路由到v2版本reviews服务的结果数量进行统计。
for ((i=1;i<=10;i++));do curl http://<ack-hangzhou集群中80端口的入口网关地址>/productpage 2>&1|grep full.stars;done|wc -l
预期输出:
20
可以看到访问10次,返回20(每次路由到v2版本reviews服务会返回两行包含
full stars
的结果),说明10次请求全部路由到了ack-shanghai集群的v2版本reviews服务,跨地域故障转移成功。
FAQ
为什么通过云企业网CEN打通了集群VPC网络,在ASM中加入K8s集群仍然提示失败?
当您的集群处于不同地域,在打通集群VPC网络时,您若未购买跨地域流量包,或者正确设置跨地域流量,ASM控制平面将无法连接到数据平面集群,导致ASM添加集群失败。
针对以上这个问题,您需要重新在云企业网CEN中设置跨地域流量打通集群VPC网络,具体操作,请参见步骤二:使用CEN实现跨地域VPC网络互通。