코딩/sparta TIL

CI/CD 구축하기 : Jenkins에서 GitHub Push되면 → EC2에 자동 배포까지 완료

americanoallday 2025. 6. 18. 21:43

🔁 전체 자동화 흐름

1. GitHub push 발생
    ↓
2. Jenkins가 빌드 트리거 (웹훅 or Poll SCM)
    ↓
3. Jenkins가 Docker 이미지 빌드
    ↓
4. Jenkins가 EC2로 SSH 접속
    ↓
5. EC2에서 docker-compose down → up -d --build 자동 실행

 

✅ Jenkinsfile 

pipeline {
    agent any

    environment {
        EC2_HOST = 'ubuntu@54.ㅌㅌㅌ.ㅌㅌㅌ.ㅌㅌㅌ'        // 너의 chat 서버 IP
        EC2_DIR = '/home/ubuntu/cluvr-chat'       // EC2 내부에서 git clone 받은 위치
    }

    stages {
        stage('Deploy to EC2') {
            steps {
                // chat 서비스만 재빌드 및 재시작 (다른 컨테이너는 유지)
                sh """
                ssh -o StrictHostKeyChecking=no -i /var/lib/jenkins/.ssh/id_rsa ${EC2_HOST} '
                cd ${EC2_DIR} &&
                git pull origin main &&
                sudo docker-compose rm -f spring || true &&
                sudo docker container prune -f &&
                sudo docker-compose up -d --build spring
                '
                """
            }
        }
    }
}

 

🔒 단, 이게 되려면 전제 조건이 있어:

조건 설명
✅ Jenkins가 EC2에 SSH 접속 가능해야 함 Jenkins 서버에서 EC2에 접속하려면 EC2에 공개키 등록돼 있어야 해 (~/.ssh/authorized_keys)
✅ EC2에 git clone 미리 되어 있어야 함 즉, /home/ubuntu/cluvr-chat 디렉토리에 프로젝트가 git으로 클론돼 있어야 함
docker-compose가 EC2에 설치돼 있어야 함 없으면 sudo apt install docker-compose 해줘야 함
✅ Jenkins 서버에서 GitHub 접근 가능해야 함 보통 문제 안 됨. 만약 private repo라면 token 설정도 필요
더보기

🔹 Jenkins가 각 서버에 접근해서 docker-compose 등을 실행하려면,

각 서버에 Jenkins의 SSH 공개키 등록이 필요합니다.

 

 

🔹 단순히 Dockerfile, Jenkinsfile, docker-compose.yml 파일만 있다고 해서 자동으로 다른 서버에 접근 할 수는 없습니다.

📌 왜 SSH 키 등록이 필요한가?

  • Jenkins 서버가 다른 EC2 인스턴스들 (e.g., notification 서버, batch 서버)직접 SSH로 접속해서 다음 작업을 하려면:
    • git pull 해서 최신 코드 받아오기
    • docker-compose up -d 같은 명령 실행
    • 로그 확인 등
    👉 이런 모든 작업은 리모트 쉘 접근이 가능해야만 Jenkins에서 실행됩니다.

 

📌 그렇다면 어떻게 해야 하냐?

✅ Jenkins 빌드 서버 → 다른 서버들에 SSH 접근할 수 있도록 설정

  1. Jenkins 서버에서 생성한 SSH 공개키 (~/.ssh/id_rsa.pub)를
  2. notification 서버 / batch 서버 / api 서버의 ~/.ssh/authorized_keys 에 추가

 

이렇게 하면 Jenkins에서 각 서버로 SSH 접속 가능해집니다.

 

📌 Jenkinsfile에선 뭐가 일어나는 거냐?

예시로 보자면:

pipeline {
    agent any
    stages {
        stage('Deploy to Batch Server') {
            steps {
                sshagent (credentials: ['jenkins-ssh-key']) {
                    sh '''
                        ssh ec2-user@batch-server '
                            cd /home/ec2-user/app &&
                            git pull &&
                            docker-compose down &&
                            docker-compose up -d --build
                        '
                    '''
                }
            }
        }
    }
}

 

  • 여기서 ssh ec2-user@batch-server를 하려면,👉 그걸 위해선 SSH 키 등록이 필수입니다.
  • 👉 Jenkins가 해당 서버에 비밀번호 없이 SSH 접속할 수 있어야 하고,

✅ 요약

질문 답변
Jenkins가 각 서버에 접근하려면 SSH 키 필요해? 예 (필수)
Dockerfile, Jenkinsfile만 있다고 해서 알아서 배포되나? 아니오. Jenkins가 직접 그 서버로 접근해야 함
각 서버에 Docker 설치돼 있어야 하나? 예. Jenkins가 해당 서버에서 docker 명령 실행해야 하므로
Jenkins가 다른 서버에서도 docker-compose up 같은 거 하게 하고 싶어 그럼 Jenkins의 SSH 키를 그 서버들의 authorized_keys에 등록해야 해

 

✅ 1단계: Jenkins EC2에 SSH 키가 있는지 확인

Jenkins EC2 (34.XXX.XX.XXX)에 접속해서:

ls ~/.ssh/id_rsa.pub

 

  • ❌ 없으면 → 아래 명령어로 생성:
ssh-keygen -t rsa -b 4096 -C "jenkins@cluvr"
# 그냥 Enter 연타하면 됨

 

✅ 2단계: Jenkins EC2의 공개키 복사

아래 명령어 입력 후 나오는 키값 복사

cat ~/.ssh/id_rsa.pub

 

 

✅ 3단계: Chat EC2 (54.XXX.XXX.XXX)에 접속

ssh ubuntu@54.XXX.XXX.XXX

 

✅ 4단계: Chat EC2에 Jenkins 공개키 등록

Chat 서버 안에서 다음 명령 실행:

mkdir -p ~/.ssh
nano ~/.ssh/authorized_keys

→ 방금 복사한 Jenkins 공개키 내용을 붙여넣고 저장 (Ctrl + O, Enter, Ctrl + X)

 

퍼미션 설정도 해야 함:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

 

✅ 5단계: 테스트

이제 Jenkins EC2에서 Chat EC2로 접속 테스트:

ssh ubuntu@54.XXX.XXX.XXX
  • 비밀번호 없이 접속되면 성공!
  • 🔥 이게 돼야 Jenkins에서 ssh 명령어로 자동 배포 가능함.

id_rsa.pub 파일 등록 하기

더보기

/var/lib/jenkins/.ssh 경로는 Jenkins에서 사용하는 SSH 키를 저장하는 기본 경로이지만, 현재 API 서버에서는 해당 경로에 SSH 키가 없어서 연결이 되지 않는 것 같습니다. 대신, Jenkins 서버의 SSH 키/home/ubuntu/.ssh 경로에 저장된 것으로 보임.

 

문제 해결 방법:

1. 혹시 모르니 기존 키 등록 제거 : 

- sudo -u jenkins ssh-keygen -R 44.239.99.137

 

2. 재등록

- sudo -u jenkins ssh-keyscan -H 44.239.99.137 >> /var/lib/jenkins/.ssh/known_hosts

- sudo -u jenkins ssh -i /var/lib/jenkins/.ssh/id_rsa ubuntu@44.239.99.137 "echo 연결 성공"

  1. Jenkins 서버의 SSH 키를 사용하기 위해서는 /home/ubuntu/.ssh/ 경로에서 사용하고자 하는 SSH 키를 확인하고, 해당 키가 Jenkins에서 사용될 수 있도록 설정해야 합니다.
  2. SSH 키를 Jenkins에서 사용하도록 설정:
  3. Jenkins는 기본적으로 /var/lib/jenkins/.ssh 디렉토리에서 SSH 키를 찾습니다. 현재 /home/ubuntu/.ssh/ 경로에 SSH 키가 있다면, 해당 키를 Jenkins가 사용할 수 있도록 심볼릭 링크를 만들어줘야 합니다.
  4. 심볼릭 링크 생성:아래와 같이 진행하세요:
    1. SSH 키 위치 확인:
    2. 이미 /home/ubuntu/.ssh/id_rsaid_rsa.pub 키가 있다고 확인되었습니다.
    3. 심볼릭 링크 생성:
    4. 아래 명령어를 사용하여 /home/ubuntu/.ssh/id_rsa/home/ubuntu/.ssh/id_rsa.pub 파일을 /var/lib/jenkins/.ssh/ 디렉토리에서 참조할 수 있도록 심볼릭 링크를 만들어줍니다.
  5. Jenkins가 /home/ubuntu/.ssh/id_rsa를 사용할 수 있도록 /var/lib/jenkins/.ssh/id_rsa에 심볼릭 링크를 만들면 됩니다.
sudo ln -s /home/ubuntu/.ssh/id_rsa /var/lib/jenkins/.ssh/id_rsa
sudo ln -s /home/ubuntu/.ssh/id_rsa.pub /var/lib/jenkins/.ssh/id_rsa.pub
sudo ln -s /home/ubuntu/.ssh/known_hosts /var/lib/jenkins/.ssh/known_hosts

 

  1. 권한 설정:
  2. SSH 키 파일에 적절한 권한이 설정되어 있는지 확인합니다.
sudo chown jenkins:jenkins /var/lib/jenkins/.ssh/id_rsa /var/lib/jenkins/.ssh/id_rsa.pub /var/lib/jenkins/.ssh/known_hosts
sudo chmod 600 /var/lib/jenkins/.ssh/id_rsa /var/lib/jenkins/.ssh/id_rsa.pub /var/lib/jenkins/.ssh/known_hosts

 

  1. 확인:
  2. 위 작업 후에, Jenkins에서 API 서버에 SSH 연결을 시도하면 Host key verification failed 오류 없이 연결이 가능해질 것입니다.

정리:

  1. /home/ubuntu/.ssh/에 있는 SSH 키 파일들을 /var/lib/jenkins/.ssh/에 심볼릭 링크로 연결.
  2. chmodchown 명령어로 권한을 적절하게 설정.
  3. Jenkins 빌드를 다시 실행하여 문제가 해결되었는지 확인.

 

이렇게 설정하면 Jenkins에서 SSH 연결을 시도할 때 Host key verification failed 문제를 해결할 수 있습니다.

🔁 작동 순서 요약

  1. Jenkins가 EC2에 SSH로 접속해서
  2. 해당 경로로 이동 (cd /home/ubuntu/cluvr-chat)
  3. 최신 코드 pull (git pull)
  4. 기존 컨테이너 down
  5. 다시 build + up (docker-compose up -d --build)