Distributed Cloud Container Platform for Kubernetes (ACK One) では、登録済みクラスターを使用して、オンプレミス データセンターまたは他のクラウドプロバイダーにデプロイされた外部 Kubernetes クラスターを Container Service for Kubernetes (ACK) に接続できます。これにより、クラスターとリソースを一元管理できるようになり、ハイブリッドクラウド環境を迅速にデプロイできます。ローカル データセンターの計算リソースが制約された場合、ノードプールを作成してクラウドの計算リソースをスケールアウトし、動的なビジネスの成長需要に対応できます。このトピックでは、クラウドノードプールのプロビジョニングに必要なカスタムスクリプトを作成する方法について説明します。
前提条件
ACK One 登録済みクラスターが作成され、データセンターにデプロイされた外部 Kubernetes クラスターがACK One 登録済みクラスターに接続されていること。詳細については、「ACK One 登録済みクラスターを作成する」をご参照ください。
外部 Kubernetes クラスターのネットワークが、ACK One 登録済みクラスターの VPC に接続されていること。詳細については、「VPC 接続のシナリオベースのネットワーキング」をご参照ください。
プライベートネットワークモードで、外部 Kubernetes クラスターのプロキシ構成をACK One 登録済みクラスターにインポートする必要があります。詳細については、「ACK One 登録済みクラスターを作成する」をご参照ください。
手順
サンプルノードスクリプトを使用するか、実際の環境と前の図の条件に基づいてカスタムスクリプトを作成できます。
サンプルスクリプトは、パッケージマネージャーとして Yellowdog Updater, Modified (YUM) を使用するオペレーティングシステムのみをサポートしています。
ステップ 1 (A): カスタムスクリプトに Alibaba Cloud 環境変数を追加する
ノードが GPU アクセラレーションノードであるかどうかを確認します。この手順はオプションです。
次のスクリプトを使用して、Elastic Compute Service (ECS) ノードが GPU アクセラレーションノードであるかどうかを確認できます。
#!/bin/bash # Ispci がインストールされているかどうかを確認します。 if ! which lspci &>/dev/null; then yum -y install pciutils fi # ノードに GPU が搭載されているかどうかを確認します。 if lspci | grep -i nvidia &>/dev/null; then echo "ノードは GPU アクセラレーションノードであるため、関連ドライバーをインストールしてください。" fi通常の ECS ノードとは異なり、GPU アクセラレーションノードの場合はドライバーとデバイスプラグインをインストールする必要があります。詳細については、「ノードの NVIDIA ドライバーを手動で更新する」をご参照ください。
登録済みクラスターのノードプールがリソーススケジューリングのためにノードステータスを正常に同期できるように、カスタムスクリプトを準備する必要があります。カスタムスクリプトは、登録済みクラスターによって発行された環境変数を取得する必要があります。環境変数を取得するために使用される方法は、外部 Kubernetes クラスターの作成方法によって異なります。 kubeadm またはバイナリメソッドを使用して Kubernetes クラスターを作成できます。
Kubernetes クラスターは kubeadm メソッドを使用して作成されます
kubeadm メソッドは Kubernetes によって推奨されており、公式ツール kubeadm を使用して Kubernetes クラスターがセットアップされます。カスタムノードスクリプトに次のコンテンツを追加する必要があります。
.... ####### <次のコンテンツを追加します。 # ノードラベル、テイント、ノード名、およびノードプロバイダー ID を構成します。 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 ####### 前述のコンテンツを追加します。 # ランタイムと kubelet を再起動します。 ....Kubernetes クラスターはバイナリメソッドを使用して作成されます
クラスターが Kubernetes バイナリファイルを使用して作成された場合は、カスタムノードスクリプトで kubelet の起動構成を変更して、環境変数を取得する必要があります。通常、
kubelet.serviceファイルは/usr/lib/systemd/system/ディレクトリに保存されます。cat >/usr/lib/systemd/system/kubelet.service <<EOF # カスタム構成は表示されません。 ... [Service] ExecStart=/data0/kubernetes/bin/kubelet \\ # 次の構成を変更します。 --node-ip=${ALIBABA_CLOUD_NODE_NAME} \\ --hostname-override=${ALIBABA_CLOUD_NODE_NAME} \\ --node-labels=${ALIBABA_CLOUD_LABELS} \\ --provider-id=${ALIBABA_CLOUD_PROVIDER_ID} \\ --register-with-taints=${ALIBABA_CLOUD_TAINTS} \\ .... --v=4 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
次の表に、登録済みクラスターによって発行された環境変数を示します。
環境変数 | 説明 | 例 |
ALIBABA_CLOUD_PROVIDER_ID | カスタムノードスクリプトはこの環境変数を取得する必要があります。そうしないと、登録済みクラスターは正常に実行できません。 | ALIBABA_CLOUD_PROVIDER_ID=cn-shenzhen.i-wz92ewt14n9wx9mo*** |
ALIBABA_CLOUD_NODE_NAME | カスタムノードスクリプトはこの環境変数を取得する必要があります。そうしないと、ノードプールのノードが異常な状態で実行される可能性があります。 | ALIBABA_CLOUD_NODE_NAME=cn-shenzhen.192.168.1.*** |
ALIBABA_CLOUD_LABELS | カスタムノードスクリプトはこの環境変数を取得する必要があります。そうしないと、ノードプールの管理中およびクラウドノードとオンプレミスノード間のワークロードスケジューリング中にエラーが発生する可能性があります。 | ALIBABA_CLOUD_LABELS=alibabacloud.com/nodepool-id=np0e2031e952c4492bab32f512ce142***,ack.aliyun.com=cc3df6d939b0d4463b493b82d0d670***,alibabacloud.com/instance-id=i-wz960ockeekr3dok0***,alibabacloud.com/external=true,workload=cpu workload=cpu ラベルは、ノードプール構成で定義されたカスタムラベルです。他のラベルはシステムラベルです。 |
ALIBABA_CLOUD_TAINTS | カスタムノードスクリプトはこの環境変数を取得する必要があります。そうしないと、ノードプールに追加されたテイントは有効になりません。 | ALIBABA_CLOUD_TAINTS=workload=ack:NoSchedule |
上記の手順を実行した後、ステップ 2:スクリプトを保存してファイルサーバーにアップロードするに進みます。
ステップ 1 (B): ノードスクリプトを追加する
関連するシステム情報を取得します。
クラスターの Kubernetes バージョンが 1.18 以降の場合
次のコマンドを実行して、外部クラスターの Kubernetes バージョンをクエリします。 Kubernetes バージョンは、後続の手順でサンプルスクリプトの環境変数
KUBE_VERSIONで指定されます。kubectl get no $(kubectl get nodes -l node-role.kubernetes.io/control-plane -o json | jq -r '.items[0].metadata.name') -o json | jq -r '.status.nodeInfo.kubeletVersion'予期される出力:
v1.14.10次のコマンドを実行して、外部クラスターのランタイムとランタイムバージョンをクエリします。ランタイムとランタイムバージョンは、後続の手順でサンプルスクリプトの環境変数
RUNTIME_VERSIONで指定されます。kubectl get no $(kubectl get nodes -l node-role.kubernetes.io/control-plane -o json | jq -r '.items[0].metadata.name') -o json | jq -r '.status.nodeInfo.containerRuntimeVersion'予期される出力:
docker://18.6.3 # Docker が使用されています。 containerd://1.4.3 # containerd が使用されています。次のコマンドを実行して、ノードを追加するために使用される kubeadm コマンドをクエリします。コマンドは、後続の手順でサンプルスクリプトの環境変数
KUBEADM_JOIN_CMDで指定されます。# --ttl 0 は非常に重要です。ノードプールの自動スケーリングが無効にならないように、TTL を 0(有効期限なし)に設定します。 kubeadm token create --ttl 0 --print-join-command予期される出力:
kubeadm join 192.168.8.XXX:6443 --token k8xsq8.4oo8va9wcqpb*** --discovery-token-ca-cert-hash sha256:cb5fc894ab965dfbc4c194e1065869268f8845c3ec40f78f9021dde24610d***
クラスターの Kubernetes バージョンが 1.18 より前の場合
次のコマンドを実行して、外部クラスターの Kubernetes バージョンをクエリします。 Kubernetes バージョンは、後続の手順でサンプルスクリプトの環境変数
KUBE_VERSIONで指定されます。kubectl get no $(kubectl get nodes -l node-role.kubernetes.io/master -o json | jq -r '.items[0].metadata.name') -o json | jq -r '.status.nodeInfo.kubeletVersion'予期される出力:
v1.14.10次のコマンドを実行して、外部クラスターのランタイムとランタイムバージョンをクエリします。ランタイムとランタイムバージョンは、後続の手順でサンプルスクリプトの環境変数
RUNTIME_VERSIONで指定されます。kubectl get no $(kubectl get nodes -l node-role.kubernetes.io/master -o json | jq -r '.items[0].metadata.name') -o json | jq -r '.status.nodeInfo.containerRuntimeVersion'予期される出力:
docker://18.6.3 # Docker が使用されています。 containerd://1.4.3 # containerd が使用されています。次のコマンドを実行して、ノードを追加するために使用される kubeadm コマンドをクエリします。コマンドは、後続の手順でサンプルスクリプトの環境変数
KUBEADM_JOIN_CMDで指定されます。# --ttl 0 は非常に重要です。ノードプールの自動スケーリングが無効にならないように、TTL を 0(有効期限なし)に設定します。 kubeadm token create --ttl 0 --print-join-command予期される出力:
kubeadm join 192.168.8.XXX:6443 --token k8xsq8.4oo8va9wcqpb*** --discovery-token-ca-cert-hash sha256:cb5fc894ab965dfbc4c194e1065869268f8845c3ec40f78f9021dde24610d***
サンプルスクリプトを取得します。
説明サンプルスクリプトは、通常の ECS ノードにのみ適用されます。 GPU アクセラレーション ECS ノードの場合は、submit a ticket を R&D チームに送信してください。
サンプルスクリプトの環境変数で、取得した外部クラスターの Kubernetes バージョン、ランタイム、ランタイムバージョン、および kubeadm コマンドを指定します。
Docker
containerd
ステップ 2: スクリプトを保存してファイルサーバーにアップロードする
カスタムノードスクリプトまたは変更したサンプルノードスクリプトを、Object Storage Service (OSS) バケットなどのファイルサーバーにアップロードする必要があります。例:https://kubelet-****.oss-cn-hangzhou-internal.aliyuncs.com/join-ecs-nodes.sh。
ステップ 3: ack-cluster-agent 構成を変更する
ノードプールを作成する前に、この手順を完了する必要があります。そうしないと、ノードプールをスケールアウトするときにカスタムスクリプトを取得できません。その結果、スケールアウト操作は失敗します。
スクリプトがアップロードされ、スクリプトのパスが記録されたら、kube-system 名前空間の ack-agent-config 構成の addNodeScriptPath フィールドにパスを指定します。
# kubectl を使用して ack-agent-config 構成を変更します。
kubectl edit cm ack-agent-config -n kube-system
# addNodeScriptPath フィールドを次のように変更します。
apiVersion: v1
data:
addNodeScriptPath: https://kubelet-****.oss-cn-hangzhou-internal.aliyuncs.com/join-ecs-nodes.sh
kind: ConfigMap
metadata:
name: ack-agent-config
namespace: kube-system