k8sを勉強してます。Service の ExternalName を何に使うかわからなかったので Tech Rock Festivial にも参加している同僚に教えてもらいました。
Dev, Prod で API の向き先を変えたいシーン
例えば、betaでは社内のmock、prodでは api.slack.com の API を使うみたいなシーンです。(同僚が教えてくれた例そのまんま)
applicationの実装
podで動くapplication側は、ダミーのドメインにアクセスします。ここでは slack
とします。
requests.get("https://slack")
or
requests.get("https://slack.default.svc.cluster.local")
ExternalName でドメインを置き換える
Overview
簡単にいうとこういうことです。metadata.name
に指定した名前に対して、podは slack
または slack.<namespace>.svc.cluster.local
で名前解決ができるようになります。
apiVersion: v1
kind: Service
metadata:
name: slack # <-- pod がアクセスするのはこっち。externalName宛のaliasみたいなもの
namespace: default
spec:
type: ExternalName
externalName: api.slack.com # <--- 実際の名前解決先はこっち
実際に pod から名前解決をしてみた例
# host slack
slack.default.svc.cluster.local is an alias for api.slack.com.
# host slack.default.svc.cluster.local
slack.default.svc.cluster.local is an alias for api.slack.com.
Beta 環境 の例
Beta環境では https://slack
宛のリクエストが mock.internal.example.com
に行くようにします。
apiVersion: v1
kind: Service
metadata:
name: slack
namespace: default
spec:
type: ExternalName
externalName: mock.internal.example.com # <--
Production 環境 の例
productionでは https://slack
宛のリクエストが本当のslack APIに行くようにします。
apiVersion: v1
kind: Service
metadata:
name: slack
namespace: default
spec:
type: ExternalName
externalName: api.slack.com # <--
このようにすれば、beta/prod どちらも共通のapplicationコードで、違う API にアクセスさせることができます。便利!
ExternalName って使った方がいいの?
この利用シーンであれば、個人的には使わない方がいいと思います。同僚も production で使っている例は知らないそうです。
Pros
- beta/prod で向き先間違えてました!てへっ。がなくなる
Cons
- application log の debug が困難(どこに名前解決したかわからない)
- HTTP request の Host header がおかしくなる
特に後者が気になります。TLS であれば SNI である程度は proxy なども反応してくれますが、相手の実装次第でルーティングされなくなることも大いに考えられます。動いているシステムをわざわざ ExternalName に変更する利点は少ないでしょう。
もっと便利なシーンを知りたい
もちろん、これ以外の用途で便利なシーンがあると思います。ご存知の方はぜひコメントなりで教えてください!
追伸
同僚さん Thank you!