今回は、Discovery&LBリソースタイプを説明します。WorkloadsリソースにおけるPodやReplicaSetなどの基本的なリソースに対して、外部から参照する口を提供するものです。
まず、ServiceはL4のロードバランシングを実現します。Podの数は変動するため、個別のIPアドレスへアクセスするというよりは、代表IPアドレスにアクセスするなどにより、個別のPodとの疎結合を実現します。
次に、IngressはL7ロードバランシングを実現します。IPアドレスは同じだが、別のPodにアクセスさせたい場合などに利用します。URL1へのアクセスはPodAへ、URL2へのアクセスはPodBへといった制御が可能です。
次節より、ServiceとIngressについて、それぞれ説明します。
![]() |
リソースタイプ(再掲) |
4つのServiceの特徴
Serviceの種別は以下の4つです。それぞれについて説明を交えていきます。
- 1. ClusterIP
- クラスタ内仮想IP指定
- 外部公開IP指定(externalIPs)
- Headless(DNSラウンドロビン)
- Endpoint(selector 指定無し)
- 2. NodePort
- 3. Loadbalancer
- 4. ExternalName
以下、設定例を先に示しておきます。ClusterIPをベースとした設定例としていますが、NodePortなど他の種別に変更する方法を、コメントアウト(#)で記載しています。設定箇所の違いを併せて理解していくと良いでしょう。
apiVersion: v1
kind: Service
metadata:
name: sample-clusterip
spec:
type: ClusterIP # 他にもNodePort、LoadBalancer、ExternalNameがある
clusterIP: xxx.xxx.xxx.xxx # Headlessの場合はNoneを指定
# externalIPs:
# - xxx.xxx.xxx.xxx
# - xxx.xxx.xxx.xxx
# externalName: ext.sample.com (typeがExternalNameの際に指定)
ports:
- name: "http-port"
protocol: "TCP"
port: 8080
targetPort: 80
# nodePort: 38080 (NodePort、LoadBalancerの時に指定)
selector:
app: sample-app
#apiVersion: v1
#kind: StatefulSet (Headlessの場合で、かつPod名でのサービスディスカバリをする場合
#kind: Endpoint (個別の転送先を指定する場合)
順に説明していきましょう。
ClusterIP
1つ目に、ClusterIPサービスはクラスタ内でアクセス可能な代表IPアドレスを提供します。デフォルトで、このService種別になります。以下の例では、ClusterIPサービスを[spec.type]にて指定し、[clusterIP]にてクラスタ内からアクセス可能な仮想IPを指定しています。[externalIPs]を設定するとクラスタ外部からのアクセスのための代表IPアドレス提供します。
サービスディスカバリを行うためのServiceを定義したい場合には、clusterIPにNoneを設定することで、Headlessサービスを作成できます。代表IPアドレスは提供されず、個々のPodへのIPアドレスへアクセスするためのDNSラウンドロビン機能が提供されます。
個別の転送先を定義したい場合には、Endpointリソースと組み合わせて定義します。[spec.selector]を指定せず、同名のEndpoint(sample-app)を設定します。
NodePort
2つ目に、NodePortサービスは各Podへの直接アクセスを可能とし、指定した<NodeIP>:<NodePort>にアクセスできます。お試し環境などで、外部からPodへ簡易にアクセスしたい場合は、NodePortサービスを利用すると良いでしょう。
LoadBalancer
3つ目に、LoadBalancerサービスはクラスタ外に代表IPアドレスを提供します。外部に公開するという意味では、externalIPsとNodePortもありますが、いずれかのNodeが単一障害点となってしまいます。LoadBalancerでは外部の仕組みで信頼性を担保するため、本番運用を見据える上では最も実用的と言えるでしょう。
ExternalName
4つ目にExternalNameサービスは外部のドメイン宛のCNAMEを返す機能を提供します。一方でNon-SelectorはClusterIPなどの自ら定義したサービスのCNAMEを返します。
YAMLとの関連
設定箇所の差分をより明確にするため、前述の内容を表形式にし、各Serviceの種類/特徴と設定項目(YAML)の対応づけを示します。
表:Serviceの種類/特徴と設定項目(YAML)の対応づけ
各Serviceの特徴/用途 | YAML内の設定箇所 | |||||||
---|---|---|---|---|---|---|---|---|
spec | kind | |||||||
type | clusterIP | externalIPs | externalName | ports[].nodePort | selector | StatefulSet | Endpoint | |
クラスタ内仮想IP指定 | ClusterIP | ◯ | - | - | - | ◯ | - | - |
外部公開IP指定(externslIPs) | - | ◯ | - | - | ◯ | - | - | |
Headless(DNSラウンドロビン) | ◯(None) | - | - | - | ◯ | ◯ ※2 | - | |
Endpoint | - | - | - | - | - | - | ◯ | |
外部公開Port指定 | NodePort | - | - | - | ◯ | ◯ | - | - |
クラスタ外ロードバランサの配置 | LoadBalancer | - | - | - | ◯ ※1 | ◯ | - | - |
名前解決(CNAME) | ExternalName | - | - | ◯ | - | - | - | - |
※1 指定しない場合は自動でポートが付与される ※2 Pod名でのサービスディスカバリをする場合指定する |
Ingress
Minikubeのアドオンを使ってIngressを使ってみましょう。enableオプションを使って起動するのみでインストール完了です。
$minikube addons list
- ingress: disabled
$minikube addons enable ingress
ingress was successfully enabled
$kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-586cdc477c-lllkc 1/1 Running 0 15s
※ 無関係な行は記載を省略
DeploymentとServiceを作った上で、Ingressリソースを作ってみましょう。
$kubectl create deployment sample-nginx --image=nginx
deployment.apps/sample-nginx created
$kubectl expose deployment sample-nginx --target-port=80 --port=80
service/sample-nginx exposed
$cat sample.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx
spec:
rules:
- host: sample.nginx
http:
paths:
- backend:
serviceName: sample-nginx
servicePort: 80
$kubectl apply -f sample.yaml
ingress.extensions/nginx created
$kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
nginx sample.nginx 10.0.2.15 80 4m53s
作成したIngressにアクセスしてみましょう。ホスト名[sample.nginx]にてアクセスできていることがわかります。
$curl -I http://`minikube ip` -H 'Host: sample.nginx'
HTTP/1.1 200 OK
Server: nginx/1.15.9
Date: Sat, 20 Apr 2019 18:44:19 GMT
Content-Type: text/html
Content-Length: 612
Connection: keep-alive
Vary: Accept-Encoding
Last-Modified: Tue, 16 Apr 2019 13:08:19 GMT
ETag: "5cb5d3c3-264"
Accept-Ranges: bytes
* * *
今回は5つのリソースタイプの2つ目であるDiscovery&LBを紹介しました。コンテナの外部からL4でアクセスするServiceやL7でアクセスするIngressなどがあります。
簡易に試したい場合や、本番環境で運用したい場合など利用シーンに応じて使い分けると良いでしょう。連載第3回で紹介しましたが、マネージドサービスや構築ツールによってさまざまな特徴があります。例えば、マネージドサービス以外の場合、LoadBalancerなど利用環境が限定されるケースもあります。使い始めてから制約を知るということがないよう、利用条件を確認しておくと良いでしょう。
著者紹介
![]() |
正野 勇嗣 (SHONO Yuji ) - NTTデータ 課長
2011年まで開発自動化技術のR&Dに従事。その後、開発プロジェクト支援やトラブルシューティング等に主戦場を移す。「ソースコード自動生成」に加えて、JenkinsやMaven等の「ビルド自動化」、JsTestDriverやSelenium等の「テスト自動化」を扱うようになり、多様化する開発自動化技術動向に興味。
最近は第四の自動化であるInfrastructure as Code等の「基盤自動化」の魅力に惹かれている。開発自動化技術に関する雑誌・記事執筆も行う。2児のパパ。