TIL/DOCKER

CI/CD via Jenkins #2

아람2 2024. 12. 23. 21:08
반응형

Jenkins 설정 

Jenkins 를 설치하고 Git Repo 까지 연결했으니 (#1 참고) 이제 설정할 차례 -

각오는 했지만 생각보다 설정할 내용들이 많았고 제법 어렵기도 했다 

Jenkins 배포 전략 세우기

방안1) 빌드 서버 따로, 배포 서버 따로 진행 

방안2) 빌드와 배포를 하나의 서버에서 진행 

두 개의 방안 중에 방안1 은 빌드 서버에서 각 배포 서버로 접근하는 통합 파이프라인 작성이 복잡해서

조금 귀찮지만 하나의 서버에서 진행하는 2번 방안을 택했다 

 

그리고 빌드, 배포 및 실행할 Instance 를 t2.medium 으로 하나 만들어 줬다 

Jenkins Domain Settings (Optional)

가비아 도메인이 Jenkins 에 연결되지 않아서, 일단 AWS EC2 URL 을 넣어 줬다 

Swap Memory 설정하기 (Optional)

EC2 메모리가 부족하여 꺼지는 사태를 방지하기 위해 Swap 메모리를 확인한다 

free -h 로 메모리를 확인하면, Swap 파일 메모리가 0 인 것을 확인할 수 있다 

$ free -h
               total        used        free      shared  buff/cache   available
Mem:           949Mi       131Mi       456Mi       0.0Ki       361Mi       674Mi
Swap:             0B          0B          0B

 

// Swap 디렉토리 파일을 만들어 주고 
$ sudo mkdir /var/spool/swap
$ sudo touch /var/spool/swap/swapfile
$ sudo dd if=/dev/zero of=/var/spool/swap/swapfile count=2048000 bs=1024

// Swap 파일을 설정하고 
$ sudo chmod 600 /var/spool/swap/swapfile
$ sudo mkswap /var/spool/swap/swapfile
$ sudo swapon /var/spool/swap/swapfile

// Swap 파일을 등록한다 
$ sudo vim /etc/fstab
// 아래 내용 입력 후 저장
/var/spool/swap/swapfile    none    swap    defaults    0 0

 

이렇게 해주면 Swap 메모리가 잘 설정되어 있는 것을 확인할 수 있다 

$ free -h
               total        used        free      shared  buff/cache   available
Mem:           949Mi       136Mi        60Mi       0.0Ki       752Mi       667Mi
Swap:          2.0Gi          0B       2.0Gi

 

Jenkins 에 java 설치하기

// Java Version 확인 
$ java -version
openjdk version "17.0.13" 2024-10-15 LTS
OpenJDK Runtime Environment Corretto-17.0.13.11.1 (build 17.0.13+11-LTS)
OpenJDK 64-Bit Server VM Corretto-17.0.13.11.1 (build 17.0.13+11-LTS, mixed mode, sharing)

// Java 위치 확인 
$ which java
/usr/lib/jvm/java-17-amazon-corretto.x86_64/bin/java

 

SSH Key Generation 

node 와 연결에 사용할 SSH Key 를 생성한다 

// node 와 연결에 사용할 SSH 키 생성 
$ ssh-keygen
// id_rsa.pub 내용을 node 의 authorized_keys 에 저장 
$ cat ~/.ssh/authorized_keys

Credentials 추가 

Kind - SSH Username with private Key 

Scope - Global

ID - Key 의 네이밍 할당 

Username - Slave 에 접근할 사용자명 

Private Key - id_rsa 의 전체 값 

Agent Node 추가

노드 Node 는 Jenkins 마스터가 작업/ 빌드를 실행할 수 있는 컴퓨터 또는 환경이다 

젠킨스를 각 머신마다 설치하고 설정하는 번거로움을 피하기 위해,

빌드 머신 or 개발 환경을 컨트롤/ 분산 처리할 수 있는 Agent Node 를 설정해 준다 

 

 

Number of Executors - 노드에서 동시에 실행할 수 있는 실행자의 개수 

Remote Root Directory - 노드로 사용할 원격 서버의 디렉토리, Jenkins 가 설치된 장소의 디렉토리가 아닌 Agent Node 가 실행될 서버의 디렉토리를 기입한다 > 우리는 jenkins 가 있는 디렉토리에다가 jenkins 디렉토리를 하나 더 생성하여 홈 디렉토리처럼 사용할 예정이다 > /home/ec2-user/jenkins 

🐣 jenkins 가 있는 디렉토리에서 pwd 를 치면 경로를 알 수 있다 🐣

 

Launch Method - 인스턴스에 젠킨스 마스터와 통신을 위한 에이전트를 설치하는 방법 

Host - 연결하고자 하는 에이전스 인스턴스의 Private IP 

 > New Instance 의 Private IP 를 기재해 준다 

Credentials - 아까 생성한 Credential User Name 

JavaPath - New Instance 에서 설정된 Java 경로
🐣 [which java] Command 로 알 수 있는 줄 알았는데 /usr/lib/jvm 에 들어가서 java-170amazon-corretto 폴더 안에 있는 파일이 

진짜 실행 파일 경로니까, which java 로 찾지 말고 /usr/lib/jvm 타고 들어가라고 하루이가 말해줬다 🐣

Pipeline Script 

Docker Hub 를 이용한 Pipeline Script 를 작성했다 

환경 설정 변수와, 아래 순서를 차례로 작성해 준다 

1. Clone Git Repo and Build Docker Image  

2. Docker Login and Push Docker Image 

3. Deploy to EC2

 

🐣 여기 아래는 토글하고 싶은데 티스토리 토글 만들기 넘 귀찮다 🐣

어찌저찌 Pipeline 을 넣어준 Node 를 만들고 Build 해보니, Deploy to EC2 에서 Fail 이 떴다 

docker run -d --name jenkins-test-container -p 80:80 ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} - Shell Script
+ docker run -d --name jenkins-test-container -p 80:80 jenkins-test-image:latest
docker: Error response from daemon: Conflict. The container name "/jenkins-test-container" is already in use by container "adba93c1a64349590de8057525c9091cc14390e80a91fbc97c8de92f506fcca4". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.
script returned exit code 125

 

Error MSG 를 확인해 보니, Test 용도로 이미 등록했던 컨테이너 이름이 --name 에 존재하니 삭제하라는 내용이었다 

🐣 Linux 환경에서 docker 가 실행되는지/ 되었는지 보려면 docker ps -a 로 볼 수 있다 🐣

Pipeline 에 기존의 jenkins-test-container 이름을 가진 컨테이너를 삭제해 주는 내용을 추가하고 다시 빌드를 해봤다

docker rm jenkins-test-container

 

이번에는 run 상태인 docker 를 삭제할 수 없다는 Error 가 출력이 됐다 

그래서 docker 를 stop 하는 명령어도 추가해줬다 

docker rm jenkins-test-container - Shell Script
+ docker rm jenkins-test-container
Error response from daemon: cannot remove container "/jenkins-test-container": container is running: stop the container before removing or force remove
script returned exit code 1

 

짜잔-!

빌드 성공!!

 

완성된 Pipeline Script 🐣

pipeline {
    agent any
    
    environment {
        DOCKER_IMAGE_NAME = 'jenkins-test2'
        DOCKER_IMAGE_TAG = 'latest'
        REMOTE_HOST = '10.0.128.64'  // EC2 IP 주소
        REMOTE_USER = 'ec2-user'  // EC2 사용자 이름
        SSH_KEY_PATH = '/home/ec2-user/JenkinsKey.pem'  // Jenkins에서 사용하는 SSH 키 경로
        DOCKER_USERNAME = 'Docker_ID' // 자격 증명 ID
        DOCKER_PASSWORD =  'Docker_PW'  // 자격 증명 PW
    }
    
    stages {
        stage('Clone Git Repository') {
            steps {
                script {
                    // Git 저장소에서 코드 클론 (main 브랜치로 명시적으로 체크아웃)
                    sh 'rm -rf jenkins-test-repo'
                    sh 'git clone --branch main https://github.com/Team-BBanana/jenkins-test-repo.git'
                }
            }
        }
        
        stage('Build Docker Image') {
            steps {
                script {
                    // Dockerfile 경로를 명확하게 지정 
                    // docker build -t [Iamge Name:Tag] [Docker File Directory]
                    sh 'docker build -t jenkins-test-image:latest jenkins-test-repo/'
                }
            }
        }

        stage('Docker Login') {
            steps {
                script {
                    // Docker Hub 로그인
                    sh 'echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin'
                }
            }
        }

        stage('Push Docker Image') {
            steps {
                script {
               		// docker tag [Docker Image] [New Image Name:Tag]
                    sh 'docker tag jenkins-test-image:latest haru2/jenkins-test-image:latest'

                    // 도커 이미지를 Docker Hub 나 다른 레지스트리에 푸시
                    sh 'docker push {DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG}'
                }
            }
        }

        stage('Deploy to EC2') {
            steps {
                script {
                    // EC2 인스턴스에 SSH로 접속하여 도커 이미지 실행
                    // 실행 중이라면 컨테이너를 중지 후 삭제하고 다시 실행 
                    sh 'docker stop jenkins-test-container'
                    sh 'docker rm jenkins-test-container'
                    sh 'docker run -d --name jenkins-test-container -p 80:80 ${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG}'
                }
            }
        }
    }
}

 

Jenkins 드디어 했다,.... 휴 

이제 다음 스텝이닷!

반응형

'TIL > DOCKER' 카테고리의 다른 글

[Docker] Docker Image Build  (0) 2025.01.04
Docker Exited (0) 되는 문제 수정하기  (0) 2024.12.24
CI/CD via Jenkins + Docker #1  (1) 2024.12.22
쿠버네티스 Kubernetes  (0) 2024.12.17
[Docker] docker-container 로 MySQL 접속하기  (2) 2024.12.07