すべてのプロダクト
Search
ドキュメントセンター

Elastic Container Instance:CCM のデプロイ

最終更新日:Dec 28, 2024

クラウドコントローラーマネージャー (CCM) を使用すると、Kubernetes をクラシックロードバランサー (CLB) や仮想プライベートクラウド (VPC) などの Alibaba Cloud サービスと統合できます。CCM を使用して、Kubernetes クラスター内のノードと Kubernetes クラスター外の Elastic Compute Service (ECS) インスタンスに CLB インスタンスを関連付けることができます。これにより、サービス移行中のトラフィックの中断を防ぎます。CCM を使用して、複数の Kubernetes クラスターにトラフィックを転送できます。このデータバックアップとディザスタリカバリの対策により、サービスの高可用性が確保されます。このトピックでは、セルフマネージド Kubernetes クラスターに CCM をデプロイする方法について説明します。

前提条件

  • セルフマネージド Kubernetes クラスターに VNode がデプロイされていること。

  • セルフマネージド Kubernetes クラスターがデータセンターにデプロイされている場合、データセンターが Alibaba Cloud に接続されていること。

背景情報

CCM は、Alibaba Cloud が提供するコンポーネントであり、Kubernetes を Alibaba Cloud サービスと統合できます。CCM は次の機能を提供します。

  • サーバーロードバランサー (SLB) インスタンスの管理

    サービスのタイプを LoadBalancer に設定すると、CCM はサービスの CLB インスタンスを自動的に作成し、CLB インスタンスのリスナーとバックエンド vServer グループを設定します。サービスの vServer グループ内の ECS インスタンスのエンドポイントが変更された場合、またはクラスターノードが変更された場合、CCM は CLB インスタンスの vServer グループを自動的に更新します。

  • クロスノード通信の有効化

    Flannel が Kubernetes クラスターのネットワークプラグインとして使用されている場合、CCM はコンテナーとノード間のネットワーク接続を有効にし、ポッドの CIDR ブロックをクラスターがデプロイされている VPC のルートテーブルに追加します。これにより、コンテナーはノード間で相互に通信できます。この機能は、CCM のインストール後にすぐに使用できます。

詳細については、クラウドコントローラーマネージャー を参照してください。

説明

CCM はオープンソースです。プロジェクトの詳細については、cloud-provider-alibaba-cloud を参照してください。

準備

セルフマネージド Kubernetes クラスターで ECS インスタンスがノードとして使用されていない場合は、準備をスキップしてください。セルフマネージド Kubernetes クラスターで ECS インスタンスがノードとして使用されている場合は、次の操作を実行して ECS インスタンスの providerID を設定します。これにより、CCM は ECS インスタンスのルートを管理できます。

  1. BroadcastJob を使用するために OpenKruise をデプロイします。

    コマンド例:

    helm repo add openkruise https://openkruise.github.io/charts/
    helm repo update
    helm install kruise openkruise/kruise --version 1.3.0

    詳細については、OpenKruise のドキュメントをご覧ください。

  2. BroadcastJob を使用して、ECS インスタンスの providerID を設定します。

    1. provider.yaml という名前のファイルを作成し、次のテンプレートをファイルにコピーします。

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: ecs-node-initor
      rules:
        - apiGroups:
            - ""
          resources:
            - nodes
          verbs:
            - get
            - patch
      ---
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: ecs-node-initor
      ---
      kind: ClusterRoleBinding
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: ecs-node-initor
      subjects:
      - kind: ServiceAccount
        name: ecs-node-initor
        namespace: default
      roleRef:
        kind: ClusterRole
        name: ecs-node-initor
        apiGroup: rbac.authorization.k8s.io
      ---
      apiVersion: apps.kruise.io/v1alpha1
      kind: BroadcastJob
      metadata:
        name: create-ecs-node-provider-id
      spec:
        template:
          spec:
            serviceAccount: ecs-node-initor
            restartPolicy: OnFailure
            affinity:
              nodeAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                  nodeSelectorTerms:
                  - matchExpressions:
                    - key: type
                      operator: NotIn
                      values:
                      - virtual-kubelet
            tolerations:
            - operator: Exists
            containers:
              - name: create-ecs-node-provider-id
                image: registry.cn-beijing.aliyuncs.com/eci-release/provider-initor:v1
                command: [ "/usr/bin/init" ]
                env:
                - name: NODE_NAME
                  valueFrom:
                    fieldRef:
                      fieldPath: spec.nodeName
        completionPolicy:
          type: Never
        failurePolicy:
          type: FailFast
          restartLimit: 3
    2. BroadcastJob をデプロイします。

      kubectl apply -f provider.yaml
  3. BroadcastJob の実行結果を表示します。

    kubectl get pods -o wide

    名前が create-ecs-node-provider-id を含むすべてのポッドが Completed 状態になったら、ECS インスタンスの providerID が設定されています。次の図は出力例を示しています。

    部署CCM1

  4. (オプション) BroadcastJob を削除します。

    kubectl delete -f provider.yaml

手順

  1. ConfigMap を作成します。

    1. Alibaba Cloud アカウントの AccessKey ペアを環境変数に保存します。

      export ACCESS_KEY_ID=LTAI********************
      export ACCESS_KEY_SECRET=HAeS**************************

      AccessKey ID と AccessKey シークレットを取得する方法については、AccessKey ペアの取得を参照してください。

    2. 次のスクリプトを実行して、ConfigMap を作成します。

      configmap-ccm.sh という名前のスクリプトを作成し、次のテンプレートをスクリプトにコピーして、リージョン値を実際の値に置き換えます。次に、スクリプトを実行します。

      #!/bin/bash
      
      ## CCM 用の ConfigMap kube-system/cloud-config を作成します。
      accessKeyIDBase64=`echo -n "$ACCESS_KEY_ID" |base64 -w 0`
      accessKeySecretBase64=`echo -n "$ACCESS_KEY_SECRET"|base64 -w 0`
      
      cat <<EOF >cloud-config.yaml
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: cloud-config
        namespace: kube-system
      data:
        cloud-config.conf: |-
          {
              "Global": {
                  "accessKeyID": "$accessKeyIDBase64",
                  "accessKeySecret": "$accessKeySecretBase64",
                  "region": "cn-hangzhou"
              }
          }
      EOF
      
      kubectl create -f cloud-config.yaml
      bash configmap-ccm.sh

      スクリプトが実行されると、cloud-config という名前の ConfigMap が Kube-system ネームスペースに作成されます。

  2. CCM をデプロイします。

    1. ${ImageVersion}{$ClusterCIDR} を置き換え、ccm.yaml という名前のファイルを作成し、次のテンプレートをファイルにコピーします。

      • CCM の更新レコードに基づいて ImageVersion の値を取得できます。詳細については、クラウドコントローラーマネージャー を参照してください。

      • kubectl cluster-info dump | grep -m1 cluster-cidr コマンドを実行して、ClusterCIDR を表示できます。

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: system:cloud-controller-manager
      rules:
        - apiGroups:
            - coordination.k8s.io
          resources:
            - leases
          verbs:
            - get
            - list
            - update
            - create
        - apiGroups:
            - ""
          resources:
            - persistentvolumes
            - services
            - secrets
            - endpoints
            - serviceaccounts
          verbs:
            - get
            - list
            - watch
            - create
            - update
            - patch
        - apiGroups:
            - ""
          resources:
            - nodes
          verbs:
            - get
            - list
            - watch
            - delete
            - patch
            - update
        - apiGroups:
            - ""
          resources:
            - services/status
          verbs:
            - update
            - patch
        - apiGroups:
            - ""
          resources:
            - nodes/status
          verbs:
            - patch
            - update
        - apiGroups:
            - ""
          resources:
            - events
            - endpoints
          verbs:
            - create
            - patch
            - update
      ---
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: cloud-controller-manager
        namespace: kube-system
      ---
      kind: ClusterRoleBinding
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: system:cloud-controller-manager
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: system:cloud-controller-manager
      subjects:
        - kind: ServiceAccount
          name: cloud-controller-manager
          namespace: kube-system
      ---
      kind: ClusterRoleBinding
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: system:shared-informers
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: system:cloud-controller-manager
      subjects:
        - kind: ServiceAccount
          name: shared-informers
          namespace: kube-system
      ---
      kind: ClusterRoleBinding
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: system:cloud-node-controller
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: system:cloud-controller-manager
      subjects:
        - kind: ServiceAccount
          name: cloud-node-controller
          namespace: kube-system
      ---
      kind: ClusterRoleBinding
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: system:pvl-controller
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: system:cloud-controller-manager
      subjects:
        - kind: ServiceAccount
          name: pvl-controller
          namespace: kube-system
      ---
      kind: ClusterRoleBinding
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: system:route-controller
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: system:cloud-controller-manager
      subjects:
        - kind: ServiceAccount
          name: route-controller
          namespace: kube-system
      ---
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        labels:
          app: cloud-controller-manager
          tier: control-plane
        name: cloud-controller-manager
        namespace: kube-system
      spec:
        selector:
          matchLabels:
            app: cloud-controller-manager
            tier: control-plane
        template:
          metadata:
            labels:
              app: cloud-controller-manager
              tier: control-plane
            annotations:
              scheduler.alpha.kubernetes.io/critical-pod: ''
          spec:
            serviceAccountName: cloud-controller-manager
            tolerations:
              - effect: NoSchedule
                operator: Exists
                key: node-role.kubernetes.io/master
              - effect: NoSchedule
                operator: Exists
                key: node.cloudprovider.kubernetes.io/uninitialized
            nodeSelector:
              node-role.kubernetes.io/master: ""
            containers:
              - command:
                -  /cloud-controller-manager
                - --leader-elect=true
                - --cloud-provider=alicloud
                - --use-service-account-credentials=true
                - --cloud-config=/etc/kubernetes/config/cloud-config.conf
                - --configure-cloud-routes=true
                - --route-reconciliation-period=3m
                - --leader-elect-resource-lock=endpoints
                # ${cluster-cidr} を独自のクラスター CIDR に置き換えます
                # 例: 172.16.0.0/16
                - --cluster-cidr=${ClusterCIDR}  
                # ${ImageVersion} を最新のリリースバージョンに置き換えます
                # 例: v2.1.0
                image: registry.cn-hangzhou.aliyuncs.com/acs/cloud-controller-manager-amd64:${ImageVersion}
                livenessProbe:
                  failureThreshold: 8
                  httpGet:
                    host: 127.0.0.1
                    path: /healthz
                    port: 10258
                    scheme: HTTP
                  initialDelaySeconds: 15
                  timeoutSeconds: 15
                name: cloud-controller-manager
                resources:
                  requests:
                    cpu: 200m
                volumeMounts:
                  - mountPath: /etc/kubernetes/
                    name: k8s
                  - mountPath: /etc/ssl/certs
                    name: certs
                  - mountPath: /etc/pki
                    name: pki
                  - mountPath: /etc/kubernetes/config
                    name: cloud-config
            hostNetwork: true
            volumes:
              - hostPath:
                  path: /etc/kubernetes
                name: k8s
              - hostPath:
                  path: /etc/ssl/certs
                name: certs
              - hostPath:
                  path: /etc/pki
                name: pki
              - configMap:
                  defaultMode: 420
                  items:
                    - key: cloud-config.conf
                      path: cloud-config.conf
                  name: cloud-config
                name: cloud-config
    2. 次のコマンドを実行して、CCM をデプロイします。

      kubectl create -f ccm.yaml

結果の確認

  1. Type=LoadBalancer とサービスのエンドポイントを持つサービスを作成します。

    1. ccm-test.yaml という名前のファイルを作成し、次のテンプレートをファイルにコピーします。

      イメージのダウンロードエラーを防ぐため、イメージアドレスを VNode が存在するリージョンのアドレスに置き換えます。

      apiVersion: v1
      kind: Service
      metadata:
        name: nginx
        namespace: default
        annotations:
          service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type: "intranet"
      spec:
        ports:
        - port: 80
          protocol: TCP
          targetPort: 80
        selector:
          app: nginx
        type: LoadBalancer
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: test-nginx
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: registry-vpc.cn-beijing.aliyuncs.com/eci_open/nginx:1.14.2
    2. 次のコマンドを実行して、サービスとデプロイメントを作成します。

      kubectl create -f ccm-test.yaml

      サービスとデプロイメントが作成されると、CCM はサービスの CLB インスタンスを自動的に作成し、CLB インスタンスのリスナーとバックエンド vServer グループを設定します。

  2. サービスが期待どおりに動作するかどうかを確認します。

    curl コマンドを実行して、サービスのアドレスにアクセスします。次の図に示すように、バックエンド NGINX サービスにはサービスのアドレスを介してアクセスできます。

    ccm

サービスの使用方法の詳細については、CCM の使用方法をご覧ください。