Các bước chạy Kubernetes Volume cơ bản (Phần 1)

cloudFun

Chặng tiếp theo của hành trình “Kubernettes trong một nốt nhạc” sẽ dừng chân tại trạm Kubernettes Volumes. Bài viết này sẽ bao gồm những nội dung:
  • Tổng quan và tầm quan trọng của Volume
  • Cách sử dụng một Volume
  • Kỹ thuật để chạy Volume “mượt mà”
Code sử dụng trong bài có sẵn tại GitHub

kubernetes.jpg


Điều kiện tiên quyết:

Để thực hiện các bước hướng dẫn, cần cài đặt minikube kubectl.

Cài đặt minikube[/URL] dưới dạng một single-node Kubernetes cluster trong một máy ảo cài đặt trên PC. Đối với Mac, chỉ cần chạy lệnh sau:
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 \
&& chmod +x minikube
sudo mv minikube /usr/local/bin

Cài đặt kubectl[/URL] để tương tác với yur AKS cluster. Đối với Mac, chạy lệnh:
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
chmod +x ./kubectl


Tổng quan
Data được lưu trữ trong các container Docker có tính chất tạm thời, nó chỉ tồn tại khi một container tồn tại. Kubernetes có thể khởi động lại một container bị lỗi hoặc bị hỏng (trong cùng một Pod), tuy nhiên data lưu trữ trong container đó sẽ bị mất. Kubernetes giải quyết vấn đề này với sự trợ giúp của Volume. Hơn nữa, Kubernetes còn hỗ trợ nhiều loại Volume của các cloud khác như Azure Disk, Amazon EBS, GCE Persistent Disk…, các hệ thống file được nối mạng như Ceph, GlusterFS... và các tùy chọn khác như emptyDir, hostPath, local, downAPAPI, secret, config
Volume được sử dụng như thế nào?
Việc sử dụng Volume tương đối đơn giản, Pod spec dưới đây là ví dụ mình hoạ
spec:
containers:
- name: kvstore
image: abhirockzz/kvstore:latest
volumeMounts:
- mountPath: /data
name: data-volume
ports:
- containerPort: 8080
volumes:
- name: data-volume
emptyDir: {}

Lưu ý :

[URL='https://kubernetes.io/docs/tasks/tools/install-minikube/']k39990r9jd888qwycu65.jpg
Một Pod có thể sở hữu nhiều hơn một Volume được khai báo trong spec.volume. Mỗi Volume này có thể truy cập được tất cả các container trong Pod nhưng không bắt buộc đối tất cả các container phải lắp hoặc sử dụng tất cả các volume. Nếu cần thiết, một container trong Pod có thể gắn nhiều volume vào các đường dẫn khác nhau trong file system của nó. Ngoài ra, các container có thể có thể cùng mount một volume.
Phân loại các Volume
Có thể phân loại volume theo các tiêu chí sau:

    • Tính tạm thời - Các Volume được kết hợp chặt chẽ với lifetime của Pod (ví dụ: emptyDir volume), tức là chúng sẽ bị xóa nếu Pod bị xóa (vì bất kỳ lý do nào).
    • Tính bền vững - Các Volume lưu trữ lâu dài và độc lập với lifecircle của Pod hoặc Node. Đây có thể là NFS hoặc lưu trữ dựa trên nền tảng cloud trong trường hợp các dịch vụ Kubernetes được quản lý như Azure Kubernetes Service, Google Kubernetes Engine…
Cùng lấy emptyDir làm ví dụ
emptyDir volume hoạt động
Một volume emptyDir được khởi tạo rỗng và mang bản chất tạm thời, tức là chỉ tồn tại chừng nào Pod tồn tại. Khi Pod bị xóa, data emptyDir cũng biến mất. Điều này khá hữu ích trong một số trường hợp hoặc yêu cầu như bộ đệm tạm thời, bộ nhớ chia sẻ cho nhiều container trong Pod
Để chạy ví dụ ở đây, sẽ cần sử dụng kho lưu trữ đơn giản hoá khóa giá trị để tiếp xúc REST API với mục đích:
Thêm các cặp khóa - giá trị
Đọc value cho một key
Tham khảo code tại đây.
Các bước deploy
Khởi động minikube
minikube start
Deploy ứng dụng kvstore. Bước này sẽ tạo Deployment một cách đơn giản với một instance (Pod) của ứng dụng đang chạy cùng với một NodePort service.
kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/volumes-1/kvstore.yaml
Để đơn giản hoá các bước, YAML được dẫn chiếu thẳng từ GitHub repo, tuy nhiên có thể tải file về local machine và dùng tương tự.
Xác nhận các thành phần nói trên đã được tạo
kubectl get deployments kvstore
NAME READY UP-TO-DATE AVAILABLE AGE
kvstore 1/1 1 1 28s
kubectl get pods -l app=kvstore
NAME READY STATUS RESTARTS AGE
kvstore-6c94877886-gzq25 1/1 Running 0 40s

Không cần lo lắng khi không biêt NodePort là gì – khái niệm này sẽ được đề cập trong bài viết tiếp theo. Hiện tại, chỉ cần hiểu rằng đó là một cách để truy cập ứng dụng REST endpoint trong trường hợp này.
Khi kiểm tra value của port ngẫu nhiên được tạo bởi NodePort service có thể thấy một kết quả tương tự (với các IP, port khác nhau).
kubectl get service kvstore-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kvstore-service NodePort 10.106.144.48 <none> 8080:32598/TCP 5m

Kiểm tra cột PORT(S) để tìm ra port ngẫu nhiên, tại ví dụ này là 32598. (8080 là internal port (cổng nội bộ) trong container được hiển thị bới ứng dụng – không cần quan tâm đến port này).
Đến đây, cần IP của minikube node bằng cách sử dụng minikube ip.
(Bước này có thể trả về một giá trị như 192.168.99.100 nếu sử dụng VirtualBox VM)
Trong các lệnh theo sau host thay thế bằng port và IP VM minikube với giá trị cổng ngẫu nhiên
Tạo một vài cặp khóa giá trị mới
curl http://[host]:[port]/save -d 'foo=bar'
curl http://[host]:[port]/save -d 'mac=cheese'

ví dụ
curl http://192.168.99.100:32598/save -d 'foo=bar'
curl http://192.168.99.100:32598/save -d 'mac=cheese'

Truy cập value cho key foo
curl http://[host]:[port]/read/foo
Đến đây sẽ nhận được giá trị đã được lưu cho foo - bar. Áp dụng tương tự cho mac, tức là lấy chesse làm value của nó. Chương trình lưu dữ data khóa giá trị trong /data – xác nhận bằng cách nhìn trực tiếp vào Docker container trong Pod.
kubectl exec <pod name> -- ls /data/
foo
mac

foo, mac là các file độc lập được đặt tên theo key. Nếu đào sâu hơn, có thể xác nhận được các giá trị tương ứng.
Dùng lệnh sau để xác nhận value cho key mac
kubectl exec <pod name> -- cat /data/mac`
cheese

Đến đây, nhận được cheese là kết quả vì nó đã được lưu trữ trước đó. Nếu cố tìm một key chưa được lưu trữ trước, kết quả trả về sẽ là error.
cat: can't open '/data/moo': No such file or directory
command terminated with exit code 1

Loại bỏ container
Sử dụng một Volume đảm bảo rằng data sẽ được bảo toàn trong quá trình restarts/crash của container. Hãy “ăn gian” một chút và loại bỏ container Docker.
kubectl exec [pod name] -- ps
PID USER TIME COMMAND
1 root 0:00 /kvstore
31 root 0:00 ps

Lưu ý: quá trình ID cho ứng dụng kvstore nên là 1.
Trên một terminal khác, đặt lệnh watch trên Pod.
kubectl get pods -l app=kvstore --watch
Tắt app
kubectl exec [pod name] -- kill 1
Có thể nhận thấy rằng Pod sẽ chuyển qua một vài giai đoạn (ví dụ: Error…) trước khi quay trở lại trạng thái Running (restart bởi Kubernetes).
NAME READY STATUS RESTARTS AGE
kvstore-6c94877886-gzq25 1/1 Running 0 15m
kvstore-6c94877886-gzq25 0/1 Error 0 15m
kvstore-6c94877886-gzq25 1/1 Running 1 15m

Thực hiện lệnh kubectl exec <pod name> -- ls /data để xác nhận rằng data thực tế đã sống sót sau khi đã restart container.
Xoá Pod
Có thể data sẽ không tồn tại ngoài vòng đời của Pod. Để xác nhận điều này, hãy xóa Pod bằng tay.
kubectl delete pod -l app=kvstore
Một thông báo xác nhận như sau sẽ xuất hiện
pod "kvstore-6c94877886-gzq25" deleted
Kubernetes sẽ restart lại Pod. Có thể xác nhận điều tương tự sau vài giây.
kubectl get pods -l app=kvstore
Pod mới sẽ ở trong trạng thái Running
Lấy tên Pod và theo dõi lại file
kubectl get pods -l app=kvstore
kubectl exec [pod name] -- ls /data/store

Đến đây, directory /data/ sẽ trống.
Sự cần thiết của persistent storage
Sự tồn tại của các Volume tạm thời phụ thuộc vào Pod - nhưng điều này sẽ không đủ cho phần lớn các ứng dụng. Để có khả năng phục hồi, đáng tin cậy, khả dụng và có thể thay đổi kích cỡ, các ứng dụng Kubernetes cần có khả năng chạy nhiều phiên bản trên các Pod và chính các Pod này có thể được lên lịch hoặc đặt trên các Node khác nhau trong cluster Kubernetes. Những gì cần là một kho lưu trữ ổn định, bền bỉ vượt xa Pod hoặc thậm chí là Node mà Pod đang chạy.
Như đã đề cập ở phần đầu của bài viết, việc sử dụng Volume rất đơn giản. Nó không chỉ là bộ lưu trữ tạm thời, mà còn là các kho lưu trữ dài hạn persistent store.
Dưới đây là một ví dụ (giả định) về cách sử dụng Azure Disk -phương tiện lưu trữ cho các ứng dụng, được triển khai cho [URL='https://azure.microsoft.com/services/kubernetes-service/?WT.mc_id=devto-blog-abhishgu']Azure Kubernetes Service.
apiVersion: v1
kind: Pod
metadata:
name: testpod
spec:
volumes:
- name: logs-volume
azureDisk:
kind: Managed
diskName: myAKSDiskName
diskURI: myAKSDiskURI
containers:
- image: myapp-docker-image
name: myapp
volumeMounts:
- mountPath: /app/logs
name: logs-volume


Về cơ bản, cách tiếp cận Kubernetes Volume này đơn giản và dễ hiểu, tuy nhiên nó còn tồn tại một số hạn chế. Đón đọc phần 2 để tìm hiểu thêm về những hạn chế này và nhiều thông tin khác xoay quanh Kubernetes Volume.

Nguồn: https://dev.to/
 
Sửa lần cuối:
Top