DevOps

CI/CD 파이프라인 구축하기 - 3.1 (Docker 설정 및 Jenkins SSH server 설정하기)

우잉~ 2024. 12. 13. 17:16

CI/CD 파이프라인 구축하기 - 2에서 이어집니다!

https://wooinge.tistory.com/139

 

CI/CD 파이프라인 구축하기 - 2 (Tomcat)

CI/CD 파이프라인 구축하기 - 1에서 이어집니다!https://wooinge.tistory.com/93 CI/CD 파이프라인 구축하기 - 1 (Git, Jenkins, Maven(Java))* Jenkins: 지속적인 통합(CI) 서비스를 제공하는 오픈 소스 도구* Maven: Java

wooinge.tistory.com

 



지난 포스팅에서는 Apache Tomcat과 Jenkins를 통합한 CI/CD 파이프라인을 구축했다.

이번에는 Jenkins와 Docker를 연결하고 코드를 배포하는 실습을 진행할 것이다.

 

 

CI/CD Pipeline 구성

 

[CI/CD 파이프라인 구축 실습 목표]

  • Jenkins server와 Docker의 연결

 

1. Docker host 구성하기

  • 이름: docker-host
  • AMI: Amazon Linux 2
  • 인스턴스 유형: t2.micro
  • 기존 키페어 연결: devops-project-key
  • 기존 보안 그룹 설정: devops-sg

 

EC2 인스턴스 실행

 

도커 설치

yum install docker -y

service docker status를 입력하면 docker가 현재 실행 중인디 확인할 수 있는데 현재 inactive 상태이다.

도커를 실행하기 위해서 service docker start 명령어를 사용한다.

 

 

2. Tomcat 컨테이너 생성하기

docker는 이미지 저장 집합소인 docker hub에서 이미지를 가져올 수 있다.
tomcat, nginx, mysql 등과 같은 이미지를 가져와 컨테이너로 실행할 수 있게 된다.

DockerHub를 이용한 이미지 가져오기 과정

 

 

 

 

편의를 위해 hostname을 dockerhost로 변경한다. 변경된 hostname을 적용하기 위해서 init 6 명령어를 입력한다.

hostname 변경

재부팅으로 인해 꺼진 docker를 다시 실행하고 docker hub에 있는 tomcat 이미지를 가져온다.

> docker pull tomcat

 

tomcat 이미지가 제대로 가져와졌는지 확인하기 위해서는 docker images 명령어를 이용한다.

 

tomcat 이미지를 이용하여 컨테이너를 실행한다.

 

> docker run -d --name tomcat-container -p 8081:8080 tomcat

 

[명령어 및 옵션 해석]

  • docker run: 컨테이너 생성
  • -d: detach mode로 컨테이너를 백그라운드로 실행 * defalut는 attach mode로 다른 명령어를 사용하기 위해서는 다른 터미널을 열어야 한다.
  • --name tomcat-container: 컨테이너의 이름을 tomcat-container로 지정
  • -p 8081:8080: 포트 번호 지정. '로컬 포트(Source port)':'도커 내부 포트(Destination port)'를 입력하면 되는데, 이미지 종류에 따라서 도커 내부 포트는 변경된다.
  • tomcat: 컨테이너 생성에 이용할 이미지 이름(docker images 명령어를 사용하면 이미지의 이름을 확인할 수 있다.)

위 명령어를 이용하여 컨테이너를 생성했다.

이제 docker-host 인스턴스의 퍼블릭 IP를 이용하여 액세스할 수 있게 되었다.

현재 로컬 포트를 8081로 설정했기 때문에 외부 브라우저에서 접속하기 위해서는 docker instance IP:8081을 입력하면 된다.

접속 불가

 

아마 처음 접속은 실패할 것이다! 왜? 보안 그룹 설정을 하지 않았기 때문이다.

현재 devops-sg의 인바운드 규칙을 살펴보면 22번 포트와 8080 포트만을 허용하고 있다.

8081 포트를 사용하기 위해서는 인스턴스의 보안 그룹 인바운드 규칙을 꼭 추가해줘야 한다.

 

다중 포트를 등록하기 위해서 하이픈(-) 기호를 이용하여 여러 포트를 등록하는 방법도 있다. 9000까지 등록한다.

보안그룹 인바운드 규칙 설정
404 에러 발생

 

접속해보면 아까와는 좀 다르지만 또~~! 접속할 수 없다고 뜬다.

HTTP Status 404 에러가 발생하였다.

페이지에 정상적으로 접속하기 위해서는 어떻게 해야할까?

 

이 문제는 tomcat 9 버전 이후에서 발생하는 문제인데, webapps의 폴더가 webapps.dist 폴더로 이동되었기 때문에 발생하는 에러이다. 원래는 webapps 폴더를 통해 브라우저에서 파일을 제공하게 되는데 현재 다른 폴더로 이동되어서 브라우저에서 제공할 파일이 없단 뜻이다.

구글링을 해보면 문제를 해결할 수 있는 방법을 찾을 수 있는데, 해당 컨테이너에서만 변경되는 내용이기 때문에 새로운 컨테이너를 생성하면 똑같은 작업을 반복해줘야하는 불편함이 있다.

https://forums.docker.com/t/tomcat-give-error-404/95130

 

Tomcat give error 404

Hi guys, After running tomcat on ubuntu with port forwarding its give this error Can you help to understand whats the problem? HTTP Status 404 – Not found Type Status Report Description The origin server did not find a current representation for the targ

forums.docker.com

 

그래서 Dockerfile이란 것을 직접 작성하여 입맛대로 해먹을 것이다.

 

++++ Dockerfile 작성하기

Dockerfile을 이용한 이미지 빌드 및 컨테이너 실행

 

Dockerfile을 작성하면서 사용되어야 할 명령어가 몇 가지 있다.

 

[Dockerfile 작성 시 사용할 수 있는 명령어]

  • FROM: Docker Hub에서 가져올 기본 이미지(Base image)
  • RUN: 명령어 실행
  • CMD: 컨테이너 실행 시 기본으로 사용할 명령어 설정
  • ENTRYPOINT: 실행 파일처럼 동작할 컨테이너 설정
  • WORKDIR: 작업 디렉토리 설정
  • COPY: 로컬 머신의 디렉토리를 Docker 컨테이너로 복사
  • ADD: 로컬 머신의 파일과 폴더를 Docker 컨테이너로 복사
  • EXPOSE: Docker에게 컨테이너가 실행 중에 특정 네트워크 포트를 사용할 것임을 알림
  • ENV: 환경 변수 설정

진행 순서는 다음과 같다.

순서 amazonlinux 2 에 Tomcat 설치 방법 사용해야 할 Dockerfile 명령어
1 Dockerhub에서 amazonlinux 2 이미지 가져오기 FROM
2 JAVA 설치 RUN
3 디렉토리 생성 RUN
4 생성한 디렉토리를 작업 디렉토리로 변경 WORKDIR
5 톰캣 패키지 설치(tar.gz) ADD /RUN
6 패키지 파일 압축 해제 및 설치 RUN
7 설치 파일 디렉토리 이름 tomcat으로 변경 RUN
8 Docker 컨테이너에게 8080 포트를 사용할 것이라고 알리기 EXPOSE
9 톰캣 서비스 실행 CMD

 

 

루트 디렉토리에서 Dockerfile을 생성한다

vi Dockerfile 

 

# Dockerfile

FROM amazonlinux:2
RUN yum install java-17-amazon-corretto -y
RUN mkdir /opt/tomcat
WORKDIR /opt/tomcat
RUN yum install -y tar
ADD https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.98/bin/apache-tomcat-9.0.98.tar.gz .
RUN tar -xvzf apache-tomcat-9.0.98.tar.gz
RUN mv apache-tomcat-9.0.98/* /opt/tomcat
EXPOSE 8080
CMD ["/opt/tomcat/bin/catalina.sh", "run"]

 

 

dockerfile을 이용하여 새 톰캣 이미지를 생성한다.

docker build -t mytomcat .

 

명령이 종료되면 docker images 명령을 이용하여 생성된 이미지를 확인한다.

 

이제 생성한 이미지를 이용하여 컨테이너를 실행해볼 것이다. 외부에서 접근할 포트는 8083으로 지정하였다.

docker run -d --name mytomcat-server -p 8083:8080 mytomcat

 

실행 중인 컨테이너를 확인하기 위해서 docker ps 명령을 사용한다.

 

브라우저에 포트 8083으로 접속하면 정상적으로 접속할 수 있다.

 

docker stop mytomcat-server 명령을 이용하여 컨테이너 실행을 종료하면 브라우저 연결이 끊기게 된다.

컨테이너 실행 종료

 

접속 끊김

3. Tomcat 서비스 실행을 위한 Dockerfile 생성하기

Dockerfile 생성 연습을 위해 사용했던 Dockerfile을 rm 명령을 이용하여 삭제하고, Tomcat 서버를 컨테이너로 실행하기 위한 Dockerfile을 생성할 것이다.

 

FROM tomcat:latest
RUN cp -R /usr/local/tomcat/webapps.dist/* webapps

 

* cp 명령어 사용하는 이유: 브라우저 접속에 필요한 파일을 멋대로 webapps.dist 디렉토리로 옮겨놨기 때문에 다시 옮겨주는 작업을 진행해야 한다.

 

이미지를 빌드한다.

docker build -t demotomcat .

도커 이미지 생성

 

생성한 도커 이미지로 컨테이너를 실행한다.

docker run -d --name demotomcat-container -p 8085:8080 demotomcat

8085 포트로 접속하면 기본 톰캣 사이트에 접속할 수 있다.

톰캣 접속 완료

 

 

4. Jenkins와 Docker 통합하기

파이프라인 구축을 위해 젠킨스와 도커를 본격적으로 통합해볼 것이다.

 

[목표]

  • dockeradmin 사용자 생성하기
  • Jenkins 콘솔에서 Publish Over SSH 플러그인 설치하기
  • Jenkins 콘솔에서 dockerhost 시스템 구성하기

 

우선 /etc/passwd 파일을 cat 명령어로 살펴보게 되면, ec2-user라는 사용자 존재하는 걸 확인할 수 있다.

마찬가지로 /etc/group을 살펴보면 docker라는 그룹이 있는 것을 확인할 수 있는데, 우리는 dockeradmin 사용자를 먼저 생성하여 docker 그룹에 넣어야 한다.

/etc/passwd
/etc/group

useradd 명령어를 이용하여 사용자를 생성하고, passwd 명령을 이용하여 이 사용자의 비밀번호를 등록한다.

사용자 추가

 

id dockeradmin 명령어를 사용해보면 해당 사용자의 정보를 확인할 수 있는데, 지금 dockeradmin이라는 기본 그룹에 속해있기 때문에 이 그룹을 docker로 옮길 것이다.

dockeradmin의 그룹 확인
docker 그룹 추가

usermod -aG docker dockeradmin 명령을 이용하여 dockeradmin의 그룹에 docker를 추가한다.

 

 

이제 생성한 계정으로 로그인해보려 한다.

새로운 터미널을 열어 dockeradmin 계정으로 로그인을 시도한다.

하지만 서버가 해당 사용자의 키를 거부하고 있기 때문에 로그인이 불가능하다는 화면이 뜨면서 실패한다. → 로그인 방식이 다르기 때문!!!!!!!

여태까지 우리는 맨 처음 ec2 인스턴스를 생성할 때 등록한 key를 이용하여 로그인하였다.

하지만 현재 새로운 사용자 dockeradmin을 생성하면서 Key를 생성하지 않고 패스워드를 생성한 상태이다.

 

결론적으로 docker-host 인스턴스는 현재 키 기반 인증(로그인)을 하고 있기 때문에 dockeradmin 사용자의 로그인이 거부되었단 뜻이다.

하지만 패스워드를 이용한 로그인도 허용하여 dockeradmin 유저로 로그인하고 싶다! 이 문제를 해결하기 위해서 /etc/ssh/sshd_config 파일에 저장된 PasswordAuthentication yes 주석을 해제하고 PasswordAuthentication no 부분을 주석처리하면 된다.

/etc/ssh/sshd_config 파일 수정

 

파일을 수정한 뒤 서비스를 재시작해야 한다.

service sshd reload

 

패스워드 기반 인증 부분을 yes로 변경함으로써 이제는 암호 기반 인증을 할 수 있게 되었다.

 

새 터미널을 열어 dockeradmin 계정으로 로그인을 다시 시도해본다.

접속 성공

아까는 아예 접속이 안 됐었는데, 이번에는 비밀번호를 물어보는 문구가 나왔다.

등록한 비밀번호를 입력하여 터미널에 접속한다.

 

이제 젠킨스 콘솔에 로그인하여 Publish Over SSH 플러그인을 설치한다.

 

Manage Jenkins - System을 클릭하여 새로운 SSH Servers를 추가한다. 스크롤을 아래로 쭉 내리면 나온다.

추가할 dockeradmin의 패스워드도 추가해야하기 때문에 Advenced를 클릭하여 추가로 작성해야 한다. Use password authentication, or use a different key를 체크하여 비밀번호를 추가한다.

 

  • Name: dockerhost
  • Hostname: ec2 인스턴스의 프라이빗 IP
  • Username: dockeradmin
  • Passphrase/Password: 비밀번호 입력

+ 만약에 key로 등록하고 싶다면 터미널에서 ssh-keygen 명령을 이용하여 키를 생성하면 된다. 생성을 마치면 키가 저장된 디렉토리가 출력되는데, 이 위치에 생성한 키를 확인할 수 있다. 

 

 

제대로 생성되었는지 확인하기 위해서 Test Configuration을 클릭하면 성공적으로 인증되었다는 것을 확인할 수 있다. 만약에 성공되지 않았다면,,, 무언가 잘못 입력된 것이기 때문에 검토 후 다시 테스트를 시도해보면 된다.

다음 포스팅에서는 배포와 자동 빌드에 대해 다뤄볼 것이다.