kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Kubernetes の Service で「環境変数」を使ったサービスディスカバリを試す

Kubernetes の Service ドキュメントを読み直していたら「サービスディスカバリ」のモードとして「環境変数」「DNS」をサポートしていると書いてあった.一般的によく使うのは「DNS」{ServiceName}.{NamespaceName}.svc.cluster.local というレコードで名前解決できる.今回は「環境変数」を試すぞー💪

kubernetes.io

検証環境は以下の通り.

  • 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_HOSTBACKEND2_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