はじめに
Kubernetesのマニフェストファイルの内容がよくわからない、という方いらっしゃるではないでしょうか?
私もその一人です。
今回はマニフェストファイルの読み方についてyamlコード内にコメントをつけて解説してきたいと思います。
補足説明はコード外にいたします。
マニフェストファイルの解説
apiVersion: apps/v1 # KubernetesにはAPIバージョンがあるためそれを記述します。 ①
kind: Deployment # リソースの種類を記述します。 (Ingress, Serviceなど) DeploymentはReplicaSetを生成/管理し、ReplicaSetはPod(Podの数 = レプリカ数)を生成/管理します。
metadata: # その名の通りメタデータ、要するに「そのデータ(ここではDeployment)に関連する情報を記述したデータ」を記述します。
name: nginx-deployment # Deploymentの名前を記述します。
namespace: default # 名前空間を記述します。 ②
spec: # ReplicaSetのあるべき姿を定義します。
replicas: 1 # レプリカ数を定義します = 1の場合1つのPodを要求します。
selector: # Deploymentの管理対象とするPodの情報を指定します。selectorによってラベルの条件が指定され、その条件に一致するPodがDeploymentによって管理されます。
matchLabels: # Podをラベルでフィルタリングします。 ③
app: nginx # Podが持つラベルを指定します。
template: # Deploymentが生成するPodの使用を定義します。 ④
metadata:
labels:
app: nginx
spec: # コンテナのスペックを定義します。使用するイメージ, cpu, memory, portなど
containers:
- name: nginx
image: nginx:1.27.1
resources:
requests:
cpu: "2"
memory: "10G"
ports:
- containerPort: 80 # コンテナのポートに関する情報です。 ⑤
livenessProbe: # Podに対するヘルスチェックを行う仕組みです。 ⑥
httpGet:
port: 80
path: /liveness/healthcheck
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 10
補足説明
① apiVersion
kubectlコマンドでkubectl api-resourcesとすると、以下のように各apiVersionを表示することができます。
$ kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
limitranges limits v1 true LimitRange
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
pods po v1 true Pod
podtemplates v1 true PodTemplate
replicationcontrollers rc v1 true ReplicationController
resourcequotas quota v1 true ResourceQuota
secrets v1 true Secret
serviceaccounts sa v1 true ServiceAccount
services svc v1 true Service
mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration
validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration
customresourcedefinitions crd,crds apiextensions.k8s.io/v1 false CustomResourceDefinition
apiservices apiregistration.k8s.io/v1 false APIService
controllerrevisions apps/v1 true ControllerRevision
daemonsets ds apps/v1 true DaemonSet
deployments deploy apps/v1 true Deployment
replicasets rs apps/v1 true ReplicaSet
statefulsets sts apps/v1 true StatefulSet
selfsubjectreviews authentication.k8s.io/v1 false SelfSubjectReview
tokenreviews authentication.k8s.io/v1 false TokenReview
localsubjectaccessreviews authorization.k8s.io/v1 true LocalSubjectAccessReview
selfsubjectaccessreviews authorization.k8s.io/v1 false SelfSubjectAccessReview
selfsubjectrulesreviews authorization.k8s.io/v1 false SelfSubjectRulesReview
subjectaccessreviews authorization.k8s.io/v1 false SubjectAccessReview
horizontalpodautoscalers hpa autoscaling/v2 true HorizontalPodAutoscaler
cronjobs cj batch/v1 true CronJob
jobs batch/v1 true Job
certificatesigningrequests csr certificates.k8s.io/v1 false CertificateSigningRequest
leases coordination.k8s.io/v1 true Lease
endpointslices discovery.k8s.io/v1 true EndpointSlice
events ev events.k8s.io/v1 true Event
flowschemas flowcontrol.apiserver.k8s.io/v1 false FlowSchema
prioritylevelconfigurations flowcontrol.apiserver.k8s.io/v1 false PriorityLevelConfiguration
ingressclasses networking.k8s.io/v1 false IngressClass
ingresses ing networking.k8s.io/v1 true Ingress
networkpolicies netpol networking.k8s.io/v1 true NetworkPolicy
runtimeclasses node.k8s.io/v1 false RuntimeClass
poddisruptionbudgets pdb policy/v1 true PodDisruptionBudget
clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
rolebindings rbac.authorization.k8s.io/v1 true RoleBinding
roles rbac.authorization.k8s.io/v1 true Role
priorityclasses pc scheduling.k8s.io/v1 false PriorityClass
csidrivers storage.k8s.io/v1 false CSIDriver
csinodes storage.k8s.io/v1 false CSINode
csistoragecapacities storage.k8s.io/v1 true CSIStorageCapacity
storageclasses sc storage.k8s.io/v1 false StorageClass
volumeattachments storage.k8s.io/v1 false VolumeAttachment
grepすることで、このマニフェストのapiVersionってなんだっけ?を確認する手段として使用できます。
> kubectl api-resources | grep deployment
deployments deploy apps/v1 true Deployment
② namespace
namespaceとは例えると家の中でそれぞれの名前が付けられた部屋を作って分離することです。
家(クラスター)の中に各部屋(namespace)が存在し、それぞれの部屋は独立して管理されています。
例えば、4人家族で父、母、娘、息子の家族構成の場合、娘の部屋、息子の部屋、寝室などを倫理的に区切り、それらは独立して管理できるようにしています。
娘の部屋を模様替えしても、息子の部屋まで模様替えされることはありえません。
namespaceの運用方法として例えば運用と開発のチームごとに、namespaceを分離することです。
- 運用のnamespaceには特定のリソースに対してのみ読み取り権限を与える
- 開発のnamespaceにはリソースの作成、変更削除をできる権限を与える
といった具合です。
Kubernetesにはデフォルトで以下のnamespaceが存在し、この名前空間をすぐに使用できるように設定されています。
- default
- kube-system (Kubernetesコンポーネントに使用)
- kube-public (パブリックリソースに使用)
以下コマンドを実行することでnamespaceの情報を取得することができます。
> kubectl get namespace
NAME STATUS AGE
default Active 192d
kube-node-lease Active 192d
kube-public Active 192d
kube-system Active 192d
kubernetes-dashboard Active 192d
namespaceを作成する場合は以下コマンドで作成することができます。
> kubectl create namespace <名前空間名>
③ matchLabels
説明が長くなりそうなので補足します。
Podをラベルでフィルタリングする方法がmatchLabelsです。
matchLabelsにapp: nginxというラベルが指定されています。
つまり、app: nginxというラベルを持つPodがDeploymentによって管理される対象となります。
selector:
matchLabels:
app: nginx
DeploymentはReplicaSetを生成/管理し、ReplicaSetはPodを生成/管理します。
ReplicaSetは指定されたPod数に調整、管理を行う仕組みです。

マニフェストにReplicasetを定義することで、障害などでPodがダウンした際にも自動的に指定の数にPod数を調整してくれます。
Deploymentは例えばコンテナのイメージのバージョンアップをしなければならない場合などに、新しいReplicaSetを作成し、新旧の全体のPod数を調整しながら新しいPodを生成します。

④ templateとmatchLabelsの違い
templateの役割
Podの仕様を定義する部分で、「どんなコンテナを使用するか」「どんなリソースを要求するか」「どんなラベルを付けるのか」といったことを設定します。
template以下を見てもらうとわかりやすいかと思いますが、ぱっと見でも「コンテナの名前」「コンテナのイメージ」「コンテナのスペック」などが定義されているのがわかります。
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27.1
resources:
requests:
cpu: "2"
memory: "10G"
ports:
- containerPort: 80
以下に記述されているtemplate.metadata.labelsに記述されているフィールドは生成されるPodにどんなラベルを付けるを指定する箇所です。
生成されるPodにはapp: nginxというラベルが付与されます。
template:
metadata:
labels:
app: nginx
matchLabelsの役割
selector.matchLabelsについては「app: nginxというラベルを持つPodを管理します」ということを指定しています。
selector:
matchLabels:
app: nginx
Deploymentによる管理の流れは以下のようになります。
-
DeploymentはPodを作成するときにtemplateに基づいてPodを生成します。この時、生成される全てのPodにapp: nginxというラベルが付与されます。 -
selector.matchLabelsは「app: nginxというラベルを持つPod」を管理対象として指定します。
Deployment
└─ spec:
└─ template: <-- Podがこのテンプレートに従って作成される
└─ metadata:
└─ labels:
└─ app: nginx <-- 作成されたPodに「app=nginx」ラベルが付与される
└─ spec:
└─ selector: <-- このラベルに一致するPodを管理する
└─ matchLabels:
└─ app: nginx
⑤ containerport
このcontainerportですが、あくまでコンテナのポートは80を指定していますよ、ということにすぎず、実際にマニフェストファイルにポートを記述したからと言って記述したポートが実際のコンテナに設定されるわけではありません。
つまりただの飾りであることがわかりました。
以下の公式ドキュメントに内にも
https://kubernetes.io/ja/docs/concepts/services-networking/connect-applications-service/
コンテナポートの仕様を指定していることに注意してください。
と記載があるように、仕様を指定しているにすぎません。
ほんとですか?という信じられない気持ちでしたので検証してみました。
前提としてKubernetesクラスターはkindを使用してKubernetesリソースの作成ができている状態で検証しております。
以下のDockerfileを準備します。
# Dockerfile
FROM nginx:latest
# Install bash net-tools
RUN apt-get update && apt-get install -y bash bash net-tools && rm -rf /var/lib/apt/lists/*
docker image を作成します。
docker image build -t my-nginx .
containerportを8080にしてPodを生成します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-liveness-check
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: nginx-liveness
template:
metadata:
labels:
app: nginx-liveness
spec:
containers:
- name: nginx
image: my-nginx:latest
ports:
- containerPort: 8080
applyしてPodを作成 -> 起動します。
kubectl get podsでRunningになっていることを確認します。
kubectl apply -f <yamlファイル名>
kubectl get pods -w
NAME READY STATUS RESTARTS AGE
<Pod名> 1/1 Running 0 4s
以下コマンドでコンテナに接続します。
kubectl exec -it <Pod名> -- /bin/bash
netstatでリッスンしているポートを確認すると0.0.0.0:80となっているので8080でリッスンしていないことが確認できます。
netstat -tnlp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1/nginx: master pro
tcp6 0 0 :::80 :::* LISTEN 1/nginx: master pro
まんまと騙されましたが、マニフェストに記載するcontainerportはただの飾りであることがわかりました。
⑥ Probeについて
Probeについては以前の記事で解説しておりますので、こちらを参照ください。
最後に
Kubernetesマニフェストファイルの中身についてどんな意味なのかについて深掘りしていきました。
あいまいだった理解がアウトプットすることで少しづつ深まっていきました。
また、実際に動作確認することで、見た目に騙されないマニフェストファイルの奥深さを理解できて非常に勉強になりました。
本記事がマニフェストファイルの読み方がわからない、という方の助けになれば幸いです。
参考