apiVersion: v1
kind: Service
metadata:
name: mongodb
labels:
app: mongodb
spec:
clusterIP: None
selector:
app: mongodb
ports:
- port: 27017
targetPort: 27017
Save the above YAML in mongodb-svc.yaml
and create the Service by running kubectl apply -f mongodb-svc.yaml
. If you list the Services, you will notice the mongodb
Service does not have an IP address set:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 47h
mongodb ClusterIP None <none> 27017/TCP 1s
Next, we will create the following StatefulSet:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
serviceName: mongodb
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
selector: mongodb
spec:
containers:
- name: mongodb
image: mongo:4.0.17
ports:
- containerPort: 27017
volumeMounts:
- name: pvc
mountPath: /data/db
volumeClaimTemplates:
- metadata:
name: pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Save the above YAML in mongodb-statefulset.yaml
and create the StatefulSet by running kubectl apply -f mongodb-statefulset.yaml
.
If you list the Pods, you will notice you created a single Pod named mongodb-0
:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mongodb-0 1/1 Running 0 29m
Similarly, let's list the PersistentVolumes and PersistentVolumeClaims:
$ kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-275f7731-0f10-4b33-b99a-3cc95d0be30a 1Gi RWO Delete Bound default/pvc-mongodb-0 standard 31m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/pvc-mongodb-0 Bound pvc-275f7731-0f10-4b33-b99a-3cc95d0be30a 1Gi RWO standard 31m
Notice the naming of both resources - the PVC uses the name (pvc
) we provided under the volumeClaimTemplates
, and it appends the name of the Pod (mongodb-0
) to it. Kubernetes prefixes the PersistentVolume name with the PVC name (pvc
). The rest of the name is a unique identifier.
Let's see what happens if we scale the StatefulSet to 3 Pods:
$ kubectl scale statefulset mongodb --replicas=3
statefulset.apps/mongodb scaled
If you watch the Pods as Kubernetes creates them (kubectl get pods -w
) you will notice they are created in order - the replica named mongodb-1
is created first, and after that replica mongodb-2
is created.
A StatefulSet stores the name of the pod in label called statefulset.kubernetes.io/pod-name
. You can see these labels if you run kubectl get po --show-labels
:
$ kubectl get po --show-labels
NAME READY STATUS RESTARTS AGE LABELS
mongodb-0 1/1 Running 0 44m statefulset.kubernetes.io/pod-name=mongodb-0
mongodb-1 1/1 Running 0 2m34s statefulset.kubernetes.io/pod-name=mongodb-1
mongodb-2 1/1 Running 0 2m30s statefulset.kubernetes.io/pod-name=mongodb-2