Kubernetesの実体はPodやServiceなどのリソースです。したがって、どういったリソースがあるかをつかむことでKubernetesの全体像をイメージできます。
リソースに関する記述はYAMLであるため、少し割り切って言えば、Kubernetesを理解することは、YAMLにおけるリソースの記述方法を理解することとほぼ同義です。
Kubernetesのリソースは5つのリソースタイプに分類されます。前回説明したPod/ReplicaSet/DeploymentはWorkloadsに分類され、ServiceはDiscovery & LBに分類されます。リソースを定義するYAMLの記述方法の詳細はAPIドキュメントを参照ください。
Workloadsは前回紹介したPod/ReplicaSet/Deploymentなど、Kubernetesを構成する基本的なリソースです。今回は、Pod/ReplicaSet/Deployment以外のWorkloadsリソースを紹介します。
DaemonSet
まずは、DaemonSetです。ReplicaSetがノードにいくつPodが配置されるかはKubernetesに委ねられるのに対し、DaemonSetはノードに1つずつPodを配置します。具体的な利用シーンとしては、ログ収集のエージェントなどがあります。
なお、特定ノードにのみリソースを配置する場合には、ノードに対してTaints/Tolerations設定を行います。
$cat daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
# NodeにTaints設定されているkey-valueを設定することで、配置可能となる
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: k8s.gcr.io/fluentd-elasticsearch:1.20
# ボリューム設定
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
hostPath:
path: /var/log
$kubectl apply -f daemonset.yaml
daemonset.apps/fluentd-elasticsearch created
$kubectl get daemonsets
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
fluentd-elasticsearch 1 1 0 1 0 <none> 21s
StatefulSet
次にStatefulSetです。データベースなど、データの永続化の用途で利用されます。StatefultSetに2つのPodを立て、データを[index.html]ファイルに永続化する例をみてみましょう。
$cat statefulset.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
# マウントするボリュームのパス
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
$kubectl apply -f statefulset.yaml
service/nginx created
statefulset.apps/web created
$kubectl get statefulset web
NAME DESIRED CURRENT AGE
web 2 1 37s
Pod名が[web-0]、[web-1]といった形で連番になるのが特徴です。以下の例では、連番である特徴を使って[for i in 0 1; do kubectl exec web-$i]の形でforループで各Podに対して処理を実行しています 。
$kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 2m
web-1 1/1 Running 0 1m
$for i in 0 1; do kubectl exec web-$i -- sh -c 'echo hello $(hostname) > /usr/share/nginx/html/index.html'; done
$for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done
hello web-0
hello web-1
Job/CronJob
最後にJobとCronJobです。Jobはバッチ処理のようなケースを想定し、処理が終わったらPodが(正常)終了します。CronJobはJobをスケジュール実行するためのリソースです。LinuxのCrontabのようなイメージで実行時間は、分、時、日、月、曜日を指定できます。例えば、毎月10日の12:30に実行する場合は、「30 12 10 * *」といった形で指定します。
JobとCronJobの関係をつかむために、1分ごとに日時と「Hello Kubernetes」と返すだけのジョブを実行してみましょう 。
$vi cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello Kubernetes
restartPolicy: OnFailure
$kubectl apply -f cronjob.yaml
cronjob.batch/hello created
$kubectl get cronjob
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 0 <none> 14s
$kubectl get job
NAME DESIRED SUCCESSFUL AGE
hello-1539424740 1 0 5s
$kubectl get pods --selector=job-name=hello-1539425040 --output=jsonpath={.items..metadata.name}
hello-1539425040-9w7gf$
$kubectl logs hello-1539425040-9w7gf
Sat Oct 13 10:04:13 UTC 2018
Hello Kubernertes
* * *
今回は、5つのリソースタイプのうち、Workloadsを説明しました。前回説明したPod/ReplicaSet/Deploymentと併せて理解しておきましょう。
次回以降、Discovery&LBなどの残りのリソースタイプを説明していきます。
著者紹介
正野 勇嗣 (SHONO Yuji ) - NTTデータ 課長
2011年まで開発自動化技術のR&Dに従事。その後、開発プロジェクト支援やトラブルシューティング等に主戦場を移す。「ソースコード自動生成」に加えて、JenkinsやMaven等の「ビルド自動化」、JsTestDriverやSelenium等の「テスト自動化」を扱うようになり、多様化する開発自動化技術動向に興味。
最近は第四の自動化であるInfrastructure as Code等の「基盤自動化」の魅力に惹かれている。開発自動化技術に関する雑誌・記事執筆も行う。3児のパパ。