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.
- Dependencies
- K8s
- Pods
- Deployments
- Services
- Ingress
- ConfigMap
- Secrets
- Namespaces
- Persistent Volumes
- Persistent Volume Claims)
- Sources
- Open source container orchestration tool
- Helps manage containerized applications in different environments
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
.
- Ephemeral (they can "die" easily)
- Usually 1 application per Pod
- Each pod gets their IP address (internal)
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:
- container image with the
.spec.template.spec.containers[n].image
attribute. - number
Pods
with the.spec.replicas
attribute - environment variables with
.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.
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
- Not meant to be interacted with
- System processes
- Master and Kubectl processes
- Publicly accessidble data
- Has a config map that contains cluster information
- i.e.
kubectl cluster-info
- i.e.
- Info about hearbeats of nodes
- Lease object associated to each node in namespace
- Determines availability of each node
- Everything you create will default to this namespace
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
andNodes
)
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
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
- Kubernetes official docs
- Kubernetes Tutorial for Beginners - by TechWorld with Nana