
If you have ever worked with containers such as Docker, you know how efficient and fast they are.
Kubernetes is a container orchestrator that automates deployments and shutdowns to make applications highly available and elastic in response to demand fluctuations.
Everything starts with a Cluster, the “pool” that contains N resources called Nodes.
The first node is the “master” and manages the workload on the other nodes, called “workers”.
Pods (which contain the containers running the application) are distributed among the nodes for better performance.
Kubernetes can scale the number of nodes up or down based on parameters such as CPU or RAM usage, indicating whether physical resources are insufficient or idle.
INSTALLING KUBERNETES
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl chmod +x ./kubectl sudo mv ./kubectl /usr/local/bin/kubectl
Download the configuration file from your Kubernetes server and assign it to a variable (store it in a safe location with appropriate permissions):
export KUBECONFIG=kube1-kubeconfig.yaml
MANAGING KUBERNETES
Useful commands for managing the cluster:
kubectl --help kubectl get nodes kubectl cluster-info
Example of a simple manual container deployment:
kubectl run nginx-api --image=nginx --port=80 kubectl get pods kubectl describe pods kubectl delete pods nginx-api
Getting a Shell into the Container
kubectl exec --stdin --tty nginx-api-***********-**** -- bash
kubectl exec -it nginx-api-***********-**** -- bash
Automating Deployments
Create deployments.yaml using the template below (indentation must be respected):
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-instance
spec:
replicas: 6
selector:
matchLabels:
app: nginx-instance
template:
metadata:
labels:
app: nginx-instance
spec:
containers:
- name: nginx-instance
image: nginx
imagePullPolicy: Always
ports:
- containerPort: 80
kubectl apply -f nginx-deployment.yaml
Editing the deployment configuration:
export KUBE_EDITOR=nano kubectl edit deployment nginx-deployment kubectl get pods -o wide
Load Balancer
Create a file called loadbalancer.yaml as shown below:
apiVersion: v1 kind: Service metadata: name: nginx-loadbalancer annotations: service.beta.kubernetes.io/linode-loadbalancer-throttle: "5" labels: app: nginx-loadbalancer spec: type: LoadBalancer selector: app: nginx-instance ports: - name: http protocol: TCP port: 80 targetPort: 80 sessionAffinity: None
kubectl apply -f loadbalancer.yaml kubectl get services kubectl describe service nginx-loadbalancer
Port Forwarding
kubectl port-forward app-********-***** 8080:80 kubectl port-forward pods/app-********-***** 8080:80 kubectl port-forward deployment/app 8080:80 kubectl port-forward replicaset/app-******** 8080:80 kubectl port-forward service/app 8080:80
NGINX is now accessible externally through the load balancer service!
Other useful commands:
kubectl get pods -w kubectl get all kubectl scale deploy/nginx --replicas=3 kubectl rollout status deploy/nginx kubectl rollout undo deploy/nginx kubectl deploy nginx --image=nginx:1.17-alpine -o yaml --dry-run=client kubectl explain services
BONUS
Recover an accidentally deleted manifest file from a K8s runtime:
kubectl get <resource-type> <resource-name> -n <namespace> -o yaml > manifest.yaml
Install the Helm package manager:
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
Free SSL/TLS certificate from Let’s Encrypt.
Install the prerequisites:
helm repo add jetstack https://charts.jetstack.io helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.17.2 --set crds.enabled=true helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginx --create-namespace --set controller.kind=DaemonSet --set controller.hostNetwork=true --set controller.daemonset.useHostPort=true --set controller.service.type="" --set controller.ingressClassResource.name=nginx
Optionally, Traefik can be set as the default ingress controller:
helm repo add traefik https://traefik.github.io/charts helm install traefik traefik/traefik
Cluster Issuer
cat < cluster-issuer.yml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
email: [email protected]
server: https://acme-staging-v02.api.letsencrypt.org/directory
# server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt
solvers:
- http01:
ingress:
class: nginx
EOF
kubectl apply -f cluster-issuer.yml
sleep 10
kubectl get clusterissuer
kubectl describe clusterissuer
Certificate
cat < certificate.yml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: certificate-name
namespace: default
spec:
secretName: tls-secret-name
issuerRef:
name: letsencrypt
kind: ClusterIssuer
dnsNames:
- app.dev.example.com
# - app.example.com
# Up to 100 additional domains per single cert.
EOF
kubectl apply -f certificate.yml
sleep 10
kubectl describe certificate
kubectl describe certificaterequest
kubectl describe order
kubectl describe challenges
Inline creation of an ingress with an SSL certificate:
kubectl create ingress <ingress-name> --rule=example.com/*=web:80,tls=<certificate-name>
Rollout (or rollback) and restart of all pods in a deployment:
kubectl rollout restart deployment <deployment-name>
Meet etcd, the distributed key-value store that guarantees the integrity of critical data in a distributed system like K8s [Link].
- It runs in the background and keeps all nodes in a K8s cluster in sync.
- It provides strong consistency and distributed coordination using the Raft algorithm.
- It makes intensive use of non-volatile memory and only returns success when a quorum is reached.
sudo apt-get update wget https://github.com/etcd-io/etcd/releases/download/v3.6.6/etcd-v3.6.6-linux-amd64.tar.gz tar -xvzf etcd-v3.6.6-linux-amd64.tar.gz cd etcd-v3.6.6-linux-amd64/ sudo mv etcd etcdctl /usr/local/bin/ && etcd --version sudo mkdir -p /etc/etcd /var/lib/etcd sudo useradd -r -s /sbin/nologin etcd cat <<EOF > /etc/systemd/system/etcd.service [Unit] Description=etcd key-value store Documentation=https://etcd.io/docs/ After=network.target [Service] User=etcd Type=notify ExecStart=/usr/local/bin/etcd –name default –data-dir /var/lib/etcd –listen-client-urls http://0.0.0.0:2379 –advertise-client-urls http://localhost:2379 Restart=on-failure LimitNOFILE=40000 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo chown -R etcd:etcd /var/lib/etcd sudo chmod 700 /var/lib/etcd sudo systemctl enable etcd --now
Now, test it:
etcdctl put hello "Ubuntu 24.04"
etcdctl get hello
SEE ALSO
Minikube on Ubuntu 22.04 [Link].
MicroK8s on Ubuntu 22.04 [Link].
K3s on Ubuntu 22.04 [Link].
Kubernetes Persistent Volumes [Link].
Kubernetes Dashboard [Link].
kURL – Open Source Kubernetes Installer [Link].
K0s – Single Binary K8s [Link]
K9s – CLI Tool [Link].