LoginSignup
9
4

More than 5 years have passed since last update.

最強のマネージドNATサービス Cloud NATとGKEのセットアップ手順が公開されたので翻訳がてら動かしてみました

Posted at

Cloud NATが発表されて以降、心待ちにしていたGKEでのセットアップ方法がしれっと公式ドキュメントに追加されていました!!
(いつから公開されていたんでしょうね?自分が気付いてなかっただけとかいうオチもありえますが・・笑)

Example GKE Setup  |  Cloud NAT  |  Google Cloud

という訳で、このエントリーではドキュメントを翻訳しながら、実際にKubernetesクラスタを作成していきたいと思います!!ちなみにCloud NATがいかに最強か?という事は下記のエントリーが分かりやすくまとまっているので、一読されることをオススメします。

マネージドNATサービス GCP Cloud NAT がリリースされました - 本日も乙

イントロダクション

このページはCloud NATの設定方法を説明します。Cloud NATをセットアップする前にCloud NAT Overviewも読んでおきましょう。

事前準備

1. IAMパーミッション

roles/compute.networkAdmin ロールは下記の権限を得るために必要です。

  • Cloud Router上へのNATゲートウェイの作成
  • NAT IPの予約・割り当て
  • NATゲートウェイによるIPアドレス変換を適用すべきトラフィックが流れるNATサブネットを指定

2. GCPのセットアップ

  1. GCPプロジェクトを選択、または作成
  2. プロジェクトに対して課金が有効になっていることを確認
  3. Cloud SDKをインストールし、初期化する

今回のチュートリアルのためにk8s-sample-app-20181220というプロジェクトを作りました。リージョンはasia-northeast1(東京リージョン)を使います。

# set environment variables
$ PRJ=k8s-sample-app-20181220
$ REGION=asia-northeast1

$ gcloud config set project $PRJ

$ gcloud config list --format='text(core.project)'
core.project: k8s-sample-app-20181220

GKEのセットアップ

Step 1: VPCネットワークとサブネットを作成

既にVPCネットワークとサブネットがあるなら、次のステップに進みましょう。

まずはカスタムモードで新しいVPCネットワークを作成します。

$ NW=custom-network1

$ gcloud compute networks create $NW --subnet-mode custom

NAME             SUBNET_MODE  BGP_ROUTING_MODE  IPV4_RANGE  GATEWAY_IPV4
custom-network1  CUSTOM       REGIONAL

注意: これはVPCネットワークなので、ネットワークレベルのIPv4アドレスのレンジやゲートウェイIPはありません。

次に、リージョン情報を付けたサブネットを作成しましょう。この例ではasia-northeast1(東京リージョン)に192.168.1.0/24のIPアドレスレンジを割り当てます。

$ SUBNW=subnet-asia-northeast1-192

$ gcloud compute networks subnets create $SUBNW \
  --network $NW \
  --region $REGION \
  --range 192.168.1.0/24

NAME                        REGION           NETWORK          RANGE
subnet-asia-northeast1-192  asia-northeast1  custom-network1  192.168.1.0/24

Step 2: テスト用に踏み台サーバーを作成

Cloud NATをテストするために、外部IPアドレスを持たないテスト用のVMインスタンスを用意する必要があります。そのインスタンスは外部IPアドレスを持たないため、直接SSHで接続することができません。そこで、まずは外部IPアドレスを持つ踏み台サーバーに接続し、そこから内部IPアドレスを使って目標のインスタンスに接続します。

このステップでは踏み台サーバー用のVMを作成します。(後のステップでテストインスタンスへ接続するために、この踏み台を使います。)
今回はインスタンスのゾーンはasia-northeast1-aを指定します。

$ ZONE=asia-northeast1-a

$ gcloud compute instances create bastion-1 \
  --image-family debian-9 \
  --image-project debian-cloud \
  --network $NW \
  --subnet $SUBNW \
  --zone asia-northeast1-a

NAME       ZONE               MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP    STATUS
bastion-1  asia-northeast1-a  n1-standard-1               192.168.1.2  35.221.81.168  RUNNING

Step 3: プライベートk8sクラスターを作成

enable-private-nodesを指定することでk8sクラスターをプライベートにできます。

$ gcloud container --project $PRJ clusters create "nat-test-cluster" \
  --zone $ZONE \
  --username admin \
  --cluster-version "1.11.2-gke.26" \
  --num-nodes "3" \
  --machine-type n1-standard-1 \
  --image-type COS \
  --disk-type pd-standard \
  --disk-size 100 \
  --scopes "https://www.googleapis.com/auth/compute","https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append" \
  --enable-cloud-logging \
  --enable-cloud-monitoring \
  --enable-private-nodes \
  --enable-private-endpoint \
  --master-ipv4-cidr 172.16.0.0/28 \
  --enable-ip-alias \
  --network projects/$PRJ/global/networks/$NW \
  --subnetwork projects/$PRJ/regions/$REGION/subnetworks/$SUBNW \
  --max-nodes-per-pool "110" \
  --enable-master-authorized-networks \
  --addons HorizontalPodAutoscaling,HttpLoadBalancing,KubernetesDashboard \
  --enable-autoupgrade \
  --enable-autorepair

NAME              LOCATION           MASTER_VERSION  MASTER_IP   MACHINE_TYPE   NODE_VERSION   NUM_NODES  STATUS
nat-test-cluster  asia-northeast1-a  1.11.2-gke.26   172.16.0.2  n1-standard-1  1.11.2-gke.26  3          RUNNING

Step 4: SSH接続を許可するためのファイアウォールを作成

$ gcloud compute firewall-rules create allow-ssh \
  --network $NW \
  --allow tcp:22

NAME       NETWORK          DIRECTION  PRIORITY  ALLOW   DENY  DISABLED
allow-ssh  custom-network1  INGRESS    1000      tcp:22        False

Step 5: ノードへログインし、外部ネットワークから隔離されていることを確認

いずれかのクラスターノード名を取得しましょう。ノード名はgke-nat-test-cluster-default-pool-7d3a845e-c2qfなどです。

$ gcloud compute instances list

NAME                                             ZONE               MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP    STATUS
bastion-1                                        asia-northeast1-a  n1-standard-1               192.168.1.2  35.221.81.168  RUNNING
gke-nat-test-cluster-default-pool-7d3a845e-c2qf  asia-northeast1-a  n1-standard-1               192.168.1.4                 RUNNING
gke-nat-test-cluster-default-pool-7d3a845e-jkt6  asia-northeast1-a  n1-standard-1               192.168.1.3                 RUNNING
gke-nat-test-cluster-default-pool-7d3a845e-nm15  asia-northeast1-a  n1-standard-1               192.168.1.5                 RUNNING

Compute EngineのSSHキーをローカルマシンに追加します。

$ ssh-add ~/.ssh/google_compute_engine

踏み台サーバーbastion-1に接続します。
インスタンスへの初回アクセスの場合はGCPはSSHキーを生成します。

$ gcloud compute ssh bastion-1 --zone $ZONE -- -A

踏み台サーバーからk8sクラスターのいずれかのノード名を指定してSSHで接続します。(この手順だけ公式ドキュメントの"GCLOUD"版で記載漏れがありましたのでご注意を

ssh gke-nat-test-cluster-default-pool-7d3a845e-c2qf -A

curlコマンドが入っていればどのノードでも良いのですが、今回はプロンプトからStackdriverエージェント用のコンテナに接続します。

$ docker exec -it $(docker container list | grep stackdriver | awk '{print $1}') /bin/bash

ちなみに、公式ドキュメントではkube-dnsコンテナに入る手順が示されていますが、今回のチュートリアルで使用しているk8sエンジンのバージョン1.11.2-gke.26ではkube-dnsのコンテナは見つかりませんでした
kube-dnsはCoreDNSに統合されるらしいので、それが関係していそうです。

CoreDNS is currently a Beta feature in Kubernetes and on course to being graduated to General Availability (GA) for Kubernetes 1.11
Migration from kube-dns to CoreDNS

コンテナ内に入ったら、外部のサイトにアクセスしてみましょう。クラスターがプライベートになっていれば、結果が返って返って来ないはずです。

$ curl example.com

Step 6: Cloud Routerを使ってNATを設定する

次に、Cloud NATを使うインスタンスと同じリージョンにCloud Routerを作成する必要があります。Cloud NATはVM上にNAT情報を保存するためだけに使われます。実際のNATゲートウェイの一部としては使われません。

この設定により、リージョンに属する全てのインスタンスが、プライマリおよびエイリアスIP範囲のためにCloud NATを使うことができるようになります。また、NATゲートウェイのための外部IPアドレスを自動で割り当てます。その他のオプションはgcloud command-line interfaceのドキュメントを参照してください。

注記: Cloud NATはNATの設定情報をグルーピングするためだけにCloud Routerを使います。(コントロール側)Cloud NATはCloud RouterにBGP(Border Gateway Protocol)の利用や、ルーティング追加の命令は出しません。また、NATのトラフィックはCloud Routerを通過しません。(データ側)

Cloud Routerを作成します。

$ gcloud compute routers create nat-router \
  --network $NW \
  --region $REGION

NAME        REGION           NETWORK
nat-router  asia-northeast1  custom-network1

routerに設定を追加します。

$ gcloud compute routers nats create nat-config \
  --router-region $REGION \
  --router nat-router \
  --nat-all-subnet-ip-ranges \
  --auto-allocate-nat-external-ips

Step 7: 再度インターネットアクセスを試行

NAT設定が反映されるのに長いと3分程度かかることもあるため、再度インターネットアクセスを試みる前に少し待つ必要があります。

もし、先程ログインしたコンテナに入ったままなら、再接続を行い、curlコマンドを実行しましょう。

$ curl example.com

<!doctype html>
<html>
<head>
    <title>Example Domain</title>
...
...
</body>
</html>

今度はHTMLがレスポンスとして返って来たはずです。
これでプライベートクラスターからNATゲートウェイを経由して外部ネットワークに接続できたことが確認できましたね!!

最後にチュートリアルのプロジェクトを削除しておきましょう。

$ gcloud projects delete $PRJ

以上でチュートリアルは終了です。

まとめ

動作確認のための手順を除くと、非常に少ない設定でGKEにCloud NATを組み込むことができましたね!
Cloud NATが登場するまでは、NATゲートウェイ用のGCEインスタンスを自前で用意して、ルーティング設定を行う必要がありました。この構成では、NATゲートウェイのインスタンスが単一障害点になったり、帯域のボトルネックになったりしていました。しかし、マネージドなCloud NATを使うことで、NATインスタンス自体が無くなり、レイテンシやスループットが安定するようになります。これらの要因で、既存のオンプレや他のパブリッククラウドと組み合わせることに踏み切れなかった方も一度、導入を検討してみてはいかがでしょうか!?

それではCloud NATで快適なクラウドライフを〜!!

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4