TT Lab
はじめる
学ぶ 学習パス コース

Kubespray と Terraform でクラスターを構築する

アドオンは group_vars のスイッチ。有効にしたら動作を確かめる

TT Labで続きを見る

目標

インストール前にgroup_varsでmetrics-server・local-path-provisioner・Helmを有効にし、インストール後にそれぞれが実際に動作するかを確認します。-eがブール値を文字列として渡す落とし穴と、デフォルトのネットワークプラグインのcalicoがどんなカプセル化で動いているかも見ます。

なぜ重要なのか

kubesprayでは、アドオンは変数1つです。そのため、有効にするのは簡単で、有効にしたという事実と動作するという事実が、混ざりやすいです。metrics-serverは起動していても、APIServiceがAvailableでなければHPAが止まり、StorageClassはあってもPVCがノードのディスクに結び付かなければ、ステートフルなアプリが起動しません。 ネットワークプラグインは、インストール後に変更するのが最も難しい選択なので、何がデフォルトで、そのデフォルトがどんなネットワーク条件を要求するかを知って選ぶ必要があります。

ステップ

  1. metrics_server_enabled、local_path_provisioner_enabled、helm_enabledを、すべてtrueに変更してください(対象: /root/ks/inventory/lab/group_vars/k8s_cluster/addons.yml)。ansible-inventory --host node1で展開したとき、3つの値が文字列ではなくブール値のtrueである必要があります。
  2. /opt/ks/kubesprayで、ansible-playbook -i /root/ks/inventory/lab/inventory.ini playbooks/boilerplate.yml -e helm_enabled=trueと-e '{"helm_enabled": true}'をそれぞれ実行してみてください。次のフィールドを書いてください(書き込み先: /root/ks/addons/string-trap.json)。kv_failed_task(最初のコマンドが失敗したタスク名、ロールの接頭辞なし)、kv_type(最初のコマンドでhelm_enabledになった型: "str"または"bool")、json_passed(2番目のコマンドがfailed=0で終わったか、ブール値)です。
  3. /opt/ks/kubesprayでansible-playbook -i /root/ks/inventory/lab/inventory.ini cluster.ymlを実行して、出力の全体を残してください(約8分、保存先: /root/ks/logs/cluster-1.log)。PLAY RECAPのnode1がfailed=0である必要があります。
  4. kubectl top nodeがnode1のCPUとメモリを表示するまで待ってから、次のフィールドを書いてください(書き込み先: /root/ks/addons/metrics.json)。apiservice_available(APIServicev1beta1.metrics.k8s.ioのAvailable条件のstatus)、image(metrics-server Deploymentのコンテナイメージ)、insecure_tls(metrics-serverが--kubelet-insecure-tls引数で起動しているか、ブール値)です。
  5. defaultネームスペースにPVCdata(storageClassNameはlocal-path、64Mi、ReadWriteOnce)と、それを/dataにマウントしたPodwriter(イメージはbusybox:latest、コマンドはsh -c 'echo kubespray > /data/hello.txt && sleep 3600')を作成してください。PVCがBoundになり、ノードのlocal-pathのストレージパスの下のそのボリュームのディレクトリに、hello.txtがkubesprayとしてある必要があります。
  6. helm create /root/ks/addons/demoでチャートを作成し、helm install demo /root/ks/addons/demo -n demo --create-namespace --waitでインストールしてください。リリースdemoがdeployedで、PodがReadyである必要があります。次のフィールドを書いてください(書き込み先: /root/ks/addons/helm.json)。helm_version(helm version --template '{{.Version}}')、kubespray_helm_version(このkubesprayのバージョンのデフォルトのhelm_version、先頭にvを付けて)です。
  7. 次のフィールドを書いてください(書き込み先: /root/ks/addons/cni.json)。plugin(インベントリが展開したkube_network_plugin)、calico_version(calico-node DaemonSetのcalico-nodeコンテナのイメージタグ)、vxlan_mode、ipip_mode(calicoctl.sh get ippool default-pool -o jsonのspecの値)、pool_cidr(そのIPプールのcidr)です。

参考

アドオンはインストール前に選ぶ

metrics_server_enabled、local_path_provisioner_enabled、helm_enabledを、すべてtrueに変更してください(対象: /root/ks/inventory/lab/group_vars/k8s_cluster/addons.yml)。ansible-inventory --host node1で展開したとき、3つの値が文字列ではなくブール値のtrueである必要があります。

サンプルのaddons.ymlには、3行がfalseで書かれています。YAMLでは、引用符のないtrueはブール値で、"true"は文字列です。ansible-inventoryのJSON出力では、両者はtrueと"true"で区別されます。

-eは文字列を渡す

/opt/ks/kubesprayで、ansible-playbook -i /root/ks/inventory/lab/inventory.ini playbooks/boilerplate.yml -e helm_enabled=trueと-e '{"helm_enabled": true}'をそれぞれ実行してみてください。次のフィールドを書いてください(書き込み先: /root/ks/addons/string-trap.json)。kv_failed_task(最初のコマンドが失敗したタスク名、ロールの接頭辞なし)、kv_type(最初のコマンドでhelm_enabledになった型: "str"または"bool")、json_passed(2番目のコマンドがfailed=0で終わったか、ブール値)です。

ansible-core 2.19から、条件式は必ずブール値である必要があり、-e key=valueは常に文字列を渡します。kubesprayは、いくつかの知られたブール値を、validate_inventoryで型として検査します。型は、ansible -i ... node1 -m debug -a 'msg={{{{ helm_enabled | type_debug }}}}' -e helm_enabled=trueで見られます。

アドオンと一緒に構築する

/opt/ks/kubesprayでansible-playbook -i /root/ks/inventory/lab/inventory.ini cluster.ymlを実行して、出力の全体を残してください(約8分、保存先: /root/ks/logs/cluster-1.log)。PLAY RECAPのnode1がfailed=0である必要があります。

アドオンは、cluster.ymlの最後のplay(Install Kubernetes apps)でインストールされます。すでに構築したクラスターなら、group_varsを変えた後に--tags appsやアドオンのタグ(metrics_serverなど)で、その部分だけを再実行することもできますが、ここでは最初から有効にして構築します。コンソールが切れても動き続けるように、systemd-runやtmuxで起動してください。

metrics-serverは本当に数値を出すか

kubectl top nodeがnode1のCPUとメモリを表示するまで待ってから、次のフィールドを書いてください(書き込み先: /root/ks/addons/metrics.json)。apiservice_available(APIServicev1beta1.metrics.k8s.ioのAvailable条件のstatus)、image(metrics-server Deploymentのコンテナイメージ)、insecure_tls(metrics-serverが--kubelet-insecure-tls引数で起動しているか、ブール値)です。

metrics-serverは、aggregation layerでAPIサーバーに接続されます。APIServiceがAvailableでなければ、kubectl topは「Metrics API not available」で失敗します。最初の数値が出るまでに数十秒かかります。kubesprayのデフォルト値(metrics_server_kubelet_insecure_tls: true)は、kubeletのサービング証明書を検証しないという意味なので、本番では、kubeletのサービング証明書を適切に発行する方向を検討する必要があります。

PVCがノードのディスクに結び付く

defaultネームスペースにPVCdata(storageClassNameはlocal-path、64Mi、ReadWriteOnce)と、それを/dataにマウントしたPodwriter(イメージはbusybox:latest、コマンドはsh -c 'echo kubespray > /data/hello.txt && sleep 3600')を作成してください。PVCがBoundになり、ノードのlocal-pathのストレージパスの下のそのボリュームのディレクトリに、hello.txtがkubesprayとしてある必要があります。

local-path-provisionerは、PVCを使うPodがスケジュールされるとき(WaitForFirstConsumer)、ノードのディスクにディレクトリを作ってPVとして渡します。PVのspec.hostPath.pathやspec.local.pathが、そのディレクトリです。busyboxはlocal-pathが使うヘルパーイメージなので、kubesprayがすでに取得してあります。

kubesprayがインストールしたHelmでリリースを1つ

helm create /root/ks/addons/demoでチャートを作成し、helm install demo /root/ks/addons/demo -n demo --create-namespace --waitでインストールしてください。リリースdemoがdeployedで、PodがReadyである必要があります。次のフィールドを書いてください(書き込み先: /root/ks/addons/helm.json)。helm_version(helm version --template '{{.Version}}')、kubespray_helm_version(このkubesprayのバージョンのデフォルトのhelm_version、先頭にvを付けて)です。

kubesprayのHelmは、get.helm.shからチェックサムで固定したバージョンを取得して、/usr/local/bin/helmに置きます。デフォルトのバージョンは、roles/kubespray_defaults/vars/main/checksums.ymlのhelm_archive_checksumsの最初のキーです。helm createが作ったチャートは、docker.ioのnginxイメージを使います。

calicoはどのように動いているか

次のフィールドを書いてください(書き込み先: /root/ks/addons/cni.json)。plugin(インベントリが展開したkube_network_plugin)、calico_version(calico-node DaemonSetのcalico-nodeコンテナのイメージタグ)、vxlan_mode、ipip_mode(calicoctl.sh get ippool default-pool -o jsonのspecの値)、pool_cidr(そのIPプールのcidr)です。

kubesprayは、calicoctlを/usr/local/bin/calicoctl.shとしてラップしてあります。デフォルトのIPプールは、kube_pods_subnetから作られ、カプセル化は、calico_vxlan_modeとcalico_ipip_modeの変数で決まります。VXLANはノード間のL3だけが通じればよく、IPIPはIPプロトコル4を通す必要があります。クラウドのファイアウォールが、判断を分けるポイントです。