Chuỗi hội thảo trên web: Triển khai và mở rộng quy mô Microservices trong Kubernetes
Bài viết này bổ sung chuỗi hội thảo trên web về triển khai và quản lý dung lượng công việc được chứa trong cloud . Loạt bài này bao gồm các yếu tố cần thiết của containers , bao gồm quản lý vòng đời của containers , triển khai các ứng dụng đa containers , mở rộng dung lượng công việc và làm việc với Kubernetes. Nó cũng nêu bật các phương pháp hay nhất để chạy các ứng dụng trạng thái. Hướng dẫn này bao gồm các khái niệm và lệnh trong phiên thứ năm của loạt bài, Triển khai và Mở rộng Microservices trong Kubernetes.
Kubernetes là một công cụ điều phối containers open-souce để quản lý các ứng dụng được chứa trong containers . Trong phần hướng dẫn trước của loạt bài này, Xem kỹ hơn về Kubernetes, bạn đã học được các khối xây dựng của Kubernetes.
Trong hướng dẫn này, bạn sẽ áp dụng các khái niệm từ các hướng dẫn trước để xây dựng, triển khai và quản lý một ứng dụng microservices end-to-end trong Kubernetes. Ứng dụng web mẫu mà bạn sẽ sử dụng trong hướng dẫn này là ứng dụng “danh sách việc cần làm” được viết bằng Node.js sử dụng MongoDB làm database . Đây là ứng dụng tương tự mà ta đã sử dụng trong hướng dẫn Xây dựng ứng dụng được chứa trong thùng .
Bạn sẽ tạo một containers images cho ứng dụng này từ Dockerfile, đẩy hình ảnh đến Docker Hub, sau đó triển khai nó vào cụm của bạn. Sau đó, bạn sẽ mở rộng ứng dụng để đáp ứng nhu cầu ngày càng tăng.
Yêu cầu
Để hoàn thành hướng dẫn này, bạn cần :
Một cụm Kubernetes, mà bạn có thể cấu hình trong phần thứ ba của loạt bài hướng dẫn này, Bắt đầu với Kubernetes .
Tài khoản Docker Hub đang hoạt động để lưu trữ hình ảnh.
Git được cài đặt trên máy local của bạn. Bạn có thể làm theo hướng dẫn Đóng góp vào Nguồn mở: Bắt đầu với Git để cài đặt và cài đặt Git trên máy tính của bạn .
Bước 1 - Xây dựng hình ảnh bằng Dockerfile
Ta sẽ bắt đầu bằng cách chứa ứng dụng web bằng cách đóng gói nó thành một Docker image .
Bắt đầu bằng cách thay đổi folder chính của bạn, sau đó sử dụng Git để sao chép ứng dụng web mẫu của hướng dẫn này từ repository chính thức của nó trên GitHub.
- cd ~
- git clone https://github.com/janakiramm/todo-app.git
Xây dựng containers images từ Dockerfile. Sử dụng lựa chọn -t để gắn thẻ hình ảnh bằng tên user đăng ký, tên hình ảnh và thẻ tùy chọn.
- docker build -t sammy/todo .
Kết quả kết quả xác nhận hình ảnh đã được tạo thành công và được gắn thẻ thích hợp.
OutputSending build context to Docker daemon 8.238MB Step 1/7 : FROM node:slim ---> 286b1e0e7d3f Step 2/7 : LABEL maintainer = "jani@janakiram.com" ---> Using cache ---> ab0e049cf6f8 Step 3/7 : RUN mkdir -p /usr/src/app ---> Using cache ---> 897176832f4d Step 4/7 : WORKDIR /usr/src/app ---> Using cache ---> 3670f0147bed Step 5/7 : COPY ./app/ ./ ---> Using cache ---> e28c7c1be1a0 Step 6/7 : RUN npm install ---> Using cache ---> 7ce5b1d0aa65 Step 7/7 : CMD node app.js ---> Using cache ---> 2cef2238de24 Successfully built 2cef2238de24 Successfully tagged sammy/todo-app:latest
Xác minh hình ảnh được tạo bằng cách chạy lệnh docker images.
- docker images
Bạn có thể xem kích thước của hình ảnh cùng với thời gian kể từ khi nó được tạo.
OutputREPOSITORY TAG IMAGE ID CREATED SIZE sammy/todo-app latest 81f5f605d1ca 9 minutes ago 236MB
Tiếp theo, đẩy hình ảnh của bạn vào register công khai trên Docker Hub. Để thực hiện việc này, hãy đăng nhập vào account Docker Hub của bạn:
- docker login
Sau khi bạn cung cấp thông tin đăng nhập của bạn , hãy gắn thẻ hình ảnh của bạn bằng tên user Docker Hub:
- docker tag your_docker_hub_username/todo-app
Sau đó đẩy hình ảnh của bạn lên Docker Hub:
- docker push
Bạn có thể xác minh hình ảnh mới có sẵn bằng cách tìm kiếm Docker Hub trong trình duyệt web .
Với Docker image được đẩy vào register , hãy đóng gói ứng dụng cho Kubernetes.
Bước 2 - Triển khai MongoDB Pod trong Kubernetes
Ứng dụng sử dụng MongoDB để lưu trữ danh sách việc cần làm được tạo thông qua ứng dụng web. Để chạy MongoDB trong Kubernetes, ta cần đóng gói nó dưới dạng Pod. Khi ta chạy Pod này, nó sẽ chạy một version MongoDB.
Tạo file YAML mới có tên db-pod.yaml:
- nano db-pod.yaml
Thêm mã sau để xác định một Pod với một containers dựa trên MongoDB. Ta hiển thị cổng 27017
, cổng tiêu chuẩn được sử dụng bởi MongoDB. Lưu ý định nghĩa chứa name
nhãn và app
. Ta sẽ sử dụng các nhãn đó để xác định và cấu hình các Group cụ thể.
apiVersion: v1 kind: Pod metadata: name: db labels: name: mongo app: todoapp spec: containers: - image: mongo name: mongo ports: - name: mongo containerPort: 27017 volumeMounts: - name: mongo-storage mountPath: /data/db volumes: - name: mongo-storage hostPath: path: /data/db
Dữ liệu được lưu trữ trong khối gọi là mongo-storage
được ánh xạ tới vị trí /data/db
của nút. Để biết thêm thông tin về các Tập, hãy tham khảo tài liệu chính thức về các Tập của Kubernetes .
Chạy lệnh sau để tạo Pod.
- kubectl create -f db-pod.yml
Bạn sẽ thấy kết quả này:
Outputpod "db" created
Bây giờ hãy xác minh việc tạo Pod.
- kubectl get pods
Đầu ra hiển thị Pod và cho biết rằng nó đang chạy:
OutputNAME READY STATUS RESTARTS AGE db 1/1 Running 0 2m
Hãy làm cho Pod này có thể truy cập được đối với người tiêu dùng nội bộ của cụm.
Tạo một file mới có tên db-service.yaml
chứa mã này để xác định Dịch vụ cho MongoDB:
apiVersion: v1 kind: Service metadata: name: db labels: name: mongo app: todoapp spec: selector: name: mongo type: ClusterIP ports: - name: db port: 27017 targetPort: 27017
Dịch vụ phát hiện tất cả các Group trong cùng một Không gian tên trùng với Nhãn có name: db
. Phần selector
của file YAML xác định rõ ràng liên kết này.
Ta chỉ định rằng Dịch vụ được hiển thị trong cụm thông qua type: ClusterIP
khai báo type: ClusterIP
.
Lưu file và thoát khỏi editor . Sau đó, sử dụng kubectl
để gửi nó vào cụm.
- kubectl create -f db-service.yml
Bạn sẽ thấy kết quả này cho biết Dịch vụ đã được tạo thành công:
Outputservice "db" created
Hãy lấy cổng mà Pod có sẵn.
- kubectl get services
Bạn sẽ thấy kết quả này:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE db ClusterIP 10.109.114.243 <none> 27017/TCP 14s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 47m
Từ kết quả này, bạn có thể thấy rằng Dịch vụ có sẵn trên cổng 27017
. Ứng dụng web có thể truy cập MongoDB thông qua dịch vụ này. Khi nó sử dụng tên server db
, dịch vụ DNS chạy trong Kubernetes sẽ phân giải địa chỉ thành ClusterIP được liên kết với Dịch vụ. Cơ chế này cho phép các Group khám phá và giao tiếp với nhau.
Với database Pod và Service đã có sẵn, hãy tạo một Pod cho ứng dụng web.
Bước 3 - Triển khai Node.JS Web App dưới dạng một Pod
Hãy đóng gói Docker image bạn đã tạo trong bước đầu tiên của hướng dẫn này dưới dạng Pod và triển khai nó vào cụm. Điều này sẽ hoạt động như lớp ứng dụng web giao diện user cuối có thể truy cập được.
Tạo một file YAML mới có tên là web-pod.yaml
:
- nano web-pod.yaml
Thêm mã sau để xác định một Pod với một containers dựa trên Docker image sammy/todo-app
. Nó được hiển thị trên cổng 3000
qua giao thức TCP.
apiVersion: v1 kind: Pod metadata: name: web labels: name: web app: todoapp spec: containers: - image: sammy/todo-app name: myweb ports: - containerPort: 3000
Lưu ý định nghĩa chứa name
nhãn và app
. Một Dịch vụ sẽ sử dụng các nhãn này để định tuyến lưu lượng vào đến các cổng thích hợp.
Chạy lệnh sau để tạo Pod:
- kubectl create -f web-pod.yaml
Outputpod "web" created
Hãy xác minh việc tạo Pod:
- kubectl get pods
OutputNAME READY STATUS RESTARTS AGE db 1/1 Running 0 8m web 1/1 Running 0 9s
Lưu ý ta có cả database MongoDB và ứng dụng web đang chạy dưới dạng Pod.
Bây giờ ta sẽ làm cho web
Pod có thể truy cập được vào Internet công cộng.
Các dịch vụ hiển thị một bộ Group bên trong hoặc bên ngoài. Hãy xác định một Dịch vụ làm cho web
Pod có sẵn công khai. Ta sẽ giới thiệu nó thông qua NodePort, một sơ đồ giúp Pod có thể truy cập thông qua một cổng tùy ý được mở trên mỗi Node của cụm.
Tạo một file mới có tên là web-service.yaml
chứa mã này để xác định Dịch vụ cho ứng dụng:
apiVersion: v1 kind: Service metadata: name: web labels: name: web app: todoapp spec: selector: name: web type: NodePort ports: - name: http port: 3000 targetPort: 3000 protocol: TCP
Dịch vụ phát hiện tất cả các Group trong cùng một Không gian tên trùng với Nhãn với web
tên. Phần bộ chọn của file YAML xác định rõ ràng liên kết này.
Ta chỉ định rằng Dịch vụ thuộc loại NodePort
thông qua khai báo type: NodePort
.
Sử dụng kubectl
để gửi điều này đến cụm.
- kubectl create -f web-service.yml
Bạn sẽ thấy kết quả này cho biết Dịch vụ đã được tạo thành công:
Outputservice "web" created
Hãy lấy cổng mà Pod có sẵn.
- kubectl get services
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE db ClusterIP 10.109.114.243 <none> 27017/TCP 12m kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 59m web NodePort 10.107.206.92 <none> 3000:30770/TCP 12s
Từ kết quả này, ta thấy rằng Dịch vụ có sẵn trên cổng 30770
. Hãy thử kết nối với một trong các node Công nhân.
Lấy địa chỉ IP công cộng cho một trong các Nút công nhân được liên kết với Cụm Kubernetes của bạn bằng cách sử dụng console DigitalOcean.
Khi bạn đã có địa chỉ IP, hãy sử dụng lệnh curl
để thực hiện yêu cầu HTTP đến một trong các node trên cổng 30770
:
- curl http://your_worker_ip_address:30770
Bạn sẽ thấy kết quả tương tự như sau:
Output<!DOCTYPE html> <html> <head> <title>Containers Todo Example</title> <link rel='stylesheet' href='/stylesheets/screen.css' /> <!--[if lt IE 9]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> </head> <body> <div id="layout"> <h1 id="page-title">Containers Todo Example</h1> <div id="list"> <form action="/create" method="post" accept-charset="utf-8"> <div class="item-new"> <input class="input" type="text" name="content" /> </div> </form> </div> <div id="layout-footer"></div> </div> <script src="/javascripts/ga.js"></script> </body> </html>
Bạn đã xác định Pod web và một Dịch vụ. Bây giờ ta hãy xem xét việc mở rộng nó với Bộ bản sao.
Bước 5 - Mở rộng quy mô ứng dụng web
Bộ Bản sao đảm bảo số lượng Group tối thiểu luôn chạy trong cụm. Khi một Group được đóng gói dưới dạng Bộ bản sao, Kubernetes sẽ luôn chạy số lượng Group tối thiểu được xác định trong thông số kỹ thuật.
Hãy xóa Pod hiện tại và tạo lại hai Pod thông qua Bộ bản sao. Nếu ta để Pod chạy, nó sẽ không phải là một phần của Bộ bản sao. Do đó, bạn nên chạy Pod thông qua Bộ bản sao, ngay cả khi số lượng chỉ là một.
Đầu tiên, xóa Pod hiện có.
- kubectl delete pod web
Outputpod "web" deleted
Bây giờ, hãy tạo một khai báo Replica Set mới. Định nghĩa của Replica Set giống hệt với một Pod. Sự khác biệt chính là nó chứa phần tử replica
xác định số lượng Group cần chạy. Giống như Pod, nó cũng chứa Nhãn dưới dạng metadata giúp khám phá Dịch vụ.
Tạo file web-rs.yaml
và thêm mã này vào file :
apiVersion: extensions/v1beta1 kind: ReplicaSet metadata: name: web labels: name: web app: todoapp spec: replicas: 2 template: metadata: labels: name: web spec: containers: - name: web image: sammy/todo-app ports: - containerPort: 3000
Lưu và đóng file .
Bây giờ hãy tạo Bộ bản sao:
- kubectl create -f web-rs.yaml
Outputreplicaset "web" created
Sau đó, kiểm tra số lượng Group :
- kubectl get pods
OutputNAME READY STATUS RESTARTS AGE db 1/1 Running 0 18m web-n5l5h 1/1 Running 0 25s web-wh6nf 1/1 Running 0 25s
Khi ta truy cập Dịch vụ thông qua NodePort, yêu cầu sẽ được gửi đến một trong các Group do Bộ bản sao quản lý.
Hãy kiểm tra chức năng của Group bản sao bằng cách xóa một trong các Group và xem điều gì sẽ xảy ra:
- kubectl delete pod web-wh6nf
Outputpod "web-wh6nf" deleted
Nhìn lại Pod:
- kubectl get pods
OutputNAME READY STATUS RESTARTS AGE db 1/1 Running 0 19m web-n5l5h 1/1 Running 0 1m web-wh6nf 1/1 Terminating 0 1m web-ws59m 0/1 ContainerCreating 0 2s
Ngay sau khi Pod bị xóa, Kubernetes đã tạo một Pod khác đảm bảo duy trì số lượng mong muốn.
Ta có thể mở rộng Bộ bản sao để chạy các Group web bổ sung.
Chạy lệnh sau để chia tỷ lệ ứng dụng web thành 10 Pod.
- kubectl scale rs/web --replicas=10
Outputreplicaset "web" scaled
Kiểm tra số lượng Pod:
- kubectl get pods
Bạn sẽ thấy kết quả này:
OutputNAME READY STATUS RESTARTS AGE db 1/1 Running 0 22m web-4nh4g 1/1 Running 0 21s web-7vbb5 1/1 Running 0 21s web-8zd55 1/1 Running 0 21s web-f8hvq 0/1 ContainerCreating 0 21s web-ffrt6 1/1 Running 0 21s web-k6zv7 0/1 ContainerCreating 0 21s web-n5l5h 1/1 Running 0 3m web-qmdxn 1/1 Running 0 21s web-vc45m 1/1 Running 0 21s web-ws59m 1/1 Running 0 2m
Kubernetes đã bắt đầu quá trình mở rộng quy mô web
Pod. Khi yêu cầu đến với Dịch vụ thông qua NodePort, nó sẽ được chuyển đến một trong các Group trong Bộ bản sao.
Khi lưu lượng và tải giảm, ta có thể hoàn nguyên về cấu hình ban đầu của hai Pod.
kubectl scale rs/web --replicas=2
Outputreplicaset "web" scaled
Lệnh này kết thúc tất cả các Group ngoại trừ hai.
- kubectl get pods
OutputNAME READY STATUS RESTARTS AGE db 1/1 Running 0 24m web-4nh4g 1/1 Terminating 0 2m web-7vbb5 1/1 Terminating 0 2m web-8zd55 1/1 Terminating 0 2m web-f8hvq 1/1 Terminating 0 2m web-ffrt6 1/1 Terminating 0 2m web-k6zv7 1/1 Terminating 0 2m web-n5l5h 1/1 Running 0 5m web-qmdxn 1/1 Terminating 0 2m web-vc45m 1/1 Terminating 0 2m web-ws59m 1/1 Running 0 4m
Để xác minh tính khả dụng của Bộ bản sao, hãy thử xóa một trong các Group và kiểm tra số lượng.
- kubectl delete pod web-ws59m
Outputpod "web-ws59m" deleted
- kubectl get pods
OutputNAME READY STATUS RESTARTS AGE db 1/1 Running 0 25m web-n5l5h 1/1 Running 0 7m web-ws59m 1/1 Terminating 0 5m web-z6r2g 0/1 ContainerCreating 0 5s
Ngay sau khi số lượng Pod thay đổi, Kubernetes sẽ điều chỉnh nó để trùng với số lượng được xác định trong file YAML. Khi một trong các Group web trong Tập hợp bản sao bị xóa, một Group khác sẽ ngay lập tức được tạo để duy trì số lượng mong muốn. Điều này đảm bảo tính khả dụng cao của ứng dụng bằng cách đảm bảo số lượng Pod tối thiểu luôn chạy.
Bạn có thể xóa tất cả các đối tượng được tạo trong hướng dẫn này bằng lệnh sau:
- kubectl delete -f db-pod.yaml -f db-service.yaml -f web-rs.yaml -f web-service.yaml
Outputpod "db" deleted service "db" deleted replicaset "web" deleted service "web" deleted
Kết luận
Trong hướng dẫn này, bạn đã áp dụng tất cả các khái niệm được đề cập trong loạt bài để đóng gói, triển khai và mở rộng quy mô các ứng dụng microservices.
Trong phần tiếp theo của loạt bài này, bạn sẽ học cách làm cho MongoDB trở nên khả dụng cao bằng cách chạy nó dưới dạng StatefulSet.
Các tin liên quan