hoatranlab.io.vn Zalo: 0917516878 Hotline: 0917516878 [email protected]
HoaTranLab Logo HoaTranLab
Linux Bible 11th Edition • Chapter 31

Deploying Applications as Containers with Kubernetes

Làm chủ Kubernetes: kiến trúc cluster, kubectl commands, YAML manifests (Deployment/Service/ConfigMap), Minikube, scaling, rolling updates và Helm.

Mục tiêu học tập

Kiến trúc Kubernetes

Hiểu Control Plane (API server, scheduler, controller-manager, etcd) và Data Plane (kubelet, container runtime, kube-proxy) trên worker nodes.

kubectl Commands

Thành thạo kubectl: get, describe, apply, delete, logs, exec, scale, rollout để quản lý resources trên Kubernetes cluster.

YAML Manifests

Viết Kubernetes manifests: Deployment, Service (ClusterIP/NodePort/LoadBalancer), ConfigMap, Namespace để deploy applications.

Minikube

Cài đặt và sử dụng Minikube để chạy Kubernetes cluster cục bộ trên laptop, phù hợp cho học tập và development.

Scaling & Rolling Updates

Scale deployments tăng/giảm replicas, thực hiện rolling updates và rollback khi deployment gặp vấn đề.

Helm Package Manager

Sử dụng Helm để install, upgrade và manage Kubernetes applications thông qua Helm charts.

Lý thuyết: Kubernetes

1. Kiến trúc Kubernetes Cluster

Control Plane

  • kube-apiserver: API gateway, nhận tất cả requests. Trung tâm giao tiếp.
  • kube-scheduler: Quyết định pod chạy trên node nào dựa vào resources.
  • kube-controller-manager: Đảm bảo desired state (replicas, endpoints...).
  • etcd: Distributed key-value store, lưu trữ cluster state.
  • cloud-controller-manager: Tích hợp với cloud provider APIs (AWS/Azure/GCP).

Worker Nodes (Data Plane)

  • kubelet: Agent trên mỗi node, nhận PodSpecs từ API server, đảm bảo containers chạy.
  • containerd: Container runtime (thay Docker từ K8s v1.23).
  • kube-proxy: Network proxy, maintain network rules cho pods.
  • Pods: Đơn vị nhỏ nhất, chứa 1+ containers cùng network namespace.

Pod

Nhóm 1+ containers chia sẻ network/storage. Ephemeral — có thể bị destroy và recreate bất kỳ lúc nào.

Deployment

Quản lý ReplicaSets và Pods. Định nghĩa desired state: bao nhiêu replicas, container image nào.

Service

Stable IP/DNS name cho một set of pods. Load balances traffic. Types: ClusterIP, NodePort, LoadBalancer.

Namespace

Logical partitioning của cluster. Mặc định: default, kube-system, kube-public. Cô lập resources.

ConfigMap

Lưu config data dạng key-value. Inject vào pods qua env vars hoặc volume mounts.

Secret

Như ConfigMap nhưng cho sensitive data (passwords, tokens). Base64 encoded, có thể encrypt at rest.

2. Cài đặt Minikube

Terminal - Cài đặt Minikube trên Linux x86-64

# Tải và cài đặt minikube binary

$ curl -LO https://github.com/kubernetes/minikube/releases/latest/download/minikube-linux-amd64

$ sudo install minikube-linux-amd64 /usr/local/bin/minikube

$ rm minikube-linux-amd64

# Khởi động cluster

$ minikube start

* minikube v1.35.0 on Fedora 42

* Automatically selected the kvm2 driver

* Creating kvm2 VM (CPUs=2, Memory=2200MB, Disk=20000MB) ...

* Preparing Kubernetes v1.31.0 on Docker 27.2.0 ...

* Done! kubectl is now configured to use "minikube"

# Kiểm tra cluster

$ minikube version

minikube version: v1.35.0

$ kubectl cluster-info

Kubernetes control plane is running at https://localhost:36355

CoreDNS is running at https://localhost:36355/api/v1/namespaces/kube-system/...

3. kubectl Cơ bản

Terminal - kubectl commands

# Xem thông tin nodes

$ kubectl get nodes

NAME STATUS ROLES AGE VERSION

minikube Ready control-plane 5m v1.31.0

# Xem tất cả pods ở mọi namespace

$ kubectl get pods --all-namespaces

NAMESPACE NAME READY STATUS RESTARTS

kube-system coredns-7db6d8ff4d-x9p5t 1/1 Running 0

kube-system etcd-minikube 1/1 Running 0

kube-system kube-apiserver-minikube 1/1 Running 0

# Deploy nginx nhanh

$ kubectl create deployment nginx-demo --image=nginx:latest

deployment.apps/nginx-demo created

$ kubectl get pods

NAME READY STATUS RESTARTS AGE

nginx-demo-7d458d8d74-xk9p2 1/1 Running 0 30s

# Describe pod chi tiết

$ kubectl describe pod nginx-demo-7d458d8d74-xk9p2

Name: nginx-demo-7d458d8d74-xk9p2

Namespace: default

Node: minikube/192.168.49.2

Status: Running

IP: 10.244.0.5

# Xem logs của pod

$ kubectl logs nginx-demo-7d458d8d74-xk9p2

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration

# Exec vào container

$ kubectl exec -it nginx-demo-7d458d8d74-xk9p2 -- bash

root@nginx-demo-7d458d8d74-xk9p2:/# nginx -v

nginx version: nginx/1.27.3

4. YAML Manifests: Deployment + Service

nginx-deployment.yaml

---

apiVersion

: apps/v1

kind

: Deployment

metadata

:

name: nginx-deployment

namespace: default

labels:

app: nginx

spec

:

replicas: 3

selector:

matchLabels:

app: nginx

template:

metadata:

labels:

app: nginx

spec:

containers:

- name: nginx

image: nginx:1.27

ports:

- containerPort: 80

resources:

requests:

memory: "64Mi"

cpu: "250m"

limits:

memory: "128Mi"

cpu: "500m"

---

apiVersion

: v1

kind

: Service

metadata

:

name: nginx-service

spec

:

type: NodePort

selector:

app: nginx

ports:

- port: 80

targetPort: 80

nodePort: 30080

Terminal - Apply manifests

$ kubectl apply -f nginx-deployment.yaml

deployment.apps/nginx-deployment created

service/nginx-service created

$ kubectl get pods -l app=nginx

NAME READY STATUS RESTARTS AGE

nginx-deployment-5d9d547f98-4j2kp 1/1 Running 0 45s

nginx-deployment-5d9d547f98-7m9xz 1/1 Running 0 45s

nginx-deployment-5d9d547f98-r8qlt 1/1 Running 0 45s

$ kubectl get services

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 30m

nginx-service NodePort 10.103.42.181 <none> 80:30080/TCP 45s

$ minikube service nginx-service --url

http://192.168.49.2:30080

5. Scaling và Rolling Updates

Terminal - Scale và Update

# Scale deployment lên 5 replicas

$ kubectl scale deployment nginx-deployment --replicas=5

deployment.apps/nginx-deployment scaled

$ kubectl get pods -l app=nginx

NAME READY STATUS RESTARTS AGE

nginx-deployment-5d9d547f98-4j2kp 1/1 Running 0 5m

nginx-deployment-5d9d547f98-7m9xz 1/1 Running 0 5m

nginx-deployment-5d9d547f98-r8qlt 1/1 Running 0 5m

nginx-deployment-5d9d547f98-wk2pl 1/1 Running 0 15s

nginx-deployment-5d9d547f98-zt8mn 1/1 Running 0 15s

# Rolling update - thay đổi image version

$ kubectl set image deployment/nginx-deployment nginx=nginx:1.28

deployment.apps/nginx-deployment image updated

$ kubectl rollout status deployment/nginx-deployment

Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 5 new replicas have been updated...

Waiting for deployment "nginx-deployment" rollout to finish: 3 out of 5 new replicas have been updated...

deployment "nginx-deployment" successfully rolled out

# Rollback nếu có vấn đề

$ kubectl rollout undo deployment/nginx-deployment

deployment.apps/nginx-deployment rolled back

$ kubectl rollout history deployment/nginx-deployment

deployment.apps/nginx-deployment

REVISION CHANGE-CAUSE

1 <none>

2 <none>

6. ConfigMap và Namespaces

app-configmap.yaml

apiVersion

: v1

kind

: ConfigMap

metadata

:

name: app-config

namespace: production

data

:

APP_ENV: "production"

APP_PORT: "8080"

DATABASE_HOST: "db.production.svc.cluster.local"

nginx.conf: |

server {

listen 80;

root /var/www/html;

}

Terminal - Namespaces và ConfigMaps

# Tạo namespace

$ kubectl create namespace production

namespace/production created

$ kubectl get namespaces

NAME STATUS AGE

default Active 30m

kube-system Active 30m

production Active 5s

# Apply ConfigMap

$ kubectl apply -f app-configmap.yaml

$ kubectl get configmap -n production

NAME DATA AGE

app-config 4 10s

$ kubectl describe configmap app-config -n production

7. Helm Package Manager

Helm là package manager cho Kubernetes. "Charts" là packages chứa tất cả Kubernetes resources cần thiết cho một application.

Terminal - Helm commands

# Cài đặt Helm

$ curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

Downloading https://get.helm.sh/helm-v3.16.2-linux-amd64.tar.gz

helm installed into /usr/local/bin/helm

# Thêm Bitnami repo

$ helm repo add bitnami https://charts.bitnami.com/bitnami

$ helm repo update

# Cài WordPress qua Helm

$ helm install my-wordpress bitnami/wordpress \

--set wordpressUsername=admin \

--set wordpressPassword=securepass \

--namespace wordpress \

--create-namespace

NAME: my-wordpress

STATUS: deployed

# Liệt kê releases

$ helm list --all-namespaces

NAME NAMESPACE REVISION STATUS CHART

my-wordpress wordpress 1 deployed wordpress-23.0.1

# Upgrade và uninstall

$ helm upgrade my-wordpress bitnami/wordpress --set replicaCount=2

$ helm uninstall my-wordpress -n wordpress

8. Kubernetes Service Types

ClusterIP (mặc định)

Chỉ accessible trong cluster. Dùng cho internal services (databases, caches). IP chỉ routable trong cluster network.

type: ClusterIP

NodePort

Expose service trên port của mỗi node (range 30000-32767). Accessible từ ngoài cluster qua NodeIP:NodePort.

type: NodePort, nodePort: 30080

LoadBalancer

Tạo external load balancer (cloud provider). Assign external IP cố định. Best cho production workloads.

type: LoadBalancer

ExternalName

Map service đến DNS CNAME. Dùng để reference external services bên ngoài cluster qua DNS name.

type: ExternalName, externalName: api.external.com

Lab Thực Hành

Triển khai ứng dụng web hoàn chỉnh trên Kubernetes với Minikube: Deployment 3 replicas, NodePort Service, ConfigMap, rolling update và rollback.

1

Khởi động Minikube

Terminal

$ minikube start --cpus=2 --memory=2048

* Done! kubectl is now configured to use "minikube"

$ kubectl get nodes

NAME STATUS ROLES AGE VERSION

minikube Ready control-plane 2m v1.31.0

2

Tạo Namespace và ConfigMap

Terminal

$ kubectl create namespace webapp

$ kubectl create configmap web-config \

--from-literal=APP_ENV=staging \

--from-literal=APP_VERSION=v1.0 \

-n webapp

configmap/web-config created

3

Deploy Nginx với 3 replicas

webapp-deploy.yaml

---

apiVersion

: apps/v1

kind

: Deployment

metadata

:

name: webapp

namespace: webapp

spec

:

replicas: 3

selector:

matchLabels: {app: webapp}

template:

metadata:

labels: {app: webapp}

spec:

containers:

- name: webapp

image: nginx:1.26

ports:

- containerPort: 80

envFrom:

- configMapRef:

name: web-config

---

apiVersion

: v1

kind

: Service

metadata

:

name: webapp-svc

namespace: webapp

spec

:

type: NodePort

selector: {app: webapp}

ports:

- port: 80

targetPort: 80

nodePort: 30090

Terminal

$ kubectl apply -f webapp-deploy.yaml

deployment.apps/webapp created

service/webapp-svc created

$ kubectl get pods -n webapp

NAME READY STATUS RESTARTS AGE

webapp-6b9db8c5fd-2kl4p 1/1 Running 0 30s

webapp-6b9db8c5fd-8nzxj 1/1 Running 0 30s

webapp-6b9db8c5fd-r4tmw 1/1 Running 0 30s

4

Truy cập ứng dụng

Terminal

$ minikube service webapp-svc -n webapp --url

http://192.168.49.2:30090

$ curl http://192.168.49.2:30090

<!DOCTYPE html>

<title>Welcome to nginx!</title>

5

Rolling Update lên nginx:1.27

Terminal

$ kubectl set image deployment/webapp \

webapp=nginx:1.27 -n webapp

$ kubectl rollout status deployment/webapp -n webapp

deployment "webapp" successfully rolled out

$ kubectl rollout history deployment/webapp -n webapp

REVISION CHANGE-CAUSE

1 <none>

2 <none>

6

Scale và Dọn dẹp

Terminal

$ kubectl scale deployment webapp --replicas=5 -n webapp

deployment.apps/webapp scaled

$ kubectl get pods -n webapp --watch

NAME READY STATUS RESTARTS AGE

webapp-... 1/1 Running 0 5m (x5)

# Dọn dẹp

$ kubectl delete namespace webapp

namespace "webapp" deleted

$ minikube stop

* Stopping node "minikube"...

Câu hỏi ôn tập

1

Pod trong Kubernetes là gì?

Pod là đơn vị deployment nhỏ nhất trong Kubernetes. Chứa một hoặc nhiều containers chia sẻ cùng network namespace (IP, ports) và storage volumes. Containers trong cùng pod có thể giao tiếp qua localhost. Pods là ephemeral — khi fail, Kubernetes tạo pod mới thay thế.
2

Deployment khác gì so với chạy pod trực tiếp?

Deployment quản lý một ReplicaSet, đảm bảo số lượng replicas luôn chạy. Nếu pod crash, Deployment tự tạo pod mới. Hỗ trợ rolling updates, rollback, scaling. Pod trực tiếp: nếu crash, không tự restart. Luôn dùng Deployment (hoặc StatefulSet/DaemonSet) thay vì bare pods.
3

Sự khác biệt giữa NodePort và LoadBalancer service types?

NodePort: expose service trên port cố định (30000-32767) của TẤT CẢ nodes. Accessible qua NodeIP:Port. Đơn giản, dùng cho dev/testing. LoadBalancer: tạo external load balancer qua cloud provider, assign external IP. Tự động distribute traffic. Dùng cho production workloads cần HA.
4

kubectl apply khác kubectl create như thế nào?

kubectl create: tạo resource mới, báo lỗi nếu đã tồn tại. kubectl apply: tạo nếu chưa có, cập nhật nếu đã tồn tại (declarative). apply là best practice vì idempotent — chạy nhiều lần an toàn. Giữ track của "desired state" qua annotation. Dùng apply -f file.yaml cho workflow chuẩn.
5

Rolling update trong Kubernetes hoạt động như thế nào?

Rolling update thay dần pods cũ bằng pods mới: (1) Tạo pod mới với image mới; (2) Khi pod mới Ready, terminate pod cũ; (3) Lặp lại cho đến khi tất cả pods được update. Đảm bảo zero downtime. Cấu hình bởi maxSurge (pods tạm thời thêm) và maxUnavailable (pods tạm thời unavailable).
6

ConfigMap dùng để làm gì trong Kubernetes?

ConfigMap lưu trữ configuration data (non-sensitive) dạng key-value, tách biệt khỏi container image. Inject vào pods qua: (1) Environment variables (envFrom: configMapRef); (2) Volume mounts (mount config file vào container). Cho phép thay đổi config mà không cần rebuild image.
7

Minikube là gì và tại sao dùng nó?

Minikube chạy Kubernetes cluster cục bộ trên một máy tính (laptop/desktop). Tạo VM với single-node cluster. Dùng để: (1) học Kubernetes; (2) develop và test applications locally; (3) thử nghiệm trước khi deploy lên production cluster. Tích hợp sẵn kubectl, hỗ trợ nhiều drivers (kvm2, docker, VirtualBox).
8

Lệnh kubectl rollout undo dùng để làm gì?

kubectl rollout undo deployment/<name> rollback deployment về revision trước. Nếu rolling update gây ra lỗi (pods crash, liveness probe fail), rollback về version đang hoạt động. Dùng --to-revision=N để rollback về revision cụ thể. Kubernetes giữ lịch sử rollout (revisionHistoryLimit, mặc định 10).
9

Helm là gì và chart là gì?

Helm là "package manager" cho Kubernetes. Chart là package chứa tất cả Kubernetes resource definitions (YAML templates) cần thiết cho một application. Helm cho phép: (1) install apps phức tạp với một lệnh; (2) manage app versions; (3) share apps qua Helm repositories (như Bitnami, Artifact Hub). helm install, upgrade, uninstall là các lệnh chính.
10

Namespace trong Kubernetes phục vụ mục đích gì?

Namespace phân chia cluster thành các virtual clusters. Mục đích: (1) Cô lập môi trường (dev/staging/production); (2) Multi-team: mỗi team có namespace riêng; (3) Resource quotas: giới hạn CPU/memory per namespace; (4) RBAC: phân quyền per namespace. Mặc định: default (app), kube-system (K8s components), kube-public (public data).