Google Kubernetes Engine

此示例展示在两个 Google Kubernetes Engine 集群上使用单网络 deployment 配置多集群网格。

开始之前

除了为安装 Istio 准备环境,该示例还需要以下设置:

创建 GKE 集群

  • gcloud 设置默认的项目,并执行以下操作:
  1. $ gcloud config set project myProject
  2. $ proj=$(gcloud config list --format='value(core.project)')
  • 创建 2 GKE 集群来使用多集群的特性。 注意: —enable-ip-alias 需要允许集群中 pod 之间的直接通信。该 zone 值必须是GCP zones 其中之一。
  1. $ zone="us-east1-b"
  2. $ cluster="cluster-1"
  3. $ gcloud container clusters create $cluster --zone $zone --username "admin" \
  4. --machine-type "n1-standard-2" --image-type "COS" --disk-size "100" \
  5. --scopes "https://www.googleapis.com/auth/compute","https://www.googleapis.com/auth/devstorage.read_only",\
  6. "https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring",\
  7. "https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly",\
  8. "https://www.googleapis.com/auth/trace.append" \
  9. --num-nodes "4" --network "default" --enable-cloud-logging --enable-cloud-monitoring --enable-ip-alias --async
  10. $ cluster="cluster-2"
  11. $ gcloud container clusters create $cluster --zone $zone --username "admin" \
  12. --machine-type "n1-standard-2" --image-type "COS" --disk-size "100" \
  13. --scopes "https://www.googleapis.com/auth/compute","https://www.googleapis.com/auth/devstorage.read_only",\
  14. "https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring",\
  15. "https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly",\
  16. "https://www.googleapis.com/auth/trace.append" \
  17. --num-nodes "4" --network "default" --enable-cloud-logging --enable-cloud-monitoring --enable-ip-alias --async
  • 通过以下命令轮询集群的状态,以等待集群转换为 RUNNING 状态:
  1. $ gcloud container clusters list
  1. $ gcloud container clusters get-credentials cluster-1 --zone $zone
  2. $ gcloud container clusters get-credentials cluster-2 --zone $zone
  • 验证 kubectl 是否能访问每一个集群,并创建一个 cluster-admin 集群角色,使其与 GCP 用户关联的 Kubernetes 证书绑定。

    • 对于 cluster-1:
  1. $ kubectl config use-context "gke_${proj}_${zone}_cluster-1"
  2. $ kubectl get pods --all-namespaces
  3. $ kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user="$(gcloud config get-value core/account)"
  • 对于 cluster-2:
  1. $ kubectl config use-context "gke_${proj}_${zone}_cluster-2"
  2. $ kubectl get pods --all-namespaces
  3. $ kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user="$(gcloud config get-value core/account)"

创建 Google Cloud 防火墙规则

为了允许 pod 在每个集群中直接通信,创建以下规则:

  1. $ function join_by { local IFS="$1"; shift; echo "$*"; }
  2. $ ALL_CLUSTER_CIDRS=$(gcloud container clusters list --format='value(clusterIpv4Cidr)' | sort | uniq)
  3. $ ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}"))
  4. $ ALL_CLUSTER_NETTAGS=$(gcloud compute instances list --format='value(tags.items.[0])' | sort | uniq)
  5. $ ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
  6. $ gcloud compute firewall-rules create istio-multicluster-test-pods \
  7. --allow=tcp,udp,icmp,esp,ah,sctp \
  8. --direction=INGRESS \
  9. --priority=900 \
  10. --source-ranges="${ALL_CLUSTER_CIDRS}" \
  11. --target-tags="${ALL_CLUSTER_NETTAGS}" --quiet

安装 Istio 控制平面

以下命令生成 Istio 安装清单,使其安装,并在 default 命名空间开启 sidecar 自动注入:

  1. $ kubectl config use-context "gke_${proj}_${zone}_cluster-1"
  2. $ helm template install/kubernetes/helm/istio --name istio --namespace istio-system > $HOME/istio_master.yaml
  3. $ kubectl create ns istio-system
  4. $ helm template install/kubernetes/helm/istio-init --name istio-init --namespace istio-system | kubectl apply -f -
  5. $ kubectl apply -f $HOME/istio_master.yaml
  6. $ kubectl label namespace default istio-injection=enabled

通过以下命令轮询其状态,以等待 pod 创建完成:

  1. $ kubectl get pods -n istio-system

生成远程集群清单

  • 获取控制平面 pod 的 IP:
  1. $ export PILOT_POD_IP=$(kubectl -n istio-system get pod -l istio=pilot -o jsonpath='{.items[0].status.podIP}')
  2. $ export POLICY_POD_IP=$(kubectl -n istio-system get pod -l istio=mixer -o jsonpath='{.items[0].status.podIP}')
  3. $ export TELEMETRY_POD_IP=$(kubectl -n istio-system get pod -l istio-mixer-type=telemetry -o jsonpath='{.items[0].status.podIP}')
  • 生成远程集群清单;

Zip

  1. $ helm template install/kubernetes/helm/istio \
  2. --namespace istio-system --name istio-remote \
  3. --values @install/kubernetes/helm/istio/values-istio-remote.yaml@ \
  4. --set global.remotePilotAddress=${PILOT_POD_IP} \
  5. --set global.remotePolicyAddress=${POLICY_POD_IP} \
  6. --set global.remoteTelemetryAddress=${TELEMETRY_POD_IP} > $HOME/istio-remote.yaml

安装远程集群清单中的配置

以下命令将安装 Istio 最低配置所需的组件, 并在远程集群上的 default 命名空间开启 sidecar 自动注入:

  1. $ kubectl config use-context "gke_${proj}_${zone}_cluster-2"
  2. $ kubectl create ns istio-system
  3. $ kubectl apply -f $HOME/istio-remote.yaml
  4. $ kubectl label namespace default istio-injection=enabled

为 Istio Pilot 创建远程集群的 kubeconfig

The istio-remote Helm 图表创建了一个具有最少访问权限的服务帐户,供 Istio Pilot 发现使用。

  • 准备环境变量为服务账户 istio-multi 创建 kubeconfig 文件:
  1. $ export WORK_DIR=$(pwd)
  2. $ CLUSTER_NAME=$(kubectl config view --minify=true -o jsonpath='{.clusters[].name}')
  3. $ CLUSTER_NAME="${CLUSTER_NAME##*_}"
  4. $ export KUBECFG_FILE=${WORK_DIR}/${CLUSTER_NAME}
  5. $ SERVER=$(kubectl config view --minify=true -o jsonpath='{.clusters[].cluster.server}')
  6. $ NAMESPACE=istio-system
  7. $ SERVICE_ACCOUNT=istio-multi
  8. $ SECRET_NAME=$(kubectl get sa ${SERVICE_ACCOUNT} -n ${NAMESPACE} -o jsonpath='{.secrets[].name}')
  9. $ CA_DATA=$(kubectl get secret ${SECRET_NAME} -n ${NAMESPACE} -o jsonpath="{.data['ca\.crt']}")
  10. $ TOKEN=$(kubectl get secret ${SECRET_NAME} -n ${NAMESPACE} -o jsonpath="{.data['token']}" | base64 --decode)

在许多系统中,openssl enc -d -base64 -Abase64 —decode 是的一种替代方式。

  • 在工作目录中为服务账户 istio-multi 创建一个 kubeconfig 文件:
  1. $ cat <<EOF > ${KUBECFG_FILE}
  2. apiVersion: v1
  3. clusters:
  4. - cluster:
  5. certificate-authority-data: ${CA_DATA}
  6. server: ${SERVER}
  7. name: ${CLUSTER_NAME}
  8. contexts:
  9. - context:
  10. cluster: ${CLUSTER_NAME}
  11. user: ${CLUSTER_NAME}
  12. name: ${CLUSTER_NAME}
  13. current-context: ${CLUSTER_NAME}
  14. kind: Config
  15. preferences: {}
  16. users:
  17. - name: ${CLUSTER_NAME}
  18. user:
  19. token: ${TOKEN}
  20. EOF

至此,远程集群的 kubeconfig 文件已被创建在 ${WORK_DIR} 目录中。集群的文件名与原始的 kubeconfig 集群名字相同。

配置 Istio 控制平面来发现远程集群

创建 secret 并为每一个远程集群标记:

  1. $ kubectl config use-context "gke_${proj}_${zone}_cluster-1"
  2. $ kubectl create secret generic ${CLUSTER_NAME} --from-file ${KUBECFG_FILE} -n ${NAMESPACE}
  3. $ kubectl label secret ${CLUSTER_NAME} istio/multiCluster=true -n ${NAMESPACE}

跨集群部署 Bookinfo 示例

  • 在第一个集群上安装 Bookinfo。移除 reviews-v3 deployment 来部署在远程上:

ZipZip

  1. $ kubectl config use-context "gke_${proj}_${zone}_cluster-1"
  2. $ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo.yaml@
  3. $ kubectl apply -f @samples/bookinfo/networking/bookinfo-gateway.yaml@
  4. $ kubectl delete deployment reviews-v3
  • 在远程集群上安装 reviews-v3 deployment。

ZipZipZipZip

  1. $ kubectl config use-context "gke_${proj}_${zone}_cluster-2"
  2. $ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo.yaml@ -l service=ratings
  3. $ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo.yaml@ -l service=reviews
  4. $ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo.yaml@ -l account=reviews
  5. $ kubectl apply -f @samples/bookinfo/platform/kube/bookinfo.yaml@ -l app=reviews,version=v3

注意:ratings 服务定义被添加到远程集群,因为 reviews-v3ratings 的一个客户端,并创建服务对象以创建 DNS 条目。在 DNS 查询被解析为服务地址后,在 reviews-v3 pod 中的 Istio sidecar 将确定正确的 ratings endpoint。如果额外设置了多集群的 DNS 解决方案,例如联邦 Kubernetes 环境,则上面的步骤是没必要的。

  • 获取 istio-ingressgateway 服务的外部 IP 访问 bookinfo 页面以验证 Istio 是否在 review 版本的负载均衡中包括远程的 reviews-v3 实例:
  1. $ kubectl config use-context "gke_${proj}_${zone}_cluster-1"
  2. $ kubectl get svc istio-ingressgateway -n istio-system

重复访问 http://<GATEWAY_IP>/productpage 并且每个 review 的版本均应负载均衡,包含远程集群(红色星星)中的 reviews-v3。或许需要几次(数十次)操作才能演示 reviews 版本之间的负载均衡。

卸载

除了卸载 Istio 之外,还应执行基于 VPN 的多集群卸载部分 中的操作:

  • 删除 Google Cloud 防火墙规则:
  1. $ gcloud compute firewall-rules delete istio-multicluster-test-pods --quiet
  • 从不再用于 Istio 的每个集群中删除 cluster-admin 集群角色绑定:
  1. $ kubectl delete clusterrolebinding gke-cluster-admin-binding
  • 删除不再使用的所有 GKE 集群。以下是删除 cluster-2 远程集群的命令示例:
  1. $ gcloud container clusters delete cluster-2 --zone $zone

相关内容

IBM Cloud Private

跨两个 IBM Cloud Private 集群的多集群网格示例。

共享控制平面(单一网络)

安装一个跨多个 Kubernetes 集群的 Istio 网格,多集群共享控制平面,并且集群间通过 VPN 互连。

共享的控制平面(多网络)

跨多个 Kubernetes 集群安装一个 Istio 网格,使互不联通的集群网络共享同一个控制平面。

控制平面副本集

通过控制平面副本集实例,在多个 Kubernetes 集群上安装 Istio 网格。

简化地多集群安装 [实验性]

配置一个跨多个 Kubernetes 集群的 Istio 网格。

DNS 证书管理

在 Istio 中配置和管理 DNS 证书。