Kubernetesの公式チュートリアルをやってみる その4 では Node と Pod 概念について扱いました。
この記事のチュートリアルでは Service について取り扱います。
注意 && disclaimer
翻訳・意訳が主目的ではないのでいろいろ端折ったりすることがあります。
明らかな間違いはしないつもりですが、何かあれば優しくツッコんであげてください。
→記事のまとめは Kubernetesの公式チュートリアルをやってみる その1 にあります。
本記事の取り扱う範囲
Using a Service to Expose Your App の内容を扱います。
Using a Service to Expose Your App
コンテナ化アプリを公開する Service 関連の内容
Service
-
Serviceとは、Pod の論理セットとそのアクセス方法を定義した抽象領域を指す。- Pod のレプリカがいくつあっても外部からは1つのエンドポイントとしてアクセスさせることができる。
- Pod が停止したり入れ替える際もフロント側を無停止で制御することができる。
- Pod のIP自体はグローバルに公開されないため、外部からのアクセス手段を提供する。
-
Serviceはselectorでラベルを指定することで、トラフィックを転送する先の Pod を識別する。- ラベルは Pod に key-value ペアで定義する。
- 以下のようなユースケースがある。
- 環境ラベル、development, test, production など
- バージョンタグで公開バージョンを指定する
- ロール毎にタグを分ける
-
Serviceはいくつかの公開種別(type)がある。-
ClusterIP- スペックに
typeを指定しない場合の既定値。 - クラスタ内の内部IPを用いて公開する。
- クラスタ外部からはアクセスできない。
- スペックに
-
NodePort- NAT経由で Node のポートを直接公開する。
-
[ノードIP]:[ポート]の指定で外部から直接アクセスできるようになる。
-
LoadBalancer- 外部にロードバランサーを構築し、ロードバランサーと Pod のセットを紐付ける。
- クラウドなどサポートされている環境でのみ使用可能。
-
ExternalName- 外部のDNSで定義された
CNAMEレコードを用いて公開する。 -
kube-dnsのv1.7以上で利用可能。
- 外部のDNSで定義された
-
-
Serviceはselectorを指定しないで構築することもできる。-
Serviceを特定のエンドポイントに紐付ける際に使用する。 -
type=ExternalNameの際に使用することができる。
-
-
kubectl runで Deployment を構築する際に--exposeを付与することで同時にServiceを作成することもできる。
Interactive Tutorial
Estimate Time: 10分
-
kubectl get service-
Serviceをリストするコマンド。- このチュートリアルでは初期から
Serviceが1つ作成されている。
- このチュートリアルでは初期から
-
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12s
-
kubectl expose [deployment name]-
Serviceを作成するコマンド。 - 以下の例では NodePort の8080ポートでサービスを公開している。1
- デフォルトでは deployment と同じ名称でサービスができるらしい。
-
$ kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
service/kubernetes-bootcamp exposed
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4m
kubernetes-bootcamp NodePort 10.109.31.123 <none> 8080:31022/TCP 2m
-
kubectl describe service [service name]-
Serviceの詳細内容を表示する。2
-
$ kubectl describe service kubernetes-bootcamp
Name: kubernetes-bootcamp
Namespace: default
Labels: run=kubernetes-bootcamp
Annotations: <none>
Selector: run=kubernetes-bootcamp
Type: NodePort
IP: 10.109.31.123
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 31022/TCP
Endpoints: 172.18.0.2:8080
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
- curlで確認
- クラスタ内でクラスタIPとノードポートを指定すると
Service経由でアプリへアクセスできる。
- クラスタ内でクラスタIPとノードポートを指定すると
$ export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
$ echo NODE_PORT=$NODE_PORT
NODE_PORT=31022
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-5c69669756-9bk6s | v=1
- ラベル管理
- Pod や
Serviceは管理元の deployment 名でrun = [deployment name]のラベルが付与される。 - 既存のリソースに対して追加でラベルを付与することもできる。
- 既存のラベルを削除する場合は
kubectl label [type] name [key]-とラベルキーにハイフンを付与する。
- 既存のラベルを削除する場合は
- Pod や
$ kubectl describe deployment | head -4
Name: kubernetes-bootcamp
Namespace: default
CreationTimestamp: Thu, 27 Sep 2018 15:23:36 +0000
Labels: run=kubernetes-bootcamp
# ラベル指定でPodをリストする
$ kubectl get pods -l run=kubernetes-bootcamp
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-5c69669756-9bk6s 1/1 Running 0 20m
# ラベル指定でServiceをリストする
$ kubectl get services -l run=kubernetes-bootcamp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-bootcamp NodePort 10.109.31.123 <none> 8080:31022/TCP 19m
# 新規ラベルを付与
$ kubectl get pod $POD_NAME -o yaml | grep -i label -A3
labels:
pod-template-hash: "1725225312"
run: kubernetes-bootcamp
name: kubernetes-bootcamp-5c69669756-9bk6s
$ kubectl label pod $POD_NAME app=v1
pod/kubernetes-bootcamp-5c69669756-9bk6s labeled
$ kubectl get pod $POD_NAME -o yaml | grep -i label -A3
labels:
app: v1
pod-template-hash: "1725225312"
run: kubernetes-bootcamp
-
kubectl delete service [ラベルセレクタ]- ラベルを指定して
Serviceを削除する。-
Serviceを削除してもバックエンドの Pod は削除されない。
-
- ラベルを指定して
$ kubectl delete service -l run=kubernetes-bootcamp
service "kubernetes-bootcamp" deleted
# ノードポートはアクセスできなくなる。
$ curl $(minikube ip):$NODE_PORT
curl: (7) Failed to connect to 172.17.0.55 port 31022: Connection refused
# Pod内ではアプリは稼働している。
$ kubectl exec -ti $POD_NAME curl localhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-5c69669756-9bk6s | v=1