Thứ tư, 07/03/2018 | 00:00 GMT+7

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 :

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.

Output
Sending 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.

Output
REPOSITORY                                       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ể.

db-pod.yaml
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:

Output
pod "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:

Output
NAME      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:

db-service.yaml
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:

Output
service "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:

Output
NAME         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.

web-pod.yaml
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
Output
pod "web" created

Hãy xác minh việc tạo Pod:

  • kubectl get pods
Output
NAME      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:

Output
service "web" created

Hãy lấy cổng mà Pod có sẵn.

  • kubectl get services
Output
NAME         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.

 Control panel  DigitalOcean hiển thị  các node  công nhân

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
Output
pod "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
Output
replicaset "web" created

Sau đó, kiểm tra số lượng Group :

  • kubectl get pods
Output
NAME        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
Output
pod "web-wh6nf" deleted

Nhìn lại Pod:

  • kubectl get pods
Output
NAME        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
Output
replicaset "web" scaled

Kiểm tra số lượng Pod:

  • kubectl get pods

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

Output
NAME        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 
Output
replicaset "web" scaled

Lệnh này kết thúc tất cả các Group ngoại trừ hai.

  • kubectl get pods
Output
NAME        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
Output
pod "web-ws59m" deleted
  • kubectl get pods
Output
NAME        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
Output
pod "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.


Tags:

Các tin liên quan