Jenkins
빌드를 내 PC가 아니라 정해진 곳에서 매번 똑같이 돌린다.
한눈에
- CI 도구 — 코드를 합쳐 빌드하고 검증하는 데까지가 담당이다
- Jenkinsfile = 손으로 하던 순서를 적어 둔 스크립트. 레포 안에 같이 산다
- 파이프라인을 토막 내면 실패한 단계만 다시 돌릴 수 있다
- 이미지 태그에 브랜치·날짜·커밋을 넣으면 지금 도는 서버를 역추적할 수 있다
- 클러스터에 접속하지 않는다. 이미지를 창고에 넣고 values.yaml 한 줄 고치고 끝
- Credentials 는 Jenkins가 들고 코드에는 절대 안 적는다
Jenkins가 없앤 문제는 하나다. "내 PC에선 되는데."
빌드를 내 노트북이 아니라 정해진 서버에서 한다. 같은 자바, 같은 라이브러리, 같은 명령으로 매번 똑같이 돈다. 그리고 그 순서를 사람이 기억하는 대신 파일로 적어 둔다.
Jenkinsfile은 레포 안에 산다
Jenkins 화면에서 클릭으로 설정할 수도 있지만, 그러면 그 설정이 어디에도 기록되지 않는다. 누가 언제 뭘 바꿨는지 모르고, 서버가 날아가면 같이 날아간다.
그래서 파이프라인을 코드로 적어 소스와 같은 레포에 둔다.
pipeline {
agent any
stages {
stage('빌드') {
steps { sh './gradlew clean build -x test' }
}
stage('테스트') {
steps { sh './gradlew test' }
}
stage('이미지') {
steps {
sh 'docker build -f DockerfileK8s -t $REGISTRY/my-app:$TAG .'
sh 'docker push $REGISTRY/my-app:$TAG'
}
}
}
}
코드가 바뀌면 파이프라인도 같은 커밋에서 같이 바뀐다. 이게 화면 설정과의 결정적 차이다.
파이프라인을 토막 내는 이유
한 파일에 다 넣어도 돌아간다. 그런데 실무에서는 대개 토막을 낸다.
| 파일 | 하는 일 | 결과물 |
|---|---|---|
Jenkinsfile.build-java | Maven·Gradle 빌드 | .jar |
Jenkinsfile.build-docker | base 이미지 + jar → 앱 이미지, 레지스트리에 push | 이미지 |
Jenkinsfile.update-manifest | manifest 레포의 values.yaml 태그를 고쳐 커밋 | 커밋 |
Jenkinsfile.all | 위 셋을 한 번에 |
토막을 내는 값어치는 실패했을 때 나온다. 이미지 push가 네트워크 문제로 실패했을 때 자바 빌드부터 다시 돌릴 이유가 없다. 그리고 각 단계의 소요 시간이 따로 찍혀서 어디가 느린지가 보인다.
태그를 어떻게 짓나
여기가 나중에 크게 갈린다.
main-250827-79f1
│ │ └ 커밋 해시 앞자리
│ └ 날짜
└ 브랜치
latest 하나만 쓰면 안 된다. 지금 서버에 떠 있는 게 어느 코드인지 알 방법이 없고, 되돌릴 지점도 없다. 위처럼 지으면 태그 하나로 어느 브랜치의 어느 커밋이 언제 구워졌는지가 역추적된다.
Jenkins는 배포하지 않는다
가장 많이 어긋나는 지점이다. "젠킨스가 dev 서버에 배포한다"고 기억하기 쉬운데, 컨테이너 기반 파이프라인에서 Jenkins의 일은 여기서 끝난다.
클러스터 접속 정보를 안 갖고 있다. 이게 불편해 보이지만 보안 심사에서는 장점이다. CI 서버가 뚫려도 운영 클러스터로 바로 이어지지 않는다.
전체 그림은 DevOps와 CI/CD, 그 다음 단계는 ArgoCD에 있다.
비밀값은 코드에 안 적는다
레지스트리 비밀번호, Git 토큰, 서명 키. 전부 Jenkins의 Credentials에 등록하고 파이프라인에서는 이름으로만 부른다.
withCredentials([usernamePassword(
credentialsId: 'registry-cred',
usernameVariable: 'U', passwordVariable: 'P')]) {
sh 'echo $P | docker login $REGISTRY -u $U --password-stdin'
}
로그에 값이 찍히면 그 순간 유출이다. Jenkins가 등록된 비밀값은 로그에서 마스킹해 주지만, echo로 직접 찍는 것까지 막아 주지는 않는다.
자주 걸리는 것
대안도 알아 둘 것
Jenkins가 유일한 답은 아니다. GitLab CI, GitHub Actions는 형상관리와 한 몸이라 설정이 훨씬 적다. Jenkins를 계속 쓰는 이유는 대개 폐쇄망이다. 외부로 못 나가는 환경에서는 사내에 세울 수 있는 것이 선택지가 된다.
개념은 셋 다 같다. 순서를 파일로 적고, 정해진 곳에서 매번 똑같이 돌린다.