1. 程式人生 > >gitlab的ci/cd釋出專案隱藏帳號密碼

gitlab的ci/cd釋出專案隱藏帳號密碼

轉載請註明出處:gitlab的ci/cd釋出專案隱藏帳號密碼

為了安全需要,一般專案中不允許包含明文密碼,防止獲取到專案程式碼的人拿到資料庫的帳號密碼,防止帳號密碼洩露。

去掉明文密碼的方式 有很多,比如:
1、使用k8s的secret,參考文章
python專案中通過環境變數的方式使用secret金鑰引數
2、使用gitlab的引數設定,在ci時把環境變數傳入映象。
本章介紹這種方式。

gitlab設定帳號密碼等變數

gitlab中配置變數名和值,點選settings,ci/cd,找到variables,填入key和value即可。
如果是很多個專案通用的變數,可以設定在group的變數中,在group層級找到settings即可。
如果是單個專案使用的變數,只在專案層級找到settings,設定專案的變數。

注意,protected如果打勾,則只有protected分支和打了tag的ci能夠獲取到這個變數。

gitlab的ci中獲取gitlab中設定的變數如下:

  variables:
    AWS_ACCESS_KEY_ID: ${AWSAccessKeyID}
    AWS_DEFAULT_REGION: ${DefaultRegionName}
    AWS_SECRET_ACCESS_KEY: ${AWSSecretAccessKey}
或者docker build時傳入環境變數
  - docker build -t  -e REDIS_HOST=${HOST} $IMAGE_NAME:sit .

完整參考如下:

variables:
  MGAP_ENV: ci
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache"
  IMAGE_NAME: 123-3456-1.amazonaws.com.cn/mgap-module/mgap-module

cache:
  paths:
    - .cache/pip
    - .venv/

stages:
  - test
  - package
  - build
  - deploy

test:
  stage: test
  only:
    - dev
    - master
    - tags
  image: 567.aliyuncs.com/zzq-public/poetry:latest
  script:
    - python3.7 -m venv ./venv
    - source venv/bin/activate
    - poetry develop
    - poetry run pytest -s -vv --cov=./mgap_module

package:
  stage: package
  only:
    - dev
    - master
    - tags
  image: 567.aliyuncs.com/zzq-public/poetry:latest
  script:
    - poetry build
  artifacts:
    paths:
      - dist/*.whl
    expire_in: 30 days

build-sit:
  stage: build
  only:
    - dev
  image: 567.aliyuncs.com/zzq-public/docker-with-awscli:latest
  tags:
    - common
  script:
    - docker build -t  -e REDIS_HOST=${HOST} $IMAGE_NAME:sit .
    - eval $(aws ecr get-login --no-include-email --region cn-northwest-1)
    - docker push $IMAGE_NAME:sit
  variables:
    AWS_ACCESS_KEY_ID: ${AWSAccessKeyID}
    AWS_DEFAULT_REGION: ${DefaultRegionName}
    AWS_SECRET_ACCESS_KEY: ${AWSSecretAccessKey}

專案中使用環境變數

java版本

當docker啟動SpringBoot打包的服務時,且一些引數需要從外界獲取而非寫死在properties檔案裡,通過以下兩步完成此需求:
1.在配置檔案中配置環境變數

spring.redis.host=${REDIS_HOST:127.0.0.1}
spring.redis.port=6379
spring.redis.timeout=30000

以上表是REDIS_HOST在系統環境變數中獲取,如果獲取不到預設值為127.0.0.1
程式碼中使用如下:

@Value("${host.port.url}")
	private String host;

2.在啟動docker容器時傳入環境引數

docker run -d --name test2 {映象名} -e REDIS_HOST=192.168.0.1

如果是使用的kubectl create方式則要麻煩一些,因為gitlab中設定的變數只能在gitlab.ci檔案中使用${}方式識別到。並沒找到一種直接能傳導到k8s的yaml中的方式。

我這裡找到了三種方式:
1、gitlabci中使用sed -i替換yaml中的文字資訊
2、使用configmap作為中轉(不推薦,configmap管理得不好其他人還是能夠通過configmap獲取到賬號密碼)
3、sed -i的高階版本使用envsubst

首先了解一下k8s中設定環境變數的方式如下:
例如

kubectl create -f https://k8s.io/docs/tasks/inject-data-application/envars.yaml

需要在yml中加入如下配置

env:
   - name: DEMO_GREETING
     value: "Hello from the environment"

例子如下:

apiVersion: v1
kind: Pod
metadata:
  name: envar-demo
  labels:
    purpose: demonstrate-envars
spec:
  containers:
  - name: envar-demo-container
    image: gcr.io/google-samples/node-hello:1.0
    env:
    - name: DEMO_GREETING
      value: "Hello from the environment"

方式一 sed文字替換
service.yml如下:

apiVersion: v1
kind: Service
metadata:
  name: presentation-gitlab-k8s-__CI_BUILD_REF_SLUG__
  namespace: presentation-gitlab-k8s
  labels:
    app: __CI_BUILD_REF_SLUG__
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "8000"
    prometheus.io/scheme: "http"
    prometheus.io/path: "/metrics"
spec:
  type: ClusterIP
  ports:
    - name: http-metrics
      port: 8000
      protocol: TCP
  selector:
    app: __CI_BUILD_REF_SLUG__

使用程式碼如下:

- sed -i "s/__CI_BUILD_REF_SLUG__/${CI_ENVIRONMENT_SLUG}/" deployment.yaml ingress.yaml service.yaml

例子

deploy_live:
  image: lachlanevenson/k8s-kubectl:latest
  stage: deploy
  environment:
    name: live
    url: https://live-presentation-gitlab-k8s.edenmal.net
  only:
    - tags
  when: manual
  script:
    - kubectl version
    - cd manifests/
    - sed -i "s/__CI_BUILD_REF_SLUG__/${CI_ENVIRONMENT_SLUG}/" deployment.yaml ingress.yaml service.yaml
    - sed -i "s/__VERSION__/${CI_COMMIT_REF_NAME}/" deployment.yaml ingress.yaml service.yaml
    - kubectl apply -f deployment.yaml
    - kubectl apply -f service.yaml
    - kubectl apply -f ingress.yaml
    - kubectl rollout status -f deployment.yaml
    - kubectl get all,ing -l app=${CI_ENVIRONMENT_SLUG}

方式二configmap

configmap實際上就是一系列鍵值對,儲存於etcd裡。etcd的官網有這樣一句話:

etcd是一個高效能的分散式鍵值對儲存庫,用於儲存和訪問關鍵資料。

使用下面的命令列建立一個Kubernetes config map:

kubectl create configmap test-config --from-literal=test.type=unit --from-literal=test.exec=always

建立一個名為test-config的鍵值對,key為test.type,值為unit,key為test.exec, 值為always。

下面我打算建立一個pod,消費這個名為test-config的configmap。

建立一個內容如下的yaml檔案:

apiVersion: v1
kind: Pod
metadata:
    name: test-configmap
spec:
    containers:
        - name: test-container
          image: alpine:3.8
          command: [ "/bin/sh", "-c", "env" ]
          env:
              - name: TEST_TYPE
                valueFrom:
                    configMapKeyRef:
                        name: test-config
                        key: test.type
              - name: TEST_EXEC
                valueFrom:
                configMapKeyRef:
                    name: test-config
                    key: test.exec
restartPolicy: Never

這個yaml檔案定義的pod基於docker映象alpine,執行shell命令/bin/sh -c env檢視環境變數。

在env區域,我給該pod注入一個名為TEST_TYPE的環境變數,值從configMap鍵值對的鍵名稱為test.type的值中取。

kubectl create -f 建立這個pod

使用命令kubectl logs test-configmap檢視這個pod執行生成的日誌,發現輸出的環境變數列表中,出現了TEST_TYPE=unit,這個TEST_TYPE是我在yaml檔案裡注入的環境變數名稱,而unit就來自configmap裡test-config的值unit。

方式三envsubst
在deploy.yml中:

LoadbalancerIP: $LBIP

然後只需建立你的env var並像這樣執行kubectl:

export LBIP="1.2.3.4"
envsubst < deploy.yml | kubectl apply -f -

您只需將常規Bash變數放入您想要使用的任何檔案中,在本例中為YAML清單,並且確保讀取該檔案.它將輸出檔案,其env變數由其值替換.您還可以使用它來建立這樣的新檔案:

envsubst < input.yml > output.yml

envsubst可在例如Ubuntu / Debian gettext包.

詳情參考
為容器設定環境變數
https://edenmal.moe/post/2018/GitLab-Kubernetes-Using-GitLab-CIs-Kubernetes-Cluster-feature/
https://github.com/kubernetes/kubernetes/issues/52787
https://segmentfault.com/a/1190000017116762
https://codeday.me/bug/20181112/369915.html

python版本

python–讀取環境變數

轉載請註明出處:gitlab的ci/cd釋出專案隱藏帳號密碼