Springboot 專案通過 gitlab CI/CD 整合 k8s 自動部署

你個大豬蹄子發表於2021-01-04

本章節主要講的是 springboot 專案發到 gitlab 倉庫,觸發 gitlab ci/cd 實現專案自動整合和部署,其中部署是以 k8s 方式部署

關於 gitlab-runner 安裝和註冊可以參考我的另一篇部落格 Docker安裝gitlab-runner 實現自動 CI/CD (持續整合/持續部署) 配置

關於 k8s 叢集搭建可以參考我的另一篇部落格 k8s 叢集之使用 kubeadm 在 Centos8 上部署 kubernetes 1.20

先建立 springboot 專案 push 到 gitlab 遠端倉庫,這裡專案名稱是 springboot-ci-cd-demo
新建一個 Controller 用於測試,如下

@RestController
@RequestMapping("/demo")
public class DemoController {

    private static final Logger LOGGER = LoggerFactory.getLogger(DemoController.class);

    @GetMapping
    public String demo() throws UnknownHostException {
        String hostAddress = InetAddress.getLocalHost().getHostAddress();
        LOGGER.info("{} : Hello, 2021 Happy New Year", hostAddress);
        return hostAddress + " : Hello, 2021 Happy New Year";
    }
}

gitlab-runner 安裝好之後,註冊 gitlab-runner 可使用如下命令,url 和 registration-token 在 gitlab 頁面獲取(註冊如有不理解可以參考我的另一篇部落格 Docker安裝gitlab-runner 實現自動 CI/CD (持續整合/持續部署) 配置

docker run -it --rm -v /srv/gitlab-runner/config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner register \
  --non-interactive \
  --executor "docker" \
  --docker-privileged \
  --docker-image docker:latest \
  --url "https://gitlab.com/" \
  --registration-token "2xAmgi-WmzWh9evSH*****" \
  --description "ci-runner" \
  --tag-list "" \
  --run-untagged="true" \
  --locked="false" \
  --access-level="not_protected";

部分變數需要在 gitlab 上配置,如下圖
在這裡插入圖片描述

REG_USERNAME 和 REG_PASSWORD 是映象倉庫的使用者名稱和密碼
K8S_ADMIN_CONF :value 的值取之 k8s 叢集環境 master 節點的 admin.conf 配置檔案,拷貝檔案裡邊的內容放到 value 裡
K8S_DEMO_YAML:value 的值如下(值裡邊的變數需要在當前頁面定義或者在,gitlab-ci.yml檔案裡邊定義)

---
apiVersion: v1
kind: Service
metadata:
  name: $DEPLOYMENT_NAME
  namespace: demo
  labels:
    app: ci-cd-demo
spec:
  type: NodePort
  ports:
  - name: ci-cd-demo
    port: 8080
    protocol: TCP
    nodePort: 30080 
  selector:
    app: ci-cd-demo

---
apiVersion: apps/v1
kind: Deployment #物件型別
metadata:
  name: $DEPLOYMENT_NAME #名稱
  labels:
    app: ci-cd-demo #標註
spec:
  replicas: 1 #執行容器的副本數,修改這裡可以快速修改分散式節點數量
  selector:
    matchLabels:
      app: ci-cd-demo
  template:
    metadata:
      labels:
        app: ci-cd-demo
    spec:
      containers: #docker容器的配置
      - name: $DEPLOYMENT_NAME
        image: $PROJECT_IMAGE
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
        env: 
        - name: JAVA_OPTS
          value: -Xms256m -Xmx256m
      imagePullSecrets:
      - name: regsecret
   

編寫 Dockerfile 檔案,放在專案根目錄

FROM openjdk:8-jdk
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]

編寫 .gitlab-ci.yml 檔案,放在專案根目錄

# 因為我們Runner執行器設定為docker, 所以這裡需要指定docker的版本
image: docker:stable

variables:
  MAVEM_IMAGE: registry.cn-hangzhou.aliyuncs.com/sanchar/maven:1.0  # maven 打包使用的映象
  K8S_IMAGE: registry.cn-hangzhou.aliyuncs.com/sanchar/kubectl:v1.20.1  # k8s 部署使用的映象
  PROJECT_IMAGE_SERVER: registry.cn-hangzhou.aliyuncs.com  # 阿里雲映象地址
  PROJECT_IMAGE: registry.cn-hangzhou.aliyuncs.com/sanchar/springboot-ci-cd-demo:1.0  # 專案映象連結
  MAVEN_OPTS: -Dmaven.repo.local=/.m2  # 指定 maven 本地倉庫路徑,以便做快取
  PACKAGE_CACHE_REF_NAME: springboot-ci-cd-demo-cache
  DEPLOYMENT_NAME: springboot-ci-cd-demo  # 專案在 k8s 中部署的名稱
  K8S_NS: demo  # k8s 名稱空間

stages:
  - package
  - build
  - deploy

# 打包
package:
  stage: package
  # 打包用到了maven, 所有需要拉取maven映象, 這是我自己構建的阿里雲maven私服的maven映象
  image: $MAVEM_IMAGE
  script:
    - echo "=============== mvn package  ==============="
    - mvn $MAVEN_OPTS clean package -Dmaven.test.skip=true
  # 只作用在master分支
  only:
    - master
  # 使用快取速度更快,如果希望在gitlab-ci頁面上可以下載jar包,可以使用下邊的 artifacts 方式
  cache:
    key: $PACKAGE_CACHE_REF_NAME
    paths:
      - target/*.jar
  # 這裡可以將maven 打包好的檔案傳遞給下一個 stage ,然後下一步的docker 就可以根據 這個 jar 包 和Dockerfile 構建映象
#    artifacts:
#      # 指定下過期時間和路徑
#      # expire_in: 1 days
#      paths:
#        - target/*.jar

# 構建docker映象並推送到映象倉庫
build:
  stage: build
  cache:
    key: $PACKAGE_CACHE_REF_NAME
    policy: pull
    paths:
      - target/*.jar
  script:
    - echo "=============== docker build image  ==============="
    - docker build -t $PROJECT_IMAGE .
    - docker login --username $USERNAME --password $PASSWORD $PROJECT_IMAGE_SERVER
    - docker push $PROJECT_IMAGE
  only:
    - master

# 使用 k8s 部署
deploy:
  stage: deploy
  image: $K8S_IMAGE
  # 構建 k8s 可執行環境
  before_script:
    - mkdir -p /etc/kubernetes
    - mv $K8S_ADMIN_CONF /etc/kubernetes/admin.conf
    - echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
    - source ~/.bash_profile
  script:
    - echo "=============== deploy  ==============="
    - if [ "$(kubectl get deployment -n $K8S_NS | grep $DEPLOYMENT_NAME | awk '{print $1}')" ]; then
    - kubectl set image deploy $DEPLOYMENT_NAME $DEPLOYMENT_NAME=$PROJECT_IMAGE -n $K8S_NS
    - kubectl scale deployment $DEPLOYMENT_NAME --replicas=0 -n $K8S_NS
    - kubectl scale deployment $DEPLOYMENT_NAME --replicas=1 -n $K8S_NS
    - else
    - mv $K8S_DEMO_YAML $DEPLOYMENT_NAME.yaml
    - kubectl apply -f $DEPLOYMENT_NAME.yaml -n $K8S_NS
    - fi
  only:
    - master
 

映象是私有的,在釋出程式碼跑 CI/CD 之前,k8s 需要配置 imagePullSecrets,在叢集環境 master 節點下執行如下命令生成 regsecret

[root@master ~]# kubectl create secret docker-registry regsecret --docker-server=registry.cn-hangzhou.aliyuncs.com --docker-username=使用者名稱 --docker-password=密碼 -n 名稱空間

配置裡映象倉庫的 secret 之後,本地修改的程式碼推送到遠端倉庫,gitlab 會自動跑
CI/CD,如下圖
在這裡插入圖片描述

CI/CD 跑成功之後,可在 k8s 叢集中檢視釋出的 pod 狀態

[root@master ~]# kubectl get pod -n demo 
NAME                                     READY   STATUS    RESTARTS   AGE
springboot-ci-cd-demo-5694574854-8xxh9   1/1     Running   0          29m

頁面訪問介面 http://192.168.1.25:30080/demo

在這裡插入圖片描述

如上顯示說明專案已經部署成功

相關文章