はじめに
待望の?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に割り振られるらしい。
↓こんな感じ(公式)
GCE
特に公式通りでつまずきポイントはありませんでした。
以下の様なネットワークとVMを用意します。
- subnet(private)をCloud NATの対象とする
- Cloud NATのIPは固定で取得する(35.200.9.157)
- 外部へのアクセス用にwebを用意(35.200.38.77)
-
bastion-1
のみに外部IPを付与し外部からssh接続し、dmz-vm
やdmz-vm2
にssh接続する
※ 外部IPを付与するとNATされない為(ここ重要!!)
Cloud NATの設定
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の対象に変更します(以下の設定)
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範囲」を指定する
GKEのノード(GCE)をコンソールで見るとExternalIPが None
になってました
GKEの設定
CLoud NATの設定
以下の様にScondary IP ranges
が表示されるようになる
接続テスト
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