Thứ ba, 30/04/2019 | 00:00 GMT+7

Cách mở rộng ứng dụng Node.js với MongoDB trên Kubernetes bằng Helm

Kubernetes là một hệ thống để chạy các ứng dụng container hiện đại trên quy mô lớn. Với nó, các nhà phát triển có thể triển khai và quản lý các ứng dụng trên các cụm máy. Và mặc dù nó được dùng để cải thiện hiệu quả và độ tin cậy trong các cài đặt ứng dụng đơn lẻ, Kubernetes được thiết kế để chạy nhiều version của một ứng dụng trên các group máy.

Khi tạo các triển khai đa dịch vụ với Kubernetes, nhiều nhà phát triển chọn sử dụng trình quản lý gói Helm . Helm sắp xếp hợp lý quá trình tạo nhiều tài nguyên Kubernetes bằng cách cung cấp các biểu đồ và mẫu điều phối cách các đối tượng này tương tác. Nó cũng cung cấp các biểu đồ đóng gói sẵn cho các dự án nguồn mở phổ biến.

Trong hướng dẫn này, bạn sẽ triển khai ứng dụng Node.js với database MongoDB trên một cụm Kubernetes bằng cách sử dụng biểu đồ Helm. Bạn sẽ sử dụng biểu đồ tập hợp bản sao Helm MongoDB chính thức để tạo một đối tượng StatefulSet bao gồm ba Pod , một Headless Service và ba PersentlyVolumeClaims . Bạn cũng cần tạo biểu đồ để triển khai ứng dụng Node.js nhiều bản sao bằng hình ảnh ứng dụng tùy chỉnh. Cài đặt bạn sẽ xây dựng trong hướng dẫn này sẽ phản ánh chức năng của mã được mô tả trong Chứa ứng dụng Node.js với Docker Compose và sẽ là điểm khởi đầu tốt để xây dựng một ứng dụng Node.js có khả năng phục hồi với repodata MongoDB có thể mở rộng quy mô bạn cần.

Yêu cầu

Để hoàn thành hướng dẫn này, bạn cần :

Bước 1 - Nhân bản và đóng gói ứng dụng

Để sử dụng ứng dụng của ta với Kubernetes, ta cần phải đóng gói nó để tác nhân kubelet có thể kéo hình ảnh. Tuy nhiên, trước khi đóng gói ứng dụng, ta cần sửa đổi URI kết nối MongoDB trong mã ứng dụng đảm bảo rằng ứng dụng của ta có thể kết nối với các thành viên của tập bản sao mà ta sẽ tạo bằng biểu đồ Helm mongodb-replicaset .

Bước đầu tiên của ta sẽ là sao chép kho lưu trữ node-mongo-docker-dev từ tài khoản GitHub của Cộng đồng DigitalOcean .Kho lưu trữ này bao gồm mã từ cài đặt được mô tả trong Kho chứa ứng dụng Node.js để phát triển với Docker Compose , sử dụng ứng dụng Node.js demo với database MongoDB để trình bày cách cài đặt môi trường phát triển với Docker Compose. Bạn có thể tìm thêm thông tin về ứng dụng trong loạt bài Từ containers đến Kubernetes với Node.js.

Sao node_project repository vào một folder có tên là node_project :

  • git clone https://github.com/do-community/node-mongo-docker-dev.git node_project

Điều hướng đến folder node_project :

  • cd node_project

Thư mục node_project chứa các file và folder cho một ứng dụng thông tin cá mập hoạt động với đầu vào của user . Nó đã được hiện đại hóa để hoạt động với các containers : thông tin cấu hình nhạy cảm và cụ thể đã được xóa khỏi mã ứng dụng và được cấu trúc lại để đưa vào trong thời gian chạy và trạng thái của ứng dụng đã được download database MongoDB.

Để biết thêm thông tin về việc thiết kế các ứng dụng hiện đại, được đóng gói, vui lòng xemỨng dụng lưu trữ cho KubernetesỨng dụng hiện đại hóa cho Kubernetes .

Khi ta triển khai biểu đồ mongodb-replicaset Helm, nó sẽ tạo:

  • Một đối tượng StatefulSet với ba Pod - các thành viên của bộ bản sao MongoDB. Mỗi Pod sẽ có một PersentlyVolumeClaim được liên kết và sẽ duy trì một danh tính cố định trong trường hợp lên lịch lại.
  • Một bộ bản sao MongoDB được tạo thành từ các Pod trong StatefulSet. Bộ này sẽ bao gồm một chính và hai phụ. Dữ liệu sẽ được sao chép từ dữ liệu chính sang dữ liệu thứ hai, đảm bảo dữ liệu ứng dụng của ta vẫn có tính khả dụng cao.

Để ứng dụng của ta tương tác với các bản sao database , URI kết nối MongoDB trong mã của ta cần bao gồm cả tên server của các thành viên group bản sao cũng như tên của chính bộ bản sao. Do đó, ta cần đưa các giá trị này vào URI.

Tệp trong repository lưu trữ nhân bản của ta chỉ định thông tin kết nối database được gọi là db.js Mở file đó ngay bây giờ bằng nano hoặc editor bạn quen dùng :

  • nano db.js

Hiện tại, file bao gồm các hằng số được tham chiếu trong URI kết nối database lúc chạy. Các giá trị cho các hằng số này được đưa vào bằng thuộc tính process.env của Node, thuộc tính này trả về một đối tượng có thông tin về môi trường user của bạn trong thời gian chạy. Đặt giá trị động trong mã ứng dụng của ta cho phép ta tách mã khỏi cơ sở hạ tầng bên dưới, điều này cần thiết trong một môi trường động, không trạng thái. Để biết thêm thông tin về cách cấu trúc lại mã ứng dụng theo cách này, hãy xem Bước 2 của Việc chứa ứng dụng Node.js để phát triển với Docker Compose và thảo luận có liên quan trong Ứng dụng 12 nhân tố .

Các hằng số cho URI kết nối và bản thân chuỗi URI hiện trông giống như sau:

~ / node_project / db.js
... const {   MONGO_USERNAME,   MONGO_PASSWORD,   MONGO_HOSTNAME,   MONGO_PORT,   MONGO_DB } = process.env;  ...  const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`; ... 

Để phù hợp với cách tiếp cận 12FA, ta không muốn mã hóa cứng tên server của các version sao của ta hoặc tên tập hợp bản sao của ta vào chuỗi URI này. Hằng số MONGO_HOSTNAME hiện có có thể được mở rộng để bao gồm nhiều tên server - các thành viên của tập hợp bản sao của ta - vì vậy ta sẽ giữ nguyên giá trị đó. Tuy nhiên, ta cần thêm một hằng số tập hợp bản sao vào phần options của chuỗi URI.

Thêm MONGO_REPLICASET vào cả đối tượng hằng số URI và chuỗi kết nối:

~ / node_project / db.js
... const {   MONGO_USERNAME,   MONGO_PASSWORD,   MONGO_HOSTNAME,   MONGO_PORT,   MONGO_DB,   MONGO_REPLICASET } = process.env;  ... const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?replicaSet=${MONGO_REPLICASET}&authSource=admin`; ... 

Sử dụng tùy chọn replicaSet trong phần tùy chọn của URI cho phép ta truyền vào tên của tập hợp bản sao, cùng với tên server được xác định trong hằng số MONGO_HOSTNAME , sẽ cho phép ta kết nối với các thành viên đã đặt.

Lưu file khi bạn hoàn tất chỉnh sửa.

Với thông tin kết nối database của bạn đã được sửa đổi để hoạt động với các tập hợp bản sao, giờ đây bạn có thể đóng gói ứng dụng của bạn , xây dựng hình ảnh bằng lệnh docker build và đẩy nó vào Docker Hub.

Xây dựng hình ảnh bằng bản docker build và cờ -t , cho phép bạn gắn thẻ hình ảnh bằng một cái tên dễ nhớ. Trong trường hợp này, hãy gắn thẻ hình ảnh bằng tên user Docker Hub của bạn và đặt tên cho nó node-replicas hoặc tên do bạn chọn:

  • docker build -t your_dockerhub_username/node-replicas .

Các . trong lệnh chỉ định rằng ngữ cảnh xây dựng là folder hiện tại.

Sẽ mất một hoặc hai phút để xây dựng hình ảnh. Sau khi hoàn tất, hãy kiểm tra hình ảnh của bạn:

  • docker images

Bạn sẽ thấy kết quả sau:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/node-replicas latest 56a69b4bc882 7 seconds ago 90.1MB node 10-alpine aa57b0242b33 6 days ago 71MB

Tiếp theo, đăng nhập vào account Docker Hub bạn đã tạo trong yêu cầu :

  • docker login -u your_dockerhub_username

Khi được yêu cầu , hãy nhập password account Docker Hub của bạn. Đăng nhập theo cách này sẽ tạo file ~/.docker/config.json trong folder chính của user không phải root bằng thông tin đăng nhập Docker Hub của bạn.

Đẩy hình ảnh ứng dụng vào Docker Hub bằng lệnh docker push . Hãy nhớ thay your_dockerhub_username bằng tên user Docker Hub của bạn :

  • docker push your_dockerhub_username/node-replicas

Đến đây bạn có một hình ảnh ứng dụng mà bạn có thể kéo để chạy ứng dụng được sao chép của bạn với Kubernetes. Bước tiếp theo sẽ là cấu hình các thông số cụ thể để sử dụng với biểu đồ MongoDB Helm.

Bước 2 - Tạo bí mật cho bộ bản sao MongoDB

Biểu đồ stable/mongodb-replicaset cung cấp các tùy chọn khác nhau khi sử dụng Secrets và ta sẽ tạo hai biểu đồ để sử dụng với việc triển khai biểu đồ của bạn :

  • Bí mật cho keyfile tập hợp bản sao của ta sẽ hoạt động như một password chia sẻ giữa các thành viên tập hợp bản sao, cho phép họ xác thực các thành viên khác.
  • Bí mật cho admin-user MongoDB của ta , người sẽ được tạo với quyền là user gốc trên database admin . Role này sẽ cho phép bạn tạo những user tiếp theo với các quyền hạn chế khi triển khai ứng dụng của bạn vào production .

Với những Bí mật này, ta sẽ có thể đặt các giá trị tham số ưa thích của bạn trong file giá trị chuyên dụng và tạo đối tượng StatefulSet và bộ bản sao MongoDB với biểu đồ Helm.

Đầu tiên, hãy tạo keyfile. Ta sẽ sử dụng lệnh openssl với tùy chọn rand để tạo chuỗi ngẫu nhiên 756 byte cho file khóa:

  • openssl rand -base64 756 > key.txt

Đầu ra do lệnh tạo ra sẽ được mã hóa base64 , đảm bảo truyền dữ liệu đồng nhất và được chuyển hướng đến file có tên key.txt , tuân theo các nguyên tắc được nêu trong tài liệu xác thực biểu đồ mongodb-replicaset . Bản thân khóa phải dài từ 6 đến 1024 ký tự, chỉ bao gồm các ký tự trong bộ base64.

Đến đây bạn có thể tạo một Bí mật có tên là keyfilesecret bằng cách sử dụng file này với kubectl create :

  • kubectl create secret generic keyfilesecret --from-file=key.txt

Điều này sẽ tạo một đối tượng Bí mật trong không gian tên default , vì ta chưa tạo một không gian tên cụ thể cho cài đặt của bạn .

Bạn sẽ thấy kết quả sau cho biết rằng Bí mật của bạn đã được tạo:

Output
secret/keyfilesecret created

Xóa key.txt :

  • rm key.txt

Ngoài ra, nếu bạn muốn lưu file , hãy đảm bảo hạn chế quyền của nó và thêm nó vào tệp .gitignore của bạn để giữ nó ngoài tầm kiểm soát của version .

Tiếp theo, tạo Bí mật cho admin-user MongoDB của bạn. Bước đầu tiên sẽ là chuyển đổi tên user và password mong muốn của bạn thành base64.

Chuyển đổi tên user database của bạn:

  • echo -n 'your_database_username' | base64

Ghi lại giá trị bạn thấy trong kết quả .

Tiếp theo, chuyển đổi password của bạn:

  • echo -n 'your_database_password' | base64

Lưu ý về giá trị trong kết quả ở đây.

Mở file cho Bí mật:

  • nano secret.yaml

Lưu ý: Các đối tượng Kubernetesthường được xác định bằng YAML , điều này nghiêm cấm các tab và yêu cầu hai khoảng trắng để thụt lề. Nếu bạn muốn kiểm tra định dạng của các file YAML nào của bạn , bạn có thể sử dụng linter hoặc kiểm tra tính hợp lệ của cú pháp bằng cách sử dụng kubectl create với cờ --dry-run--validate :

  • kubectl create -f your_yaml_file.yaml --dry-run --validate=true

Nói chung, bạn nên xác thực cú pháp của bạn trước khi tạo tài nguyên bằng kubectl .

Thêm mã sau vào file để tạo Bí mật sẽ xác định userpassword với các giá trị được mã hóa mà bạn vừa tạo. Đảm bảo thay thế các giá trị giả tại đây bằng tên user và password được mã hóa của bạn :

~ / node_project / secret.yaml
apiVersion: v1 kind: Secret metadata:   name: mongo-secret data:   user: your_encoded_username   password: your_encoded_password 

Ở đây, ta đang sử dụng các tên chính mà biểu đồ mongodb-replicaset mong đợi: userpassword . Ta đã đặt tên cho đối tượng Bí mật là mongo-secret , nhưng bạn có thể tự do đặt tên cho nó bạn muốn .

Lưu file khi bạn hoàn tất chỉnh sửa.

Tạo đối tượng Bí mật bằng lệnh sau:

  • kubectl create -f secret.yaml

Bạn sẽ thấy kết quả sau:

Output
secret/mongo-secret created

, bạn có thể xóa secret.yaml hoặc hạn chế quyền của nó và thêm nó vào file .gitignore của bạn.

Với các đối tượng Bí mật của bạn đã được tạo, bạn có thể chuyển sang chỉ định các giá trị tham số bạn sẽ sử dụng với biểu đồ mongodb-replicaset và tạo triển khai MongoDB.

Bước 3 - Cấu hình Biểu đồ Helm MongoDB và Tạo Triển khai

Helm đi kèm với một repository được duy trì tích cực được gọi là ổn định chứa biểu đồ mà ta sẽ sử dụng: mongodb-replicaset . Để sử dụng biểu đồ này với Secrets mà ta vừa tạo, ta sẽ tạo một file với các giá trị tham số cấu hình gọi là mongodb-values.yaml và sau đó cài đặt biểu đồ bằng file này.

Tệp mongodb-values.yaml của ta sẽ phản ánh phần lớn file giá trị mặc values.yaml trong repository lưu trữ biểu đồ mongodb-replicaset . Tuy nhiên, ta sẽ áp dụng các thay đổi sau đối với file của bạn :

  • Ta sẽ đặt tham số auth thành true đảm bảo rằng các version database của ta bắt đầu với tính năng ủy quyền được bật . Điều này nghĩa là tất cả các client sẽ được yêu cầu xác thực để truy cập vào các hoạt động và tài nguyên database .
  • Ta sẽ thêm thông tin về Bí mật mà ta đã tạo ở Bước trước để biểu đồ có thể sử dụng các giá trị này để tạo file keyfile và admin-user tập hợp bản sao.
  • Ta sẽ giảm kích thước của PersentlyVolumes được liên kết với mỗi Pod trong StatefulSet để sử dụng đơn vị Lưu trữ khối DigitalOcean khả thi tối thiểu , 1GB, mặc dù bạn có thể tự do sửa đổi điều này để đáp ứng yêu cầu lưu trữ của bạn .

Tuy nhiên, trước khi viết file mongodb-values.yaml , trước tiên bạn nên kiểm tra xem bạn đã tạo và cấu hình StorageClass để cung cấp tài nguyên lưu trữ hay chưa. Mỗi Pod trong database StatefulSet của bạn sẽ có một danh tính cố định và một PersentlyVolumeClaim được liên kết, sẽ cung cấp động một PersentlyVolume cho Pod. Nếu một Pod được lên lịch lại, PersentlyVolume sẽ được gắn vào bất kỳ nút nào mà Pod được lên lịch (mặc dù mỗi Dung lượng phải được xóa theo cách thủ công nếu Pod hoặc StatefulSet được liên kết của nó bị xóa vĩnh viễn).

Bởi vì ta đang làm việc với DigitalOcean Kubernetes , trình provisioner StorageClass mặc định của ta được đặt thành dobs.csi.digitalocean.com - DigitalOcean Block Storage - ta có thể kiểm tra bằng lệnh :

  • kubectl get storageclass

Nếu bạn đang làm việc với một cụm DigitalOcean, bạn sẽ thấy kết quả sau:

Output
NAME PROVISIONER AGE do-block-storage (default) dobs.csi.digitalocean.com 21m

Nếu bạn không làm việc với một cụm DigitalOcean, bạn cần tạo StorageClass và cấu hình người provisioner lựa chọn của bạn. Để biết chi tiết về cách thực hiện việc này, vui lòng xem tài liệu chính thức .

Đến đây bạn đã đảm bảo bạn đã cấu hình StorageClass, hãy mở mongodb-values.yaml để chỉnh sửa:

  • nano mongodb-values.yaml

Bạn sẽ đặt các giá trị trong file này sẽ thực hiện như sau:

  • Bật ủy quyền.
  • Tham chiếu keyfilesecret và các đối tượng mongo-secret .
  • Chỉ định 1Gi cho 1Gi của bạn.
  • Đặt tên tập hợp bản sao của bạn thành db .
  • Chỉ định 3 bản sao cho tập hợp.
  • Ghim hình ảnh mongo vào version mới nhất tại thời điểm viết bài: 4.1.9 .

Dán mã sau vào file :

~ / node_project / mongodb-values.yaml
replicas: 3 port: 27017 replicaSetName: db podDisruptionBudget: {} auth:   enabled: true   existingKeySecret: keyfilesecret   existingAdminSecret: mongo-secret imagePullSecrets: [] installImage:   repository: unguiculus/mongodb-install   tag: 0.7   pullPolicy: Always copyConfigImage:   repository: busybox   tag: 1.29.3   pullPolicy: Always image:   repository: mongo   tag: 4.1.9   pullPolicy: Always extraVars: {} metrics:   enabled: false   image:     repository: ssalaues/mongodb-exporter     tag: 0.6.1     pullPolicy: IfNotPresent   port: 9216   path: /metrics   socketTimeout: 3s   syncTimeout: 1m   prometheusServiceDiscovery: true   resources: {} podAnnotations: {} securityContext:   enabled: true   runAsUser: 999   fsGroup: 999   runAsNonRoot: true init:   resources: {}   timeout: 900 resources: {} nodeSelector: {} affinity: {} tolerations: [] extraLabels: {} persistentVolume:   enabled: true   #storageClass: "-"   accessModes:     - ReadWriteOnce   size: 1Gi   annotations: {} serviceAnnotations: {} terminationGracePeriodSeconds: 30 tls:   enabled: false configmap: {} readinessProbe:   initialDelaySeconds: 5   timeoutSeconds: 1   failureThreshold: 3   periodSeconds: 10   successThreshold: 1 livenessProbe:   initialDelaySeconds: 30   timeoutSeconds: 5   failureThreshold: 3   periodSeconds: 10   successThreshold: 1 

Ở đây, tham số persistentVolume.storageClass được comment : xóa comment và đặt giá trị của nó thành "-" sẽ vô hiệu hóa cấp phép động. Trong trường hợp của ta , vì ta để giá trị này không xác định, biểu đồ sẽ chọn người provisioner mặc provisioner - trong trường hợp của ta là dobs.csi.digitalocean.com .

Cũng lưu ý accessMode liên kết với khóa persistentVolume accessMode : ReadWriteOnce nghĩa là ổ đĩa được cung cấp sẽ chỉ được đọc-ghi bởi một nút duy nhất. Vui lòng xem tài liệu để biết thêm thông tin về các chế độ truy cập khác nhau.

Để tìm hiểu thêm về các tham số khác có trong file , hãy xem bảng cấu hình đi kèm với repo.

Lưu file khi bạn hoàn tất chỉnh sửa.

Trước khi triển khai biểu đồ mongodb-replicaset , bạn cần cập nhật repo ổn định bằng lệnh helm repo update :

  • helm repo update

Thao tác này sẽ nhận được thông tin biểu đồ mới nhất từ repository ổn định .

Cuối cùng, cài đặt biểu đồ bằng lệnh sau:

  • helm install --name mongo -f mongodb-values.yaml stable/mongodb-replicaset

Lưu ý: Trước khi cài đặt biểu đồ, bạn có thể chạy helm install với các tùy chọn --dry-run--debug để kiểm tra các file kê khai đã tạo cho bản phát hành của bạn:

  • helm install --name your_release_name -f your_values_file.yaml --dry-run --debug your_chart

Lưu ý ta đang đặt tên mongo phát hành Helm. Tên này sẽ đề cập đến việc triển khai biểu đồ cụ thể này với các tùy chọn cấu hình mà ta đã chỉ định. Ta đã chỉ ra các tùy chọn này bằng cách bao gồm cờ -f và file mongodb-values.yaml của ta .

Cũng lưu ý vì ta không bao gồm các --namespace cờ với helm install , các đối tượng biểu đồ của ta sẽ được tạo ra trong default không gian tên.

Khi bạn đã tạo bản phát hành, bạn sẽ thấy kết quả về trạng thái của nó, cùng với thông tin về các đối tượng đã tạo và hướng dẫn để tương tác với chúng:

Output
NAME: mongo LAST DEPLOYED: Tue Apr 16 21:51:05 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/ConfigMap NAME DATA AGE mongo-mongodb-replicaset-init 1 1s mongo-mongodb-replicaset-mongodb 1 1s mongo-mongodb-replicaset-tests 1 0s ...

Đến đây bạn có thể kiểm tra việc tạo Group của bạn bằng lệnh sau:

  • kubectl get pods

Bạn sẽ thấy kết quả như sau khi các Group đang được tạo:

Output
NAME READY STATUS RESTARTS AGE mongo-mongodb-replicaset-0 1/1 Running 0 67s mongo-mongodb-replicaset-1 0/1 Init:0/3 0 8s

Kết quả kết quả READYSTATUS ở đây cho biết các Pod trong StatefulSet của ta chưa hoàn toàn sẵn sàng: các Init Containers được liên kết với các container của Pod vẫn đang chạy. Vì các thành viên của StatefulSet được tạo theo thứ tự tuần tự , nên mỗi Pod trong StatefulSet phải RunningReady trước khi tạo Pod tiếp theo.

Khi các Group đã được tạo và tất cả các containers được liên kết của chúng đang chạy, bạn sẽ thấy kết quả này:

Output
NAME READY STATUS RESTARTS AGE mongo-mongodb-replicaset-0 1/1 Running 0 2m33s mongo-mongodb-replicaset-1 1/1 Running 0 94s mongo-mongodb-replicaset-2 1/1 Running 0 36s

STATUS Running cho biết Group của bạn được liên kết với các node và các containers được liên kết với các Group đó đang chạy. READY cho biết có bao nhiêu containers trong một Pod đang chạy. Để biết thêm thông tin, vui lòng tham khảo tài liệu về Vòng đời Pod .

Ghi chú:
Nếu bạn thấy các pha không mong muốn trong cột STATUS , hãy nhớ rằng bạn có thể khắc phục sự cố Group của bạn bằng các lệnh sau:

  • kubectl describe pods your_pod
  • kubectl logs your_pod

Mỗi Pod trong StatefulSet của bạn có một tên kết hợp tên của StatefulSet với chỉ mục thứ tự của Pod. Vì ta đã tạo ba bản sao nên các thành viên StatefulSet của ta được đánh số 0-2 và mỗi thành viên đều có mục nhập DNS ổn định bao gồm các phần tử sau: $( statefulset-name )-$( ordinal ).$( service name ).$( namespace ).svc.cluster.local .

Trong trường hợp của ta , StatefulSet và Headless Service được tạo bởi biểu đồ mongodb-replicaset có cùng tên:

  • kubectl get statefulset
Output
NAME READY AGE mongo-mongodb-replicaset 3/3 4m2s
  • kubectl get svc
Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 42m mongo-mongodb-replicaset ClusterIP None <none> 27017/TCP 4m35s mongo-mongodb-replicaset-client ClusterIP None <none> 27017/TCP 4m35s

Điều này nghĩa là thành viên đầu tiên của StatefulSet của ta sẽ có mục nhập DNS sau:

mongo-mongodb-replicaset-0.mongo-mongodb-replicaset.default.svc.cluster.local 

Bởi vì ta cần ứng dụng của bạn kết nối với từng version MongoDB, điều cần thiết là ta phải có thông tin này để có thể giao tiếp trực tiếp với Pods, thay vì với Dịch vụ. Khi ta tạo biểu đồ Helm ứng dụng tùy chỉnh của bạn , ta sẽ chuyển các mục nhập DNS cho mỗi Pod vào ứng dụng của bạn bằng cách sử dụng các biến môi trường.

Với các version database của bạn đã được cài đặt và chạy, bạn đã sẵn sàng tạo biểu đồ cho ứng dụng Node của bạn .

Bước 4 - Tạo biểu đồ ứng dụng tùy chỉnh và cấu hình thông số

Ta sẽ tạo một biểu đồ Helm tùy chỉnh cho ứng dụng Node của bạn và sửa đổi các file mặc định trong folder biểu đồ tiêu chuẩn để ứng dụng của ta có thể hoạt động với bộ bản sao mà ta vừa tạo. Ta cũng sẽ tạo các file để xác định các đối tượng ConfigMap và Secret cho ứng dụng của ta .

Đầu tiên, tạo một folder biểu đồ mới có tên là nodeapp bằng lệnh sau:

  • helm create nodeapp

Thao tác này sẽ tạo một folder có tên là nodeapp trong folder ~/ node_project của bạn với các tài nguyên sau:

  • Chart.yaml với thông tin cơ bản về biểu đồ của bạn.
  • values.yaml cho phép bạn đặt các giá trị tham số cụ thể, như bạn đã làm với triển khai MongoDB của bạn .
  • .helmignore với các mẫu file và folder sẽ bị bỏ qua khi đóng gói biểu đồ.
  • templates/ folder chứa các file mẫu sẽ tạo file kê khai Kubernetes.
  • Một folder templates/tests/ cho các file thử nghiệm.
  • Một charts/ folder cho bất kỳ biểu đồ nào mà biểu đồ này phụ thuộc vào.

Tệp đầu tiên ta sẽ sửa đổi trong số các file mặc định này là giá values.yaml . Mở file đó ngay bây giờ:

  • nano nodeapp/values.yaml

Các giá trị mà ta sẽ đặt ở đây bao gồm:

  • Số lượng bản sao.
  • Hình ảnh ứng dụng mà ta muốn sử dụng. Trong trường hợp của ta , đây sẽ là hình ảnh node-replicas mà ta đã tạo ở Bước 1 .
  • Các Loại Dịch vụ . Trong trường hợp này, ta sẽ chỉ định LoadBalancer để tạo một điểm truy cập vào ứng dụng của ta cho mục đích thử nghiệm. Bởi vì ta đang làm việc với cụm DigitalOcean Kubernetes, điều này sẽ tạo ra Bộ cân bằng tải DigitalOcean khi ta triển khai biểu đồ của bạn . Trong quá trình production , bạn có thể cấu hình biểu đồ của bạn để sử dụng Tài nguyên IngressBộ điều khiển Ingress để định tuyến lưu lượng truy cập đến Dịch vụ của bạn.
  • TargetPort để chỉ định cổng trên Pod nơi ứng dụng của ta sẽ được hiển thị.

Ta sẽ không nhập các biến môi trường vào file này. Thay vào đó, ta sẽ tạo các mẫu cho các đối tượng ConfigMap và Secret và thêm các giá trị này vào file kê khai Triển khai ứng dụng của ta , nằm tại ~/node_project/ nodeapp /templates/deployment.yaml .

Cấu hình các giá trị sau trong file giá values.yaml :

~ / node_project / gật gù / giá trị.yaml
# Default values for nodeapp. # This is a YAML-formatted file. # Declare variables to be passed into your templates.  replicaCount: 3  image:   repository: your_dockerhub_username/node-replicas   tag: latest   pullPolicy: IfNotPresent  nameOverride: "" fullnameOverride: ""  service:   type: LoadBalancer   port: 80   targetPort: 8080 ... 

Lưu file khi bạn hoàn tất chỉnh sửa.

Tiếp theo, mở file secret.yaml trong folder nodeapp /templates :

  • nano nodeapp/templates/secret.yaml

Trong file này, hãy thêm giá trị cho các hằng số ứng dụng MONGO_PASSWORDMONGO_USERNAME của bạn. Đây là các hằng số mà ứng dụng của bạn sẽ có quyền truy cập vào trong thời gian chạy, như được chỉ định trong db.js , file kết nối database của bạn. Khi bạn thêm các giá trị cho các hằng số này, hãy nhớ sử dụng các giá trị được mã hóa base64 mà bạn đã sử dụng trước đó ở Bước 2 khi tạo đối tượng mongo-secret . Nếu bạn cần tạo lại các giá trị đó, bạn có thể quay lại Bước 2 và chạy lại các lệnh liên quan.

Thêm mã sau vào file :

~ / node_project / gật gù / các mẫu / secret.yaml
apiVersion: v1 kind: Secret metadata:   name: {{ .Release.Name }}-auth data:   MONGO_USERNAME: your_encoded_username   MONGO_PASSWORD: your_encoded_password 

Tên của đối tượng Bí mật này sẽ phụ thuộc vào tên của bản phát hành Helm mà bạn sẽ chỉ định khi triển khai biểu đồ ứng dụng.

Lưu file khi bạn hoàn tất.

Tiếp theo, mở một file để tạo Bản đồ cấu hình cho ứng dụng của bạn:

  • nano nodeapp/templates/configmap.yaml

Trong file này, ta sẽ xác định các biến còn lại mà ứng dụng của ta mong đợi: MONGO_HOSTNAME , MONGO_PORT , MONGO_DBMONGO_REPLICASET . Biến MONGO_HOSTNAME của ta sẽ bao gồm mục nhập DNS cho từng version trong tập hợp bản sao của ta , vì Đây là kết quả URI kết nối MongoDB yêu cầu .

Theo tài liệu Kubernetes , khi một ứng dụng thực hiện kiểm tra tính sẵn sàng và hoạt động, các bản ghi SRV sẽ được sử dụng khi kết nối với Pod. Như đã thảo luận ở Bước 3 , các bản ghi Pod SRV của ta tuân theo mẫu sau: $( statefulset-name )-$( ordinal ).$( service name ).$( namespace ).svc.cluster.local . Vì MongoDB StatefulSet của ta thực hiện kiểm tra tính sẵn sàng và hoạt động, ta nên sử dụng các số nhận dạng ổn định này khi xác định các giá trị của biến MONGO_HOSTNAME .

Thêm mã sau vào file để xác định các MONGO_HOSTNAME , MONGO_PORT , MONGO_DBMONGO_REPLICASET . Bạn có thể tự do sử dụng tên khác cho database MONGO_DB của bạn , nhưng các giá trị MONGO_REPLICASETMONGO_HOSTNAME của bạn phải được viết như chúng xuất hiện ở đây:

~ / node_project / gật gù / mẫu / configmap.yaml
apiVersion: v1 kind: ConfigMap metadata:   name: {{ .Release.Name }}-config data:   MONGO_HOSTNAME: "mongo-mongodb-replicaset-0.mongo-mongodb-replicaset.default.svc.cluster.local,mongo-mongodb-replicaset-1.mongo-mongodb-replicaset.default.svc.cluster.local,mongo-mongodb-replicaset-2.mongo-mongodb-replicaset.default.svc.cluster.local"     MONGO_PORT: "27017"   MONGO_DB: "sharkinfo"   MONGO_REPLICASET: "db" 

Vì ta đã tạo đối tượng StatefulSet và tập hợp bản sao, nên các tên server được liệt kê ở đây phải được liệt kê trong file của bạn chính xác như chúng xuất hiện trong ví dụ này. Nếu bạn phá hủy các đối tượng này và đổi tên bản phát hành MongoDB Helm của bạn , thì bạn cần phải sửa đổi các giá trị có trong Bản đồ cấu hình này. Điều tương tự cũng áp dụng cho MONGO_REPLICASET , vì ta đã chỉ định tên tập hợp bản sao với bản phát hành MongoDB của bạn .

Cũng lưu ý các giá trị được liệt kê ở đây được trích dẫn, đó là kỳ vọng cho các biến môi trường trong Helm .

Lưu file khi bạn hoàn tất chỉnh sửa.

Với các giá trị tham số biểu đồ của bạn được xác định và tạo file kê khai Bản đồ bí mật và Bản đồ cấu hình, bạn có thể chỉnh sửa mẫu Triển khai ứng dụng để sử dụng các biến môi trường của bạn .

Bước 5 - Tích hợp các biến môi trường vào triển khai Helm của bạn

Với các file cho ứng dụng Secret và ConfigMap đã có sẵn, ta cần đảm bảo Triển khai ứng dụng của ta có thể sử dụng các giá trị này. Ta cũng sẽ tùy chỉnh các đầu dò về tính sẵn sàng và hoạt động đã được xác định trong file kê khai Triển khai.

Mở mẫu Triển khai ứng dụng để chỉnh sửa:

  • nano nodeapp/templates/deployment.yaml

Mặc dù đây là file YAML, các mẫu Helm sử dụng cú pháp khác với file Kubernetes YAML chuẩn để tạo file kê khai. Để biết thêm thông tin về các mẫu, hãy xem tài liệu Helm .

Trong file , trước tiên hãy thêm khóa env vào thông số kỹ thuật containers ứng dụng của bạn, bên dưới khóa imagePullPolicyports phía trên:

~ / node_project / nodemon / mẫu / triển khai.yaml
apiVersion: apps/v1 kind: Deployment metadata: ...   spec:     containers:       - name: {{ .Chart.Name }}         image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"         imagePullPolicy: {{ .Values.image.pullPolicy }}         env:         ports: 

Tiếp theo, thêm các khóa sau vào danh sách các biến env :

~ / node_project / nodemon / mẫu / triển khai.yaml
apiVersion: apps/v1 kind: Deployment metadata: ...   spec:     containers:       - name: {{ .Chart.Name }}         image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"         imagePullPolicy: {{ .Values.image.pullPolicy }}         env:         - name: MONGO_USERNAME           valueFrom:             secretKeyRef:               key: MONGO_USERNAME               name: {{ .Release.Name }}-auth         - name: MONGO_PASSWORD           valueFrom:             secretKeyRef:               key: MONGO_PASSWORD               name: {{ .Release.Name }}-auth         - name: MONGO_HOSTNAME           valueFrom:             configMapKeyRef:               key: MONGO_HOSTNAME               name: {{ .Release.Name }}-config         - name: MONGO_PORT           valueFrom:             configMapKeyRef:               key: MONGO_PORT               name: {{ .Release.Name }}-config         - name: MONGO_DB           valueFrom:             configMapKeyRef:               key: MONGO_DB               name: {{ .Release.Name }}-config               - name: MONGO_REPLICASET           valueFrom:             configMapKeyRef:               key: MONGO_REPLICASET               name: {{ .Release.Name }}-config         

Mỗi biến bao gồm một tham chiếu đến giá trị của nó, được xác định bởi khóa secretKeyRef , trong trường hợp là giá trị Secret hoặc configMapKeyRef cho giá trị ConfigMap. Các khóa này trỏ đến các file Secret và ConfigMap mà ta đã tạo ở Bước trước.

Tiếp theo, bên dưới khóa ports , hãy sửa đổi định nghĩa containerPort để chỉ định cổng trên containers nơi ứng dụng của ta sẽ được hiển thị:

~ / node_project / nodemon / mẫu / triển khai.yaml
apiVersion: apps/v1 kind: Deployment metadata: ...   spec:     containers:     ...       env:     ...       ports:         - name: http           containerPort: 8080           protocol: TCP       ... 

Tiếp theo, hãy sửa đổi các kiểm tra tính sẵn sàng và hoạt động có trong file kê khai Triển khai này theo mặc định. Những kiểm tra này đảm bảo các Group ứng dụng của ta đang chạy và sẵn sàng phục vụ lưu lượng truy cập:

  • Các đầu dò về mức độ sẵn sàng đánh giá xem liệu Pod có sẵn sàng phục vụ lưu lượng truy cập hay không, dừng tất cả các yêu cầu tới Pod cho đến khi kiểm tra thành công.
  • Đầu dò Liveness kiểm tra hành vi ứng dụng cơ bản để xác định xem ứng dụng trong containers có đang chạy và hoạt động như mong đợi hay không. Nếu một đầu dò độ sống không thành công, Kubernetes sẽ khởi động lại containers .

Để biết thêm về cả hai, hãy xem thảo luận có liên quan trongỨng dụng kiến trúc cho Kubernetes .

Trong trường hợp của ta , ta sẽ xây dựng trên yêu cầu httpGet mà Helm đã cung cấp theo mặc định và kiểm tra xem ứng dụng của ta có chấp nhận các yêu cầu trên điểm cuối /sharks . Dịch vụ kubelet sẽ thực hiện thăm dò bằng cách gửi yêu cầu GET đến server Node đang chạy trong containers của ứng dụng Pod và lắng nghe trên cổng 8080 . Nếu mã trạng thái cho phản hồi nằm trong repository ảng từ 200 đến 400, thì kubelet sẽ kết luận rằng containers hoạt động tốt. Nếu không, trong trường hợp trạng thái 400 hoặc 500, kubelet sẽ dừng lưu lượng truy cập vào containers , trong trường hợp đầu dò độ sẵn sàng, hoặc khởi động lại containers , trong trường hợp đầu dò độ sống.

Thêm sửa đổi sau vào path đã nêu cho các đầu dò độ sống và độ sẵn sàng:

~ / node_project / nodemon / mẫu / triển khai.yaml
apiVersion: apps/v1 kind: Deployment metadata: ...   spec:     containers:     ...       env:     ...       ports:         - name: http           containerPort: 8080           protocol: TCP       livenessProbe:         httpGet:           path: /sharks           port: http       readinessProbe:         httpGet:           path: /sharks           port: http 

Lưu file khi bạn hoàn tất chỉnh sửa.

Đến đây bạn đã sẵn sàng để tạo bản phát hành ứng dụng của bạn với Helm. Chạy lệnh helm install sau, bao gồm tên của bản phát hành và vị trí của folder biểu đồ:

  • helm install --name nodejs ./nodeapp

Lưu ý bạn có thể chạy helm install trước tiên với các tùy chọn --dry-run--debug , như đã thảo luận trong Bước 3 , để kiểm tra các file kê khai đã tạo cho bản phát hành của bạn.

, bởi vì ta không bao gồm --namespace cờ với helm install , các đối tượng biểu đồ của ta sẽ được tạo ra trong default không gian tên.

Bạn sẽ thấy kết quả sau cho biết rằng bản phát hành của bạn đã được tạo:

Output
NAME: nodejs LAST DEPLOYED: Wed Apr 17 18:10:29 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/ConfigMap NAME DATA AGE nodejs-config 4 1s ==> v1/Deployment NAME READY UP-TO-DATE AVAILABLE AGE nodejs-nodeapp 0/3 3 0 1s ...

, kết quả sẽ cho biết trạng thái của bản phát hành, cùng với thông tin về các đối tượng đã tạo và cách bạn có thể tương tác với chúng.

Kiểm tra trạng thái của Pod của bạn:

  • kubectl get pods
Output
NAME READY STATUS RESTARTS AGE mongo-mongodb-replicaset-0 1/1 Running 0 57m mongo-mongodb-replicaset-1 1/1 Running 0 56m mongo-mongodb-replicaset-2 1/1 Running 0 55m nodejs-nodeapp-577df49dcc-b5fq5 1/1 Running 0 117s nodejs-nodeapp-577df49dcc-bkk66 1/1 Running 0 117s nodejs-nodeapp-577df49dcc-lpmt2 1/1 Running 0 117s

Khi Pod của bạn đã cài đặt và đang chạy, hãy kiểm tra Dịch vụ của bạn:

  • kubectl get svc
Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 96m mongo-mongodb-replicaset ClusterIP None <none> 27017/TCP 58m mongo-mongodb-replicaset-client ClusterIP None <none> 27017/TCP 58m nodejs-nodeapp LoadBalancer 10.245.33.46 your_lb_ip 80:31518/TCP 3m22s

EXTERNAL_IP liên kết với Dịch vụ nodejs-nodeapp là địa chỉ IP nơi bạn có thể truy cập ứng dụng từ bên ngoài cụm. Nếu bạn thấy trạng thái <pending> trong cột EXTERNAL_IP , điều này nghĩa là trình cân bằng tải của bạn vẫn đang được tạo.

Khi bạn thấy một IP trong cột đó, hãy chuyển đến IP đó trong trình duyệt của bạn: http:// your_lb_ip .

Bạn sẽ thấy trang đích sau:

Trang đích ứng dụng

Bây giờ ứng dụng được sao chép của bạn đang hoạt động, hãy thêm một số dữ liệu thử nghiệm đảm bảo rằng bản sao đang hoạt động giữa các thành viên của tập hợp bản sao.

Bước 6 - Kiểm tra bản sao MongoDB

Với việc ứng dụng của ta đang chạy và có thể truy cập thông qua địa chỉ IP bên ngoài, ta có thể thêm một số dữ liệu thử nghiệm và đảm bảo nó đang được sao chép giữa các thành viên của tập bản sao MongoDB của ta .

Trước tiên, hãy đảm bảo bạn đã chuyển trình duyệt của bạn đến trang đích của ứng dụng:

Trang đích ứng dụng

Nhấp vào nút Nhận thông tin cá mập . Bạn sẽ thấy một trang có mẫu mục nhập, nơi bạn có thể nhập tên cá mập và mô tả về đặc điểm chung của con cá mập đó:

Biểu mẫu thông tin cá mập

Trong biểu mẫu, hãy thêm một con cá mập ban đầu mà bạn chọn. Để chứng minh, ta sẽ thêm Megalodon Shark vào trường Shark NameAncient vào trường Shark Character :

Hình thức cá mập đầy

Bấm vào nút Gửi . Bạn sẽ thấy một trang với thông tin cá mập này được hiển thị lại cho bạn:

Đầu ra cá mập

Bây giờ quay lại biểu mẫu thông tin về cá mập bằng cách nhấp vào Cá mập trong thanh chuyển trên cùng:

Biểu mẫu thông tin cá mập

Nhập một con cá mập mới mà bạn chọn. Ta sẽ đi với Whale SharkLarge :

Tham gia Shark mới

Khi bạn nhấp vào Gửi , bạn sẽ thấy rằng cá mập mới đã được thêm vào bộ sưu tập cá mập trong database của bạn:

Bộ sưu tập cá mập hoàn chỉnh

Hãy kiểm tra xem dữ liệu ta đã nhập đã được sao chép giữa các thành viên chính và phụ của tập hợp bản sao của ta chưa.

Nhận danh sách các Group của bạn:

  • kubectl get pods
Output
NAME READY STATUS RESTARTS AGE mongo-mongodb-replicaset-0 1/1 Running 0 74m mongo-mongodb-replicaset-1 1/1 Running 0 73m mongo-mongodb-replicaset-2 1/1 Running 0 72m nodejs-nodeapp-577df49dcc-b5fq5 1/1 Running 0 5m4s nodejs-nodeapp-577df49dcc-bkk66 1/1 Running 0 5m4s nodejs-nodeapp-577df49dcc-lpmt2 1/1 Running 0 5m4s

Để truy cập trình bao mongo trên Pods của bạn, bạn có thể sử dụng lệnh thực thi kubectl exec và tên user bạn đã sử dụng để tạo mongo-secretBước 2 . Truy cập shell mongo trên Pod đầu tiên trong StatefulSet bằng lệnh sau:

  • kubectl exec -it mongo-mongodb-replicaset-0 -- mongo -u your_database_username -p --authenticationDatabase admin

Khi được yêu cầu , hãy nhập password được liên kết với tên user này:

Output
MongoDB shell version v4.1.9 Enter password:

Bạn sẽ được đưa vào một shell quản trị:

Output
MongoDB server version: 4.1.9 Welcome to the MongoDB shell. ... db:PRIMARY>

Mặc dù bản thân dấu nhắc bao gồm thông tin này, bạn có thể kiểm tra theo cách thủ công để xem thành viên tập hợp bản sao nào là thành viên chính bằng phương thức rs.isMaster() :

  • rs.isMaster()

Bạn sẽ thấy kết quả như sau, cho biết tên server của chính:

Output
db:PRIMARY> rs.isMaster() { "hosts" : [ "mongo-mongodb-replicaset-0.mongo-mongodb-replicaset.default.svc.cluster.local:27017", "mongo-mongodb-replicaset-1.mongo-mongodb-replicaset.default.svc.cluster.local:27017", "mongo-mongodb-replicaset-2.mongo-mongodb-replicaset.default.svc.cluster.local:27017" ], ... "primary" : "mongo-mongodb-replicaset-0.mongo-mongodb-replicaset.default.svc.cluster.local:27017", ...

Tiếp theo, chuyển sang database sharkinfo của bạn:

  • use sharkinfo
Output
switched to db sharkinfo

Liệt kê các bộ sưu tập trong database :

  • show collections
Output
sharks

Xuất các tài liệu trong bộ sưu tập:

  • db.sharks.find()

Bạn sẽ thấy kết quả sau:

Output
{ "_id" : ObjectId("5cb7702c9111a5451c6dc8bb"), "name" : "Megalodon Shark", "character" : "Ancient", "__v" : 0 } { "_id" : ObjectId("5cb77054fcdbf563f3b47365"), "name" : "Whale Shark", "character" : "Large", "__v" : 0 }

Thoát khỏi MongoDB Shell:

  • exit

Bây giờ ta đã kiểm tra dữ liệu trên trang chính của bạn , hãy kiểm tra xem nó có đang được sao chép sang dữ liệu phụ hay không. kubectl exec thành mongo-mongodb-replicaset-1 bằng lệnh sau:

  • kubectl exec -it mongo-mongodb-replicaset-1 -- mongo -u your_database_username -p --authenticationDatabase admin

Khi ở trong hệ thống quản trị, ta cần sử dụng phương thức db.setSlaveOk() để cho phép các thao tác đọc từ version phụ:

  • db.setSlaveOk(1)

Chuyển sang database sharkinfo :

  • use sharkinfo
Output
switched to db sharkinfo

Cho phép thao tác đọc các tài liệu trong bộ sưu tập sharks :

  • db.setSlaveOk(1)

Xuất các tài liệu trong bộ sưu tập:

  • db.sharks.find()

Đến đây bạn sẽ thấy cùng một thông tin mà bạn đã thấy khi chạy phương thức này trên version chính của bạn :

Output
db:SECONDARY> db.sharks.find() { "_id" : ObjectId("5cb7702c9111a5451c6dc8bb"), "name" : "Megalodon Shark", "character" : "Ancient", "__v" : 0 } { "_id" : ObjectId("5cb77054fcdbf563f3b47365"), "name" : "Whale Shark", "character" : "Large", "__v" : 0 }

Đầu ra này xác nhận dữ liệu ứng dụng của bạn đang được sao chép giữa các thành viên của tập hợp bản sao của bạn.

Kết luận

Như vậy, bạn đã triển khai một ứng dụng thông tin cá mập được nhân rộng, có tính khả dụng cao trên một cụm Kubernetes bằng cách sử dụng biểu đồ Helm. Ứng dụng demo này và quy trình làm việc được nêu trong hướng dẫn này có thể hoạt động như một điểm khởi đầu khi bạn xây dựng biểu đồ tùy chỉnh cho ứng dụng của bạn và tận dụng repository ổn định của Helm và các kho biểu đồ khác .

Khi bạn chuyển sang production , hãy cân nhắc thực hiện những điều sau:

Để tìm hiểu thêm về Helm, hãy xem Giới thiệu về Helm, Trình quản lý gói cho Kubernetes , Cách cài đặt phần mềm trên Kubernetes Cluster với Trình quản lý gói Helmtài liệu Helm .


Tags:

Các tin liên quan