Tous les produits
Search
Centre de documentation

Container Service for Kubernetes:Créer un cluster de conteneurs élastique hybride (ECS élastique)

Dernière mise à jour :Aug 11, 2026

Un cluster hybride relie votre cluster Kubernetes autogéré sur site à Alibaba Cloud via un cluster enregistré. Cela vous permet de mettre à l'échelle votre cluster sur site avec des nœuds Elastic Compute Service (ECS) basés sur le cloud, tout en gérant les deux environnements depuis un seul plan de contrôle.

Ce guide utilise comme exemple un cluster de centre de données exécutant Calico en mode réflecteur de route. Côté cloud, Alibaba Cloud Container Service for Kubernetes (ACK) utilise le plugin Terway pour la mise en réseau des conteneurs.

Prérequis

Avant de commencer, assurez-vous de disposer des éléments suivants :

  • Une connectivité réseau entre votre cluster sur site et le virtual private cloud (VPC) utilisé par le cluster enregistré, couvrant à la fois le réseau des nœuds de calcul et le réseau des conteneurs. Utilisez Cloud Enterprise Network (CEN) pour établir cette connectivité. Pour plus de détails, consultez Établir des connexions multi-VPC dans différents scénarios.

Important

La connectivité réseau entre votre environnement sur site et le VPC est une exigence fondamentale. Si elle n'est pas en place, aucune des étapes suivantes ne réussira.

Architecture du cluster hybride

Dans un cluster hybride, Calico s'exécute sur site et Terway dans le cloud. Les deux plugins réseau ne doivent pas interférer entre eux : les pods Calico restent sur les nœuds sur site, tandis que les pods Terway s'exécutent uniquement sur les nœuds ECS basés sur le cloud.

Le diagramme suivant illustre la topologie réseau de cet exemple.

image

Sur site (centre de données) :

  • Bloc CIDR privé : 192.168.0.0/24

  • Bloc CIDR du réseau de conteneurs : 10.100.0.0/16

  • Plugin réseau : Calico (mode réflecteur de route)

Côté cloud :

  • Bloc CIDR du VPC : 10.0.0.0/8

  • Bloc CIDR du vSwitch pour les nœuds de calcul : 10.10.24.0/24

  • Bloc CIDR du vSwitch pour les pods : 10.10.25.0/24

  • Plugin réseau : Terway (mode partagé)

Assurez-vous que le bloc CIDR du réseau de conteneurs sur site ( 10.100.0.0/16 ) ne chevauche pas le bloc CIDR du VPC ( 10.0.0.0/8 ).

Configurer le cluster hybride

La configuration comporte sept étapes :

  1. Restreindre Calico aux nœuds sur site

  2. Accorder des permissions RAM à Terway

  3. Installer Terway

  4. Vérifier le DaemonSet Terway

  5. Configurer le ConfigMap ENI de Terway

  6. Créer un script d'initialisation de nœud personnalisé

  7. Créer un pool de nœuds et ajouter des nœuds ECS

Étape 1 : Restreindre Calico aux nœuds sur site

Les nœuds ECS basés sur le cloud ajoutés à un cluster ACK enregistré sont automatiquement étiquetés alibabacloud.com/external=true. Configurez nodeAffinity sur le DaemonSet Calico afin que les pods Calico s'exécutent uniquement sur les nœuds sur site (nœuds sans cette étiquette).

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)"

Étape 2 : Accorder des permissions RAM à Terway

Terway nécessite des permissions Resource Access Management (RAM) pour gérer les elastic network interfaces (ENI) sur les nœuds ECS.

Option A : Utilisation d'onectl (recommandée)

  1. Installez et configurez onectl. Consultez Gérer les clusters enregistrés à l'aide d'onectl.

  2. Exécutez la commande suivante :

    onectl ram-user grant --addon terway-eniip

    Sortie attendue :

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

Option B : Utilisation de la console

Accordez la politique RAM suivante à l'AccessKey utilisée par Terway. Pour obtenir des instructions, consultez Gérer les permissions des utilisateurs 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"
        }
    ]
}

Étape 3 : Installer Terway

Option A : Utilisation d'onectl

onectl addon install terway-eniip

Sortie attendue :

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

Option B : Utilisation de la console

  1. Connectez-vous à la Console de gestion Container Service. Dans le volet de navigation de gauche, cliquez sur Clusters.

  2. Cliquez sur le nom de votre cluster, puis sur Add-ons dans le volet de navigation de gauche.

  3. Sur la page Add-ons, recherchez terway-eniip. Cliquez sur Install dans le coin inférieur droit de la carte du composant, puis sur OK.

Étape 4 : Vérifier le DaemonSet Terway

Avant d'ajouter des nœuds basés sur le cloud, confirmez que Terway n'est pas planifié sur les nœuds sur site.

kubectl -nkube-system get ds |grep terway

Sortie attendue :

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

Le sélecteur de nœud alibabacloud.com/external=true confirme que les pods Terway s'exécuteront uniquement sur les nœuds ECS basés sur le cloud.

Étape 5 : Configurer le ConfigMap ENI de Terway

Modifiez le ConfigMap eni-config dans le namespace kube-system pour définir les identifiants AccessKey pour Terway :

kubectl -n kube-system edit cm eni-config

Définissez access_key et access_secret dans la section eni_conf :

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"
    }

Remplacez access_key et access_secret par l'ID AccessKey et le secret AccessKey de l'utilisateur RAM disposant des permissions accordées à l'étape 2.

Étape 6 : Créer un script d'initialisation de nœud personnalisé

Lorsqu'un cluster ACK enregistré ajoute un nœud ECS, il exécute un script d'initialisation de nœud et lui transmet des variables d'environnement spécifiques au cloud. Votre script d'initialisation sur site existant (init-node.sh) doit être étendu pour prendre en charge ces variables.

Variables d'environnement transmises par le cluster enregistré :

Variable d'environnement Objectif
ALIBABA_CLOUD_PROVIDER_ID Définit --provider-id sur kubelet
ALIBABA_CLOUD_NODE_NAME Définit --hostname-override sur kubelet
ALIBABA_CLOUD_LABELS Définit --node-labels sur kubelet
ALIBABA_CLOUD_TAINTS Définit --register-with-taints sur kubelet

6a. Étendre le script d'initialisation

Le script personnalisé init-node-ecs.sh commence par la même configuration que init-node.sh (installation de containerd, kubelet, kubeadm, etc.), puis ajoute une section qui lit les variables d'environnement Alibaba Cloud et les transmet à kubelet avant de rejoindre le cluster.

Afficher l'exemple de script 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

Afficher l'exemple de script 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

####### Start of added section
# Configure node labels, taints, node name, and provider ID
# from environment variables passed by the registered ACK cluster
KUBELET_CONFIG_FILE="/etc/sysconfig/kubelet"

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

# Reload and restart kubelet with the new configuration
systemctl daemon-reload
systemctl enable kubelet && systemctl start kubelet
####### End of added section

kubeadm join 10.200.1.253:XXXX --token cqgql5.1mdcjcvhszol**** --discovery-token-unsafe-skip-ca-verification

6b. Héberger le script et l'enregistrer auprès du cluster

  1. Téléchargez init-node-ecs.sh sur un serveur de fichiers HTTP accessible depuis le cloud, par exemple un compartiment Object Storage Service (OSS) :

    https://kubelet-****.oss-cn-hangzhou-internal.aliyuncs.com/init-node-ecs.sh
  2. Définissez addNodeScriptPath dans le ConfigMap ack-agent-config avec l'URL du script :

    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

Étape 7 : Créer un pool de nœuds et ajouter des nœuds ECS

  1. Connectez-vous à la Console de gestion Container Service. Dans le volet de navigation de gauche, cliquez sur Clusters.

  2. Cliquez sur le nom de votre cluster, puis sur Nodes > Node Pools dans le volet de navigation de gauche.

  3. Sur la page Node Pools, créez un pool de nœuds et ajoutez des nœuds. Pour plus de détails, consultez Créer et gérer un pool de nœuds.

Vérifier le cluster hybride

Après l'ajout de nœuds, confirmez que les nouveaux nœuds ECS ont rejoint le cluster avec l'étiquette correcte :

kubectl get nodes --show-labels | grep external=true

Les nœuds étiquetés alibabacloud.com/external=true sont des nœuds ECS basés sur le cloud. Les nœuds sans cette étiquette sont des nœuds sur site. Si les deux types apparaissent dans la sortie, le cluster hybride est opérationnel.

Étapes suivantes