๐Ÿ‘” Jenkins๋ž€

์  ํ‚จ์Šค(Jenkins)๋ž€ ๋ฌด์—‡์ด๊ณ , ์–ธ์ œ ์‚ฌ์šฉํ•˜๋Š”๊ฑธ๊นŒ?

  • Jenkins๋Š” ์˜คํ”ˆ์†Œ์Šค ๊ธฐ๋ฐ˜์˜ ์ž๋™ํ™” ์„œ๋ฒ„๋กœ, ์ฃผ๋กœ ์ง€์†์  ํ†ตํ•ฉ(CI: Continuous Integration)๊ณผ ์ง€์†์  ๋ฐฐํฌ(CD: Continuous Delivery/Deployment)๋ฅผ ์ž๋™ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

ํŠน์ง•

  • java๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์ ธ, OS์— ์ƒ๊ด€์—†์ด ์‹คํ–‰ ๊ฐ€๋Šฅ
  • ํŒŒ์ดํ”„๋ผ์ธ ๊ธฐ๋ฐ˜์œผ๋กœ ์†Œํ”„ํŠธ์›จ์–ด ๋นŒ๋“œ, ํ…Œ์ŠคํŠธ, ๋ฐฐํฌ ์ž๋™ํ™”
  • ํ”Œ๋Ÿฌ๊ทธ์ธ ์•„ํ‚คํ…์ฒ˜๋กœ ํ™•์žฅ์„ฑ์ด ๋›ฐ์–ด๋‚จ

์  ํ‚จ์Šค์˜ ํ•ต์‹ฌ ์—ญํ• 

๐Ÿ›  1) ์ง€์†์  ํ†ตํ•ฉ (CI)

  • ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ ์ž๋™์œผ๋กœ ๋นŒ๋“œ + ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰
  • ์ฝ”๋“œ ๋ณ‘ํ•ฉ ์‹œ ๋ฌธ์ œ ์กฐ๊ธฐ ํƒ์ง€
  • ์ฝ”๋“œ ํ’ˆ์งˆ ์œ ์ง€ + ๋ฆด๋ฆฌ์ฆˆ ์ฃผ๊ธฐ ๋‹จ์ถ•

๐Ÿ“ฆ 2) ์ง€์†์  ๋ฐฐํฌ/๋ฐฐํฌ (CD)

  • ํ…Œ์ŠคํŠธ ํ†ต๊ณผ ํ›„ ์ž๋™์œผ๋กœ ์Šคํ…Œ์ด์ง• ๋˜๋Š” ์šด์˜ ์„œ๋ฒ„์— ๋ฐฐํฌ
  • ๋ฆด๋ฆฌ์ฆˆ ์ฃผ๊ธฐ ์ž๋™ํ™” โ†’ ๋น ๋ฅธ ํ”ผ๋“œ๋ฐฑ ๋ฃจํ”„

๐Ÿ”„ 3) ์ž๋™ํ™” ์›Œํฌํ”Œ๋กœ์šฐ ๊ด€๋ฆฌ

  • ๋นŒ๋“œ โ†’ ํ…Œ์ŠคํŠธ โ†’ ๋ฐฐํฌ โ†’ ๋ชจ๋‹ˆํ„ฐ๋ง๊นŒ์ง€์˜ ์ „์ฒด ๊ณผ์ •์„ ํŒŒ์ดํ”„๋ผ์ธ์œผ๋กœ ์‹œ๊ฐํ™” Pasted image 20250421164348.png
  • Git Hook, Cron, Webhook, Polling ๋“ฑ ๋‹ค์–‘ํ•œ ํŠธ๋ฆฌ๊ฑฐ ์ง€์›
Webhook vs Polling

ํด๋ง(Poliing) : ์ผ์ • ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์ €์žฅ์†Œ์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ํ™•์ธ
์›นํ›…(Webhook) : ์ €์žฅ์†Œ(Git ๋“ฑ)์— ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ, ์  ํ‚จ์Šค์— ์ฆ‰์‹œ ์•Œ๋ ค์ฃผ๋Š” ๋ฐฉ์‹

์ด๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์  ํ‚จ์Šค์˜ ํŒŒ์ดํ”„ ๋ผ์ธ ์„ค์ •์„ ํ†ตํ•ด ์ด๋ฃจ์–ด ์ง„๋‹ค.

  • ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์กฐ ์˜ˆ์‹œ
pipeline {
    agent any
    triggers {
        // GitHub์—์„œ Webhook์„ ํ†ตํ•ด ์ด๋ฒคํŠธ๊ฐ€ ์˜ฌ ๋•Œ ํŠธ๋ฆฌ๊ฑฐ๋จ
        githubPush()
    }
    stages {
        stage('Checkout') {
            steps {
                git url: 'https://github.com/your-org/your-repo.git', branch: 'main'
            }
        }
        stage('Build') {
            steps {
                sh 'echo Building...'
            }
        }
    }

----

    agent any
    triggers {
        // 5๋ถ„๋งˆ๋‹ค Git ๋ณ€๊ฒฝ์‚ฌํ•ญ ํ™•์ธ (cron ํ‘œํ˜„์‹)
        pollSCM('H/5 * * * *')
    }
    stages {
        stage('Checkout') {
            steps {
                git url: 'https://github.com/your-org/your-repo.git', branch: 'main'
            }
        }
        stage('Build') {
            steps {
                sh 'echo Building...'
            }
        }
    }
}

์  ํ‚จ์Šจ์˜ ์ฃผ์š” ๊ธฐ๋Šฅ

๐Ÿงฑ 1) Job๊ณผ Build System

  • Freestyle Job: ๊ธฐ๋ณธ ์ž‘์—… ๋‹จ์œ„ (๋นŒ๋“œ, ํ…Œ์ŠคํŠธ, ๋ฐฐํฌ ์„ค์ •)
  • Pipeline: Groovy ๊ธฐ๋ฐ˜ DSL๋กœ ๋ฉ€ํ‹ฐ์Šคํ… ์ž‘์—… ์ •์˜
  • Multibranch Pipeline: ๋ธŒ๋žœ์น˜๋งˆ๋‹ค ํŒŒ์ดํ”„๋ผ์ธ ๋ถ„๊ธฐ ์„ค์ •

๐Ÿ”Œ 2) Plugin ์ƒํƒœ๊ณ„

  • 1,800๊ฐœ ์ด์ƒ์˜ ๊ณต์‹ ํ”Œ๋Ÿฌ๊ทธ์ธ
  • ์ฃผ์š” ํ”Œ๋Ÿฌ๊ทธ์ธ:
    • Git / GitHub / Bitbucket
    • Docker
    • Slack / Email Notification
    • Kubernetes
    • SonarQube
    • Artifactory / Nexus

๐Ÿ’ฌ 3) Notification ๋ฐ ์•Œ๋ฆผ ๊ธฐ๋Šฅ

  • ์ด๋ฉ”์ผ, Slack, Teams, Webhook ๋“ฑ ๋‹ค์–‘ํ•œ ์•Œ๋ฆผ ์ง€์›
  • ์‹คํŒจ/์„ฑ๊ณต/๊ฒฝ๊ณ  ์ƒํƒœ์— ๋”ฐ๋ผ ์กฐ๊ฑด๋ถ€ ๋ฉ”์‹œ์ง€ ์ „์†ก ๊ฐ€๋Šฅ

๐Ÿ“Š 4) ๋นŒ๋“œ ์ด๋ ฅ ๋ฐ ๋กœ๊น…

  • ์ž‘์—…๋‹น ๋นŒ๋“œ ๊ฒฐ๊ณผ ๋กœ๊ทธ ์ €์žฅ
  • ์‹คํŒจ ์‹œ ์–ด๋–ค ์Šคํ…์—์„œ ์‹คํŒจํ–ˆ๋Š”์ง€ ๋ช…ํ™•ํžˆ ์ถ”์  ๊ฐ€๋Šฅ

๐Ÿ”’ 5) ์‚ฌ์šฉ์ž ๋ฐ ๊ถŒํ•œ ๊ด€๋ฆฌ

  • LDAP, Active Directory ์—ฐ๋™
  • Role ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ์ œ์–ด (RBAC)
  • Job/Folder ๋‹จ์œ„ ๊ถŒํ•œ ์„ค์ •

โ˜๏ธ 6) ๋ถ„์‚ฐ ๋นŒ๋“œ (Master-Agent ์•„ํ‚คํ…์ฒ˜)

  • Master๋Š” Job ์Šค์ผ€์ค„๋ง ๋ฐ ๊ด€๋ฆฌ
  • Agent (๋…ธ๋“œ)๋Š” ์‹ค์ œ ๋นŒ๋“œ ์‹คํ–‰ ๋‹ด๋‹น
  • ์Šค์ผ€์ผ์•„์›ƒ ๊ตฌ์กฐ๋กœ ๋ถ€ํ•˜ ๋ถ„์‚ฐ ๊ฐ€๋Šฅ

Jenkins์™€ ๋‹ค๋ฅธ CI/CD ๋„๊ตฌ ๋น„๊ต

ํ•ญ๋ชฉ Jenkins GitHub Actions GitLab CI CircleCI
์„ค์น˜ ๋ฐฉ์‹ ์ž์ฒด ์„ค์น˜ (on-prem, cloud) ํด๋ผ์šฐ๋“œ ๊ธฐ๋ฐ˜ ์ž์ฒด/ํด๋ผ์šฐ๋“œ ํด๋ผ์šฐ๋“œ ์ค‘์‹ฌ
ํŒŒ์ดํ”„๋ผ์ธ ์–ธ์–ด Groovy (Jenkinsfile) YAML YAML YAML
ํ™•์žฅ์„ฑ ๋งค์šฐ ๋†’์Œ (ํ”Œ๋Ÿฌ๊ทธ์ธ ์ค‘์‹ฌ) GitHub ์—ฐ๊ณ„ ์ค‘์‹ฌ GitLab๊ณผ ๋ฐ€์ ‘ ๋น ๋ฅธ CI ํŠนํ™”
๋Ÿฌ๋‹ ์ปค๋ธŒ ์ค‘๊ฐ„~๋†’์Œ ์‰ฌ์›€ ์ค‘๊ฐ„ ์‰ฌ์›€

Jenkins์™€ Docker

๋„์ปค์— ๋Œ€ํ•œ ์„ค๋ช… โ–ถ๐Ÿ‹ docker ๋ž€

์  ํ‚จ์Šค์™€ ๋„์ปค๋Š” ์„œ๋ฒ„ ์ž๋™ํ™”(CI/CD)ํ™˜๊ฒฝ์—์„œ ๋งค์šฐ ์ž์ฃผ ํ•จ๊ป˜ ํ™œ์šฉ๋œ๋‹ค. ๋‘ ๋„๊ตฌ์˜ ์—ญํ• ์€ ์„œ๋กœ ๋‹ค๋ฅด์ง€๋งŒ ์„œ๋กœ๋ฅผ ๋ณด์™„ํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

๋จผ์ € ๋„์ปค์˜ ์ฃผ ์—ญํ• ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ํ™˜๊ฒฝ์˜ ์บก์Аํ™” ์ด๋‹ค. ์ด๋ ‡๊ฒŒ ์บก์Аํ™”๋œ ๊ฒƒ์„ ์ด๋ฏธ์ง€ ๋˜๋Š” ์ปจํ…Œ์ด๋„ˆ๋ผ๊ณ  ํ•œ๋‹ค.

์ด๋ฏธ์ง€์™€ ์ปจํ…Œ์ด๋„ˆ?

์ด๋ฏธ์ง€์™€ ์ปจํ…Œ์ด๋„ˆ๋Š” ์‚ฌ์‹ค์ƒ ๊ฐ™์€ ๊ฐœ๋…์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ์šฉ์–ด์ด๋‹ค.

๋„์ปค ์ด๋ฏธ์ง€ : Docker๋ผ๋Š” ํŠน์ • ๊ธฐ์ˆ /ํ”Œ๋žซํผ์„ ํ†ตํ•ด ์ƒ์„ฑ๋˜๊ณ  ๊ด€๋ฆฌ๋˜๋Š” ์ด๋ฏธ์ง€. Docker์— ์ข…์†์ 
์ปจํ…Œ์ด๋„ˆ : ๋ณด๋‹ค ์ผ๋ฐ˜์ ์ธ ์šฉ์–ด๋กœ, ์ปจํ…Œ์ด๋„ˆ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ํ”Œ๋žซํผ์˜ ์ด๋ฏธ์ง€๋ฅผ ๋œปํ•œ๋‹ค.

์ฆ‰, ์  ํ‚จ์Šค์™€ ๋„์ปค์˜ ๊ด€๊ณ„๋ฅผ ์š”์•ฝํ•˜์ž๋ฉด Jenkins๋Š” Docker๋ฅผ ์‚ฌ์šฉํ•ด ์ปจํ…Œ์ด๋„ˆ ํ™˜๊ฒฝ์—์„œ ๋นŒ๋“œ์™€ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ Docker ์ด๋ฏธ์ง€๋กœ ๋นŒ๋“œํ•˜๊ณ  ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๋ฐฐํฌํ•˜๋ฉฐ, ํ•„์š” ์‹œ Jenkins ์ž์ฒด๋„ Docker ์ปจํ…Œ์ด๋„ˆ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

์‹คํ–‰ ํ”Œ๋กœ์šฐ

  1. ํŒŒ์ดํ”„๋ผ์ธ ์‹คํ–‰ ํŠธ๋ฆฌ๊ฑฐ
    • GitHub/GitLab์—์„œ ์ฝ”๋“œ ๋ณ€๊ฒฝ ๋ฐœ์ƒ ์‹œ:
      • โœ… Webhook: ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ Jenkins์— ์ฆ‰์‹œ ์•Œ๋ฆผ
      • โœ… Polling: Jenkins๊ฐ€ ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ณ€๊ฒฝ ์—ฌ๋ถ€ ํ™•์ธ
  2. ์†Œ์Šค์ฝ”๋“œ + Dockerfile ๊ฐ€์ ธ์˜ค๊ธฐ
    • ํŠธ๋ฆฌ๊ฑฐ ๊ฐ์ง€ ํ›„ Jenkins๊ฐ€ Git ์ €์žฅ์†Œ์—์„œ ์ฝ”๋“œ์™€ Dockerfile์„ `checkout
dockerfile

โ†’ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์„ค์ • ํŒŒ์ผ(์Šคํฌ๋ฆฝํŠธ)
์‰ฝ๊ฒŒ ๋งํ•ด, โ€œ์–ด๋–ค OS์—, ์–ด๋–ค ์•ฑ์„ ์„ค์น˜ํ•˜๊ณ , ์–ด๋–ค ๋ช…๋ น์„ ์‹คํ–‰ํ•  ๊ฒƒ์ธ์ง€โ€๋ฅผ ์ •์˜ํ•œ ๋ ˆ์‹œํ”ผ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

  1. Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ
    • docker build -t my-app . ๋ช…๋ น์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ์ƒ์„ฑ
  2. ์ปจํ…Œ์ด๋„ˆ ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰ (์„ ํƒ)
    • docker run์œผ๋กœ ํ…Œ์ŠคํŠธ ์ž๋™ํ™” ์‹คํ–‰
  3. Docker ์ด๋ฏธ์ง€ ํ‘ธ์‹œ
    • DockerHub, ECR ๋“ฑ์— docker push ์ˆ˜ํ–‰
  4. ์„œ๋ฒ„ ๋˜๋Š” ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌ
  5. ์•Œ๋ฆผ ๋ฐ ๋กœ๊ทธ ์ €์žฅ
    • Slack, Email ์•Œ๋ฆผ ์ „์†ก + Jenkins์— ๋นŒ๋“œ ๋กœ๊ทธ ๊ธฐ๋ก