Jenkins

1️⃣ EC2 μ„œλ²„ μ€€λΉ„ & RDS μ€€λΉ„

  • 두 개의 EC2 μΈμŠ€ν„΄μŠ€λ₯Ό t3.medium νƒ€μž… μ΄μƒμœΌλ‘œ μƒμ„±ν•©λ‹ˆλ‹€.

    • Jenkins μ„œλ²„ (EC2 #1): t3.medium

    • 개발 μ„œλ²„ (EC2 #2): t3.medium

    • RDS 생성

πŸ“š t3.medium νƒ€μž… 이상이 ν•„μš”ν•œ 이유
- μ§€κΈˆ μ—¬κΈ°μ„œλŠ” Jenkins 와 Java λ₯Ό Docker Continer 둜 λ„μš°λŠ” 것이 λͺ©μ μž…λ‹ˆλ‹€.
- 일단 Docker λ₯Ό μ„€μΉ˜ν•˜κ³  μ‹€ν–‰ν•˜κ²Œ 되면, 1GB 의 λ©”λͺ¨λ¦¬λŠ” λΆ€μ‘±ν•©λ‹ˆλ‹€.
- t3.micro λ˜λŠ” t3.small νƒ€μž…μ˜ λ©”λͺ¨λ¦¬λŠ” 1GB μž…λ‹ˆλ‹€.
- t3.micro 와 t3.small νƒ€μž…μ€, Jenkins UI κ°€ 맀우 느렸으며, μˆ˜μ‹œλ‘œ μ„œλ²„κ°€ μ£½λŠ” ν˜„μƒμ„
  κ²½ν—˜ν•˜μ˜€μŠ΅λ‹ˆλ‹€. 특히 Jenkins 의 경우 μ»¨ν…Œμ΄λ„ˆλ‘œ λ„μš°λŠ” 경우, μ΅œμ†Œ 4κΈ°κ°€μ˜ 램이 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

λ³΄μ•ˆ κ·Έλ£Ή μ„€μ •

  • Jenkins 와 κ°œλ°œμ„œλ²„μ— λŒ€ν•΄μ„œ λ™μΌν•œ λ³΄μ•ˆ 그룹을 μ‚¬μš©ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

  • ν•„μš”μ— λ”°λΌμ„œ λ³΄μ•ˆ 그룹을 λ‚˜λˆ„μ–΄μ„œ μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  • μ‚¬μš©μž μ§€μ • TCP 8080 port *Jenkins λŠ” 일반적으둜 8080 포트 μƒ€μš©

  • SSH 22 port * SSH 접속을 μœ„ν•΄μ„œ

  • RDS 에 λŒ€ν•œ λ³΄μ•ˆ κ·Έλ£Ή 생성 ν›„, Inbound κ·œμΉ™μ—μ„œ 개발 μ„œλ²„μ˜ λ³΄μ•ˆ κ·Έλ£Ή ν—ˆμš©

개발 μ„œλ²„ λ³΄μ•ˆκ·Έλ£Ή
RDS λ³΄μ•ˆκ·Έλ£Ή

개발 μ„œλ²„μ™€ Jenkins μ„œλ²„μ— λŒ€ν•΄μ„œ 탄λ ₯적 IP(EIP) μ μš©ν•˜κΈ°

μ„œλ²„ 접속 및 μ½”λ“œ μƒμ—μ„œ IP μž…λ ₯ λΆ€λΆ„μ—μ„œ 맀번 λ³€κ²½ν•˜μ§€ μ•Šλ„λ‘, κ³ μ • IPv4 λ₯Ό μƒμ„±ν•˜μ—¬, 각 μΈμŠ€ν„΄μŠ€μ— μ—°κ²°ν•΄μ€λ‹ˆλ‹€.

πŸ“š EIP λŠ” μΈμŠ€ν„΄μŠ€μ™€ μ—°κ²° 쀑일 λ•ŒλŠ” ν•œ 개 κΉŒμ§€ 무료이며, μ—°κ²°λ˜μ§€ μ•Šμ€ μƒνƒœλ‘œ 두면 μš”κΈˆ λΆ€κ³Ό

2️⃣ Jenkins μ„œλ²„μ— κΈ°λ³Έ ν™˜κ²½ μ„€μΉ˜ (EC2 #1)

Jenkins 와 개발 μ„œλ²„μ— λŒ€ν•œ EC2λŠ” Ubuntu 24 버전 이미지λ₯Ό μ‚¬μš©ν•˜μ—¬ μƒμ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

SSH 접속 ν›„ Docker & Compose μ„€μΉ˜:


3️⃣ Jenkins Dockerfile / Docker Compose μ„ΈνŒ…

Dockerfile

jenkins-plugin.txt:

jenkins-plugin.txt λ₯Ό ν†΅ν•΄μ„œ, Java Springboot μ•±μ˜ CI/CD 에 ν•„μš”ν•œ ν”ŒλŸ¬κ·ΈμΈμ„, 미리 μ„€μΉ˜ν•΄μ€λ‹ˆλ‹€.

Docker compose 파일

λ„€μž„λ“œ λ³Όλ₯¨ jenkins_home λ₯Ό μƒμ„±ν•˜μ—¬ κ΄€λ¦¬ν•©λ‹ˆλ‹€.

πŸ“¦ λ„€μž„λ“œ λ³Όλ₯¨(named volume)을 μ‚¬μš©ν•˜λŠ” 이유

Docker κ°€ 직접 관리 β†’ μ„±λŠ₯ μ΅œμ ν™”

  • λ„€μž„λ“œ λ³Όλ₯¨μ€ Docker 엔진이 /var/lib/docker/volumes/ μ•„λž˜μ—μ„œ 직접 κ΄€λ¦¬ν•©λ‹ˆλ‹€.

  • 둜컬 λ””μŠ€ν¬μ™€ 달리 OverlayFS μ΅œμ ν™”κ°€ μ μš©λ˜μ–΄ μž…μΆœλ ₯(I/O) 속도가 더 λΉ λ¦…λ‹ˆλ‹€.

  • Jenkins처럼 μˆ˜λ§Žμ€ μž‘μ€ 파일(ν”ŒλŸ¬κ·ΈμΈ μΊμ‹œ, λΉŒλ“œ 둜그 λ“±)을 λ‹€λ£¨λŠ” 경우 μ„±λŠ₯ 차이가 ν½λ‹ˆλ‹€.

    • 둜컬 λ°”μΈλ“œ λ§ˆμš΄νŠΈλŠ” 호슀트 νŒŒμΌμ‹œμŠ€ν…œκ³Ό Docker OverlayFS μ‚¬μ΄μ—μ„œ I/O overheadκ°€ λ°œμƒν•©λ‹ˆλ‹€.

    • JenkinsλŠ” 수천 개의 μž‘μ€ νŒŒμΌμ„ λ‹€λ£¨λ―€λ‘œ 속도 μ €ν•˜κ°€ μ‹¬κ°ν•΄μ§‘λ‹ˆλ‹€.

    • macOS/Windowsμ—μ„œλŠ” Hypervisorλ₯Ό 거치기 λ•Œλ¬Έμ— 더 λŠλ €μ§‘λ‹ˆλ‹€.

데이터 μ˜μ†μ„± 보μž₯

  • μ»¨ν…Œμ΄λ„ˆκ°€ μ‚­μ œλ˜μ–΄λ„ λ„€μž„λ“œ λ³Όλ₯¨μ€ λ‚¨μ•„μžˆμŠ΅λ‹ˆλ‹€.

  • docker compose down -v둜 λͺ…μ‹œμ μœΌλ‘œ μ‚­μ œν•˜κΈ° μ „κΉŒμ§€λŠ” μ•ˆμ „ν•˜κ²Œ λ³΄κ΄€λ©λ‹ˆλ‹€.

  • Jenkins μ„œλ²„λ₯Ό μž¬λ°°ν¬ν•΄λ„ μ„€μ •, ν”ŒλŸ¬κ·ΈμΈ, λΉŒλ“œ νžˆμŠ€ν† λ¦¬κ°€ κ·ΈλŒ€λ‘œ μœ μ§€λ©λ‹ˆλ‹€.

호슀트 경둜 독립성

  • νŠΉμ • 경둜(./jenkins_home)에 μ˜μ‘΄ν•˜μ§€ μ•Šκ³ , μ–΄λ–€ μ„œλ²„/ν™˜κ²½μ—μ„œλ„ λ™μΌν•˜κ²Œ λ™μž‘ν•©λ‹ˆλ‹€.

  • μ—¬λŸ¬ 개발자/μš΄μ˜μžκ°€ 같은 compose νŒŒμΌμ„ 써도 둜컬 파일 경둜 좩돌이 μ—†μŠ΅λ‹ˆλ‹€.

μ‹€ν–‰

처음 μ‹€ν–‰ν•˜λ©΄ Jenkins κ΄€λ¦¬μž λΉ„λ°€λ²ˆν˜Έλ₯Ό λ‘œκ·Έμ—μ„œ 확인:

  • λΈŒλΌμš°μ €μ—μ„œ http://<JENKINS_EC2_PUBLIC_IP>:8080 접속 β†’

  • Unlock Jenkins (λ‘œκ·Έμ—μ„œ λΉ„λ°€λ²ˆν˜Έ 확인)

  • κ΄€λ¦¬μž 계정 생성

  • ν”ŒλŸ¬κ·ΈμΈ μ„€μΉ˜

    • μœ„μ˜ jenkins_plugin.txt λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³ , 직접 μ„€μΉ˜ν•˜λŠ” 경우

    • Github, SSH Agent, Pipeline λ“± μ„€μΉ˜

4️⃣ 배포 μ„œλ²„ (EC2 #2) μ„€μ •

배포 μ„œλ²„μ—λ„ Docker & Docker Compose μ„€μΉ˜ (Spring Boot 배포용):

μœ„μ˜, 2️⃣ Jenkins μ„œλ²„μ— κΈ°λ³Έ ν™˜κ²½ μ„€μΉ˜ (EC2 #1) μ°Έμ‘°

5️⃣ Jenkins β†’ 배포 μ„œλ²„ SSH μ—°κ²°

Jenkinsfile 을 ν”„λ‘œμ νŠΈ λ£¨νŠΈμ— μƒμ„±ν•˜μ—¬, Jenkins μ—μ„œ ν•΄λ‹Ή 파일의 슀크립트λ₯Ό μ‹€ν–‰ν•  μ˜ˆμ •μž…λ‹ˆλ‹€. κ·Έλ ‡κ²Œ ν•˜κΈ° μœ„ν•΄μ„œλŠ”, Jenkins μ„œλ²„μ—μ„œ 개발 μ„œλ²„λ‘œμ˜ ssh 접속이 κ°€λŠ₯ν•΄μ•Ό ν•©λ‹ˆλ‹€.

  • Jenkins μ„œλ²„μ—μ„œ ssh-keygen 을 μ‚¬μš©ν•˜μ—¬, ν‚€ νŒŒμΌμ„ λ§Œλ“€μ–΄μ€λ‹ˆλ‹€.

  • μƒμ„±λœ rsa 퍼블릭킀λ₯Ό, 개발 μ„œλ²„μ— λ“±λ‘ν•΄μ€λ‹ˆλ‹€.

  • 개발 μ„œλ²„μ˜ ~/.ssh/authrized_keys 에 μΆ”κ°€ν•©λ‹ˆλ‹€.

μ  ν‚¨μŠ€ μ„œλ²„μ—μ„œ cat 으둜 .pub 파일 좜λ ₯ ν›„ 볡사 -> κ°œλ°œμ„œλ²„μ— λΆ™μ—¬λ„£κΈ°

μ  ν‚¨μŠ€ μ„œλ²„:

Jenkins μ„œλ²„

개발 μ„œλ²„:

개발 μ„œλ²„

μ  ν‚¨μŠ€ μ„œλ²„ -> 개발 μ„œλ²„ ssh 접속 ν…ŒμŠ€νŠΈ:

6️⃣ Jenkins Job (Pipeline) ꡬ성

Jenkins UIμ—μ„œ μƒˆλ‘œμš΄ Item β†’ Pipeline 생성. GitHub 연동 ν›„ μ•„λž˜ μ˜ˆμ‹œ νŒŒμ΄ν”„λΌμΈ 슀크립트 (Jenkinsfile) μž‘μ„±:

Jenkinsfile-dev

μœ„μ˜ credential 섀정에 λŒ€ν•΄μ„œλŠ”, μ•„λž˜μ˜ [7️⃣ Jenkins Credential μ„€μ •] μ—μ„œ μ„€λͺ…ν•œλ‹€.

  • credentialsId: 'my-jenkins-credentials'

  • sshagent (credentials: ['deploy-server-ssh'])

πŸ“š TIPs - pipeline μ•„λž˜μ˜ tools java 등을 μ„€μ •ν•˜μ§€ μ•Šμ€ 이유

  • μ§€κΈˆ μ„€μΉ˜λœ Jenkins dockerfile 은 이미 Java 21 버전이 μ„€μΉ˜λ˜μ–΄ 있기 λ•Œλ¬Έμ—, λ³„λ„μ˜ tools 섀정이 ν•„μš” μ—†μŠ΅λ‹ˆλ‹€.

7️⃣ Jenkins Credential μ„€μ •

μ—¬κΈ°μ„œλŠ” μ•„λž˜μ˜ credentialsId 와 sshagent 의 credentials 에 λ“€μ–΄κ°€λŠ” 값에 λŒ€ν•΄μ„œ μ„€λͺ…ν•©λ‹ˆλ‹€.

πŸ”‘ credentialsId κ°€ ν•„μš”ν•œ 이유

GitHub 인증 문제 ν•΄κ²°

  • Jenkinsμ—μ„œ git ν”ŒλŸ¬κ·ΈμΈμ„ 톡해 private repoλ₯Ό clone/pull ν•˜λ €λ©΄ 인증이 ν•„μš”ν•©λ‹ˆλ‹€.

  • μ˜ˆμ „μ—λŠ” GitHub username/passwordλ₯Ό μΌμ§€λ§Œ, μ§€κΈˆμ€ Personal Access Token (PAT) λ˜λŠ” SSH key만 μ§€μ›ν•©λ‹ˆλ‹€.

  • credentialsIdλŠ” Jenkins λ‚΄λΆ€ Credentials Store에 μ €μž₯된 인증 정보λ₯Ό μ°Έμ‘°ν•˜κΈ° μœ„ν•œ ν‚€μž…λ‹ˆλ‹€.

λ³΄μ•ˆ μœ μ§€

  • Jenkinsfile에 직접 ν† ν°μ΄λ‚˜ λΉ„λ°€λ²ˆν˜Έλ₯Ό 적으면 λ³΄μ•ˆμƒ μœ„ν—˜ν•©λ‹ˆλ‹€. (GitHub에 λ…ΈμΆœλ  수 있음)

  • λŒ€μ‹  Jenkins Credentials Store에 μ•ˆμ „ν•˜κ²Œ μ €μž₯ν•˜κ³ , Jenkinsfileμ—μ„œλŠ” credentialsId 만 λͺ…μ‹œν•©λ‹ˆλ‹€.

  • μ‹€μ œ 비밀값은 λΉŒλ“œ μ‹€ν–‰ μ‹œμ μ—λ§Œ μ£Όμž…λ©λ‹ˆλ‹€.

μœ μ—°ν•œ 관리

  • 같은 Jenkinsfile을 쓰더라도 Jenkins μ„œλ²„λ§ˆλ‹€ λ‹€λ₯Έ 인증정보λ₯Ό μ—°κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  • 예: 둜컬 JenkinsλŠ” 개인 GitHub 토큰, νšŒμ‚¬ JenkinsλŠ” 쑰직 계정 토큰 β†’ μ½”λ“œ μˆ˜μ • 없이 κ°€λŠ₯.

credentialsId μ„€μ • 방법

Github 접속

  • 였λ₯Έμͺ½ 상단 profile -> settings

  • μ™Όμͺ½ ν•˜λ‹¨ <> Developer settings

  • Personal access tokens -> Tokens (classic)

  • Generate new token

  • Token name, Expiration, Repository access μ„€μ •

  • μ΅œμ†Œν•œ repo, workflow, write:packages 선택

  • μƒμ„±λ˜λŠ” ν‚€ 볡사 (λ‹€μ‹œ λ³Ό 수 μ—†μŒ)

Jenkins μ—μ„œ Credential μ„€μ •

  • 상단 ν”„λ‘œν•„ -> Credentials 클릭 jenkins-credentials

  • Stores from partent 의 (global) 클릭 jenkins-credentials

  • Add Credentials 클릭 jenkins-credentials

  • Username with password 둜 μ„€μ •

    • Username 은 Github Id 둜 μ„€μ •

    • Password λŠ” Github μ—μ„œ μƒμ„±ν•œ ν‚€ λΆ™μ—¬λ„£κΈ°

    • ID λŠ” μ»€μŠ€ν…€ν•˜κ²Œ μ„€μ •ν•˜λ˜, ν•΄λ‹Ή ID λ₯Ό Jenkinsfile μ—μ„œ μ‚¬μš©ν•¨

    • jenkins-credentials

deploy-server-ssh μ„€μ • 방법

  • μœ„μ™€ λ™μΌν•œ λ°©λ²•μœΌλ‘œ Add Credentials 클릭

  • SSH Username with private key 선택

  • ID: deploy-server-ssh *Jenkinsfile μ—μ„œ sshagent 에 λ“€μ–΄κ°€λŠ” κ°’

  • Username: ubuntu

  • Private Key 에 AWS .pem ν‚€μ˜ λ‚΄μš© λΆ™μ—¬λ„£κΈ°

    • μ•„λž˜μ™€ 같이 ν–ˆμ„ λ•Œ, terminal 에 좜λ ₯λ˜λŠ” κ°’μ˜ λ§ˆμ§€λ§‰μ— % λŠ” μ œμ™Έν•˜κ³  볡뢙 ν•˜λ„λ‘ ν•œλ‹€

jenkins credential

8️⃣ GitHub β†’ Jenkins Webhook μ—°κ²°

  • GitHub repo β†’ Settings β†’ Webhooks

    • Payload URL: http://<JENKINS_EC2_PUBLIC_IP>:8080/github-webhook/

    • Content type: application/json

github webhook

9️⃣ Jenkins pipeline μ„€μ •

pipeline
pipeline
pipeline
pipeline
pipeline
pipeline
pipeline
pipeline
pipeline

βœ… μ™„λ£Œ


Trouble Shooting

μ  ν‚¨μŠ€ CI/CD 연동 μž‘μ—…μ—μ„œ λ°œμƒν•œ λͺ¨λ“  νŠΈλŸ¬λΈ” μŠˆνŒ…μ„ κΈ°λ‘ν•©λ‹ˆλ‹€.

ssh 접속 λΆˆκ°€

βœ… pem ν‚€ 파일 κΆŒν•œ 확인

EC2 접속할 λ•Œ pem ν‚€ κΆŒν•œμ΄ 잘λͺ»λ˜λ©΄ λ°”λ‘œ κ±°μ ˆλ©λ‹ˆλ‹€.

정상 κΆŒν•œμ€ μ•„λž˜ 쀑 ν•˜λ‚˜μ—¬μ•Ό ν•©λ‹ˆλ‹€:

  • -r-------- (chmod 400)

  • -rw------- (chmod 600)

βœ… 2. EC2 λ³΄μ•ˆ κ·Έλ£Ή (Security Group) μ„€μ •

AWS μ½˜μ†” β†’ EC2 β†’ μΈμŠ€ν„΄μŠ€ 선택 β†’ λ³΄μ•ˆ κ·Έλ£Ή 확인

  • Inbound κ·œμΉ™μ— μ•„λž˜κ°€ μžˆμ–΄μ•Ό 함:

    • SSH (TCP) / 포트 22 / μ†ŒμŠ€: λ‚΄ IP (λ˜λŠ” 0.0.0.0/0 ν…ŒμŠ€νŠΈμš©)

βœ… 3. μ˜¬λ°”λ₯Έ μœ μ €λͺ… 확인

AMI μ’…λ₯˜μ— 따라 접속 계정이 λ‹¬λΌμ§‘λ‹ˆλ‹€.

  • Amazon Linux 2 / Amazon Linux 2023 β†’ ec2-user

  • Ubuntu β†’ ubuntu

  • CentOS β†’ centos

  • RHEL β†’ ec2-user λ˜λŠ” root

즉, AMIκ°€ Ubuntu라면 μ•„λž˜μ²˜λŸΌ μ‹œλ„ν•΄μ•Ό ν•©λ‹ˆλ‹€:

βœ… 4. 퍼블릭 IP / Elastic IP 확인

  • EC2에 퍼블릭 IPv4 μ£Όμ†Œκ°€ 할당돼 μžˆλŠ”μ§€ (λ˜λŠ” Elastic IP μ—°κ²°ν–ˆλŠ”μ§€) 확인

  • 프라이빗 μ„œλΈŒλ„·μ—λ§Œ 있으면 μ™ΈλΆ€μ—μ„œ μ ‘κ·Ό λΆˆκ°€

βœ… 5. λ„€νŠΈμ›Œν¬ ACL / VPC λΌμš°νŒ… 확인

  • 퍼블릭 μ„œλΈŒλ„·μ— μžˆμ–΄μ•Ό μ™ΈλΆ€ μ ‘κ·Ό κ°€λŠ₯

  • 인터넷 κ²Œμ΄νŠΈμ›¨μ΄(IGW)κ°€ VPC에 연결돼 μžˆμ–΄μ•Ό 함

βœ… 6. SSH 둜그 확인 (EC2 λ‚΄λΆ€)

ν˜Ήμ‹œ 이미 λ‚΄λΆ€ μ½˜μ†”λ‘œ λ“€μ–΄κ°ˆ 수 μžˆλ‹€λ©΄ (AWS Systems Manager Session Manager 같은 것)

  • /var/log/secure λ˜λŠ” /var/log/auth.log ν™•μΈν•΄μ„œ SSH 거절 이유 확인 κ°€λŠ₯

docker compose up λͺ…λ Ήμ–΄λ₯Ό μˆ˜ν–‰ν•  λ•Œ permission denided

μ—λŸ¬ λ©”μ„Έμ§€μ˜ 핡심은 μ•„λž˜μ˜ 메세지이닀.

μœ„μ—μ„œ ν˜„μž¬ μœ μ €λ₯Ό docker group 에 μΆ”κ°€ν•˜λŠ” λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰ν•˜μ˜€λŠ”λ°, κ·Έλ£Ή 변경은 μ¦‰μ‹œ 반영이 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ—, μ„Έμ…˜μ„ μƒˆλ‘œ μ—΄μ–΄μ•Ό ν•œλ‹€. λ”°λΌμ„œ, λ‘œκ·Έμ•„μ›ƒ ν›„ λ‹€μ‹œ ec2 에 μ ‘μ†ν•œλ‹€.

κ·Έλ£Ή ν™•μΈν•˜μ—¬, docker κ°€ ν¬ν•¨λ˜μ–΄ μžˆμ–΄μ•Ό ν•œλ‹€.

Last updated