前回はKubernetesの概要について、解説しました。Kubernetesの管理は、APIサーバーを使用してユーザーや各コンポーネントから管理情報にアクセスするように設計されており、クラスタ上ではそれぞれ必要なコンポーネントが稼働しています。
クラスタを管理するには、ユーザーが理想状態を宣言し、その宣言された状態に動作するように各コンポーネントが各オブジェクトを構築します。今回は基本的なオブジェクトを4つ紹介します。
Kubernetes上でコンテナが実行されますが、Kubernetesはコンテナをそれぞれ個別に管理するわけではありません。1つ以上の関連するコンテナをPodという単位で管理します。
PodはKubernetesにおけるデプロイの最小単位です。
Kubernetesのクラスタ管理は、コンテナを1つずつ管理することはありません。1つのPodに含まれるコンテナはひとまとめとして扱われます。Pod内のコンテナは同一ノード上にデプロイされて、ネットワークやストレージの割り当てを共有します。
KubernetesはPodを起動するときに、クラスタ内で有効なIPアドレスをPod単位で払い出します。Pod内の各コンテナはその仮想的なネットワークインタフェースを共有して、Localhostで通信が可能です。
大規模なシステムになればなるほど、Podやコンテナの数も多くなり管理が煩雑になりがちです。Kubernetesでは、各リソースを分類するタグを付けることができます。タグにはアノテーションとラベルの2種類があります。
特定のPodに対して指示したい場合などに、ラベルを使って絞り込みを行い、指示を行うといった場合に利用します。
アノテーションもラベルと同じように、オブジェクトに付与できるメタデータですが、アノテーションを利用した絞り込みをすることはできず、Kubernetes自身が利用することを想定しています。
それでは試しに、基本的なPodの作成手順を見ていきましょう。
Podを作成するには、まずKubernetesのマニフェストファイルを作成する必要がある。
今回はMAC上のDocker for Desktopを利用してKubernetesの動作を確認します。
Applyを押してからKubernetesが有効になるまで5分ぐらいかかりますので、気長に待ちましょう。
もしKubernetes Startingのまま変わらず、Kubernetes Running にならない場合は、Dockerに割り当てているリソースが不足している可能性が高いため、以下の様にリソースの上限を変更してみましょう。
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クラスタとしてのアプリケーションをデプロイしていくのかを定義したものがマニフェストファイルになります。
Kuebernetesの基本リソースには、Pod/ReplicaSet/Deployment/Serviceの4つになります。
Podは先程説明したとおり、同一ノードで動作するコンテナの管理を行います。
ReplicaSetは、KubernetesでPodを管理するためのリソースで、指定した数のPodを起動し、その数を維持し続けてくれます。
また、Podがなんらかの理由で停止したら、ReplicaSetが再起動してくれます。
Kubernetesは、通常Podを単独で起動することはほとんどないため、ReplicaSetなどの管理用オブジェクトを通してPodを利用します。
Deploymentはアプリケーションのスケーリングやバージョンを管理するリソースです。具体的にDeploymentはクラスタ内のPodを管理するReplicaSetリソースを管理します。DeploymentリソースからReplicaSetおよびPodが自動的に作成されます。
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/」にアクセスして起動を確認します。
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>