1οΈβ£ EC2 μλ² μ€λΉ & RDS μ€λΉ
λ κ°μ EC2 μΈμ€ν΄μ€λ₯Ό t3.medium νμ
μ΄μμΌλ‘ μμ±ν©λλ€.
Jenkins μλ² (EC2 #1): t3.medium
κ°λ° μλ² (EC2 #2): t3.medium
Copy π 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 κ·μΉμμ κ°λ° μλ²μ 보μ κ·Έλ£Ή νμ©
κ°λ° μλ² λ³΄μκ·Έλ£Ή κ°λ° μλ²μ Jenkins μλ²μ λν΄μ νλ ₯μ IP(EIP) μ μ©νκΈ°
μλ² μ μ λ° μ½λ μμμ IP μ
λ ₯ λΆλΆμμ λ§€λ² λ³κ²½νμ§ μλλ‘, κ³ μ IPv4 λ₯Ό μμ±νμ¬, κ° μΈμ€ν΄μ€μ μ°κ²°ν΄μ€λλ€.
π EIP λ μΈμ€ν΄μ€μ μ°κ²° μ€μΌ λλ ν κ° κΉμ§ 무λ£μ΄λ©°, μ°κ²°λμ§ μμ μνλ‘ λλ©΄ μκΈ λΆκ³Ό
2οΈβ£ Jenkins μλ²μ κΈ°λ³Έ νκ²½ μ€μΉ (EC2 #1)
Jenkins μ κ°λ° μλ²μ λν EC2λ Ubuntu 24 λ²μ μ΄λ―Έμ§λ₯Ό μ¬μ©νμ¬ μμ±νμμ΅λλ€.
SSH μ μ ν Docker & Compose μ€μΉ:
3οΈβ£ Jenkins Dockerfile / Docker Compose μΈν
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 νμΌ μΆλ ₯ ν λ³΅μ¬ -> κ°λ°μλ²μ λΆμ¬λ£κΈ°
μ ν¨μ€ μλ²:
κ°λ° μλ²:
μ ν¨μ€ μλ² -> κ°λ° μλ² ssh μ μ ν
μ€νΈ:
6οΈβ£ Jenkins Job (Pipeline) ꡬμ±
Jenkins UIμμ μλ‘μ΄ Item β Pipeline μμ±. GitHub μ°λ ν μλ μμ νμ΄νλΌμΈ μ€ν¬λ¦½νΈ (Jenkinsfile) μμ±:
μμ 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)
Token name, Expiration, Repository access μ€μ
μ΅μν repo, workflow, write:packages μ ν
μμ±λλ ν€ λ³΅μ¬ (λ€μ λ³Ό μ μμ)
Jenkins μμ Credential μ€μ
μλ¨ νλ‘ν -> Credentials ν΄λ¦
Stores from partent μ (global) ν΄λ¦
Add Credentials ν΄λ¦
Username with password λ‘ μ€μ
Username μ Github Id λ‘ μ€μ
Password λ Github μμ μμ±ν ν€ λΆμ¬λ£κΈ°
ID λ 컀μ€ν
νκ² μ€μ νλ, ν΄λΉ ID λ₯Ό Jenkinsfile μμ μ¬μ©ν¨
deploy-server-ssh μ€μ λ°©λ²
μμ λμΌν λ°©λ²μΌλ‘ Add Credentials ν΄λ¦
SSH Username with private key μ ν
ID: deploy-server-ssh *Jenkinsfile μμ sshagent μ λ€μ΄κ°λ κ°
Private Key μ AWS .pem ν€μ λ΄μ© λΆμ¬λ£κΈ°
μλμ κ°μ΄ νμ λ, terminal μ μΆλ ₯λλ κ°μ λ§μ§λ§μ % λ μ μΈνκ³ λ³΅λΆ νλλ‘ νλ€
8οΈβ£ GitHub β Jenkins Webhook μ°κ²°
GitHub repo β Settings β Webhooks
Payload URL: http://<JENKINS_EC2_PUBLIC_IP>:8080/github-webhook/
Content type: application/json
9οΈβ£ Jenkins pipeline μ€μ
β
μλ£
Trouble Shooting
μ ν¨μ€ CI/CD μ°λ μμ
μμ λ°μν λͺ¨λ νΈλ¬λΈ μν
μ κΈ°λ‘ν©λλ€.
ssh μ μ λΆκ°
β
pem ν€ νμΌ κΆν νμΈ
EC2 μ μν λ pem ν€ κΆνμ΄ μλͺ»λλ©΄ λ°λ‘ κ±°μ λ©λλ€.
μ μ κΆνμ μλ μ€ νλμ¬μΌ ν©λλ€:
β
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
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 4 months ago