LoginSignup
37
28

More than 5 years have passed since last update.

Cloud NAT使ってみる

Posted at

はじめに

待望の?NAT-GWであるCloud NATがGCPでベータリリースされました。
AWSでは普通に利用していましたが、GCPで外部アクセスの送信元IPを固定したい場合(連携先のFWで制御されている等)、
こんは手順こんな手順でひと手間をかける必要があったので、マネージド信者としては助かります!
GCEは公式(Using Cloud NAT)があり問題なく動作したのですが、GKEが公式に手順があまりなく少々ハマったので記事にしてみました。

ざっくり特徴

  • フルマネージドなNATゲートウェイ
  • gcpからアウトバンドアクセスのゲートウェイ
  • リージョン単位
  • 従来のインライン(NW型のアプライアンス)型ではなく、Software Defined型
    その為、外部IPを使用するVMと同程度の外部帯域幅
    ※この辺がawsと差別化してるところなんだろうなぁ
  • NAT-IPは固定と自動がある(これ重要!)※大体これが目的だと思いますが、送信元IPを固定する場合は固定
  • NATの設定(GIPとかポート範囲)をグループ化したのが、クラウドルータ(リソース)で、そこから各VMに割り振られるらしい。 ↓こんな感じ(公式)

image.png

GCE

特に公式通りでつまずきポイントはありませんでした。

以下の様なネットワークとVMを用意します。
* subnet(private)をCloud NATの対象とする
* Cloud NATのIPは固定で取得する(35.200.9.157)
* 外部へのアクセス用にwebを用意(35.200.38.77)
* bastion-1のみに外部IPを付与し外部からssh接続し、dmz-vmdmz-vm2にssh接続する
外部IPを付与するとNATされない為(ここ重要!!)

image.png

Cloud NATの設定

image.png

dmz-vmから外部のwebへアクセス

dmz-vm
[root@dmz-vm ~]$ curl -LI http://35.200.38.77 -o /dev/null -w '%{http_code}\n' -s
200

web側

web
[root@web nginx]# tail -f access.log
35.200.9.157 - - [28/Oct/2018:01:43:12 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"

問題なくNATされてました。続いて、外部IPが付与されている bastion-1 からアクセスすると

web
[root@web nginx]# tail -f access.log
35.200.9.157 - - [28/Oct/2018:01:43:12 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"
35.190.225.32 - - [28/Oct/2018:01:44:33 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"

VMのGIPでアクセスしていました。(仕様通り)
割愛しますが、 dmz-vm2 からはアクセス不可でした。
次に全てのsubnetをNATの対象に変更します(以下の設定)

image.png

dmz-vm2から外部のwebへアクセス

dmz-vm2
[root@dmz-vm2 ~]$ curl -LI http://35.200.38.77 -o /dev/null -w '%{http_code}\n' -s
200

web側

web
[root@web nginx]# tail -f access.log
35.200.9.157 - - [28/Oct/2018:01:43:12 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"
35.190.225.32 - - [28/Oct/2018:01:44:33 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"
35.200.9.157 - - [28/Oct/2018:01:43:12 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"

特に問題ありません。

GKE

いくつかポイントがあります。

  • エイリアスIPを有効にする
    ※プライマリCIDRは通常のGCEに付与されるLANのIPで、セカンダリCIDR(≒エイリアスIP)からpodのIPが付与される
  • 限定公開クラスタ(private cluster)を有効にする ※そうすると外部IPが付与されずCloud NATが有効になる
  • private clusterにするとデフォルトだとgkeマスタへアクセス出来なくなるので、以下の様に 「外部IPアドレスを使用したマスターへのアクセス」と「マスターIP範囲」を指定する

image.png

GKEのノード(GCE)をコンソールで見るとExternalIPが Noneになってました
image.png

GKEの設定

image.png

CLoud NATの設定

以下の様にScondary IP ranges が表示されるようになる
image.png

接続テスト

gke-to-web
$ kubectl run -it --rm test --image=alpine -- sh

If you don't see a command prompt, try pressing enter.

/ # apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
v3.8.1-39-gd5b2bf402a [http://dl-cdn.alpinelinux.org/alpine/v3.8/main]
v3.8.1-35-ga062ffc9e8 [http://dl-cdn.alpinelinux.org/alpine/v3.8/community]
OK: 9539 distinct packages available
/ # apk add curl
(1/5) Installing ca-certificates (20171114-r3)
(2/5) Installing nghttp2-libs (1.32.0-r0)
(3/5) Installing libssh2 (1.8.0-r3)
(4/5) Installing libcurl (7.61.1-r0)
(5/5) Installing curl (7.61.1-r0)
Executing busybox-1.28.4-r1.trigger
Executing ca-certificates-20171114-r3.trigger
OK: 6 MiB in 18 packages
/ # curl -LI http://35.200.38.77 -o /dev/null -w '%{http_code}\n' -s
200
web
[root@web nginx]# tail -f access.log
35.200.9.157 - - [28/Oct/2018:07:29:47 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.61.1" "-"

送信元IPがCloud NATのアドレスになっています

感想

  • GCEでの利用は問題ないと思いますが、GKEでのproduvtion利用は取りあえずGAまで待とうw
  • GKEで特定のpodのみNATとかやりたい場合はネットワークポリシーで制御しろとの事
  • GKEで使う場合はCloud NAT使う用の専用のクラスタを立てた方がよさそう
    ※aliaseIPとかあんまり使いたくないので…w
37
28
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
37
28