在GitLab CI / CD中构建/测试/部署Docker映像的首选方法

时间:2020-09-16 04:40:15

标签: docker kubernetes gitlab-ci bitnami

我正在尝试在GitLab中构建CI / CD管道。目标是从Dockerfile构建Docker映像,在运行的容器上运行测试,将映像推送到DockerHub,然后将其部署到Kubernetes集群。这是我目前为gitlab-ci.yml准备的东西。

variables:
  DOCKER_TLS_CERTDIR: "/certs"
  DOCKER_DRIVER: overlay2
  CONTAINER_IMAGE: ${DOCKER_USER}/my_app

services:
  - docker:19.03.12-dind

build:
  image: docker:19.03.12
  stage: build
  script:
    - echo ${DOCKER_PASSWORD} | docker login --username ${DOCKER_USER} --password-stdin
    - docker pull ${CONTAINER_IMAGE}:latest || true
    - docker build --cache-from ${CONTAINER_IMAGE}:latest --tag ${CONTAINER_IMAGE}:$CI_COMMIT_SHA --tag ${CONTAINER_IMAGE}:latest .
    - docker push ${CONTAINER_IMAGE}:$CI_COMMIT_SHA
    - docker push ${CONTAINER_IMAGE}:latest

deploy:
  image:
    name: bitnami/kubectl:1.16.15
    entrypoint: [""]
  stage: deploy
  variables:
    GIT_STRATEGY: none
  script:
     - kubectl get pods -A   # <- Won't work until I pass a Kubeconfig file with cluster details

我有几个主要问题:

  1. 如何部署此映像?我知道我需要将KUBECONFIG文件传递给bitnami / kubectl,但不确定如何使用GitLab CI / CD进行此操作
  2. 在推送到DockerHub之前,我可以将构建的映像传递到 test 阶段吗?

2 个答案:

答案 0 :(得分:0)

对于部署到Kubernetes,我没有任何答案,但是我确实建议在构建构建映像的合并请求/开发分支时,将测试/构造映像发布到Dockerhub。然后,仅在将分支合并到master时才部署最新映像。

---
stages:
  - build
  - test
  - deploy

build image:
  stage: build
  script:
    - docker build your_iamge:test
    - deploy push your_image:test
  rules:
    - if: '$CI_BUILD_REF_NAME != "master"

test image:
  stage: test
  image: your_image:test
  script:
    - commands to test image
  rules:
    - if: '$CI_BUILD_REF_NAME != "master"

deploy image:
  stage: deploy
  script:
    - docker build your_image:latest
    - docker push your_image:latest
  rules:
    - if: '$CI_BUILD_REF_NAME == "master"


---
stages:
  - build
  - test
  - deploy

build image:
  stage: build
  script:
    - docker build your_image:$CI_BUILD_REF_NAME
    - deploy push your_image:$CI_BUILD_REF_NAME
  rules:
    - if: '$CI_BUILD_REF_NAME != "master"

test image:
  stage: test
  image: your_image:test
  script:
    - commands to test image
  rules:
    - if: '$CI_BUILD_REF_NAME != "master"

deploy image:
  stage: deploy
  script:
    - docker build your_image:latest
    - docker push your_image:latest
    - export BRANCH=${CI_COMMIT_TITLE#*\'}; export BRANCH=${BRANCH%\' into*}
    - docker delete your_image:$BRANCH
  rules:
    - if: '$CI_BUILD_REF_NAME == "master"

答案 1 :(得分:0)

---
stages:
  - test app
  - build
  - test
  - deploy

test app:
  stage: test_app
  image: node:latest
  script:
    - git clone (path to code)
    - npm install 
    - lint
    - audit fix
  rules:
    - if: '$CI_BUILD_REF_NAME != "master"
    
build image:
  stage: build
  script:
    - docker build your_image:$CI_BUILD_REF_NAME
    - deploy push your_image:$CI_BUILD_REF_NAME
  rules:
    - if: '$CI_BUILD_REF_NAME != "master"

test image:
  stage: test
  image: anchor:latest  (one you have built yourself or use another testing suite)
  script:
    - anchore-cli image add user/image:v1
    - anchore-cli image wait user/image:v1
    - anchore-cli image content user/image:v1
    - image vuln user/image:v1 all
    - anchore-cli evaluate check user/image:v1 > result .txt
    - if ( grep -ci "fail" result.txt >= 1); then exit 1 fi  
  rules:
    - if: '$CI_BUILD_REF_NAME != "master"

deploy image:
    image:
        name: kubectl:latest  (build your own image that installed kubectl)
        entrypoint: [""]
    stage: deploy
    tags:
        - privileged
    # Optional: Manual gate
    when: manual
    dependencies:
        - build-docker
    script:
        - kubectl config set-cluster k8s --server="$CLUSTER_ADDRESS"
        - kubectl config set clusters.k8s.certificate-authority-data $CA_AUTH_DATA
        - kubectl config set-credentials gitlab-service-account --token=$K8S_TOKEN
        - kubectl config set-context default --cluster=k8s --user=gitlab-service-account --namespace=my-service
        - kubectl config use-context default
        - kubectl set image $K8S_DEPLOYMENT_NAME $CI_PROJECT_NAME=$IMAGE_TAG
        - kubectl rollout restart $K8S_DEPLOYMENT_NAME
1. have variables passed in for cluter address, cert data, and token stuff... so you can target other clusters, pre-prod, prod, qa...

2. you can't test an image that isn't on the repo, as the testing suite needs to pull the image from somewhere... You should have a clean up script running to cleanup old image in your repo anyway, so the initial push should be a (test location)

like:  docker push untrusted/image:v1

You should also have before scripts and after scripts... before calls docker login
after calls docker logout...