시나리오
1) pycharm, VScode등 IDE 에서 코드 commit 후 push
2) gitlab webhook으로 jenkins에 전달
3) jenkins에서 Jenkins 파이프라인 스크립트와 Dockerfile에 정의 된 대로 docker image로 빌드
4) 빌드된 Docker 이미지 nexus 레지스트리에 전달(Jenkins 파이프라인 스크립트에 정의)
5) 레지스트리에서 운영 서버로 이미지 push후 실행
Fast API로 작은 python 프로젝트를 만들고 도커 빌드 및 운영 서버에 배포하기 위해 CI/CD 파이프 라인을 구축했다.
1. GitLab과 Jenkins 연동하기
1) GitLab 설치 & Jenkins 설치하기
(외부링크 첨부)
2) Jenkins 설정
- GitLab과 Docker , SSH 관련 플러그인 설치
- Jenkins > Jenkins 관리 > Plugins 클릭
- Available plugins > GitLab 검색 > 설치할 플러그인 체크 후 > Install 버튼 클릭
설치할 플러그인 목록
- Git
- Git client
- Generic Webhook Trigger
- GitLab
- GitLab API
- Docker plugin
- Docker Pipeline
- SSH
- Credentials 등록하기
- Jenkins > Jenkins 관리 > Security : Credentials 클릭
- Stores coped to Jenkins > Domains : Add credentials 클릭
- GitLab에서 personal access tokens 발급받기
- User > Edit profile > AccessTokens > [Add new Token] 버튼 클릭
- 토큰 이름과, 만료일, 필요한 scopes 클릭후 토큰 생성
- 생성한 토큰을 복사 > Jenkins 페이지로 돌아가기
- Jenkins 에서 credential 추가하기
- Kind : GitLab Personal Access Token > Token : 아까 복사한 토큰 붙여넣기 > ID : 해당 토큰의 ID 작성 > [Create] 버튼 클릭
그 외에 추가하면 좋은 것
GitLab API token
: GitLab 프로젝트의 Settings > access tokens > Project Access Tokens 발급
Username with password
: GitLab의 User와 Password 작성
- Jenkins 환경변수 설정하기
- Jenkins > Jenkins 관리 > System 클릭
- 스크롤을 쭉 내려서 GitLab Servers 항목을 찾고
- GitLab 서버 Url 입력
> 전 단계에서 설정한 Credientials을 등록 (Personal Access Token 리스트만 노출 된다)
> Web Hook 체크
> 위 설정이 다 되었으면 오른쪽 하단 [Test Connection]을 클릭해 실제로 connection이 되는지 체크 한다.
- 프로젝트 생성 후 GitLab과 연동하기
- Jenkins > [+ 새로운 Item] > 프로젝트 이름 작성 후 Pipeline project 클릭
※ Freestyle project와 Pipeline의 차이점?
Freestyle은 GUI 기반 단순한 CI/CD 파이프라인 또는 단일한 빌드 작업을 설정할 때 사용
파이프라인의 구조를 마음대로 바꿀수 없고 커스텀마이징 또한 할수 없음
Pipeline의 경우 복잡한 CI/CD 파이프라인을 필요로 하거나, 작업 흐름을 코드로 관리하고 버전 컨트롤에서 추적하려는 경우 사용
- Configuer의 General > Build Triggers에 : Bulid ~ GitLab hook URL 체크
> 관련 설정 영역이 노출 될 텐데 이 때 [고급] 버튼 클릭 후 Secret token 발급 - URL와 Secret 토큰을 복사해 둔다 이것은 GitLab Webhook 설정할 때 사용 한다.
3) GitLab Webhook 설정하기
- 프로젝트 Webhooks 설정
- [add new webhook] > Jenkins에서 발급받은 url와 Secret token을 입력
- Trigger : Push events설정
- 생성된 Webhook을 테스트 해본다.
Hook executed successfully라는 문구가 뜨면 성공!
※ 테스트가 안되는 경우도 있다?
만약 GitLab과 Jenkins가 같은 네트워크 망 혹은 로컬에 설치된 경우 : 관리자 계으로 접속해서
Admin > Settings > Network > Outbound requests > Allow requests local network ~ (생략) 을 체크 한다.
2. Jenkins Pipeline 스크립트 작성하기
1) SCM 으로 스크립트 작성하기
- 해당 아이템 > 설정에 Pipeline 클릭 > Definition으로 ~ SCM 클릭
SCM(Source Code Management)이란?
git 같은 소스코드의 형상을 관리 하는 것
즉, GitLab프로젝트 레포지토리에 파이프라인 스크립트를 추가하여 관리하겠다는 뜻이다.
- 레포지토리 url 을 추가
- 해당 프로젝트를 관리하는 / 접근 가능한 User Credentials을 추가
- 어느 브랜치를 바라볼건지?
- 스크립트 경로 (Jenkinsfile)
- Jenkinsfile 이라는 이름을 가진 파일에 스크립트를 작성한다.
- 민감한 정보는 환경변수에 등록해서 사용해야 한다.
환경변수 등록 : Jenkins 관리 > 시스템 설정 > Global properties > Enviroment variables
pipeline {
agent any
environment {
DOCKER_IMAGE = "python-cicd-test" // Docker 이미지 이름
DOCKER_TAG = "latest" // Docker 태그
REGISTRY = "10.22.5.110:5000" // Docker 레지스트리 URL
DOCKER_USERNAME = "admin"
DOCKER_PASSWORD = "password"
SSH_CREDENTIALS_ID = "ssh-credentials" // 운영 서버에 SSH 접속할 자격 증명 ID
REMOTE_HOST = "development@10.3.20.126" // 운영 서버의 SSH 호스트 정보
}
stages {
stage('Clone') {
steps {
// GitLab 저장소 클론
git branch: 'main', url: 'http://10.3.20.122/root/ipm.git'
}
}
stage('Build Docker Image') {
steps {
script {
// Docker 이미지 빌드
sh 'docker build -t ${REGISTRY}/${DOCKER_IMAGE}:${DOCKER_TAG} .'
}
}
}
stage('Push Docker Image') {
steps {
script {
// Docker 레지스트리에 로그인
sh 'docker login -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD} $REGISTRY'
// Docker 이미지 푸시
sh 'docker push ${REGISTRY}/${DOCKER_IMAGE}:${DOCKER_TAG}'
}
}
}
stage('Deploy') {
steps {
script {
sshagent(credentials: [SSH_CREDENTIALS_ID]) {
// 운영 서버에서 Docker 컨테이너를 중지하고 제거 후 새 컨테이너 실행
sh '''
ssh -o StrictHostKeyChecking=no ${REMOTE_HOST} "
docker login -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD} $REGISTRY
docker stop python-cicd-test || true
docker rm python-cicd-test || true
docker pull ${REGISTRY}/${DOCKER_IMAGE}:${DOCKER_TAG}
docker run -d --name python-cicd-test -p 80:80 ${REGISTRY}/${DOCKER_IMAGE}:${DOCKER_TAG}
"
'''
}
}
}
}
}
}
docker.withRegistry("http://${DOCKER_REGISTRY}", "${DOCKER_CREDENTIALS_ID}") { ... } 로도 가능 하다는데 이건 다음에 해봐야겠다.
2) 운영서버에 Jenkins SSH 접속 허용하기
참고 블로그
Pipeline이란?
'인프라' 카테고리의 다른 글
디스크와 파티션 볼륨 그리고 파일시스템 (0) | 2024.10.07 |
---|