クラウドコントローラーマネージャー (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 インスタンスのルートを管理できます。
BroadcastJob を使用するために OpenKruise をデプロイします。
コマンド例:
helm repo add openkruise https://openkruise.github.io/charts/ helm repo update helm install kruise openkruise/kruise --version 1.3.0
詳細については、OpenKruise のドキュメントをご覧ください。
BroadcastJob を使用して、ECS インスタンスの providerID を設定します。
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
BroadcastJob をデプロイします。
kubectl apply -f provider.yaml
BroadcastJob の実行結果を表示します。
kubectl get pods -o wide
名前が create-ecs-node-provider-id を含むすべてのポッドが Completed 状態になったら、ECS インスタンスの providerID が設定されています。次の図は出力例を示しています。
(オプション) BroadcastJob を削除します。
kubectl delete -f provider.yaml
手順
ConfigMap を作成します。
Alibaba Cloud アカウントの AccessKey ペアを環境変数に保存します。
export ACCESS_KEY_ID=LTAI******************** export ACCESS_KEY_SECRET=HAeS**************************
AccessKey ID と AccessKey シークレットを取得する方法については、AccessKey ペアの取得を参照してください。
次のスクリプトを実行して、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 ネームスペースに作成されます。
CCM をデプロイします。
${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
次のコマンドを実行して、CCM をデプロイします。
kubectl create -f ccm.yaml
結果の確認
Type=LoadBalancer とサービスのエンドポイントを持つサービスを作成します。
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
次のコマンドを実行して、サービスとデプロイメントを作成します。
kubectl create -f ccm-test.yaml
サービスとデプロイメントが作成されると、CCM はサービスの CLB インスタンスを自動的に作成し、CLB インスタンスのリスナーとバックエンド vServer グループを設定します。
サービスが期待どおりに動作するかどうかを確認します。
curl コマンドを実行して、サービスのアドレスにアクセスします。次の図に示すように、バックエンド NGINX サービスにはサービスのアドレスを介してアクセスできます。
サービスの使用方法の詳細については、CCM の使用方法をご覧ください。