Jenkins 설치 가이드
1. 개요
본 문서는 gitops 저장소의 /jenkins 디렉터리 구조를 기반으로 Jenkins CI/CD 서버를 설치하고 GitHub와 연동하는 전체 과정을 안내합니다. Kustomize를 사용하여 환경별 설정을 관리하고, Makefile을 이용한 배포 자동화 방법을 다룹니다.
2. 사전 요구사항
- Kubernetes 클러스터: v1.30 이상
- 로컬 도구: kubectl, kustomize, helm 설치 완료
- 인증서:
cert-manager를 통한 Ingress 인증서 복제 구성 준비 - GitHub 계정: Personal Access Token 발급이 가능한 계정
- DNS 등록: jenkibs.cnapcloud.com
- Keycloak Client 설정: jenkins client 생성
3. 디렉터리 구조 및 역할
Makefile:apply,delete,preview,pull등 배포 자동화 스크립트kustomize/base/: 모든 환경에 공통으로 적용될 리소스 및 원본 Helm Chartresources/: BuildKit Deployment 및 Service (컨테이너 이미지 빌드용)
kustomize/overlays/dev/:dev환경을 위한 설정helm/values.yaml:dev환경에 특화된 Jenkins 설정helm/helm-chart.yaml: Helm Chart 생성기 설정
jenkins-agent/: 커스텀 Jenkins 빌드 에이전트 이미지
4. 설치 단계 (기본 설치)
4.1. Namespace 생성
kubectl create namespace cicd || true
4.2. Helm Chart 준비
최신 Jenkins Helm Chart를 다운로드합니다.
make pull
4.3. values.yaml 커스터마이징
kustomize/overlays/dev/helm/values.yaml 파일을 열어 Jenkins의 기본 설정을 수정합니다.
4.3.1. 관리자 계정 설정
controller:
admin:
username: admin
password: <your-secure-password> # 초기 관리자 비밀번호
보안 경고: 프로덕션 환경에서는 Kubernetes Secret을 사용하여 비밀번호를 관리하는 것을 권장합니다.
4.3.2. Ingress 및 도메인 설정
controller:
ingress:
enabled: true
hostName: jenkins.cnapcloud.com # Jenkins 접속 도메인
tls:
- secretName: cnapcloud.com-tls # cert-manager가 생성한 TLS Secret
hosts:
- jenkins.cnapcloud.com
4.3.3. Prometheus 메트릭 활성화
controller:
prometheus:
enabled: true
scrapeInterval: 30s
scrapeEndpoint: /prometheus
serviceMonitorAdditionalLabels:
prometheus: main
4.3.4. 플러그인 설정 (installPlugins)
Jenkins에서 필요한 플러그인을 사전 설치하도록 설정합니다.
controller:
installPlugins:
- kubernetes:latest # Kubernetes Pod 기반 에이전트 지원
- workflow-aggregator:latest # Pipeline 기능
- git:latest # Git 연동
- configuration-as-code:latest # JCasC (Jenkins Configuration as Code)
- matrix-auth:latest # Matrix Authorization Strategy (권한 관리)
- oic-auth:latest # OpenID Connect 인증 (Keycloak SSO)
참고:
latest대신 특정 버전을 지정하여 재현 가능한 배포를 구성할 수 있습니다.
4.3.5. JCasC (Jenkins Configuration as Code) 설정
JCasC를 사용하여 Jenkins OIDC 인증과 권한 관리를 코드로 설정합니다.
중요: UI에서 수동으로 설정한 OIDC 연동 설정은 Pod 재시작 시 기본값으로 초기화됩니다. JCasC를 사용하면 설정이 코드로 관리되어 재시작 후에도 유지됩니다.
controller:
JCasC:
defaultConfig: true
configScripts:
jenkins-config: |
jenkins:
systemMessage: Welcome to our CI\CD server. This Jenkins is configured and managed 'as code'.
securityRealm:
oic:
clientId: "jenkins"
clientSecret: "YE6GuMNlZ4qHGewA3r96p7QZMLi8a1e6"
disableSslVerification: false
emailFieldName: "email"
groupIdStrategy: "caseSensitive"
groupsFieldName: "groups"
postLogoutRedirectUrl: "https://jenkins.cnapcloud.com/"
serverConfiguration:
wellKnown:
scopesOverride: "openid email profile groups"
wellKnownOpenIDConfigurationUrl: "https://keycloak.cnapcloud.com/realms/cnap/.well-known/openid-configuration"
userIdStrategy: "caseSensitive"
userNameField: "email"
authorizationStrategy:
globalMatrix:
permissions:
- "Overall/Administer:admin"
- "Overall/Read:authenticated"
- "Job/Read:authenticated"
- "Overall/Read:editor"
- "Job/Build:editor"
- "Job/Read:editor"
- "Job/Workspace:editor"
보안 주의:
clientSecret은 민감 정보이므로 프로덕션 환경에서는 Kubernetes Secret 또는 SOPS를 사용하여 암호화하는 것을 권장합니다.
4.3.6. 리소스 설정
controller:
resources:
limits:
cpu: 2000m
memory: 4096Mi
requests:
cpu: 512m
memory: 512Mi
4.3.7. 스토리지 설정
persistence:
size: "4Gi" # Jenkins 홈 디렉터리 크기
workspaceVolume:
type: PVC
claim: jenkins-workspace # 워크스페이스용 별도 PVC
readOnly: false
4.3.8. 빌드 에이전트 설정
Jenkins는 동적으로 Kubernetes Pod를 빌드 에이전트로 생성합니다.
additionalAgents:
build:
podName: build
idleMinutes: 5
customJenkinsLabels: build
image:
repository: cnapcloud/jenkins-build-agent
tag: 0.0.1
resources:
limits:
cpu: 2000m
memory: 4096Mi
requests:
cpu: 512m
memory: 512Mi
docker:
podName: docker
customJenkinsLabels: docker
image:
repository: docker
tag: "latest"
command: "/bin/sh -c"
args: "cat"
TTYEnabled: true
4.4. Kustomization 구성
Jenkins 배포를 위한 Kustomization 파일들을 구성합니다.
4.4.1. Base 구성
kustomize/base/kustomization.yaml에 BuildKit 리소스를 추가합니다:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./resources/buildkit-deployment.yaml
- ./resources/buildkit-svc.yaml
#### 4.4.2. Dev 구성
`kustomize/overlays/dev/kustomization.yaml`에서 Helm Chart를 생성하고 환경별 설정을 적용합니다:
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: cicd
generators:
- ./helm/helm-chart.yaml
resources:
- ../../base
patches:
- target:
kind: ConfigMap
name: jenkins
path: ./patches/apply-sh.yaml
apply-sh.yaml 패치는 Jenkins 초기화 시 플러그인이 이미 설치되어 있으면 재설치를 방지하여 배포 시간을 단축합니다.
4.5. 배포 프로세스
Step 0: 네임스페이스 생성
kubectl create namespace cicd || true
Step 1: Helm Chart 준비
make pull
Step 2: 배포 미리보기 (권장)
make preview DEPLOY_ENV=dev
Step 3: 배포 실행
make apply DEPLOY_ENV=dev
5. 설치 후 검증 (기본 설치)
리소스 상태 확인:
kubectl get pods,svc,ingress,pvc -n cicd- 모든 Pod이
Running상태이고, PVC가Bound상태인지 확인합니다.
- 모든 Pod이
웹 UI 접속: 브라우저에서
https://jenkins.cnapcloud.com에 접속합니다.관리자 로그인:
admin계정과values.yaml에서 설정한 비밀번호로 로그인합니다.Time Zone 설정:
- 우측 상단 사용자 > Account > Time Zone:
Asia/Seoul선택
- 우측 상단 사용자 > Account > Time Zone:
Jenkins 경고 비활성화 (선택사항):
- Jenkins 관리 > 시스템 > Administrative monitors
Update Site Warnings및Jenkins Update Notification체크 해제
6. Keycloak OIDC 연동 (SSO)
Jenkins UI에서 Keycloak을 연동하여 SSO(Single Sign-On)를 구성합니다.
참고: 4.3.5 섹션에서 JCasC를 통해 OIDC 설정을 이미 구성한 경우, 이 섹션은 건너뛰어도 됩니다. 이 섹션은 UI에서 수동으로 설정하는 방법을 안내합니다. 이 설정은 Jenkins를 재시작하면 사라지니 테스트 용도로만 사용하세요.
6.1. 필수 플러그인 설치
- Jenkins 관리 > Plugins > Available plugins 로 이동합니다.
- 다음 플러그인을 검색하여 설치합니다:
OpenID Connect Authentication PluginMatrix Authorization Strategy Plugin(권한 관리용)
- 설치 후 Jenkins를 재시작합니다.
6.2. Keycloak에서 OIDC 클라이언트 생성
- Keycloak 관리 콘솔에 접속하여 원하는 Realm을 선택합니다.
- Clients 메뉴로 이동하여 Create client를 클릭합니다.
- 다음 정보를 입력하여 클라이언트를 생성합니다:
- Client ID:
jenkins - Name:
Jenkins - Client authentication:
On - Valid redirect URIs:
https://jenkins.cnapcloud.com/* - Valid post logout redirect URIs:
+(redirect URIs와 동일하게 적용) - Web origins:
https://jenkins.cnapcloud.com
- Client ID:
- 생성된 클라이언트의 Credentials 탭으로 이동하여 Client secret을 복사합니다.
- Client Scopes 설정:
- 클라이언트 설정 페이지에서 Client scopes 탭으로 이동
groups스코프를 Assigned 목록에 추가groups스코프를 클릭하여 Mappers 탭으로 이동- Add mapper > By configuration > Group Membership 선택
- 다음과 같이 설정:
- Name:
groups - Token Claim Name:
groups - Add to ID Token:
On - Add to Access Token:
On - Full group path:
Off
- Name:
6.3. Jenkins에서 OIDC 인증 설정
Jenkins 관리 > Security 로 이동합니다.
Security Realm 섹션에서 Login with Openid Connect 를 선택합니다.
다음과 같이 설정합니다:
Client Configuration:
- Client id:
jenkins - Client secret: 6.2 단계에서 복사한 Client Secret
Configuration mode:
- Discovery via well-known endpoint 선택
- Well-known configuration endpoint:
https://keycloak.cnapcloud.com/realms/cnap/.well-known/openid-configuration
Scopes:
- Override scopes:
openid email profile groups
User fields:
- User name field name:
email - Email field name:
email - Groups field name:
groups
Logout:
- Logout from OpenID Provider: 체크 ✓
- Post logout redirect URL:
https://jenkins.cnapcloud.com/
- Client id:
저장 버튼을 클릭합니다.
6.4. 권한 관리 설정 (Matrix Authorization Strategy)
Keycloak 그룹 기반으로 Jenkins 권한을 관리합니다.
Jenkins 관리 > Security 로 이동합니다.
Authorization 섹션에서 Matrix-based security 를 선택합니다.
그룹별 권한을 설정합니다:
예시: 관리자 그룹 추가
- Add group 버튼을 클릭
- 그룹 이름 입력:
jenkins-admins(Keycloak에 정의된 그룹명) - Overall > Administer 권한 부여
예시: 개발자 그룹 추가
- Add group 버튼을 클릭
- 그룹 이름 입력:
jenkins-developers - Overall > Read 권한 부여
- Job > Build, Read, Workspace 권한 부여
저장 버튼을 클릭합니다.
6.5. OIDC 로그인 검증
- Jenkins에서 로그아웃합니다.
- 로그인 페이지에 다시 접속합니다.
- Login with OpenID Connect 버튼이 나타나는지 확인합니다.
- 버튼을 클릭하여 Keycloak 로그인 페이지로 이동하는지, 그리고 로그인 후 Jenkins로 정상적으로 리디렉션되는지 확인합니다.
- Jenkins 대시보드 우측 상단에 Keycloak 사용자 이메일이 표시되는지 확인합니다.
7. GitHub 연동 설정
7.1. 필수 플러그인 설치
Jenkins에 GitHub 연동을 위한 플러그인을 설치합니다.
Jenkins 관리 > Plugins > Available plugins 로 이동합니다.
다음 플러그인을 검색하여 설치합니다:
GitHubGitHub Branch SourceGitHub APIGitHub Authentication
설치 후 Jenkins를 재시작합니다.
7.2. GitHub Personal Access Token 발급
- GitHub에 로그인하여 우측 상단 프로필을 클릭합니다.
- Settings > Developer settings > Personal access tokens > Tokens (classic) 로 이동합니다.
- Generate new token (classic) 을 클릭합니다.
- 다음 권한(scope)을 선택합니다:
repo(전체)admin:repo_hook(전체)user:email
- 토큰을 생성하고 안전한 곳에 복사해둡니다.
7.3. Jenkins Credentials 등록
- Jenkins 관리 > Credentials > System > Global credentials (unrestricted) 로 이동합니다.
- + Add Credentials 를 클릭합니다.
Credential 1: Github Username/Password
- Kind:
Username with password - Scope:
Global - Username: GitHub 사용자 이름
- Password: 7.2 단계에서 생성한 Personal Access Token
- ID:
github-password - Description:
GitHub Username and Token
Credential 2: Github Secret Text
- Kind:
Secret text - Scope:
Global - Secret: 7.2 단계에서 생성한 Personal Access Token
- ID:
github-token - Description:
GitHub Personal Access Token
Credential 3: Harbor Secret Text
- Kind:
Secret text - Scope:
Global - Secret: Harbor Password
- ID:
harbor-password - Description:
Harbor Password
7.4. GitHub Server 등록
- Jenkins 관리 > 시스템 으로 이동합니다.
- GitHub 섹션을 찾습니다 (없으면 아래로 스크롤).
- Add GitHub Server > GitHub Server 를 선택합니다.
- 다음과 같이 설정합니다:
- Name:
github.com - API URL:
https://api.github.com - Credentials:
github-token(7.3에서 생성한 Secret Text) - Manage hooks: 체크 ✓
- Name:
- Test connection 버튼을 클릭하여 연결을 확인합니다.
- 성공 시:
Credentials verified for user <username>, rate limit: ...메시지가 표시됩니다.
- 성공 시:
- 저장 버튼을 클릭합니다.
※ Manage hooks를 체크하면 Multibranch Pipeline 생성 시 자동으로 Webhook이 등록되므로 별도의 수동 설정이 필요하지 않습니다.
7.5. Multibranch Pipeline 생성
GitHub 저장소와 연동된 Multibranch Pipeline을 생성합니다.
7.5.1. 새로운 Item 생성
- Jenkins 대시보드에서 새로운 Item 을 클릭합니다.
- Enter an item name: 프로젝트 이름 입력 (예:
my-app) - Multibranch Pipeline 을 선택하고 OK 를 클릭합니다.
7.5.2. Branch Sources 설정
- Branch Sources 섹션에서 Add source > GitHub 를 선택합니다.
- 다음과 같이 설정합니다:
- Credentials:
github-password(7.3에서 생성한 Username/Password)- 이 설정은 GitHub API rate limit을 방지합니다
- Repository HTTPS URL: GitHub 저장소 URL (예:
https://github.com/username/my-app)
- Credentials:
7.5.3. Discover Branches 전략 설정
- Behaviors 섹션에서 Add > Discover branches 를 추가합니다.
- Strategy:
Exclude branches that are also filed as PRs(PR이 아닌 브랜치만 빌드)
7.5.4. Discover Pull Requests 설정
- Behaviors 섹션에서 Add > Discover pull requests from origin 을 추가합니다.
- Strategy:
Merging the pull request with the current target branch revision(PR을 머지한 상태로 빌드)
7.5.5. 브랜치 필터 설정
- Behaviors 섹션에서 Add > Filter by name (with wildcards) 를 추가합니다.
- Include:
main(메인 브랜치)PR-*(PR 브랜치)develop(개발 브랜치, 필요한 경우)
7.5.6. Scan Triggers 설정
Scan Repository Triggers 섹션에서:
- Periodically if not otherwise run: 체크 ✓
- Interval:
1 minute또는 원하는 간격 설정
저장 버튼을 클릭합니다.
8. GitLab 연동 설정
8.1. 필수 플러그인 설치
Jenkins에 GitLab 연동을 위한 플러그인을 설치합니다.
Jenkins 관리 > Plugins > Available plugins 로 이동합니다.
다음 플러그인을 검색하여 설치합니다:
Generic Webhook Trigger PluginGitLab API PluginGitLab Branch Source PluginGitLab Logo PluginGitLab Merge Request BuilderGitLab PluginMultibranch Build Strategy Extension(특정 폴더 변경 시 빌드용)
설치 후 Jenkins를 재시작합니다.
8.2. GitLab Personal Access Token 발급
- GitLab에 로그인하여 좌측 상단 프로필 아이콘을 클릭합니다.
- Preferences > Access Tokens 로 이동합니다.
- Add new token을 클릭하고 다음을 설정합니다:
- Token name: 토큰 식별 이름 (예:
jenkins-token) - Expiration date: 만료일 설정 (또는 비워두면 무기한)
- Select scopes: 다음 권한 선택
api: GitLab API 전체 접근read_repository: 저장소 읽기write_repository: 저장소 쓰기 (Webhook 관리용)
- Token name: 토큰 식별 이름 (예:
- Create personal access token을 클릭하고 생성된 토큰을 복사합니다.
참고: Group Access Token이나 Project Access Token도 사용 가능하지만, 해당 그룹/프로젝트에만 접근이 제한됩니다. 여러 프로젝트를 관리하려면 Personal Access Token을 사용하세요.
8.3. Jenkins Credentials 등록
- Jenkins 관리 > Credentials > System > Global credentials (unrestricted) 로 이동합니다.
- + Add Credentials 를 클릭하여 다음 Credential들을 생성합니다.
참고: 8.2에서 생성한 동일한 토큰을 Jenkins의 서로 다른 Credential 형식으로 등록합니다. GitLab Plugin과 GitLab Branch Source Plugin이 각각 다른 형식을 요구하기 때문입니다.
Credential 1: Username with password
- Kind:
Username with password - Scope:
Global - Username: GitLab 사용자 이름 (예:
root) - Password: GitLab 비밀번호
- ID:
gitlab-password - Description:
GitLab Username and Password
Credential 2: GitLab API token
- Kind:
GitLab API token - Scope:
Global - API token: 8.2 단계에서 생성한 Access Token
- ID:
gitlab-api-token - Description:
GitLab API Token
Credential 3: GitLab Personal Access Token
- Kind:
GitLab Personal Access Token - Scope:
Global - Token: 8.2 단계에서 생성한 Access Token (Credential 2와 동일한 토큰)
- ID:
gitlab-access-token - Description:
GitLab Personal Access Token
Credential 4: Webhook Secret text
- Kind:
Secret text - Scope:
Global - Secret: 임의의 비밀 문자열 생성 (예:
9acc55ba66e4f53d9be86ea5efe895f7) - ID:
gitlab-webhook-token - Description:
GitLab Webhook Token
Credential 3: Harbor Secret Text
- Kind:
Secret text - Scope:
Global - Secret: Harbor Password
- ID:
harbor-password - Description:
Harbor Password
참고: Webhook Secret은 GitLab과 Jenkins 간의 통신을 보호하는 비밀키입니다. 안전한 랜덤 문자열을 사용하세요.
8.4. GitLab 서버 등록
- Jenkins 관리 > 시스템 으로 이동합니다.
GitLab 설정 1 (GitLab)
- GitLab 섹션을 찾아 다음과 같이 설정합니다:
- Enable authentication for ‘/project’ end-point: 체크 ✓
- Connection name:
gitlab-internal(또는 GitLab 서버 식별 이름) - GitLab host URL:
https://gitlab.cnapcloud.com(또는 GitLab 서버 URL) - Credentials:
gitlab-api-token(GitLab API Token)
GitLab 설정 2 (GitLab Servers)
- GitLab Servers 섹션을 찾아 Add GitLab Server 를 클릭하고 다음과 같이 설정합니다:
- Display Name:
gitlab-internal - Server URL:
https://gitlab.cnapcloud.com - Credentials:
gitlab-access-token(GitLab Personal Access Token) - Web Hook:
- Manage Web Hooks: 체크 ✓
- Manage System Hooks: 체크 ✓
- Secret Token:
gitlab-webhook-token(8.3에서 생성한 Secret text)
- Display Name:
GitLab Merge Request Builder 설정
GitLab Merge Request Builder 섹션을 찾아 다음과 같이 설정합니다:
- GitLab Host URL:
https://gitlab.cnapcloud.com
- GitLab Host URL:
저장 버튼을 클릭합니다.
8.5. Multibranch Pipeline 생성 (GitLab)
GitLab 저장소와 연동된 Multibranch Pipeline을 생성합니다.
8.5.1. 새로운 Item 생성
- Jenkins 대시보드에서 새로운 Item 을 클릭합니다.
- Enter an item name: 프로젝트 이름 입력 (예:
spring-msa-demo) - Multibranch Pipeline 을 선택하고 OK 를 클릭합니다.
8.5.2. Branch Sources 설정
- Branch Sources 섹션에서 Add source > GitLab Project 를 선택합니다.
- 다음과 같이 설정합니다:
- Server:
gitlab-internal(8.4에서 등록한 서버) - Checkout Credentials:
gitlab-password(8.3에서 생성한 Username/Password) - Owner: GitLab 그룹 또는 사용자명 (예:
msa) - Projects: GitLab 프로젝트 경로 (예:
msa/spring-msa-demo)
- Server:
8.5.3. Discover Branches 전략 설정
- Behaviors 섹션에서 Add > Discover branches 를 추가합니다.
- Strategy:
Only branches that are not also filed as MRs(MR이 아닌 브랜치만 빌드)
8.5.4. Discover Merge Requests 설정
Behaviors 섹션에서 Add > Discover merge requests from origin 을 추가합니다.
Strategy:
Merging the merge request with the current target branch revision(MR을 머지한 상태로 빌드)
Behaviors 섹션에서 Add > Discover merge requests from forks 를 추가합니다.
Strategy:
Merging the merge request with the current target branch revision
Trust:
Trust Members
8.5.5. 브랜치 필터 설정
- Behaviors 섹션에서 Add > Filter by name (with wildcards) 를 추가합니다.
- Include:
main(메인 브랜치)MR-*(Merge Request 브랜치)
8.5.6. Webhook Listener 설정
- Webhook Listener Conditions 섹션에서:
- Always build pipeline on Open MR webhook: 체크 ✓
- Always build pipeline on Re-Open MR webhook: 체크 ✓
8.5.7. Scan Triggers 설정
- Scan Multibranch Pipeline Triggers 섹션에서:
- Periodically if not otherwise run: 체크 ✓
- Interval:
1 minute또는 원하는 간격 설정
8.5.8. 특정 폴더 변경 시에만 빌드 (선택사항)
특정 디렉터리가 변경될 때만 빌드를 트리거하려면:
Build strategies 섹션에서 Add > Build included regions strategy 를 선택합니다.
Trigger builds for included regions:
project/**(project 폴더 변경 시에만 빌드)- 또는 원하는 경로 패턴 입력
저장 버튼을 클릭합니다.
8.6. GitLab Webhook 설정
8.4에서 Manage Web Hooks를 체크한 경우, Multibranch Pipeline 생성 시 Webhook이 자동으로 등록됩니다. 이 섹션은 자동 등록이 실패하거나 수동으로 설정해야 하는 경우에만 참고하세요.
Webhook 자동 등록 확인
- GitLab 프로젝트 페이지로 이동합니다.
- Settings > Webhooks 로 이동합니다.
- Jenkins URL이 포함된 Webhook이 등록되어 있는지 확인합니다.
수동 설정 (자동 등록 실패 시)
- GitLab 프로젝트 페이지에서 Settings > Integrations 로 이동합니다.
- Jenkins 통합을 선택하거나 추가합니다.
- 다음과 같이 설정합니다:
- Trigger:
Push,Merge request선택 - Jenkins server URL:
https://jenkins.cnapcloud.com(또는 Jenkins URL) - SSL verification: 체크 (HTTPS 사용 시)
- Project name:
spring-msa-demo(Jenkins에서 생성한 프로젝트 이름) - Username:
admin(Jenkins 관리자 계정) - Enter new password: Jenkins 관리자 비밀번호
- Trigger:
- Test settings 버튼을 눌러 연결을 확인합니다.
- Save changes 를 클릭합니다.
8.7. GitLab Outbound Requests 허용
GitLab이 내부 네트워크의 Jenkins에 요청을 보낼 수 있도록 설정합니다.
- GitLab 관리자 계정으로 로그인합니다.
- Admin Area > Settings > Network 로 이동합니다.
- Outbound requests 섹션을 확장합니다.
- 다음 옵션을 체크합니다:
- Allow requests to the local network from webhooks and integrations: 체크 ✓
- Allow requests to the local network from system hooks: 체크 ✓
- Local IP addresses and domain names that hooks and integrations can access 필드에 Jenkins 도메인을 추가합니다:
jenkins.cnapcloud.com- 또는 Jenkins IP 주소
- Save changes 를 클릭합니다.
참고: 외부 도메인을 사용하는 경우 GitLab이 해당 도메인에 접근 가능해야 합니다.
내부 네트워크 구성 예:jenkins.cnapcloud.com→192.168.0.75:80,443→192.168.64.7:80,443(k8s ingress)
8.8. GitLab 연동 검증
- GitLab 저장소에 커밋을 푸시합니다.
- Jenkins에서 자동으로 빌드가 트리거되는지 확인합니다.
- GitLab 프로젝트의 CI/CD > Pipelines 에서 Jenkins 파이프라인 상태를 확인할 수 있습니다.
- Merge Request를 생성하여 MR 빌드가 트리거되는지 확인합니다.
9. Dashboard 뷰 구성
여러 프로젝트를 한눈에 보기 위한 대시보드를 구성합니다.
9.1. 새로운 뷰 생성
- Jenkins 대시보드에서 + 탭 또는 New View 를 클릭합니다.
- View name: 원하는 이름 입력 (예:
GitHub Projects또는MSA) - List View 를 선택하고 Create 를 클릭합니다.
9.2. 뷰 설정
- Job Filters 섹션에서:
- Jobs:
Recurse in subfolders체크 ✓- 포함할 프로젝트 선택:
- GitHub 프로젝트 예:
my-app→main체크 ✓ - GitLab 프로젝트 예:
msa / spring-msa-demo→main체크 ✓
- GitHub 프로젝트 예:
- Jobs:
- Columns 섹션에서 표시할 열을 선택합니다:
StatusWeatherNameLast SuccessLast FailureLast DurationBuild Button
- OK 를 클릭합니다.
10. 파이프라인 작성 예시 (GitHub 기준)
이 섹션에서는 GitHub 저장소를 기준으로 실제 프로젝트에 사용할 수 있는 Jenkinsfile과 Makefile 예시를 제공합니다.
10.1. Makefile 작성
프로젝트 루트에 Makefile을 생성하여 빌드 작업을 자동화합니다.
# Docker image variables
IMAGE_ORG := harbor.cnapcloud.com/library
IMAGE_REPOSITORY := ${IMAGE_ORG}/spring-msa-demo
IMAGE_TAG := $(shell git rev-parse --short=7 HEAD)
# Gitops variables
GITOPS_REPO := https://github.com/username/gitops.git
GITOPS_PATH := tmp/gitops
GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD)
help:
@echo "Available targets:"; awk '/^[a-zA-Z0-9_-]+:/ {t=$$1; sub(/:$$/, "", t); \
if(t=="help") next; getline; if($$0 ~ /@echo/) {sub(/.*@echo[ \t]*/, "", $$0); \
printf " %-15s %s\n", t, $$0}}' $(MAKEFILE_LIST)
build:
@echo "[build] Build all projects."
./gradlew clean build -x test --no-build-cache
report:
@echo "[report] Generate test report."
./gradlew test jacocoTestReport
publish:
@echo "[publish] Publish artifacts."
./gradlew publish -x test -Pusername=admin -Ppassword=password
run-project:
@echo "[run] Run project service locally."
./gradlew project-service:bootRun
run-orchestrator:
@echo "[run] Run orchestrator service locally."
./gradlew orchestrator-service:bootRun
docker-build:
@echo "[docker-build] Build and push Docker image"
buildctl --addr tcp://buildkitd.cicd.svc:1234 build \
--frontend dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--output type=image,name=$(IMAGE_REPOSITORY):$(IMAGE_TAG),push=true
update-tag:
@echo "[update-tag] Update image tag in GitOps repo."
update-tag.sh \
--repo $(GITOPS_REPO) \
--branch main \
--image $(IMAGE_REPOSITORY):$(IMAGE_TAG)
clean:
@echo "[clean] Clean up Docker builder cache."
buildctl --addr tcp://buildkitd.cicd.svc:1234 prune --all --force
.PHONY: help build report run-project run-orchestrator docker-build update-tag clean
Makefile 주요 타겟 설명
- build: Gradle을 사용하여 프로젝트 빌드
- docker-build: BuildKit을 사용하여 Docker 이미지 빌드 및 푸시
- update-tag: GitOps 저장소의 이미지 태그를 업데이트하는 스크립트 실행
- clean: Docker 빌더 캐시 정리
참고:
buildctl은 4.3.6에서 설정한 BuildKit 서비스를 사용합니다.
10.2. Jenkinsfile 작성 (GitHub 연동)
프로젝트 루트에 Jenkinsfile을 생성하여 파이프라인을 정의합니다.
pipeline {
agent { label 'build' }
environment {
GITHUB_TOKEN = credentials('github-token')
HARBOR_PASSWD = credentials('harbor-password')
}
options {
disableConcurrentBuilds()
timeout(time: 30, unit: 'MINUTES')
buildDiscarder(logRotator(numToKeepStr: '14'))
}
stages {
stage('setup-github') {
steps {
sh '''
### git user info !! important to reuse pod.
git config --global user.email "your-email@example.com"
git config --global user.name "Your Name"
git config --global url.https://username:${GITHUB_TOKEN}@github.com/orgname/.insteadOf https://github.com/orgname/
'''
}
}
stage("build") {
steps {
sh '''
make build
'''
}
}
stage('push image') {
steps {
sh '''
docker login harbor.cnapcloud.com -u admin -p ${HARBOR_PASSWD}
make docker-build
'''
}
}
stage('deploy') {
steps {
sh '''
make update-tag
'''
}
}
}
}
주요 설정 설명
- agent:
label 'build'- 7.5.6 또는 8.5.7에서 설정한 빌드 에이전트 사용 - credentials: GitHub 토큰과 Harbor 패스워드를 Credentials에서 가져옴
- options:
disableConcurrentBuilds(): 동시 빌드 방지timeout: 30분 제한buildDiscarder: 최근 14개 빌드만 보관
단계별 설명
- setup-github: Git 사용자 정보 설정 및 GitHub 인증 구성
- build: Gradle 또는 Maven 빌드 실행
- push image: Docker 이미지 빌드 및 Harbor 레지스트리에 푸시
- update gitops: GitOps 저장소의 이미지 태그 업데이트
10.3. 필수 Credentials 설정
파이프라인 실행을 위해 다음 Credentials가 필요합니다:
GitHub Token (이미 설정됨)
- Section 7.3에서 설정한
github-token사용
Harbor Password (추가 필요)
- Jenkins 관리 > Credentials > System > Global credentials (unrestricted) 로 이동합니다.
- + Add Credentials 를 클릭합니다.
- 다음과 같이 설정합니다:
- Kind:
Secret text - Scope:
Global - Secret: Harbor 관리자 비밀번호
- ID:
harbor-password - Description:
Harbor Registry Password
- Kind:
10.4. 파이프라인 테스트
- 프로젝트에
Jenkinsfile,Makefile,update-tag.sh를 추가합니다. - 변경사항을 Git에 커밋하고 푸시합니다:
git add Jenkinsfile Makefile update-tag.sh git commit -m "Add Jenkins pipeline configuration" git push origin main - Jenkins에서 프로젝트를 Scan Multibranch Pipeline Now 를 클릭합니다.
- 자동으로 파이프라인이 실행되는지 확인합니다.
10.5. 파이프라인 커스터마이징 팁
알림 추가
Slack이나 이메일 알림을 추가하려면 Jenkinsfile에 post 섹션을 추가합니다:
pipeline {
// ... existing configuration ...
post {
success {
echo 'Pipeline succeeded!'
// slackSend(color: 'good', message: "Build succeeded: ${env.JOB_NAME} ${env.BUILD_NUMBER}")
}
failure {
echo 'Pipeline failed!'
// slackSend(color: 'danger', message: "Build failed: ${env.JOB_NAME} ${env.BUILD_NUMBER}")
}
}
}
테스트 단계 추가
필요 플러그인:
JUnit Plugin,JaCoCo Plugin
테스트를 실행하고 결과를 수집하면 Jenkins UI에서 테스트 트렌드와 코드 커버리지 그래프를 확인할 수 있습니다.
stage('test') {
steps {
sh 'make report'
}
post {
always {
junit '**/build/test-results/**/*.xml'
jacoco execPattern: '**/build/jacoco/*.exec'
}
}
}
환경별 배포
main branch가 업데이트되는 경우에만 애플리케이션을 배포합니다.
stage('deploy') {
when {
branch 'main'
}
steps {
sh '''
make update-tag
'''
}
}
11. 추가 플러그인 설치 (권장)
11.1. Prometheus 플러그인 설정
Jenkins 메트릭을 Prometheus로 수집하여 모니터링할 수 있습니다.
11.1.1. 플러그인 설치
- Jenkins 관리 > Plugins > Available plugins 로 이동합니다.
Prometheus metrics와CloudBees Disk Usage Simple플러그인을 검색하여 설치합니다.- 설치 후 Jenkins를 재시작합니다.
11.1.2. Prometheus 메트릭 설정
- Jenkins 관리 > 시스템 으로 이동합니다.
- Prometheus 섹션을 찾아 다음과 같이 설정합니다:
기본 설정:
- Path:
prometheus(기본값, 변경 가능)- 메트릭 엔드포인트:
https://jenkins.cnapcloud.com/prometheus
- 메트릭 엔드포인트:
- Default namespace:
cicd(기본값) - Collecting metrics period in seconds:
120(2분마다 수집)
인증 설정 (테스트용):
- Use authenticating to collect metrics: 체크 해제 ✗
- 또는 Unprotected Metrics 옵션 체크 ✓ (인증 없이 메트릭 접근 허용)
보안 경고: 프로덕션 환경에서는 인증을 활성화하여 메트릭 엔드포인트를 보호하는 것을 권장합니다.
수집 항목 설정:
- Collect disk usage: 체크 ✓ (디스크 사용량 메트릭 수집)
- Count successful builds: 체크 ✓ (성공한 빌드 수 추적)
- Count failed builds: 체크 ✓ (실패한 빌드 수 추적)
- Count builds: 체크 ✓ (전체 빌드 수 추적)
- 저장 버튼을 클릭합니다.
11.1.3. 메트릭 엔드포인트 확인
설정 후 다음 URL에서 메트릭을 확인할 수 있습니다:
https://jenkins.cnapcloud.com/prometheus
또는 curl 명령으로 확인:
curl https://jenkins.cnapcloud.com/prometheus
11.1.4. ServiceMonitor 설정 (Kubernetes)
4.3.3에서 설정한 values.yaml의 Prometheus 설정이 자동으로 ServiceMonitor 리소스를 생성합니다.
ServiceMonitor 확인:
kubectl get servicemonitor jenkins -n cicd
11.1.5. 주요 메트릭 예시
jenkins_node_online_value: 온라인 노드 수jenkins_executor_count_value: 전체 실행기(executor) 수jenkins_job_count_value: 전체 작업 수jenkins_builds_success_build_count_total: 성공한 빌드 수jenkins_builds_failed_build_count_total: 실패한 빌드 수jenkins_builds_duration_milliseconds_summary: 빌드 소요 시간
11.2. 기타 유용한 플러그인 목록
- Blue Ocean: 현대적인 UI와 파이프라인 시각화
- CloudBees Disk Usage Simple Plugin: 디스크 사용량 모니터링
- Generic Webhook Trigger Plugin: 유연한 Webhook 처리
- Multibranch Build Strategy Extension: 특정 폴더 변경 시에만 빌드
11.3. 플러그인 설치 방법
- Jenkins 관리 > Plugins > Available plugins 로 이동합니다.
- 플러그인 이름으로 검색하여 설치합니다.
- 필요한 경우 Jenkins를 재시작합니다.
12. Jenkins 설정 백업 및 복원
12.1. 백업/복원 개요
| 백업 대상 | 포함 내용 | Helm 관리 시 |
|---|---|---|
| Jenkins 홈 (PVC) | Jobs, UI Credentials, 빌드 이력, plugins, secrets | 백업 필요 |
| JCasC 설정 | 시스템 설정, 인증/권한, JCasC Credentials | values.yaml로 관리되어 별도 백업 불필요 |
⚠️ 중요: JCasC를 Helm(
values.yaml)으로 관리하지 않는 경우, 반드시 JCasC 설정을 먼저 백업한 후 Jenkins 홈을 백업하세요.
12.2. 백업
JCasC 설정 백업
values.yaml로 JCasC를 관리하고 GitOps 저장소에 버전 관리 중이면 생략 가능
export JENKINS_URL="https://jenkins.cnapcloud.com"
export JENKINS_USER="admin"
export JENKINS_API_TOKEN="<your-api-token>"
curl -s -u "${JENKINS_USER}:${JENKINS_API_TOKEN}" \
"${JENKINS_URL}/configuration-as-code/export" \
-o jenkins-casc-export.yaml
Jenkins 홈 백업
kubectl cp cicd/jenkins-0:/var/jenkins_home ./jenkins-home-backup
12.3. 복원
Jenkins 홈 복원
# 1. Jenkins Pod 중지
kubectl scale statefulset jenkins -n cicd --replicas=0
# 2. 임시 Pod로 PVC에 데이터 복원
kubectl run jenkins-restore --rm -it --restart=Never \
--image=busybox \
--overrides='{"spec":{"containers":[{"name":"restore","image":"busybox","command":["sh"],"stdin":true,"tty":true,"volumeMounts":[{"name":"jenkins-home","mountPath":"/var/jenkins_home"}]}],"volumes":[{"name":"jenkins-home","persistentVolumeClaim":{"claimName":"jenkins"}}]}}' \
-n cicd
# 3. 별도 터미널에서 백업 데이터 복사
kubectl cp ./jenkins-home-backup/. cicd/jenkins-restore:/var/jenkins_home/
# 4. 임시 Pod 종료 후 Jenkins Pod 시작
kubectl scale statefulset jenkins -n cicd --replicas=1
JCasC 설정 복원
Helm으로 JCasC 관리 시
make apply로 배포하면 자동 적용되므로 생략 가능
curl -s -u "${JENKINS_USER}:${JENKINS_API_TOKEN}" \
-X POST -H "Content-Type: text/yaml" \
--data-binary @jenkins-casc-export.yaml \
"${JENKINS_URL}/configuration-as-code/apply"
12.4. 권장사항
- JCasC 설정:
values.yaml에 정의하고 GitOps 저장소에서 버전 관리 (별도 백업 불필요) - Jenkins 홈: PVC 스냅샷 또는
kubectl cp로 주기적 백업 - Credentials: JCasC + Kubernetes Secret 참조 방식 권장
13. 문제 해결 (Troubleshooting)
13.1. Pod Pending 상태
- 원인: PVC가
Bound되지 않았거나 리소스(CPU/Memory)가 부족합니다. - 해결:이벤트 로그를 확인하여 문제를 파악합니다.
kubectl describe pod <pod-name> -n cicd
13.2. Ingress 접속 불가
- 원인: Ingress 컨트롤러 문제 또는 TLS Secret 미생성
- 해결:
- Ingress 컨트롤러 로그 확인
- TLS Secret은
securitynamespace에서 생성되어 Reflector를 통해 다른 namespace로 복사됩니다:
# security namespace에서 Certificate 확인 kubectl get certificate -n security # cicd namespace에 Secret이 복사되었는지 확인 kubectl get secret cnapcloud.com-tls -n cicd- Reflector 설정 확인 (Certificate에 다음 annotation이 필요):
reflector.v1.k8s.emberstack.com/reflection-allowed: "true" reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "security,cicd,default,gateway,database"
13.3. GitHub 연결 실패
- 원인: Personal Access Token 권한 부족 또는 만료
- 해결:
- GitHub에서 토큰 권한 확인 (
repo,admin:repo_hook필요) - 토큰이 만료되지 않았는지 확인
- Jenkins에서 Test connection 재시도
- GitHub에서 토큰 권한 확인 (
13.4. GitHub Webhook이 작동하지 않음
- 원인: Webhook URL 오류 또는 네트워크 문제
- 해결:
- GitHub Webhook 설정에서
Recent Deliveries확인 - Jenkins가 외부에서 접근 가능한지 확인
- Jenkins 로그 확인:
kubectl logs -n cicd <jenkins-pod-name>
- GitHub Webhook 설정에서
13.5. 빌드 에이전트 Pod 생성 실패
- 원인: 이미지 Pull 실패 또는 리소스 부족
- 해결:
- Kubernetes Events 확인:
kubectl get events -n cicd --sort-by='.lastTimestamp' - 이미지 저장소 접근 권한 확인
- 노드 리소스 확인
- Kubernetes Events 확인:
13.6. GitLab 연결 실패
- 원인: Access Token 권한 부족 또는 만료
- 해결:
- GitLab에서 토큰 권한 확인 (
api,read_repository,write_repository필요) - 토큰이 만료되지 않았는지 확인
- Jenkins에서 GitLab 서버 연결 테스트 재시도
- GitLab에서 토큰 권한 확인 (
13.7. GitLab Webhook이 작동하지 않음
- 원인: Webhook URL 오류, 네트워크 문제 또는 Outbound requests 미허용
- 해결:
- GitLab Integration 설정에서 Test settings 확인
- GitLab Admin > Settings > Network에서 Outbound requests 허용 확인
- Jenkins가 GitLab에서 접근 가능한지 확인 (내부 네트워크의 경우)
- Jenkins 로그 확인:
kubectl logs -n cicd <jenkins-pod-name>
13.8. OIDC 로그인 실패
- 원인: Keycloak 설정 오류 또는 네트워크 문제
- 해결:
- Keycloak의 Well-known endpoint가 Jenkins에서 접근 가능한지 확인:
curl https://keycloak.cnapcloud.com/realms/cnap/.well-known/openid-configuration - Jenkins 로그 확인:
kubectl logs -n cicd <jenkins-pod-name> - Keycloak 클라이언트 설정에서 Redirect URI가 정확한지 확인
- Client Secret이 올바르게 입력되었는지 확인
- 기본 admin 계정으로 로그인하여 설정 재확인:
https://jenkins.cnapcloud.com/login
- Keycloak의 Well-known endpoint가 Jenkins에서 접근 가능한지 확인:
14. 참고 정보
14.1. Jenkins API Token 사용
Jenkins API를 통해 자동화 작업을 수행할 수 있습니다.
API Token 생성:
- Jenkins UI 우측 상단 사용자 아이콘 선택
- Security 메뉴로 이동
- API Token 섹션에서 Add new Token 클릭
- 토큰 이름 입력 후 Generate
- 생성된 토큰을 안전한 곳에 복사
API 사용 예시:
curl -u admin:11bda33d840757231cc12b0abe1e058762 \
https://jenkins.cnapcloud.com/whoAmI/api/json