preface

Recently, my friend received an outsourcing company, which uses GitLab to make CICD. Before my friend’s automatic deployment, he basically used Jenkins and never had contact with CICD of GitLab. My friend is also ambitious in technology, and he found that many fields could be extracted from the YAML file of K8S of this company. Instead of writing those fields directly to yamL files, such as docker images, work with CICD to dynamically pass in. Just as I had played cicD based on GitLab for a while before, he asked me if I had any ideas, so I got the material for this article

Front knowledge

1. How to use GitLab to make CICD

Check out the official website link below

Docs.gitlab.com/ee/ci/READM…

2. Understand the envsubst command

A, the role of ENvsubst

This command can be used to pass environment variables to a file and implement variable substitution of the file in the format var or {var} or var or var

B. How to use ENvsubst

  • Replace the environment variable stdin to stdout:
echo '{{$HOME}}' | envsubst
Copy the code
  • Replace the environment variable in the input file with stdout:
envsubst < {{path/to/input_file}}
Copy the code
  • Replace the environment variable in the input file with the file and output it to the file:
envsubst < {{path/to/input_file}} > {{path/to/output_file}}
Copy the code
  • Replace the environment variables in the input file with a whitespace separated list:
envsubst '{{$USER $SHELL $HOME}}' < {{path/to/input_file}}
Copy the code

The above command comes from the following blog post, which I posted because it was a few lines short

Blog.csdn.net/oopxiajun20…

Note: On a MAC, gettext needs to be installed to use enVsubst

C. How to replace K8S Deployment.ymal with ENVsubst

Assume that deployment.yaml has an image content that looks like this

image: $DEPLOY_PROCJECT_IMAGE
Copy the code

We can execute the following command

 envsubst < deployment.yml | kubectl apply -f -
Copy the code

This line reads deployment.yml and replaces the $DEPLOY_PROCJECT_IMAGE in deployment.yml with the appropriate environment variable via envsubst and pipes, Pass the contents of deployment.yml to Kubectl

How do I transparently pass gITLAB CI environment variables to K8S Deployment.yaml

Example:

Gitlab-ci. yml is deployed by the trigger that triggers the deployment service. The example column is only relevant to this article, and other configuration information is cleaned up

1. Gitlab-ci. yml of business services is configured 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

Copy the code

Among them

variables[DEPLOY_PROCJECT_IMAGE]=$REGISTRY/$IMAGE:dev
Copy the code

That’s the environment variable

Gitlab-ci. yml is configured 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

Copy the code

3. Example 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 rolls pod updates according to changes in deployment.yml. If the code is updated but the deployment.yml content is not, K8S will assume that
            # Pod does not change, so there is no rolling upgrade. DEPLOY_VERSION is used to dynamically update the deployment.yml content for each deployment
          - name: DEPLOY_VERSION
            value: "$DEPLOY_VERSION"
          
Copy the code

conclusion

It seems that there is no content summary, just post the variables document built into GitLab CI as a summary. The document content is as follows

Docs.gitlab.com/ce/ci/varia…