Repo I’m using to learn and experiment with the basics of Kubernetes in a local development environment. For the purpose of simplicity this repo is using mongo and mongo-express docker images.
Master Nodes! Master nodes control the cluster state and the worker nodes. There are 4 processes that run on every master node:
When we want to deploy a new application in a Kubernetes cluster we interact with the API server through some client (Kubernetes dashboard, CLI tool like Kubelet or the Kubernetes API). It servers as a cluster gateway that gets the initial requests of any updates into the cluster and the queries to the cluster.
After the API server validates a request it handles it to the Scheduler. It checks for current and desired resources and decides where to create/update/delete resources.
Daemon process in charge of detecting state changes within the cluster (i.e. crashing Pods
).
When a resource “dies” it will make a request to the Scheduler to re-schedule that resource.
Key-value store of the cluster state. Any change in the cluster is stored here (except application data).
This are the smallest deployable unit in K8s and an abstraction layer over Containers.
Generally we do NOT create these directly, instead they are created by resources like Deployments
or Jobs
.
apiVersion: v1
kind: Pod
metadata:
name: mongodb
spec:
containers:
- name: mongodb
image: mongo:6.0
ports:
- containerPort: 80
Declarative definition for Pods
and ReplicaSets
.
We can specify the desired:
.spec.template.spec.containers[n].image
attribute.Pods
with the .spec.replicas
attribute.spec.template.spec.containers[n].env
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb-deployment
spec:
replicas: 3 # default to 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo # https://hub.docker.com/_/mongo
ports:
- containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongodb-secret # secret name
key: mongo-root-username # secret data key
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secret # secret name
key: mongo-root-password # secret data key
Basically a static/permanent IP address that can be attached to pods in the corresponding network.
Its lifecycle is not connected to the referenced Pods.
The resulting url usually looks like this: protocol://node-ip-address:port
.
apiVersion: v1
kind: Service
metadata:
name: mongodb-service
spec:
selector:
app: mongodb # spec.selector.matchLabels.app from Deployment template
ports:
- port: 27017
targetPort: 27017
minikube service mongo-express-service
Manages external access to services in a cluster. It exposes HTTP/HTTPS routes from outside the cluster to services within it.
host
in Ingress
to access service:minikube tunnel
Maps external configuration of your application
apiVersion: v1
kind: ConfigMap
metadata:
name: mongo-configmap
data:
database_url: mongodb-service
Pretty much the same as ConfigMap but it is used to store secret data AND it is stored in base64 encoded format.
apiVersion: v1
kind: Secret
metadata:
name: mongodb-secret
type: Opaque
data:
mongo-root-username: dXNlcm5hbWU= # "username" base64 encoded
mongo-root-password: cGFzc3dvcmQ= # "password" base64 encoded
These provide a way to isolate groups of resources within a single cluster. Resource names have to be unique within a namespace, but not across namespaces
Command: kubectl get namespaces
NAME STATUS AGE
default Active 10h
kube-node-lease Active 10h
kube-public Active 10h
kube-system Active 10h
kube-system
kube-public
kubectl cluster-info
kube-node-lease
default
In the following ConfigMap database_url
will point to example-service
from example-namespace
apiVersion: v1
kind: ConfigMap
metadata:
name: example-configmap
data:
database_url: example-service.example-namespace
kubectl apply -f example-deployment.yml --namespace=example-namespace
apiVersion: v1
kind: ConfigMap
metadata:
name: example-configmap
namespace: example-namespace
data:
database_url: example-service
kubectl get all
will allways defer to the default
namespace unless told otherwise with -n namespace-name
.
There are tools like kubens
to have a more comfortable experience working with multiple namespaces
You usually can’t share resources between namespaces. (i.e. each namespace will have to have their own ConfigMap
to connect to a DB even if the config is the same)
Some components are cluster-specific and can’t be bound to a namespace (i.e. Volumes
and Nodes
)
Cluster resource that is used to store data. It assumes that you take care of your actual physical storage.
apiVersion: v1
kind: PersistentVolume
metadata:
name: mongo-persistent-volume
spec:
persistentVolumeReclaimPolicy: Retain
capacity:
storage: 1Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
storageClassName: manual
hostPath:
path: /mnt/mongodb
minikube
Command: minikube mount <host_dir>:<cluster_dir>
📁 Mounting host path ./mongo_volumes into VM as /mnt/mongodb ...
▪ Mount type: 9p
▪ User ID: docker
▪ Group ID: docker
▪ Version: 9p2000.L
▪ Message Size: 262144
▪ Options: map[]
▪ Bind Address: 172.23.105.90:37415
🚀 Userspace file server: ufs starting
✅ Successfully mounted ./mongo_volumes to /mnt/mongodb
📌 NOTE: This process must stay alive for the mount to be accessible ...
These allow a Pod to “claim” a persistent volume (and takes care of “picking” the “correct” persistent volume).
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongodb-persistent-volume-claim
spec:
storageClassName: manual
resources:
requests:
storage: 1Gi
volumeName: mongo-persistent-volume
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb-deployment
spec:
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
securityContext:
runAsUser: 999 # mongodb user
fsGroup: 999 # mongodb user
containers:
- name: mongodb
...
volumeMounts:
- name: random-volume-mount-name
mountPath: /data/db # as specified in mongo official docs and docker image info
securityContext:
privileged: true
volumes:
- name: random-volume-mount-name
persistentVolumeClaim:
claimName: mongodb-persistent-volume-claim