カスタムのCloud-init初期化スクリプトを使用した管理対象ノードの設定

Container Engine for Kubernetes (OKE)を使用して作成したクラスタのワーカー・ノードで実行するカスタムcloud-initスクリプトを記述する方法を確認します。

Cloud-initは、クラウド・インスタンスの初期化、プライベート・クラウド・インフラストラクチャおよびベアメタル・インストール用のシステムのプロビジョニングを行うための業界標準の方法です。Oracle Cloud Infrastructureを含むすべての主要なパブリック・クラウド・プロバイダにわたってサポートされます(ユーザー・データを参照)。Cloud-initは、インスタンスを初期化および構成するためのスクリプトを実行します。cloud-initの詳細は、cloud-initのドキュメントを参照してください。

Container Engine for Kubernetesは、cloud-initを使用して、管理対象ノードをホストするコンピュート・インスタンスを設定します。Container Engine for Kubernetesは、管理対象ノードをホストする各インスタンスにデフォルトの起動スクリプトをインストールします。インスタンスが初めて起動すると、cloud-initによってデフォルトの起動スクリプトが実行されます。デフォルトの起動スクリプトには、Container Engine for Kubernetesによって提供される次のロジックが含まれます:

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh

デフォルト・ロジックの前後に独自のロジックをスクリプトに追加することで、デフォルトの起動スクリプトをカスタマイズできます。デフォルトの起動スクリプトをカスタマイズすると、次のようになります。

  • セキュリティおよびコンプライアンスの目的で、すべてのワーカー・ノード・ホストにSELinuxポリシーを構成します。
  • 起動時にインスタンスのエフェメラル・パブリックIPの割当てを解除し、かわりに予約済パブリックIPをインスタンスに再割当てします
  • 企業プロキシの構成
  • カスタムyumプロキシの構成
  • 必須のウイルス対策ソフトウェアおよびその他のセキュリティツールをインストールする

デフォルトの起動スクリプトをカスタマイズする場合は、Container Engine for Kubernetesによって提供されるロジックを変更しないでください。

新しいクラスタの作成時、新しいノード・プールの作成時、および既存のノード・プールの変更時に、デフォルトの起動スクリプトをカスタマイズできます。

  • コンソールの使用(新しいクラスタを作成する場合は、カスタム作成ワークフローを使用します)
  • CLIの使用
  • APIの使用

カスタマイズした起動スクリプトは、ワーカー・ノードをホストしているインスタンスが初めて起動したときに実行されます。デフォルトの起動スクリプトをカスタマイズした後、Node Doctorスクリプトを実行して、新しく起動したインスタンスのワーカー・ノードが期待どおりに機能していることを確認することをお薦めします(ノード・ドクター・スクリプトを使用したKubernetesクラスタのノードの問題のトラブルシューティングを参照)。

カスタムCloud-initスクリプトのユースケースの例

例1: カスタムCloud-initスクリプトを使用した管理対象ノードでのSELinux (セキュリティ強化Linux)の構成

カスタムcloud-initスクリプトを使用して、管理対象ノードにSELinuxを構成できます。SELinuxは、管理者がポリシー内のルールに基づいてどのユーザーおよびアプリケーションからどのリソースにアクセスできるかを制限できるようにする、Linuxのセキュリティ強化です。SELinuxは、アクセス制御にさらに細かい粒度を追加します。

SELinuxは、有効または無効の2つの状態のいずれかになります。有効にすると、SELinuxを2つのモード(強制または許容)のいずれかで実行できます。

デフォルトでは、SELinuxは有効になっており、ワーカー・ノードで許容モードで実行するように設定されています。許可モードで実行する場合、SELinuxはアクセス・ルールを強制せず、ロギングのみを実行します。

SELinuxでアクセス・ルールを適用する場合は、強制モードで実行するように設定できます。強制モードで実行する場合、SELinuxはポリシーに反するアクションをブロックし、対応するイベントを監査ログに記録します。

SELinuxを強制モードで実行するように設定するには、次のcloud-initスクリプトを使用します。

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh
setenforce 1
sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config 

ワーカー・ノードで実行されているSELinuxのステータスおよびモードを確認するには、ワーカー・ノードに接続し、getenforceコマンドを使用します。前述のcloud-initスクリプトがワーカー・ノードで実行されると、getenforceコマンドはEnforcingを返します。

例2: カスタムCloud-initスクリプトを使用した管理対象ノードでのNodeLocal DNSCacheの設定

カスタムcloud-initスクリプトを使用して、管理対象ノードにNodeLocal DNSCacheを構成できます。NodeLocal DNSCacheは、ワーカー・ノードでDNSキャッシュ・エージェントをデーモンセットとして実行することで、クラスタDNSのパフォーマンスを向上させます。

NodeLocal DNSCacheが有効になっていない場合、ClusterFirst DNSモードのポッドは、DNS問合せのkube-dns serviceIPに到達します。iptablesルールを使用して、このリクエストはkube-proxyによって追加されたkube-dns/CoreDNSエンドポイントに変換されます。詳細は、KubernetesドキュメントのサービスおよびポッドのDNSを参照してください。

NodeLocal DNSCacheが有効な場合、ポッドは、同じワーカー・ノードで実行されているDNSキャッシュ・エージェントに到達し、iptables DNATルールおよび接続トラッキングをバイパスできます。ローカル・キャッシュ・エージェントは、kube-dns/CoreDNSサービスに、クラスタ・ホスト名のキャッシュ・ミス(デフォルトではcluster.local接尾辞)を問い合せます。

NodeLocal DNSCacheを構成するには、次のcloud-initスクリプトを使用します。CLUSTER DNSを、クラスタ内のいずれとも競合しないローカル・リスニングIPアドレスに置き換えます。IPv4の場合は169.254.0.0/16、IPv6の場合はfd00::/8の一意のローカル・アドレス範囲から推奨されるリンク・ローカル範囲があります。

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh --cluster-dns "[CLUSTER DNS]"

NodeLocal DNSCacheが正常にデプロイされたことを確認するには、ワーカー・ノードに接続し、sudo systemctl status -l kubeletコマンドを使用します。前述のcloud-initスクリプトがワーカー・ノードで実行されると、sudo systemctl status -l kubeletコマンドは、デフォルトのローカル・リンク・アドレス(169.254.20.10など)に設定されたkubeletフラグの1つとして--cluster-dnsを返します。

前述のcloud-initスクリプトを使用してノードを作成した後、KubernetesドキュメントのKubernetesクラスタでのNodeLocal DNSCacheの使用のステップに従って、DNSキャッシュ・エージェントをデプロイします。有効にすると、各クラスタ・ノードのkube-systemネームスペースでnode-local-dnsポッドが実行されます。node-local-dnsポッドはCoreDNSをキャッシュ・モードで実行するため、異なるプラグインによって公開されるすべてのCoreDNSメトリックをノード単位で使用できます。

DNS解決をテストするには、次のコマンドを1つ以上使用します(KubernetesドキュメントのDNS解決のデバッグを参照)。コマンドは両方とも機能し、カスタムcloud-initスクリプトの--cluster-dnsフラグによって設定されたIPアドレスも出力します。

kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml
kubectl exec -it dnsutils – nslookup kubernetes.default
kubectl exec -it dnsutils – cat /etc/resolv.conf

NodeLocal DNSCacheを無効にするには、デーモンセットを削除し、nodelocaldnsマニフェストを削除します。また、kubelet構成に加えた変更も元に戻す必要があります。

例3: カスタムCloud-initスクリプトを使用した管理対象ノードでのkubelet-extra-argsの設定

カスタムcloud-initスクリプトを使用して、管理対象ノードのkubelet (プライマリ・ノード・エージェント)に多数の追加オプションを構成できます。これらの追加オプションは、kubelet-extra-argsと呼ばれることもあります。そのような kubelet-extra-argsオプションの1つは、デバッグレベルのログ冗長性を構成するオプションです。

デバッグ・レベルのログの詳細度を構成するには、次のcloud-initスクリプトを使用します。

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh --kubelet-extra-args "--v=4"

デバッグ・レベルのログの詳細度の設定を確認するには、ワーカー・ノードに接続し、sudo systemctl status -l kubeletコマンドを使用します。前述のcloud-initスクリプトがワーカー・ノードで実行されると、sudo systemctl status -l kubeletコマンドは冗長性レベルを4として返します。kubeletログにも詳細が含まれています。

例4: カスタムCloud-initスクリプトを使用したKubernetesおよびOSシステム・デーモンのリソースの予約

カスタムcloud-initスクリプトを使用して、Kubernetesシステム・デーモン(kubeletcontainer runtimeなど)およびOSシステム・デーモン(sshdsystemdなど)のCPUおよびメモリー・リソースを予約できます。KubernetesおよびOSシステム・デーモンのリソースを予約するには、カスタムcloud-initスクリプトに--kube-reservedおよび--system-reserved kubeletフラグをそれぞれkubelet-extra-argsオプションとして含めます。

KubernetesおよびOSシステム・デーモンのリソースを予約するには、次のcloud-initスクリプトを使用します:

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh --kubelet-extra-args "--kube-reserved=cpu=500m,memory=1Gi --system-reserved=cpu=100m,memory=100Mi"

詳細および--kube-reservedおよび--system-reserved kubeletフラグの推奨値については、ベスト・プラクティス: KubernetesおよびOSシステム・デーモンのリソースの予約を参照してください。

例5: カスタムCloud-initスクリプトおよびoci-growfsを使用したブート・ボリューム・パーティションのサイズの増加

カスタムcloud-initスクリプトを使用して、管理対象ノードのブート・ボリュームのパーティションを拡張できます。クラスタとノード・プールを作成および更新するときに、ワーカー・ノード・ブート・ボリュームのカスタム・サイズを指定できます。指定するカスタム・ブート・ボリューム・サイズは、選択したイメージのデフォルトのブート・ボリューム・サイズより大きくする必要があります。ブート・ボリュームのサイズを増やすときに、より大きなブート・ボリューム・サイズを利用するには、ブート・ボリュームのパーティションも拡張する必要があります。

Oracle Linuxプラットフォーム・イメージには、oci-utilsパッケージが含まれています。cloud-initスクリプトでそのパッケージからoci-growfsコマンドを使用して、ルート・パーティションを拡張し、ファイル・システムを拡張できます。

ブート・ボリュームのパーティションを拡張するには、次のcloud-initスクリプトを使用します:

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh
bash /usr/libexec/oci-growfs -y

詳細は、ブート・ボリュームのパーティションの拡張を参照してください。

カスタムCloud-initスクリプトの作成

Container Engine for Kubernetesで提供されるデフォルトのcloud-init起動スクリプトをカスタマイズするには:

  1. Container Engine for Kubernetesが提供するデフォルト・ロジックを含む新しいスクリプト・ファイルを作成します。これは、次の2つの方法で実行できます。
    • 「カスタム作成クラスタ」「ノード・プールの追加」または「ノード・プールの編集」ダイアログの使用時に、「カスタムCloud-Initスクリプト・テンプレートのダウンロード」オプション(ノード・プールの「拡張オプション」セクション)を選択します。ダウンロードするファイルには、デフォルトのロジックが含まれています。
    • cloud-init (.yamlなど)でサポートされているファイル・タイプで新しいファイルを最初から作成し、Container Engine for Kubernetesが提供するデフォルト・ロジックを追加します。例:
      #!/bin/bash
      curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
      bash /var/run/oke-init.sh
  2. Container Engine for Kubernetesで提供されるデフォルト・ロジックの前または後に、独自のカスタム・ロジックをスクリプト・ファイルに追加します。デフォルト・ロジックは変更しないでください。

    たとえば、デバッグ・レベルのログの詳細度を構成するには、--kubelet-extra-args "--v=4"を追加して、ファイルは次のようになります。

    #!/bin/bash
    curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
    bash /var/run/oke-init.sh --kubelet-extra-args "--v=4"

    その他の例は、カスタムCloud-initスクリプトのユースケースの例を参照してください。

  3. 作成したカスタムcloud-initスクリプト・ファイルを保存します。
  4. 新しいクラスタの作成時、新しいノード・プールの追加時、または既存のノード・プールの変更時に、カスタムcloud-initスクリプト・ファイルを指定します。

コンソールの使用

コンソールを使用して、新しいクラスタ、新しいノード・プールまたは既存のノード・プールで管理対象ノードをホストするインスタンス用のカスタムcloud-initスクリプトを提供するには:

  1. cloud-initでサポートされているいずれかの形式(cloud-configなど)およびファイル・タイプ(.yamlファイルなど)で、有効なcloud-initファイルを作成します。カスタムCloud-initスクリプトの作成を参照してください。
  2. ナビゲーション・メニューを開き、「開発者サービス」をクリックします。「コンテナとアーティファクト」で、「Kubernetesクラスタ(OKE)」をクリックします。
  3. 作業する権限があるコンパートメントを選択します。
  4. カスタム作成ワークフローを使用して新しいクラスタを作成するか、既存のクラスタに新しいノード・プールを追加するか、既存のノード・プールを変更します。
  5. 「カスタム作成クラスタ」「ノード・プールの追加」または「ノード・プールの編集」ダイアログのノード・プールの「拡張オプション」セクションで、次のように指定します。
    • 初期化スクリプト: (オプション)インスタンスが初めて起動したときにワーカー・ノードをホストする各インスタンスでcloud-initを実行するスクリプト。指定するスクリプトは、cloud-initでサポートされている形式(cloud-configなど)のいずれかで記述する必要があり、サポートされているファイル・タイプ(.yamlなど)である必要があります。スクリプトを次のように指定します。
      • Cloud-Initスクリプトの選択: cloud-initスクリプトを含むファイルを選択するか、ファイルをボックスにドラッグ・アンド・ドロップします。
      • Cloud-Initスクリプトの貼付け: cloud-initスクリプトの内容をコピーして、ボックスに貼り付けます。

      Container Engine for Kubernetesによって作成されたクラスタでワーカー・ノードを初期化するためのcloud-initスクリプトを以前に記述していない場合は、「カスタムCloud-Initスクリプト・テンプレートのダウンロード」をクリックすることが役立つ場合があります。ダウンロードしたファイルには、Container Engine for Kubernetesによって提供されるデフォルトのロジックが含まれています。独自のカスタム・ロジックは、デフォルト・ロジックの前または後に追加できますが、デフォルト・ロジックは変更しないでください。例については、カスタムCloud-initスクリプトのユースケースの例を参照してください。

CLIの使用

CLIの使用の詳細は、コマンド・ライン・インタフェース(CLI)を参照してください。CLIコマンドで使用できるフラグおよびオプションの完全なリストは、コマンドライン・リファレンスを参照してください。

CLIを使用して、新しいノード・プールまたは既存のノード・プールでワーカー・ノードをホストするインスタンス用のカスタムcloud-initスクリプトを指定するには:

  1. cloud-initでサポートされているいずれかの形式(cloud-configなど)およびファイル・タイプ(.yamlファイルなど)で、有効なcloud-initファイルを作成します。カスタムCloud-initスクリプトの作成を参照してください。
  2. コマンド・プロンプトを開き、次のコマンドのいずれかを入力して、新しいノード・プールを作成するか、または必要に応じて既存のノード・プールを更新します。
    • oci ce node-pool create
    • oci ce node-pool update
  3. 使用しているコマンドに必要な必須パラメータに加えて、次のものがあります。
    1. カスタム・イメージを指定しない場合でも、--node-image-idパラメータを含めます。
    2. --node-metadataオプション・パラメータを次の形式で含めます。
      --node-metadata '{"user_data": "'$(cat <cloud-init-file> | base64)'"}'
      ここでは:
      • <cloud-init-file>は、作成したcloud-initファイルの名前です。
      • base64は、ファイルがbase64エンコードされることを指定します

      例:

      --node-metadata '{"user_data": "'$(cat my-custom-cloud-init.yaml | base64)'"}'

このサンプル・コマンドは、既存のクラスタ用にmy-cloud-init-test-nodepoolという新しいノード・プールを作成し、Oracle Linuxを実行しているVM 2.1シェイプを持つ単一のKubernetes 1.18.10ノードを使用します。新しいノード・プールでワーカー・ノードをホストしているインスタンスが初めて起動すると、my-custom-cloud-init.yamlというカスタムcloud-initスクリプトが実行されます。

oci ce node-pool create \
--cluster-id ocid1.cluster.oc1.iad.aaaa______m4w \
--name my-cloud-init-test-nodepool \
--node-image-id ocid1.image.oc1.iad.aaaa______zpq \
--compartment-id ocid1.tenancy.oc1..aaa______q4a \
--kubernetes-version v1.18.10 \
--node-shape VM.Standard2.1 \
--placement-configs "[   { \"availabilityDomain\": \"PKGK:US-ASHBURN-AD-1\", \"subnetId\": \"ocid1.subnet.oc1.iad.aaaa______kfa\"   }   ]" \
--size 1 \
--region us-ashburn-1 \
--node-metadata '{"user_data": "'$(cat my-custom-cloud-init.yaml | base64)'"}'