[Docker] docker-compose 구성파일 & Harbor

신현식·2023년 2월 12일
1

구름_Docker

목록 보기
6/6
post-thumbnail

python 실행

docker run -itd --name os1 centos:7
docker exec -it os1 bash
[root@cf810cf2d3b3 /]# mkdir /python_dir
[root@cf810cf2d3b3 /]# cd python_dir/
[root@cf810cf2d3b3 python_dir]# vi test.py

print("hello world")

[root@cf810cf2d3b3 python_dir]# python test.py
hello world

exit
  • ./test.py로는 실행이 안된다. 그 이유는 파이썬 같은 경우에는
    실행 파일이 아닌 그냥 문서파일이기 떄문에 단독으로 돌아가지 않는다. 따라서 앞에 python을 붙여줘야 실행이 가능하다.
# 파이썬이 바로 실행되도록 이미지 생성
docker commit -c 'CMD ["./test.py"]' -c 'ENTRYP
OINT ["python"]' -c 'WORKDIR /python_dir' os1 python_app:v1

# 내용확인
docker inspect python_app:v1 | less

# 파이썬 바로 실행
docker run --name python_app1 python_app:v1

도커파일로 실행


mkdir Dockerfile

cd Dockerfile

mkdir {webserver, python}
ls

# 웹서버 도커파일 만들기
cd webserver
vi Dockerfile

FROM centos:7
RUN ["yum","-y","install","httpd"]
COPY index.html /var/www/html/
CMD ["httpd","-D","FOREGROUND"]
VOLUME /var/www/html/
WORKDIR /var/www/html/
EXPOSE 80/tcp
EXPOSE 443/tcp
EXPOSE 443/udp

cp ~/index.html ./
cat index.html

# 생성
docker build -t my_web:v4 ./

# 들어가서 레이어 확인
docker inspect my_web:v4 | less
# webserver 디렉터리안에 도커파일과 index.html 파일이 존재해야 한다.
ls


# python 들어가기
cd ../python/
vi input_test.py

print("Input Test")
name=input("name :")
age=input("age : ")
print("내 이름은 {} 이고 내 나이는 {} 입니다.",format(name,age))

# python3 버전으로 실행
vi Dockerfile

FROM centos:7
RUN ["yum","-y","install","python3"]
RUN mkdir /python_dir
COPY input_test.py /python_dir
CMD ["./input_test"]
ENTRYPOINT ["python3"]
WORKDIR /python_dir


docker build -t python_app:v2 ./

docker run -it --name python_app2 python_app:v2

docker compose

일반적으로는 하나의 서비스를 제공하기 위해서는 서버는 다수의 시스템을 구동하고 연결하게 된다.
도커를 사용하는 경우를 생각해보면, 웹 서비스를 제공하기 위한 어플리케이션을 구동하는 컨테이너와, 어플리케이션 구동에 필요한 데이터를 저장하고 있는 데이터베이스 컨테이너를 함께 구동하는 환경을 예로 들수 있다.

하나의 서비스를 구동하기 위해 다수의 컨테이너가 필요할 경우, 각 컨테이너를 따로 관리한다면 불편할 뿐만 아니라, 구동시켜야 할 컨테이너가 누락되거나 하는 상황이 발생될 수 있다. 일반적인 docker는 한번에 하나씩만 컨테이너를 관리할 수 밖에 없기 때문에 다수의 컨테이너를 관리하는 데에는 어려움이 있을 수 있다.

이때 docker-compose를 이용하게 되면 다수의 컨테이너를 관리할 수 있다.
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

# 도커 컴포즈 위치 확인
ls -l /usr/local/bin/docker-compose

# 실행권한이 없기에 권한 부여
chmod a+x /usr/local/bin/docker-compose
ls -l /usr/local/bin/docker-compose

# 심볼릭 링크 설정
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
ls -l /usr/bin/docker-compose

# 설치 확인
docker-compose -v

docker-compose 명령은 컨테이너를 실행하기 위해 필요한 내용을 구성파일(YAML 형식)로부터 전달 받아 실행

구성 파일

  • docker-compose는 YAML 언어로 작성된 텍스트 파일을 기반으로 동작

  • 컨테이너가 사용할 이미지, 마운트 할 볼륨, 연결할 포트 등의 정보를 지정해야 하며 구성파일의 이름은 docker-compose.yml을 사용

  • Dockerfile을 디렉토리 별로 관리해야 되는 것처럼 docker-compose 또한 디렉토리 별로 관리하는 것이 바람직함

- docker-compose 문법 정리

ex) 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/
  1. 'version'은 도커 engine의 버전과 연관이 있으며, 버전에 따라 지원하는 기능이 달라질 수 있음. 'version'을 지정하지 않을 경우 1.0 지정

  2. 'services'은 서비스를 지정하는 항목으로 docker-compose를 통해 구동한 각 서비스에 대해 서술하는 부분으로 주의할 것은 service 내 항목의 이름이 생성된 컨테이너의 이름과는 다르다는 점

  • services의 항목은 생성되는 컨테이너의 이름으로 사용되지 않고 컨테이너 스케일 조정시에 사용
    • image: docker-compose 안에서 베이스 이미지를 지정할 수 있는데, docker build를 할 때와 마찬가지로 이미지가 로컬 환경에 없다면 해당 이미지를 다운받아서 base 이미지로 사용
      image: <이미지이름> : <태그>
services:
  proxy:
    image: nginx:latest # nginx 이미지
  1. build: build는 docker-compose에서 Dockerfile을 이용해 자동으로 docker build를 실행하고 생성된 이미지를 base 이미지로 사용
servies:
server:
    build: # Dockerfile 빌드
  • 만약 Dockerfile의 경로나 이름이 다른 곳에 있다면 특정 경로를 작성해 Dockerfile을 지정할 수 있음
servies:
server:
    build: # Dockerfile 빌드
      context: ./src/servers # Dockerfile 빌드 경로
      dockerfile: dockerfile-server   # dockerfile의 파일명이 dockerfile이 아닐 경우 파일명을 입력해야 함     
  1. command / entrypoint: command는 Dockerfile의 entrypoint와 거의 비슷
    Dockerfile의 entrypoint보다 docker-compose의 entrypoint가 우선순위가 더 높음
  • 아래와 같이 dockerfile에 entrypoint를 정의해도 docker-compose를 실행하게 되면 dockerfile의 entrypoin를 덮어쓰고 docker-compose의 entrypoint가 우선적으로 실행하게 됨
# docker-compose.yml 우선적으로 실행
services:
  nginx:
    build: .
    entrypoint: cat /etc/hosts
    # 또는
    entrypoint:
      - /bin/cat
      - /etc/hosts
      
-------------------------------- 

# Dockerfile
FROM centos:7
 
ENTRYPOINT ["/bin/ls", "-lh", "/root"]
      
  1. ports: ports는 호스트 OS와 컨테이너의 포트를 바인딩시키는 포트포워딩의 역할을 한다.
  • ports아래 옵션을 추가할 수 있는데, target은 컨테이너 내부 포트고, published는 호스트OS의 포트임.
    protocol은 포트 프로토콜을 지정할 수 있음
    <호스트 머신의 포트번호> : <컨테이너의 포트 번호> 와 같은 순서로 바인딩이 이루어짐

  • 만약, 8080:8080이 아닌 8080만 지정했을 경우(컨테이너의 포트번호만 지정한 경우, 호스트 머신의 포트는 랜덤한 값으로 설정됨 ex. 4631(랜덤):8080

# docker-compose.yml
version: "3"
services:
  nginx:
    build: .
    ports:
      - "8080:8080"
      
      # 위와 같은 표현방식, 이 방식으로도 표현가능
      - target: 8080       ## 컨테이너 내부 포트
        published: 8080    ## 호스트OS에서 공개할 포트
        protocol: tcp      ## 포트 프로토콜
  1. 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는 호스트 쪽에서는 접근이 불가능하며, 컨테이너 사이의 통신만 가능하도록 지정하는 것

  1. volume: dockerfile에서 사용되는 volume과 같이 컨테이너에 볼륨을 마운트할 때 사용
    <호스트>:<컨테이너> 방식으로 사용하고 마지막에 :ro를 추가해 볼륨을 읽기 전용으로 사용할 수 있음

보통 도커 컴포즈를 통해 빌드하게 되면 이미지가 생성되는데, 개발을 하다보면 수시로 코드를 수정하게 되는데 수정할 때마다 이미지를 재생성하면 굉장히 비효율적이게 됨

이때 코드 수정을 하고 있는 호스트의 경로를 컨테이너와 연결시켜서 이미지 빌드 없이 코드가 반영될 수 있도록 하는 것이 docker compose 에서의 volume

# docker-compose.yml
volumes:
  - ./mysql/mysql_data:/var/lib/mysql
  - ./mysql/sqls/:/docker-entrypoint-initdb.d/
  1. container_name: 컨테이너의 이름을 지정할 경우에 사용

docker-compose 명령어
up: 컨테이너 생성 및 실행
-d : 백그라운드에서 실행
--no-deps : 링크된 서비스를 실행하지 않음
--no-build : 이미지를 빌드하지 않음
-t : 컨테이너 타임아웃 시간 지정

scale : 생성할 컨테이너 수 지정
ps : 컨테이너 목록 확인
logs : 컨테이너 로그 출력
run : 컨테이너 실행
start : 컨테이너 시작
stop : 컨테이너 중지
restart : 컨테이너 재시작
kill : 컨테이너 강제 종료
rm : 컨테이너 삭제

web 서비스 실행


mkdir docker-compose
cd docker-compose

mkdir dc{1..5}
pwd -> /root/docker-compose

cd dc1
vi docker-compose.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 start

# 실행중인 것 확인
docker ps
docker-compose ps

# 지우기 위해서는 중지 필요
docker-compose stop 
docker-compose rm / rm -f

scale을 이용하여 동일한 컨테이너 여러개 생성

# 위의 .yml파일에서 ports, container_name을 주석처리한다
# 컨테이너 하나 생성
docker compose up -d  

# 한번에 3개 컨테이너 생성 = 나머지 두개 생성 
docker-compose scale web=3 

docker-compose ps

# 여러개 중지, 여러개 삭제 
docker-compose stop 
docker-compose rm -f 

-> yml에서 ports의 포트포워딩이나 container_name은 하나의 컨테이너밖에 적용하지 못하는 유니크한 특성 오류가 발생
-> 예시처럼 docker-compose를 이용하면 여러개를 쉽게 생성, 시작, 중지, 삭제할 수 있다 => 관리가 편하다

-> scale을 이용하려면 처음에 docker-compose up -d로 하나를 만들어놓고 그 다음에 scale을 이용해 원하는 개수만큼 컨테이너를 생성해주면 더 빠르고 편리

한번에 여러 다른 컨테이너 생성

# 새로운 작업공간 이동
cd dc2 

vi docker-compose.yml 

version: '3'
services:
  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 

docker-compose stop 
docker-compose rm -f 

-> web과 os 컨테이너 두개가 생성된 것을 확인, scale과는 차이가 있다.

dockerfile을 이용한 docker-compose 실행


cd dc3 

echo docker-compose test > index.html

# Dockerfile 작성 
vi Dockerfile 

FROM centos:7
RUN yum -y install httpd
COPY index.html /var/www/html/
CMD ["httpd","-D","FOREGROUND"]


# 도커 컴포즈용 yml 파일 작성
vi docker-compose.yml

version: '3'
services:
  web:
    build: ./  
    expose:
    - 80/tcp
    - 443/tcp
    - 443/udp

# 총 3개의 컨테이너 생성
docker-compose up -d
docker-compose scale web=3 

# 만들어진 web의 IP를 확인하고 curl를 보내본다.
docker inspect dc3_web_1 | grep IPA

-> "docekr build -t image이름 ./" 대신 docker-compse에서 직접 빌드하고 image생성

-> 처음부터 scale로 실행했을 때 에러가 발생할 수 있다. 이때는 도커 파일을 따로 실행해 image로 만들어 주고 이 이미지를 사용해서 docker-compose를 진행하면 scale로 실행해도 에러가 발생하지 않는다.

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개의 컨테이너 생성 

프라이빗 저장소

Harbor

harbor 설치과정 정보 보기


도커 초기화

# harbor 다운로드
yum install -y wget
wget https://github.com/goharbor/harbor/releases/download/v2.0.2/harbor-offline-installer-v2.0.2.tgz

or

curl -LO https://github.com/goharbor/harbor/releases/download/v2.0.2/harbor-offline-installer-v2.0.2.tgz



# 압축해제
tar zxvf harbor-offline-installer-v2.0.2.tgz

cd harbor

cp harbor.yml.tmpl harbor.yml

vi harbor.yml

hostname 수정 => goorm.study.com
# 비활성화
https => #https
port =443 => # port =443
certificate   => # certificate: /your/certificate/path
private_key   => # private_key: /your/private/key/path
harbor_admin_password: 0000


# daemon.json 파일 만들기
mkdir /etc/docker
vi /etc/docker/daemon.json

{
"insecure-registries":["192.168.56.102"]
}

# 최종 실행, 환경구축
systemctl restart docker
./install.sh
systemctl stop firewalld.service

#이후 웹사이트에서 192.168.56.102 접속
-> username: admin / passwoed: 0000

or

docker login 192.168.56.102

profile
전공 소개

0개의 댓글