아래는 Jenkins 도입 과정과, 겪었던 시행 착오들에 대한 과거 기록들이다.
- 배포 과정은 아래와 같다.
- Master 브랜치에 커밋이 발생함을 감지 (Merge 커밋)
- Matser 브랜치의 소스 코드를 가져와 Docker 이미지 빌드
- 빌드된 이미지를 Private Registry에 푸시
- 배포할 서버에 .env 파일과 docker-compose.yml 파일 전송
- 배포할 서버에 빌드된 이미지를 pull 하여 컨테이너 구동
- 이를 위해선 Github 연동과 Credentials 생성이 우선이다.
Github 설정
Github SSH KEY 연동
ssh-keygen -t rsa -f jenkins
- .pub 키를 복사해서 계정/조직의 ssh 키를 추가해 복사해 넣는다
- Jenkins Credentials 추가
- Kind: SSH Username with private key
- ID 임의 설정
- username: 깃허브 계정명
- Private key: 생성된 jenkins 키 내용 전체 복사 붙여넣기
- 이렇게 설정하니, Host key verification failed. 라고 하며 git fetch 실패 에러가 뜨더라
- Jenkins Secure 설정
- 위 에러를 해결하기 위해 아래처럼 했다
- Git Host Key Verification Configuration 설정 변경
- Accep First connection 설정
Github Access Token
- 깃헙 계정 에서 personal access token 생성
- settings - developer settings - personal access tokens - tokens(classic)
- Classic Token 생성하기
- exiration: No expiration
- repo
- admin:org
- admin:repo_hook
- 생성되는 값 복사해두기
Github WebHook 설정
- 레포지토리/조직의 설정으로 이동
- 탭 중 webhook 선택
- Add webhook 선택
- url에 "${jenkins-url}/github-webhook/"입력
- 생성하면, 성공 시 초록색 체크와 함께 완료된다
- 실패 시, 이미 실패한 요청을 선택하여 redeliver하면 해결되더라
Jenkins 설정
Credential 설정
- Jenkins 관리로 이동
- Credentials - Stores scoped to Jenkins의 System 클릭 - Global credentials 클릭 -> Add Credentials 클릭
- 깃허브 레포지토리 / 조직 접근 키 설정 - 깃헙 웹훅 사용 용
- Kind를 Secret Text로 설정
- Secret에 위에서 복사한 Personal Access Token 값 붙여넣기
- ID: 마음껏 설정 - 나중에 이 값으로 깃헙 연동해야 하므로 알 수 있게끔 설정
- Description: 설명
- 개인 계정 - 아이템에서 깃헙 레포지토리 접근 용
- Kind를 Username with password
- username: 깃허브 계정 명
- password: Personal Access Token 값
- ID: 마음껏 설정
- Description
- 서버 - 접속 SSH 키 세팅
- Kind를 Username and SSH
- private key에 SSH private key 입력
- 환경변수 파일 - 배포시 서버에 파일 전송.
- Kind: Secret File
- Id: 서비스 별로 분리할 수 있게끔 설정
- 환경변수 파일 업로드
Github webhook 설정
- Jenkins 관리로 이동
- System 선택
- 하단의 Github 탭의 Github Server 클릭
- Name에 아무거나 임의로 입력
- API URL은 건들지 말고
- Credentials 에 위에서 secret text로 생성한 Credentials 선택
- Manage Hooks 체크
- Test connection 선택하여 연동 여부 체크
Jenkins Item 설정
- 실질적인 파이프라인 설정 내용
- 새로운 Item 클릭
Jenkinsfile로 사용할 시
- 소스코드 내에 Jenkinsfile을 위치시켜 이를 사용해서 빌드하는 방법
- Jenkinsfile에서 사용할 키는 위의 SSH Credential
- pipeline 선택
- Github project 체크
- project url 선택: git@github.com:{브랜치명}
- Github hook trigger for GITScm polling 선택
- pipeline 변경
- Definiton을 Pipeline script from SCM 선택
- SCM을 Git 으로 변경
- Repository URL에 깃헙 레포 주소 입력
- Credentials: 깃허브 SSH Credential 선택
- Branch Specifier: 연동할 브랜치
- 이제 master 브랜치로 커밋이 감지될 때 마다 Jenkins가 레포 안의 Jenkinsfile을 감지해서 입력된 순서대로 동작할거다
Jenkins 파일 사용 안할 시
- freestyle project 체크
- 소스코드 관리 - Git 체크
- Repository Url: 깃헙 레포 주소 입력
- Credentials
- 깃허브 SSH Credential 선택
- master: 연동할 브랜치 설정 * 빌드 유발
- Github hook trigger for GITScm polling 선택 * 저장`
- 이제 Build Steps에 과정을 입력한다.
Plugins
- Docker common: 도커 통합 플러그인
- Docker Pipeline
- SSH Pipeline steps
- SSH Server
- Publish Over SSH
에러 해결 - 1 docker.sock 퍼미션
- Jenkins 빌드 과정에서 도커 이미지 빌드 내용이 있었다
- 여기에서 permission denied while trying to connect to the Docker daemon socket 에러 발생
- 결국 호스트의 var/run/docker.sock을 마운트하고 있기 때문이므로, 이를 수정해주었다.
# 새로운 계정 생성 sudo adduser jenkins
권한 부여
sudo usermod -a -G docker jenkins
- 그럼에도 해결되지가 않았다
- 누군가는 chmod 666으로 변경하면 된다지만, 이럴 경우 권한이 너무 열려버려서 위험해질 수 있다고 한다.
- 아무튼 확인 결과 컨테이너 내부의 docker.sock은 root:999 으로 잡혀있었다.
- root:docker 혹은 docker:1000이 되어야 할텐데
- 때문에 컨테이너 내부 접근해서 직접 퍼미션 체크를 해 줬다.
sudo docker exec -it -u root jenkins-host /bin/bash
chown root:docker /var/run/docker.sock
에러 해결 - 2 bad crum
- 사실 이 문제는 왜 해결됐는지 원인 파악이 다 되지 않았다.
- 내가 시도한 방식은 아래와 같다.
curl -v -X GET https://{jenkins_url}/crumbIssuer/api/json --user dong:samquinnWkd1
curl -X POST https://{jenkins_url}/job/manage/credentials/store/system/domain/_/createCredentials/build --user dong:samquinnWkd1 -H 'Jenkins-Crumb: 9e107e40a5f7b6597e4020a4680bdda68b6b04c480aba07311166caa3bf98f9f'