Backend boot camp/Session4
[Cloud]배포 컨테이너
by orioncsy
2022. 12. 9.
Docker
컨테이너 기술과 Docker의 탄생 배경
컨테이너
- 소프트웨어 수송, 즉 배포를 빠르게 하기 위해 리눅스 컨테이너 개발
- 도커를 통해 애플리케이션을 컨테이너 방식으로 실행 가능
- 실행 환경에 구애받지 않고 애플리케이션 실행 가능
Docker의 장점
의존성 충돌 문제 해결
- 의존성 충돌 문제
- 두 가지 프로그램이 다른 하나의 프로그램의 다른 버전에 의존 관계를 가지는 경우
- 여러 버전의 애플리케이션이 설치되지가 않기 때문에 하나는 제대로 된 실행 보장이 어렵다.
- 컨테이너에서 실행 중인 애플리케이션은 각자 고유의 의존성을 포함하고 실행 환경 격리
- 독립적으로 소유하고 격리하는 대상
- 프로세스
- 컨테이너 안에서만 엑세스 가능
- 다른 컨테이너 프로세스에 영향을 줄 수 없다.
- 네트워크
- 파일 시스템
- 가상 머신과 다른 방식
개발과 배포환경 일치
- 개발 환경이 다른 경우, 즉 운영체제나, jdk, node.js 같은 런타임 환경, 시스템 환경 변수가 다른 경우를 docker가 해결 가능
- docker를 사용하면 운영체제 상관없이 즉시 애플리케이션 실행 환경을 만들고 컨테이너 위에서 동일한 환경 하에 개발 진행 가능
- 배포 시 컨테이너에 담긴 애플리케이션을 실행하는 방식으로 서비스 제공
- EC2에 도커 설치 혹은 ECS 같은 애플리케이션을 도커 컨테이너째로 배포하는 방식 사용
수평 확장과 새로운 내용 배포 용이
- 트래픽 분산을 위해 프록시 서버를 운영하며 여러 서버 중 한 군데 사용하도록 돕는다.
- 위와 같은 서버를 리버스 프록시의 한 종류인 로드 밸런서라고 한다.
- 많은 트래픽으로 서버 증설하는 데 있어 컨테이너 기술이 사용
- 해당 애플리케이션을 컨테이너로 실행하고 로드 밸런서에 서버를 추가한다.
- 쿠버네티스와 같은 오케스트레이션 도구는 여러 서버 중 몇 대에만 운영하여 테스트를 하여 문제를 확인하는 것이 가능
Docker 용어
컨테이너
- 애플리케이션이 의존성, 네트워크 환경, 파일 시스템에 영향을 받지 않고 도커 위에 실행할 수 있도록 만든 장치
이미지
- 모든 컨테이너는 이미지로부터 생성
- 이미지는 애플리케이션 구성을 함께 담아놓은 템플릿으로 컨테이너 생성 가능
- 여러 개의 컨테이너를 생성할 수 있어 수평 확장 가능
- 기본 이미지에서 변경 사항을 추가하여 다른 이미지 생성 가능
레지스트리
- 이미지는 레지스트리에 저장
- 도커 CLI에서 이미지를 이용해 컨테이너를 생성할 때 이미지가 없다면 레지스트리에서 다운
- docker hub, amazon ECR 존재
Docker CLI
도커 이용하기
docker/whalesay
- 레지스트리 계정, 레포지토리 이름, 태그 세 가지 정보로 구성
- Registry_Account/Repository_Name:Tage
- registry
- docker hub
- 도커 이미지를 관리하는 공간
- 도커 허브를 기본 레지스트리로 설정
- Docker Hub, Private Docker Hub, 회사 내부 레지스트리
- repository
- 레지스트리 내 도커 이미지 저장되는 공간
- 이미지 이름이 사용
- github 레포지토리와 유사
- Tag
- 해당 이미지를 설명하는 버전 정보 입력
- 별도의 지정이 없으면 latest 태그를 붙인 이미지를 가져온다.
- docker/whalesay:latest
- docker hub 레지스트리에서 docker라는 유저의 whalesay 레포지토리에서 latest 태그를 가진 이미지라는 뜻
docker/whalesay 실행
- docker image pull docker/whalesay:latest 터미널에서 실행
- image pull은 레지스트리에서 이미지나 레포지토리를 가져온다.
- docker image ls를 통해 이미지 리스트 출력
- docker container run --name 컨테이너_이름 docker/whalesay:latest cowsay boo
- container run은 컨테이너 실행
- —name 은 컨테이너 이름 할당
- cowsay는 컨테이너 실행 시 호출
- boo는 cowsay에 넘겨질 파라미터
- docker container ps -a
- container ps는 컨테이너 리스트 출력
- -a 옵션은 종료된 컨테이너 포함 모든 컨테이너 출력
- docker container rm 컨테이너_이름
- container rm는 컨테이너를 지칭해서 삭제(ps 명령으로 확인하는 names 혹은 container ID 사용)
- docker image ls
- docker image rm docker/whalesay
- docker container run --name 컨테이너_이름 --rm docker/whalesay cowsay boo
- container run을 통해 이미지가 없다면 이미지 받아온 뒤 실행
- —rm은 컨테이너를 일회성으로 실행하고 중지, 종료될 때 리소스 모두 제거
- 예시
- docker container run -it --rm danielkraic/asciiquarium:latest
- -it의 경우 사용자와 컨테이너 간에 인터렉션이 필요할 때 사용하는 옵션으로 출력된 화면을 사용자가 지속적으로 보기 위해 사용
Copy, dockerfile
Docker 컨테이너에 파일 복사하기
- 웹 서버가 도커 컨테이너로 실행되고 웹 서버 구성 파일을 직접 만들거나 가져온 파일 구성할 경우 docker 컨테이너에 파일을 복사할 수 있다.
- 서버와 문제가 생기는 것을 호스트와 별개로 파악 가능하고 문제가 생긴 서버를 끄고 도커 이미지로 서버 재구동 가능
- 로컬에 있는 파일과 도커 이미지를 연결하는 방법
- CP(copy) : 호스트와 컨테이너 사이에 파일을 복사
- Volume: 호스트와 컨테이너 사이에 공간을 mount
- 마운트는 저장 공간을 다른 장치에서 접근할 수 있도록 경로를 허용
httpd 웹 서버
- 사용할 도커 이미지는 httpd(http daemon)
- Apache HTTP Server를 실행할 수 있는 오픈소스 웹 서버 소프트웨어
- httpd는 /user/local/apache2/htdocs/ 경로에 웹 서버 관련 파일이 저장되어 있다면 해당 파일 기반 웹 서버가 실행되도록 한다.
- docker container run --name 컨테이너_이름 -p 818:80 httpd
- 명령어로 httpd 실행
- -p 옵션은 로컬호스트의 포트와 컨테이너의 포트를 연결(818이 로컬 호스트 포트, 80이 컨테이너 포트)
- httpd는 일정 시간 연결 기록이 없으면 서버 가동 중지
- localhost:818을 웹브라우저에서 실행하면 웹 서버 동작을 확인 가능
- 새로운 터미널을 열어서 docker container cp 명령어를 입력해 로컬 호스트에 있는 파일을 컨테이너에 전달
- /src/main/resourc/template에서 docker container cp ./ 컨테이너 이름:/usr/local/apache2/htdocs/를 통해 로컬 파일을 컨테이너에 복사한다.
- /src/main/resourc/static에서 docker container cp ./ 컨테이너 이름:/usr/local/apache2/htdocs/를 통해 로컬 파일을 컨테이너에 복사한다.
- 문제가 발생한다면 docker exec -it 컨테이너 이름 bash 명령어를 통해 내부 터미널 접속 가능
- localhost:818로 접속하여 게임 서버 구동 확인
Docker 이미지 만들기
Docker 이미지 다루기
1개의 docker image 다루기
- sebcontents/part1 이미지를 사용하고 latest 태그를 사용한다.
- sebcontents/part1는 아파치 웹 서버 이미지(httpd)를 기반으로 commit 된 새로운 이미지
- docker run —name [컨테이너 이름] -d -p 3000:80 sebcontents/part1를 통해 컨테이너 생성 후 실행
- -d는 백그라운드로 실행(종료할 경우 docker container kill 컨테이너 이름
- docker cp ./ [컨테이너 이름]:/usr/local/apache2/htdocs/
컨테이너 내 bash shell 접속
- docker exec -it 컨테이너 이름 bash 명령어를 통해 컨테이너 내 bash shell 실행
- 종료는 exit를 통해 종료 가능
2 개의 docker image 다루기
- nginx 이미지 기반 sebcontents/client 이미지를 이용하여 client 컨테이너 생성
- spring 이미지 기반으로 0xnsky/server-spring 이미지를 이용하여 server 컨테이너 생성
- localhost 8080포트로 접속하면 sebcontents/client 이미지를 이용해 배포한 client 컨테이너의 80번 포트로 연결
- docker-compose CLI
- docker-compose up # -d 컨테이너를 백그라운드로 실행 가능(docker-compose.yaml에 정의된 이지미를 컨테이너로 실행)
- docker-compose down은 컨테이너 종료
- docker-compose up {특정 이미지}는 특정 이미지만 컨테이너로 실행
도커의 Volume
Volume
- 운영체제 환경에서 하나의 파일 시스템을 갖춘 스토리지 영역
- 도커 컨테이너와 데이터 볼륨을 활용하여 로컬 볼륨과 도커 컨테이너 볼륨을 공유 가능
- docker-compose.yml을 생성 후 작성
version: '3.8'
services:
nginx:
image: sebcontents/client
restart: 'always'
ports:
- "8080:80"
container_name: client
spring:
image: 0xnsky/server-spring
restart: 'always'
ports:
- "4999:3000"
container_name: server-spring
volumes:
- "./volumefolder:/data"
mysql:
image: mysql:latest
restart: 'always'
ports:
- "3307:3306"
container_name: database
environment:
MYSQL_ROOT_PASSWORD: root_계정_비밀번호
MYSQL_DATABASE: 초기_생성_데이터베이스
MYSQL_USER: 유저_이름
MYSQL_PASSWORD: 유저_패스워드
컨테이너와 VM 비교
컨테이너와 가상머신 공통점
- 프로세스, 네트워크, 파일 시스템을 격리할 수 있다.
컨테이너와 VM의 차이점
- VM은 컴퓨팅 자원을 많이 필요로 한다.
- 도커는 한 호스트 컴퓨터에 여러 개 컨테이너를 띄워도 무리가 가지 않는다.
- Docker Hub Registry를 통해 이미지를 보면 애플리케이션 단위로 만들어져 있다.
- 그러나 VM을 사용하기 위해서는 VM 위에 운영체제를 설치해야 하는 과정을 반드시 거쳐야 한다.
컨테이너 기술과 VM 작동 원리 비교
- VM에서는 운영체제가 구성요소로 필요한데 도커 컨테이너는 운영체제가 필요하지 않다.
- 도커는 도커라는 플랫폼위에 컨테이너들이 올라가고 그 아래 호스트 OS 만 존재한다.
- 각 컨테이너는 호스트 OS의 커널을 공유하고 있는 형태이다.
- 도커는 애플리케이션을 컨테이너화 하여 실행하는 것이 목적이기 때문에 OS에 컨테이너를 올려 사용하지 않는다.
- 호스트 입장에서는 컨테이너는 하나의 프로세스로 존재
- Docker hub에 존재하는 OS 이미지
- 컨테이너 내 애플리케이션 구성의 편의를 위해 존재하는 이미지로 사용
- 하이퍼바이저는 VM을 생성하고 구동하는 소프트웨어를 의미
- VMware, VirtualBox 등과 같은 프로그램이 존재
- 윈도우나 macOS 용 도커는 컨테이너 안쪽이 “리눅스”로 작동
- 리눅스 커널을 VM의 형태로 실행시키는 하이퍼바이저를 자체 구동