動機
GKEでサービスを稼働させているのですが、そのサービス上からある既存外部システムに接続することになりました。
その外部システムでは接続元IPアドレスをホワイトリストでブロックしている為、GKEの外向きの接続IPアドレスを固定する必要があります。
Cloud NAT登場以前は方法が見つからず1、GKEクラスタ作成後にノードのIPアドレスを直接gcloudコマンドで書き換えていました。
参考: https://stackoverflow.com/a/42295292
しかしその方法だとGKEのアップグレードが走るとIPアドレスが剥がれてしまったり、ノードのスケールができなかったりと、かなり不便な状態でした。
Cloud NAT登場で外向けIPアドレスを固定できる様になったので、その手順を紹介します。
さらにそれをDeployment Managerを使ってデプロイします。
VPCネットワーク周りの定義
以下のサンプルを参考にしてVPCネットワークを作成します。
https://cloud.google.com/nat/docs/gke-example#step_1_create_a_vpc_network_and_subnet
network 定義
下記のコマンドと同等の設定になるようにします。
gcloud compute networks create custom-network1 --subnet-mode custom
ドキュメントを参考にして設定ファイルを記述します。
https://cloud.google.com/compute/docs/reference/latest/networks?hl=ja
- custom モードにしたいので、 autoCreateSubnetworks を false に設定します。
- name: custom-network1
type: compute.v1.network
properties:
name: custom-network1
autoCreateSubnetworks: false
subnetwork 定義
下記のコマンドと同様になるように設定します。
gcloud compute networks subnets create subnet-asia-northeast1-192 \
--network custom-network1 \
--region asia-northeast1 \
--range 192.168.1.0/24
ドキュメントを参考にして設定ファイルを記述します。
https://cloud.google.com/compute/docs/reference/rest/v1/subnetworks?hl=ja
- network に上記で定義した custom-network1 を設定します。
- ipCidrRange が range にあたるので、サンプルと同じ値を設定します。
- name: subnet-asia-northeast1-192
type: compute.v1.subnetwork
properties:
name: subnet-asia-northeast1-192
network: $(ref.custom-network1.selfLink)
region: asia-northeast1
ipCidrRange: 192.168.1.0/24
Static IP 定義の作成
今回は Static IP を指定したいので、ドキュメントを参考にして Static IP の定義を作成します。
https://cloud.google.com/compute/docs/reference/latest/addresses?hl=ja
- name: my-static-ip
type: compute.v1.address
properties:
name: my-static-ip
region: asia-northeast1
Cloud Router, Cloud NAT 定義
以下のサンプルを参考にして Cloud Router と Cloud NAT を作成します。
https://cloud.google.com/nat/docs/gke-example#step_6_create_a_nat_configuration_using
下記のコマンドと同様になるように設定します。
※ 今回は静的IPにするので、nat-external-ip-pool に上記で定義したIPアドレスを設定します。
gcloud compute routers nats create nat-config \
--router=nat-router \
--nat-all-subnet-ip-ranges
--nat-external-ip-pool=my-static-ip
ドキュメントを参考にして設定ファイルを記述します。
https://cloud.google.com/compute/docs/reference/latest/routers?hl=ja
- network に上記で定義した custom-network1 を設定します。
- natIps に上記で定義した my-static-ip を設定します。
- natIps に値を設定するので、 natIpAllocateOption に MANUAL_ONLY を設定します。
- name: nat-router
type: compute.v1.router
properties:
name: nat-router
network: $(ref.custom-network1.selfLink)
region: asia-northeast1
nats:
- name: nat-config
sourceSubnetworkIpRangesToNat: ALL_SUBNETWORKS_ALL_IP_RANGES
natIpAllocateOption: MANUAL_ONLY
natIps:
- $(ref.my-static-ip.selfLink)
Cluster の定義
以下のサンプルを参考にしてクラスタを作成します。
https://cloud.google.com/nat/docs/gke-example#step_2_create_a_private_cluster
下記のコマンドと同様になるように設定します。
gcloud container clusters create "nat-test-cluster" \
--zone "asia-northeast1-a" \
--enable-private-nodes \
--master-ipv4-cidr "172.16.0.0/28" \
--enable-ip-alias \
--network "projects/PROJECT_ID/global/networks/custom-network1" \
--subnetwork "projects/PROJECT_ID/regions/asia-northeast1/subnetworks/subnet-asia-northeast1-192" \
--enable-master-authorized-networks
ドキュメントを参考にして設定ファイルを記述します。
https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1/projects.zones.clusters
- network に上記で定義した custom-network1 を設定します。
- subnetwork に上記で定義した subnet-asia-northeast1-192 を設定します。
- 限定公開クラスタでないと Cloud NAT を使用できないので、enablePrivateNodes を true に設定します。
- 限定公開クラスタはエイリアスIPを有効にする必要があるので、useIpAliases を true に設定します。
- name: nat-test-cluster
type: container.v1.cluster
properties:
zone: asia-northeast1-a
cluster:
name: nat-test-cluster
network: $(ref.custom-network1.selfLink)
subnetwork: $(ref.subnet-asia-northeast1-192.selfLink)
nodePools:
- name: default-pool
initialNodeCount: 1
privateClusterConfig:
enablePrivateNodes: true
enablePrivateEndpoint: false
masterIpv4CidrBlock: 172.16.0.0/28
ipAllocationPolicy:
useIpAliases: true
masterAuthorizedNetworksConfig:
enabled: true
cidrBlocks:
- displayName: any
cidrBlock: 0.0.0.0/0
完成した定義ファイル
my-cluster-with-cloud-nat.jinja
resources:
- name: custom-network1
type: compute.v1.network
properties:
name: custom-network1
autoCreateSubnetworks: false
- name: subnet-asia-northeast1-192
type: compute.v1.subnetwork
properties:
name: subnet-asia-northeast1-192
network: $(ref.custom-network1.selfLink)
region: asia-northeast1
ipCidrRange: 192.168.1.0/24
- name: my-static-ip
type: compute.v1.address
properties:
name: my-static-ip
region: asia-northeast1
- name: nat-router
type: compute.v1.router
properties:
name: nat-router
network: $(ref.custom-network1.selfLink)
region: asia-northeast1
nats:
- name: nat-config
sourceSubnetworkIpRangesToNat: ALL_SUBNETWORKS_ALL_IP_RANGES
natIpAllocateOption: MANUAL_ONLY
natIps:
- $(ref.my-static-ip.selfLink)
- name: nat-test-cluster
type: container.v1.cluster
properties:
zone: asia-northeast1-a
cluster:
name: nat-test-cluster
network: $(ref.custom-network1.selfLink)
subnetwork: $(ref.subnet-asia-northeast1-192.selfLink)
nodePools:
- name: default-pool
initialNodeCount: 1
privateClusterConfig:
enablePrivateNodes: true
enablePrivateEndpoint: false
masterIpv4CidrBlock: 172.16.0.0/28
ipAllocationPolicy:
useIpAliases: true
masterAuthorizedNetworksConfig:
enabled: true
cidrBlocks:
- displayName: any
cidrBlock: 0.0.0.0/0
my-cluster-with-cloud-nat.yaml
my-cluster-with-cloud-nat.jinja を参照しているだけです。
imports:
- path: my-cluster-with-cloud-nat.jinja
resources:
- name: my-cluster-with-cloud-nat
type: my-cluster-with-cloud-nat.jinja
リソースのデプロイ
下記のコマンドでデプロイします。
gcloud deployment-manager deployments create my-cluster-deployment --config ./my-cluster-with-cloud-nat.yaml
IPアドレス確認
下記のコマンドで認証情報を取得します。
$ gcloud container clusters get-credentials --zone asia-northeast1-a nat-test-cluster
サンプルイメージをクラスタにデプロイします。
$ kubectl create deployment hello-server --image=gcr.io/google-samples/hello-app:1.0
ポッドに入って IPアドレスを確認します。
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
hello-server-xxxxxx 1/1 Running 0 3s
$ kubectl exec -it hello-server-xxxxxx /bin/sh
$ wget -qO- httpbin.org/ip
-
もしかしたら最新GKEやKubernetesでは外向きIPを固定できる機能があるのかもしれません。ご存知の方の目に止まりましたらコメントで教えていただけると幸甚です。 ↩