在共享控制平面部署模型下,多个Kubernetes远程集群连接到在主集群中运行的共享Istio控制平面。远程群集可以与主群集位于同一网络中,也可以位于不同网络中。连接一个或多个远程集群后,主集群的控制平面将管理所有服务端点上的服务网格。
Istio网格跨越多个Kubernetes集群,可通过VPN直接访问远程Pod
先决条件
- 两个或更多运行受支持的Kubernetes版本(1.16、1.17、1.18)的集群。
- 所有Kubernetes控制平面API服务器必须可相互路由。
- 同一网络上的群集必须是RFC1918网络,VPN或满足以下要求的替代的更高级的网络技术:
- 各个集群Pod CIDR范围和服务CIDR范围在整个网络中必须是唯一的,并且不能重叠。
- 同一网络中的所有Pod CIDR必须彼此可路由。
- 不同网络上的集群必须具有
istio-ingressgateway
服务,该服务可从其他每个集群访问,最好使用L4网络负载平衡器(NLB)。并非所有的云提供商都支持NLB,并且某些云提供商需要使用特殊的注释才能使用它们。
准备
CA
从组织的根CA为每个集群的CA生成中间CA证书。共享的根CA允许跨不同集群的相互TLS通信。为便于说明,以下说明将Istio示例目录中的证书用于两个集群。
在网格中的每个集群上运行以下命令以安装证书。有关配置外部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
samples中的根证书和中间证书已广泛分发并广为人知。不要在生产中使用这些证书,因为这样集群将容易受到安全漏洞和危害。
跨集群控制平面访问
确定如何向远程集群公开主集群的Istiod发现服务。选择以下两个选项之一:
- Option (1) - 使用与数据流量共享的
istio-ingressgateway
网关。. - Option (2) - 在Istiod服务上使用云提供商的内部负载平衡器。有关在群集之间使用内部负载均衡器时可能适用的其他要求和限制,请参阅Kubernetes内部负载均衡器文档和您的云提供商的文档。
集群和网络命名
确定网格中集群和网络的名称。这些名称将在mesh网络配置中以及配置mesh网络的服务注册表时使用。为每个集群分配一个唯一的名称。该名称必须是DNS标签名称。在下面的示例中,主集群称为main0
,而远程群集为remote0
。
$ export MAIN_CLUSTER_NAME=main0
$ export REMOTE_CLUSTER_NAME=remote0
如果集群位于不同的网络上,请为每个网络分配一个唯一的网络名称。
$ export MAIN_CLUSTER_NETWORK=network1
$ export REMOTE_CLUSTER_NETWORK=network2
如果集群在同一网络上,则这些集群使用相同的网络名称。
$ export MAIN_CLUSTER_NETWORK=network1
$ export REMOTE_CLUSTER_NETWORK=network1
部署
主集群
创建主集群的配置。选择跨集群控制平面访问的两个选项之一。
如果是选择istio-ingressgateway
, 则:
cat <<EOF> istio-main-cluster.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
multiCluster:
clusterName: ${MAIN_CLUSTER_NAME}
network: ${MAIN_CLUSTER_NETWORK}
# Mesh network configuration. This is optional and may be omitted if
# all clusters are on the same network.
meshNetworks:
${MAIN_CLUSTER_NETWORK}:
endpoints:
- fromRegistry: ${MAIN_CLUSTER_NAME}
gateways:
- registry_service_name: istio-ingressgateway.istio-system.svc.cluster.local
port: 443
${REMOTE_CLUSTER_NETWORK}:
endpoints:
- fromRegistry: ${REMOTE_CLUSTER_NAME}
gateways:
- registry_service_name: istio-ingressgateway.istio-system.svc.cluster.local
port: 443
# Use the existing istio-ingressgateway.
meshExpansion:
enabled: true
EOF
如果是选择内部负载均衡器,则:
cat <<EOF> istio-main-cluster.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
multiCluster:
clusterName: ${MAIN_CLUSTER_NAME}
network: ${MAIN_CLUSTER_NETWORK}
# Mesh network configuration. This is optional and may be omitted if
# all clusters are on the same network.
meshNetworks:
${MAIN_CLUSTER_NETWORK}:
endpoints:
- fromRegistry: ${MAIN_CLUSTER_NAME}
gateways:
- registry_service_name: istio-ingressgateway.istio-system.svc.cluster.local
port: 443
${REMOTE_CLUSTER_NETWORK}:
endpoints:
- fromRegistry: ${REMOTE_CLUSTER_NAME}
gateways:
- registry_service_name: istio-ingressgateway.istio-system.svc.cluster.local
port: 443
# Change the Istio service `type=LoadBalancer` and add the cloud provider specific annotations. See
# https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer for more
# information. The example below shows the configuration for GCP/GKE.
# If the GCP/GKE version is less than 1.16, add `network.gke.io/internal-load-balancer-allow-global-access: "true"` to the `service_annotations`.
# See https://stackoverflow.com/questions/59680679/gcp-internal-load-balancer-global-access-beta-annotation-does-not-work?answertab=active#tab-top.
components:
pilot:
k8s:
service:
type: LoadBalancer
service_annotations:
cloud.google.com/load-balancer-type: Internal
EOF
应用主集群的配置。
istioctl install -f istio-main-cluster.yaml --context=${MAIN_CLUSTER_CTX}
等待控制平面准备就绪,然后再继续。
kubectl get pod -n istio-system --context=${MAIN_CLUSTER_CTX}
NAME READY STATUS RESTARTS AGE
istio-ingressgateway-7c8dd65766-lv9ck 1/1 Running 0 136m
istiod-f756bbfc4-thkmk 1/1 Running 0 136m
根据之前选择的远程控制平面配置选项设置ISTIOD_REMOTE_EP
环境变量。
如果选择的是istio-ingressgateway
,则:
$ export ISTIOD_REMOTE_EP=$(kubectl get svc -n istio-system --context=${MAIN_CLUSTER_CTX} istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ echo "ISTIOD_REMOTE_EP is ${ISTIOD_REMOTE_EP}"
如果选择的是内部负载均衡器,则:
$ export ISTIOD_REMOTE_EP=$(kubectl get svc -n istio-system --context=${MAIN_CLUSTER_CTX} istiod -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ echo "ISTIOD_REMOTE_EP is ${ISTIOD_REMOTE_EP}"
远程集群
创建远程集群的配置。
cat <<EOF> istio-remote0-cluster.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
# The remote cluster's name and network name must match the values specified in the
# mesh network configuration of the primary cluster.
multiCluster:
clusterName: ${REMOTE_CLUSTER_NAME}
network: ${REMOTE_CLUSTER_NETWORK}
# Replace ISTIOD_REMOTE_EP with the the value of ISTIOD_REMOTE_EP set earlier.
remotePilotAddress: ${ISTIOD_REMOTE_EP}
## The istio-ingressgateway is not required in the remote cluster if both clusters are on
## the same network. To disable the istio-ingressgateway component, uncomment the lines below.
#
# components:
# ingressGateways:
# - name: istio-ingressgateway
# enabled: false
EOF
应用远程集群配置。
$ istioctl install -f istio-remote0-cluster.yaml --context ${REMOTE_CLUSTER_CTX}
等待远程集群准备就绪。
$ kubectl get pod -n istio-system --context=${REMOTE_CLUSTER_CTX}
NAME READY STATUS RESTARTS AGE
istio-ingressgateway-55f784779d-s5hwl 1/1 Running 0 91m
istiod-7b4bfd7b4f-fwmks 1/1 Running 0 91m
在远程集群中运行的istiod部署为远程集群的pod提供自动sidecar注入和CA服务。这些服务以前由Sidecar注入器和Citadel部署提供,而Istiod中不包含这服务。远程集群的Pod正在从主集群的Istiod获取配置以进行服务发现。
跨集群负载均衡
配置 ingress gateway
如果两个集群都在同一网络上,请跳过此步骤并继续配置服务注册表。
跨网络流量通过每个目标集群的ingress gateway安全地路由。当网格中的集群位于不同的网络上时,您需要在入口网关上配置端口443,以将传入流量传递到请求的SNI标头中指定的目标服务,以获取本地顶级域(即Kubernetes)的SNI值。 DNS域)。相互TLS连接将从源到目的地一直使用。
将以下配置应用于每个集群。
cat <<EOF> cluster-aware-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: cluster-aware-gateway
namespace: istio-system
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: tls
protocol: TLS
tls:
mode: AUTO_PASSTHROUGH
hosts:
- "*.local"
EOF
$ kubectl apply -f cluster-aware-gateway.yaml --context=${MAIN_CLUSTER_CTX}
$ kubectl apply -f cluster-aware-gateway.yaml --context=${REMOTE_CLUSTER_CTX}
配置跨集群服务注册
为了实现跨集群的负载平衡,Istio控制平面要求访问网格中的所有集群以发现服务,端点和Pod属性。要配置访问权限,请为每个具有凭据的远程集群创建一个秘钥,以访问远程集群的kube-apiserver
并将其安装在主集群中。此秘钥使用远程集群中istio-reader-service-account
的凭据。 --name
指定远程集群的名称。它必须与主集群的IstioOperator配置中的集群名称匹配。
$ istioctl x create-remote-secret --name ${REMOTE_CLUSTER_NAME} --context=${REMOTE_CLUSTER_CTX} |
kubectl apply -f - --context=${MAIN_CLUSTER_CTX}
不要为运行Istio控制平面的本地群集创建远程秘钥。 Istio始终知道本地集群的Kubernetes凭据。
其他
Automatic injection
每个集群中的Istiod服务都会为其自身集群中的代理提供自动Sidecar注入。必须按照自动Sidecar注入指南在每个集群中标记名称空间。
访问来自不同集群的服务
Kubernetes会基于集群解析DNS。由于DNS解析与集群相关,因此无论服务端点的位置如何,您都必须在运行客户端的每个集群中定义服务对象。为确保这种情况,请使用kubectl将服务对象复制到每个集群。复制可确保Kubernetes可以解析任何集群中的服务名称。由于服务对象是在名称空间中定义的,因此您必须定义该名称空间(如果该名称不存在),并将其包含在所有集群的服务定义中。
安全
每个集群中的Istiod服务向其自己集群中的代理提供CA功能。早期的CA设置可确保网格中集群之间的代理具有相同的信任根。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。