使用ChatGPT,阿里云,K8S,GitHub Action搭建小型网站

效果展示:https://www.windrunner0707.tech/

技术栈说明

ChatGPT

辅助生成样例代码与K8S配置文件

阿里云

提供ECS实例和容器镜像仓库
ECS:活动价99元购入,配置为2vCPU,2G内存,3Mbps带宽

容器镜像仓库:阿里云ACR,个人版免费,用于保存前后端代码打包的镜像,在阿里云使用Docker Hub可能会发生超时问题。

K3S

由于Kubernetes占用资源较多,所以无法在我的阿里云ECS部署,这里采用K3S。官网对它的描述是”Lightweight Kubernetes“即轻量化Kubernetes,是为物联网和边缘计算打造的经认证的Kubernetes发行版。

GitHub Action

GitHub Actions 是 GitHub 提供的持续集成和持续部署(CI/CD)服务,它允许你在代码仓库中定义自动化流程,从而在特定事件发生时自动执行一系列任务,比如:

  • push 或 PR 时自动运行测试
  • 构建和发布 Docker 镜像
  • 部署代码到服务器或 Kubernetes 集群
  • 静态分析、格式检查、打包发布等

准备阶段

阿里云ECS安装K3S

由于网络原因,阿里云服务器访问GitHub服务会超时,所以参考官方文档会发生超时的错误。然后我使用了以下方法安装K3S

wget https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh
INSTALL_K3S_MIRROR=cn INSTALL_K3S_EXEC="--system-default-registry registry.cn-hangzhou.aliyuncs.com --tls-san 8.130.108.60" ./k3s-install.sh

首先,安装 K3s 使用的是存储在阿里云对象存储上的 K3s 安装脚本,并且使用存储在国内 channel 去解析对应的 K3s 版本。
其次,通过 INSTALL_K3S_MIRROR=cn 环境变量来指定 K3s 的二进制文件从国内的阿里云对象存储上去拉取。
最后,通过--system-default-registry参数来指定 K3s 的系统镜像从国内的阿里云镜像仓库去拉取。

准备代码仓库

这里我准备了后端常用的Spring Boot代码仓库和React + Vite代码仓库,具体代码仓库如下:
前端:https://github.com/windrunner0707/transaction-system-frontend
后端:https://github.com/windrunner0707/transaction-system
工程的搭建主要依赖于ChatGPT,并且保证本地能打包成功

部署阶段

配置Dockerfile

Dockerfile主要用来打包前后端镜像,并push到阿里云ACR镜像仓库。
前端Dockerfile如下:

## 构建阶段
FROM node:20-alpine AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build

# 运行阶段
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

后端Dockerfile如下:

# Start with a base image containing Java runtime
FROM openjdk:21-jdk-slim

# Set the working directory
WORKDIR /app

# Copy the built jar file into the container
COPY target/transaction-system-0.0.1-SNAPSHOT.jar /app/transaction-system.jar

# Expose the port the application runs on
EXPOSE 8080

# Set the command to run the application
CMD ["java", "-jar", "transaction-system.jar"]

配置GitHub Action

GitHub Action功能主要在代码仓库中创建这样一个yaml配置文件来使用

其yaml配置文件内容如下:

name: Build and Deploy to K3s

on:
  push:
    branches:
      - main

env:
  IMAGE_NAME: transaction-system
  ACR_REGISTRY: crpi-kw9b5zmptdsw1y03.cn-wulanchabu.personal.cr.aliyuncs.com
  ACR_NAMESPACE: windrunner0707

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up JDK
        uses: actions/setup-java@v3
        with:
          java-version: '21'
          distribution: 'temurin'

      - name: Build with Maven
        run: mvn clean package -DskipTests

      - name: Log in to ACR
        run: echo "${{ secrets.ACR_PASSWORD }}" | docker login ${{ env.ACR_REGISTRY }} -u "${{ secrets.ACR_USERNAME }}" --password-stdin

      - name: Build Docker Image
        run: |
          docker build -t $ACR_REGISTRY/$ACR_NAMESPACE/$IMAGE_NAME:latest .

      - name: Push Docker Image to ACR
        run: |
          docker push $ACR_REGISTRY/$ACR_NAMESPACE/$IMAGE_NAME:latest

      - name: Upload deployment.yaml to server
        uses: appleboy/scp-action@v0.1.4
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SERVER_SSH_KEY }}
          source: deployment.yaml
          target: /home/${{ secrets.SERVER_USER }}/deploy

      - name: Deploy to K3s via SSH
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SERVER_SSH_KEY }}
          script: |
            export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
            kubectl delete deployment transaction-system --ignore-not-found
            kubectl apply -f /home/${{ secrets.SERVER_USER }}/deploy/deployment.yaml

主要步骤为:设置环境 -> Maven打包 -> 登陆阿里云ACR -> 打包Docker镜像 -> push Docker镜像 -> 上传K8S配置文件至阿里云ECS -> 登陆ECS服务器使用kubectl完成部署。
将配置文件push至GitHub仓库后,可以在Actions下看到该pipeline的所有流程,如图所示:

检查服务部署情况

登陆至ECS服务器,使用kubectl get pods命令可以查看前后端部署的Pods情况

域名解析

在阿里云购买域名后,使用云解析DNS,将域名解析到我们的ECS服务器,并填写个人资料,完成备案流程

配置HTTPS

在阿里云数字证书管理服务购买个人测试用的免费证书,一般有效期为3个月

然后下载公钥与私钥,上传到ECS服务器

将密钥加入K8S的Secret

kubectl create secret tls windrunner-tls   --cert=www.windrunner0707.tech.pem   --key=www.windrunner0707.tech.key   --namespace=default


配置Ingress并开启HTTPS

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: frontend-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  tls:
    - hosts:
        - www.windrunner0707.tech
      secretName: windrunner-tls
  rules:
    - host: www.windrunner0707.tech
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: transaction-system-frontend
                port:
                  number: 80

后续开发(TODO)

至此已完成了一个Demo的部署,后续还有前后端的连通,开发更多feature