GitLab CIからのScaleway要素APIキーへのアクセスの確保


どのように多くのAPIキーは、GitLab CIの設定の変数として1日あたり保存されますか?
Scaleway Elements API Key GITLABに保存され、クラウドのインフラストラクチャの外に資格情報を格納するすべてのセキュリティ上の問題に直面する:アクセス、認証、キーの回転、年齢、破壊、場所など.
開発者がgtlab ciでgcpの資格情報を保存するには2つの一般的な理由があります.
  • 利用するshared runners .
  • 利用するspecific/group runners Aで配備されるScaleway Kubernetes Kapsule クラスタが使用しないGitlab additional configurations .
  • GITLAB CIがユーザーのために提案する選択肢は、各ビルドのために作成されたランナーポッドに秘密ボリュームをマウントすることです.

    必要条件
    次のツールをインストールします
  • Scaleway cli

  • kubectl
  • Helm
  • Scaleway組織で2つのプロジェクトを作成します.
  • 悪魔
  • 開発

  • Kapsuleでの作業
    最初のステップは、Kapsule devopsクラスタを作成し、環境を設定することです.

    Generate the API Key for the devops project. You can create one by following the documentation .


    scw init
    scw k8s cluster create name=kapsule-devops
    
    ランナー仕事のためにプールをつくりましょう:
    scw k8s pool create cluster-id=$(scw k8s cluster list | grep kapsule-devops | awk '{ print $1 }') name=dev node-type=GP1_XS size=2
    
    汚れを加える
    kubectl taint nodes gitlab-runner-jobs-dev-reserved=true:NoSchedule --selector=k8s.scaleway.com/pool-name=dev
    
  • 構成kubectl クラスタと通信するには、次の手順に従います.
  • scw k8s kubeconfig install kapsule-devops
    
  • devランナーの名前空間を作成します
  • kubectl create namespace dev
    
  • 特定のランナーに使用するKubernetesサービスアカウントを作成します
  • kubectl create serviceaccount --namespace dev app-deployer
    
  • 特定のランナーのために生成します.
  • Note: For easier visibility and auditing, I recommend to centrally store API keys in a dedicated project and in an external tools like Vault.

  • 特定のランナーがAPIキーを偽装するのを許容するために、我々はKubernetes秘密で資格証明書を保存する必要があります.
  • kubectl create secret generic dev-api-key --from-file ~/.config/scw/config.yaml -n dev
    


    GitLabランナーにAPIキーを割り当てます
    次のステップは秘密をデータボリューム[ 4 ]としてマウントすることです.
  • ヘルムをインストールする
  • curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
    chmod 700 get_helm.sh
    ./get_helm.sh
    
  • gitlabヘルムパッケージを追加します.
  • helm repo add gitlab https://charts.gitlab.io
    
  • ランナーの設定
  • ファイルを作るvalues.yaml :
    imagePullPolicy: IfNotPresent
    gitlabUrl: https://gitlab.com/
    unregisterRunners: true
    terminationGracePeriodSeconds: 3600
    concurrent: 10
    checkInterval: 30
    rbac:
      create: true
    metrics:
      enabled: true
    runners:
      image: ubuntu:18.04
      config: |
       [[runners]]
         [runners.kubernetes]
            [[runners.kubernetes.volumes.secret]]
              name = "dev-api-key"
              mount_path = "/root/.config/scw"
              read_only = true
      locked: true
      pollTimeout: 360
      protected: true
      serviceAccountName: app-deployer
      privileged: false
      secret: dev-runner-tokens
      namespace: dev
      builds:
        cpuRequests: 100m
        memoryRequests: 128Mi
      services:
        cpuRequests: 100m
        memoryRequests: 128Mi
      helpers:
        cpuRequests: 100m
        memoryRequests: 128Mi
      tags: "k8s-dev-runner"
      nodeSelector: 
         k8s.scaleway.com/pool-name: dev
      nodeTolerations:
        - key: "gitlab-runner-jobs-dev-reserved"
          operator: "Equal"
          value: "true"
          effect: "NoSchedule"
    

    You can find the description of each attribute in the Gitlab runner charts repository [2]

  • からのGitlab登録トークンを得てくださいProject -> Settings -> CI/CD -> RunnersSetup a specific Runner manually セクションを作成し、次の秘密を作成します
  • kubectl create secret generic dev-runner-tokens --from-literal=runner-token='' --from-literal=runner-registration-token='<TOKEN>' -n dev
    
  • ランナーをインストール
  • helm install -n dev app-dev-runner -f values.yaml gitlab/gitlab-runner
    


    Gitlab CIで特定のランナーを使用する
    パイプラインの作成.gitlab-ci.yml :
    stages:
      - dev
    
    infra:
      stage: dev
      image:
        name: scaleway/cli:v2.3.1
      script: 
        - /scw k8s cluster create name=kapsule-dev
        - /scw k8s pool create cluster-id=$(/scw k8s cluster list | grep kapsule-dev | awk '{ print $1 }') name=apps node-type=DEV1_M size=2
      tags:
        - k8s-dev-runner
      only:
        - main
    
    ジョブは、Kapsuleクラスタを作成しますdevelopment プロジェクト我々は、同じ手順に従うことができますproduction 環境.

    If you want to change the API Key, you just need to delete and recreate the dev-api-key secret.



    アクセスKapsuleクラスタ
    あなたのGitlabの仕事からKapsuleクラスタに接続するために、同じ手順に従うことができます.
  • 秘密を作る
  • kubectl create secret generic dev-kapsule-config --from-file ~/.kube/config -n dev
    
  • データボリュームとしてマウントします:
  •         [[runners.kubernetes.volumes.secret]]
              name = "dev-kapsule-config"
              mount_path = "/root/.kube"
              read_only = true
    

    In this example, we used a kubeconfig with admin access. You should use RBAC to restrict access to only specific Kubernetes resources that the runner needs.



    Gitlabフローの実装
    Environment branches with Gitlab Flow 分岐戦略とワークフローです.事前生産環境や生産環境のような追加環境があるとします.主ブランチを開発環境に配置します.プリプロダクションに展開するには、メインブランチからプリプロップブランチへのマージ要求[ 3 ]を作成します.プリブランチブランチをプロダクションブランチにマージすることによって、ライブを行ってください.

    次のスクリプトを追加./utils/autoMergeRequest.sh :
    #!/bin/bash
    
    [[ $CI_PROJECT_URL =~ ^https?://[^/]+ ]] && CI_PROJECT_URL="${BASH_REMATCH[0]}/api/v4/projects/"
    
    BODY="{
        \"id\": ${CI_PROJECT_ID},
        \"source_branch\": \"${CI_COMMIT_REF_NAME}\",
        \"target_branch\": \"${TARGET_BRANCH}\",
        \"remove_source_branch\": false,
        \"title\": \"Deployment to ${TARGET_BRANCH}\",
        \"assignee_id\":\"${GITLAB_USER_MAILINGLIST_ID}\"
    }";
    
    LISTMR=`curl --silent "${CI_PROJECT_URL}${CI_PROJECT_ID}/merge_requests?state=opened" --header "PRIVATE-TOKEN:${PRIVATE_TOKEN}"`;
    COUNTBRANCHES=`echo ${LISTMR} | grep -o "\"source_branch\":\"${CI_COMMIT_REF_NAME}\"" | wc -l`;
    
    if [ ${COUNTBRANCHES} -eq "0" ]; then
        curl -X POST "${CI_PROJECT_URL}${CI_PROJECT_ID}/merge_requests" \
            --header "PRIVATE-TOKEN:${PRIVATE_TOKEN}" \
            --header "Content-Type: application/json" \
            --data "${BODY}";
    
        echo "Opened a new merge request: Deployment to ${TARGET_BRANCH} and assigned to you";
        exit;
    fi
    
    echo "No new merge request opened";
    
    メーリングリストからマージ要求を受け取るのは一般的なパターンです.このメーリングリストでgitlabユーザを作成し、変数ci/cdを追加しますGITLAB_USER_MAILINGLIST_ID ユーザIDを指定します.URLを使用してIDを取得できますhttps://gitlab.com/api/v4/users?username=<USERNAME> .
    変数ci/cdの追加PRIVATE_TOKEN , あなたは1から作成することができますSettings > Project Access Tokens .
    gitlab-ci.yml :
    stages:
      - build
      - dev
      - preprod
      - prod
    
    build:
      stage: build
      script: 
        - echo 'build'
        - TARGET_BRANCH=main ./utils/autoMergeRequest.sh
      only:
        - /^feature\/*/
        - /^hotfix\/*/
    
    dev:
      stage: dev
      script: 
        - echo 'deploy dev'
        - TARGET_BRANCH=preprod ./utils/autoMergeRequest.sh
      tags:
        - k8s-dev-runner
      only:
        - main
    
    preprod:
      stage: preprod
      script: 
        - echo 'deploy preprod'
        - TARGET_BRANCH=prod ./utils/autoMergeRequest.sh
      tags:
        - k8s-preprod-runner
      only:
        - preprod
    
    prod:
      stage: prod
      script: 
        - echo 'deploy prod'
      tags:
        - k8s-prod-runner
      only:
        - prod
    

    The preprod and prod branches need to be marked as protected. Go to Settings > Repository > Protected branches.



    結論
    この投稿では、devopsクラスタを作りました.特定のランナーにYMLファイルを作成し、環境プロジェクトにScaleway要素とKubernetesリソースを展開しました.
    このメカニズムは、Scaleway要素のAPIキーリソースのエンドツーエンドセキュリティを保証します.
    ご質問やご意見がある場合は、コメントを残して自由に感じてください.
    それ以外の場合は、GitLab CI変数からAPIキーを削除するように確信しています.
    ところで、仲間と共有することを躊躇しないでください😊
    読書ありがとう!

    ドキュメント
    〔1〕https://www.scaleway.com/en/docs/compute/kubernetes/api-cli/creating-managing-kubernetes-lifecycle-cliv2/
    〔2〕https://gitlab.com/gitlab-org/charts/gitlab-runner/-/blob/main/values.yaml
    [ 3 ]https://about.gitlab.com/blog/2017/09/05/how-to-automatically-create-a-new-mr-on-gitlab-with-gitlab-ci/
    〔4〕https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod