全部產品
Search
文件中心

Container Service for Kubernetes:構建混合彈性容器叢集(彈性ECS)

更新時間:Jun 19, 2024

混合叢集是通過阿里雲註冊叢集接入本機資料中心自建Kubernetes叢集的容器叢集。它可以為自建Kubernetes叢集擴容雲上計算節點,同時也可以管理雲上雲下計算資源。本文以使用Calico容器網路組件的IDC自建Kubernetes叢集為例,介紹如何建立混合叢集。

前提條件

  • 本機資料中心自建Kubernetes叢集的網路與雲上註冊叢集使用的Virtual Private Cloud互聯互連,網路互聯互連包括計算節點網路和容器網路互聯互連。您可以通過雲企業網產品服務實現網路互連。更多資訊,請參見入門概述

  • 目的地組群必須使用註冊叢集提供的私網叢集匯入代理配置接入註冊叢集。

  • 通過註冊叢集擴容的雲上計算節點能夠訪問本機資料中心自建Kubernetes叢集的API Server。

  • 已通過Kubectl串連註冊叢集。具體操作,請參見擷取叢集KubeConfig並通過kubectl工具串連叢集

混合彈性容器叢集架構

由於自建Kubernetes叢集使用Calico路由情境較多,本文將以IDC自建叢集使用Calico路由模式的情境為例進行闡述。關於雲上容器網路外掛程式的使用,建議您使用對應雲平台定製化的網路組件,阿里雲容器平台統一使用Terway網路組件進行容器網路的管理。混合叢集組網模式如下圖所示。

您在本機資料中心內的私網網段為192.168.0.0/24,容器網路網段為10.100.0.0/16,採用Calico網路外掛程式的路由反射模式;雲上專用網路網段為10.0.0.0/8,計算節點虛擬交換器網段為10.10.24.0/24,容器Pod虛擬交換器網段為10.10.25.0/24,採用Terway網路組件的共用模式。

使用ACK註冊叢集構建混合容器叢集

  1. 配置雲上雲下容器網路外掛程式。

    在混合叢集中,需要保證雲下的Calico網路外掛程式只運行在雲下,雲上的Terway網路組件只運行在雲上。

    由於ACK註冊叢集節點擴容的雲上ECS節點會自動添加節點標籤alibabacloud.com/external=true,為了使IDC內的Calico Pod只運行在雲下,需要為其設定NodeAffinity配置,樣本如下:

    cat <<EOF > calico-ds.patch
    spec:
      template:
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: alibabacloud.com/external
                    operator: NotIn
                    values:
                    - "true"
                  - key: type
                    operator: NotIn
                    values:
                    - "virtual-kubelet"
    EOF
    kubectl -n kube-system patch ds calico-node -p "$(cat calico-ds.patch)"
  2. 為Terway外掛程式配置RAM許可權。

    通過onectl配置

    1. 在本地安裝配置onectl。具體操作,請參見通過onectl管理註冊叢集

    2. 執行以下命令,為Terway外掛程式配置RAM許可權。

      onectl ram-user grant --addon terway-eniip

      預期輸出:

      Ram policy ack-one-registered-cluster-policy-terway-eniip granted to ram user ack-one-user-ce313528c3 successfully.

    通過控制台配置

    為Terway網路組件配置AK資訊所需的RAM許可權,權限原則內容如下,具體操作,請參見為RAM使用者授權

    {
        "Version": "1",
        "Statement": [
            {
                "Action": [
                    "ecs:CreateNetworkInterface",
                    "ecs:DescribeNetworkInterfaces",
                    "ecs:AttachNetworkInterface",
                    "ecs:DetachNetworkInterface",
                    "ecs:DeleteNetworkInterface",
                    "ecs:DescribeInstanceAttribute",
                    "ecs:AssignPrivateIpAddresses",
                    "ecs:UnassignPrivateIpAddresses",
                    "ecs:DescribeInstances",
                    "ecs:ModifyNetworkInterfaceAttribute"
                ],
                "Resource": [
                    "*"
                ],
                "Effect": "Allow"
            },
            {
                "Action": [
                    "vpc:DescribeVSwitches"
                ],
                "Resource": [
                    "*"
                ],
                "Effect": "Allow"
            }
        ]
    }
  3. 安裝Terway外掛程式。

    通過onectl安裝

    執行以下命令,安裝Terway外掛程式。

    onectl addon install terway-eniip

    預期輸出:

    Addon terway-eniip, version **** installed.

    通過控制台安裝

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇營運管理 > 組件管理

    3. 組件管理頁面,搜尋terway-eniip組件,單擊組件右下方的安裝,然後單擊確定

    4. 執行以下命令,查看Terway網路組件守護進程集。

  4. 通過kubectl串連叢集後,在註冊叢集中執行以下命令,查看Terway網路組件守護進程集。

    在混合叢集擴容雲上節點之前,Terway將不會被調度到任何一個雲下節點上。

    kubectl -nkube-system get ds |grep terway

    預期輸出:

    terway-eniip   0         0         0       0            0           alibabacloud.com/external=true      16s

    預期輸出表明,Terway Pod將只運行在打標alibabacloud.com/external=true的雲上ECS節點。

  5. 執行以下命令,編輯ConfigMap的eni-config,並配置eni_conf.access_key eni_conf.access_secret

    kubectl -n kube-system edit cm eni-config

    eni-config配置樣本如下:

    kind: ConfigMap
    apiVersion: v1
    metadata:
     name: eni-config
     namespace: kube-system
    data:
     eni_conf: |
      {
       "version": "1",
       "max_pool_size": 5,
       "min_pool_size": 0,
       "vswitches": {"AZoneID":["VswitchId"]}, 
       "eni_tags": {"ack.aliyun.com":"{{.ClusterID}}"},
       "service_cidr": "{{.ServiceCIDR}}",
       "security_group": "{{.SecurityGroupId}}",
       "access_key": "",
       "access_secret": "",
       "vswitch_selection_policy": "ordered"
      }
     10-terway.conf: |
      {
       "cniVersion": "0.3.0",
       "name": "terway",
       "type": "terway"
      }
  6. 配置自訂節點初始化指令碼。

    1. 改造自建Kubernetes叢集原始的節點初始化指令碼。

      以使用Kubeadm工具初始化的IDC自建Kubernetes叢集為例,在IDC中為叢集添加新節點的原始初始化指令碼init-node.sh指令碼樣本如下。

      展開查看init-node.sh指令碼樣本

      #!/bin/bash
      
      export K8S_VERSION=1.24.3
      
      export REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com
      cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
      overlay
      br_netfilter
      EOF
      modprobe overlay
      modprobe br_netfilter
      cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
      net.bridge.bridge-nf-call-iptables  = 1
      net.ipv4.ip_forward                 = 1
      net.bridge.bridge-nf-call-ip6tables = 1
      EOF
      sysctl --system
      yum remove -y containerd.io
      yum install -y yum-utils device-mapper-persistent-data lvm2
      yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
      yum install -y containerd.io-1.4.3
      mkdir -p /etc/containerd
      containerd config default > /etc/containerd/config.toml
      sed -i "s#k8s.gcr.io#registry.aliyuncs.com/k8sxio#g"  /etc/containerd/config.toml
      sed -i '/containerd.runtimes.runc.options/a\ \ \ \ \ \ \ \ \ \ \ \ SystemdCgroup = true' /etc/containerd/config.toml
      sed -i "s#https://registry-1.docker.io#${REGISTRY_MIRROR}#g"  /etc/containerd/config.toml
      systemctl daemon-reload
      systemctl enable containerd
      systemctl restart containerd
      yum install -y nfs-utils
      yum install -y wget
      cat <<EOF > /etc/yum.repos.d/kubernetes.repo
      [kubernetes]
      name=Kubernetes
      baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
      enabled=1
      gpgcheck=0
      repo_gpgcheck=0
      gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
             http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
      EOF
      yum remove -y kubelet kubeadm kubectl
      yum install -y kubelet-$K8S_VERSION kubeadm-$K8S_VERSION kubectl-$K8S_VERSION
      crictl config runtime-endpoint /run/containerd/containerd.sock
      systemctl daemon-reload
      systemctl enable kubelet && systemctl start kubelet
      containerd --version
      kubelet --version
      
      kubeadm join 10.200.1.253:XXXX --token cqgql5.1mdcjcvhszol**** --discovery-token-unsafe-skip-ca-verification

      ACK註冊叢集中所需要配置的自訂節點初始化指令碼init-node-ecs.sh,就是在init-node.sh指令碼的基礎上接收並配置註冊叢集下發的ALIBABA_CLOUD_PROVIDER_IDALIBABA_CLOUD_NODE_NAMEALIBABA_CLOUD_LABELSALIBABA_CLOUD_TAINTS這些環境變數即可,init-node-ecs.sh指令碼樣本如下。

      展開查看init-node-ecs.sh指令碼樣本

      #!/bin/bash
      
      export K8S_VERSION=1.24.3
      
      export REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com
      cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
      overlay
      br_netfilter
      EOF
      modprobe overlay
      modprobe br_netfilter
      cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
      net.bridge.bridge-nf-call-iptables  = 1
      net.ipv4.ip_forward                 = 1
      net.bridge.bridge-nf-call-ip6tables = 1
      EOF
      sysctl --system
      yum remove -y containerd.io
      yum install -y yum-utils device-mapper-persistent-data lvm2
      yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
      yum install -y containerd.io-1.4.3
      mkdir -p /etc/containerd
      containerd config default > /etc/containerd/config.toml
      sed -i "s#k8s.gcr.io#registry.aliyuncs.com/k8sxio#g"  /etc/containerd/config.toml
      sed -i '/containerd.runtimes.runc.options/a\ \ \ \ \ \ \ \ \ \ \ \ SystemdCgroup = true' /etc/containerd/config.toml
      sed -i "s#https://registry-1.docker.io#${REGISTRY_MIRROR}#g"  /etc/containerd/config.toml
      systemctl daemon-reload
      systemctl enable containerd
      systemctl restart containerd
      yum install -y nfs-utils
      yum install -y wget
      cat <<EOF > /etc/yum.repos.d/kubernetes.repo
      [kubernetes]
      name=Kubernetes
      baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
      enabled=1
      gpgcheck=0
      repo_gpgcheck=0
      gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
             http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
      EOF
      yum remove -y kubelet kubeadm kubectl
      yum install -y kubelet-$K8S_VERSION kubeadm-$K8S_VERSION kubectl-$K8S_VERSION
      crictl config runtime-endpoint /run/containerd/containerd.sock
      systemctl daemon-reload
      systemctl enable kubelet && systemctl start kubelet
      containerd --version
      kubelet --version
      
      ####### <新增部分
      # 配置Node Labels,Taints,Node Name,Provider ID
      #KUBEADM_CONFIG_FILE="/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf"
      KUBELET_CONFIG_FILE="/etc/sysconfig/kubelet"
      #KUBELET_CONFIG_FILE="/etc/systemd/system/kubelet.service.d/10-kubeadm.conf"
      if [[ $ALIBABA_CLOUD_LABELS != "" ]];then
        option="--node-labels"
        if grep -- "${option}=" $KUBELET_CONFIG_FILE &> /dev/null;then
          sed -i "s@${option}=@${option}=${ALIBABA_CLOUD_LABELS},@g" $KUBELET_CONFIG_FILE
        elif grep "KUBELET_EXTRA_ARGS=" $KUBELET_CONFIG_FILE &> /dev/null;then
          sed -i "s@KUBELET_EXTRA_ARGS=@KUBELET_EXTRA_ARGS=${option}=${ALIBABA_CLOUD_LABELS} @g" $KUBELET_CONFIG_FILE
        else
          sed -i "/^\[Service\]/a\Environment=\"KUBELET_EXTRA_ARGS=${option}=${ALIBABA_CLOUD_LABELS}\"" $KUBELET_CONFIG_FILE
        fi
      fi
      
      if [[ $ALIBABA_CLOUD_TAINTS != "" ]];then
        option="--register-with-taints"
        if grep -- "${option}=" $KUBELET_CONFIG_FILE &> /dev/null;then
          sed -i "s@${option}=@${option}=${ALIBABA_CLOUD_TAINTS},@g" $KUBELET_CONFIG_FILE
        elif grep "KUBELET_EXTRA_ARGS=" $KUBELET_CONFIG_FILE &> /dev/null;then
          sed -i "s@KUBELET_EXTRA_ARGS=@KUBELET_EXTRA_ARGS=${option}=${ALIBABA_CLOUD_TAINTS} @g" $KUBELET_CONFIG_FILE
        else
          sed -i "/^\[Service\]/a\Environment=\"KUBELET_EXTRA_ARGS=${option}=${ALIBABA_CLOUD_TAINTS}\"" $KUBELET_CONFIG_FILE
        fi
      fi
      
      if [[ $ALIBABA_CLOUD_NODE_NAME != "" ]];then
        option="--hostname-override"
        if grep -- "${option}=" $KUBELET_CONFIG_FILE &> /dev/null;then
          sed -i "s@${option}=@${option}=${ALIBABA_CLOUD_NODE_NAME},@g" $KUBELET_CONFIG_FILE
        elif grep "KUBELET_EXTRA_ARGS=" $KUBELET_CONFIG_FILE &> /dev/null;then
          sed -i "s@KUBELET_EXTRA_ARGS=@KUBELET_EXTRA_ARGS=${option}=${ALIBABA_CLOUD_NODE_NAME} @g" $KUBELET_CONFIG_FILE
        else
          sed -i "/^\[Service\]/a\Environment=\"KUBELET_EXTRA_ARGS=${option}=${ALIBABA_CLOUD_NODE_NAME}\"" $KUBELET_CONFIG_FILE
        fi
      fi
      
      if [[ $ALIBABA_CLOUD_PROVIDER_ID != "" ]];then
        option="--provider-id"
        if grep -- "${option}=" $KUBELET_CONFIG_FILE &> /dev/null;then
          sed -i "s@${option}=@${option}=${ALIBABA_CLOUD_PROVIDER_ID},@g" $KUBELET_CONFIG_FILE
        elif grep "KUBELET_EXTRA_ARGS=" $KUBELET_CONFIG_FILE &> /dev/null;then
          sed -i "s@KUBELET_EXTRA_ARGS=@KUBELET_EXTRA_ARGS=${option}=${ALIBABA_CLOUD_PROVIDER_ID} @g" $KUBELET_CONFIG_FILE
        else
          sed -i "/^\[Service\]/a\Environment=\"KUBELET_EXTRA_ARGS=${option}=${ALIBABA_CLOUD_PROVIDER_ID}\"" $KUBELET_CONFIG_FILE
        fi
      fi
      
      #重啟Docker,並啟動kubelet
      systemctl daemon-reload
      systemctl enable kubelet && systemctl start kubelet
      
      ####### 新增部分>
      
      kubeadm join 10.200.1.253:XXXX --token cqgql5.1mdcjcvhszol**** --discovery-token-unsafe-skip-ca-verification
    2. 儲存和配置自訂指令碼。

      將自訂指令碼儲存在HTTP檔案伺服器上,例如存放在OSS Bucket上。樣本地址為https://kubelet-****.oss-cn-hangzhou-internal.aliyuncs.com/init-node-ecs.sh

      將自訂節點添加指令碼的路徑https://kubelet-****.oss-cn-hangzhou-internal.aliyuncs.com/init-node-ecs.sh配置到addNodeScriptPath欄位地區並儲存,如下所示:

      apiVersion: v1
      data:
        addNodeScriptPath: https://kubelet-****.oss-cn-hangzhou-internal.aliyuncs.com/init-node-ecs.sh
      kind: ConfigMap
      metadata:
        name: ack-agent-config
        namespace: kube-system

    當您完成上述配置操作後,即可在目標ACK註冊叢集建立節點池以及擴容ECS節點。

  7. 建立節點池並擴容ECS節點。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇節點管理 > 節點池

    3. 節點池頁面,根據需求建立節點池並擴容節點。具體操作,請參見建立節點池

相關文檔

規劃Terway情境的容器網路。具體操作,請參見Kubernetes叢集網路規劃

本機資料中心Kubernetes網路與雲上Virtual Private Cloud互聯互連。具體操作,請參見功能特性

建立註冊叢集並接入本機資料中心自建Kubernetes叢集。具體操作,請參見通過控制台建立註冊叢集