Service概要
- Service
- ClusterIP:k8s内部ロードバランサー
- ExternalIP(ClusterIPに属する):指定のNodeのIPを使って、外部と通信可能なClusterIP
- NodePort:任意NodeのIPを使って、外部からk8s内部への通信を可能にするリソース
- LoadBalancer:外部ロードバランサー + NodePort + ClusterIP
- Headless(None)(ClusterIPに属する):主にStatefulSetのためのClusterIP
- ExternalName:k8sのCNAME変換用リソース
- None-Selector(ClusterIPに属する):Endpointsをカスタマイズ可能なClusterIP
LoadBalancer Service
manifestのリソース指定:
kind: Service
spec.type: LoadBalancer
LoadBalancerはk8s外部からのアクセスを受け付けに、一番実用的なServiceです。
仕組みとしては、k8sクラスタ外部のLoadBalancerからNodePortへバランシングする形になります。
ただ、外部LoadBalancerが必要なので、オンプレ環境ですと、その仕組みを自分で作る必要があります。
そこで、パブリッククラウド(GCP,AWS,Azure)を利用すれば、特に外部LoadBalancerを気にすることなく使用可能です。
※パブリッククラウドでLoadBalancer Service作成すると、自動的にリソースを作成してくれます。
イメージ図で行きましょう
外部からのトラフィックはLoadBalancer→NodePort→ClusterIP→Podの流れで転送されます。
ポートの転送は:
- LoadBalancerはClusterIPと同じPortで受け付け
- LoadBalancerでPortを変換し、NodePortのポートに合わせる
- NodePortは自分のPortで受け付け
- NodePortでPortを変換し、ClusterIPのポートに合わせる(LoadBalancerポート)
- ClusterIPはポートをPodのPortを変換し、転送する。
ちょっと複雑そうですが、ここで気にする必要のあるPortは以下の二つのみです。
spec.ports[].port
:LoadBalancerのPortspec.ports[].targetPort
:PodのPort
なぜなら、LoadBalancerのPortはClusterIPのPortと同じだから、一個で十分です。
また、NodePortのPortは前説明した通り、指定しない場合、ランダムPortを使うのです。
※もちろん指定してもいいです。
特徴:
- k8sクラスタ外部から、LoadBalancerのIPでアクセス可能
- LoadBalancerを作ると、LoadBalancer関連の以下のものが自動的に作成される
- 外部ロードバランサー(クラウド)
- NodePort
- ClusterIP
- LoadBalancerはNodeのIP以外の静的IPの指定が可能
- グローバルIPと内部IPどちらでも指定可能
- spec.loadBalancerIP: "<LBのIP>"
- グローバルIPと内部IPどちらでも指定可能
- GCPで使用時の注意点:
- グローバルIPは「プレミアム」*(ネットワークサービス階層)で作成する必要がある
- 実際試して、「標準」の場合、ExternalIPがずっとPending状態になる
- グローバルIPは使用可能(リージョンtypeのみ対応可能)
- 使用する場合、事前にGCPでグローバルIPを作成する必要がある
- グローバルIPを静的IPを予約する場合、IPが静的になる
- GCP内部ロードバランシングの場合
metadata.annotations
でLoadBalancerの種類を指定する必要があるcloud.google.com/load-balancer-type: "Internal"
- グローバルIPは「プレミアム」*(ネットワークサービス階層)で作成する必要がある
- ファイアウォール機能はあるが、GCPを使う場合、GCPのFW機能のサービスを使ったほうがいい
spec.loadBalancerSourceRanges[]
*:GCPのLoadBalancerの要件
LoadBalancer manifest例
この例はGCPのグローバルIPを使用した例となります。
事前にグローバルIPを作成する必要があります。
apiVersion: v1
kind: Service
metadata:
name: my-nlb-service
labels:
app: nginx
# 内部LoadBalancerの場合、annotationsでInternalの指定が必須
# annotations:
# cloud.google.com/load-balancer-type: "Internal"
spec:
selector:
app: nginx
type: LoadBalancer
loadBalancerIP: "35.xxx.xxx.xxx" # GCPのグローバルIP
ports:
- port: 8080
targetPort: 80
※GCPなどの場合の特別指定項目もあるので、ここもご参照ください
最後に
以上でk8sのLoadBalancerについて、説明させていただきました。
k8sにおいて、LoadBalancerの出場頻度が結構高めなServiceなので、重要なポイントです。
ここまで読んでいただいて、お疲れ様でした。
コメント