taxin's notes

読書、勉強メモ etc.

Kubernetes the hard way (GCP版) #3 (コンピューティングリソースのプロビジョニング)

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

前回の記事はこちら。 taxintt.hatenablog.com

Chap3. Provisioning Compute Resources(コンピューティングリソースのプロビジョニング)

このチャプターでは、コンピューティングリソース(=クラスタで利用するノード)のプロビジョニングを行います。

ネットワークの作成

最初に、今回作成するクラスタを作成するVPCを作成します
サブネットモードとしてcustomを指定することで、サブネットとサブネットのCIDRブロック(=IPの範囲)をユーザーが任意で設定することができます。

(参考)サブネットモードについて

cloud.google.com

> gcloud compute networks create kubernetes-the-hard-way --subnet-mode custom                                                                                     

...

Created [https://www.googleapis.com/compute/v1/projects/k8s-hardway-20200229/global/networks/kubernetes-the-hard-way].
NAME                     SUBNET_MODE  BGP_ROUTING_MODE  IPV4_RANGE  GATEWAY_IPV4
kubernetes-the-hard-way  CUSTOM       REGIONAL

Instances on this network will not be reachable until firewall rules
are created. As an example, you can allow all internal traffic between
instances as well as SSH, RDP, and ICMP by running:

$ gcloud compute firewall-rules create <FIREWALL_NAME> --network kubernetes-the-hard-way --allow tcp,udp,icmp --source-ranges <IP_RANGE>
$ gcloud compute firewall-rules create <FIREWALL_NAME> --network kubernetes-the-hard-way --allow tcp:22,tcp:3389,icmp


次に、VPCの中でサブネットを作成して、サブネットのCIDRブロックとして10.240.0.0/24を設定します。
/24なので256個分のIPアドレス枠がありますが、予約済みのアドレスとして4つ確保されているため残り252個分のIPアドレスを利用することが可能です。

(参考)予約済みIPアドレスについて

cloud.google.com

> gcloud compute networks subnets create kubernetes \
  --network kubernetes-the-hard-way \
  --range 10.240.0.0/24
Created [https://www.googleapis.com/compute/v1/projects/k8s-hardway-20200229/regions/us-west1/subnetworks/kubernetes].
NAME        REGION    NETWORK                  RANGE
kubernetes  us-west1  kubernetes-the-hard-way  10.240.0.0/24

続いて、作成したVPCに対してFirewall Ruleの設定を行います
--networkを用いてルールを設定するVPCを指定し、--allow--source-rangesを用いて許可する通信プロトコルと通信元のIPアドレスを設定します。

> gcloud compute firewall-rules create kubernetes-the-hard-way-allow-internal \
  --allow tcp,udp,icmp \
  --network kubernetes-the-hard-way \
  --source-ranges 10.240.0.0/24,10.200.0.0/16
Creating firewall...⠧Created [https://www.googleapis.com/compute/v1/projects/k8s-hardway-20200229/global/firewalls/kubernetes-the-hard-way-allow-internal].
Creating firewall...done.
NAME                                    NETWORK                  DIRECTION  PRIORITY  ALLOW         DENY  DISABLED
kubernetes-the-hard-way-allow-internal  kubernetes-the-hard-way  INGRESS    1000      tcp,udp,icmp        False

> gcloud compute firewall-rules create kubernetes-the-hard-way-allow-external \
  --allow tcp:22,tcp:6443,icmp \
  --network kubernetes-the-hard-way \
  --source-ranges 0.0.0.0/0
Creating firewall...⠶Created [https://www.googleapis.com/compute/v1/projects/k8s-hardway-20200229/global/firewalls/kubernetes-the-hard-way-allow-external].
Creating firewall...done.
NAME                                    NETWORK                  DIRECTION  PRIORITY  ALLOW                 DENY  DISABLED
kubernetes-the-hard-way-allow-external  kubernetes-the-hard-way  INGRESS    1000      tcp:22,tcp:6443,icmp        False

(+α) GCPFirewall ruleに対する補足

AWSでは、GCPFirewall ruleと同じようなものとしてSecurity Group(インスタンスレベル)やNetwork ACL(サブネットレベル)があります。
GCPFirewall ruleは下記の特徴を有しています。

  • ステートフルなFirewall(=戻りの通信は自動的に許可されるFirewall)
  • Allow/Denyの両方のルールを設定できる
  • ルールに対して優先度を設定できる

このハンズオンではVPC全体を指定する形でFirewall Ruleを定義しています。
要件によっては、インスタンスレベルで通信をフィルタリングしたい場面もあるかと思います。
GCPFirewall ruleでは、--target-tagsを用いて特定のインスタンス(タグ)を指定することでSecurity Groupのようなインスタンス単位でルールを設定できるようです。

(参考)--target-tagsを用いたFirewall Rule cloud.google.com

また、デフォルトのFirewall Ruleに関しては、リンク先に記載されている4つのルールが設定されています。
ルールとしてコンソールなどで表示されてはいませんが、Outbound通信はDefault Allow、Inbound通信はDefault Denyであることも把握しておく必要があります。

(参考)デフォルトのFirewall Ruleについて cloud.google.com

IPアドレスの払い出し

次に、API Serverの外部公開用のIPアドレスを払い出します。 このIPアドレスは、API Serverの前段に配置されるロードバランサーの固定IPとして利用されます。

~/Downloads ❯❯❯ gcloud compute addresses create kubernetes-the-hard-way \
  --region $(gcloud config get-value compute/region)
Created [https://www.googleapis.com/compute/v1/projects/k8s-hardway-20200229/regions/us-west1/addresses/kubernetes-the-hard-way].

~/Downloads ❯❯❯ gcloud compute addresses list --filter="name=('kubernetes-the-hard-way')"
NAME                     ADDRESS/RANGE  TYPE      PURPOSE  NETWORK  REGION    SUBNET  STATUS
kubernetes-the-hard-way  35.233.237.51  EXTERNAL                    us-west1          RESERVED

インスタンス(ノード)の作成

クラスタを構成するControl PlaneとWorkerをそれぞれ作成します。
今回は、HA構成のクラスタを作成するため、下記のような構成で作成します。

  • Control Plane:3
  • Worker Node:3
for i in 0 1 2; do
gcloud compute instances create controller-${i} \
    --async \
    --boot-disk-size 200GB \
    --can-ip-forward \
    --image-family ubuntu-1804-lts \
    --image-project ubuntu-os-cloud \
    --machine-type n1-standard-1 \
    --private-network-ip 10.240.0.1${i} \
    --scopes compute-rw,storage-ro,service-management,service-control,logging-write,monitoring \
    --subnet kubernetes \
    --tags kubernetes-the-hard-way,controller
done

Worker Nodeの作成時には--metadataで、各Nodeでデプロイ可能なpodのCIDRブロック(IPアドレスの範囲)を設定します。
設定したメタデータはCNIを用いたネットワーク周りの設定時に利用されます。

for i in 0 1 2; do
  gcloud compute instances create worker-${i} \
    --async \
    --boot-disk-size 200GB \
    --can-ip-forward \
    --image-family ubuntu-1804-lts \
    --image-project ubuntu-os-cloud \
    --machine-type n1-standard-1 \
    --metadata pod-cidr=10.200.${i}.0/24 \
    --private-network-ip 10.240.0.2${i} \
    --scopes compute-rw,storage-ro,service-management,service-control,logging-write,monitoring \
    --subnet kubernetes \
    --tags kubernetes-the-hard-way,worker
done

SSHアクセスの設定

インスタンスの作成が完了したら、作成したインスタンスSSHでのアクセスを試みます。
内部的にはGCP用のSSH keyの有無がチェックされて、保持していなければSSH Key-pairの生成を行いGCPに公開鍵を送信するということが行われています。

> gcloud compute ssh controller-0
WARNING: The public SSH key file for gcloud does not exist.
WARNING: The private SSH key file for gcloud does not exist.
WARNING: You do not have an SSH key for gcloud.
WARNING: SSH keygen will be executed to generate a key.
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/...(省略).../.ssh/google_compute_engine.
Your public key has been saved in /Users/...(省略).../.ssh/google_compute_engine.pub.
The key fingerprint is:

...(省略)...

Updating project ssh metadata...⠼
Updated [https://www.googleapis.com/compute/v1/projects/<project_name>].
Updating project ssh metadata...done.
Waiting for SSH key to propagate.

Updating project ssh metadataというメッセージから想像がつくかと思いますが、生成したsshの公開鍵はプロジェクトレベルで共有されます。

そのため、1台目のインスタンスSSHでのアクセスが成功すると、同じパスワードを用いて他のインスタンスにもSSH接続が可能となります。

cloud.google.com

(+α) SSH keyの共有について

今回のハンズオンでは、全てのインスタンスで公開鍵を共有していますが、インスタンス個別の公開鍵を利用することも可能です。
その場合は、プロジェクト全体の公開 SSH 認証鍵をブロックした上でインスタンス レベルの公開 SSH 認証鍵を追加する必要があります。

(参考)プロジェクト全体の公開 SSH 認証鍵の使用について cloud.google.com

今回は、Chap3の内容をまとめました。
ハンズオンの手順的には難しい箇所は特にありませんが、Firewall RuleやSSHの鍵の扱いなどNWやセキュリティの観点で重要な内容なので正確に理解することを心がけたいと思います。