๐ŸณDocker&๐Ÿ‘ฉ๐Ÿปโ€๐ŸฆฒJenkins๋ฅผ ํ†ตํ•œCI&CD ์ด๊ฑฐ๋ณด๊ณ  ์„ฑ๊ณตํ•˜์„ธ์š”๐Ÿ˜๐Ÿ˜๐Ÿ˜

์ด์ฐฝํฌยท2022๋…„ 9์›” 24์ผ
0
post-thumbnail

๋“ค์–ด๊ฐ€๊ธฐ์ „...

์‰ฝ์ง€์•Š์•˜๋˜ Docker&Jenkins์ด์˜€์Šต๋‹ˆ๋‹ค... ๊ทธ๋ ‡์ง€๋งŒ 4๋ฒˆ์˜ ์‹คํŒจ ๋์— ์„ฑ๊ณตํ•ด๋ƒˆ์Šต๋‹ˆ๋‹ค!!!(์™œ ์  ํ‚จ์Šค ๋กœ๊ณ ๊ฐ€ ํƒˆ๋ชจ์ธ์ง€ ์•Œ๊ฒŒ๋˜๋Š”...ใ…Ž)
์ œ๊ฐ€ ๊ฒช์—ˆ๋˜ ๋„์ค‘์— ์—๋Ÿฌ๋“ค๊ณผ ํ•„์š”ํ–ˆ๋˜ ๊ณผ์ •์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ๋ธ”๋กœ๊ทธ์˜ ๊ธ€์„ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์ด ๋งŽ์€ ๊ธ€์ด ๋˜๊ฒ ์ง€๋งŒ... ์กฐ๊ธˆ์ด๋ผ๋„ ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ํ•˜๋Š” ๋งˆ์Œ์— ์ž‘์„ฑํ•ด๋ด…๋‹ˆ๋‹ค!

๊ตฌ์„ฑ์š”์†Œ

  • Jenkins Serverย : AWS EC2 Ubuntu 18.04
  • Spring Boot Serverย : AWS EC2 Ubuntu 18.04
  • Github Repository
  • Docker Hub Repository

    ๋„์ปคํŒŒ์ผ(ํŒŒ์ผ๋ช…: Dockerfile)

    • ์œ„์น˜๋Š” bulid.gradle๊ณผ ๊ฐ™์€์œ„์น˜์— ๋‘ก๋‹ˆ๋‹ค.

      # JDK11 ์ด๋ฏธ์ง€ ์‚ฌ์šฉ
      FROM openjdk:11-jdk
      
      VOLUME /tmp
      
      # JAR_FILE ๋ณ€์ˆ˜์— ๊ฐ’์„ ์ €์žฅ
      ARG JAR_FILE=./build/libs/*.jar
      # ๋ณ€์ˆ˜์— ์ €์žฅ๋œ ๊ฒƒ์„ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰์‹œ ์ด๋ฆ„์„ app.jarํŒŒ์ผ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ์— ์ €์žฅ
      COPY ${JAR_FILE} app.jar
      
      # ๋นŒ๋“œ๋œ ์ด๋ฏธ์ง€๊ฐ€ run๋  ๋•Œ ์‹คํ–‰ํ•  ๋ช…๋ น์–ด
      ENTRYPOINT ["java","-jar","app.jar"]

      bulid.gradle

      plugins {
          id 'org.springframework.boot' version '2.7.3'
          id 'io.spring.dependency-management' version '1.0.13.RELEASE'
          id 'java'
      }
      
      jar {
          enabled = false
      }
      
      bootJar{
          archivesBaseName = 'app'
          archiveFileName = 'app.jar'
          archiveVersion = "0.0.0"
      }
      
      group = 'com.example'
      version = '0.0.1-SNAPSHOT'
      sourceCompatibility = '11'
      
      configurations {
          compileOnly {
              extendsFrom annotationProcessor
          }
      }
      
      repositories {
          mavenCentral()
      }
      
      dependencies {
          implementation 'org.springframework.boot:spring-boot-starter-web'
          compileOnly 'org.projectlombok:lombok'
          developmentOnly 'org.springframework.boot:spring-boot-devtools'
          annotationProcessor 'org.projectlombok:lombok'
          testImplementation 'org.springframework.boot:spring-boot-starter-test'
      }
      
      tasks.named('test') {
          useJUnitPlatform()
      }

์ง„ํ–‰์ˆœ์„œ

  1. Ec2 ์ค€๋น„ ๋ฐ ์ดˆ๊ธฐ ์„ค์ •
  2. Jenkins Server์— Docker ์„ค์น˜
  3. Jenkins Server์— Docker๋ฅผ ์ด์šฉํ•˜์—ฌ Jenkins ์‹คํ–‰
  4. Jenkins ์ ‘์†
  5. Jenkins์™€ Github ์—ฐ๋™
  6. Jenkins์™€ Docker Hub ์—ฐ๊ฒฐ
  7. Jenkins Server์™€ Spring Boot Server SSH ์—ฐ๊ฒฐ ์„ค์ •
  8. Jenkins Pipeline ๊ตฌ์„ฑ

1. ec2 ์ค€๋น„ ๋ฐ ์ดˆ๊ธฐ ์„ค์ •

ec2 ์ŠคํŽ™

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ OS ์ด๋ฏธ์ง€ : Ubuntu
  • ์ธ์Šคํ„ด์Šค ์œ ํ˜• : t2.micro
  • ํ‚คํŽ˜์–ด ํ•„์ˆ˜

EC2์— ํƒ„๋ ฅ์  IP ํ• ๋‹นํ•˜๊ธฐ

  • ์ธ์Šคํ„ด์Šค๋Š” ์ƒ์„ฑ ์‹œ์— ํ•ญ์ƒ ์ƒˆ IP๋ฅผ ํ• ๋‹นํ•œ๋‹ค. ๋‹ค์‹œ ์‹œ์ž‘ํ•  ๋–„๋„ ์ƒˆ IP๋ฅผ ํ• ๋‹นํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋งค๋ฒˆ IP๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€์•Š๊ณ  ๊ณ ์ • IP๋ฅผ ๊ฐ€์ ธ๊ฐ€๊ธฐ ์œ„ํ•ด ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.(ํŽธ๋ฆฌ๋ฅผ ์œ„ํ•œ ์„ค์ • ์ž…๋‹ˆ๋‹ค^^)

EC2 ์ ‘์†ํ•˜๊ธฐ

  • ๊ธฐ๋ณธ๋ฐฉ๋ฒ•
    ssh -i pemํ‚ค์œ„์น˜ ํƒ„๋ ฅ์ IP์ฃผ์†Œ
  • ์ถ”์ฒœ๋ฐฉ๋ฒ•
    //pemํŒŒ์ผ์„ ~/.ssh/๋กœ ๋ณต์‚ฌ
    cp pemํ‚ค์˜์œ„์น˜ ~/.ssh/
    
    // pemํ‚ค์˜ ๊ถŒํ•œ์„ ๋ณ€๊ฒฝ
    chmod 600 ~/.ssh/pemํ‚คํŒŒ์ผ๋ช….pem
    
    // ~/.ssh๋””๋ ‰ํ† ๋ฆฌ์— config ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    vim ~/.ssh/config
    • config ํŒŒ์ผ ์ž‘์„ฑ

      Host springBoot
              HostName [ํ•ด๋‹น ํƒ„๋ ฅ์  IP์ฃผ์†Œ]
              User ubuntu
              IdentityFile ~/.ssh/[ํ•ด๋‹น ํ‚คํŽ˜์–ด.pem]
      Host jenkins
              HostName [ํ•ด๋‹น ํƒ„๋ จ์  IP์ฃผ์†Œ]
              User ubuntu
              IdentityFile ~/.ssh/[ํ•ด๋‹น ํ‚คํŽ˜์–ด.pem]

      ์œ„์™€ ๊ฐ™์ด ์ž‘์„ฑ์„ ๋งˆ์น˜๋ฉด :wq๋ช…๋ น์–ด๋กœ ์ €์žฅํ•˜๊ณ  ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

      ์ƒ์„ฑ๋œ configํŒŒ์ผ์— ์‹คํ–‰ ๊ถŒํ•œ ์„ค์ •

      chmod 700 ~/.ssh/config

      ์ด์ œ ์ ‘์†์‹œ ssh Host ๋ช… ์œผ๋กœ ์ ‘์†ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

      ex:) ssh springBoot

2. Jenkins Server์— Docker ์„ค์น˜

jenkins server์— ์ ‘์†ํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ด EC2 ์ดˆ๊ธฐ์„ค์ •์„ ๋งˆ๋ฌด๋ฆฌํ•ฉ๋‹ˆ๋‹ค

sudo apt update
sudo apt upgrade
sudo apt install build-essential

Docker ์„ค์น˜

1. ๊ธฐ๋ณธ ์„ค์ •, ์‚ฌ์ „ ์„ค์น˜

$ sudo apt update
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common

2. ์ž๋™ ์„ค์น˜ ์Šคํฌ๋ฆฝํŠธ ํ™œ์šฉ

๋ฆฌ๋ˆ…์Šค ๋ฐฐํฌํŒ ์ข…๋ฅ˜๋ฅผ ์ž๋™์œผ๋กœ ์ธ์‹ํ•˜์—ฌ Docker ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ด์ฃผ๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ œ๊ณต

$ sudo wget -qO- https://get.docker.com/ | sh

3. Docker ์„œ๋น„์Šค ์‹คํ–‰ํ•˜๊ธฐ ๋ฐ ๋ถ€ํŒ… ์‹œ ์ž๋™ ์‹คํ–‰ ์„ค์ •

$ sudo systemctl start docker
$ sudo systemctl enable docker

4. Docker ๊ทธ๋ฃน์— ํ˜„์žฌ ๊ณ„์ • ์ถ”๊ฐ€

$ sudo usermod -aG docker ${USER}
$ sudo systemctl restart docker
  • sudo๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  docker๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • docker ๊ทธ๋ฃน์€ root ๊ถŒํ•œ๊ณผ ๋™์ผํ•˜๋ฏ€๋กœ ๊ผญ ํ•„์š”ํ•œ ๊ณ„์ •๋งŒ ํฌํ•จํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
  • ํ˜„์žฌ ๊ณ„์ •์—์„œ ๋กœ๊ทธ์•„์›ƒํ•œ ๋’ค ๋‹ค์‹œ ๋กœ๊ทธ์ธ

5. Docker ์„ค์น˜ ํ™•์ธ

$ docker -v

Jenkins Server์— Docker๋ฅผ ์ด์šฉํ•˜์—ฌ Jenkins ์‹คํ–‰

1. Jenkins ์ด๋ฏธ์ง€ ํŒŒ์ผ ๋‚ด๋ ค๋ฐ›๊ธฐ(lts ๋ฒ„์ „)

$ docker pull jenkins/jenkins:lts

2. ๋‚ด๋ ค๋ฐ›์•„์ง„ ์ด๋ฏธ์ง€ ํ™•์ธ

$ docker images

3. Jenkins ์ด๋ฏธ์ง€๋ฅผ Container๋กœ ์‹คํ–‰

$ docker run -d -p 8080:8080 -p 50000:50000 -v /jenkins:/var/jenkins -v /home/ubuntu/.ssh:/root/.ssh -v /var/run/docker.sock:/var/run/docker.sock --name jenkins -u root jenkins/jenkins:lts

4. ๋Œ์•„๊ฐ€๊ณ  ์žˆ๋Š” Container ํ™•์ธ

$ docker ps
๐Ÿ’ก EC2 ํ”„๋ฆฌํ‹ฐ์–ด ์‚ฌ์šฉ์‹œ Jenkins๊ฐ€ ์ฃฝ์–ด์š” ๐Ÿ˜‚

ํ˜„์žฌ ์  ํ‚จ์Šค ์„œ๋ฒ„๋กœ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋ฆฌํ‹ฐ์–ด EC2๋Š” ์  ํ‚จ์Šค๋ฅผ ๋ฒ„ํ‹ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์  ํ‚จ์Šค๋ฅผ ๋„์ปค๋กœ ๋„์šฐ๊ณ  ์„ค์ •๊นŒ์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์œผ๋‚˜ ๊นƒํ—ˆ๋ธŒ ์›นํ›…์œผ๋กœ ์  ํ‚จ์Šค๋ฅผ ์ด์šฉํ•ด spring์„ ๋นŒ๋“œํ•˜๋Š” ๊ณผ์ •์—์„œ ๋žจ์„ 1๊ธฐ๊ฐ€ ์ด์ƒ(ํ”„๋ฆฌํ‹ฐ์–ด EC2 ๋žจ์€ 1๊ธฐ๊ฐ€) ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด์„œ EC2๊ฐ€ ๋จนํ†ต์ด ๋˜์–ด๋ฒ„๋ฆฝ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ์˜ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ์œผ๋กœ๋Š” ๋ฆฌ๋ˆ…์Šค์˜ ํ•˜๋“œ๋””์Šคํฌ๋ฅผ ๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌ๋กœ ์ „ํ™˜์‹œ์ผœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ์ด์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

  • ์Šค์™‘ ํŒŒ์ผ ์ƒ์„ฑ๋ฐฉ๋ฒ• 1. ์Šค์™‘ ํŒŒ์ผ ์ƒ์„ฑํ•˜๊ธฐ ****์•„๋ž˜ ๋ช…๋ น์€ ์‹œ๊ฐ„์ด ์•ฝ 10~20์ดˆ ์ •๋„ ๊ฑธ๋ฆฌ๋ฏ€๋กœ ์—ฌ์œ ์žˆ๊ฒŒ ๊ธฐ๋‹ค๋ฆฌ๋ฉด ๋ฉ๋‹ˆ๋‹ค. sudo dd if=/dev/zero of=/swapfile bs=128M count=16
    • dd ๋ฉธ๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฃจํŠธ ํŒŒ์ผ ์‹œ์Šคํ…œ์— ์Šค์™‘ ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    • ๋ช…๋ น์—์„œ dd๋Š” ๋ธ”๋ก ํฌ๊ธฐ์ด๊ณ  count๋Š” ๋ธ”๋ก ์ˆ˜ ์ž…๋‹ˆ๋‹ค.

    • ์ง€์ •ํ•œ ๋ธ”๋ก ํฌ๊ธฐ๋Š” ์ธ์Šคํ„ด์Šค์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ณด๋‹ค ์ž‘์•„์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด memory exhauted ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

    • ํ”„๋ฆฌํ‹ฐ์–ด์˜ ๋ฉ”๋ชจ๋ฆฌ๋Š” 1GB์ด๋ฏ€๋กœ ๊ถŒ์žฅ์‚ฌํ•ญ๋Œ€๋กœ 2GB๋ฅผ ์ฆ์„ค์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    • ํ˜„์žฌ ์œ„ ์ฝ”๋“œ๋Œ€๋กœ๋ผ๋ฉด 2GB(128MB * 16 = 2,048MB) ์ž…๋‹ˆ๋‹ค

      2. ์Šค์™‘ ํŒŒ์ผ์— ๋Œ€ํ•œ ์ฝ๊ธฐ ์“ฐ๊ธฐ ๊ถŒํ•œ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ

      sudo chmod 600 /swapfile

      3. Linux ์Šค์™‘ ์˜์—ญ ์„ค์ •ํ•˜๊ธฐ

      sudo mkswap /swapfile

      4. ์Šค์™‘ ๊ณต๊ฐ„์— ์Šค์™‘ ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์Šค์™‘ ํŒŒ์ผ์„ ์ฆ‰์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ธฐ

      sudo swapon /swapfile

      5. ์ ˆ์ฐจ๊ฐ€ ์„ฑ๊ณตํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ

      sudo swapon -s

      6. /etc/fstab ํŒŒ์ผ์„ ํŽธ์ง‘ํ•˜์—ฌ ๋ถ€ํŒ… ์‹œ ์Šค์™‘ ํŒŒ์ผ์„ ํ™œ์„ฑํ™”ํ•˜๊ธฐ

      ํŒŒ์ผ ์—ด๊ธฐ
      sudo vi /etc/fstab
      
      ํŒŒ์ผ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•˜๊ณ  :wq๋กœ ์ €์žฅํ•˜๊ณ  ์ข…๋ฃŒ
      /swapfile swap swap defaults 0 0

      7. free ๋ช…๋ น์–ด๋กœ ๋ฉ”๋ชจ๋ฆฌ ํ™•์ธํ•˜๊ธฐ

      free

4.Jenkins ์ ‘์†

1. ๋ธŒ๋ผ์šฐ์ €์—์„œ [EC2 ์ธ์Šคํ„ด์Šค URL]:8080์œผ๋กœ ์ ‘์†

๋ณด์•ˆ๊ทธ๋ฃน์—์„œ 8080 - > ๋‚ดIP๋ฅผ ์ถ”๊ฐ€ํ•ด์ค˜์•ผํ•œ๋‹ค.

2. ์•”ํ˜ธ ์ž…๋ ฅ

/var/lib/jenkins/secrets/initialAdminPassword๋ฅผ ํ™•์ธํ•ด์•ผ ํ•˜๋Š”๋ฐ Jenkins Container์— ์ ‘์†ํ•˜์—ฌ ์–ป์–ด์˜ค๊ฑฐ๋‚˜ "docker logs jenkins" ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

// Container ์ ‘์†
$ docker exec -it jenkins bash

// ์•”ํ˜ธ ํŒŒ์ผ ํ™•์ธ
$ cat /var/lib/jenkins/secrets/initialAdminPassword

3. Install suggested plugins๋กœ ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜

4. Jenkins ๊ณ„์ • ์ƒ์„ฑ

Jenkins ๋ฉ”์ธ ๋Œ€์‹œ๋ณด๋“œ ํŽ˜์ด์ง€๊ฐ€ ๋‚˜์˜ค๋ฉด ์„ฑ๊ณต

5. Jenkins์™€ Github ์—ฐ๋™

1. ssh ํ‚ค ์ƒ์„ฑ

Jenkins Container๋ฅผ ์ƒ์„ฑํ•  ๋•Œ "/home/ubuntu/.ssh:/root/.ssh"๋กœ .ssh ๋””ํ…๋„๋ฆฌ๋ฅผ ๋งˆ์šดํŠธ ํ•ด๋†“์•˜๊ธฐ ๋•Œ๋ฌธ์— Container ๋ฐ–์—์„œ ssh ํ‚ค๋ฅผ ์ƒ์„ฑํ•˜๋ฉด Jenkins Container์™€ ์—ฐ๊ฒฐ๋œ๋‹ค.

// ๊ทธ๋ƒฅ ์ „๋ถ€ enter๋ฅผ ์ž…๋ ฅํ•ดdefault๋กœ ๋งŒ๋“ ๋‹ค.
$ ssh-keygen

EC2์— ์ ‘์†ํ•˜๋ฉด ๊ธฐ๋ณธ ์œ ์ €๊ฐ€ ubuntu์ด๊ธฐ ๋•Œ๋ฌธ์— /home/ubuntu/.ssh์— id_rsa์™€ id_rsa.pub์ด ์ƒ์„ฑ๋œ๋‹ค.

2. Github Deploy Key ๋“ฑ๋ก

๋งŒ๋“ค์–ด ๋†“์€ Github Repository > Settings > Deploy Keys > Add deploy key๋กœ ์ ‘์†ํ•œ๋‹ค.Title์€ Jenkins๋กœ ์ง€์–ด ์ฃผ๊ณ (๋งˆ์Œ๋Œ€๋กœ ํ•ด๋„ ๋œ๋‹ค), Key ๋ถ€๋ถ„์— id_rsa.pub์— ๋“ค์–ด์žˆ๋Š” public key ๊ฐ’์„ ๋„ฃ์–ด์ค€๋‹ค. ์•„๋ž˜ ๋ช…๋ น์–ด๋กœ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค.

$ cd /home/ubuntu/.ssh
$ cat id_rsa.pub

3. Jenkins Credentials ๋“ฑ๋ก

Jenkins ๋Œ€์‹œ๋ณด๋“œ > Jenkins ๊ด€๋ฆฌ > Manage Credentials > Credentials์— ์ ‘์†ํ•œ๋‹ค.Store Jenkins์— Domain์ด (global)์ธ ํ™”์‚ดํ‘œ๋ฅผ ๋ˆŒ๋Ÿฌ Global credentials (unrestricted)๋กœ ์ด๋™ํ•œ๋‹ค.์™ผ์ชฝ ๋ฉ”๋‰ด์˜ Add credentials๋ฅผ ๋ˆŒ๋Ÿฌ credentials๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

  • Kind : SSH Username with private key
  • ID : github -> ๋งˆ์Œ๋Œ€๋กœ ์ง€์–ด๋„ ๋œ๋‹ค. ๋‹ค๋งŒ Pipeline Script ์ž‘์„ฑ ์‹œ credentialsId๋กœ ์‚ฌ์šฉ๋˜๋‹ˆ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์ž.
  • Username : root (default)
  • Private Key : Enter directly ์ฒดํฌ -> private key ์ž…๋ ฅ์—ฌ๊ธฐ์„œ private key๋Š” Jenkins Server์—์„œ ์ƒ์„ฑํ•œ id_rsa์ด๋‹ค. ์•„๋ž˜ ๋ช…๋ น์–ด๋กœ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค.
    $ cd /home/ubuntu/.ssh
    $ cat id_rsa
    -----BEGIN OPENSSHPRIVATEKEY-----
    ...
    ... ์ด์™€ ๊ฐ™์€ ํ˜•ํƒœ์˜key๊ฐ€privatekey ์ž…๋‹ˆ๋‹ค ...
    ...
    -----END OPENSSHPRIVATEKEY-----
  • BEGIN ~END๊นŒ์ง€ ๋‹ค ๋„ฃ์–ด ์ค˜์•ผํ•œ๋‹ค.
  • OK๋ฅผ ๋ˆŒ๋Ÿฌ ํ‚ค๋ฅผ ์ƒ์„ฑ

6.Jenkins์™€ Docker Hub ์—ฐ๊ฒฐ

1. Docker Plugin ์„ค์น˜

Jenkins ๋Œ€์‹œ๋ณด๋“œ > Jenkins ๊ด€๋ฆฌ > ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ด€๋ฆฌ > ์„ค์น˜ ๊ฐ€๋Šฅ > Docker ๊ฒ€์ƒ‰ > Docker, Docker Pipeline ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜ ๋ฐ ์žฌ์‹คํ–‰

2. Docker Hub Credentials ๋“ฑ๋ก

Jenkins ๋Œ€์‹œ๋ณด๋“œ > Jenkins ๊ด€๋ฆฌ > Manage Credentials > Credentials์— ์ ‘์†ํ•œ๋‹ค.Store Jenkins์— Domain์ด (global)์ธ ํ™”์‚ดํ‘œ๋ฅผ ๋ˆŒ๋Ÿฌ Global credentials (unrestricted)๋กœ ์ด๋™ํ•œ๋‹ค.์™ผ์ชฝ ๋ฉ”๋‰ด์˜ Add credentials๋ฅผ ๋ˆŒ๋Ÿฌ credentials๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

  • Kind :Username with password
  • Username : ๋ณธ์ธ์˜ Docker Hub ID
  • Password : ๋ณธ์ธ์˜ Docker Hub Password
  • ID : docker-hub -> ๋งˆ์Œ๋Œ€๋กœ ์ง€์–ด๋„ ๋œ๋‹ค. ๋‹ค๋งŒ Pipeline Script ์ž‘์„ฑ ์‹œ credentialsId๋กœ ์‚ฌ์šฉ๋˜๋‹ˆ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์ž.
  • OK ๋ฅผ ๋ˆŒ๋Ÿฌ ํ‚ค๋ฅผ ์ƒ์„ฑ

3. Jenkins Container ๋‚ด๋ถ€์— Docker ์„ค์น˜

Jenkins Pipeline์—์„œ Docker ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก Jenkins Container ๋‚ด๋ถ€์— Docker๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•œ๋‹ค.

  • Jenkins Container์— ์ ‘์†
$ docker exec -it jenkins bash
  • Docker ์„ค์น˜(docker ์„ค์น˜๋Š” ์œ„์—์„œ ์ง„ํ–‰ํ•œ ๊ฒƒ๊ณผ ๊ฐ™๋‹ค.)
    • ๋‹ค๋งŒ Container ๋‚ด๋ถ€์— sudo, vi, wget์ด ์„ค์น˜๋˜์–ด ์žˆ์ง€ ์•Š์•„ ์ฐจ๋ก€๋Œ€๋กœ ์„ค์น˜ ํ›„ Docker๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•œ๋‹ค.
    1. sudo ์„ค์น˜

      $ apt-get update && apt-get install -y sudo
    2. vi ์„ค์น˜

      apt-get update
      apt-get install vim 
    3. wget ์„ค์น˜

      apt-get install wget

7. Jenkins Server์™€ Spring Boot Server SSH ์—ฐ๊ฒฐ ์„ค์ •

Jenkins๋กœ Gradle ๋นŒ๋“œํ•˜๊ณ  Dockerfile๋กœ ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•ด์„œ Docker Hub์— Pushํ•˜๊ณ  Spring Boot Server์—์„œ ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ Pullํ•ด์„œ ์‹คํ–‰ํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•˜๋‹ค. Jenkins Pipeline Script์—์„œ SSH๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Spring Boot Server์˜ ๋ช…๋ น์–ด ์‹คํ–‰์„ ํ•  ์ˆ˜ ์žˆ๋„๋กœ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

1. SSH Agent Plugin ์„ค์น˜

Jenkins ๋Œ€์‹œ๋ณด๋“œ > Jenkins ๊ด€๋ฆฌ > ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ด€๋ฆฌ > ์„ค์น˜ ๊ฐ€๋Šฅ > SSH Agent ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์„ค์น˜ ๋ฐ ์žฌ์‹คํ–‰

2. Spring Boot Server ์ ‘์†

3. Spring Boot Server์˜ .ssh/authorized_keys ํŒŒ์ผ์— Jenkins Server์˜ public key๋ฅผ ์ถ”๊ฐ€

// Jenkins Server์—์„œ public key ํ™•์ธ
$ cat /home/ubuntu/.ssh/id_rsa.pub// Spring Boot Server์— Jenkins Server public key ์ถ”๊ฐ€

$ vi /home/ubuntu/.ssh/authorized_keys
// authorized_keys์— ํ•œ์ค„ ๋„์šฐ๊ณ  public key  ๋“ฑ๋ก

4. Jenkins Credentials ๋“ฑ๋ก

Jenkins ๋Œ€์‹œ๋ณด๋“œ > Jenkins ๊ด€๋ฆฌ > Manage Credentials > Credentials์— ์ ‘์†ํ•œ๋‹ค.Store Jenkins์— Domain์ด (global)์ธ ํ™”์‚ดํ‘œ๋ฅผ ๋ˆŒ๋Ÿฌ Global credentials (unrestricted)๋กœ ์ด๋™ํ•œ๋‹ค.์™ผ์ชฝ ๋ฉ”๋‰ด์˜ Add credentials๋ฅผ ๋ˆŒ๋Ÿฌ credentials๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

  • Kind : SSH Username with private key
  • ID : ssh -> ๋งˆ์Œ๋Œ€๋กœ ์ง€์–ด๋„ ๋œ๋‹ค. ๋‹ค๋งŒ Pipeline Script ์ž‘์„ฑ ์‹œ credentialsId๋กœ ์‚ฌ์šฉ๋˜๋‹ˆ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์ž.
  • Username : root (default)
  • Private Key : Enter directly ์ฒดํฌ -> private key ์ž…๋ ฅ์—ฌ๊ธฐ์„œ private key๋Š” Jenkins Server์—์„œ ์ƒ์„ฑํ•œ id_rsa์ด๋‹ค. ์•„๋ž˜ ๋ช…๋ น์–ด๋กœ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค.
    $ cd /home/ubuntu/.ssh
    $ cat id_rsa
    -----BEGIN OPENSSHPRIVATEKEY-----
    ...
    ... ์ด์™€ ๊ฐ™์€ ํ˜•ํƒœ์˜key๊ฐ€privatekey ์ž…๋‹ˆ๋‹ค ...
    ...
    -----END OPENSSHPRIVATEKEY-----
  • OK๋ฅผ ๋ˆŒ๋Ÿฌ ํ‚ค๋ฅผ ์ƒ์„ฑ์‚ฌ์‹ค์ƒ ์œ„์˜ Jenkins์™€ Github ์—ฐ๋™ ์‹œ ์ƒ์„ฑํ•œ Jenkins Credentials๊ณผ ๋™์ผํ•˜๋‹ค. ํ•˜์ง€๋งŒ ID๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ ์ž SSH Credentials์„ ๋ณ„๋„๋กœ ์ƒ์„ฑํ•˜์˜€๋‹ค.

8. Jenkins Pipeline ๊ตฌ์„ฑ

1๏ธโƒฃ Jenkins, Github Webhook ์—ฐ๋™

Github Repository์— push event๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ž๋™์œผ๋กœ Build๊ฐ€ ์‹คํ–‰๋˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด Pipeline๊ณผ Github Webhook์„ ์—ฐ๋™ํ•ด์•ผ ํ•œ๋‹ค.

1. Github Integration Plugin ์„ค์น˜

Jenkins ๋Œ€์‹œ๋ณด๋“œ > Jenkins ๊ด€๋ฆฌ > ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ด€๋ฆฌ > ์„ค์น˜ ๊ฐ€๋Šฅ > Github Integration ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์„ค์น˜ ๋ฐ ์žฌ์‹คํ–‰

2. Jenkins Pipeline ์„ค์ •

  • Github project ์„ค์ • Pipeline ๊ตฌ์„ฑ ํ™”๋ฉด > General ์˜์—ญ์—์„œ Github project๋ฅผ ์„ ํƒํ•œ๋‹ค. > Project url์— ๋ณธ์ธ์˜ Github Repository Url์„ ์ž…๋ ฅํ•œ๋‹ค. ์ด ๋•Œ Repository Url์€ Clone ์‹œ ์‚ฌ์šฉํ•˜๋Š” HTTPS Url(.git์œผ๋กœ ๋๋‚จ)์„ ์ž…๋ ฅํ•œ๋‹ค.
  • Build Triggers ์„ค์ •Pipeline ๊ตฌ์„ฑ ํ™”๋ฉด > Build Triggers ์˜์—ญ์—์„œ GitHub hook trigger for GITScm polling์„ ์„ ํƒํ•œ๋‹ค.

3. Github Webhook ์ถ”๊ฐ€

Github Repository์—์„œ Settings > Webhooks > Add Webhook ์„ ๋ˆŒ๋Ÿฌ Webhook์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

  • Payload URL[Jenkins Server URL]:[Jenkins Server ํฌํŠธ]/github-webhook/
  • Content typeapplication/x-www-form-urlencoded
  • ๋‚˜๋จธ์ง€๋Š” ๋ชจ๋‘ default ์„ค์ • ์œ ์ง€Add webhook ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ Webhook์„ ์ถ”๊ฐ€ -> ๋ชฉ๋ก์—์„œ ๋…น์ƒ‰ ์ฒดํฌ ์•„์ด์ฝ˜์ด ์ƒ์„ฑ๋˜๋ฉด ์„ฑ๊ณต

2๏ธโƒฃ Pipeline Script ์ž‘์„ฑ

pipeline {
    agent any

    environment {
        imagename = "docker build๋กœ ๋งŒ๋“ค ์ด๋ฏธ์ง€ ์ด๋ฆ„"
        registryCredential = 'Docker Hub Credential ID'
        dockerImage = ''
    }

    stages {
stage('Prepare') {
          steps {
            echo 'Clonning Repository'
            git url: 'Github Repository SSH Url(git@github.com๋กœ ์‹œ์ž‘)',
              branch: 'Clone ๋ฐ›์•„์˜ฌ Branch ์ด๋ฆ„',
              credentialsId: 'Github Credential ID -> github'
            }
            post {
             success {
               echo 'Successfully Cloned Repository'
             }
           	 failure {
               error 'This pipeline stops here...'
             }
          }
        }

stage('Bulid Gradle') {
          steps {
            echo 'Bulid Gradle'
dir('.'){
								sh 'chmod +x ./gradlew'
                sh './gradlew clean build'
            }
          }
          post {
            failure {
              error 'This pipeline stops here...'
            }
          }
        }

stage('Bulid Docker') {
          steps {
            echo 'Bulid Docker'
            script {
                dockerImage = docker.build imagename
            }
          }
          post {
            failure {
              error 'This pipeline stops here...'
            }
          }
        }

stage('Push Docker') {
          steps {
            echo 'Push Docker'
            script {
                docker.withRegistry( '', registryCredential) {
                    dockerImage.push()
                }
            }
          }
          post {
            failure {
              error 'This pipeline stops here...'
            }
          }
        }

stage('Docker Run') {
            steps {
                echo 'Pull Docker Image & Docker Image Run'
                sshagent (credentials: ['SSH Credential ID -> ssh']) {
                    sh "ssh -o StrictHostKeyChecking=no [Spring Boot Server username]@[Spring Boot Server IP ์ฃผ์†Œ] 'docker pull [๋„์ปค์ด๋ฏธ์ง€ ์ด๋ฆ„]'"
                    sh "ssh -o StrictHostKeyChecking=no [Spring Boot Server username]@[Spring Boot Server IP ์ฃผ์†Œ] 'docker ps -q --filter name=[์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„] | grep -q . && docker rm -f \$(docker ps -aq --filter name=[์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„])'"
                    sh "ssh -o StrictHostKeyChecking=no [Spring Boot Server username]@[Spring Boot Server IP ์ฃผ์†Œ] 'docker run -d --name [์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„] -p 8080:8080 [๋„์ปค์ด๋ฏธ์ง€ ์ด๋ฆ„]'"
                }
            }
        }
    }
    
}

Stage ๋กœ ๋Š์–ด์„œ prepare ์™€ gradle ๋งŒ ์„ค๋ช…ํ•˜๊ฒ ๋‹ค.

Prepare

  • git url : github์—์„œ url์„ ๋ณต์‚ฌํ•ด์„œ ๋ถ™์—ฌ ๋„ฃ์–ด์ค€๋‹ค.
  • branch : clone ๋ฐ›์•„์˜ฌ branch ์ด๋ฆ„ ex) main
  • credentialsId : Github Credential ID
stage('Prepare') {
          steps {
            echo 'Clonning Repository'
            git url: 'Github Repository SSH Url(git@github.com๋กœ ์‹œ์ž‘)',
              branch: 'Clone ๋ฐ›์•„์˜ฌ Branch ์ด๋ฆ„',
              credentialsId: 'Github Credential ID -> github'
            }
            post {
             success {
               echo 'Successfully Cloned Repository'
             }
           	 failure {
               error 'This pipeline stops here...'
             }
          }
        }

Bulid Gradle

sh 'chmod +x ./gradlew' : gradlew ์‹คํ–‰๊ถŒํ•œ ์ ์šฉ

sh './gradlew clean build' : grdlew cleanํ›„ bulid

stage('Bulid Gradle') {
          steps {
            echo 'Bulid Gradle'
dir('.'){
								sh 'chmod +x ./gradlew'
                sh './gradlew clean build'
            }
          }
          post {
            failure {
              error 'This pipeline stops here...'
            }
          }
        }

ํ…Œ์ŠคํŠธ

  • ์Šคํ”„๋ง ์„œ๋ฒ„์— ์ ‘์†ํ•ด์„œ ๋Œ์•„๊ฐ€๋Š” ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ™•์ธํ•ด๋ณด์ž
$ docker ps

๋„์›€์„ ์ฃผ์‹  ๋ธ”๋กœ๊ทธ๋“ค ๐Ÿ‘

https://hyeinisfree.tistory.com/23

https://backtony.github.io/spring/aws/2021-08-08-spring-cicd-1/#๋„์ปค-์„ธํŒ…

https://yongho1037.tistory.com/720

profile
๋ฐฑ์•ค๋“œ ๊ฐœ๋ฐœ์ž๋ฅผ ๊ฟˆ๊พธ๋Š” ๊ฐœ๋ฐœ์ž ์ง€๋ง์ƒ์ž…๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€