kubernetesのお話
先日、アプリケーションの追加機能の動作確認をしていて、どうも思ったように動かない、なんでだ…
と思って色々調べたところ、全く覚えのない環境変数が設定されていて、それがそのアプリケーションで使用する環境変数名で、値がアプリケーションが想定していない形式だったので、それが原因でエラーになっていた
ということがありました
果たしてこいつはどこから来たのか
原因
kubernetesのservice discoveryのひとつでした(完全に仕様)
https://kubernetes.io/ja/docs/concepts/services-networking/service/#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0
おそらく一般的に使われているservice discoveryはdnsかと思います
service-name.namespace.svc.cluster.local
で目的のserviceにアクセスするというやつ
それの他に、環境変数でserviceのipやportを名前解決(?)してにアクセスできるというものがある、ということ
こんな方法があったんですね、全く知らなかった
で、このドキュメントに書かれている例だと
REDIS_MASTER_SERVICE_HOST=10.0.0.11
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
ポート番号がkeyに入ってるやつはまだしも、その他はなかなか汎用的なワードになっていて
[service名]_SERVICE_HOST
[service名]_SERVICE_PORT
[service名前]_PORT
となります
例えばとあるnamespace内に mysql
という名前のserviceがあるとしたら(あくまで例えば)
そのnamespace内の全てのコンテナに MYSQL_SERVICE_HOST
MYSQL_SERVICE_PORT
MYSQL_PORT
という環境変数が設定されてしまいます
ちょっとそれはどうなの…という感じ
知らなかったらなんかに引っかかってもおかしくないし、知っててもうっかり引っかかりそうです
対応など
無効化できます
https://kubernetes.io/ja/docs/concepts/services-networking/connect-applications-service/#service%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%99%E3%82%8B
podの設定に spec.enableServiceLinks: false
を追加します
deploymentの場合は spec.template.spec.enableServiceLinks: false
ですね
デフォルト無効にするような設定はないみたいです
コンテナの環境変数定義で同じ名前のものがある場合、そちらが優先されます
環境変数があれば優先だけど、設定がない場合はflag、configファイルからの設定などを使用する、みたいな場合に引っかかる流れですね
その他
これservice作る前から立ち上がってたコンテナは起動し直さないと環境変数設定されないのですごい使いにくそうですね
namespaceまたぎもできなさそう
この先この機能が消えたり、デフォルトでオフになるとかはなさそうです
https://github.com/kubernetes/kubernetes/issues/92226