kubernetesのServiceを使ってプライベートサブネットのRDSに接続する方法
EKSとRDSを利用して構築している環境があるのですが、RDSについてはプライベートサブネットに配置しているため、DB接続するには踏み台サーバを置いてポートフォワードするなどの対応が必要になります。
この方法だと踏み台サーバが必要になるため、以下のような構成でRDSに対して接続経路を用意しています。このPodはsocatが同梱されておりプロキシサーバーとなっています。
Podでプロキシを行いRDSに接続する構成
負荷も高いわけではなく特に問題はないのですが、このためだけにPodを起動させておくのもなーと思い、Podを使わずにプライベートなRDSへ接続できる方法がないか検証した結果、以下のような構成で接続できましたので、やり方を紹介したいと思います。ただし、RDSの接続先についてはDNSではなくIP指定となるためあまり使い勝手の良い方法ではないと思います。
Podを使わずにRDSへ接続する構成
通常ServiceはPodをメンバとして登録しますが、このケースではEndpointsというリソースをメンバとして登録します。そしてEndpointsからRDSへ接続するという形になります。
ELBの作成
以下の設定でロードバランサーを作成します。
当然ですが、セキュリティグループも以下に合わせて作成しておいてください。
Type: CLB
Protocol: TCP
Load Balancer Port: 13306
Instance Port: 30306
Kubernetesのリソースデプロイ
以下がRDS(MySQL)に接続するサンプルになります。
RDSのIPを自環境に合わせて書き換えてapplyしてください。
apiVersion: v1 kind: Service metadata: name: rds-service spec: type: NodePort ports: - protocol: TCP port: 3306 targetPort: 3306 nodePort: 30306 --- apiVersion: v1 kind: Endpoints metadata: name: rds-service subsets: - addresses: - ip: 10.10.213.27 #RDSのIP ports: - port: 3306
注意点としてはServiceとEndpointsのnameは同じにしておく必要があります。
また、マルチAZを利用している場合は、フェイルオーバーした場合にIPを書き換えるという一手間が必要になりますので注意してください。
以下のコマンドで接続できます。
mysql -h ELB_DNS -u mysql_user -P 13306 -p
初回接続は何故か数十秒かかります。またkeep aliveを調整しておかないと接続がすぐ切れるので長めに設定しておくことをお勧めします。
まとめ
Podを使わずに接続できたのはよかったのですが、Endpointsには接続先をIPでしか登録できないところがすごく惜しい機能です。DNSが指定できるようになったらいいですね。