+4

[CI-CD] Triển khai Ứng dụng lên Kubernetes Engine của Google Cloud Platform

Tiếp nối bài viết lần trước mình đã deploy ứng dụng lên cloud run của GCP rồi thì hôm nay mình sẽ tiếp tục deploy thử ứng dụng lên Kubernetes Engine nhé 😆

Và đôi lời một chút với Kubernetes, nó là một nền tảng mạnh mẽ để quản lý và triển khai ứng dụng mà hầu hết các ứng dụng lớn hiện nay đều sử dụng, hãy cùng mình khám phá nhé!

Repository: https://github.com/dongtranthien/Kubernetes-Engine-CI-CD-Template

Bước 1: Tạo project nodejs cơ bản

Khởi tạo thư mục dự án

mkdir Kubernetes-Engine-CI-CD-Template
cd Kubernetes-Engine-CI-CD-Template
npm init -y

Tạo file index.js với mã nguồn tạo một server web cơ bản, đoạn mã nguồn tạo một server web đơn giản để trả về chuỗi "Hello, World!" khi truy cập địa chỉ cụ thể.

const http = require('http');

const hostname = '0.0.0.0';
const port = process.env.PORT || 8080;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello, World!\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

Bước 2: Tạo Dockerfile

File này dùng để build ra image để chạy trên container

FROM node:latest            // Sử dụng image Node.js làm base image

WORKDIR /usr/src/app        // Thiết lập thư mục làm việc trong container

COPY package*.json ./       // Copy tập tin package.json và package-lock.json vào thư mục làm việc

RUN npm install             // Cài đặt các dependencies của ứng dụng

COPY . .                    // Copy toàn bộ nội dung của thư mục hiện tại vào thư mục làm việc trong container

EXPOSE 8080                 // Khai báo cổng 8080 để ứng dụng có thể được truy cập từ bên ngoài

CMD ["node", "index.js"]    // Chạy ứng dụng Node.js khi container được khởi chạy

Bước 3: Tạo Github action để chạy các tiến trình CI CD

Trước khi bước vào job chính deploy lên gcp thì mình có thêm các job gửi tin nhắn đến group telegram để thông báo bắt đầu và kết thúc quá trình. Mình mô tả xíu về các step để deploy:

  • Checkout mã nguồn từ repository.
  • Thiết lập Google Cloud SDK.
  • Cấu hình Docker CLI để làm việc với Container Registry.
  • Xây dựng Docker image từ mã nguồn và đẩy image lên Container Registry.
  • Cài đặt kubectl để quản lý Kubernetes.
  • Lấy thông tin xác thực và cấu hình kubectl để truy cập Cluster.
  • Áp dụng các cấu hình triển khai từ file deployment.yaml lên Kubernetes.
name: Deploy to Kubernetes

on:
  push:
    branches:
      - main

jobs:
  send-notification-started:
    runs-on: ubuntu-latest
    steps:
      - name: Send Telegram Notification
        env:
          TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          TELEGRAM_CHAT_ID: "${{ secrets.TELEGRAM_GROUP_DEPLOYMENTS }}"
        run: |
          curl -X POST \
            https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage \
            -d chat_id=${TELEGRAM_CHAT_ID} \
            -d text="🚀 <b>Kubernetes Engine CI-CD Template</b> Deployment has started!
            Your deployment process is in progress. 🛠️🔍" \
            -d parse_mode=HTML

  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Google Cloud SDK
        run: |
          curl -o google-cloud-sdk.tar.gz https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-372.0.0-linux-x86_64.tar.gz
          tar -xf google-cloud-sdk.tar.gz
          ./google-cloud-sdk/install.sh --quiet
          echo "${{ secrets.GCLOUD_AUTH }}" > /tmp/gcloud.json
          ./google-cloud-sdk/bin/gcloud auth activate-service-account --key-file=/tmp/gcloud.json
          ./google-cloud-sdk/bin/gcloud config set project ${{ secrets.GCP_PROJECT_ID }}

      - name: Configure Docker CLI
        run: |
          ./google-cloud-sdk/bin/gcloud auth configure-docker

      - name: Build and push Docker image
        run: |
          docker build -t gcr.io/${{ secrets.GCP_PROJECT_ID }}/kubernetes-engine-ci-cd-template .
          docker push gcr.io/${{ secrets.GCP_PROJECT_ID }}/kubernetes-engine-ci-cd-template

      - name: Install kubectl plugin
        run: |
          ./google-cloud-sdk/bin/gcloud components install kubectl

      - name: Set kubectl context
        run: |
          ./google-cloud-sdk/bin/gcloud container clusters get-credentials ${{ secrets.GCP_CLUSTER_NAME }} --zone ${{ secrets.GCP_CLUSTER_ZONE }} --project ${{ secrets.GCP_PROJECT_ID }}

      - name: Configure kubectl
        run: |
          gcloud auth activate-service-account --key-file=/tmp/gcloud.json
          kubectl config set-credentials gke-cluster-user --token=$(gcloud auth print-access-token)
          kubectl config set-context gke-cluster --cluster=${{ secrets.GCP_CLUSTER_CONTEXT }} --user=gke-cluster-user
          kubectl config use-context gke-cluster

      - name: Deploy to Kubernetes
        run: |
          kubectl apply -f deployment.yaml
  send-notification-successful:
    needs: deploy
    runs-on: ubuntu-latest
    if: ${{ success() && needs.deploy.result == 'success' }}
    steps:
      - name: Send Telegram Notification
        env:
          TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          TELEGRAM_CHAT_ID: "${{ secrets.TELEGRAM_GROUP_DEPLOYMENTS }}"
        run: |
          curl -X POST \
            https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage \
            -d chat_id=${TELEGRAM_CHAT_ID} \
            -d text="🎉 <b>Kubernetes Engine CI-CD Template</b> Deployment was successful!
            Your amazing tool is now available for everyone! 🚀✨" \
            -d parse_mode=HTML

  send-notification-failed:
    needs: deploy
    runs-on: ubuntu-latest
    if: ${{ failure() && needs.deploy.result == 'failure' }}
    steps:
      - name: Send Telegram Notification
        env:
          TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          TELEGRAM_CHAT_ID: "${{ secrets.TELEGRAM_GROUP_DEPLOYMENTS }}"
        run: |
          curl -X POST \
            https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage \
            -d chat_id=${TELEGRAM_CHAT_ID} \
            -d text="❌ Oh no! <b>Kubernetes Engine CI-CD Template</b> Deployment failed!
            There might be something wrong with the process. 
            Please check it out! 🛠️🔍" \
            -d parse_mode=HTML

Bước 4: Tạo file deployment.yaml để tạo workload, pod auto scaler và service

  • Tạo workload: nhầm xác định số lượng replicas (bản sao) của ứng dụng chúng ta muốn triển khai, lưu ý phải từ 2 trở lên nha, nếu bạn chỉ dùng 1 thì khi deploy bản mới lên thì workload ko có pod để chạy bản mới của bạn đâu(khi chạy xong pod mới thì pod cũ sẽ tắt đi nhé)
  • Tạo HorizontalPodAutoscaler: phần này sẽ tự động mở rộng số lượng Pods dựa trên tài nguyên sử dụng (trong trường hợp này, CPU)
  • Tạo service: để tạo một dịch vụ để có thể truy cập vào ứng dụng từ bên ngoài
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-1
  namespace: default
  labels:
    app: nginx-1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-1
  template:
    metadata:
      labels:
        app: nginx-1
    spec:
      containers:
        - name: nginx-container
          image: gcr.io/cdtest-406103/kubernetes-engine-ci-cd-template:latest
          ports:
            - containerPort: 8080

---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-1-hpa-zylx
  namespace: default
  labels:
    app: nginx-1
spec:
  scaleTargetRef:
    kind: Deployment
    name: nginx-1
    apiVersion: apps/v1
  minReplicas: 1
  maxReplicas: 2
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 80

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: default
spec:
  selector:
    app: nginx-1
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer

Chúng ta đã hoàn thành quá trình triển khai ứng dụng lên Kubernetes Engine.

Việc sử dụng Kubernetes giúp quản lý và mở rộng ứng dụng của bạn trở nên linh hoạt và mạnh mẽ hơn. Bài viết này mong muốn giúp bạn hiểu rõ hơn về quá trình triển khai trên môi trường Kubernetes và ứng dụng nó vào công việc thực tế của bạn. Hãy tiếp tục khám phá và tận dụng sức mạnh của Kubernetes nhé, chúc các bạn thành công!

Có thắc mắc gì các bạn cứ comment bên dưới nha 😁


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí