Kubernetes learning


Kubernetes learning

Docker vs Kubernetes

Docker và container

Trước khi đi vào kubernetes thì ta sẽ đi qua docker và container trước.

image

Trong mô hình Virtual Machine, mỗi VM đều có hệ điều hành riêng (guest OS) và một bản sao của kernel của hệ điều hành đó. Khi bạn khởi động một VM, nó sẽ khởi động guest OS, và sau đó các ứng dụng và dịch vụ chạy trên guest OS này. Mỗi VM hoạt động như một máy tính ảo hoàn chỉnh với hệ điều hành độc lập.

Khác với VM, Containers là một công nghệ ảo hóa mức ứng dụng, nó không cần Guest OS mà trực tiếp chia sẻ với nhau Host OS thông qua Docker Engine.

Kubernetes

Cũng là ứng dụng quản lý container, nhưng khác với Docker là công cụ tạo và quản lý container độc lập, Kubernetes là hệ thống orkestrasi container mạnh mẽ giúp quản lý, mở rộng, và tự động hóa quá trình triển khai và quản lý ứng dụng container phức tạp.

Kubernetes Architecture

image

Cluster

image

Cluster (cụm) là một nhóm các Node (là các máy ảo), trên Cluster sẽ có môi trường Kubernetes.

Một cụm Kubernetes (Kubernetes cluster) bao gồm control plane nodes (hay còn gọi là Master nodes quản lý Cluster) và các worker nodes.

Master chịu trách nhiệm quản lý cụm và master điều phối tất cả các hoạt động trong cụm.

Mỗi worker node xem như một máy riêng và có một kubelet, là proxy quản lý node và giao tiếp với Kubernetes Master node.

Control Plane (Master node)

Control plane chịu trách nhiệm điều phối vùng chứa và duy trì trạng thái của Cluster. Control plane bao gồm những thành phần sau:

  1. kube-apiserver
  2. etcd
  3. kube-scheduler
  4. kube-controller-manager
  5. cloud-controller-manager
image

Worker nodes

Các worker nodes là nơi chạy các ứng dụng containerized. Gồm những thành phần sau:

  1. kubelet
  2. kube-proxy
  3. Container runtime

Pods

image

Trong Docker, các container là đơn vị nhỏ nhất để triển khai. Tuy nhiên, Kubernetes đưa ra một đơn vị mới là Pod làm đơn vị nhỏ nhất.

Pod là một tập hợp các containers, chúng chia sẻ một không gian mạng và bộ nhớ. Điều này giúp dễ quản lý các containers hơn.

Mỗi Pod sẽ có một địa chỉ ip riêng.

Ví dụ một Pod sẽ bao gồm 2 containers:

  • Một server nginx chạy trên port 80
  • Một server backend nodejs chạy trên port 3000

Pod sẽ được mô tả bằng một tệp YAML, và khi triển khai lên Kubernetes, nó sẽ tạo ra một Pod ví dụ như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
- name: backend
image: web-backend-image:latest
ports:
- containerPort: 3000

Đặt tên file trên và chạy lệnh kubectl apply -f your-file.yaml là ta có thể triển khai một Pod trên kubernetes.

Những thành phần và khái niệm cơ bản

Basic concepts

  • ReplicaSet: Được định nghĩa khi khai báo kind của app, được sử dụng để quản lý và đảm bảo số lượng bản sao (replicas) của Pod. Giúp đảm bảo tính sẵn sàng nếu một trong những bản sao bị lỗi.

Ví dụ ta có một server nginx. Để đảm bảo tính sẵn sàng và dự phòng cho trường hợp lỗi, ta khai báo ReplicaSet với số lượng replicas là 3 như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: my-replicaset
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: nginx:latest
  • Deployment: Có nhắc đến ở dưới phần demo.
  • Service:
    • Định nghĩa cổng vào dịch vụ (service) và cung cấp một địa chỉ IP và cổng cho ứng dụng khác kết nối tới.
    • Nó sử dụng Label Selector để xác định các Pod cụ thể mà nó liên kết và cung cấp một cách thống nhất để truy cập các ứng dụng trên cụm Kubernetes.
      Ví dụ ta có một ứng dụng web được triển khai trên Kubernetes bằng một số Pod, bây giờ ta muốn nó có thể được truy cập từ bên ngoài cụm Kubernetes, ta sẽ sử dụng service như sau:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      apiVersion: v1
      kind: Service
      metadata:
      name: my-service
      spec:
      selector:
      app: my-app
      ports:
      - protocol: TCP
      port: 80
      targetPort: 8080
  • metadata: Xác định tên của Service (ở đây là “my-service”).
  • selector: Sử dụng Label Selector để xác định những Pod nào sẽ thuộc về Service (ở đây là các Pod có label “app: my-app”).
  • ports: Xác định cổng ngoài (port) và cổng mục tiêu (targetPort) mà Service sẽ sử dụng để chuyển hướng truy cập.
  • Bây giờ, ta chỉ cần truy cập bằng ip của cluster http://<cluster-ip>:80

Kubernetes Control Plane Components

Tạo một ứng dụng đơn giản với kuberctl

Tạo một AKS Cluster với Azure cloud service

Đầu tiên vào https://portal.azure.com/ chọn loại Kubernetes service để tạo một AKS Cluster mới. Xem hướng dẫn thêm ở đây.

Kết nối đến Cluster

Đầu tiên ta cần config kubectl kết nối đến Kubernetes cluster:

1
az aks get-credentials --resource-group <group-name> --name <Cluster-name>

Sau khi chạy lệnh xong, ta sẽ nhận được kết quả: Merged "AKSCluster" as current context in /home/azureuser/.kube/config

Chạy lệnh kubectl get nodes để xem trạng thái Cluster.

1
2
3
kubectl get nodes
NAME STATUS ROLES AGE VERSION
aks-agentpool-75533554-vmss000000 Ready agent 2m29s v1.25.6

Vậy là Azure đã bắt đầu tính phí rồi :D, sử dụng xong nhớ xóa cluster vừa tạo nhé.

Kubernetes YAML File

Mọi Configuration file trong Kubernetes gồm 3 phần:

  • Header: gồm hai trường như sau:
    • apiVersion: Xác định phiên bản API của Kubernetes, thường là v1.
    • kind: Xác định loại đối tượng mà file YAML định nghĩa.
      1
      2
      3
      kind: Deployment # 
      kind: Service #
      kind: Pod # đại diện cho một nhóm các container chạy trên cùng một node.
      1
      2
      apiVersion: v1
      kind: Pod
  • metadata: chứa thông tin mô tả về dữ liệu, tài nguyên. Bao gồm các trường sau:
    • name: Tên của app
    • labels:
  • specification:

Demo cho Kind Deployment, Service, Pod

Pod

Thường ta sử dụng kind: Pod với những ứng dụng đơn lẻ, tác vụ đơn giản như nginx, Redis, các container ghi log,…

Ví dụ: Tạo file name <name>.yaml ví dụ pod.yaml

1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
spec:
containers:
- name: my-app-container
image: nginx:latest
ports:
- containerPort: 80

Khởi chạy:

1
2
3
4
5
6
7
PS /home/azureuser/test> kubectl apply -f pod.yaml
pod/my-app-pod created
PS /home/azureuser/test> kubectl get pods
NAME READY STATUS RESTARTS AGE
my-app-pod 1/1 Running 0 2m5s
PS /home/azureuser/test> kubectl describe pod my-app-pod
# Thông tin pod

Tương tác với container trong pod:

1
2
3
4
5
PS /home/azureuser/test> kubectl exec my-app-pod -c my-app-container -- nginx -v
nginx version: nginx/1.25.1
# Kết quả trả về có nghĩa nginx container của ta đang chạy trong pod
# Hoặc tương tự ta có thể sử dụng Pseudo-TTY như docker
PS /home/azureuser/test> kubectl exec -it my-app-pod -c my-app-container -- /bin/bash

kubectl exec -h để xem thêm những câu lệnh khác.

Xóa pod: PS /home/azureuser/test> kubectl delete pod my-app-pod

Pod template

Ở trên là ta chỉ build riêng pod. Nhưng với một số Kind khác như Deployment, Job, DaemonSet thì để setting cho pod, ta phải định nghĩa thêm Pod template.

Ví dụ:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: batch/v1
kind: Job
metadata:
name: hello
spec:
template:
# This is the pod template
spec:
containers:
- name: hello
image: busybox:1.28
command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
restartPolicy: OnFailure
# The pod template ends here
1
2
3
4
5
6
7
8
9
PS /home/azureuser/test> kubectl get jobs
NAME COMPLETIONS DURATION AGE
hello 0/1 13s 13s
PS /home/azureuser/test> kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-rh9xw 1/1 Running 0 30s
my-app-pod 1/1 Running 0 129m
PS /home/azureuser/test> kubectl exec hello-rh9xw -c hello -- echo "hello"
hello

Xóa jobs: PS /home/azureuser/test> kubectl delete job hello

Deployment

Deployment là một tài nguyên trong Kubernetes để quản lý và duy trì một nhóm các Pod .

Với kind: Pod thì ta chỉ có thể chạy riêng lẻ từng ứng dụng. Nhưng nếu ta muốn tạo nhiều bản sao của Pod và đảm bảo duy trì các Pod, kind: Deployment sẽ giúp ta điều đó.

Số pod sẽ được định nghĩa ở trường replicas của Deployment.

Khi tạo một Deployment, bạn chỉ cần xác định mẫu Pod (Pod template) và các nhãn (labels) để Deployment theo dõi. Deployment sẽ sử dụng mẫu Pod để tạo và duy trì các bản sao của Pod.

Nếu một Pod không phản hồi, Deployment sẽ thay thế nó để đảm bảo số lượng Pod. Cũng như nếu vượt quá thì nó sẽ giảm số Pod.

Lưu ý:
Nếu container bị lỗi, Pod vẫn được coi là hoạt động bình thường và không có thay đổi trong Deployment.

Một ví dụ đơn giản:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app-container
image: nginx:latest
ports:
- containerPort: 80
1
2
3
4
5
6
7
8
9
10
11
PS /home/azureuser/test>kubectl apply -f nginx-deployment.yaml
PS /home/azureuser/test> kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
my-app-deployment 3/3 3 3 17s
PS /home/azureuser/test> kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-rh9xw 1/1 Running 0 26m
my-app-deployment-dc547ddd7-bxbhz 1/1 Running 0 23s
my-app-deployment-dc547ddd7-cvrjx 1/1 Running 0 23s
my-app-deployment-dc547ddd7-z9vtz 1/1 Running 0 23s
my-app-pod 1/1 Running 0 155m

my-app-deployment đã được đưa lên Deployment, và nó tạo ra 3 pods khác nhau. Tuy nhiên các pods vẫn chưa READY.

Xem trạng thái của Deployment: kubectl rollout status deployment/my-app-deployment

Bây giờ ta thử xóa một pod để xem Deployment làm gì:

1
2
3
4
5
6
7
8
PS /home/azureuser/test> kubectl delete pod my-app-deployment-dc547ddd7-bxbhz --grace-period=0 --force
Warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "my-app-deployment-dc547ddd7-bxbhz" force deleted
PS /home/azureuser/test> kubectl get pods
NAME READY STATUS RESTARTS AGE
my-app-deployment-dc547ddd7-bjblw 1/1 Running 0 10s
my-app-deployment-dc547ddd7-cvrjx 1/1 Running 0 7m22s
my-app-deployment-dc547ddd7-z9vtz 1/1 Running 0 7m22s

Như kết quả ở trên, Deployment đã phát hiện pod bị xóa và ngay lập tức tái tạo lại pod.

Để xóa Deployment vừa tạo, ta dùng lệnh:

1
kubectl delete deployment my-app-deployment

Kiểm tra Pod đang sử dụng:

1
2
kubectl get pods
kubectl describe pod <name-pod>

Câu lệnh cơ bản

Environment variable:
https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/#define-an-environment-variable-for-a-container

1
2
kuberctl create deployment <name> --image=<name>
kubectl expose deployment <name> --type=<type> --port=8080

Tham khảo: