仕事をすればするほど自分の無力さを感じる(´・ω・`)
でも、千里の道も一歩から!
地道に今日もブログを書いていきます◎
今回は、kubernetes(以下k8s)のSerivce、サービスディスカバリ、クラスタ内・クラスタ外DNSについて、
基本的なことをさらってみます。
参考文献
■podとIPアドレスの考え方
pod1つにつき1つのIPアドレスがk8sによって自動で割り当てられる。
割り当てられるIPは、k8sクラスタにプールされているIP群の1つであり、このIPを利用してpod間で通信が行われる。
なお、k8s内のpodには複数のコンテナを内包することができるが、
同一podに複数のコンテナが存在する場合、それらのコンテナは同じIPアドレスを共有することになる。
その場合、コンテナの行先特定にはポート番号が用いられる。
■k8sでServiceを用いるメリット
・自動的に割り当てられるpodのIPを、手動で確認・宛先設定するのはほぼ不可能
→Serviceがpodへのアクセス窓口を果たしてくれる(k8s利用者が個々のpodの所在を意識しなくて良い)
・Serviceがpodの負荷分散を行ってくれる
■Serviceのマニフェストファイルの基本的な書き方
◎spec.type
Serviceの種類を定義する。
※Serviceの種類については後日記事にまとめる予定
◎spec.ports[]
転送元・転送先のポート番号と転送プロトコルを記述する。
複数記述可能。
ports[].portには転送元(つまりService自身)のポート番号、
ports[].targetPortには、対象ポートつまり転送先のpodのポート番号を指定する。
◎spec.selector
トラフィックの転送条件。
たとえばラベルを定義することで、そのラベルがついたpodにトラフィックを転送する。
◎マニフェストファイル例
spec~の部分は赤字で示した。
apiVersion: v1
kind: Service
metadata:
name: test-service
spec:
type: ClusterIP
ports:
- name: "http"
protocol: "TCP"
port: 8080
targetPort: 80
- name: "https"
protocol: "TCP"
port: 8443
targetPort: 443
selector:
app: test
■クラスタ内DNS(Aレコード)
あるpodから別のServiceへアクセスさせたい時は、基本的にはIPアドレスではなく、いわゆる「ホスト名」を指定することになる。
podのIPアドレス同様、SerivceのIPアドレスも、k8sによって動的に設定されるものであり、
ServiceへのアクセスにIPアドレスを指定しても想定通りの動きになりえないからである。
イメージはこんなかんじ。↓
「ホスト名」と書いたが、k8sクラスタ上においてServiceのホスト名にあたる部分は、
・Serviceの名前(マニフェストファイルのmetadata.nameの値)
・Seviceのデプロイ先ネームスペース(マニフェストファイルのmetadata.namespaceの値)
から成り立つ。
例えばSerive名が「test-service」、ネームスペースが「test」とすると、
test-service.test が、いわゆるホスト名となる。
ただし、同じネームスペース内でのアクセスであれば、ネームスペースを省略し、Service名だけでアクセスすることが可能である。
なお、IP⇔Service名の名前解決は、逆引きも含めて、k8sが自動的に行ってくれる。(そもそもIPが動的に変わるので、手動で名前解決するのは至難の業。。。)
■外部DNSへの問い合わせ
最後に、podからクラスタ外のDNSに問い合わせをすることについても触れておく。
デフォルトでは、podは、まずクラスタ内DNSに問い合わせを行い、
解決できなかった場合のみ、クラスタ外にあるアップストリームのDNSサーバへ問い合わせをする仕組みとなっている。
最初からクラスタ外のDNSサーバに問い合わせを行いたいときは、
podのマニフェストファイルの、spec.dnsPolicyの値を"None"に設定すれば良い。
(クラスタ内DNSには問い合わせしなくなるため注意。)
逆に、デフォルト状態に戻したい時は、podのマニフェストファイルのspec.dnsPolicyを指定しないか、
値を"ClusterFirst"に設定すればOK。
■参考文献
・青山真也著『Kubernetes完全ガイド』