• 2024广东省职业技能大赛云计算赛项实战——构建CICD


    构建CI/CD

    前言

    题目如下:

    构建CI/CD
    编写流水线脚本.gitlab-ci.yml触发自动构建,具体要求如下:
    (1)基于镜像maven:3.6-jdk-8构建项目的drone分支;
    (2)构建镜像的名称:demo:latest;
    (3)将镜像推送到Harbor仓库demo项目中;
    (4)将demo-2048应用自动发布到Kubernetes集群gitlab-ci命名空间下。

    .gitlab-ci.yml 是 GitLab 中用来定义 CI/CD 流水线的配置文件,可以自动化执行定义的任务,并且在不同的环境中运行。通过.gitlab-ci.yml ,我们可以将项目的 CI/CD 流程集成到GitLab中,并利用其自动化功能来提高开发效率、减少部署错误。

    使用的环境是之前搭建的容器云平台:2024广东省职业技能大赛云计算赛项实战——容器云平台搭建-CSDN博客,只有master节点,使用的IP是192.168.200.15/24
    并且根据之前文章的操作部署了GitLab、GitLab Runner,和将K8S连接到GitLab中:2024广东省职业技能大赛云计算赛项实战——集群部署GitLab-CSDN博客2024广东省职业技能大赛云计算赛项实战——集群部署GitLab Runner-CSDN博客2024广东省职业技能大赛云计算赛项实战——集群部署GitLab Agent-CSDN博客

    操作过程

    我们先在浏览器输入宿主机IP访问Harbor,使用用户名/密码:admin/Harbor12345进行登录

    在这里插入图片描述

    在项目主页点击"新建项目",根据题目要求设置项目名为demo。将项目设为公开,然后确定,创建项目

    在这里插入图片描述

    提供的项目包里其实是有一个.gitlab-ci.yml文件的,但是并不完全,需要我们修改一下

    我们来到GitLab的Web界面,点击demo-2048项目左侧导航栏的"Code"→"Repository",切换到drone分支,可以在上方看到一个.gitlab-ci.yml文件,我们点击名称进去查看

    在这里插入图片描述

    将其内容复制

    在这里插入图片描述

    点击左侧导航栏的“Build”→“Pipeline editor”,切换到drone分支,点击"Configure pipeline"配置CI/CD管道

    在这里插入图片描述

    将我们复制的内容粘贴进去并修改

    #修改前:
    stages:
      - build
      - release
      - review
    
    variables:
      MAVEN_OPTS: "-Dmaven.repo.local=/opt/cache/.m2/repository"
    
    
    maven_build:
      image: maven:3.6-jdk-8
      stage: build
      only:
        - drone
      script:
        - cp -r /opt/repository /opt/cache/.m2/
        - mvn clean install -DskipTests=true
        - cd target && jar -xf 2048.war
        - cp -rfv 2048 /home/gitlab-runner/ci-build-cache
    
    image_build:
      image: docker:18.09.7
      stage: release
      variables:
        DOCKER_DRIVER: overlay2
        DOCKER_HOST: tcp://localhost:2375
        #启用调试模式,在执行作业时会输出额外的调试信息,包括所有执行的命令、环境变量设置和脚本的输出等等。
        #对于排查CI/CD作业中的问题非常有用,这个文件的编写者没有把它删掉,而是注释了
        #是不是在侧面告诉了我们,这个文件并不完全呢~
        #CI_DEBUG_TRACE: "true"
      services:
        - name: docker:18.09.7-dind
          entrypoint: ["dockerd-entrypoint.sh"]
          command: ["--insecure-registry", "10.24.2.14"]
      script:
        - docker login -u "${REGISTRY_USER}" -p "${REGISTRY_PASSWORD}" "${REGISTRY}"
        - cp -rfv /home/gitlab-runner/ci-build-cache/2048 .
        - sed -i "s/10.24.2.3/$REGISTRY/g" ./Dockerfiles/Dockerfile
        - docker build -t "${REGISTRY_IMAGE}:latest" -f ./Dockerfiles/Dockerfile .
        - docker tag "${REGISTRY_IMAGE}:latest" "${REGISTRY}/${REGISTRY_PROJECT}/${REGISTRY_IMAGE}:latest"
        - docker push "${REGISTRY}/${REGISTRY_PROJECT}/${REGISTRY_IMAGE}:latest"
     
    deploy_review:
      image: kubectl:1.22
      stage: review
      only:
        - drone
      script:
        - sed -i "s/REGISTRY/$REGISTRY/g" template/demo-2048.yaml
        - kubectl apply -f template/
    
    

    可以看到文件里多处使用了变量

    在这里插入图片描述

    我们需要设置这些变量的值。根据操作的内容不难判断出:
    由于进行了docker login命令登录Harbor注册表,所以:
    REGISTRY_USER 是我们Harbor的用户名
    REGISTRY_PASSWORD 是我们Harbor的密码
    REGISTRY 是我们Harbor的地址
    题目要求我们将构建的镜像命名为demo:latest,所以docker build操作里面的
    REGISTRY_IMAGE 的值要设置为demo
    题目还要求我们将镜像推送到Harbor仓库demo项目中,所以docker push操作里面的
    REGISTRY_PROJECT 的值也是demo

    #修改后:
    stages:
      - build
      - release
      - review
    
    variables:
      MAVEN_OPTS: "-Dmaven.repo.local=/opt/cache/.m2/repository"
      REGISTRY_USER: "admin"
      REGISTRY_PASSWORD: "Harbor12345"
      REGISTRY: "192.168.200.15"
      REGISTRY_IMAGE: "demo"
      REGISTRY_PROJECT: "demo"
    
    
    maven_build:
      ##
      image: maven:3.6-jdk-8
      stage: build
      only:
        - drone
      ##满足题目要求1,基于镜像maven构建项目的drone分支
      script:
        - cp -r /opt/repository /opt/cache/.m2/
        - mvn clean install -DskipTests=true
        - cd target && jar -xf 2048.war
        #这个目录需要我们自行创建
        - mkdir -p /home/gitlab-runner/ci-build-cache
        - cp -rfv 2048 /home/gitlab-runner/ci-build-cache
    
    image_build:
      image: docker:18.09.7
      stage: release
      #这里让我很疑惑,因为正常而言,在进行docker login操作时,默认是使用更安全的https进行连接,访问的是443端口,而我们的Harbor是启用的http,使用80端口。
      #如果不做任何准备直接连接的话肯定是无法连接上的,所以文件的编写者才写了下面一大段,在command: ["--insecure-registry", "${REGISTRY}"]的这个地方,
      #配置了docker的守护程序,让其允许连接到指定的不安全注册表地址,但是我当时在做这道题的时候却发现,无论我怎么改,docker login还是强制使用https,访问443端口,导致无法连接上。
      #我当时猜想,也许是语法错误的原因没有生效,于是用了各种设置方式,此路不通,然后我猜想,会不会是使用镜像的问题,毕竟它提供的docker镜像里还有20.10.12版本以及其dind版本的,挨个尝试还是不行。
      #我也尝试过在entrypoint:里使用"--tls=false",让Docker守护进程在启动时不使用TLS,不使用加密通信,结果还是以失败告终。然而,当我把这一段都删掉时,他居然莫名其妙的成功了,这让我百思不得其解...
      #variables:
      #  DOCKER_DRIVER: overlay2
      #  DOCKER_HOST: tcp://localhost:2375
        #CI_DEBUG_TRACE: "true"
      #services:
      #  - name: docker:18.09.7-dind
      #    entrypoint: ["dockerd-entrypoint.sh"]
      #    command: ["--insecure-registry", "${REGISTRY}"]
      script:
        - docker login -u "${REGISTRY_USER}" -p "${REGISTRY_PASSWORD}" "${REGISTRY}"
        - cp -rfv /home/gitlab-runner/ci-build-cache/2048 .
        - sed -i "s/10.24.2.3/$REGISTRY/g" ./Dockerfiles/Dockerfile
        #满足要求2,构建镜像名称为demo:latest
        - docker build -t "${REGISTRY_IMAGE}:latest" -f ./Dockerfiles/Dockerfile .
        - docker tag "${REGISTRY_IMAGE}:latest" "${REGISTRY}/${REGISTRY_PROJECT}/${REGISTRY_IMAGE}:latest"
        #满足要求3,将镜像推送到Harbor的demo项目中
        - docker push "${REGISTRY}/${REGISTRY_PROJECT}/${REGISTRY_IMAGE}:latest"
     
    deploy_review:
      image: kubectl:1.22
      stage: review
      only:
        - drone
      script:
        - sed -i "s/REGISTRY/$REGISTRY/g" template/demo-2048.yaml
        - kubectl apply -f template/
    

    至于要求4,将应用自动发布到集群的gitlab-ci命名空间下这个要求,它在构建2048的yaml文件中已经完成了

    [root@k8s-master-node1 gitlab-ci]# cat demo-2048/template/demo-2048.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: demo-2048
      namespace: gitlab-ci		#可以看到已经帮我们指定命名空间了
    ...  
    

    在执行脚本之前,我们还需要做一个操作,再次之前,我们先看一下构建2048的Dockerfile文件

    [root@k8s-master-node1 gitlab-ci]# cat demo-2048/Dockerfiles/Dockerfile   
    FROM 10.24.2.3/library/tomcat:8.5.64-jdk8
    RUN rm -rf /usr/local/tomcat/webapps/ROOT/
    ADD 2048 /usr/local/tomcat/webapps/ROOT/
    

    重点关注第一行,这里的ip地址在.gitlab.yml文件里我们已经通过sed命令改成Harbor仓库的地址了。可以看见,它基于的镜像是Harbor仓库的library项目里面的tomcat:8.5.64-jdk8这个镜像。但是我们的Harbor仓库还是空的呀,所以我们需要将这个镜像上传过去。

    我们来到Harbor仓库,点击library项目进来,点击推送命令就可以查看上传镜像的命令示例

    在这里插入图片描述

    我们根据示例修改一下就行了

    #首先先登录到Harbor注册表
    [root@k8s-master-node1 gitlab-ci]# docker login -u admin -p Harbor12345 192.168.200.15
    ...
    Login Succeeded
    #给镜像打个标签
    [root@k8s-master-node1 gitlab-ci]# docker tag tomcat:8.5.64-jdk8 192.168.200.15/library/tomcat:8.5.64-jdk8
    #推送镜像
    [root@k8s-master-node1 gitlab-ci]# docker push 192.168.200.15/library/tomcat:8.5.64-jdk8
    

    成功后我们在Harbor仓库的library里能看见多了镜像

    在这里插入图片描述

    OK,现在我们可以执行流水线脚本了,直接点击下面的"Commit changes"

    在这里插入图片描述

    点击左侧导航栏的"Build"→"Pipelines"等待执行结果就行

    在这里插入图片描述

    居然报错了?!
    在这里插入图片描述

    原来是我的服务账号gitlab-ci:default没有足够的权限来获取和操作deployments和services资源啊
    小问题,咱是在搞CI/CD,容错率大得很

    #在gitlab-ci创建一个role,设置其对deployments和services的权限
    [root@k8s-master-node1 gitlab-ci]# kubectl create role gitlab-role \
    --verb=get,watch,list,create,update,patch,delete --resource=deployments.apps \
    --verb=get,watch,list,create,update,patch,delete --resource=services -n gitlab-ci
    #进行角色绑定,绑定角色为上面创建的role,绑定的服务账户为gitlab-ci:default
    [root@k8s-master-node1 gitlab-ci]# kubectl create rolebinding gitlab-binding --role=gitlab-role --serviceaccount=gitlab-ci:default -n gitlab-ci
    

    重新运行,解决
    在这里插入图片描述

    来到Harbor,可以看到demo项目下面多了个镜像
    在这里插入图片描述

    #来到宿主机,查看一下pod状态
    [root@k8s-master-node1 gitlab-ci]# kubectl get pod -n gitlab-ci -owide
    NAME                                             READY   STATUS    RESTARTS       AGE     IP            NODE               NOMINATED NODE   READINESS GATES
    demo-2048-56f5dddb69-sbgpg                       1/1     Running   1 (73m ago)    4h57m   10.244.0.51   k8s-master-node1   <none>           <none>
    ...
    #查看一下服务状态
    [root@k8s-master-node1 gitlab-ci]# kubectl get svc -n gitlab-ci   
    NAME        TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
    demo-2048   NodePort   10.96.106.201   <none>        8080:8889/TCP   4m59s
    gitlab      NodePort   10.96.55.63     <none>        80:30880/TCP    104m
    #可以看到外部暴露的端口是8889
    

    后语

    至此,这道题的要求都满足了,此题完成。同时整个项目也完成了
    我们可以直接在浏览器输入ip:8889访问2048的游戏界面进行游戏,点击"New Game"按钮,通过键盘方向键操作进行游玩~

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    【数据结构与算法】堆排序(向下和向上调整)、TOP-K问题(超详细解读)
    [附源码]JAVA毕业设计婚纱影楼服务管理(系统+LW)
    .NET性能优化-你应该为集合类型设置初始大小
    搜维尔科技:使用Touch 触觉力反馈设备,用户可以完全沉浸在培训模拟、神经康复或远程的机器人操控中
    PyTorch使用神经网络进行手写数字识别实战(附源码,包括损失图像和准确率图像)
    K8S安装过程七:Kubernetes 节点配置调整
    机器学习:考试复习提纲
    嵌入式单片机无刷电机FOC控制与实现详解
    python全局和局部变量以及引用和装饰器
    【微服务】关于WSGI Server即web服务器
  • 原文地址:https://blog.csdn.net/kuuuugua/article/details/139973776