Kubernetes の Service ドキュメントを読み直していたら「サービスディスカバリ」のモードとして「環境変数」と「DNS」をサポートしていると書いてあった.一般的によく使うのは「DNS」で {ServiceName}.{NamespaceName}.svc.cluster.local
というレコードで名前解決できる.今回は「環境変数」を試すぞー💪
検証環境は以下の通り.
- Kubernetes v1.23.0
準備をする
まず準備として backend1
アプリケーション (Service + Deployment) と backend2
アプリケーション (Service + Deployment) を適当に作る.作ったら backend1
Service と backend2
Service の ClusterIP
を確認しておく.
$ kubectl create deployment backend1 --image nginx:1.21 --replicas 3 $ kubectl expose deployment backend1 --port 80 $ kubectl create deployment backend2 --image nginx:1.21 --replicas 3 $ kubectl expose deployment backend2 --port 80 $ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE backend1 ClusterIP 10.97.227.158 <none> 80/TCP 30s backend2 ClusterIP 10.98.163.125 <none> 80/TCP 20s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 25d
環境変数を確認する
次に frontend
アプリケーション (Pod) を作る.Pod の中で printenv
コマンドを使って環境変数を確認すると BACKEND1_SERVICE_HOST
や BACKEND2_SERVICE_HOST
などサービスディスカバリをしたサービス情報が自動的に設定されている!よって,環境変数の値を使ってサービスに接続できる💡
なるほどー!
$ kubectl run frontend --image nginx:1.21 $ kubectl exec -it frontend -- printenv | grep BACKEND | sort BACKEND1_PORT=tcp://10.97.227.158:80 BACKEND1_PORT_80_TCP=tcp://10.97.227.158:80 BACKEND1_PORT_80_TCP_ADDR=10.97.227.158 BACKEND1_PORT_80_TCP_PORT=80 BACKEND1_PORT_80_TCP_PROTO=tcp BACKEND1_SERVICE_HOST=10.97.227.158 BACKEND1_SERVICE_PORT=80 BACKEND2_PORT=tcp://10.98.163.125:80 BACKEND2_PORT_80_TCP=tcp://10.98.163.125:80 BACKEND2_PORT_80_TCP_ADDR=10.98.163.125 BACKEND2_PORT_80_TCP_PORT=80 BACKEND2_PORT_80_TCP_PROTO=tcp BACKEND2_SERVICE_HOST=10.98.163.125 BACKEND2_SERVICE_PORT=80
注意点としては Service オブジェクトの「作成順序」に依存している点で,あくまで Pod を起動したときに存在するサービスディスカバリ結果を環境変数に設定する仕組みになっている.
以下に構成図をまとめた!
spec.enableServiceLinks: false
で無効化する
自動的に環境変数が設定されるのは良さそうだけど,オブジェクトの「作成順序」に依存していることを考慮すると使いにくそうに感じる.実際にどういうときに積極的に使うんだろう❓
そこで,もし環境変数を使う予定がなかったり,不要な環境変数を設定したくないときは Pod の spec.enableServiceLinks: false
で無効化できる.以下のように spec.enableServiceLinks: false
を追加したマニフェストを作る.
apiVersion: v1 kind: Pod metadata: name: frontend spec: enableServiceLinks: false containers: - name: frontend image: nginx:1.21
もう1度 frontend
アプリケーション (Pod) を作る.Pod の中で printenv
コマンドを使って環境変数を確認すると,今度は設定されていなかった.ちゃんと無効化できた💡
なるほどー!
$ kubectl apply -f frontend.yaml $ kubectl exec -it frontend -- printenv | grep BACKEND | sort