- vừa được xem lúc

[K8S] Phần 15 - Triển khai ứng dụng NodeJS lên K8S

0 0 29

Người đăng: Trịnh Quốc Việt

Theo Viblo Asia

Giới thiệu

Trong các phần trước mình đã giới thiệu về cách dựng một hệ thống Kubernetes Cluster với khá đầy đủ các thành phần cần thiết như:

Sau khi đã hoàn thiện các thành phần thiết yếu trên, trong bài hôm nay mình sẽ trình bày về cách thức triển khai một ứng dụng đơn giản lên k8s sử dụng nodejs. Đây sẽ là tiền đề để phát triển tiếp tới các chủ đề liên quan tới CICD, automation mà mình sẽ đề cập ở các phần tiếp theo

Các bước cài đặt trong bài lab này có thể tóm tắt lại như sau:

  • Cài đặt môi trường để triển khai app nodejs
  • Code một module nodejs bé xinh và trả về web html
  • Build và tạo Docker Image cho ứng dụng
  • Triển khai ứng dụng lên K8S dùng các file manifest yaml

Kết quả là ta có thể cài đặt được ứng dụng và truy cập vào ứng dụng bằng IP hoặc domain name.

Giờ bắt tay vào làm thôi!!

Cài đặt môi trường để build NodeJs App (centos7):

Như các bài hướng dẫn trước đã đề cập, mình có một máy chủ cicd để lưu các file cấu hình cài đặt. Mình sẽ cài môi trường lên máy chủ này để build ứng dụng ở đây và triển khai lên k8s.

Đầu tiên máy chủ này phải cài Docker, nodejs và npm. Những hướng dẫn này khá phổ biến trên mạng rồi, nó cũng chỉ loanh quanh vài lệnh thôi, đây là cài cho centos7 nhé:

sudo yum clean all && sudo yum makecache fast
sudo yum install -y gcc-c++ make
sudo yum install -y nodejs
sudo yum install -y npm

Tạo thư mục cài đặt và pull code về

Các bạn tạo một thư mục và pull code về ở repo này nhé: https://github.com/rockman88v/nodejs-demo-k8s

Kết quả sẽ được thư mục như thế này:

[_@.com nodejs-demo-k8s]$ ls -lrt
total 52
-rw-rw-r-- 1 sysadmin sysadmin 116 Aug 12 05:35 Dockerfile
-rw-rw-r-- 1 sysadmin sysadmin 560 Aug 12 05:52 package.json
-rw-rw-r-- 1 sysadmin sysadmin 32524 Aug 12 22:26 package-lock.json
drwxrwxr-x 51 sysadmin sysadmin 4096 Aug 12 22:26 node_modules
-rw-rw-r-- 1 sysadmin sysadmin 1501 Aug 12 23:40 README.md
-rw-rw-r-- 1 sysadmin sysadmin 1652 Aug 12 23:41 app.js
drwxrwxr-x 2 sysadmin sysadmin 69 Aug 12 23:43 kubernetes
drwxrwxr-x 2 sysadmin sysadmin 58 Aug 12 23:43 documents

Các file html ở đây là mình tìm sẵn template trên mạng và customize đi một chút. Code nodejs cũng là lấy ví dụ trên mạng và sửa lại để demo cho việc sử dụng các biến môi trường từ k8s vào ứng dụng nodejs.

Cơ bản app nó làm nhiệm vụ sau:

  • Gọi vào "/" trả về file index.html, trong đó có cập nhật giá trị các biến môi trường liên quan tới triển khai (POD_NAME, POD_IP..)
  • Gọi vào "/about" hay "/about-us" trả về about.html
  • Các request khác thì trả về 404.html

Ở đây đã có sẵn node_modules rồi, hoặc các bạn có thể cài lại bằng lệnh:

npm install

Build docker và push vào registry

Ở đây mình có local registry là harbor.prod.viettq.com, các bạn thay đổi thông tin registry theo hệ thống của các bạn nhé!

Trong phần trước mình đã có hướng dẫn cách xây dựng và sử dụng local registry rồi, các bạn có thể xem lại ở đây

Thực hiện build docker:

[_@.com nodejs-demo-k8s]$ docker build -t harbor.prod.viettq.com/demo/my-app:v5 .
Sending build context to Docker daemon 3.082MB
Step 1/7 : FROM node:10 ---> 28dca6642db8
Step 2/7 : WORKDIR /usr/src/app ---> Using cache ---> 8bafdc7f0d3d
Step 3/7 : COPY package*.json ./ ---> f8e58ab5b350
Step 4/7 : RUN npm install ---> Running in 01a81426aca7
npm WARN read-shrinkwrap This version of npm is compatible with _@.com, but package-lock.json was generated for _@.com I'll try to do my best with it!
added 57 packages from 42 contributors and audited 57 packages in 2.434s 7 packages are looking for funding run `npm fund` for details found 0 vulnerabilities Removing intermediate container 01a81426aca7 ---> 18e36a7661fe
Step 5/7 : COPY . . ---> e6421f170c83
Step 6/7 : EXPOSE 8080 ---> Running in b764f46a66ca
Removing intermediate container b764f46a66ca ---> de280724aa81
Step 7/7 : CMD ["node", "app.js"] ---> Running in a67764ebddf2
Removing intermediate container a67764ebddf2 ---> 87dc4eaddb18
Successfully built 87dc4eaddb18
Successfully tagged harbor.prod.viettq.com/demo/my-app:v5

Sau đó push lên registry:

[_@.com nodejs-demo-k8s]$ docker push harbor.prod.viettq.com/demo/my-app:v5
The push refers to repository [harbor.prod.viettq.com/demo/my-app]
b960f07798ee: Pushed
617f020fecea: Pushed
97140b150373: Pushed
fc0ca60dc722: Layer already exists
3ab01e8988bf: Layer already exists
c98dc9a94132: Layer already exists
3ffdb7e28503: Layer already exists
33dd93485756: Layer already exists
607d71c12b77: Layer already exists
052174538f53: Layer already exists
8abfe7e7c816: Layer already exists
c8b886062a47: Layer already exists
16fc2e3ca032: Layer already exists
v5: digest: sha256:bbd3843ecc11992948d0289a1876ea2c316772962b6f6ce988238c26ccdd2528 size: 3052

Triển khai lên k8s

Để triển khai lên k8s thì mình có dùng 3 resource chính là deployment, service và ingress.

  • Trong cấu hình deployment có gán các biến môi trường lấy từ thông tin metadata của Pod khi deploy lên k8s
  • Service cài đặt nodeport 31123 để kết nối trực tiếp qua IP của Node
  • Ingress cài đặt ở địa chỉ host là demo-node.prod.viettq.com

Trong cấu hình của deployment bạn cần đổi thông tin image theo bước bạn build docker bên trên:

Các bạn cũng có thể set số lượng replicas (là số pod sẽ chạy ứng dụng này) ở tham số replicas.

 spec: containers: - name: node-app image: harbor.prod.viettq.com/demo/my-app:v1 imagePullPolicy: Always

Trong cấu hình service bạn có thể đổi cấu hình nodeport theo ý muốn, hiện tại mình đang để là nodePort: 31123:

apiVersion: v1
kind: Service
metadata: name: node-app-service
spec: selector: app: node-app-viettq type: LoadBalancer ports: - protocol: TCP port: 5000 targetPort: 8080 nodePort: 31123

Trong cấu hình ingress bạn đổi host theo cấu hình domain của bạn:

host: demo-node.prod.viettq.com --> Tên host bạn mong muốn

ingressClassName: local --> Thường thì mặc định class là nginx, tuy nhiên nếu bạn muốn chỉ định class cụ thể thì cấu hình ở đây.

apiVersion: networking.k8s.io/v1
# Specifying the kind as Ingress
# because we want's to manage the external user to our service
kind: Ingress
metadata:
# Naming our Ingress
name: node-app-ingress
labels: name: node-app-ingress
spec: ingressClassName: local
rules: # Defining rules such as # Providing the cluster name, DNS_NAME (where we want this image to be visible) - host: demo-node.prod.viettq.com http: paths: - pathType: Prefix path: "/" backend: service: # Specifying the name of the service that the pods are using name: node-app-service port: # Specifying the PORT to map with the service number: 5000

Xong rồi thì deploy các manifest file này lên k8s, mình sẽ cài trên namespace demo:

kubectl create ns demo
kubectl -n demo apply -f kubernetes/deployment.yaml
kubectl -n demo apply -f kubernetes/service.yaml
kubectl -n demo apply -f kubernetes/ingress.yaml

Kết quả khi cài đặt xong ta sẽ có 1 deployment với 3 pod, 1 service và 1 ingress:

[_@.com kubernetes]$ kubectl -n demo get all
NAME READY STATUS RESTARTS AGE
pod/node-app-deployment-75c7c88b58-66m69 1/1 Running 0 3h15m
pod/node-app-deployment-75c7c88b58-7mqsb 1/1 Running 0 3h15m
pod/node-app-deployment-75c7c88b58-n7qbn 1/1 Running 0 3h18m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/node-app-service LoadBalancer 10.233.53.78 <pending> 5000:31123/TCP 20h NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/node-app-deployment 3/3 3 3 20h NAME DESIRED CURRENT READY AGE
replicaset.apps/node-app-deployment-75c7c88b58 3 3 3 4h19m
[_@.com kubernetes]$ kubectl -n demo get ingress -owide
NAME CLASS HOSTS ADDRESS PORTS AGE
demo-node.prod.viettq.com local demo-node.prod.viettq.com 192.168.10.81 80 83m

Như vậy là mọi thứ đã hoàn thành, cùng kiểm tra kết quả xem sao.

Kết nối vào bằng IP:Port (IP của node bất kỳ trong k8s cluster): 192.168.10.81:31123

Kết nối vào host như đã cấu hình trong ingress: https://demo-node.prod.viettq.com/

Hola! Chạy dc rồi, nó cũng đã hiển thị được các thông tin như namespace, node, pod name, podIP ra luôn. Vì mình đang cấu hình 3 replicas tương ứng 3 pod nên khi bạn f5 lại web thì có thể pod khác sẽ đang xử lý và thông tin hiển thị trên web sẽ thay đổi theo, các bạn để ý tham số PodName và PodIP nhé.

Mình thử f5 thì ra kết quả:

Kết luận

Như vậy là mình đã triển khai xong một ứng dụng lên k8s. Nhưng trong quá trình thực hiện bài lab này thì việc update code và deploy lên để test rất mất công. Cụ thể mình làm như sau:

  • Sửa code trên máy cá nhân --> Commit lên gihub
  • Kết nối vào máy chủ cicd pull code update về
  • Build docker & push registry
  • Re-apply các file manifest

Vậy bài toán đặt ra là làm sao để cái luồng kia nó bớt thủ công hơn, cho tay bớt to? Thì đó là câu chuyện của mọi người hay nhắc tới, đó là CICD và mình trình bày trong phần sau.

Trong phần tiếp theo mục tiêu mình sẽ thực hiện:

  • Dựng helm chart cho ứng dụng --> Khi apply lên k8s sẽ thực hiện qua helm thay vì dùng kubectl để apply các file manifest
  • Cài đặt gitlab để dùng local cho giống thực tế hơn (chắc không ai để code cty lên github đâu 😄 )
  • Cài đặt jenkins để thực hiện luồng CICD
  • Update code vào thực hiện one-click trên giao diện Jenkins để chờ kết quả

Cảm ơn mọi người đã đọc tới đây. Trong bài viết có thể có những thiếu xót mong được mọi người góp ý để hoàn thiện thêm. Nếu thấy series này hữu ích thì các bạn cho mình xin 1 nút upvote để tạo động lực viết tiếp các bài tiếp theo nhé!

Thank mọi người.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Deploying A Containerized Web Application On Kubernetes

1. Overview. Kubernetes is an open source project (available on kubernetes.io) which can run on many different environments, from laptops to high-availability multi-node clusters; from public clouds to on-premise deployments; from virtual machines to bare metal.

0 0 26

- vừa được xem lúc

Kubernetes - Học cách sử dụng Kubernetes Namespace cơ bản

Namespace trong Kubernetes là gì. Tại sao nên sử dụng namespace.

0 0 96

- vừa được xem lúc

[Kubernetes] Kubectl và các command cơ bản

Mở đầu. Kubectl là công cụ quản trị Kubernetes thông qua giao diện dòng lệnh, cho phép bạn thực thi các câu lệnh trong Kubernetes cluster.

0 0 39

- vừa được xem lúc

Triển khai EFK Stack trên Kubernetes

EFK stack on K8S. Giới thiệu. Một hệ thống có thể chạy nhiều dịch vụ hoặc ứng dụng khác nhau, vì vậy việc. theo dõi hệ thống là vô cùng cần thiết.

0 0 54

- vừa được xem lúc

Thực hành Kubernetes (K8S) bằng cách sử dụng lệnh Command

Bài hướng dẫn hôm nay sẽ hướng dẫn sử dụng K8S bằng cách sử dụng câu lệnh thay vì UI trên web. Có 2 lựa chọn để thực hiện:. . Sử dụng Cloud Shell.

0 0 42

- vừa được xem lúc

Kubernetes best practices - Liveness và Readiness Health checks

Mở đầu. Kubernetes cung cấp cho bạn một framework để chạy các hệ phân tán một cách mạnh mẽ.

0 0 35