GKEからオンプレへデータ転送~暗号化を添えて~

お久しぶりです インフラの戸田です

今回の内容は、GKEからオンプレまでデータ転送をする際に行うことをまとめた記事になります。

最近の戸田は、猫に仕事を邪魔されるのでPC近くに猫用の箱をおいてみました。その結果がこれです。

f:id:AdwaysEngineerBlog:20200522113702j:plain

....邪魔ぁ!!! (効果があるときとない時があるようです。

こんな状況になりながら、このブログをかいております。

経緯

GKEで生成されるログデータをオンプレ環境にあるElasticSearchに転送したいという要件がありました。
今回はログデータをfluentdでGCP外にデータを転送する部分について記載します。

GKEの特徴としてデフォルトの設定だと、すべてのNodeにグローバルIPが付与され、各Nodeからインターネットへと通信が発生します。 もちろんNodeは増えたり減ったりするので、グローバルIPも変わります。

IPがころころ変わると、ファイアウォールの設定変更を行う必要が出てきたり、様々な面で困るためグローバルIPを固定化する必要があります。

ただし、グローバルIPを固定化するということはGKEの機能だけではできません。調査したところ、グローバルIPを固定化する方法は、2つのみでした。

  • CloudNatを使う(公式に推奨されている)
  • GCEをNatインスタンスとして使う(公式では現在非推奨とされている)

CloudNatは一見便利そうですが、使うには条件があります。

  • GKEのNodeにはグローバルIPが 付与されていない

つまり、GKEを作成時に限定公開クラスタで作成する必要があります。(限定公開クラスタについは公式ドキュメントを参照してください)

ちなみに、通常のクラスタから限定公開クラスタに無停止で移行する方法を見つける事ができませんでした。 (2020/05/21までに調査した結果)

そのため、今回の構成が当てはまる構成は、

  • GKEがすでに動いている
  • IP固定化をするために、CloudNatを使うことができない

です。前提が説明し終わったところで本題に行こうと思います。

固定化する方法と実際にログを転送する方法になります。

GKEの構成

こちらの構成が

f:id:AdwaysEngineerBlog:20200522113731p:plain

なんとこのような構成に変わります。

f:id:AdwaysEngineerBlog:20200522113742p:plain

...何をするか想像がつきました?

これから説明していきます!

設定するもの

設定するものは大きくわけて2種類になります。

  • GCP側で設定するもの
  • fluentdで設定するもの

これらについて紹介していきます。

GCPで設定するもの

更に細かく分けると下記3つを設定・構築しなければなりません。

  • Natインスタンス
  • VPCのセキュリティグループ
  • VPCのルート

これらを設定する必要があります。

Natインスタンス作成

気をつける点は2点

  • IP転送ONをつける
  • ファイアーウォールやルートを設定する際に使うネットワークタグを作成時に追加する

作成する手順は以上です。

インスタンス内でも設定する必要がある。

設定追加するものは下記コマンド

$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

下記のように追加されていけば問題ありません。

$ sudo iptables -v -L -t nat
Chain PREROUTING (policy ACCEPT 8 packets, 4063 bytes)
 pkts bytes target     prot opt in     out     source               destination
Chain INPUT (policy ACCEPT 8 packets, 4063 bytes)
 pkts bytes target     prot opt in     out     source               destination
Chain OUTPUT (policy ACCEPT 59 packets, 3867 bytes)
 pkts bytes target     prot opt in     out     source               destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
   59  3867 MASQUERADE  all  --  any    eth0    anywhere             anywhere

VPCのセキュリティグループ

デフォルトの設定だとGKEとGCE間の通信許可がされていません。そのため、GKEとGCE間で通信を行いたいPortを許可する必要があります。

設定する際に、先程のネットワークタグを利用することができるため、通信元と通信先の設定が簡単にすることができるのでおすすめです。

作成する際の注意点として、優先度の設定には気をつける必要があります。

  • デフォルトで作成される設定は1000
  • 1000より優先度が高い(0に近い)設定ほど優先される
  • 新規作成する際は、1000より小さい数字にする必要がある。

VPCのルート

インターネットに通信を発生させる際に各Nodeに付与されているグローバルIPから通信が発生します。
ルートを追加することにより、オンプレへの通信のみGKEからGCE経由で転送することができます。

セキュリティグループ同様、設定する際に、ネットワークタグを利用することができるため、通信元と通信先の設定が簡単にすることができるのでおすすめです。

作成する注意点として、セキュリティグループと同様に優先度の設定には気をつける必要がある

  • デフォルトで作成される設定は1000
  • 1000より優先度が高い(0に近い)設定ほど優先される
  • 新作作成する際は、1000よりも小さい数字にする必要がある

fluentdで設定するもの

今回、GCPからオンプレまでにデータを平文で送りたくないため、fluentdを使って暗号化してデータを転送します。

事前準備として、転送先に証明書を持たせます。

あとは、 ログを転送するための設定 のみです。

設定内容は

<source>
  @type forward
  port xxxxx
  bind 0.0.0.0
</source>

<match hoge*>
  @type forward
  transport tls #証明を使って暗号化する設定
  tls_insecure_mode true
  <server>
    host xx.xx.xx.xx
    port xxx
  </server>
</match>

のみです。

重要な部分は、 transport tls の部分です。詳細は公式ページ にありますので、ご確認ください。

これをすることにより、fluentdの通信は、暗号化されます。

tcpdumpした結果、暗号化され通信ができていることを確認しました。

以上が先程説明した構成の内容になります。

まとめ

色々な要素を組み合わせることで実現することができました。

新しくGKEを使う際は、PrivateクラスタでCloudNatを使用することをおすすめします(だってマネージドで運用できるならそうしたいじゃないですか