Jenkins 와 Docker 그리고 AWS CLI 삽질기 정리하기

박성룡 ( Andrew park )
11 min readMar 16, 2020

--

최근에 Jenkins 서버를 분리할 일이 생겼는데, Jenkins 를 다시 설정 하면서 배웠던 삽집기를 정리 해보고자 한다.

처음에는 Jenkins 를 단독으로 설치하려고 하였으나, 이참에 Docker 를 이용해서 자동화된 테스트까지 돌리고 싶어서, Docker 위에 Jenkins 를 설치하기로 마음 먹었다.

Jenkins

Jenkins 는 CI (Continuous Integration) tool 이다.

작업된 소스 코드를, 빌드 하고 테스트 하고 배포 하는 과정을 통합하고, 이를 자동화할 수 있게 도와준다.

Docker

Docker 는 환경의 구성을 Image 로 만들어 두고 이를 Container 를 이용해 항상 동일한 환경을 제공해주는 Platform 이다.

여기서 Image 는 세팅 환경이고, Container 는 실행 환경이라고 볼 수 있다.

Image 로 Jenkins 를 세팅하고, Container 에서 Jenkins 를 구동한다.

Docker 를 이용해 Jenkins 를 세팅하게 되면, Docker 내부의 Docker 를 만들어서 일정한 테스트 환경을 유지하는데 사용할 수 있다.

AWS CLI

AWS CLI 는 AWS 에서 제공하는 API 를 사용할 수 있게 도와주는 툴이다.

Jenkins 에서 build 한 파일들을 AWS 환경에 배포하는 용으로 사용 할 수 있다.

진행과정

아래 과정을 거치며, Jenkins 를 세팅하였다.

하지만 아래 과정까지 많은 삽질과 구글링이 있었다.

  1. Docker 설치
  2. Jenkins image 확인
  3. Dockerfile 에 AWS CLI 세팅
  4. Docker-compose 세팅
  5. AWS CLI 설정파일 적용
  6. Jenkins 실행 및 plugin 설치

Docker 설치

  1. apt-get update
  2. apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
  3. curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  4. apt-key fingerprint 0EBFCD88
  5. add-apt-repository “deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable”
  6. apt-get update
  7. apt-get install docker-ce docker-ce-cli containerd.io

위 과정은 os 와 hw 마다 설치 방법이 다를 수 있다.

7번의 docker-ce 부분이 실제 docker 를 설치하는 부분이며, 이전 과정은 설치를 준비하는 과정이다.

Jenkins image 확인

jenkins 도 있지만 2.60.3 이후에 더 이상 업데이트가 종료되었다. jenkins/jenkins 는 최신 jenkins 버전을 지원한다.

docker pull jenkins/jenkins:lts

jenkins/jenkins 는 Jenkins 의 기본 이미지만을 제공하기 때문에, 추가적인 작업이 필요하다면, 따로 Dockerfile 을 세팅해야 한다.

Dockerfile 에 AWS CLI 세팅

Jenkins 를 이용해서 AWS 에 배포를 위한 aws-cli 가 필요했다.

외부의 명령어에 접근하거나 aws-cli container 를 설정하고, linking 하는 방법을 적용하지 못하여, container 내부에 aws-cli 를 설치하기로 하였다.

이를 위해 docker image 를 위한 Dockerfile 을 만들었다.

// DockerfileFROM jenkins/jenkins:ltsMAINTAINER 유저정보USER rootRUN apt-get update
RUN apt install python3-pip -y
RUN pip3 install awscli — upgrade

jenkins/jenkins:lts 이미지를 사용하고, RUN 으로 pip 를 이용하여 awscli 를 설치하였다.

apt install awscli 로 바로 설치할 수 있지만, 설치중에 권한 요청을 해결하지 못하여, pip 를 이용 하였다.

작업된 Dockerfile 은 docker build 명령을 실행하여 Image 를 생성할 수 있다. 이 이미지는 고정된 환경이 되며, dockerfile 만 있으면, 다른 서버 환경에서도, 같은 환경의 image 를 만들 수 있게된다.

이때 tag 를 지정할 수 있는데, 이 tag 로 docker container 를 생성 할때 image 를 선택할 수 있다.

  1. docker build -tag jenkins_awscli:0.1 .
  2. docker images

docker images 명령어는 저장된 images 들을 확인할 수 있다.

- REPOSITORY : jenkins_awscli
- TAG : 0.1
- IMAGE ID : `image_id`
- CREATED : 2 days ago
- SIZE : 1.02GB

Docker-compose 세팅

생성한 Image 를 이용해서, Container 를 생성 하기위해, docker run jenkins_awscli:0.1 명령어를 사용할 수 있다.

하지만 이 명령어를 docker-compose 를 이용하여, 하나의 파일로 관리할 수 있다.

docker-compose 는 Container 실행에 필요한 옵션 등을 docker-compose.yml 파일을 통해 관리할 수 있다.

version: '2'services:
jenkins_awscli:
image: jenkins_awscli:0.1
volumes:
- ~/jenkins:/var/jenkins_home
- ~/.aws:/root/.aws
ports:
- "8081:8080"
- "50000:50000"
user: root

version 은 1, 2, 3 이 있으며, docker-compose 에서 사용하는 파일의 버전이 된다.

services 밑에 container 의 name 을 지정할 수 있다.

image 로 이미지를 선택하고, volumes 을 세팅할 수 있는데, 외부 폴더를 Container 내부처럼 쓸수 있도록 외부 path:container path 로 설정할 수 있다.

volumes 은 container 내에서 생성하는 데이터의 위치를 외부로 지정하므로써, 만약 container 를 지우거나 종료와는 무관하게 데이터를 관리할 수 있다.

여기서는 jenkins 와 awscli 에서 사용할 volume 을 설정하였다.

ports 는 외부:내부 에서 사용할 port 를 지정해 준다. 여기서 8081 으로 세팅하였기 때문에, 8081 으로 접근하면, container 의 8080 을 바라보게 된다.

이제 docker-compose 를 설치하고, docker-compose up 으로 docker-compose.yml 을 가지고, container 를 생성할 수 있다.

  1. apt install docker-compose
  2. docker-compose up -d
  3. docker ps -a

docker ps 로 생성된 container 를 확인할 수 있다.

AWS CLI 세팅

Jenkins Container 에 awscli 를 설치 하였기 때문에, Container 내부에서 aws 명령을 실행할 수 있다.

aws-sdk 에서 aws token 을 사용해야 한다면, awscli 에서 credentials 을 세팅해주는것이 좋다.

여기서는 ~/.aws 폴더 밑을 참조 하도록 하였으므로, 해당 폴더에 credentials 을 생성해 준다.

[default]
aws_secret_access_key = <key>
aws_access_key_id = <key>

[default] 은 프로파일 이름으로 기본값이며, aws_secret_access_keyaws_access_key_id 에 aws 에서 발급 받은 토큰을 세팅할 수 있다.

Jenkins 실행 및 plugin 설치

docker-compose up 으로 container 를 올리면, Jenkins 가 실행 되면서, 인증키를 알려준다.

docker logs CONTAINER_ID 명령어를 이용하면, 해당 Container 의 가장 최근 로그를 보여주는데, 만약 로그에서 찾을 수 없다면,

docker exec -it -u 0 “CONTAINER_ID” /bin/bash 로 Container bash 로 접근하고,

cat /var/jenkins_home/secrets/initialAdminPassword 으로 인증키를 확인할 수 있다.

만약 CONTAINER_ID 를 모른다면, docker ps -a 로 확인 할 수 있다.

인증처리가 완료되면, 권장 plugin 을 설치할 수 있는데, 만약 설치대신 Unable to connect to Jenkins 이 뜬다면, 50000 포트가 연결되지 않은것이므로, netstat -tnlp 로 docker 에 해당 port 가 세팅되어 있는 확인한다.

그리고 plugin 설치 가 전부 다 실패 한다면, volumes 으로 Jenkins Container 에게 공유한 폴더를 container 가 접근하지 못하는 것이므로 chmod 666 으로 접근 권한을 풀어준다.

Project 세팅중 만났던 이슈사항

설치후 실제 project 를 세팅 하다 보니 평소에는 만나지 못했던 이슈를 만날 수 있었다.

git ssh

Jenkins 에서는 ssh 를 이용해 git 을 연결할 수 있다.

ssh-keygen -t rsa -f path/name_rsa 으로 SSH 공개키 (name_rsa.pub) 와 비공개키 (name_rsa)를 만들 수 있다.

  1. name_rsa.pub 는 github 이나 bitbucket 에 ssh key 로 세팅할 수 있다.
  2. name_rsa 는 Jenkins 에 Global credentials (SSH Username with private key) 에 세팅할 수 있다.

이때 암호를 지정하게 되면, name_rsa 내부에 Proc-Type, DEK-Info 가 세팅되어 있는데, SSH Username with private key 에서 Passphrase 에 비밀번호를 입력해야 한다.

암호를 지정했는데, 비밀번호가 입력되지 않았다면, permission denied 가 뜬다.

NodeJS Plugin

NodeJS Plugin 를 이용하면, 빌드 하기 전의 node 환경을 세팅할 수 있다.

빌드 환경에서 Provide Node & npm bin/ folder to PATH 를 세팅하고, 사용하면 되는데 만약 angular cli 같은 globar tool 을 사용한다면, 추가 세팅이 필요하다.

NodeJS Plugin 에서 Global Tool Configuration 에서 사용할 Node 를 세팅하고, Global npm packages to install 옵션에 @angular/cli 를 추가하여 사용할 수 있게 한다.

Slack Notice Plugin

빌드가 끝난후 Slack 으로 notice 를 줄수 있는데, 이때 문서롤 보면, 2.8 버전 기준으로 작성되어 있다.

20/03/16 기준으로 slack 문서와 jenkins plugin (2.37) 문서가 다르다.

먼저, Slack 에 Jenkins CLI 를 세팅한다.

그리고 Jenkins 의 plugin 에 Slack Notice Plugin 을 설치한다.

Global credentialsSecret text 으로 Slack Jenkins bot 에서 발급 받은 token 을 입력한다.

Jenkins 환경 설정에 들어가면, Slack 에 Workspace, Credential, Default channel 이 있는데,

각각 아래 정보를 입력하면 된다.

- Workspace : Team Subdomain
- Credential : Global credentials (Secret text)
- Default channel : Channel or Slack ID

--

--