일반적으로는 하나의 서비스를 제공하기 위해서는 서버는 다수의 시스템을 구동하고 연결하게 됨.
도커를 사용하는 경우를 생각해보면, 웹 서비스를 제공하기 위한 어플리케이션을 구동하는 컨테이너와, 어플리케이션 구동에 필요한 데이터를 저정하고 있는 데이터베이스 컨테이너를 함께 구동하는 환경을 예로 들수 있음
하나의 서비스를 구동하기 위해 다수의 컨테이너가 필요할 경우, 각 컨테이너를 따로 관리한다면 불편할 뿐만 아니라, 구동시켜야 할 컨테이너가 누락되거나 하는 상황이 발생될 수 있음.
일반적인 docker는 한번에 하나씩만 컨테이너를 관리할 수 밖에 없기 때문에 다수의 컨테이너를 관리하는 데에는 어려움이 있을 수 있음.
이때 docker-compose 를 이용하게 되면 다수의 컨테이너를 관리할 수 있음.
📒 사실 Kubernetes를 이용하기 때문에 docker-compose를 자주 사용할 일은 없을 것이다
1 . curl -L 명령어를 통해 docker-compose를 설치
curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
2 . 다운로드한 도커 컴포즈 파일을 실행 가능하도록 다운로드한 경로에 권한을 부여
chmod a+x /usr/local/bin/docker-compose
3 . 심볼릭 링크 설정으로 path 경로를 아래와 같이 설정
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
4 . 설치 확인
docker-compose -v
1 . docker-compose.yml 구성파일 예시
version: '3'
services:
log:
image: centos:7
volumes:
- /root/share:/tmp
container_name: base
web:
image: httpd
ports:
- "8080:80"
container_name: web_cont
volumes:
- /var/www/html/:/var/www/html/
'version'은 도커 engine의 버전과 연관이 있으며, 버전에 따라 지원하는 기능이 달라질 수 있음.
'version'을 지정하지 않을 경우 1.0 지정
'services'은 서비스를 지정하는 항목으로 docker-compose를 통해 구동한 각 서비스에 대해 서술하는 부분으로 주의할 것은 service 내 항목의 이름이 생성된 컨테이너의 이름과는 다르다는 점
services의 항목은 생성되는 컨테이너의 이름으로 사용되지 않고 컨테이너 스케일 조정시에 사용
1 . image
services:
proxy:
image: nginx:latest # nginx 이미지
2 . build
services:
server:
build: # Dockerfile 빌드
servies:
server:
build: # Dockerfile 빌드
context: ./src/servers # Dockerfile 빌드 경로
dockerfile: dockerfile-server # dockerfile의 파일명이 dockerfile이 아닐 경우 파일명을 입력해야 함
3 . command / entrypoint
#docker-componse.yml
services:
nginx:
build: .
entrypoint: cat /etc/hosts
# 또는
entrypoint:
- /bin/cat
- /etc/hosts
#Dockerfile
FROM centos:7
ENTRYPOINT ["/bin/ls", "-lh", "/root"]
-> dockerfile에 entrypoint를 정의해도 docker-compose를 실행하게 되면 dockerfile의entrypoin를 덮어쓰고 docker-compose의 entrypoint가 우선적으로 실행하게 됨
4 . ports
ports는 호스트 OS와 컨테이너의 포트를 바인딩 시키는 포트포워딩의 역할을 함
ports아래 옵션을 추가할 수 있는데, target은 컨테이너 내부 포트고, published는 호스트OS의 포트
protocol은 포트 프로토콜을 지정할 수 있음
ports는 <호스트 머신의 포트번호> : <컨테이너의 포트 번호> 와 같은 순서로 바인딩이 이루어짐
만약, 8000:8080이 아닌 8080만 지정했을 경우(컨테이너의 포트번호만 지정한 경우, 호스트 머신의 포트는 랜덤한 값으로 설정됨
-> ex) 4631(랜덤):8080
# docker-compose.yml
version: "3"
services:
nginx:
build: .
ports:
- "8080:8080"
#또는
- target: 8080 ## 컨테이너 내부 포트
published: 8080 ## 호스트OS에서 공개할 포트
protocol: tcp ## 포트 프로토콜
5 . expose
expose는 호스트os에 포트를 공개하지 않고, 컨테이너만 포트를 공개
즉, 호스트 OS와 직접적으로 연결되지 않고 링크등으로 연결된 컨테이너-컨테이너간의 통신만이 필요한 경우에 사용
일반적으로 로그 서버와 같이 호스트 머신에서 직접 액세스하지 않고, 웹 애플리케이션 서버 기능을 갖고 있는 컨테이너를 경유해서만 액세스하고 싶은 경우 등에 사용
예를 들면 A컨테이너에 express서버와 B컨테이너에 nginx간의 통신만이 필요할 경우, A컨테이너의 express 측에 expose를 설정해 컨테이너끼리 통신할 수 있도록 설정하는 것
dockerfile에 expose가 명시되어 있다면 docker-compose에는 작성하지 않아도 됨
#docker-compose.yml
version: "3"
services:
server:
build: # Dockerfile 빌드
expose:
- 8080 # 도커 내부적 포트
-> 다시 한 번 정리하자면, expose는 호스트 쪽에서는 접근이 불가능하며, 컨테이너 사이의 통신만 가능하도록 지정하는 것
6 . volume
dockerfile에서 사용되는 volume과 같이 컨테이너에 볼륨을 마운트할 때 사용
<호스트>:<컨테이너> 방식으로 사용하고 마지막에 :ro를 추가해 볼륨을 읽기 전용으로 사용할 수 있음
보통 도커 컴포즈를 통해 빌드하게 되면 이미지가 생성되는데, 개발을 하다보면 수시로 코드를 수정하게 되는데 수정할 때마다 이미지를 재생성하면 굉장히 비효율적이게 됨
이때 코드 수정을 하고 있는 호스트의 경로를 컨테이너와 연결시켜서 이미지 빌드 없이 코드가 반영될 수 있도록 하는 것이 docker compose 에서의 volume
#docker-compose.yml
volumes:
- ./mysql/mysql_data:/var/lib/mysql
- ./mysql/sqls/:/docker-entrypoint-initdb.d/
7 . container_name
up : 컨테이너 생성 및 실행
- -d : 백그라운드에서 실행
- --no-deps : 링크된 서비스를 실행하지 않음
- --no-build : 이미지를 빌드하지 않음
- -t : 컨테이너 타임아웃 시간 지정
scale : 생성할 컨테이너 수 지정
ps : 컨테이너 목록 확인
logs : 컨테이너 로그 출력
run : 컨테이너 실행
start : 컨테이너 시작
stop : 컨테이너 중지
restart : 컨테이너 재시작
kill : 컨테이너 강제 종료
rm : 컨테이너 삭제
1 . docker-compose 생성 예시
mkdir docker-compose # 작업할 디렉터리
cd docker-compose/
mkdir dc{1..5} # 여러 예시를 위해 각각의 작업공간 생성
cd dc1 # 첫번째 예시
vi docker-compose.yml # yml파일 작성
# shell
version: '3'
services:
web:
image: httpd:latest # 베이스 이미지 가져오기
expose: # 방화벽 뚫기
- 80/tcp
- 443/tcp
- 443/udp
ports:
- 8080:80 # 포트포워딩
container_name: web1
docker-compose up -d # docker-compose로 컨테이너 생성
docker-compose start # 컨테이너 시작
docker ps / docker-compose ps # 상태확인
docker-compose stop # 지우기 위해서는 중지해야한다
docker-compose rm / rm -f
2 . scale을 이용하여 동일한 컨테이너 여러개 생성
# 위의 .yml파일에서 ports, container_name을 주석처리한다
docker compose up -d # 컨테이너 하나 생성
docker-compose scale web=3 # 한번에 3개 컨테이너 생성 = 나머지 두개 생성
docker-compose ps # 상태확인
docker-compose stop # 여러개 중지
docker-compose rm -f # 여러개 삭제
-> yml에서 ports의 포트포워딩이나 container_name은 하나의 컨테이너밖에 적용하지 못하는 유니크한 특성때문에 scale을 할때 오류가 발생할 수 있다
-> 예시처럼 docker-compose를 이용하면 여러개를 쉽게 생성, 시작, 중지, 삭제할 수 있다 = 관리가 편하다
📒 scale을 이용하려면 처음에 docker-compose up -d로 하나 만들어놓고 그 다음에 scale을 이용해 원하는 개수만큼 컨테이너를 생성해주면 더 빠르고 편하다
3 . 한번에 여러 다른 컨테이너 생성
cd dc2 # 새로운 작업공간
vi docker-compose.yml # yml파일 작성
version: '3'
services:
web: # web 컨테이너 생성
image: httpd:latest # 이미지 가져오기
expose: # 방화벽 뚫기
- 80/tcp
- 443/tcp
- 443/udp
ports: # 포트포워딩
- 8080:80
container_name: my_web1
os: # os 컨테이너 생성
image: centos:7
docker-compose up -d # 컨테이너 실행
docker ps -a # 확인
-> web과 os 컨테이너 두개가 생성된 것을 확인
-> scale은 동일한 컨테이너를 여러개 생성하는 느낌이라면 이번 예시는 다른 컨테이너를 여러개 생성하는 것이다
4 . dockerfile을 이용한 docker-compose 실행
cd dc3
echo docker-compose test > index.html
vi Dockerfile # Dockerfile 작성
FROM centos:7
RUN yum -y install httpd
COPY index.html /var/www/html/
CMD ["httpd","-D","FOREGROUND"]
vi docker-compose.yml
version: '3'
services:
web:
build: ./
# "docekr build -t image이름 ./" 대신 docker-compse에서 직접 빌드하고 image생성한다
expose:
- 80/tcp
- 443/tcp
- 443/udp
docker-compose scale web=3 # 총 3개의 컨테이너 생성
4-1 . 미리 dockerfile을 build한 image로 docker-compose 실행
docker build -t my_web:v1 ./ # 미리 이미지 생성
vi docker-compose.yml
version: '3'
services:
web:
image: my_web:v1 # 생성한 이미지 가져오기
expose:
- 80/tcp
- 443/tcp
- 443/udp
docker-compose scale web=3 # 3개의 컨테이너 생성
1 . wget 설치
yum -y install wget
2 . 다운로드
wget https://github.com/goharbor/harbor/releases/download/v2.0.2/harbor-offline-installer-v2.0.2.tgz
3 . 압축 해제
tar zxvf harbor-offline-installer-v2.0.2.tgz
4 . https를 비활성화 해준다
cd harbor
cp harbor.yml.tmpl harbor.yml
vi harbor.yml
5 . daemon.json파일 작성
mkdir /etc/docker/
vi /etc/docker/daemon.json
{
"insecure-registries":["192.168.56.105"]
}
6 . 최종 설치
systemctl restart docker
./install.sh
📒 harbor 홈페이지
📒 harbor 설치 조건
📒 harbor 다운로드
📒 harbor 다운로드 github