본문 바로가기
개발공부 개발새발/CICD

CI/CD ) Docker 와 함께 자동 배포하기

by 휴일이 2024. 5. 13.

목표 : Docker 컨테이너에서 코드 배포하기

이전까지와 하는 일은 동일하나, 이제는 Jenkins 가 Tomcat 대신 docker 컨테이너로 배포한다.

도커용 EC2 인스턴스 생성 후 docker 설치

# 도커 설치
yum install docker

# 도커 상태 확인
service docker status

# 도커 시작
service docker start

Tomcat 컨테이너 생성 - with pull Image

docker pull tomcat

docker images

# 컨테이너 내부 포트 8080
# 외부 (로컬) 에서는 8081 포트로 연결
docker run -d --name tomcat-container -p 8081:8080 tomcat

# 지금 접속하면 에러가 뜬다.
<http://publicIP:8081>

# 컨테이너 속으로 접속
docker exec -it tomcat-container /bin/bash

  • 톰캣이 webapps 디렉토리 안에 있는 애플리케이션을 보여줘야하는데 webapps 디렉토리 안이 비어있어서 404 NOT Found 를 보내는 것.
cd tomcat/webapps.dist
cp -R * ../webapps/
  • webapps 에 있어야 할 내용물들이 webapps.dist 에 있으므로, 내용물을 복붙해주자.

  • 복붙 후에는 정상적으로 작동한다 ^0^/

Tomcat 컨테이너 생성 - with Dockerfile

톰캣 서버를 직접 설치한다면 해야하는 과정

  1. 베이스 운영체제 이미지를 가져온다. (Centos 를 가져올 것임)
  2. 자바 설치
  3. /opt/tomcat 디렉토리 생성
  4. /opt/tomcat 디렉토리를 작업 디렉토리로 설정
  5. tomcat 패키지 설치
  6. tar.gz 파일 압축 풀기
  7. 파일 압축 푼 걸 디렉토리 이동
  8. 포트 8080 에서 통신하도록 설정
  9. 톰캣 시작

각 과정을 Dockerfile 로 옮겨보자

# 1. 베이스 운영체제 이미지 가져오기
FROM centos:latest
# 2. 자바 설치 (bash 에 yum install java -y 커맨드 작성한다는 뜻)
RUN /bin/sh -c yum install java -y
# 3. 디렉토리 생성
RUN mkdir /opt/tomcat
# 4. tomcat 디렉토리를 작업 디렉토리로 설정
WORKDIR /opt/tomcat
# 5. tomcat 패키지 설치
ADD <https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.89/bin/apache-tomcat-9.0.89.tar.gz> .
# 6. 다운받은 tomcat 패키지 압축 풀기
RUN tar -xvzf apache-tomcat-9.0.89.tar.gz
# 7. 내용물을 /opt/tomcat (workdir) 로 옮김
RUN mv apache-tomcat-9.0.89/* /opt/tomcat
# 8. 포트 지정
EXPOSE 8080
# 9. 톰캣 시작 명령어
CMD [ "/opt/tomcat/bin/catalina.sh", "run" ]

최신 톰캣 파일을 가져와서 만들어보자

FROM tomcat:latest
RUN cp -R /usr/local/tomcat/webapps.dist/* /usr/local/tomcat/webapps
  • 이렇게 한 뒤 해당 이미지를 빌드해준다.

도커와 젠킨스 통합하기

도커로 만든 톰캣 컨테이너로 프로젝트를 배포하려면 젠킨스와 도커를 통합해야 한다!

docker 관리자 사용자 만들기

# 사용자 확인
cat /etc/passwd
# 그룹 확인
cat /etc/group

# 도커 관리자용 사용자를 하나 만들어서 그룹에 추가한다.
useradd dockeradmin
# 이 명령어를 입력하면 비밀번호를 설정할 수 있다.
passwd dockeradmin

# 내가 만든 유저 확인
id dockeradmin
# 하면 이렇게 기본 그룹에 속해있다. 이걸 docker 그룹에 추가해줘야 함.
[root@dockerhost ~]# id dockeradmin
uid=1001(dockeradmin) gid=1001(dockeradmin) groups=1001(dockeradmin)

# 도커 그룹에 추가
usermod -aG docker dockeradmin

# 암호 기반으로 로그인할 수 있도록 파일내용을 변경해줘야함.
vi /etc/ssh/sshd_config
# 이렇게 변경해줌
PasswordAuthentication yes

# 서비스 다시 시작
service sshd reload

# 터미널로 ssh 로 접속할 때, 유저 명을 변경해서 접속함
ssh -i "key.pem" dockeradmin@서버
패스워드 입력

젠킨스 설정하기

ssh 플러그인 추가

ssh 설정

  • ssh-keygen 으로 ssh 키를 만들고, 그 경로 (/home/dockeradmin/.ssh ) 를 주는 방법도 있으나
  • 아까만든 패스워드를 넣어줘도 인증이 된다.

젠킨스가 dockerhost에 아티팩트를 빌드 복사하기

젠킨스가 깃허브에서 코드를 가져오고, maven 으로 빌드해서 도커호스트에 복사한다.

새 작업을 기존 내용 복사해서 만들기

  • Copy from 에 기존 작업 이름을 적어넣으면 기존 작업과 똑같은 설정으로 만들 수 있음.

빌드 후 조치 설정

 

  • Send build artifacts over SSH 옵션을 지정해준다.
  • Source files 소스파일 경로, git 에서 pull 해올 경로중에 소스파일이 있는 경로를 적어준다.
  • Remove prefix 소스파일을 가져온 후 삭제할 경로, *.war 파일만 가져오고 경로까진 가져오지 않을 거니까 소스파일 앞 경로를 적어줬음.

  • Remote directory 대상 폴더, 이 폴더 안에 소스파일이 들어감. 없으면 생성됨.
    • 기본으로 호스트 경로를 잡고있기 때문에 /home/dockeradmin 을 안 해줘도 해당 경로에생성됨 (이미지엔 넣어져있지만 지워주자)

dockerfile 업데이트하고 배포 자동화하기

아직까진 배포가 자동화되어있진 않다. (배포 파일만 자동 복붙됨) 배포 자동화를 해주자.

root

# 모든 작업은 dockerhost 가 아닌 root 에서 하자

# /opt 에 dockeradmin이 관리할 디렉토리 생성
cd /opt
mkdir docker

# 도커파일을 해당 경로로 이동시키기
mv Dockerfile /opt/docker 

# 해당 경로에 dockeradmin 에게 권한 주기
chown -R dockeradmin:dockeradmin /opt/docker

# 권한 확인
ll -l

  • root → dockeradmin 으로 권한이 변경된 모습 😊

Jenkins 설정 변경

  • Remote directory 를 //opt/docker 로 변경해준다. (우리가 권한 줬던 폴더)
    • /home/dockeradmin 이후에 있는 절대경로임을 알려주기 위해 더블슬래시를 사용한다.

Dockerfile 수정

FROM tomcat:latest
RUN cp -R /usr/local/tomcat/webapps.dist/* /usr/local/tomcat/webapps
COPY ./*.war /usr/local/tomcat/webapps
  • 복사된 war 파일을 톰캣의 webapps 폴더에 복사하도록 수정한다.

docker build

docker build -t tomcat:v1 .

docker run -d --name tomcatv1 -p 8086:8080 tomcat:v1
  • 카피한 아티팩트를 이미지를 빌드하고 컨테이더를 올리면 잘 동작한다.

자동 배포하기

지금까지는 수동으로 배포했으나 자동으로 배포되도록 만들어보장.

  • Exec command 에서 war 를 복사한 후 실행 될 커맨드를 추가한다. 명령 구분자는 ;
    • Dockerfile 이 있는 디렉토리로 가서 이미지를 빌드하고 컨테이너를 만드는 것 까지의 명령어다.
docker ps -a

# 필요 없는 컨테이너를 전부 멈추고 전부 삭제
docker stop 컨테이너이름1 이름2 이름 ...
docker container prune

# 이미지 전부 삭제
docker image prune -a
  • 필요없는 이미지와 컨테이너도 전부 삭제해주었다!

자동 배포 경험해보기

  • index.jsp 내용을 간단히 수정하고 master branch 에 push 해주었다.

  • 자동으로 땡겨오는 중..하지만 오류가 뜰 것이다.
  • 이유는 컨테이너 이름을 중복으로 사용할 수 없다고 뜬다.
  • 당연하다. 기존 컨테이너가 살아있으니까… 그럼 어떻게 해결할까?

Exec command 수정

cd /opt/docker;
docker build -t regapp:v1 .;
# 컨테이너를 정지하고 삭제하는 구문을 추가해준다.
docker stop registerapp;
docker rm registerapp;
# 이후 컨테이너를 만들어줌.
docker run -d --name registerapp -p 8087:8080 regapp:v1
  • 이렇게 하면 컨테이너를 정지 → 삭제하고 다시 컨테이너를 올리기 때문에 걱정이 없다~!
💡 하지만 이렇게 커맨드를 직접해서 여러 명령을 실행하는 건 좋은 방법은 아니다. Ansable 을 사용하면 이 커맨드를 실행하고 더 효율적으로 환경을 설정할 수 있다.^0^/)
728x90