data engineering

git push - jenkins - docker build자동화, 간단한 카운터 구현

qkqhxla1 2021. 1. 24. 18:20

이미 구글에 jenkins docker build and publish, jenkins docker 배포 등으로 검색해보면 많은 좋은 한글 자료가 있다. 

https://medium.com/hgmin/jenkins-github-webhook-3dc13efd2437 이글이 가장 도움 잘 됐고 현재 한 작업이랑 큰 차이도 없음.

 

현재 도커 이미지 만드는 프로세스를 예전에 만들었었는데.. 지식이 많이 없기도 했고 그땐 젠킨스를 안 쓰기도 했고 해서 도커 이미지 만드는 프로세스가 복잡하다.

1. 리모트 깃헙 서버에 푸시해서 소스코드를 저장해놓음.

2. 푸시한 소스를 로컬 깃에서 pull해서 최신 버전으로 업데이트.

3. 2번에서 pull한 최신 소스를 참조해서 도커 이미지를 로컬에서 직접 빌드.

 

인데 매번 git pull 받기도 귀찮고, 이젠 젠킨스도 쓰고 소스들을 새 깃으로 옮길일이 있어서 도커 빌드도 자동화를 하기로 마음먹었다. 새로 만드는 배포 자동화 파이프라인은

 

1. 리모트 서버에 푸시함.

2. 젠킨스에서 깃 푸시 이벤트를 받아서 자동으로 도커 이미지를 만듦.

 

이다. 푸시만 하면 추가로 뭔가를 안해도 도커 이미지를 만들려고 한다. 회사 깃인 깃 엔터프라이즈를 사용할 것이므로 다른 사람과 환경이 좀 다를 수도 있음.

 

 

1. github에 webhook등록.

이처럼 github에서 Settings의 Hooks에 '내 젠킨스 주소'/github-webhook/을 불여줘서 등록해준다.

 

 

2. 젠킨스에서 잡을 만든다.

 

1) 깃헙 프로젝트 주소 입력

2) deploy키 등록

3) 빌드 유발에서 훅 트리거 체크

4) Build에서 Docker Build and Publish를 만듦.

5) 오른쪽 아래에 고급 탭이 있는데 누른다음 Dockerfile Path를 지정해주자.

Dockerfile Path는 등록한 깃의 프로젝트 루트부터 시작한다. 내 프로젝트의 루트에는 doker라는 디렉터리가 있고, 그 안에 Dockerfile이라는 디렉터리가, 그 안에는 test.Dockerfile이 있다. 경로를 주의하자. 

Dockerfile에서 COPY를 쓸 일이 많은데, 'COPY . /경로' 처럼 현재 위치의 모든것을 /경로로 복사하는 경우가 있다. 이때 현재 위치는 docker build를 실행시키는 위치이다. 젠킨스에서 docker build를 할 경우에 현재 위치는 프로젝트의 루트이므로,(위의 Dockerfile Path와 동일.) COPY를 사용할시 path에 유의하자.

 

조금 더 적자면 젠키스의 Docker Build and Publish이름 그대로 docker build와 docker push를 해준다고 보면 된다. 그리고 그에 필요한 Dockerfile은 깃에 넣었으며, 참조할 위치는 저기에 인자로 준다.

 

3. 깃헙에 푸시를 했을대 젠킨스로 트리거링이 제대로 되는지 확인한다.

 

4. 트리거링이 되었으면 이미지가 제대로 만들어지는지 확인한다.

 

% 참고로 맨 마지막에 젠킨스의 빌드 후 조치에서 Slack Notification을 설정해놓으면 빌드 실패했을때나 성공했을시 알람이 와서 보기 편하다.

 

--------------------------------------------------------------------------------------------------------------

+ vault를 사용한 기본적인 카운터 구현.

도커 버전을 좀 더 세분화하고자 매번 빌드시에 버전을 뒤에 붙이려고 한다. 단순하게 1씩 증가하는 카운터를 만들어서 붙이면 되고 구현하는 방법은 상당히 많을건데. 레디스에 카운터용으로 만들어서 참조할까 하다가 적당한 레디스가 없고 젠킨스에서 최대한 간단하게 쉘로만 구현하길 원했기에 생각하다가 vault에 변수를 하나 만들어두고 카운터로 쓰기로 했다.

 

1. 젠킨스에 password parameter로 VAULT_SECRET_KEY를 받음.

2. www.vaultproject.io/docs/auth/approle 를 참조해서 알수 있듯이 

$ curl \
    --request POST \
    --data '{"role_id":"988a9df-...","secret_id":"37b74931..."}' \
    http://127.0.0.1:8200/v1/auth/approle/login

이런식으로 요청을 보내서 client token을 받아올수 있다. 이걸 사용해서 아래처럼 환경변수에 저장해둔다.

VAULT_CLIENT_TOKEN=`curl --request POST --data "{\"role_id\":\"123455b-93ab-1e1e-ab7e-sdf2fe2f2ef23\",\"secret_id\":\"$VAULT_SECRET_ID\"}" http://127.0.0.1:8200/v1/auth/approle/login | jq -r '.auth.client_token'`

``로 curl을 실행시키고 내가 위에서 환경변수로 넣은 $VAULT_SECRET_ID를 사용하기 위해 "로 감싸고 내부의 "를 \로 이스케이핑해준다.(내부에 홑따옴표를 사용하면 환경변수를 못 가져감)
결과값은 json이 리턴되며 , auth라는 키 안의 client_token이라는 키 값이므로 jq로 '.auth.client_token'으로 가져온다. jq에 -r옵션이 있는데 -r옵션을 주지 않으면 문자열이라는 의미로 VAULT_CLIENT_TOKEN에 앞뒤로 "가 붙게 된다.

이제 임시 토큰을 가져왔으니 임시 토큰을 사용해서 VAULT에서 카운터 변수를 가져와야 한다.

CURRENT_VERSION=`curl -H "X-Vault-Token: $VAULT_CLIENT_TOKEN" -X GET https://VAULT_주소/v1/secret/role이름/키값 | jq -r '.data.docker_version'`

이처럼 가져온 임시 토큰을 사용해서 vault에 접근해 내가 넣어둔 role의 키값을 가져온다. 
json이 리턴되고, data안에 docker_version이라는 키값에 내가 1을 설정해놨다. 마찬가지로 jq로 가져온다.

NEW_VERSION=$(($CURRENT_VERSION+1))

# write new version to vault
curl -H "X-Vault-Token: $VAULT_CLIENT_TOKEN" -H "Content-Type: application/json" -X POST -d "{\"docker_version\":\"$NEW_VERSION\"}" https://VAULT_주소/v1/secret/role이름/키값
DOCKER_IMAGE_TAG=$NEW_VERSION

NEW_VERSION은 말그대로 현 버전에서 +1한 값이고 버전 값을 가져왔으니 1 증가시킨 NEW_VERSION을 VAULT에 다시 저장해준다.
간단하게 개발 끝