Hướng dẫn điều phối các ứng dụng phi trạng thái (stateless apps) trong Kubernetes?

cloudFun

Đầu tiên, chúng ta sẽ tìm hiểu những gì cơ bản nhất trong Kubernetes nhằm quản lý các stateless apps. Một trong những use case phổ biến nhất cho Kubernetes là điều phối và vận hành các stateless app. Trong Kubernetes, cần một Pod (hoặc một nhóm Pods trong hầu hết các trường hợp) để đại diện cho một ứng dụng hay một tác vụ nào đó. Tùy nhiên, bài viết sẽ không chỉ đề cập các khái niệm cơ bản như Pod mà còn đi sâu vào các thành phần cấp cao khác như ReplicaSets và Deployments.

Capture.PNG


Như mọi khi, code có sẵn trên GitHub



Cần có một Kubernetes cluster để bắt đầu. Có nhiều cách để có Cluster Kubernetes, như cài đặt minikube để có kubernetes một node để thực hành (môi trường chạy thử), hay dùng ngay Kubernetes trong Docker Desktop, hay cài đặt một hệ thống đầy đủ (Cài Docker, Cài và khởi tạo Cluster Kubernetes), hay mua từ các nhà cung cấp dịch vụ như Google Cloud Platform, AWS, Azuze ...Để truy cập Kubernetes cluster sẽ cần kubectl, cài đặt nó rất dễ.

ví dụ. để cài đặt kubectl cho Mac, chỉ cần

Mã:
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 && \
sudo mv ./kubectl /usr/local/bin/kubectl
Trong trường hợp đã cài đặt Azure CLI, tất cả những gì cần làm là az acs kubernetes install-cli.

Nếu quan tâm đến việc học Kubernetes và Container bằng Azure, chỉ cần tạo một tài khoản miễn phí và bắt đầu! Nên bắt đầu bằng cách sử dụng quickstarts, hướng dẫn và mẫu code trong tài liệu để làm quen với dịch vụ. Người dùng nâng cao có thể muốn tham khảo các thực tiễn tốt nhất của Kubernetes hoặc xem một số video về các bản demo, tính năng hàng đầu và sessions.
Hãy bắt đầu bằng cách hiểu khái niệm về Pod

Pod
Trong kubernetes thì Pod là là đơn vị nhỏ nhất và được cấu thành từ 1 hoặc nhiều container Các container này chia sẻ tài nguyên (dung lượng, khối lượng) và có thể giao tiếp với nhau qua localhost.
Tạo một Pod đơn giản bằng cách sử dụng tệp YAML bên dưới.
Pod chỉ là một tài nguyên hoặc đối tượng Kubernetes. Tệp YAML mô tẩ trạng thái của Pod cùng với các thông tin cơ bản - nó cũng được gọi là một manifest, spec hoặc definition.
Mã:
apiVersion: v1
kind: Pod
metadata:
  name: kin-stateless-1
spec:
  containers:
  - name: nginx
    image: nginx
Là một phần của thông số Pod, ví dụ này sẽ chạy nginx trong Kubernetes được truyển đạt và sử dụng spec.containers.image để trỏ đến container image của nó trên DockerHub.
Sử dụng lệnh kubectl apply để gửi thông tin của Pod cho Kubernetes.
Để đơn giản, tệp YAML đang được tham chiếu trực tiếp từ GitHub repo, nhưng cũng có thể tải tệp xuống máy cục bộ và sử dụng nó theo cách tương tự.

$ kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/stateless-apps/kin-stateless-pod.yaml

pod/kin-stateless-1 created

$ kubectl get pods

NAME READY STATUS RESTARTS AGE
kin-stateless-1 1/1 Running 0 10s


Bây giờ, hãy xóa Pod và xem điều gì sẽ xảy ra. Để làm điều này, sẽ sử dụng kubectl delete pod <pod_name>

$ kubectl delete pod kin-stateless-1
pod "kin-stateless-1" deleted

$ kubectl get pods
No resources found.


Đối với các ứng dụng quan trọng, cần quan tâm đến các khía cạnh sau:
  • Khả năng sẵn sàng và khả năng phục hồi cao - Lý tưởng nhất, ứng dụng phải đủ mạnh để tự phục hồi và vẫn có sẵn khi đối mặt với thất bại, ví dụ: Xóa Pod do lỗi node, v.v.
  • Khả năng mở rộng - Điều gì xảy ra nếu một phiên bản duy nhất của ứng dụng (Pod) không đủ? Liệu có muốn chạy bản sao/nhiều phiên bản hay không?
Khi có nhiều phiên bản ứng dụng chạy trên cluster sẽ cần phải suy nghĩ về:
  • Mở rộng – Liệu có thể tin tưởng vào nền tảng cơ bản để xử lý tỷ lệ ngang tự động không?
  • Truy cập ứng dụng - Làm thế nào để khách hàng (nội bộ hoặc bên ngoài) tiếp cận ứng dụng và làm thế nào lưu lượng được điều chỉnh qua nhiều phiên bản (Pods)?
  • Nâng cấp - Làm thế nào có thể xử lý các cập nhật ứng dụng theo cách không gây gián đoạn, tức là không có downtime?
Rất nhiều vấn đề. Hãy cùng xem qua một số giải pháp khả quan!

Pod Controllers
Mặc dù có thể tạo Pods trực tiếp, nhưng thật hợp lý khi sử dụng các thành phần cấp cao hơn mà Kubernetes cung cấp trên đầu Pods để giải quyết các vấn đề đã đề cập ở trên. Nói một cách đơn giản, các thành phần này (còn được gọi là Controllers - Bộ điều khiển) có thể tạo và quản lý một Pods Group.
Các controller sau hoạt động với Pod và các stateless apps:
ReplicaSet
Deployment
ReplicationController


Có các bộ điều khiển Pod khác như StatefulSet,

Job, DaemonSet, v.v. nhưng chúng không liên quan đến các stateless apps, do đó không được thảo luận ở đây



ReplicaSet
Một ReplicaSet có thể được sử dụng để đảm bảo rằng một số lượng bản sao/phiên bản cố định của ứng dụng (Pod) luôn có sẵn. Nó xác định nhóm Pod mà nó cần quản lý với sự trợ giúp của bộ chọn (do người dùng xác định) và sắp xếp chúng (tạo hoặc xóa) để duy trì số lượng cá thể mong muốn.

Một ReplicaSet spec phổ biến sẽ như sau
Mã:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: kin-stateless-rs
spec:
  replicas: 2
  selector:
    matchLabels:
      app: kin-stateless-rs
  template:
    metadata:
      labels:
        app: kin-stateless-rs
    spec:
      containers:
      - name: nginx
        image: nginx
Hãy tạo ReplicaSet
$ kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/stateless-apps/kin-stateless-replicaset.yaml

replicaset.apps/kin-stateless-rs created

$ kubectl get replicasets

NAME DESIRED CURRENT READY AGE
kin-stateless-rs 2 2 2 1m11s

$ kubectl get pods --selector=app=kin-stateless-rs

NAME READY STATUS RESTARTS AGE
kin-stateless-rs-zn4p2 1/1 Running 0 13s
kin-stateless-rs-zxp5d 1/1 Running 0 13s


Đối tượng ReplicaSet (được đặt tên là kin-stateless-rs) đã được tạo cùng với hai Pods (lưu ý rằng tên của các Pods chứa chuỗi ký tự chữ và số ngẫu nhiên, ví dụ: zn4p2)

Đây là theo những gì đã được cung cấp trong YAML (spec):
  • spec.replicas được đặt thành two
  • selector.matchLabels đã được đặt thành app: kin-stateless-rs và khớp với trường .spec.template.metadata.labels trong Pod specification.
Nhãn là các cặp khóa-giá trị (key-value) đơn giản có thể được thêm vào các đối tượng (chẳng hạn như Pod trong trường hợp này).

--selector được sử dụng trong lệnh kubectl get để lọc các Pods dựa trên nhãn của chúng, trong trường hợp này là app=kin-stateless-rs.
Hãy thử xóa một trong các Pods (giống như đã làm trong trường hợp trước)
Lưu ý rằng tên Pod sẽ khác trong thực tế, vì vậy hãy chắc chắn sử dụng đúng Pod.
$ kubectl delete pod kin-stateless-rs-zxp5d

pod "kin-stateless-rs-zxp5d" deleted

$ kubectl get pods -l=app=kin-stateless-rs

NAME READY STATUS RESTARTS AGE
kin-stateless-rs-nghgk 1/1 Running 0 9s
kin-stateless-rs-zn4p2 1/1 Running 0 5m

Tuy nhiên vẫn còn hai Pods! Điều này là do một Pod mới (được hightlight) đã được tạo để đáp ứng số lượng replica (hai) của ReplicaSet.
Để mở rộng ứng dụng theo chiều ngang, tất cả những gì cần làm là cập nhật trường spec.replicas trong tệp kê khai và gửi lại.
Hãy thử nhân rộng nó lên đến năm bản sao và sau đó quay lại ba bản.
Nhưng điều này không giải quyết được tất cả các vấn đề. Một trong số đó là xử lý các cập nhật ứng dụng - cụ thể như là việc không yêu cầu downtime. Kubernetes cung cấp một thành phần khác hoạt động ngoài ReplicaSets để xử lý việc này và các vẫn đề khác nữa.



Deployment
Deployment là một bản tóm tắt quản lý ReplicaSet - thu hồi từ phần trước đó, rằng ReplicaSet quản lý một Pods group. Ngoài khả năng mở rộng elastic, Deployments cung cấp các tính năng hữu ích khác cho phép quản lý các bản cập nhật, quay trở lại trạng thái trước đó, tạm dừng và tiếp tục quá trình triển khai, v.v. Hãy cùng khám phá những điều này.
Kubernetes Deployment mượn các tính năng sau từ ReplicaSet cơ bản của nó:
  • Khả năng phục hồi - Nếu một Pod gặp sự cố, nó sẽ tự động được khởi động lại, nhờ vào ReplicaSet. Ngoại lệ duy nhất là khi đặt restartPolicy trong Pod specification thành Never.
  • Scaling - Điều này cũng được chăm sóc bởi đối tượng ReplicaSet cơ sở.
Đây là cách mà một Deployment spec điển hình hoạt động
Mã:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kin-stateless-depl
spec:
  replicas: 2
  selector:
    matchLabels:
      app: kin-stateless-depl
  template:
    metadata:
      labels:
        app: kin-stateless-depl
    spec:
      containers:
      - name: nginx
        image: nginx
Tạo Deployment và xem đối tượng Kubernetes nào được tạo
$ kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/stateless-apps/kin-stateless-deployment.yaml
deployment.apps/kin-stateless-depl created

$ kubectl get deployment kin-stateless-dp
NAME READY UP-TO-DATE AVAILABLE AGE
kin-stateless-dp 2/2 2 2 10

$ kubectl get replicasets
NAME DESIRED CURRENT READY AGE
kin-stateless-dp-8f9b4d456 2 2 2 12

$ kubectl get pods -l=app=kin-stateless-dp
NAME READY STATUS RESTARTS AGE
kin-stateless-dp-8f9b4d456-csskb 1/1 Running 0 14s
kin-stateless-dp-8f9b4d456-hhrj7 1/1 Running 0 14s


Deployment (kin-stateless-dp) đã được tạo cùng với các ReplicaSet và (hai) Pods như được chỉ định trong trường spec.replicas. Bây giờ, hãy nhìn vào Pod để xem phiên bản nginx nào đang được sử dụng - xin lưu ý rằng tên Pod thực tế sẽ khác vì vậy hãy đảm bảo nó được sử dụng đúng.
$ kubectl exec kin-stateless-dp-8f9b4d456-csskb -- nginx -v
nginx version: nginx/1.17.3


Điều này là do latest tag của nginx image đã được chọn từ DockerHub, tại thời điểm viết là v1.17.3
kubectl exec là gì? Nói một cách đơn giản, nó cho phép thực thi một lệnh trong container cụ thể trong Pod. Trong trường hợp này, Pod có một container duy nhất, vì vậy không cần chỉ định một container

Cập nhật một Deployment
Có thể kích hoạt bản cập nhật cho Deployment hiện có bằng cách sửa đổi phần mẫu của Pod spec - một ví dụ phổ biến là việc cập nhật lên phiên bản mới hơn (nhãn) của container image. Có thể chỉ định nó bằng cách sử dụng spec.strategy.type của bảng kê khai Deployment và các tùy chọn hợp lệ là - Rolling update và Recreate.



Rolling update
Rolling update đảm bảo rằng không có downtime của ứng dụng trong quá trình cập nhật - điều này là do Pod sẽ được cập nhật từng cái một. Có một thời điểm mà cả hai phiên bản trước và hiện tại của ứng dụng cùng tồn tại. Các Pods cũ sẽ bị xóa sau khi cập nhật hoàn tất, nhưng sẽ có một giai đoạn trong đó tổng số Pod trong Deployment sẽ nhiều hơn số lượng replicas được chỉ định.
Có thể điều chỉnh thêm hành vi này bằng cách sử dụng cài đặt maxSurge maxUnavailable.
  • spec.strategy.rollingUpdate.maxSurge - số lượng tối đa của Pods có thể được tạo ra ngoài số lượng replica được chỉ định
  • spec.strategy.rollingUpdate.maxUnavailable- xác định số lượng tối đa của Pods không có sẵn
Recreate
Điều này khá đơn giản - bộ Pods cũ bị xóa trước khi các phiên bản mới được tung ra. Có thể đạt được kết quả tương tự nhờ ReplicaSets bằng cách xóa cái cũ và sau đó tạo một cái mới với thông số kỹ thuật được cập nhật (ví dụ: docker image mới, v.v.)
Hãy thử cập nhật ứng dụng bằng cách chỉ định thẻ Docker image rõ ràng - trong trường hợp này là 1.16.0. Điều này có nghĩa là một khi ứng dụng được cập nhật, phiên bản này sẽ phản ánh khi Pod được quan sát.
Tải xuống Deployment manifest ở trên, cập nhật nó để thay đổi spec.containers.image
từ nginx đến nginx:1.16.0 và gửi nó đến cluster - điều này sẽ kích hoạt cập nhật
$ kubectl apply -f deployment.yaml
deployment.apps/kin-stateless-dp configured

$ kubectl get pods -l=app=kin-stateless-dp
NAME READY STATUS RESTARTS AGE
kin-stateless-dp-5b66475bd4-gvt4z 1/1 Running 0 49s
kin-stateless-dp-5b66475bd4-tvfgl 1/1 Running 0 61s


Bây giờ có thấy một nhóm Pods mới (để ý tên). Để xác nhận cập nhật:
$ kubectl exec kin-stateless-dp-5b66475bd4-gvt4z -- nginx -v
nginx version: nginx/1.16.0

Xin lưu ý rằng tên Pod sẽ khác trong thực tế, vì vậy hãy đảm bảo nó được dùng đúng tên

Rollback
Nếu mọi thứ không như mong đợi với Deployment hiện tại, có thể quay lại phiên bản trước trong trường hợp phiên bản mới không hoạt động như mong đợi. Điều này là có thể vì Kubernetes lưu trữ lịch sử triển khai của một Deployment dưới dạng sửa đổi.
Để kiểm tra lịch sử Deployment:
$ kubectl rollout history deployment/kin-stateless-dp

deployment.extensions/kin-stateless-dp

REVISION CHANGE-CAUSE
1 <none>
2 <none>


Lưu ý rằng có hai phiên bản mới nhất. Có thể quay lại cái trước bằng cách sử dụng kubectl rollout undo

$ kubectl rollout undo deployment kin-stateless-dp
deployment.extensions/kin-stateless-dp rolled back

$ kubectl get pods -l=app=kin-stateless-dp
NAME READY STATUS RESTARTS AGE
kin-stateless-dp-5b66475bd4-gvt4z 0/1 Terminating 0 10m
kin-stateless-dp-5b66475bd4-tvfgl 1/1 Terminating 0 10m
kin-stateless-dp-8f9b4d456-d4v97 1/1 Running 0 14s
kin-stateless-dp-8f9b4d456-mq7sb 1/1 Running 0 7s


Lưu ý trạng thái trung gian nơi Kubernetes đang bận kết thúc Pods của Deployment cũ trong khi đảm bảo rằng các Pods mới được tạo để đáp ứng yêu cầu rollback.
Nếu kiểm tra lại phiên bản nginx có thể thấy ứng dụng đã được khôi phục về 1.17.3.

$ kubectl exec kin-stateless-dp-8f9b4d456-d4v97 -- nginx -v
nginx version: nginx/1.17.3


Pause and Resume
Cũng có thể tạm dừng Deployment rollout và khôi phục lại sau khi áp dụng các thay đổi cho nó (trong trạng thái tạm dừng).

ReplicationController
Một ReplicationController tương tự như một Deployment hoặc ReplicaSet. Tuy nhiên, đây không phải là cách tiếp cận được đề xuất cho việc sắp xếp stateless app vì Deployment cung cấp nhiều tính năng hơn (như được mô tả trong phần trước).

Nguồn: https://dev.to/
 
Top