Help us understand the problem. What is going on with this article?

Google Cloud の Cloud NAT を使って GKE の External IP を固定化してみた

前提

  • GKE は Kubernetes をベースとした Container as a Service です。
  • そのためクラスタには node-pools があり、 pod はこのリソースを使用して起動します。
  • node-pools はスケーリングすることを前提として存在するため、外部と通信するための External IP は変動するものと思った方が良いです。
  • ただそうすると IP アドレスによるアクセス制限をしている外部サービスとの連携に困ります。
  • そこでこれまでなら自力で Gateway サーバーを立ててそれを介して通信するようにしていました。

tl;dr

  • JST 2018-10-11 に Google Cloud / Cloud NAT という NAT サービスがベータリリースされました。
  • これを GKE と連携して使えば解決!

具体的な方法

  1. VPC を作る
  2. サブネットを作る
  3. External Static IP を払い出す
  4. ルーターを作る
  5. Cloud NAT を作る
  6. クラスタを作る
  7. pod 立てて External IP を調べてみる

VPC を作る

$ gcloud compute networks create ${vpc_name}\
  --project=${project_id}\
  --bgp-routing-mode=regional\
  --subnet-mode=custom
  • 変数部分は環境に合わせて指定
  • --bgp-routing-mode
    • global でも良いけど今回はリージョンに閉じた話なので regional
  • --subnet-mode
    • auto は勝手にサブネット作って煩わしいので使わない
    • legacy は古い方式で Cloud NAT とか使えない
    • やりたいことやるだけなら custom で手動設定

サブネットを作る

$ gcloud compute networks subnets create ${subnet_name}\
  --project=${project_id}\
  --region=${region}\
  --network=${vpc_name}\
  --range=${subnet_range}
  • 変数部分は環境に合わせて指定
    • --range=${subnet_range} は RFC1918 のお好きな IP 帯

External Static IP を払い出す

$ gcloud compute addresses create ${external_ip_name}\
  --region=${region}
  • 変数部分は環境に合わせて指定

ルーターを作る

$ gcloud compute routers create ${router_name}\
  --region=${region}\
  --network=${vpc_name}\
  --asn=65001
  • 変数部分は環境に合わせて指定
  • --asn=65001
    • 自律システム番号(ASN)
    • ネットワーク内で一意な 64512 〜 65534 または 4200000000 〜 4294967294 の範囲で決めろとのこと

Cloud NAT を作る

$ gcloud compute routers nats create ${nat_name}\
  --region=${region}\
  --router=${router_name}\
  --nat-external-ip-pool="${external_ip_name}"\
  --nat-custom-subnet-ip-ranges="${subnet_name}"
  • 変数部分は環境に合わせて指定
  • --nat-external-ip-pool="${external_ip_name}"
    • --auto-allocate-nat-external-ips で自動払出するか、割り当てる IP を列挙する
  • --nat-custom-subnet-ip-ranges="${subnet_name}"
    • --nat-all-subnet-ip-ranges--nat-primary-subnet-ip-ranges でネットワーク内全てのサブネットまたは primary 全てを範囲とするか、 NAT を使う IP 帯を列挙する

(2020-01-24) (@zawataki さんからのご指摘) alpha じゃなくなり --nat-external-ip-pool --nat-custom-subnet-ip-ranges の指定方法が変わっていたので更新

クラスタを作る

$ gcloud container clusters create ${gke_cluster_name}\
  --project=${project_id}\
  --zone=${zone}\
  --network=${vpc_name}\
  --subnetwork=${subnet_name}\
  --enable-ip-alias\
  --enable-private-nodes\
  --master-ipv4-cidr=172.16.0.0/28\
  --enable-master-authorized-networks\
  --master-authorized-networks=0.0.0.0/0\
  --no-enable-legacy-authorization\
  --no-enable-basic-auth\
  --no-issue-client-certificate
  • 変数部分は環境に合わせて指定
  • 細かくは割愛
  • --network=${vpc_name}--subnetwork=${subnet_name} で Cloud NAT の対象サブネットを指定する
  • node-pools が External IP を持っていないことが Cloud NAT を使用する条件なので --enable-private-nodes にする
  • External IP がないと kubectl で操作に困るようなのでマスターエンドポイントへのアクセスを --enable-master-authorized-networks で出来るようにする
    • --master-authorized-networks=0.0.0.0/0 で指定したアクセス元だけ許可される

pod 立てて External IP を調べてみる

$ kubectl run tmp-pod -it --rm --image=${image} -n ${namespace} --restart=Never -- curl httpbin.org/ip
{
  "origin": "${external_ip}"
}
tver-technologies
Innovate TVision, Designing Value / テレビ・動画配信の可能性を切り拓き、新しい価値をデザインしていきます。
https://www.tver-tech.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away