GKE에서 Guitlab Runner를 실행하기 전의 설정 방법 [Google Cloud SDK와 Helm 등 사용]

29391 단어 KubernetesGitLabtech
Advent Calendar 2020 9일째 보도다.

시작


안녕하세요.나는 도쿄 도내에서 엔지니어로 일한다.
이 글은 GKE에서 Guitlab Runner를 실행하기 전의 설정 방법에 대한 메모입니다.

1. 본 기사의 문제점 공유


기틀랩이 공개한 GitLab CI/CD on Google Kubernetes Engine in 15 minutes or less대로 진행하지 않아 시행착오가 몇 개 있었다.[1]
구체적으로 다음과 같다.
- Gitlabの設定画面にてHelm Tillerが見当たらない
- Gitlab Runnerはあったが、こちらはインストールに失敗する
Gitlab Runner는 GKE에서 안전하게 수행할 수 있다는 결론이다.
그래서 이 보도가 어떻게 진행되었는지 제가 쓰겠습니다.

2. 환경/버전 정보


2-1.초단순 구성도


<GCE(検証環境)> # git pushなど
↓
<https://gitlab.com> # 後続する設定に該当するGitlab Runnerを実行
↓ 
<GKE上のGitlab Runner> # .gitlab-ci.ymlに書かれたジョブを実行
↓
echo "success" # 任意のジョブが実行された!

2-2. GCP에서 활성화해야 하는 API


위 Gitlab 블로그GitLab CI/CD on Google Kubernetes Engine in 15 minutes or less에는 다음 API를 활성화해야 한다고 적혀 있습니다.
A Google Cloud project with the following APIs enabled:Google Kubernetes Engine API Cloud Resource Manager API Cloud Billing API

2-3.버전 정보

  • GCE(검증 환경)
  • $ grep "^VERSION=" /etc/os-release 
    VERSION="20.04.1 LTS (Focal Fossa)"
    
  • Google Cloud SDK(이하 GCloud SDK로 기재)
  • $ gcloud version
    Google Cloud SDK 318.0.0
    alpha 2020.11.06
    beta 2020.11.06
    bq 2.0.62
    core 2020.11.06
    gsutil 4.54
    kubectl 1.16.13
    
  • kubectl
  • $ kubectl version --client
    Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.4", GitCommit:"d360454c9bcd1634cf4cc52d1867af5491dc9c5f", GitTreeState:"clean", BuildDate:"2020-11-11T13:17:17Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
    
  • helm
  • $ helm version
    version.BuildInfo{Version:"v3.4.1", GitCommit:"c4e74854886b2efe3321e185578e6db9be0a6e29", GitTreeState:"clean", GoVersion:"go1.14.11"}
    
  • Gcloud SDK에 대한 config 정보
  • $ gcloud config list
    [compute]
    region = asia-northeast1
    zone = asia-northeast1-a
    [container]
    cluster = hello-cluster
    [core]
    account = [email protected]
    disable_usage_reporting = False
    project = your-project
    

    2-4.Gcloud SDK에 대한 config 추가 설정

  • region,zone,cluster
  • 가 설정되지 않았습니다.
  • 따라서 다음과 같이 설정
  • $ gcloud config set compute/region asia-northeast1
    $ gcloud config set compute/zone asia-northeast1-a
    $ gcloud config set container/cluster hello-cluster
    

    2-5.GCP 프로젝트의 ID를 환경 변수로 사용


    ※ 본 편은 설명하기 편리하도록 GCPプロジェクトのIDを${PROJECT_ID}로 기재했습니다.[2]
    $ gcloud config list project --format="value(core.project)"
    your-gcp-project-id
    $ gcloud config get-value project
    your-gcp-project-id
    $ export PROJECT_ID = your-gcp-project-id
    
    이로써 GKE 클러스터가 Gitlab Runner를 시작할 준비가 완료되었습니다.
    이어 GCloud SDK로 GKE 클러스터를 제작한다.

    3. GKE 클러스터 제작

  • 클러스터 이름을 hello-Cluter
  • 로 만듭니다.
    $ gcloud container clusters create hello-cluter --num-nodes=1
    
  • 생성된 클러스터 확인
  • $ gcloud container clusters list | grep -v "NAME" | awk '{print $1}'
    hello-cluster
    
  • kubectl config current-context에서 만든 GKE 클러스터 표시
  • $ gcloud container clusters get-credentials \
    > $(gcloud container clusters list | grep -v "NAME" | awk '{print $1}')
    
  • Kubectl에서 GKE 클러스터 확인
  • 다음 명령을 실행하고 그룹 이름이 아닌 것을 표시합니까?[3]
  • $ kubectl config current-context
    gke_${PROJECT_ID}_asia-northeast1-a_hello-cluster
    

    4. GKE 클러스터 및 Gitlab 통합


    4-1.Gitlab의 GUI를 통해 다양한 페이지 설정


  • 로그인https://gitlab.com, 아무 항목이나 클릭
  • 선택 gke-quickstart
  • 이 프로젝트는 .gitlab-ci.ymlpush의 창고
  • 를 가리킨다

  • 클릭Operations

  • 클릭Kubernetes

  • 클릭Connect cluster with certificate

  • 4-2.Gitlab의 GUI를 통한 다양한 설정

  • 아래 그림과 같은 화면에 아래 항목을 입력하십시오
  • Kubernetes cluster name
  • API URL
  • CA Certificate
  • Enter new Service Token

  • 지금부터 각 항목의 값을 얻는 방법을 기록합니다.
  • Kubbernetes cluster name의 획득 방법
  • $ gcloud container clusters list | grep -v "NAME" | awk '{print $1}'
    hello-cluster
    
  • API URL 획득 방법
  • $ kubectl cluster-info | grep 'Kubernetes master' | awk '/http/ {print $NF}'
    https://xx.xx.xx.xx
    
  • CA Ceertificate 획득 방법
  • $ kubectl get secret $(kubectl get secret | grep -v "NAME" | awk '{print $1}') -o jsonpath="{['data']['ca\.crt']}" | base64 --decode
    
       -----BEGIN MY CERTIFICATE-----
       -----END MY CERTIFICATE-----
       -----BEGIN INTERMEDIATE CERTIFICATE-----
       -----END INTERMEDIATE CERTIFICATE-----
       -----BEGIN INTERMEDIATE CERTIFICATE-----
       -----END INTERMEDIATE CERTIFICATE-----
       -----BEGIN ROOT CERTIFICATE-----
       -----END ROOT CERTIFICATE-----
    
  • new Service Token 취득 시 다음과 같은yaml 파일
  • 작성
    gitlab-admin-service-account.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: gitlab
      namespace: kube-system
    ---
    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRoleBinding
    metadata:
      name: gitlab-admin
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
      - kind: ServiceAccount
        name: gitlab
        namespace: kube-system
    
  • gitlab-admin-service-account.yaml의 kubectl apply
  • $ kubectl apply -f gitlab-admin-service-account.yml
    serviceaccount/gitlab created
    clusterrolebinding.rbac.authorization.k8s.io/gitlab-admin created
    
  • 서비스 토큰 수령
  • $ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep gitlab | awk '{print $1}')
    Name:         gitlab-token-2d59g
    Namespace:    kube-system
    Labels:       <none>
    Annotations:  kubernetes.io/service-account.name: gitlab
                  kubernetes.io/service-account.uid: ad6cdff8-5228-4ad6-8f4f-910e29254547
    
    Type:  kubernetes.io/service-account-token
    
    Data
    ====
    ca.crt:     1159 bytes
    namespace:  11 bytes
    token: <サービストークン>
    
  • 다음 항목은 선택 상태를 유지합니다.
  • RBAC-enabled cluster
  • GitLab-managed cluster
  • Namespace per environment
  • 아래 항목 공백 유지
  • Project namespace prefix (optional, unique)

  • 클릭Add Kubernetes cluster(이까지의 설정 저장)
  • 4-3.Gitlab Runner의 Helm Chart 설치

  • gitlab의namspace제작과Gitlab의Helm Repository
  • $ kubectl create namespace gitlab
    namespace/gitlab created
    $ helm repo add gitlab https://charts.gitlab.io
    "gitlab" has been added to your repositories
    
    # Helm Repositoryが追加されたことかどうかは、以下のコマンドで確認できる
    $ helm repo list
    NAME    URL
    gitlab  https://charts.gitlab.io
    

  • 다음 URL에서 임의의 파일로 Giitlab Runner 프로필(values.yaml)을 복사합니다.
  • 여기 복제된 values.yaml의 이름
  • https://gitlab.com/gitlab-org/charts/gitlab-runner/-/blob/master/values.yaml

  • Gitlab 화면에서 클릭Settings

  • 클릭CI/CD
  • Runnesr 오른쪽Expand
  • 클릭
  • Set up a specific Runner manually 부근의 아래 굵은 값을 복사하여 방금 제작한 values.yaml에 붙인다
  • 2.Specify the following URL during the Runner setup: http://gitlab.your-domain.com/
  • 3.Use the following registration token during setup: xxxxxxxxxxxxxxxxx
  • values.yaml 방금 복제한 gitlabUrlrunnerRegistrationToken 이외에 3곳
  • 수정
    values.yaml 수정 부분 발췌문 (줄 번호 포함)
    27 ## The GitLab Server URL (with protocol) that want to register the runner against
    28 ## ref: https://docs.gitlab.com/runner/commands/README.html#gitlab-runner-register
    29 ##
    30 # gitlabUrl: http://gitlab.your-domain.com/
    31 gitlabUrl: http://gitlab.your-domain.com/   #### 1箇所目 ####
    32 
    33 ## The Registration Token for adding new Runners to the GitLab Server. This must
    34 ## be retrieved from your GitLab Instance.
    35 ## ref: https://docs.gitlab.com/ce/ci/runners/README.html
    36 ##
    37 # runnerRegistrationToken: ""
    38 runnerRegistrationToken: "xxxxxxxxxxxxxxxxx"   #### 2箇所目 ####
    
    (略)
    
    101 ## For RBAC support:
    102 rbac:
    103 #  create: false
    104   create: true  #### 3箇所目 ####
    105   ## Define specific rbac permissions.
    106   # resources: ["pods", "pods/exec", "secrets"]
    107   # verbs: ["get", "list", "watch", "create", "patch", "delete"]
    
    (略)
    
    #### 4箇所目 (以下の記事にて解説) ####
    #### 
    143 runners:
    144   config: |
    145     [[runners]]
    146       [runners.kubernetes]
    147         image = "ubuntu:20.04"
    148         privileged = true
    149       [[runners.kubernetes.volumes.empty_dir]]
    150         name = "docker-certs"
    151         mount_path = "/certs/client"
    152         medium = "Memory"
    
    
    185   ## Specify the tags associated with the runner. Comma-separated list of tags.
    186   ##
    187   ## ref: https://docs.gitlab.com/ce/ci/runners/#use-tags-to-limit-the-number-of-jobs-using-the-runner
    188   ##
    189   # tags: ""
    190   tags: "aaa,bbb,ccc,ddd" #### 5箇所目 ####
    

    포인트는values입니다.yaml의 tag를 기록하는 곳.

  • 여러 개의 태그를 설정한 경우 태그 사이를 ,(カンマ)로 분리
  • 태그와 태그 사이에 공간이 필요 없음
  • values.yaml(다시 뜯기)
    180   # tags: ""
    181   tags: "aaa,bbb,ccc,ddd"
    
  • values.yaml를 사용하여 Guitlab Runner
  • 설치
    $ helm install -n gitlab gitlab-runner -f values.yaml gitlab/gitlab-runner
    NAME: gitlab-runner
    LAST DEPLOYED: Thu Nov 26 00:28:14 2020
    NAMESPACE: gitlab
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    Your GitLab Runner should now be registered against the GitLab instance reachable at: "https://gitlab.com/"
    
    # deployedとインストールできている
    $ helm list -n gitlab
    NAME         	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART               	APP VERSION
    gitlab-runner	gitlab   	1       	2020-11-26 00:28:14.721212245 +0000 UTC	deployed	gitlab-runner-0.23.0	13.6.0
    
    # podなども作られている
    $ kubectl get all -n gitlab
    NAME                                               READY   STATUS    RESTARTS   AGE
    pod/gitlab-runner-gitlab-runner-846756c97d-jxhgk   1/1     Running   0          30h
    
    NAME                                          READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/gitlab-runner-gitlab-runner   1/1     1            1           30h
    
    NAME                                                     DESIRED   CURRENT   READY   AGE
    replicaset.apps/gitlab-runner-gitlab-runner-846756c97d   1         1         1       30h
    
    

    6. 임무 수행 상황


    임무가 잘 수행되는지도 확인했습니다!

    [참고] 썼어요.gitlab-ci.yml
    gitlab-ci.yml
    include:
      - project: gkzz/gitlab-ci-common
        ref: master
        file: .failure.yml
    
    before_script:
      - whoami
    #  - docker --version
    #  - kubectl version
    
    stages:
      - test
      - failure
    
    test_k8s:
      stage: test
      script:
        - ls
      tags:
        - always
    
    # 上記のtest_k8sが失敗した場合のみon_failureは実行される
    # 実行される内容は外部プロジェクトの.failure.ymlを読み込む
    # https://gitlab.com/gkzz/gitlab-ci-common/-/blob/master/.failure.yml
    on_failure:
      stage: failure
      extends: .failure
      tags:
        - always
      when: on_failure
    

    7. 앞으로의 과제


    마지막으로 제가 해결할 수 없는 두 가지 과제를 들 수 있도록 허락해 주십시오.
    - GKEと接続したGitlab Runnerでdocker及びkubectlコマンドをどうやって使うか
      - Runnerが使うのはGCPのサービスアカウントなるものっぽくて、それの権限が足りないような気が。。
    - manifestファイルにベタ書きしたくない値をどうやって隠蔽するか
      - 環境変数??
    

    7-1.GKE에 연결된 Gitlab Runner에서 docker 및 kubectl 명령을 사용하는 방법


    [참조] 런너에서 docker 명령을 실행할 때의 작업 오류 메시지
    Running with gitlab-runner 13.6.0 (8fa89735)
      on gitlab-runner-gitlab-runner-846756c97d-jxhgk z3hFb2PB
    Resolving secrets
    00:00
    Preparing the "kubernetes" executor
    00:00
    Using Kubernetes namespace: gitlab
    Using Kubernetes executor with image ubuntu:16.04 ...
    Preparing environment
    00:03
    Waiting for pod gitlab/runner-z3hfb2pb-project-22922816-concurrent-0tm9ff to be running, status is Pending
    Running on runner-z3hfb2pb-project-22922816-concurrent-0tm9ff via gitlab-runner-gitlab-runner-846756c97d-jxhgk...
    Getting source from Git repository
    00:01
    Fetching changes with git depth set to 50...
    Initialized empty Git repository in /builds/gkzz/gke-quickstart/.git/
    Created fresh repository.
    Checking out c1d6cabd as master...
    Skipping Git submodules setup
    Executing "step_script" stage of the job script
    00:00
    $ whoami
    root
    $ docker --version
    /bin/bash: line 103: docker: command not found
    Cleaning up file based variables
    00:00
    ERROR: Job failed: command terminated with exit code 1
    
    [참조] 런너에서 kubectl 명령을 실행할 때의 작업 오류 메시지
    Running with gitlab-runner 13.6.0 (8fa89735)
      on gitlab-runner-gitlab-runner-846756c97d-jxhgk z3hFb2PB
    Resolving secrets
    00:00
    Preparing the "kubernetes" executor
    00:00
    Using Kubernetes namespace: gitlab
    Using Kubernetes executor with image ubuntu:16.04 ...
    Preparing environment
    00:03
    Waiting for pod gitlab/runner-z3hfb2pb-project-22922816-concurrent-09qkjk to be running, status is Pending
    Running on runner-z3hfb2pb-project-22922816-concurrent-09qkjk via gitlab-runner-gitlab-runner-846756c97d-jxhgk...
    Getting source from Git repository
    00:02
    Fetching changes with git depth set to 50...
    Initialized empty Git repository in /builds/gkzz/gke-quickstart/.git/
    Created fresh repository.
    Checking out 8f0eb238 as master...
    Skipping Git submodules setup
    Executing "step_script" stage of the job script
    00:00
    $ whoami
    root
    $ kubectl version
    /bin/bash: line 103: kubectl: command not found
    Cleaning up file based variables
    00:00
    ERROR: Job failed: command terminated with exit code 1
    

    7-2.manfest 파일에 쓰기 싫은 값을 어떻게 숨깁니까


    방안으로 다음과 같은 두 가지 방안을 고려할 수 있다.
    - manifestファイルには環境変数を置き、Gitlab Runnerのジョブを実行する際、環境変数の値に書き換える
    - あるいは環境変数のkeyを参照して値をRunnerが読み込めるようにする
    
    .gitlab-ci.환경 변수가 적힌 manfest 파일을 yml에sed 명령으로 덮어쓰려고 했지만 Syntax Error가 줄었습니다.
    sed에 Syntax Error를 그립니다.gitlab-ci.알짜
    manifests/deployment.yaml.tmpl
      script:
        - pwd
        - ls
        - cp $PWD/manifests/deployment.yml.tmpl $PWD/manifests/deployment.yml 
        - sed -i -e 's|port: <SERVICE_PORT>|port: "${SERVICE_PORT}"|' \
              -i -e 's|targetPort: <FORWARD_PORT>|targetPort: "${FORWARD_PORT}"|' \
              -i -e 's|image: <CONTAINER_IMAGE>:<IMAGE_VERSION>|image: "${CONTAINER_IMAGE}":"${IMAGE_VERSION}"|' \
              -i -e 's|- containerPort: <FORWARD_PORT>|- containerPort: "${FORWARD_PORT}"|' \ 
              $PWD/manifests/deployment.yml
    
    sed 대상의 manfests/deployment.yaml.tmpl
    manifests/deployment.yaml.tmpl
    apiVersion: v1
    kind: Service
    metadata:
      name: hello-python-service
    spec:
      selector:
        app: hello-python
      ports:
      - protocol: "TCP"
        port: <SERVICE_PORT>
        targetPort: <FORWARD_PORT>
      type: LoadBalancer
    
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-python
    spec:
      selector:
        matchLabels:
          app: hello-python
      replicas: 4
      template:
        metadata:
          labels:
            app: hello-python
        spec:
          containers:
          - name: hello-python
            image: <CONTAINER_IMAGE>:<IMAGE_VERSION>
            #imagePullPolicy: Never
            ports:
            - containerPort: <FORWARD_PORT>
    
    이상은 남은 과제다.

    8. GiitLab의 일본 커뮤니티 여러분께


    이 글을 쓸 때 깃랩의 일본 커뮤니티 여러분의 도움이 없었다면 공개될 때까지 도달하지 못했을 것 같습니다.감사합니다.만약 이 보도가 Gitlab의 더 나은 발전을 도울 수 있다면 나는 매우 기쁠 것이다.만세!

    9. 참조

  • 이 글을 집필할 때 참고하는 글
  • GitLab CI/CD on Google Kubernetes Engine in 15 minutes or less
  • Adding and removing Kubernetes clusters | GitLab
  • Quickstart | Kubernetes Engine Documentation | Google Cloud
  • kubernetes에서 Gitlab#kubernetes#gitlab-jp#developer#devops를 마음대로 이동하도록 하겠습니다.
  • kubectl Cheat Sheet
  • GitLab의 지속 포인트(CI) 및 지속 배달(CD)
  • Deploying a containerized web application
  • Gitlab의 일본 커뮤니티
  • GitLab connpass
  • GitLab-JP Slack
  • P.S. 트위터도 있으니까 팔로우 해주면 너무 좋아서 울어:)


    각주
    헬름틸러는 올해 2020년 8월 헬름v2와 함께 추천되지 않았다.Helm v2 Deprecation Timeline ↩︎
    GCP 프로젝트 ID를 확인하는 방법 정보GCP 콘솔 화면에서 대시보드를 열면 오른쪽 그림과 같은 URL이 됩니다.이 URL의 {PROJECT ID} 는 GCP 프로젝트의 ID입니다.(https://console.cloud.google.com/home/dashboard?project={PROJECT_ID}) ↩︎
    주석이 있는 명령을 실행하면 클러스터 이름 헤더에 ${PROJECT ID} 등이 표시되며, 무엇인지 알 수 없습니다.↩︎

    좋은 웹페이지 즐겨찾기