taxin's notes

読書、勉強メモ etc.

Kubernetes the hard way (GCP版) #8 (Kubernetesコントロールプレーンのブートストラップ)

Kubernetes the hard way (GCP版)の続きです。

前回の記事はこちら

taxintt.hatenablog.com

Chap8. Bootstrapping the Kubernetes Control Plane(コントロールプレーンのブートストラップ)

このチャプターでは、Control Planeのブートストラップを行います。
Control PlaneのコンポーネントであるAPI Server・Controller Manager・Schedulerの設定を行い、サービスとして起動します。
Control PlaneはHA構成なので3つのインスタンスで同じ作業を行います。

Control Plane用のバイナリーのダウンロードとインストール

最初にconfigファイル用のディレクトリを作成します。
この後の手順で作成されるconfigファイルはこのディレクトリに配置されます。

...@controller-0:~$ sudo mkdir -p /etc/kubernetes/config


次にControl Planeを構成するコンポーネントのバイナリーをダウンロードします。
ダウンロードしたバイナリーは/usr/local/bin/に配置します。

...@controller-0:~$ wget -q --show-progress --https-only --timestamping \
>   "https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kube-apiserver" \
>   "https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kube-controller-manager" \
>   "https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kube-scheduler" \
>   "https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kubectl"
kube-apiserver                                 100%[=================================================================================================>] 156.90M   203MB/s    in 0.8s
kube-controller-manager                        100%[=================================================================================================>] 111.03M   173MB/s    in 0.6s
kube-scheduler                                 100%[=================================================================================================>]  36.99M  99.8MB/s    in 0.4s
kubectl                                        100%[=================================================================================================>]  40.99M   118MB/s    in 0.3s
...@controller-0:~$ {
>   chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl
>   sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/
> }


Kubernetes API Serverの設定

ここからは各コンポーネントの設定を行っていきます。
API Serverの設定を行う前に/var/lib/kubernetes/ディレクトリを作成して、そのディレクトリに各種証明書ファイルとetcdの暗号化用の設定ファイル(encryption-config.yaml)を配置します。

...@controller-0:~$ {
>   sudo mkdir -p /var/lib/kubernetes/
>
>   sudo mv ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \
>     service-account-key.pem service-account.pem \
>     encryption-config.yaml /var/lib/kubernetes/
> }


インスタンスのPrivate IPアドレスINTERNAL_IPとして取得し、API Serverのサービスファイルを作成します。
サービスファイルでは、下記のような項目が設定されています。

  • --authorization-mode: 利用する認可モジュール
  • --enable-admission-plugins: 利用するAdmission Controlモジュール

クライアントからのAPIリクエストに対して、API Serverは認証→認可→Admission Controlの順にクライアントの認証認可とリクエストの妥当性検証を行います。
上記のチェックを行なった上で許可された処理が実行されます。


認可モジュールに関しては、下記の項目が設定されています。
認可モジュールは複数のモジュールを指定でき、先に指定したモジュール(この場合はNodeモジュール)が処理の順番として優先されます。

  • Node: kubeletからのリクエストを認可するためのモジュール
  • RBAC: Role/ClusterRoleなどのリソースを用いて定義されたRBACのルールを利用して認可を行うためのモジュール

試せてはいないのですが、外部サービスへの問い合わせ結果を基に権限認可を行うWebhookモジュールも存在します。

tech.jxpress.net


また、Admission Controlモジュールに関しては、下記の項目が設定されています。
リソースの定義内の項目 (e.g. Namespaceの指定, リソースの使用量)に関連したものが多く、不正リクエストの実行を防止します。

  • NamespaceLifecycle: 存在しないNamespaceを利用したリソース作成の制限やシステム側で予約しているNamespaceの削除防止などを行う
  • NodeRestriction: kubeletによるNodeとpodの操作を制限する
  • LimitRanger: Namespaceに設定したLimitRange (podごとに適用されるリソースの使用量制限) に準拠しているかを検証する
  • ServiceAccount: ServiceAccountが設定されていないpodにDefaultServiceAccountを設定するなどの処理の自動化を行う
  • DefaultStorageClass: StorageClassが未指定のPVCリソースの作成時にDefaultStorageClassを指定する
  • ResourceQuota: ResourceQuota (Namespaceに対して利用可能なリソース量) に準拠しているかを検証する

この部分に関しては、下記の記事や最近発売された「Docker/Kubernetes 開発・運用のためのセキュリティ実践ガイド」にも詳しく記載されています。

knowledge.sakura.ad.jp

Amazon CAPTCHA

...@controller-0:~$ INTERNAL_IP=$(curl -s -H "Metadata-Flavor: Google" \
>   http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip)
...@controller-0:~$ echo $INTERNAL_IP
10.240.0.10
...@controller-0:~$ cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service
> [Unit]
> Description=Kubernetes API Server
> Documentation=https://github.com/kubernetes/kubernetes
>
> [Service]
> ExecStart=/usr/local/bin/kube-apiserver \\
>   --advertise-address=${INTERNAL_IP} \\
>   --allow-privileged=true \\
>   --apiserver-count=3 \\
>   --audit-log-maxage=30 \\
>   --audit-log-maxbackup=3 \\
>   --audit-log-maxsize=100 \\
>   --audit-log-path=/var/log/audit.log \\
>   --authorization-mode=Node,RBAC \\
>   --bind-address=0.0.0.0 \\
>   --client-ca-file=/var/lib/kubernetes/ca.pem \\
>   --enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
>   --etcd-cafile=/var/lib/kubernetes/ca.pem \\
>   --etcd-certfile=/var/lib/kubernetes/kubernetes.pem \\
>   --etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \\
>   --etcd-servers=https://10.240.0.10:2379,https://10.240.0.11:2379,https://10.240.0.12:2379 \\
>   --event-ttl=1h \\
>   --encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\
>   --kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\
>   --kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \\
>   --kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \\
>   --kubelet-https=true \\
>   --runtime-config=api/all \\
>   --service-account-key-file=/var/lib/kubernetes/service-account.pem \\
>   --service-cluster-ip-range=10.32.0.0/24 \\
>   --service-node-port-range=30000-32767 \\
>   --tls-cert-file=/var/lib/kubernetes/kubernetes.pem \\
>   --tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \\
>   --v=2
> Restart=on-failure
> RestartSec=5
>
> [Install]
> WantedBy=multi-user.target
> EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-apiserver \
  --advertise-address=10.240.0.10 \
   ...
  --tls-cert-file=/var/lib/kubernetes/kubernetes.pem \
  --tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target


Kubernetes Controller Managerの設定

次に、Controller Managerの設定を行います。
API Server同様に必要な設定ファイルを/var/lib/kubernetes/に配置して、Controller Managerのサービスファイルを作成します。

サービスファイルでは、下記のような項目が設定されています。

  • --leader-elect: HA構成の場合にリーダーを選出するかどうかを指定するフラグ
  • --service-account-private-key-file: ServiceAccountの秘密鍵ファイル
  • --use-service-account-credentials: Controller毎にServiceAccount用のCredentialsを利用するかどうかを指定するフラグ

Controller Managerの起動時に--use-service-account-credentialsを指定して起動することで、Managerで管理される各ControllerはServiceAccount用のCredentials(トークン)を利用します。
(Credentialsの作成に必要な鍵ファイルはChap4ですでに作成済みなので、上記のフラグで指定することで鍵ファイルを基にトークンが生成されると考えられます。)

taxintt.hatenablog.com

...@controller-0:~$ sudo mv kube-controller-manager.kubeconfig /var/lib/kubernetes/
...@controller-0:~$ cat <<EOF | sudo tee /etc/systemd/system/kube-controller-manager.service
> [Unit]
> Description=Kubernetes Controller Manager
> Documentation=https://github.com/kubernetes/kubernetes
>
> [Service]
> ExecStart=/usr/local/bin/kube-controller-manager \\
>   --address=0.0.0.0 \\
>   --cluster-cidr=10.200.0.0/16 \\
>   --cluster-name=kubernetes \\
>   --cluster-signing-cert-file=/var/lib/kubernetes/ca.pem \\
>   --cluster-signing-key-file=/var/lib/kubernetes/ca-key.pem \\
>   --kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \\
>   --leader-elect=true \\
>   --root-ca-file=/var/lib/kubernetes/ca.pem \\
>   --service-account-private-key-file=/var/lib/kubernetes/service-account-key.pem \\
>   --service-cluster-ip-range=10.32.0.0/24 \\
>   --use-service-account-credentials=true \\
>   --v=2
> Restart=on-failure
> RestartSec=5
>
> [Install]
> WantedBy=multi-user.target
> EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-controller-manager \
  --address=0.0.0.0 \
  --cluster-cidr=10.200.0.0/16 \
  --cluster-name=kubernetes \
  --cluster-signing-cert-file=/var/lib/kubernetes/ca.pem \
  --cluster-signing-key-file=/var/lib/kubernetes/ca-key.pem \
  --kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \
  --leader-elect=true \
  --root-ca-file=/var/lib/kubernetes/ca.pem \
  --service-account-private-key-file=/var/lib/kubernetes/service-account-key.pem \
  --service-cluster-ip-range=10.32.0.0/24 \
  --use-service-account-credentials=true \
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target


Kubernetes Schedulerの設定

同様に、Schedulerの設定を行います。
ここでは、kube-scheduler.yamlというscheduler用の設定ファイルを作成した上でサービスファイルを作成します。

...@controller-0:~$ sudo mv kube-scheduler.kubeconfig /var/lib/kubernetes/
...@controller-0:~$ cat <<EOF | sudo tee /etc/kubernetes/config/kube-scheduler.yaml
> apiVersion: kubescheduler.config.k8s.io/v1alpha1
> kind: KubeSchedulerConfiguration
> clientConnection:
>   kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig"
> leaderElection:
>   leaderElect: true
> EOF
apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
clientConnection:
  kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig"
leaderElection:
  leaderElect: true
nishikawatakushi@controller-0:~$ ls
admin.kubeconfig  etcd-v3.4.0-linux-amd64  etcd-v3.4.0-linux-amd64.tar.gz

nishikawatakushi@controller-0:~$ cat <<EOF | sudo tee /etc/systemd/system/kube-scheduler.service
> [Unit]
> Description=Kubernetes Scheduler
> Documentation=https://github.com/kubernetes/kubernetes
>
> [Service]
> ExecStart=/usr/local/bin/kube-scheduler \\
>   --config=/etc/kubernetes/config/kube-scheduler.yaml \\
>   --v=2
> Restart=on-failure
> RestartSec=5
>
> [Install]
> WantedBy=multi-user.target
> EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-scheduler \
  --config=/etc/kubernetes/config/kube-scheduler.yaml \
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target


Control Plane用のサービス起動

サービスファイルの作成が完了した段階で、Control Plane用のサービス (kube-apiserver, kube-controller-manager, kube-scheduler) を起動します。
手順にはありませんが、systemctl status <service_name>でサービスの起動を確認したり、journalctl -u <service_name>でログを確認するのも面白いと思います。

qiita.com

...@controller-0:~$ {
>   sudo systemctl daemon-reload
>   sudo systemctl enable kube-apiserver kube-controller-manager kube-scheduler
>   sudo systemctl start kube-apiserver kube-controller-manager kube-scheduler
> }
Created symlink /etc/systemd/system/multi-user.target.wants/kube-apiserver.service → /etc/systemd/system/kube-apiserver.service.
Created symlink /etc/systemd/system/multi-user.target.wants/kube-controller-manager.service → /etc/systemd/system/kube-controller-manager.service.
Created symlink /etc/systemd/system/multi-user.target.wants/kube-scheduler.service → /etc/systemd/system/kube-scheduler.service.

...@controller-0:~$ systemctl status kube-apiserver
● kube-apiserver.service - Kubernetes API Server
   Loaded: loaded (/etc/systemd/system/kube-apiserver.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2020-02-29 04:27:20 UTC; 16s ago
     Docs: https://github.com/kubernetes/kubernetes
 Main PID: 4205 (kube-apiserver)
    Tasks: 8 (limit: 4394)
   CGroup: /system.slice/kube-apiserver.service
           └─4205 /usr/local/bin/kube-apiserver --advertise-address=10.240.0.10 --allow-privileged=true --apiserver-count=3 --audit-log-maxage=30 --audit-log-maxbackup=3 --audit-log-max

Feb 29 04:27:32 controller-0 kube-apiserver[4205]: [+]poststarthook/start-kube-aggregator-informers ok
Feb 29 04:27:32 controller-0 kube-apiserver[4205]: [+]poststarthook/apiservice-registration-controller ok
Feb 29 04:27:32 controller-0 kube-apiserver[4205]: [+]poststarthook/apiservice-status-available-controller ok
Feb 29 04:27:32 controller-0 kube-apiserver[4205]: [+]poststarthook/apiservice-openapi-controller ok
Feb 29 04:27:32 controller-0 kube-apiserver[4205]: [+]poststarthook/kube-apiserver-autoregistration ok
Feb 29 04:27:32 controller-0 kube-apiserver[4205]: [+]autoregister-completion ok
Feb 29 04:27:32 controller-0 kube-apiserver[4205]: healthz check failed
Feb 29 04:27:32 controller-0 kube-apiserver[4205]: I0229 04:27:32.410648    4205 controller.go:606] quota admission added evaluator for: endpoints
Feb 29 04:27:32 controller-0 kube-apiserver[4205]: W0229 04:27:32.428474    4205 lease.go:223] Resetting endpoints for master service "kubernetes" to [10.240.0.10]


HTTPヘルスチェックの有効化

サービスを起動したら、各Control Plane用のインスタンスにHTTPエンドポイント用のnginxを導入します。
(この部分に関しては日本語訳のページを見た方が、手順の意図がわかりやすいかと思います。)

github.com

API Serverはサービスの起動時に、HTTPSのエンドポイントを用意します。
しかし、今回の構成では前段に存在するLBがTLS終端となってしまい、API ServerのendpointにはHTTPでの通信のみ可能となるという状況になります。

そのため、今回はnginxをproxyとして利用し、ヘルスチェックのリクエスト (HTTP) をAPI ServerのEndpoint (HTTPS) に中継します。
プロキシの設定では下記の項目を設定します。

  • proxy_pass: 転送先のパス
  • proxy_ssl_trusted_certificate: プロキシサーバの証明書検証のために利用されるCA証明書

nginxのconfファイル内でproxy_ssl_certificateのように利用するTLS証明書を指定しなくてもいいのか...?という疑問は個人的に残っています。
(これに関しては、後日追記予定)

...@controller-0:~$ cat > kubernetes.default.svc.cluster.local <<EOF
> server {
>   listen      80;
>   server_name kubernetes.default.svc.cluster.local;
>
>   location /healthz {
>      proxy_pass                    https://127.0.0.1:6443/healthz;
>      proxy_ssl_trusted_certificate /var/lib/kubernetes/ca.pem;
>   }
> }
> EOF
...@controller-0:~$ {
>   sudo mv kubernetes.default.svc.cluster.local \
>     /etc/nginx/sites-available/kubernetes.default.svc.cluster.local
>
>   sudo ln -s /etc/nginx/sites-available/kubernetes.default.svc.cluster.local /etc/nginx/sites-enabled/
> }
...@controller-0:~$ sudo systemctl restart nginx
...@controller-0:~$ sudo systemctl enable nginx
Synchronizing state of nginx.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable nginx


検証1

HTTPエンドポイントの設定が完了したら、Control Planeの検証を行います。
最初にインスタンス内でadminユーザー用のconfigファイルを利用して、Control Planeのコンポーネントのステータスチェックを行います。

...@controller-0:~$ kubectl get componentstatuses --kubeconfig admin.kubeconfig
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok
controller-manager   Healthy   ok
etcd-2               Healthy   {"health":"true"}
etcd-0               Healthy   {"health":"true"}
etcd-1               Healthy   {"health":"true"}


次に、ヘルスチェックのリクエスト(HTTP)をnginxが指定のエンドポイントに中継しているかを確認します。
curlAPI Serverに対してリクエストを投げる際には、ホストヘッダーを指定します。
(これによって、kubernetes.default.svc.cluster.local (= API Serverのサービス名?) に対するリクエストの結果が返却されます。)

gihyo.jp

ここで実行している/healthzのHTTPリクエストの実態は、Kubernetesで利用できるヘルスチェックの内の一つであるLiveness Probeです。
ヘルスチェックによってpodの生死を確認することが可能です。

別のヘルスチェックとしてpodがリクエストを受け入れられるかを確認するReadiness Probeというものも存在します。

www.ianlewis.org

...@controller-0:~$ curl -H "Host: kubernetes.default.svc.cluster.local" -i http://127.0.0.1/healthz
HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Sat, 29 Feb 2020 04:45:44 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 2
Connection: keep-alive
X-Content-Type-Options: nosniff


RBACを使ったKubeletの認可

次に、API Serverに関連してRBACの設定を行います。
API Server (Control Plane) から Kubelet (Worker Node) に対してアクセスできるようにするために、ClusterRole / ClusterRoleBindingを作成します。

system:kube-apiserver-to-kubeletという名前のClusterRoleには、Kubeletに対する基本的な処理を実行するための権限を付与します。

...@controller-0:~$ cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -
> apiVersion: rbac.authorization.k8s.io/v1beta1
> kind: ClusterRole
> metadata:
>   annotations:
>     rbac.authorization.kubernetes.io/autoupdate: "true"
>   labels:
>     kubernetes.io/bootstrapping: rbac-defaults
>   name: system:kube-apiserver-to-kubelet
> rules:
>   - apiGroups:
>       - ""
>     resources:
>       - nodes/proxy
>       - nodes/stats
>       - nodes/log
>       - nodes/spec
>       - nodes/metrics
>     verbs:
>       - "*"
> EOF
clusterrole.rbac.authorization.k8s.io/system:kube-apiserver-to-kubelet created


作成したClusterRoleはkubernetesユーザーに紐づけられます。
これにより、API Serverは--kubelet-client-certificateで指定されたクライアント証明書を利用してkubeletに認証を行います。

...@controller-0:~$ cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -
> apiVersion: rbac.authorization.k8s.io/v1beta1
> kind: ClusterRoleBinding
> metadata:
>   name: system:kube-apiserver
>   namespace: ""
> roleRef:
>   apiGroup: rbac.authorization.k8s.io
>   kind: ClusterRole
>   name: system:kube-apiserver-to-kubelet
> subjects:
>   - apiGroup: rbac.authorization.k8s.io
>     kind: User
>     name: kubernetes
> EOF
clusterrolebinding.rbac.authorization.k8s.io/system:kube-apiserver created


ネットワークロードバランサーのプロビジョニング

最後にAPI Serverの前段に配置するLoad Balancerを作成します。
(個々のコマンドを説明していると長くなってしまうので設定項目などの詳細については、この記事の下部にまとめます。)

{
  KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
    --region $(gcloud config get-value compute/region) \
    --format 'value(address)')

  gcloud compute http-health-checks create kubernetes \
    --description "Kubernetes Health Check" \
    --host "kubernetes.default.svc.cluster.local" \
    --request-path "/healthz"

  gcloud compute firewall-rules create kubernetes-the-hard-way-allow-health-check \
    --network kubernetes-the-hard-way \
    --source-ranges 209.85.152.0/22,209.85.204.0/22,35.191.0.0/16 \
    --allow tcp

  gcloud compute target-pools create kubernetes-target-pool \
    --http-health-check kubernetes

  gcloud compute target-pools add-instances kubernetes-target-pool \
   --instances controller-0,controller-1,controller-2

  gcloud compute forwarding-rules create kubernetes-forwarding-rule \
    --address ${KUBERNETES_PUBLIC_ADDRESS} \
    --ports 6443 \
    --region $(gcloud config get-value compute/region) \
    --target-pool kubernetes-target-pool
}


検証2

Load Balancer (LB) の作成・設定が正常に行われたかを確認するために、LB経由でAPI Requestを実行します。
curlコマンドでCA証明書を指定した上でLoad Balancerが持つPublic IPアドレスクラスタのバージョンを確認するリクエストを投げます。

json形式のresponseが返ってきたら検証成功となります。

~/w/k/h/04 ❯❯❯ KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
  --region $(gcloud config get-value compute/region) \
  --format 'value(address)')

~/w/k/h/04 ❯❯❯ curl --cacert ca.pem https://${KUBERNETES_PUBLIC_ADDRESS}:6443/version
{
  "major": "1",
  "minor": "15",
  "gitVersion": "v1.15.3",
  "gitCommit": "2d3c76f9091b6bec110a5e63777c332469e0cba2",
  "gitTreeState": "clean",
  "buildDate": "2019-08-19T11:05:50Z",
  "goVersion": "go1.12.9",
  "compiler": "gc",
  "platform": "linux/amd64"
}%


(+α) GCPロードバランサーの設定

GCPの勉強がてら、手順の中で実施したロードバランサーの作成手順についても順を追って説明を記載していきます。

Hard wayの手順の中ではロードバランシングを構成する複数のコンポーネントを作成することでロードバランサーを構築します。
AWSのようにリソースとしてロードバランサーを作成する方法ではありません。

下記のコンポーネントの作成・設定によって、ロードバランシングを実現します。

  • バックエンドの設定
  • ホストとパスのルール
  • フロンドエンドの設定

上記のコンポーネントと作業手順を対応させると下記のようになります。

  • バックエンドの設定 → ターゲットプールの作成
  • ホストとパスのルール → フォワーディングルールの作成
  • フロンドエンドの設定 → Public IPアドレスの設定


ここからは実際のコマンドの説明をしていきます。 Public IPアドレスを取得した後に、HTTPのヘルスチェックルールを作成 (gcloud compute http-health-checks create) します。

  • --host: ヘルスチェックの対象となるホスト名 (kubernetes.default.svc.cluster.local)
  • --request-path: ヘルスチェックのパス (/healthz)
  gcloud compute http-health-checks create kubernetes \
    --description "Kubernetes Health Check" \
    --host "kubernetes.default.svc.cluster.local" \
    --request-path "/healthz"


次にFirewallルールを作成 (gcloud compute firewall-rules create) して、インスタンスが属するNetworkに対してLoad Balancerからのヘルスチェックを許可します。

ヘルスチェックのソースIPアドレスの範囲は下記に記載されています。

cloud.google.com

  gcloud compute firewall-rules create kubernetes-the-hard-way-allow-health-check \
    --network kubernetes-the-hard-way \
    --source-ranges 209.85.152.0/22, 209.85.204.0/22, 35.191.0.0/16 \
    --allow tcp


最後に、リクエスト転送先の管理単位であるターゲットプールを作成 (gcloud compute target-pools create / add-instances) します。
その上で、作成したプールにリクエストを転送するようにフォワーディングルールを作成します。

最終的には--address / --portsで指定したIPアドレス(ポート)に対するリクエストをターゲットプールに転送するような処理になります。

cloud.google.com

  KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
    --region $(gcloud config get-value compute/region) \
    --format 'value(address)')
  
  ~~~~~

  gcloud compute target-pools create kubernetes-target-pool \
    --http-health-check kubernetes

  gcloud compute target-pools add-instances kubernetes-target-pool \
   --instances controller-0,controller-1,controller-2

  gcloud compute forwarding-rules create kubernetes-forwarding-rule \
    --address ${KUBERNETES_PUBLIC_ADDRESS} \
    --ports 6443 \
    --region $(gcloud config get-value compute/region) \
    --target-pool kubernetes-target-pool


今回は、Chap8の内容をまとめました。
Control Planeのブートストラップの手順では証明書ファイルの指定やRBACの設定など各コンポーネント間が正常に通信して動作するために必要な設定がされています。

次回のWorker Nodeのブートストラップのチャプターと合わせて、クラスタの全体像をきちんと理解しようと思います。