본문 바로가기
CNCF/Spinnaker

Spinnaker 를 통한 Kubernetes환경의 Application 배포(2)-CI/SCM연동

 

앞의 문서(https://cyuu.tistory.com/161) 에서 Spinnaker의 전반적인 구조를 이야기 했었다. 이어서 Spinnaker의 장점중 하나인 다양한 CI /SCM연동을 위한 방법을 이야기 하려고 한다. 해당 문서에서는 Gitlab과 Jenkins연동을 이야기 하려고 한다.

 

Configure a GitLab artifact account

Spinnaker의 artifact는 원격지의 artifact를 이용하여 원격지의 파일 및 이미지를 가져와서 활용할 수 있는 리소스이다.

해당 문서에서는 Gitlab를 artifact로 등록 하여 Git에 저장되어 있는 파일을 호출하여 Kubernetes의 Manifset파일을 Spinnaker에서 직접 관리하는것이 아닌, 외부 Gitlab의 Git으로 관리할 수 있도록 한다.

 

Gitlab Access Token 발행

Spinnaker가 Gitlab에 접근하여 Git에 있는 파일을 엑세스할 수 있도록 Gitlab에서 Access Torken을 생성한다.

User → User Setting → Access Token 메뉴 들어가 아래와 같이 생성할 Token의 이름과 만료일을 설정한다.

Scope 설정은 api와 read_user만 체크 하여 Spinnaker가 API를 통하여 해당 파일만 읽을수 있도록 설정한다.

 

정상적으로 생성되면 발행된 Token을 확인할 수 있고, 해당정보는 미리 저장 해둔다.

Editing Spinnaker Artifact Settings

위에서 생성한 Gitlab Access Token을 hal 명령을 이용하여 등록한다. 우선 hal명령이 수행가능한 Pod에 접속하여 발행한 Token의 정보를 파일로 저장한다.

# kubectl exec --namespace spinnaker-project -it spinnaker-spinnaker-halyard-0 bash
spinnaker@spinnaker-spinnaker-halyard-0:/$ cd ~
spinnaker@spinnaker-spinnaker-halyard-0:~$ pwd
/home/spinnaker
spinnaker@spinnaker-spinnaker-halyard-0:~$ echo "BA-C_DY2Atgn9N2DzXyN" > gitlab_root_token
spinnaker@spinnaker-spinnaker-halyard-0:~$ cat gitlab_root_token
BA-C_DY2Atgn9N2DzXyN

hal명령을 이용하여 artiface 설정 및 gitlab artiface를 사용할 수 있도록 enable 하고, 등록된 token파일을 $ARTIFACT_ACCOUNT_NAME 변수에 등록되어 있는 이름으로 등록 하고 편집된 설정을 배포 한다.

spinnaker@spinnaker-spinnaker-halyard-0:~$ ARTIFACT_ACCOUNT_NAME="gitlab-root-access"
 
spinnaker@spinnaker-spinnaker-halyard-0:~$  hal config features edit --artifacts true
 
spinnaker@spinnaker-spinnaker-halyard-0:~$  hal config artifact gitlab enable
 
spinnaker@spinnaker-spinnaker-halyard-0:~$  hal config artifact gitlab account add $ARTIFACT_ACCOUNT_NAME  --token-file /home/spinnaker/gitlab_root_token
 
spinnaker@spinnaker-spinnaker-halyard-0:~$  hal deploy apply
 
spinnaker@spinnaker-spinnaker-halyard-0:~$

"hal config" 명령을 사용하여 변경된 사항에 대하여 확인한다.

spinnaker@spinnaker-spinnaker-halyard-0:~$ hal config
...
 
artifacts:
  bitbucket:
    enabled: false
    accounts: []
  gcs:
    enabled: false
    accounts: []
  oracle:
    enabled: false
    accounts: []
  github:
    enabled: false
    accounts: []
  gitlab:
    enabled: true
    accounts:
    - name: gitlab-root-access
      tokenFile: /home/spinnaker/gitlab_root_token
...

Create Test Gitlab Project For Spinnaker

Spinnaker가 Gitlab의 등록되어 있는 프로젝트에 접근하여 사용할 Manifset파일을 생성해야 한다.

아래와 같이 "test-spinnaker-project"이름으로 프로젝트를 생성한다.

생성된 프로젝트에서 Gitlab 웹상으로 간단하게 파일을 생성하기 위해서 "New File" 아이콘을 클릭한다.

이제 간단하게 nginx container가 동작하는 gitlab-test 이름의 pod를 생성하는 Manifset파일을 등록 하여 본다

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  labels:
    app: gitlab-test
  name: gitlab-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gitlab-test
  template:
    metadata:
      labels:
        app: gitlab-test
    spec:
      containers:
        - image: 'nginx:1.7'
          name: gitlab-test

이제, Spinnaker에서 등록된 Gitlab 의 인증정보를 이용하여, Git의 정보(Repository 주소, 브런치 등...)를 추가해야 하는데, 앞에서 이야기 했듯이 Spinnaker는 Gitlab의 API를 통하여 통신하기 때문에 API주소를 확인 해야 한다. 기본적인 구조는 "http://[ GITLAB HOST ]//api/v4/..." 으로 여기서 확인해야 할것은 Project의 ID를 직접 확인해야 한다. 아래와 같이 Token을 이용하여 curl로 호출하면 위에서 생성한 Project의 ID가 1이라는것을 확인할 수 있다.

$ ACCESS_TOKEN="BA-C_DY2Atgn9N2DzXyN"
$ SUBJECT="test-spinnaker-project"
$ GITLAB_HOST="http://192.168.193.132"
$ GITLAB_REQUEST="${GITLAB_HOST}/api/v4/search?scope=projects&search=${SUBJECT}"
$ curl -s --request GET --header "PRIVATE-TOKEN:${ACCESS_TOKEN}" ${GITLAB_REQUEST} | jq
[
  {
    "id": 1,
    "description": "",
    "name": "test-spinnaker-project",
    "name_with_namespace": "Administrator / test-spinnaker-project",
    "path": "test-spinnaker-project",
    "path_with_namespace": "root/test-spinnaker-project",
    "created_at": "2019-11-29T00:49:53.760Z",
    "tag_list": [],
    "ssh_url_to_repo": "git@gitlab-79f59ccf55-m2qsm:root/test-spinnaker-project.git",
    "http_url_to_repo": "http://gitlab-79f59ccf55-m2qsm/root/test-spinnaker-project.git",
    "web_url": "http://gitlab-79f59ccf55-m2qsm/root/test-spinnaker-project",
    "readme_url": null,
    "avatar_url": null,
    "star_count": 0,
    "forks_count": 0,
    "last_activity_at": "2019-11-29T00:49:53.760Z",
    "namespace": {
      "id": 1,
      "name": "Administrator",
      "path": "root",
      "kind": "user",
      "full_path": "root",
      "parent_id": null,
      "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
      "web_url": "http://gitlab-79f59ccf55-m2qsm/root"
    }
  }
]

위에서 확인한 Project ID를 이용하여 실제로 Spinnaker에서 확인하는 주소는 아래와 같은 형태가 된다. 여기서, File Name은 Project에 등록된 File위치로 Urlconde 되어 사용된다.  그렇기 때문에 gitlab-test.yaml 파일을 확인해야 하는 주소로 아래와 같이 등록되야 한다.

http://[ GITLAB HOST ]/api/v4/projects/[ PROJECT ID]/repository/files/[FILE NAME]/raw

==> http://192.168.193.132/api/v4/projects/1/repository/files/gitlab-test.yaml/raw

https://docs.gitlab.com/ee/api/repository_files.html#get-raw-file-from-repository

Create Spinnaker Pipeline

해당문서의 Spinnaker는  Kubernetes v2 Cloud Driver를 이용하여 배포될수 있도록 구성 되어있다. 해당 Driver 를 이용하여 테스트를 진행한다.

Spinnaker Deck에 접속하여 Application → Actions → Create Application 아이콘을 클릭하여 테스트를 위한 Application을 만든다.

Name 과 Owner Email필드를 작성 하여 Create버튼을 눌러 Application을 만들어 본다.

생성된 Application에서 아래와 같이 Pipeline을 생성한다.

Expected Artifacts 에서 가장 먼저 hal 명령어를 이용한 Account정보인 gitlab-root-access를 선택 하고, Use Default Artifact 설정을 하여 Private한  Gitlab의 API정보를 추가 한다. 만약 브런치가 틀릴경우 브런치 정보도 같이 추가 한다.

기본 연동은 완료 되었다. 해당 설정을 기반으로 "Add stage"버튼을 클릭 하여 Deploy(Manifest)타입의 Stage를 생성 한다.

Deploy (Manifest) Configuration 설정에서 Text로 되어 있던 Manifset source의 정보를 Artifact로 변경하면 설정에서 확인한 "gitlab-artifact"의 정보를 확인할 수 있다. 해당 내용으로 설정을 업데이트 한다.

"Start Manual Execution"아이콘을 클릭하여 수동으로 Pipeline을 실행하여 본다. 실행이 되면 등록된 Artifact의 정보를 확인할 수 있다.

배포가 완료되면 Gitlab에서 등록한 Manifest기반으로 Pod가 배포된것을 볼수 있다.

Integrating Spinnaker with Jenkins

Jenkins user token setting

 Spinnaker가 Jenkins의 특정 User로 인증하여 특정 Job이 발생하면 연속적으로 Pipeline을 실행 하거나 반대로 Spinnaker가 Jenkins 로 Job을 수행 하기 위하여 해당 User의 API Token을 생성한다.

Jenkins관리 →   Manage Users →  [  Spinnaker가 Jenkins에 접속할 User ] → 설정 

API Token →  Add new Token 클릭하여 해당 User의 Token을 생성 한다. 

Toekn의 이름을 임의로 지정하여 Generate 버튼을 클릭한다.

생성된 Token을 확인 하며, Spinnaker에서 사용할 수 있도록 미리 다른곳에 저장한다.

Jenkins api setting

"Strict Crumb Issuer" Plugin을 Plugin Manager에서 설치 한다.

Jenkins관리 →   Configure Global Security  에서 아래와 같이 CSRF Protection설정을 진행 한다.

Jenkins test job

Jenkins에서 Job이 종료되면 Spinnaker에서 해당 결과를 확인하여 CD작업을 진행하도록 Test Job을 생성한다.

간단하게 아래와 같이 커맨드만 실행될수 있도록 한다.

Spinnaker setting

Spinnaker 대시보드에 들어가서 Application생성을 한다.

Application → Action → Create Application 아이콘을 클릭하면 레이어 팝업에서 생성하려는 Application의 정보를 추가 한다

아래와 같이 추가하고 Create 아이콘을 클릭 한다.

아직 Pipeline설정이 없기 때문에 Configure a new pipeline 을 클릭하여 신규 Pipeline을 생성한다.

아래와 같이 "test-pipelin"이름의 Pipeline을 생성한다.

Pipeline의 실행을 Jenkins Job을 선택 하여 해당 Job이 종료 되면 자동으로 Spinnaker의 Pipeline이 실행 되기 위해 추가 해야 한다.

Spinnaker 웹상으로는 추가할 수 없고 Cli를 통하여 진행 하여야 한다.

helm으로 배포한 spinnaker pod들중 halyard Pod에 접속하여 진행 해야 한다.

halyard에서 config명령을 실행하면 현재 설정을 확인할 수 있다. ci→ jenkins 에 설정이 아직 활성화 안되어 있다.

$  kubectl exec --namespace spinnaker-project -it spinnaker-spinnaker-halyard-0 bash
spinnaker@spinnaker-spinnaker-halyard-0:/workdir$ hal config
...
 
timezone: America/Los_Angeles
ci:
  jenkins:
    enabled: false
    masters: []
  travis:
    enabled: false
    masters: []
  wercker:
    enabled: false
    masters: []
  concourse:
    enabled: false
    masters: []
  gcb:
    enabled: false
    accounts: []

위에서 확인한 config를 overwrite하여 jenkins master서버의 정보를 추가 한다.

이때 address를 외부 ExtrernalIP를 추가 할수 있지만,  Jenkins Master Pod의 Service DNS를 추가하는 것이 관리에 편할 것이다.

그리고 password를 입력해야 하는데, 이때 위에서 생성한 Jenkins API Token의 값을 넣은다.

추가적인  CLI 활용은 https://www.spinnaker.io/reference/halyard/commands/ 페이지를 참조 한다.

## https://www.spinnaker.io/reference/halyard/commands/#hal-config-ci-jenkins-enable
$ hal config ci jenkins enable
## https://www.spinnaker.io/reference/halyard/commands/#hal-config-ci-jenkins-master-add
$ hal config ci jenkins master add Jenkins-master --address http://jenkins.jenkins-project.svc.cluster.local:8080  --csrf true --username admin --password
## https://www.spinnaker.io/reference/halyard/commands/#hal-config-edit
$ hal config edit --timezone Asia/Seoul

이제 반영된 설정을 확인 하면 저장된 password(API Token)와 주소 등  Jenkins의 설정 및 변경된 Timezone을 확인할 수 있다.

마지막으로 "hal deploy apply" 으로 변경된 설정을 배포한다. 배포를 진행하면 orca,deck, clouddriver등 모든 컴포넌트에 해당 내용을 반영하게 된다.

$ hal config
...
timezone: Asia/Seoul
ci:
  jenkins:
    enabled: true
    masters:
    - name: Jenkins-master
      permissions: {}
      address: jenkins.jenkins-project.svc.cluster.local
      username: admin
      password: 117f144db430f---------------
 
  travis:
    enabled: false
...
$ hal deploy apply

이제 configuration 설정에서 Add Stage아이콘을 클릭하여 Deploy(Manifest)타입의 Stage를 생성하여 본다.

우선 연동만 진행하기 위해서 아래와 같이 간단한 ReplicaSet 매니패스트를 작성하여 연동이 Jenkins Build연동이 종료되면 Spinnaker PipeLine이 실행할 수 있도록 한다.

아래와 같이 Pipelien의  Trigger가 활성화 되어 있는것을 확인 한다.

Jenkins에서 앞에서 생성한  test-job을 수동으로 실행하여 본다.

Jenkins 빌드가 종료되면 Spinnaker에서 Pipeline이 자동으로 실행 되고 SUCCEED 상태로 변경된다.

마지막으로 배포된 Pod를 Cli를 통하여 확인 하여 본다.

$ kubectl  get pod
NAME                                READY   STATUS      RESTARTS   AGE
frontend-v000-5n84l                 1/1     Running     0          2m23s
...

 

Ref

반응형

'CNCF > Spinnaker' 카테고리의 다른 글

Spinnaker 를 통한 Kubernetes환경의 Application 배포(1)  (0) 2019.12.25