Cách di chuyển Docker compose workflow sang Kubernetes
Khi xây dựng các ứng dụng hiện đại, không trạng thái, việc chứa đựng các thành phần của ứng dụng là bước đầu tiên trong việc triển khai và mở rộng quy mô trên các nền tảng phân tán. Nếu bạn đã sử dụng Docker Compose trong quá trình phát triển, bạn sẽ hiện đại hóa và chứa ứng dụng của bạn bằng cách:- Extract thông tin cấu hình cần thiết từ mã của bạn.
- Đang download trạng thái ứng dụng của bạn.
- Đóng gói ứng dụng của bạn để sử dụng nhiều lần.
Bạn cũng sẽ có các định nghĩa dịch vụ bằng text chỉ định cách các containers images của bạn sẽ chạy.
Để chạy các dịch vụ của bạn trên một nền tảng phân tán như Kubernetes , bạn cần phải dịch các định nghĩa dịch vụ Soạn của bạn sang các đối tượng Kubernetes. Điều này sẽ cho phép bạn mở rộng ứng dụng của bạn với khả năng phục hồi . Một công cụ có thể tăng tốc quá trình dịch sang Kubernetes là kompose , một công cụ chuyển đổi giúp các nhà phát triển chuyển stream công việc Soạn sang các trình điều phối containers như Kubernetes hoặc OpenShift .
Trong hướng dẫn này, bạn sẽ dịch các dịch vụ Soạn thư sang các đối tượng Kubernetes bằng cách sử dụng kompose. Bạn sẽ sử dụng các định nghĩa đối tượng mà kompose cung cấp như một bắt đầu điều chỉnh điểm và làm đảm bảo rằng cài đặt của bạn sẽ sử dụng bí mật , dịch vụ , và PersistentVolumeClaims trong cách mà hy vọng Kubernetes. Đến cuối hướng dẫn, bạn sẽ có một ứng dụng Node.js đơn lẻ với database MongoDB chạy trên một cụm Kubernetes. Cài đặt 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 giải pháp sẵn sàng production phù hợp với nhu cầu của bạn.
Yêu cầu
- Một cụm Kubernetes 1.10+ được bật kiểm soát truy cập dựa trên role (RBAC). Cài đặt này sẽ sử dụng một cụm DigitalOcean Kubernetes , nhưng bạn có thể tự do tạo một cụm bằng phương pháp khác .
-  Công cụ dòng lệnh kubectlđược cài đặt trên máy local hoặc server phát triển của bạn và được cấu hình để kết nối với cụm của bạn. Bạn có thể đọc thêm về cách cài đặtkubectltrong tài liệu chính thức .
-  Docker được cài đặt trên máy local  hoặc  server  phát triển của bạn. Nếu bạn đang làm việc với Ubuntu 18.04, hãy làm theo Bước 1 và 2 của Cách cài đặt và sử dụng Docker trên Ubuntu 18.04 ; nếu không, hãy làm theo tài liệu chính thức để biết thông tin về cách cài đặt trên các hệ điều hành khác. Đảm bảo thêm  user  không phải root của bạn vào  group  docker, như được mô tả trong Bước 2 của hướng dẫn được liên kết.
- Một account Docker Hub . Để biết tổng quan về cách cài đặt , hãy tham khảo phần giới thiệu về Docker Hub này.
Bước 1 - Cài đặt kompose
 Để bắt đầu sử dụng kompose, hãy  chuyển  đến trang Bản phát hành GitHub của dự án và sao chép liên kết đến bản phát hành hiện tại (phiên bản 1.18.0 tính đến thời điểm viết bài này). Dán liên kết này vào lệnh curl sau để  download  version  kompose mới nhất:
- curl -L https://github.com/kubernetes/kompose/releases/download/v1.18.0/kompose-linux-amd64 -o kompose 
Để biết chi tiết về cài đặt trên các hệ thống không phải Linux, vui lòng tham khảo hướng dẫn cài đặt .
Làm cho file binary có thể thực thi:
- chmod +x kompose 
Di chuyển nó đến PATH của bạn:
- sudo mv ./kompose /usr/local/bin/kompose 
Để xác minh nó đã được cài đặt đúng cách, bạn có thể kiểm tra version :
- kompose version 
Nếu cài đặt thành công, bạn sẽ thấy kết quả như sau:
Output1.18.0 (06a2e56) Với kompose đã được cài đặt và sẵn sàng sử dụng, bây giờ bạn có thể sao chép mã dự án Node.js mà bạn sẽ dịch sang Kubernetes.
Bước 2 - 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  sao chép mã dự án và đóng gói ứng dụng để dịch vụ kubelet có thể kéo hình ảnh.
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 để trình bày cách cài đặt môi trường phát triển bằng Docker Compose. Bạn có thể tìm thêm thông tin về chính ứ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, không trạng thái, vui lòng xemỨng dụng lưu trữ cho Kubernetes và Ứng dụng hiện đại hóa cho Kubernetes .
 Thư mục dự án bao gồm một Dockerfile với các hướng dẫn để xây dựng hình ảnh ứng dụng. Hãy xây dựng hình ảnh ngay bây giờ để bạn có thể đẩy nó vào account  Docker Hub và sử dụng nó trong  cài đặt  Kubernetes của bạn.
 Sử dụng lệnh docker build , xây dựng hình ảnh bằng cờ -t , cho phép bạn gắn thẻ nó 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ó là node-kubernetes hoặc tên bạn chọn:
- docker build -t your_dockerhub_username/node-kubernetes . 
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:
OutputREPOSITORY                                TAG                 IMAGE ID            CREATED             SIZE your_dockerhub_username/node-kubernetes   latest              9c6f897e1fbc        3 seconds ago       90MB node                                      10-alpine           94f3c8956482        12 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  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-kubernetes 
Đế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ủa bạn với Kubernetes. Bước tiếp theo sẽ là dịch các định nghĩa dịch vụ ứng dụng của bạn sang các đối tượng Kubernetes.
Bước 3 - Dịch các Dịch vụ Soạn thư sang Đối tượng Kubernetes bằng kompose
 Tệp Docker Compose của  ta , ở đây được gọi là docker-compose.yaml , đưa ra các định nghĩa sẽ chạy các dịch vụ của  ta  với Compose. Dịch vụ trong Soạn là một containers  đang chạy và các định nghĩa dịch vụ chứa thông tin về cách mỗi  containers images   sẽ chạy. Trong bước này,  ta  sẽ dịch các định nghĩa này sang các đối tượng Kubernetes bằng cách sử dụng kompose để tạo các file  yaml . Các file  này sẽ chứa thông số kỹ thuật cho các đối tượng Kubernetes mô tả trạng thái mong muốn của chúng.
Ta sẽ sử dụng những file này để tạo ra các loại khác nhau của các đối tượng: Dịch vụ này sẽ đảm bảo các Pods chạy container của ta vẫn truy cập được; Các triển khai , sẽ chứa thông tin về trạng thái mong muốn của các Pod của ta ; một PersentlyVolumeClaim để cung cấp lưu trữ cho dữ liệu database của ta ; một ConfigMap cho các biến môi trường được đưa vào trong thời gian chạy; và một Bí mật cho user và password database của ứng dụng của ta . Một số định nghĩa này sẽ nằm trong các file mà kompose sẽ tạo cho ta và những định nghĩa khác ta cần phải tự tạo.
 Thứ nhất,  ta   cần  phải sửa đổi một số các định nghĩa trong  ta  docker-compose.yaml  file  để làm việc với Kubernetes.  Ta  sẽ bao gồm một tham chiếu đến hình ảnh ứng dụng mới được xây dựng của  ta  trong định nghĩa dịch vụ nodejs của  ta  và xóa các liên kết ràng buộc ,  dung lượng  và các lệnh bổ sung mà  ta  đã sử dụng để chạy containers  ứng dụng đang được phát triển với Soạn. Ngoài ra,  ta  sẽ xác định lại policy  khởi động lại của cả hai containers  để phù hợp với hành vi mà Kubernetes mong đợi .
 Mở file  bằng nano  hoặc editor bạn quen dùng :
- nano docker-compose.yaml 
Định nghĩa hiện tại cho dịch vụ ứng dụng nodejs trông giống như sau:
... services:   nodejs:     build:       context: .       dockerfile: Dockerfile     image: nodejs     container_name: nodejs     restart: unless-stopped     env_file: .env     environment:       - MONGO_USERNAME=$MONGO_USERNAME       - MONGO_PASSWORD=$MONGO_PASSWORD       - MONGO_HOSTNAME=db       - MONGO_PORT=$MONGO_PORT       - MONGO_DB=$MONGO_DB      ports:       - "80:8080"     volumes:       - .:/home/node/app       - node_modules:/home/node/app/node_modules     networks:       - app-network     command: ./wait-for.sh db:27017 -- /home/node/app/node_modules/.bin/nodemon app.js ... Thực hiện các chỉnh sửa sau đối với định nghĩa dịch vụ của bạn:
-  Sử dụng hình ảnh node-kubernetescủa bạn thay vìDockerfilelocal .
-  Thay đổi policy  restartcontainers từunless-stoppedthànhalways.
-  Xóa danh sách volumesvàcommand.
Định nghĩa dịch vụ đã hoàn thành bây giờ sẽ giống như sau:
... services:   nodejs:     image: your_dockerhub_username/node-kubernetes     container_name: nodejs     restart: always     env_file: .env     environment:       - MONGO_USERNAME=$MONGO_USERNAME       - MONGO_PASSWORD=$MONGO_PASSWORD       - MONGO_HOSTNAME=db       - MONGO_PORT=$MONGO_PORT       - MONGO_DB=$MONGO_DB      ports:       - "80:8080"     networks:       - app-network ... Tiếp theo, cuộn xuống định nghĩa dịch vụ db . Tại đây, hãy thực hiện các chỉnh sửa sau:
-  Thay đổi policy  restartdịch vụ thànhalways.
-  Xóa file  .env. Thay vì sử dụng giá trị từ.envfile , ta sẽ vượt qua các giá trị cho taMONGO_INITDB_ROOT_USERNAMEvàMONGO_INITDB_ROOT_PASSWORDđể container database bằng cách sử dụng bí mật, ta sẽ tạo ra trong Bước 4 .
 Định nghĩa dịch vụ db bây giờ sẽ giống như sau:
...   db:     image: mongo:4.1.8-xenial     container_name: db     restart: always     environment:       - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME       - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD     volumes:         - dbdata:/data/db        networks:       - app-network ...   Cuối cùng, ở cuối file , hãy xóa các node_modules khỏi khóa volumes cấp cao nhất. Khóa bây giờ sẽ giống như sau:
... volumes:   dbdata: Lưu file khi bạn hoàn tất chỉnh sửa.
 Trước khi dịch định nghĩa dịch vụ của  ta ,  ta   cần  phải viết các .env  file  đó kompose sẽ sử dụng để tạo ra các configMap với thông tin không nhạy cảm của  ta . Vui lòng xem Bước 2 của Lưu trữ Đơn đăng ký Node.js để Phát triển Với Docker Compose để có giải thích dài hơn về file  này.
 Trong hướng dẫn đó,  ta  đã thêm .env vào file  .gitignore mình  đảm bảo  rằng nó sẽ không sao chép vào kiểm soát version . Điều này  nghĩa là  nó không sao chép khi  ta  sao chép kho lưu trữ node-mongo-docker-dev trong Bước 2 của hướng dẫn này . Do đó,  ta   cần  phải tạo lại nó ngay bây giờ.
Tạo file :
- nano .env 
kompose sẽ sử dụng file  này để tạo Bản đồ cấu hình cho ứng dụng của  ta . Tuy nhiên, thay vì gán tất cả các biến từ định nghĩa dịch vụ nodejs trong file  Soạn của  ta ,  ta  sẽ chỉ thêm tên database  MONGO_DB và MONGO_PORT .  Ta  sẽ chỉ định tên  user  và password  database  riêng biệt khi  ta  tạo thủ công đối tượng Bí mật trong Bước 4 .
 Thêm thông tin tên cổng và database  sau vào file  .env . Hãy đổi tên database  của bạn nếu bạn muốn:
MONGO_PORT=27017 MONGO_DB=sharkinfo Lưu file khi bạn hoàn tất chỉnh sửa.
Đến đây bạn đã sẵn sàng để tạo các file với thông số kỹ thuật đối tượng của bạn . kompose cung cấp nhiều tùy chọn để dịch tài nguyên của bạn. Bạn có thể:
-  Tạo yamlfile dựa trên định nghĩa dịch vụ trong bạndocker-compose.yamlfile vớikompose convert.
-  Tạo các đối tượng Kubernetes trực tiếp với kompose up.
-  Tạo biểu đồ Helm với kompose convert -c.
 Hiện tại,  ta  sẽ chuyển đổi các định nghĩa dịch vụ  của bạn  thành các file  yaml , sau đó thêm vào và sửa đổi các file  mà kompose tạo ra.
 Chuyển đổi định nghĩa dịch vụ của bạn thành file  yaml bằng lệnh sau:
- kompose convert 
Bạn cũng có thể đặt tên cụ thể hoặc nhiều file  Soạn bằng cờ -f .
Sau khi bạn chạy lệnh này, kompose sẽ xuất ra thông tin về các file mà nó đã tạo:
OutputINFO Kubernetes file "nodejs-service.yaml" created  INFO Kubernetes file "db-deployment.yaml" created  INFO Kubernetes file "dbdata-persistentvolumeclaim.yaml" created  INFO Kubernetes file "nodejs-deployment.yaml" created  INFO Kubernetes file "nodejs-env-configmap.yaml" created  Chúng bao gồm yaml file với thông số kỹ thuật cho ứng dụng Node dịch vụ, triển khai, và configMap, cũng như cho dbdata PersistentVolumeClaim và database  MongoDB triển khai.
Những file này là một điểm khởi đầu tốt, nhưng để chức năng của ứng dụng của ta phù hợp với cài đặt được mô tả trong Chứa ứng dụng Node.js để phát triển với Docker Compose, ta cần thực hiện một số bổ sung và thay đổi đối với file mà kompose đã tạo.
Bước 4 - Tạo bí mật Kubernetes
 Để ứng dụng của  ta  hoạt động theo cách  ta  mong đợi,  ta   cần  thực hiện một số sửa đổi đối với các file  mà kompose đã tạo. Thay đổi đầu tiên trong số những thay đổi này sẽ tạo ra một Bí mật cho  user  và password  database  của  ta  và thêm nó vào Triển khai ứng dụng và database  của  ta . Kubernetes đưa ra hai cách làm việc với các biến môi trường: Bản đồ cấu hình và Bản đồ bí mật. kompose đã tạo Bản đồ cấu hình với thông tin không bảo mật mà  ta  đưa vào file  .env của .env , vì vậy bây giờ  ta  sẽ tạo Bản đồ bí mật với thông tin bí mật  của bạn : tên  user  và password  database  của  ta .
Bước đầu tiên trong việc tạo Bí mật theo cách thủ công sẽ là chuyển đổi tên user và password của bạn thành base64 , một schemas mã hóa cho phép bạn truyền dữ liệu một cách đồng nhất, bao gồm cả dữ liệu binary .
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 và --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 ra một bí mật mà sẽ xác định bạn MONGO_USERNAME và MONGO_PASSWORD sử dụng các giá trị 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:
apiVersion: v1 kind: Secret metadata:   name: mongo-secret data:   MONGO_USERNAME: your_encoded_username   MONGO_PASSWORD: your_encoded_password  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   này khi bạn hoàn tất chỉnh sửa. Như bạn đã làm với file  .env  của bạn , hãy đảm bảo thêm secret.yaml vào file  .gitignore của bạn để không kiểm soát version .
 Với secret.yaml được viết, bước tiếp theo của  ta  sẽ là  đảm bảo  các Pod ứng dụng và database  của  ta  đều sử dụng các giá trị mà  ta  đã thêm vào file . Hãy bắt đầu bằng cách thêm các tham chiếu đến Bí mật để Triển khai ứng dụng của  ta .
 Mở file  có tên nodejs-deployment.yaml :
- nano nodejs-deployment.yaml 
Đặc tả containers  của file  bao gồm các biến môi trường sau được xác định trong khóa env :
apiVersion: extensions/v1beta1 kind: Deployment ...     spec:       containers:       - env:         - name: MONGO_DB           valueFrom:             configMapKeyRef:               key: MONGO_DB               name: nodejs-env         - name: MONGO_HOSTNAME           value: db         - name: MONGO_PASSWORD         - name: MONGO_PORT           valueFrom:             configMapKeyRef:               key: MONGO_PORT               name: nodejs-env         - name: MONGO_USERNAME  Ta   cần  thêm các tham chiếu vào Bí mật của  ta  vào các MONGO_USERNAME và MONGO_PASSWORD được liệt kê ở đây, để ứng dụng của  ta  có quyền truy cập vào các giá trị đó. Thay vì bao gồm khóa configMapKeyRef để trỏ đến Bản đồ cấu hình nodejs-env của  ta , như trường hợp với các giá trị cho MONGO_DB và MONGO_PORT ,  ta  sẽ bao gồm khóa secretKeyRef để trỏ đến các giá trị trong mongo-secret mật mongo-secret của  ta .
 Thêm các tham chiếu Bí mật sau vào biến MONGO_USERNAME và MONGO_PASSWORD :
apiVersion: extensions/v1beta1 kind: Deployment ...     spec:       containers:       - env:         - name: MONGO_DB           valueFrom:             configMapKeyRef:               key: MONGO_DB               name: nodejs-env         - name: MONGO_HOSTNAME           value: db         - name: MONGO_PASSWORD           valueFrom:             secretKeyRef:               name: mongo-secret               key: MONGO_PASSWORD         - name: MONGO_PORT           valueFrom:             configMapKeyRef:               key: MONGO_PORT               name: nodejs-env         - name: MONGO_USERNAME           valueFrom:             secretKeyRef:               name: mongo-secret               key: MONGO_USERNAME Lưu file khi bạn hoàn tất chỉnh sửa.
 Tiếp theo,  ta  sẽ thêm các giá trị tương tự vào file  db-deployment.yaml .
Mở file để chỉnh sửa:
- nano db-deployment.yaml 
Trong file  này,  ta  sẽ thêm các tham chiếu vào Bí mật của  ta  cho các khóa biến sau: MONGO_INITDB_ROOT_USERNAME và MONGO_INITDB_ROOT_PASSWORD . Hình ảnh mongo cung cấp các biến này để bạn có thể sửa đổi quá trình khởi tạo đối tượng database   của bạn . MONGO_INITDB_ROOT_USERNAME và MONGO_INITDB_ROOT_PASSWORD cùng nhau tạo  user  root trong database  xác thực admin và  đảm bảo  xác thực được bật khi containers  database  khởi động.
 Việc sử dụng các giá trị mà  ta  đặt trong Bí mật  của bạn   đảm bảo   ta  sẽ có một  user  ứng dụng có  quyền  root trên cá thể database , có quyền truy cập vào tất cả các  quyền  quản trị và hoạt động của  role  đó. Khi làm việc trong production ,  bạn cần  tạo một  user  ứng dụng chuyên dụng với các  quyền  trong phạm vi phù hợp.
 Trong các MONGO_INITDB_ROOT_USERNAME và MONGO_INITDB_ROOT_PASSWORD , hãy thêm tham chiếu vào giá trị Bí mật:
apiVersion: extensions/v1beta1 kind: Deployment ...     spec:       containers:       - env:         - name: MONGO_INITDB_ROOT_PASSWORD           valueFrom:             secretKeyRef:               name: mongo-secret               key: MONGO_PASSWORD                 - name: MONGO_INITDB_ROOT_USERNAME           valueFrom:             secretKeyRef:               name: mongo-secret               key: MONGO_USERNAME         image: mongo:4.1.8-xenial ... Lưu file khi bạn hoàn tất chỉnh sửa.
Với Bí mật của bạn tại chỗ, bạn có thể chuyển sang tạo Dịch vụ database của bạn và đảm bảo containers ứng dụng của bạn chỉ cố gắng kết nối với database sau khi nó được cài đặt và chạy đầy đủ.
Bước 5 - Tạo Dịch vụ Database và Vùng chứa Đơn vị Ứng dụng
 Bây giờ  ta  đã có Bí mật  của bạn ,  ta  có thể chuyển sang tạo Dịch vụ database   của bạn  và Vùng chứa Init sẽ thăm dò Dịch vụ này  đảm bảo  rằng ứng dụng của  ta  chỉ cố gắng kết nối với database  khi database  khởi động tác vụ, bao gồm tạo  user  và password  MONGO_INITDB , đã hoàn thành.
Để thảo luận về cách triển khai chức năng này trong Soạn thư, vui lòng xem Bước 4 của Quy trình quản lý ứng dụng Node.js để phát triển với Docker Compose .
Mở file để xác định các thông số kỹ thuật cho Dịch vụ database :
- nano db-service.yaml   
Thêm mã sau vào file để xác định Dịch vụ:
apiVersion: v1 kind: Service metadata:   annotations:      kompose.cmd: kompose convert     kompose.version: 1.18.0 (06a2e56)   creationTimestamp: null   labels:     io.kompose.service: db   name: db spec:   ports:   - port: 27017     targetPort: 27017   selector:     io.kompose.service: db status:   loadBalancer: {} Bộ selector mà  ta  đã đưa vào đây sẽ khớp đối tượng Dịch vụ này với các  Group  database  của  ta , đã được xác định với nhãn io.kompose.service: db by kompose trong file  db-deployment.yaml deploy.yaml.  Ta  cũng đã đặt tên cho dịch vụ này là db .
Lưu file khi bạn hoàn tất chỉnh sửa.
 Tiếp theo, hãy thêm trường Init Container vào mảng containers trong nodejs-deployment.yaml . Điều này sẽ tạo một Vùng chứa Init mà  ta  có thể sử dụng để trì hoãn việc khởi động containers  ứng dụng  của bạn  cho đến khi Dịch vụ db được tạo bằng một Pod có thể truy cập được. Đây là một trong những cách sử dụng có thể có cho Init Containers; để tìm hiểu thêm về các trường hợp sử dụng khác, vui lòng xem tài liệu chính thức .
 Mở file  nodejs-deployment.yaml :
- nano nodejs-deployment.yaml 
Trong Pod spec và cùng với mảng containers ,  ta  sẽ thêm trường initContainers với một container sẽ thăm dò Dịch vụ db .
 Thêm mã sau vào bên dưới các ports và trường resources và bên trên restartPolicy trong mảng vùng containers nodejs :
apiVersion: extensions/v1beta1 kind: Deployment ...     spec:       containers:       ...         name: nodejs         ports:         - containerPort: 8080         resources: {}       initContainers:       - name: init-db         image: busybox         command: ['sh', '-c', 'until nc -z db:27017; do echo waiting for db; sleep 2; done;']       restartPolicy: Always ...                Init Container này sử dụng hình ảnh BusyBox , một hình ảnh nhẹ bao gồm nhiều tiện ích UNIX. Trong trường hợp này,  ta  sẽ  sử dụng trình  netcat để thăm dò xem liệu Pod được liên kết với Dịch vụ db có chấp nhận kết nối TCP trên cổng 27017 .
  Container  này command tái tạo các chức năng của wait-for kịch bản mà  ta  ra khỏi  ta  docker-compose.yaml  file  trong Bước 3 . Để thảo luận lâu hơn về cách thức và lý do ứng dụng của  ta  sử dụng tập lệnh wait-for khi làm việc với Soạn thư, vui lòng xem Bước 4 của Khoá chứa ứng dụng Node.js để phát triển với Docker Compose .
 Init Container chạy đến khi hoàn thành; trong trường hợp của  ta , điều này  nghĩa là  containers  ứng dụng Node của  ta  sẽ không bắt đầu cho đến khi containers  database  đang chạy và chấp nhận các kết nối trên cổng 27017 . Định nghĩa Dịch vụ db cho phép  ta  đảm bảo chức năng này  dù  vị trí chính xác của containers  database , có thể thay đổi.
Lưu file khi bạn hoàn tất chỉnh sửa.
Với Dịch vụ database của bạn đã được tạo và Vùng chứa Init của bạn tại chỗ để kiểm soát thứ tự khởi động của các containers , bạn có thể chuyển sang kiểm tra các yêu cầu lưu trữ trong PersisteVolumeClaim và hiển thị dịch vụ ứng dụng của bạn bằng cách sử dụng LoadBalancer .
Bước 6 - Sửa đổi PersermanentVolumeClaim và hiển thị giao diện user ứng dụng
Trước khi chạy ứng dụng của bạn , ta sẽ thực hiện hai thay đổi cuối cùng đảm bảo rằng bộ nhớ database của ta sẽ được cung cấp đúng cách và ta có thể hiển thị giao diện user ứng dụng của bạn bằng cách sử dụng LoadBalancer.
 Đầu tiên,  ta  hãy sửa đổi resource storage được xác định trong PersentlyVolumeClaim mà kompose đã tạo cho  ta . Khiếu nại này cho phép  ta  cung cấp động bộ lưu trữ để quản lý trạng thái ứng dụng của  ta .
 Để làm việc với PersentlyVolumeClaims, bạn phải tạo và  cấu hình  StorageClass để cung cấp tài nguyên lưu trữ. Trong trường hợp của  ta , vì  ta  đang làm việc với DigitalOcean Kubernetes , nên bộ 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:
OutputNAME                         PROVISIONER                 AGE do-block-storage (default)   dobs.csi.digitalocean.com   76m Nếu bạn không làm việc với cụm DigitalOcean, bạn  cần  tạo StorageClass và  cấu hình  bộ provisioner mà bạn chọ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 .
 Khi kompose tạo dbdata dbdata-persistentvolumeclaim.yaml dẳngvolumeclaim.yaml, nó sẽ đặt resource storage thành kích thước không đáp ứng yêu cầu kích thước tối thiểu của trình provisioner của  ta . Do đó,  ta   cần  sửa đổi PersentlyVolumeClaim  của bạn  để sử dụng đơn vị Lưu trữ khối DigitalOcean khả thi tối thiểu : 1GB. Vui lòng sửa đổi điều này để đáp ứng yêu cầu lưu trữ của bạn.
 Mở dbdata-persistentvolumeclaim.yaml :
- nano dbdata-persistentvolumeclaim.yaml 
Thay thế giá trị storage bằng 1Gi :
apiVersion: v1 kind: PersistentVolumeClaim metadata:   creationTimestamp: null   labels:     io.kompose.service: dbdata   name: dbdata spec:   accessModes:   - ReadWriteOnce   resources:     requests:       storage: 1Gi status: {} Cũng  lưu ý  accessMode : ReadWriteOnce  nghĩa là   dung lượng  được cung cấp là kết quả của Yêu cầu này 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.
Lưu file khi bạn hoàn tất.
 Tiếp theo, mở nodejs-service.yaml :
- nano nodejs-service.yaml 
 Ta  sẽ đưa Dịch vụ này ra bên ngoài bằng cách sử dụng Bộ cân bằng tải DigitalOcean . Nếu bạn không sử dụng cụm DigitalOcean, vui lòng tham khảo tài liệu có liên quan từ nhà cung cấp  cloud  của bạn để biết thông tin về bộ cân bằng tải của họ. Ngoài ra, bạn có thể làm theo tài liệu chính thức của Kubernetes về cách  cài đặt  một cụm khả dụng cao với kubeadm , nhưng trong trường hợp này, bạn sẽ không thể sử dụng PersentlyVolumeClaims để cung cấp bộ nhớ.
 Trong thông số Dịch vụ, chỉ định LoadBalancer làm type Dịch vụ:
apiVersion: v1 kind: Service ... spec:   type: LoadBalancer   ports: ... Khi  ta  tạo Dịch vụ nodejs , một bộ cân bằng tải sẽ được tạo tự động, cung cấp cho  ta  một IP bên ngoài để  ta  có thể truy cập ứng dụng  của bạn .
Lưu file khi bạn hoàn tất chỉnh sửa.
Với tất cả các file của ta đã có sẵn, ta đã sẵn sàng để bắt đầu và thử nghiệm ứng dụng.
Bước 7 - Khởi động và truy cập ứng dụng
Đã đến lúc tạo các đối tượng Kubernetes của ta và kiểm tra xem ứng dụng của ta có hoạt động như mong đợi hay không.
 Để tạo các đối tượng mà  ta  đã xác định,  ta  sẽ sử dụng kubectl create với cờ -f , cho phép  ta  chỉ định các file  mà kompose đã tạo cho  ta , cùng với các file   ta  đã viết. Chạy lệnh sau để tạo ứng dụng Node và các dịch vụ và triển khai database  MongoDB, cùng với Secret, ConfigMap và PersentlyVolumeClaim của bạn:
- kubectl create -f nodejs-service.yaml,nodejs-deployment.yaml,nodejs-env-configmap.yaml,db-service.yaml,db-deployment.yaml,dbdata-persistentvolumeclaim.yaml,secret.yaml 
Bạn sẽ thấy kết quả sau cho biết các đối tượng đã được tạo:
Outputservice/nodejs created deployment.extensions/nodejs created configmap/nodejs-env created service/db created deployment.extensions/db created persistentvolumeclaim/dbdata created secret/mongo-secret created Để kiểm tra xem Pod của bạn có đang chạy hay không, hãy nhập:
- kubectl get pods 
Bạn không cần chỉ định Không gian tên ở đây, vì  ta  đã tạo các đối tượng  của bạn  trong Không gian tên default . Nếu bạn đang làm việc với nhiều Không gian tên, hãy đảm bảo bao gồm cờ -n khi chạy lệnh này, cùng với tên của Không gian tên của bạn.
 Bạn sẽ thấy  kết quả  sau khi containers  db của bạn đang khởi động và Vùng chứa Init ứng dụng của bạn đang chạy:
OutputNAME                      READY   STATUS              RESTARTS   AGE db-679d658576-kfpsl       0/1     ContainerCreating   0          10s nodejs-6b9585dc8b-pnsws   0/1     Init:0/1            0          10s Khi containers đó đã chạy và các containers ứng dụng và database của bạn đã bắt đầu, bạn sẽ thấy kết quả này:
OutputNAME                      READY   STATUS    RESTARTS   AGE db-679d658576-kfpsl       1/1     Running   0          54s nodejs-6b9585dc8b-pnsws   1/1     Running   0          54s 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 
Với các containers của bạn đang chạy, bây giờ bạn có thể truy cập ứng dụng. Để lấy IP cho LoadBalancer, hãy nhập:
- kubectl get svc 
Bạn sẽ thấy kết quả sau:
OutputNAME         TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)        AGE db           ClusterIP      10.245.189.250   <none>           27017/TCP      93s kubernetes   ClusterIP      10.245.0.1       <none>           443/TCP        25m12s nodejs       LoadBalancer   10.245.15.56     your_lb_ip       80:30729/TCP   93s EXTERNAL_IP liên kết với dịch vụ nodejs là địa chỉ IP nơi bạn có thể truy cập ứng dụng. 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:
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 đó:
 Trong biểu mẫu, hãy thêm một con cá mập mà bạn chọn. Để chứng minh,  ta  sẽ thêm Megalodon Shark vào trường Shark Name và Ancient vào trường Shark Character : 
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:
Đến đây bạn có một cài đặt version duy nhất của ứng dụng Node.js với database MongoDB chạy trên cụm Kubernetes.
Kết luận
Các file bạn đã tạo trong hướng dẫn này là một điểm khởi đầu tốt để xây dựng khi bạn chuyển sang production . Khi bạn phát triển ứng dụng của bạn , bạn có thể thực hiện các bước sau:
- Ghi log và giám sát tập trung . Vui lòng xem thảo luận liên quan trong Hiện đại hóa ứng dụng cho Kubernetes để biết tổng quan chung. Bạn cũng có thể xem Cách cài đặt ngăn xếp ghi log Elasticsearch, Fluentd và Kibana (EFK) trên Kubernetes để tìm hiểu cách cài đặt ngăn xếp ghi log với Elasticsearch , Fluentd và Kibana . Ngoài ra, hãy xem Giới thiệu về Lưới dịch vụ để biết thông tin về cách các lưới dịch vụ như Istio triển khai chức năng này.
- Nhập Tài nguyên để định tuyến lưu lượng truy cập đến cụm của bạn . Đây là một giải pháp thay thế tốt cho LoadBalancer trong trường hợp bạn đang chạy nhiều Dịch vụ, mỗi Dịch vụ yêu cầu LoadBalancer riêng của chúng hoặc nơi bạn muốn triển khai các chiến lược định tuyến cấp ứng dụng (ví dụ: thử nghiệm A / B & canary). Để biết thêm thông tin, hãy xem Cách cài đặt Nginx Ingress với Cert-Manager trên DigitalOcean Kubernetes và thảo luận liên quan về định tuyến trong ngữ cảnh lưới dịch vụ trong Giới thiệu về Lưới dịch vụ .
- Các chiến lược backup cho các đối tượng Kubernetes của bạn . Để được hướng dẫn về cách triển khai backup với Velero (trước đây là Heptio Ark) với sản phẩm Kubernetes của DigitalOcean, vui lòng xem Cách backup và khôi phục Cụm Kubernetes trên DigitalOcean bằng Heptio Ark .
Các tin liên quan
Cách tối ưu hóa image Docker cho sản xuất2019-03-25
Giữ lại một ứng dụng Node.js để phát triển với Docker Compose
2019-03-05
Cách cài đặt và sử dụng Docker Compose trên CentOS 7
2019-01-23
Cách sử dụng Traefik làm reverse-proxy cho container Docker trên Debian 9
2019-01-08
Cách thiết lập registry Docker riêng trên Ubuntu 18.04
2019-01-07
Cách thiết lập triển khai nhiều node với Rancher 2.1, Kubernetes và Docker Machine trên Ubuntu 18.04
2019-01-03
Cách tạo ứng dụng Node.js với Docker
2018-11-29
Cách quản lý triển khai nhiều node với Máy Rancher và Docker trên Ubuntu 16.04
2018-10-30
Cách cài đặt và sử dụng Docker trên Ubuntu 16.04
2018-10-19
Cách cung cấp và quản lý server Docker từ xa bằng Máy Docker trên Ubuntu 18.04
2018-10-02
 

