はじめに
長い間、勉強用に立てたKubernetes環境内のServiceをどうやって公開しようか悩んでいました。
今回、ルートテーブルを学んでNginxコンテナを立ててMinikube内のPODにアクセスできるようにしたので記事を書くことにしました。
構築した構成
Dockerを使ってMinikubeを動かしています。
Minikube外部にNginxコンテナを立てています。このNginxをロードバランサーに見立てて外部からアクセスできるようにしています。
以下に作成したTerraformファイルを公開しています。良ければ見てみてください。
https://github.com/kohei39san/mystudy-handson/tree/main/k8s-manifests/make-jmeter-scenario
(上記のファイルではJMeterを使うためのものなのでその他インストールコマンドを実行しています)
※参考ですが、Minikubeを公開する方法としては他に以下のものがあります。
- ノードポートでの公開
Serviceにてノードポートを指定します。ノードに対して、30000~32767内のポートのいずれかで公開できます。しかし、ポート番号を覚えておく必要があります。また、Minikubeをコンテナで動かしている場合、コンテナのポートの公開になるのでEC2外からアクセスするには別途用意が必要になります。 - Minikubeのtunnel機能での公開
EC2から内部のk8sネットワークにアクセスできるようになります。
参考:https://qiita.com/inajob/items/4025a1d1aa83721c453d
NginxコンテナからServiceへの通信方法
Minikubeを起動すると、「minikube」というDockerネットワークが出来上がります。そこにNginxコンテナを動かします。
そうすると、Minikubeの本体のコンテナ(「minikube」というコンテナ)とNginxコンテナが通信可能になります。
Minikubeコンテナでは、内部にKubernetesのService用のネットワークを持っており、Minikubeコンテナ内からServiceにアクセスできるようになっています。
そこで、NginxコンテナからMinikubeコンテナを経由したPODへのルーティングを設定します。これはMinikubeのトンネルと同じことをやっています。以下のようにNginxコンテナにルートを追加します。
route add -net 10.96.0.0 netmask 255.240.0.0 gw 192.168.49.2 eth0
ここで、k8sネットワークのDNSの機能を持っているのはCoreDNS(kube-dnsサービス)です。
NginxコンテナのDNSサーバーにCoreDNSを指定することで、k8s内の名前解決ができるようになります。(Nginxコンテナから、service.namespace.svc.cluster.localの形式のレコードにアクセスできます)
※参考
https://qiita.com/inajob/items/4025a1d1aa83721c453d
Ingressを使うと転送先のServiceを変えられます
Nginxコンテナにてパススルーすると、k8s内で通信経路を決めやすいかもしれません。
例として、NginxのIngress Controllerを使うとk8s内部にNginx PODが立ち上がり、Ingressで通信経路を制御できます。
※参考
https://kubernetes.io/ja/docs/concepts/services-networking/ingress/
NginxコンテナはEC2のポートにバインドすることで公開できます
EC2外部から、Nginxコンテナにアクセスする方法の一つとして、ポートのバインドがあります。
https://docs.docker.jp/engine/userguide/networking/default_network/binding.html
例えば、Nginxコンテナの80,443ポートをバインドすれば、EC2の80,443ポートからk8s内部にアクセスできるようになります。
公開するポート番号を比較的自由に決められて、通信経路制御もk8s内部で決められるのが利点だと思っています。
おわりに
改めてネットワークの勉強になりました。奥が深いですね。
これからも勉強します。