K8S环境下GitLab CI/CD流水线详解及实战

作者:微信小助手

发布时间:2023-10-23T09:51:11

GitLab CI/CD是GitLab提供的持续集成和持续交付(CI/CD)工具,它允许开发团队在代码仓库中定义和管理自动化的流水线,以实现自动化构建、测试和部署应用程序的过程。通过GitLab CI/CD,开发团队可以更高效地进行软件开发和交付,提高开发速度和质量。

GitLab CI/CD的核心概念是流水线(Pipeline),它由一系列的阶段(Stage)和任务(Job)组成。每个任务可以执行一系列的操作,如构建代码、运行测试、生成文档、部署应用程序等。流水线可以根据代码仓库中的触发条件(如提交代码、合并请求等)自动触发执行,并提供了丰富的配置选项和扩展性,以满足不同项目的需求。


GitLab CI/CD流水线语法

下面是GitLab CI/CD流水线语法的完整解释:

  1. stages(阶段):使用stages关键字定义流水线的阶段,每个阶段代表流水线中的一个逻辑分组。例如:


stages:  - build  - test  - deploy


  1. jobs(任务):在每个阶段中,可以定义一个或多个任务(jobs),每个任务代表流水线中的一个操作。任务可以并行执行或按顺序执行。例如:


build:  stage: build  script:    - echo "Building the application..."


  1. script(脚本):在任务中,使用script关键字定义要执行的脚本命令。脚本可以是任何可执行的命令或脚本语言。例如:


script:  - echo "Building the application..."  - npm install  - npm run build


  1. before_script(前置脚本):在任务执行之前,可以使用before_script关键字定义要在每个任务之前执行的脚本命令。例如:


before_script:  - echo "Setting up environment..."  - apt-get install -y some-package


  1. after_script(后置脚本):在任务执行之后,可以使用after_script关键字定义要在每个任务之后执行的脚本命令。例如:


after_script:  - echo "Cleaning up..."  - rm -rf some-directory


  1. variables(变量):使用variables关键字定义流水线中的环境变量。环境变量可以在脚本中使用,用于传递参数或配置信息。例如:


variables:  ENVIRONMENT: production  API_KEY: $API_KEY


  1. rules(规则):使用rules关键字定义任务的触发规则。可以根据条件来决定是否执行任务。例如:


build:  stage: build  script:    - echo "Building the application..."  rules:    - changes    - exists:        - Dockerfile


  1. artifacts(产物):使用artifacts关键字定义任务产生的产物(如构建产物、测试报告等)。产物可以在后续的任务中使用或存档。例如:


build:  stage: build  script:    - echo "Building the application..."  artifacts:    paths:      - dist/


  1. dependencies(依赖):使用dependencies关键字定义任务的依赖关系。可以指定一个或多个任务作为当前任务的依赖,确保依赖任务执行成功后再执行当前任务。例如:


test:  stage: test  script:    - echo "Running tests..."  dependencies:    - build


以上是GitLab CI/CD流水线语法的主要要点和关键字。你可以根据你的项目需求和实际情况进行配置和扩展。在实际使用中,你还可以使用更多的关键字和功能,如缓存、环境、扩展、触发器等,以满足更复杂的需求。


基于GitLab CI/CD流水线部署到K8S流水线实战

以下是一个基于GitLab CI/CD流水线的示例,包括拉代码、安装依赖、镜像构建、推送到私服仓库、Sonar代码检测、部署Kubernetes、扫描镜像漏洞、发送钉钉构建成功或失败通知:

stages:  - build  - test  - deploy
variables: DOCKER_REGISTRY: registry.example.com DOCKER_NAMESPACE: myapp DOCKER_IMAGE_NAME: myapp DOCKER_IMAGE_TAG: latest K8S_NAMESPACE: myapp K8S_DEPLOYMENT_NAME: myapp K8S_SERVICE_NAME: myapp K8S_CONTAINER_PORT: 80 K8S_REPLICAS: 3 DOCKER_USERNAME: username DOCKER_PASSWORD: $DOCKER_PASSWORD NEXUS_USERNAME: nexus_username NEXUS_PASSWORD: $NEXUS_PASSWORD SONAR_TOKEN: $SONAR_TOKEN DINGTALK_ACCESS_TOKEN: $DINGTALK_ACCESS_TOKEN DINGTALK_SECRET: $DINGTALK_SECRET
before_script: - echo "Setting up environment..." - apk add --no-cache curl jq
build: stage: build script: - echo "Building the application..." - npm install - docker build -t $DOCKER_REGISTRY/$DOCKER_NAMESPACE/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG . - docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD $DOCKER_REGISTRY - docker push $DOCKER_REGISTRY/$DOCKER_NAMESPACE/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG - echo "Pushing the Docker image to Nexus..." - docker tag $DOCKER_REGISTRY/$DOCKER_NAMESPACE/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG $DOCKER_REGISTRY/$DOCKER_NAMESPACE/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG - docker login -u $NEXUS_USERNAME -p $NEXUS_PASSWORD $DOCKER_REGISTRY - docker push $DOCKER_REGISTRY/$DOCKER_NAMESPACE/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG artifacts: paths: - dist/
test: stage: test image: sonarsource/sonar-scanner-cli:latest script: - echo "Running Sonar analysis..." - sonar-scanner -Dsonar.login=$SONAR_TOKEN only: - master
deploy: stage: deploy image: bitnami/kubectl:latest script: - echo "Deploying the application..." - kubectl apply -f k8s/deployment.yaml -n $K8S_NAMESPACE - kubectl apply -f k8s/service.yaml -n $K8S_NAMESPACE environment: name: production url: http://$K8S_SERVICE_NAME.$K8S_NAMESPACE.svc.cluster.local:$K8S_CONTAINER_PORT only: - master
scan: stage: deploy image: aquasec/trivy:latest script: - echo "Scanning Docker image for vulnerabilities..." - trivy $DOCKER_REGISTRY/$DOCKER_NAMESPACE/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG only: - master
notify: stage: deploy image: curlimages/curl:latest script: - echo "Sending notification..." - export MESSAGE=$(echo -e "GitLab CI/CD pipeline for *$CI_PROJECT_NAME* ($CI_COMMIT_REF_NAME) *$CI_PIPELINE_STATUS*.\n\nView pipeline details at $CI_PIPELINE_URL") - export SIGN=$(echo -n "$MESSAGE$DINGTALK_SECRET" | openssl dgst -sha256 -hmac $DINGTALK_SECRET | awk '{print $2}') - curl -s -X POST "https://oapi.dingtalk.com/robot/send?access_token=$DINGTALK_ACCESS_TOKEN&timestamp=$(date +%s000)&sign=$SIGN" \ -H 'Content-Type: application/json' \ -d "{\"msgtype\": \"text\",\"text\": {\"content\": \"$MESSAGE\"}}" when: on_failure

当使用上述给出的流水线时,以下是每个阶段的详细步骤解释:

  1. build阶段:

    • 安装依赖:执行npm install命令安装项目的依赖项。

    • 构建镜像:使用docker build命令构建Docker镜像,镜像名称为$DOCKER_REGISTRY/$DOCKER_NAMESPACE/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG

    • 登录到Docker仓库:使用docker login命令登录到Docker仓库,用户名为$DOCKER_USERNAME,密码为$DOCKER_PASSWORD

    • 推送镜像:使用docker push命令将构建的镜像推送到Docker仓库。

    • 推送到Nexus私服:将构建的镜像重新标记为$DOCKER_REGISTRY/$DOCKER_NAMESPACE/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG,然后使用docker login命令登录到Nexus私服,用户名为$NEXUS_USERNAME,密码为$NEXUS_PASSWORD,最后使用docker push命令将镜像推送到Nexus私服。

  2. test阶段:

    • 运行Sonar代码检测:使用sonar-scanner命令运行Sonar代码检测,需要提供Sonar的访问令牌($SONAR_TOKEN)。

  3. deploy阶段:

    • 部署应用:使用kubectl apply命令将Kubernetes部署文件k8s/deployment.yamlk8s/service.yaml应用到Kubernetes集群中的命名空间$K8S_NAMESPACE

    • 设置环境变量:设置环境变量name为"production",url为应用的访问URL。

  4. scan阶段:

    • 扫描镜像漏洞:使用trivy命令对Docker镜像$DOCKER_REGISTRY/$DOCKER_NAMESPACE/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG进行安全扫描。

  5. notify阶段:

    • 发送通知:使用curl命令发送通知到钉钉群组,通知内容包括GitLab CI/CD流水线的状态和详情。发送通知的URL为https://oapi.dingtalk.com/robot/send?access_token=$DINGTALK_ACCESS_TOKEN,签名使用$DINGTALK_SECRET进行加密。

请根据你的实际情况和配置,修改示例中的变量和命令,确保与你的项目和环境相匹配。


往期推荐






DevOps 与 SysOps


DevOps中的Argo CD — 灾难恢复


云原生CNCF生态蓝图


Deploying ArgoCD/Prometheus/Grafana/— Including Dashboards


Cloud Native 云原生 | 概念解读