1

Preface

Recently, my friend accepted an outsourcing. This outsourcing company uses gitlab to do cicd. My friend used jenkins for automated deployment before. I have never contacted cicd of gitlab. My friend also has more technical pursuits. He found this company. In the k8s yaml file, many fields can actually be extracted and dynamically passed in with cicd instead of writing those fields directly in the yaml file, such as a docker image. I happened to have played cicd based on gitlab for a while before, and he asked me if I had any ideas, so he had the material for this article.

Pre-knowledge

1. How to use gitlab to do cicd

You can check the official website link, as follows

https://docs.gitlab.com/ee/ci/README.html

2. Understand the envsubst command

a, the role of envsubst

This command can pass the environment variable to the file, and realize the variable replacement of the file, the variable format to be replaced is ${var} or $var

b. How to use envsubst
  • Replace the environment variable stdin output to stdout:
echo '{{$HOME}}' | envsubst
  • Replace the environment variables in the input file with stdout:
envsubst < {{path/to/input_file}}
  • Replace the environment variables in the input file with a file, and output it to the file:
envsubst < {{path/to/input_file}} > {{path/to/output_file}}
  • Use a space-separated list to replace the environment variables in the input file:
envsubst '{{$USER $SHELL $HOME}}' < {{path/to/input_file}}

The content of the above command comes from the following blog post, because the command is not a few lines, I also posted it

https://blog.csdn.net/oopxiajun2011/article/details/111668011

Note: on mac, you need to install gettext to use envsubst

c. How to use envsubst to replace k8s deployment.yaml

Assume that deployment.yaml has a mirrored content shape as follows

image: $DEPLOY_PROCJECT_IMAGE

We can execute the following command

 envsubst < deployment.yml | kubectl apply -f -

This command means to read deployment.yml, replace $DEPLOY_PROCJECT_IMAGE in deployment.yml with the corresponding environment variable through envsubst, and pass the content of deployment.yml to kubectl through the pipeline

How to pass the environment variables of gitlab ci to k8s deployment.yaml transparently

Example:

Note: friend's company uses business services and deployment services.gitlab-ci.yml isolation, business services.gitlab-ci.yml is deployed by triggering the deployment service trigger. The example only lists the content related to this article, other configurations Information cleaned up

1. The configuration of .gitlab-ci.yml for business services is as follows
variables:
  REGISTRY: xxx.docker.com
  PROJECTNAME: hello-demo
  IMAGE: demo/hello-demo
  DEPLOY_VERSION: $CI_COMMIT_TIMESTAMP


stages:
  - triggerDeploy


triggerDeployK8S:
  stage: triggerDeploy
  image: $REGISTRY/devops/busyboxplus:curl
  script:
    - curl -X POST -F token=fc4754200aa027baedf97cf7d45a02 -F ref=master -F "variables[DEPLOY_PROJECT_NAME]=$PROJECTNAME" -F "variables[DEPLOY_PROCJECT_IMAGE]=$REGISTRY/$IMAGE:dev" -F "variables[DEPLOY_VERSION]=$DEPLOY_VERSION" http://xxx.gitlab.com/api/v4/projects/32/trigger/pipeline
  only:
    - dev
  tags:
    - dev

among them

variables[DEPLOY_PROCJECT_IMAGE]=$REGISTRY/$IMAGE:dev

Is the environment variable

2. The .gitlab-ci.yml configuration of the deployment service is as follows
stages:
  - deploy
deploy:
  stage: deploy
  script:
    - echo $DEPLOY_PROJECT_NAME
    - echo $DEPLOY_PROCJECT_IMAGE
    - echo $DEPLOY_VERSION
    - cd ${DEPLOY_PROJECT_NAME}
    - envsubst < deployment.yml | kubectl apply -f 
  only:
    - triggers
  tags:
    - dev-deploy
3. Example of deployment.yml
apiVersion: v1
kind: Service
metadata:
  namespace: dev
  name: hello-demo
spec:
  selector:
    app: hello-demo
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
      nodePort: 30011
  type: NodePort
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800

---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: dev
  name: hello-demo
  labels:
    app: hello-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-demo
  template:
    metadata:
      labels:
        app: hello-demo
    spec:
      imagePullSecrets:
      - name: default-secret
      containers:
      - name: hello-demo
        image: $DEPLOY_PROCJECT_IMAGE
        imagePullPolicy: Always
        ports:
         - containerPort: 8080
        env:
            # k8s滚动更新pod,是根据deployment.yml的变化来更新,如果代码更新了,但是deployment.yml内容没更新,k8s会认为
            #pod没有产生变化,因此就不会进行滚动升级。DEPLOY_VERSION是用来做每次部署动态更新deployment.yml内容
          - name: DEPLOY_VERSION
            value: "$DEPLOY_VERSION"
          

to sum up

It seems that there is not much content to summarize, just post a variable document built in gitlab ci as a summary. The content of the document is as follows

https://docs.gitlab.com/ce/ci/variables/predefined_variables.html


linyb极客之路
347 声望193 粉丝