Kubernetesの基本動作確認

前回はKubernetesの概要について、解説しました。Kubernetesの管理は、APIサーバーを使用してユーザーや各コンポーネントから管理情報にアクセスするように設計されており、クラスタ上ではそれぞれ必要なコンポーネントが稼働しています。

クラスタを管理するには、ユーザーが理想状態を宣言し、その宣言された状態に動作するように各コンポーネントが各オブジェクトを構築します。今回は基本的なオブジェクトを4つ紹介します。

Pod

Kubernetes上でコンテナが実行されますが、Kubernetesはコンテナをそれぞれ個別に管理するわけではありません。1つ以上の関連するコンテナをPodという単位で管理します。
PodはKubernetesにおけるデプロイの最小単位です。

Kubernetesのアーキテクチャ

Kubernetesのクラスタ管理は、コンテナを1つずつ管理することはありません。1つのPodに含まれるコンテナはひとまとめとして扱われます。Pod内のコンテナは同一ノード上にデプロイされて、ネットワークやストレージの割り当てを共有します。

KubernetesはPodを起動するときに、クラスタ内で有効なIPアドレスをPod単位で払い出します。Pod内の各コンテナはその仮想的なネットワークインタフェースを共有して、Localhostで通信が可能です。

ラベルとアノテーションについて

大規模なシステムになればなるほど、Podやコンテナの数も多くなり管理が煩雑になりがちです。Kubernetesでは、各リソースを分類するタグを付けることができます。タグにはアノテーションラベルの2種類があります。

特定のPodに対して指示したい場合などに、ラベルを使って絞り込みを行い、指示を行うといった場合に利用します。

アノテーションもラベルと同じように、オブジェクトに付与できるメタデータですが、アノテーションを利用した絞り込みをすることはできず、Kubernetes自身が利用することを想定しています。

Podのマニフェストを作成してみる

それでは試しに、基本的なPodの作成手順を見ていきましょう。
Podを作成するには、まずKubernetesのマニフェストファイルを作成する必要がある。

事前準備

今回はMAC上のDocker for Desktopを利用してKubernetesの動作を確認します。

Docker for MacでKubernetesを有効化する

Applyを押してからKubernetesが有効になるまで5分ぐらいかかりますので、気長に待ちましょう。
もしKubernetes Startingのまま変わらず、Kubernetes Running にならない場合は、Dockerに割り当てているリソースが不足している可能性が高いため、以下の様にリソースの上限を変更してみましょう。

Docker for Macのリソースを調整する

KubernetesのCLIであるkubectlもインストールされます。

❯ kubectl version
Client Version: version.Info{Major:"1", Minor:"16+", GitVersion:"v1.16.6-beta.0", GitCommit:"e7f962ba86f4ce7033828210ca3556393c377bcc", GitTreeState:"clean", BuildDate:"2020-01-15T08:26:26Z", GoVersion:"go1.13.5", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"16+", GitVersion:"v1.16.6-beta.0", GitCommit:"e7f962ba86f4ce7033828210ca3556393c377bcc", GitTreeState:"clean", BuildDate:"2020-01-15T08:18:29Z", GoVersion:"go1.13.5", Compiler:"gc", Platform:"linux/amd64"}

マニフェストファイル

マニフェストファイルは、システムのあるべき姿を書いているファイルで、yamlやjsonで記述します。Kubernetesは宣言的な構成管理という思想を取り入れています。

宣言的に記述したマニフェストファイルをkubectlを使ってマスタに渡すと、勝手にPodをデプロイしてくれたり、Nodeにコンテナをデプロイしたりしてくれて、あとは良い感じに監視や維持管理をしてくれます。

Kubernetesのリソース(ネットワークの設定やポート番号など)は、ServiceやIngressと呼ばれるリソースによって定義していきます。これらのリソースをどのように構成してKubernetesクラスタとしてのアプリケーションをデプロイしていくのかを定義したものがマニフェストファイルになります。

Kubernetesのアーキテクチャ

Kuebernetesの基本リソースには、Pod/ReplicaSet/Deployment/Serviceの4つになります。

Pod

Podは先程説明したとおり、同一ノードで動作するコンテナの管理を行います。

ReplicaSet

ReplicaSetは、KubernetesでPodを管理するためのリソースで、指定した数のPodを起動し、その数を維持し続けてくれます。
また、Podがなんらかの理由で停止したら、ReplicaSetが再起動してくれます。
Kubernetesは、通常Podを単独で起動することはほとんどないため、ReplicaSetなどの管理用オブジェクトを通してPodを利用します。

Deploymentリソース

Deploymentはアプリケーションのスケーリングやバージョンを管理するリソースです。具体的にDeploymentはクラスタ内のPodを管理するReplicaSetリソースを管理します。DeploymentリソースからReplicaSetおよびPodが自動的に作成されます。

Serviceリソース

Kubernetesのネットワークの定義をおこなうリソースです。ClusterIP、LoadBalancer、NodePortなどの種類があります。

それでは、nginxを起動するためのマニフェストファイルを作成します。

apiVersion: apps/v1 # APIバージョン
kind: Deployment #リソースの種類
metadata:
  name: nginx-test
spec:
  selector:
    matchLabels:
      app: nginx #テンプレートを指定
  replicas: 3 #レプリカ数(Podの数)
  template:
    metadata:
      labels:
        app: nginx #「nginx」というLabelを付ける
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80 #ポート番号
---
apiVersion: v1
kind: Service #リソースの種類
metadata:
  name: service-test
spec:
  type: NodePort
  ports:
    - port: 80
      nodePort: 30000
  selector: #下記のLabel(ラベル)を指定したPodに伝送
    app: nginx

マニフェストファイルのデプロイ

作成したマニフェストファイルをkubectlでデプロイしてみます。

❯ kubectl create -f nginx.yaml
deployment.apps/nginx-text created
service/service-test created

「http://localhost:30000/」にアクセスして起動を確認します。

Nginxの動作画面

Deoloymentの一覧を確認してみます。 (-o wideオプションを付与すると詳細が確認できます)

❯ kubectl get deploy -o wide
NAME         READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES         SELECTOR
nginx-test   3/3     3            3           11m   nginx        nginx:latest   app=nginx

作成されたPodの一覧を確認してみます。

❯ kubectl get pods -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP         NODE             NOMINATED NODE   READINESS GATES
nginx-test-59c9f8dff-mf28n   1/1     Running   0          12m   10.1.0.9   docker-desktop   <none>           <none>
nginx-test-59c9f8dff-sh8lt   1/1     Running   0          12m   10.1.0.7   docker-desktop   <none>           <none>
nginx-test-59c9f8dff-vw2js   1/1     Running   0          12m   10.1.0.8   docker-desktop   <none>           <none>

Podの詳細は以下のコマンドで確認します。

❯ kubectl describe pod nginx-test-59c9f8dff-mf28n
Name:         nginx-test-59c9f8dff-mf28n 
Namespace:    default
Priority:     0
Node:         docker-desktop/192.168.65.3
Start Time:   Mon, 22 Jun 2020 15:02:36 +0900
Labels:       app=nginx
              pod-template-hash=59c9f8dff
Annotations:  <none>
Status:       Running
IP:           10.1.0.18
IPs:
  IP:           10.1.0.18
Controlled By:  ReplicaSet/nginx-test-59c9f8dff
Containers:
  nginx:
    Container ID:   docker://667feeeaf0c9df1d959611568bb6e8e7d37cac15338ed28841500fef5199a3e0
    Image:          nginx:latest
    Image ID:       docker-pullable://nginx@sha256:21f32f6c08406306d822a0e6e8b7dc81f53f336570e852e25fbe1e3e3d0d0133
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 22 Jun 2020 15:02:41 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-7x8h2 (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-7x8h2:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-7x8h2
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age        From                     Message
  ----    ------     ----       ----                     -------
  Normal  Scheduled  <unknown>  default-scheduler        Successfully assigned default/nginx-test-59c9f8dff-mf28n to docker-desktop
  Normal  Pulling    30s        kubelet, docker-desktop  Pulling image "nginx:latest"
  Normal  Pulled     26s        kubelet, docker-desktop  Successfully pulled image "nginx:latest"
  Normal  Created    26s        kubelet, docker-desktop  Created container nginx
  Normal  Started    26s        kubelet, docker-desktop  Started container nginx

Podのログを確認することも可能です。

❯ kubectl logs nginx-test-59c9f8dff-mf28n 
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up

デプロイの詳細を確認するには、次のコマンドを実行します。

❯ kubectl describe deploy nginx-test
Name:                   nginx-test
Namespace:              default
CreationTimestamp:      Mon, 22 Jun 2020 13:12:31 +0900
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=nginx
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:        nginx:latest
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   nginx_test-59c9f8dff (3/3 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  16m   deployment-controller  Scaled up replica set nginx-test-59c9f8dff to 3

ReplicaSet一覧を確認するには次のコマンドを実行します。

❯ kubectl get rs -o wide
NAME                   DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES         SELECTOR
nginx-test-59c9f8dff   3         3         3       20m   nginx        nginx:latest   app=nginx,pod-template-hash=59c9f8dff

Service一覧を確認するには次のコマンドを実行します。

❯ kubectl get svc -o wide
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE    SELECTOR
kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP        130m   <none>
service-test   NodePort    10.109.86.138   <none>        80:30000/TCP   2s     app=nginx

自動回復の確認

それでは1つのPodを削除してみます。

❯ kubectl delete pod nginx-test-59c9f8dff-mf28n
pod "nginx-test-59c9f8dff-mf28n" deleted

自動回復機能が動作し、新しいPodが作成されました。

❯ kubectl get pods -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP         NODE             NOMINATED NODE   READINESS GATES
nginx-test-59c9f8dff-nglpf   1/1     Running   0           5s   10.1.0.9   docker-desktop   <none>           <none>
nginx-test-59c9f8dff-sh8lt   1/1     Running   0          12m   10.1.0.7   docker-desktop   <none>           <none>
nginx-test-59c9f8dff-vw2js   1/1     Running   0          12m   10.1.0.8   docker-desktop   <none>           <none>

関連記事