はじめに
この連載ではコンテナオーケストレーションツールである、 Kubernatesの使い方を学びます。
今回はReplicasetとDeploymentについて学習します。
サンプルコード
こちらに順次アップしていきますー。
連載記事一覧
Service
ServiceはKubernetesクラスタ内において、Podの集合(ReplicaSet等)に対する経路やサービスディスカバリを提供するためのリソースです。Serviceのターゲットとなる一連のPodは、Serviceで定義するラベルセレクタによって決定されます。
- サービスディスカバリ : APIへの接続先が動的に変わる場合に、クライアントが接続先を切り替えるのではなく、クライアントからは一貫した名前でアクセスできるようにする仕組み
simple-replicaset-with-label.yamlを作成し、ReplicaSetを2つ定義します。 どちらのReplicaSetも内容はほぼ同じですが、releaseというラベルの内容がそれぞれspringとsummerとなっています。
# simple-replicaset-with-label.yaml apiVersion: apps/v1 kind: ReplicaSet metadata: name: echo-spring labels: app: echo release: spring spec: replicas: 1 selector: matchLabels: app: echo release: spring template: metadata: labels: app: echo release: spring spec: containers: - name: nginx image: gihyodocker/nginx:latest env: - name: BACKEND_HOST value: localhost:8080 ports: - containerPort: 80 - name: echo image: gihyodocker/echo:latest ports: - containerPort: 8080 --- apiVersion: apps/v1 kind: ReplicaSet metadata: name: echo-summer labels: app: echo release: summer spec: replicas: 2 selector: matchLabels: app: echo release: summer template: metadata: labels: app: echo release: summer spec: containers: - name: nginx image: gihyodocker/nginx:latest env: - name: BACKEND_HOST value: localhost:8080 ports: - containerPort: 80 - name: echo image: gihyodocker/echo:latest ports: - containerPort: 8080
マニフェストファイルをapplyし、作成されたPodを確認してみます。releaseラベルにspringとsummerを持つPod・ReplicaSetがそれぞれ実行されていることがわかります。
$ kubectl apply -f simple-replicaset-with-label.yaml replicaset.apps/echo-spring created replicaset.apps/echo-summer created $ kubectl get pod -l app=echo -l release=spring NAME READY STATUS RESTARTS AGE echo-spring-drhn8 2/2 Running 0 2m38s $ kubectl get pod -l app=echo -l release=summer NAME READY STATUS RESTARTS AGE echo-summer-rxvmg 2/2 Running 0 3m55s echo-summer-zzjsv 2/2 Running 0 3m55s
release=summerを持つPodだけにアクセスできるようなServiceを作ってみましょう。
次のようにsimple-service.yamlを作成します。
spec.selector属性には、ServiceのターゲットとなるPodのラベルを設定します。
# simple-service.yaml apiVersion: v1 kind: Service metadata: name: echo spec: selector: app: echo release: summer ports: - name: http port: 80
PodのラベルがServiceにセレクタで定義しているラベルと合致した場合、対象のPodはそのServiceのターゲットとなります。
simple-service.yamlをapplyしてServiceを作成します。
$ kubectl apply -f simple-service.yaml service/echo created $ kubectl get svc echo NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo ClusterIP 10.102.218.109 <none> 80/TCP 7s
実際にrelease=summerを持つPodだけにアクセスできるか確認しましょう。
原則にServiceはKubernetesクラスタの中からしかアクセスできません。
そのためKubernetesクラスタ内に一時的なデバッグコンテナをデプロイし、コンテナ内からcurlコマンドで確認します。
リクエストとしては「http://【サービス名】」となります。 デバッグコンテナ内に入ったら、http://echo/に対してHTTPリクエストを何回か送信します。
$ kubectl run -i --rm --tty debug --image=gihyodocker/fundamental:0.1.0 --restart=Never -- bash -il If you don't see a command prompt, try pressing enter. debug:/# curl http://echo/ Hello Docker!!debug:/#
各Podのログを確認してみましょう。
# springラベルがついたPod。アクセスは来ていない。 $ kubectl logs -f echo-spring-drhn8 -c echo 2019/11/12 22:24:44 start server # summerラベルがついたPod。アクセスが来ている。 $ kubectl logs -f echo-summer-rxvmg -c echo 2019/11/12 22:24:43 start server 2019/11/12 23:05:01 received request 2019/11/12 23:05:06 received request 2019/11/12 23:05:07 received request # summerラベルがついたPod。アクセスが来ている。 $ kubectl logs -f echo-summer-zzjsv -c echo 2019/11/12 22:24:46 start server 2019/11/12 23:05:05 received request 2019/11/12 23:05:05 received request 2019/11/12 23:05:06 received request 2019/11/12 23:05:07 received request
ClusterIP Service
作成されるServiceには様々な種類があり、yaml内で定義できます。デフォルトがClusterIP Serviceです。
ClusterIPではKubernetesクラスタ上の内部IPアドレスにServiceを公開できます。これにより、あるPodから別のPod群へのアクセスはServiceを介して行うことができ、かつService名で名前解決ができるようになります。ただし、外からはリーチできません。
NodePort Service
NodePort Serviceはクラスタ外からアクセスできるServiceです。 NodePort ServiceはClusterIPを作るという点においてはClusterIP Serviceと同じです。各ノード上からServiceポートへ接続するためのグローバルなポートを開けるという違いがあります。
# simple-nodeport-service.yaml apiVersion: v1 kind: Service metadata: name: echo spec: type: NodePort selector: app: echo ports: - name: http port: 80
$ kubectl apply -f simple-nodeport-service.yaml service/echo configured $ kubectl get svc echo NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo NodePort 10.102.218.109 <none> 80:30270/TCP 50m $ curl http://127.0.0.1:30270 Hello Docker!!
LoadBalancer Service
LoadBalancer ServiceはローカルKubernetes環境では利用できないServiceです。主に各クラウドプラットフォームで提供されているロードバランサーと連携するためのものです。
ExternalName Service
ExternalName Serviceはselectorもport定義も持たないかなり特殊なServiceです。Kubernetesクラスタ内から外部のホストを解決するためのエイリアスを提供します。
例えば、次のようなServiceを作成するとgihyo.jpをgihyoで名前解決できるようになります。
apiVersion: v1 kind: Service metadata: name: gihyo spec: type: ExternalName externalName: gihyo.jp
まとめ
今回はServiceについて学びました。
次回はIngressについて学びます。