Microsoft Azureで実行するOCNEクラスタの作成
ノート
この機能は試験段階にあります。テストが完全には終わっておらず、情報提供のみを目的としています。安全性や安定性を保証するものではなく、この機能を本番環境に実装することはお薦めしません。Cluster APIプロジェクトには、クラスタ管理用にKubernetesスタイルのAPIの標準的なセットが用意されています。Verrazzanoが現在、公式にサポートしているのは、OCIでのOCNEおよびOKEクラスタのプロビジョニングにおけるCluster APIの使用のみです。
ただし、Cluster APIプロジェクトの機能を試験的に使用して、Microsoft AzureにOCNEクラスタを直接デプロイすることも可能です。
Cluster APIまたはAzureでのCluster APIの詳細は、次を参照してください:
ノート
VerrazzanoとCluster APIでは、同じ概念に対して若干異なる用語が使用されています:
- 管理クラスタ(Verrazzano) = 管理クラスタ(Cluster API)
- 管理対象クラスタ(Verrazzano) = ワークロード・クラスタ(Cluster API)
Azureリソースの準備
Cluster APIクラスタをデプロイする前に、Azureでいくつかのリソースを設定する必要があります。
- Azureコマンドライン・インタフェース(CLI)ツールをインストールします。手順は、Microsoft Azureのドキュメントの「How to install the Azure CLI」を参照してください。
- Azureリソース・グループを作成します。Azure CLIで、次のコマンドを実行します:
$ az group create --name <ResourceGroupName> --location <location>
- サービス・プリンシパルを作成します。リソースの作成に必要な権限があることを確認します。これは、最小限のコントリビュータ・ロールを意味します。次の例では、サービス・プリンシパルを作成し、それをコントリビュータ・ロールに割り当てて、スコープを定義しています。
$ az ad sp create-for-rbac --name myServicePrincipalName \ --role Contributor \ --scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName
管理クラスタの設定
Cluster APIでは、リソースをデプロイする開始点として初期クラスタが必要です。
-
kindをインストールします。kindのドキュメントのインストールの手順に従います。
-
kindを使用してKubernetesクラスタを作成します。『The Cluster API Book』の「Quick Start: Install and/or configure a Kubernetes cluster」の手順に従います。
-
clusterctl CLIツールをインストールします。clusterctlは、Cluster APIの管理クラスタのライフサイクル操作を管理します。『The Cluster API Book』の「Quick Start: Install clusterctl」の手順に従います。
-
「CLI設定」の手順で、Verrazzano CLIツールをインストールします。
-
dev
またはprod
インストール・プロファイルを使用して、クラスタにVerrazzanoをインストールします。「CLIを使用したインストール」の手順に従います。certManager
およびclusterAPI
コンポーネントは必須であるため、有効なままにしておく必要があります。 -
クラスタで、Azureアカウントおよび作成したサービス・プリンシパルから、次のAzureリソースIDの環境変数を設定します:
- サブスクリプションID
- テナントID
- クライアントID
- クライアント・シークレット
たとえば:
# Azure resource IDs $ export AZURE_SUBSCRIPTION_ID="<SubscriptionId>" $ export AZURE_TENANT_ID="<Tenant>" $ export AZURE_CLIENT_ID="<AppId>" $ export AZURE_CLIENT_SECRET="<Password>" # Base64 encode the Azure Resource IDs $ export AZURE_SUBSCRIPTION_ID_B64="$(echo -n "$AZURE_SUBSCRIPTION_ID" | base64 | tr -d '\n')" $ export AZURE_TENANT_ID_B64="$(echo -n "$AZURE_TENANT_ID" | base64 | tr -d '\n')" $ export AZURE_CLIENT_ID_B64="$(echo -n "$AZURE_CLIENT_ID" | base64 | tr -d '\n')" $ export AZURE_CLIENT_SECRET_B64="$(echo -n "$AZURE_CLIENT_SECRET" | base64 | tr -d '\n')" # Settings needed for AzureClusterIdentity used by the AzureCluster $ export AZURE_CLUSTER_IDENTITY_SECRET_NAME="<cluster-identity-secret>" $ export CLUSTER_IDENTITY_NAME="<cluster-identity>" $ export AZURE_CLUSTER_IDENTITY_SECRET_NAMESPACE="default"
-
Azureで作成されたサービス・プリンシパルIDのパスワードを含むシークレットを作成します。このシークレットは、AzureClusterで使用されるAzureClusterIdentityによって参照されます。
$ kubectl create secret generic "${AZURE_CLUSTER_IDENTITY_SECRET_NAME}" --from-literal=clientSecret="${AZURE_CLIENT_SECRET}" --namespace "${AZURE_CLUSTER_IDENTITY_SECRET_NAMESPACE}"
-
Cluster API Azureインフラストラクチャ・プロバイダをインストールします。
$ clusterctl init -n verrazzano-capi -i azure
管理クラスタが正常に初期化されると、clusterctlによって報告されます。
管理対象クラスタの作成
Cluster APIでは、クラスタ・テンプレートを使用して、事前に定義したCluster APIオブジェクトのセットをデプロイし、管理対象クラスタを作成します。
-
次の環境変数を設定して、クラスタ・テンプレートで使用できるようにします。ご使用の環境が反映されるように値を更新します。
# Base64 encoded SSH key for node access $ export AZURE_SSH_PUBLIC_KEY_B64="<sshKey>" # Select VM types. $ export AZURE_CONTROL_PLANE_MACHINE_TYPE="Standard_D2s_v3" $ export AZURE_NODE_MACHINE_TYPE="Standard_D2s_v3" # [Optional] Select resource group. The default value is ${CLUSTER_NAME}. $ export AZURE_RESOURCE_GROUP="<resourceGroupName> # Name of the Azure datacenter location. Change this value to your desired location. $ export AZURE_LOCATION="<location>" # Cluster name info $ export CLUSTER_NAME="capi-quickstart" $ export KUBERNETES_VERSION="<k8sVersion>" $ export NAMESPACE="default" $ export CONTROL_PLANE_MACHINE_COUNT="1" $ export WORKER_MACHINE_COUNT="1"
-
クラスタ・テンプレートをコピーし、ローカルに
azure-capi.yaml
として保存します。クラスタ・テンプレートはここをクリック
apiVersion: cluster.x-k8s.io/v1beta1 kind: Cluster metadata: name: ${CLUSTER_NAME} namespace: default spec: clusterNetwork: pods: cidrBlocks: - 192.168.0.0/16 controlPlaneRef: apiVersion: controlplane.cluster.x-k8s.io/v1beta1 kind: OCNEControlPlane name: ${CLUSTER_NAME}-control-plane infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: AzureCluster name: ${CLUSTER_NAME} --- apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: AzureCluster metadata: name: ${CLUSTER_NAME} namespace: default spec: identityRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: AzureClusterIdentity name: ${CLUSTER_IDENTITY_NAME} location: ${AZURE_LOCATION} networkSpec: subnets: - name: control-plane-subnet role: control-plane - name: node-subnet role: node vnet: name: ${AZURE_VNET_NAME:=${CLUSTER_NAME}-vnet} resourceGroup: ${AZURE_RESOURCE_GROUP:=${CLUSTER_NAME}} subscriptionID: ${AZURE_SUBSCRIPTION_ID} --- apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: AzureMachineTemplate metadata: name: ${CLUSTER_NAME}-control-plane namespace: default spec: template: spec: image: marketplace: publisher: "Oracle" offer: "Oracle-Linux" sku: "ol88-lvm-gen2" version: "8.8.3" dataDisks: - diskSizeGB: 256 lun: 0 nameSuffix: etcddisk osDisk: diskSizeGB: 128 osType: Linux sshPublicKey: ${AZURE_SSH_PUBLIC_KEY_B64:=""} vmSize: ${AZURE_CONTROL_PLANE_MACHINE_TYPE} --- apiVersion: cluster.x-k8s.io/v1beta1 kind: MachineDeployment metadata: name: ${CLUSTER_NAME}-md-0 namespace: default spec: clusterName: ${CLUSTER_NAME} replicas: ${WORKER_MACHINE_COUNT} selector: matchLabels: null template: spec: bootstrap: configRef: apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 kind: OCNEConfigTemplate name: ${CLUSTER_NAME}-md-0 clusterName: ${CLUSTER_NAME} infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: AzureMachineTemplate name: ${CLUSTER_NAME}-md-0 version: ${KUBERNETES_VERSION} --- apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: AzureMachineTemplate metadata: name: ${CLUSTER_NAME}-md-0 namespace: default spec: template: spec: image: marketplace: publisher: "Oracle" offer: "Oracle-Linux" sku: "ol88-lvm-gen2" version: "8.8.3" osDisk: diskSizeGB: 128 osType: Linux sshPublicKey: ${AZURE_SSH_PUBLIC_KEY_B64:=""} vmSize: ${AZURE_NODE_MACHINE_TYPE} --- apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: AzureClusterIdentity metadata: labels: clusterctl.cluster.x-k8s.io/move-hierarchy: "true" name: ${CLUSTER_IDENTITY_NAME} namespace: default spec: allowedNamespaces: {} clientID: ${AZURE_CLIENT_ID} clientSecret: name: ${AZURE_CLUSTER_IDENTITY_SECRET_NAME} namespace: ${AZURE_CLUSTER_IDENTITY_SECRET_NAMESPACE} tenantID: ${AZURE_TENANT_ID} type: ServicePrincipal --- apiVersion: controlplane.cluster.x-k8s.io/v1alpha1 kind: OCNEControlPlane metadata: name: ${CLUSTER_NAME}-control-plane namespace: default spec: moduleOperator: enabled: true verrazzanoPlatformOperator: enabled: true controlPlaneConfig: clusterConfiguration: apiServer: extraArgs: cloud-provider: external certSANs: - localhost - 127.0.0.1 dns: imageRepository: ${OCNE_IMAGE_REPOSITORY=container-registry.oracle.com}/${OCNE_IMAGE_PATH=olcne} imageTag: ${DNS_TAG=v1.9.3} etcd: local: imageRepository: ${OCNE_IMAGE_REPOSITORY=container-registry.oracle.com}/${OCNE_IMAGE_PATH=olcne} imageTag: ${ETCD_TAG=3.5.6} controllerManager: extraArgs: cloud-provider: external networking: {} scheduler: {} imageRepository: ${OCNE_IMAGE_REPOSITORY=container-registry.oracle.com}/${OCNE_IMAGE_PATH=olcne} files: - contentFrom: secret: key: control-plane-azure.json name: ${CLUSTER_NAME}-control-plane-azure-json owner: root:root path: /etc/kubernetes/azure.json permissions: "0644" initConfiguration: nodeRegistration: criSocket: /var/run/crio/crio.sock kubeletExtraArgs: cloud-provider: external name: '{{ local_hostname }}' joinConfiguration: discovery: {} nodeRegistration: criSocket: /var/run/crio/crio.sock kubeletExtraArgs: cloud-provider: external name: '{{ local_hostname }}' preOCNECommands: - hostnamectl set-hostname "{{ ds.meta_data.hostname }}" - echo "::1 ipv6-localhost ipv6-loopback localhost6 localhost6.localdomain6" >/etc/hosts - echo "127.0.0.1 {{ ds.meta_data.hostname }} {{ local_hostname }} localhost localhost.localdomain localhost4 localhost4.localdomain4" >>/etc/hosts users: - name: opc sudo: ALL=(ALL) NOPASSWD:ALL machineTemplate: infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: AzureMachineTemplate name: ${CLUSTER_NAME}-control-plane namespace: default replicas: ${CONTROL_PLANE_MACHINE_COUNT} version: ${KUBERNETES_VERSION} --- apiVersion: bootstrap.cluster.x-k8s.io/v1alpha1 kind: OCNEConfigTemplate metadata: name: ${CLUSTER_NAME}-md-0 namespace: default spec: template: spec: clusterConfiguration: imageRepository: ${OCNE_IMAGE_REPOSITORY=container-registry.oracle.com}/${OCNE_IMAGE_PATH=olcne} joinConfiguration: nodeRegistration: kubeletExtraArgs: cloud-provider: external name: '{{ local_hostname }}' preOCNECommands: - hostnamectl set-hostname "{{ ds.meta_data.hostname }}" - echo "::1 ipv6-localhost ipv6-loopback localhost6 localhost6.localdomain6" >/etc/hosts - echo "127.0.0.1 {{ ds.meta_data.hostname }} {{ local_hostname }} localhost localhost.localdomain localhost4 localhost4.localdomain4" >>/etc/hosts users: - name: opc sudo: ALL=(ALL) NOPASSWD:ALL
-
次のコマンドを実行してテンプレートを生成し、適用します:
$ clusterctl generate yaml --from azure-capi.yaml | kubectl apply -f -
クラスタおよびそのリソースのステータスを表示するには、次を実行します:
$ clusterctl describe cluster $CLUSTER_NAME
kubeconfig
ファイルを取得するには、次を実行します:
$ clusterctl get kubeconfig ${CLUSTER_NAME} > ${CLUSTER_NAME}.kubeconfig
クラスタ構成の終了
クラスタ・リソースを作成したら、追加のステップを実行して、クラスタの構成を終了する必要があります。
- クラウド・コントローラ・マネージャ(CCM)をインストールします。ロード・バランサなどのクラウド・リソースをデプロイする場合は、CCMが必要です。
$ helm install --kubeconfig=./${CLUSTER_NAME}.kubeconfig --repo https://raw.githubusercontent.com/kubernetes-sigs/cloud-provider-azure/master/helm/repo cloud-provider-azure --generate-name --set infra.clusterName=clusterName --set cloudControllerManager.clusterCIDR="192.168.0.0/16" --set cloudControllerManager.caCertDir=/etc/pki/ca-trust
- コンテナ・ネットワーク・インタフェース(CNI)をインストールします。次の例では、Calico CNIを使用します。
$ helm repo add projectcalico https://docs.tigera.io/calico/charts --kubeconfig=./${CLUSTER_NAME}.kubeconfig && \ $ helm install calico projectcalico/tigera-operator --kubeconfig=./${CLUSTER_NAME}.kubeconfig -f https://raw.githubusercontent.com/kubernetes-sigs/cluster-api-provider-azure/main/templates/addons/calico/values.yaml --namespace tigera-operator --create-namespace
管理クラスタと最初の管理対象クラスタが稼働し、アプリケーションをデプロイする準備が整います。必要に応じて、さらに管理対象クラスタを追加できます。
詳細は、Cluster APIおよびCluster API Azureのドキュメントを参照してください:
デプロイメントのトラブルシューティング
Azureリソースのデプロイメントが失敗した場合は、次のログ・ファイルを確認して問題を診断できます:
Azureクラスタ・コントローラ・プロバイダのログ:
$ kubectl logs -n verrazzano-capi -l cluster.x-k8s.io/provider=infrastructure-azure
$ kubectl logs -n verrazzano-capi -l cluster.x-k8s.io/provider=control-plane-ocne
ノート: ポッドがCrashLoopBackOff
状態になった場合は、デプロイメントを再起動するか、通常どおり実行される状態になるのを待機します。これは既知の問題で、クラスタのデプロイメントに影響はありません。
クラスタの削除
- 管理対象クラスタを削除します。
$ kubectl delete cluster $CLUSTER_NAME
- 管理クラスタを削除します。
$ kind delete cluster
手動でのクリーンアップが必要な保留中のリソースが残ってしまう可能性があるため、kubectl delete -f capi-quickstart.yaml
を使用して、クラスタ・テンプレート全体を一度に削除しないでください。