Search

Docker

Docker Internals

Docker는 LXC(리눅스 컨테이너)부터 시작된 기술로 초기 Docker는 LXC 기술을 기반으로 구현되었으나 최근에는 별도 컨테이너 기술을 구현하여 사용하고 있음

LXC (Linux COntainers)

단일 컴퓨팅 시스템에 설치된 리눅스 운영체제 상에서 다른 영역과 완전히 분리된 별도의 리눅스 시스템을 운영할 수 있는 리눅스 커널 기술
리눅스 운영체제 레벨에서 영역과 자원 할당 (CPU, 메모리, 네트워크) 등을 분리하여 마치 별도의 시스템처럼 사용할 수 있는 기술을 의미함
Docker 는 리눅스 커널에서 LXC 기술을 사용해서 리눅스 컨테이너를 만들고 리눅스 컨테이너 상에 별도로 구성된 파일 시스템에 시스템 설정 및 응용 프로그램을 실행할 수 있도록 하는 기술을 정의한 것

Docker 구성 요소

Docker Engine
Docker는 서버/클라이언트 구조로 이루어짐
서버는 Docker daemon process 형태로 동작함
Docker daemon process에 요청하기 위해 프로세스간 통신 기법이 필요하며 docker는 이를 위해 REST API를 사용함
Docker command는 일종의 클라이언트라고 이해하면 됨
Docker Image
Docker 컨테이너를 생성하기 위한 명령들을 가진 템플릿
여러 이미지들을 layer로 쌓아서 원하는 형태의 이미지를 만드는 것이 일반적임
Docker Container
Docker Image가 리눅스 컨테이너 형태로 실행한 상태(instance)를 의미함
Docker daemon에 있는 커널에서 LXC로 리눅스 컨테이너를 생성한 후 해당 컨테이너에 Docker Image에 포함된 명령을 실행하여 Docker Container를 만들고 실행함
Docker Container는 분리된 공간이므로 Docker daemon process를 통해 접속할 수도 있고 내부에 들어가서 코드 수정, 재실행 등도 가능함

Docker 명령

#기본 명령 양식 $ docker [명령] [옵션] [선택자(이미지ID/컨테이너)] $ docker image [명령] [옵션] ... $ docker container [명령] [옵션] ...
Shell
복사
1.
Docker 설치
Install Docker on Linux EC2
$ sudo yum update -y $ sudo amazon-linux-extras install docker $ sudo service docker start $ sudo systemctl enable docker $ sudo usermod -aG docker ec2-user #현 사용자를 docker group에 포함 $ id -nG #현 사용자가 docker group에 포함되어 있는지를 확인하는 명령 $ docker info
Shell
복사
Install Docker-Compose on Linux EC2
$ sudo curl -L "https://github.com/docker/compose/releases/download/{VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose $ docker-compose --version
Shell
복사
2.
Docker Image 다운로드
$ docker search [이미지명:태그] #이미지명:latest 는 최신 버전이고 latest가 기본값 $ docker pull [이미지명:태그] #이미지 다운로드 $ docker images #이미지 리스트 확인 $ docker image ls #이미지 리스트 확인 $ docker rmi [이미지ID or 이미지 REPOSITORY 이름] #이미지 삭제 $ docker image rm [이미지ID or 이미지 REPOSITORY 이름] #이미지 삭제
Shell
복사
3.
Docker Container 생성
$ docker create [이미지명:태그] #컨테이너 생성 $ docker create --name [이름] [이미지명:태그] #이름을 지정해 컨테이너 생성 $ docker ps #실행 중인 컨테이너 확인 $ docker ps -a #전체 컨테이너 확인 $ docker rm [컨테이너ID or 컨테이너명] #컨테이너 삭제
Shell
복사
COMMAND
컨테이너 실행 시 실행되는 프로세스 이름
STATUS
CREATED : 생성
UP : 실행중
PAUSE : 중지
EXISTED : 종료
4.
Docker 실행
$ docker run -it -d --rm --name [컨테이너명] [이미지명:태그] #컨테이너 이름을 붙이고 표준입력과 가상터미널을 붙여 백그라운드로 이미지를 실행하고 종료 시 삭제 $ docker attach [컨테이너ID or 컨테이너명] #실행되고 있는 컨테이너에 접근 $ docker start [컨테이너ID or 컨테이너명] #컨테이너 실행 $ docker restart [컨테이너ID or 컨테이너명] #컨테이너 재실행 $ docker pause [컨테이너ID or 컨테이너명] #컨테이너 중지 $ docker stop [컨테이너ID or 컨테이너명] #컨테이너 종료 $ docker kill [컨테이너ID or 컨테이너명] #컨테이너 즉시 종료
Shell
복사
포트포워딩
$ docker run -p [from port]:[to port] [이미지명:태그]
Shell
복사
Docker를 실행한 PC는 Host PC로 public IP를 갖고 각 컨테이너는 172.17.0.0/16 (Subnet 255.255.0.0)의 Private IP를 갖는다.
-p 옵션을 사용하면 NAPT(Network Address Port Translation) 기술로 특정 port로 access 시 해당 port를 컨테이너의 특정 Private IP로 변환해줄 수 있다.
AWS 보안그룹에서 특정 port에 대한 인바운드 규칙을 추가해줘야한다.
-P 옵션을 사용하면 EXPOSE로 오픈된 포트에 Host PC의 랜덤 포트가 매핑된다.
볼륨 마운트
$ docker run -v [호스트 PC의 절대경로]:[컨테이너의 절대경로] [이미지명:태그]
Shell
복사
호스트 PC의 파일을 컨테이너에서도 사용할 수 있도록 마운트 시켜주는 기능이다.
컨테이너가 삭제되어도 파일이 삭제되지 않고 유지할 수 있다.
컨테이너 링크
$ docker run --link [컨테이너명:사용할 호스트명]
Shell
복사
5.
이미지 빌드
$ docker build [옵션] [경로]
Shell
복사
-t 또는 —tag [이미지명:태그] : 이미지 이름 설정
-f [파일명] : 이미지 빌드 시 디폴트로 Dockerfile 파일명으로 된 파일을 찾아서 이미지를 빌드
—pull=[true/false] : FROM으로 지정된 이미지는 한 번 다운로드 받으면 이미지 생성 시마다 새로 다운로드 받지 않고 다운로드 받은 이미지를 사용
6.
이미지 조사
$ docker inspect [이미지명 or 컨테이너명]
Shell
복사
7.
이미지 히스토리
$ docker history [이미지명]
Shell
복사
8.
이미지 변경내역
$ docker diff [이미지명]
Shell
복사
A : 파일 또는 디렉토리 추가
D : 파일 또는 디렉토리 삭제
C : 파일 또는 디렉토리 수정
9.
파일 이동
$ docker cp [컨테이너명:파일 경로] [Host PC 경로]
Shell
복사
10.
커밋 (컨테이너 변경사항을 이미지로 저장)
$ docker commit [옵션] [컨테이너ID or 컨테이너명] [이미지명:태그]
Shell
복사
-m [내용] : 코멘트 작성
11.
기타 명령
$ docker system df #docker의 저장매체 현황 확인 $ docker container stats #컨테이너의 리소스 사용현황 확인 $ docker stop $(docker ps -a -q) #모든 컨테이너 중지 $ docker rm $(docker ps -a -q) #모든 컨테이너 삭제 $ docker rmi -f $(docker images -q) #모든 이미지 삭제 $ docker container prune #정지된 컨테이너 삭제 $ docker image prune #실행 중인 컨테이너 이미지 외의 이미지 삭제 $ docker system prune #정지된 컨테이너, 실행 중인 컨테이너 이미지 외의 이미지, 볼륨, 네트워크 삭제 $ docker logs [컨테이너ID or 컨테이너명] #컨테이너 에러 또는 출력 확인
Shell
복사

DockerFile이란

docker 이미지를 작성할 수 있는 기능
Dockerfile 문법으로 이미지 생성을 위한 스크립트를 작성할 수 있고 이를 기반으로 이미지를 생성할 수 있다.
나만의 이미지를 생성할 수 있고 배포를 위해서도 많이 활용된다.

DockerFile 문법

주석
#주석
Shell
복사
FROM
베이스 이미지 지정 명령으로 반드시 Dockerfile에 작성해야 하는 명령
FROM alpine
Shell
복사
LABEL
key=value 형식으로 메타 데이터를 넣을 수 있는 기능
LABEL maintainer="me" LABEL version="1.0.0" LABEL description="description"
Shell
복사
COPY
컨테이너 내부의 특정 폴더를 위한 볼륨을 생성하기 위해 사용
.dockerignore 파일에 제외목록 작성 가능
COPY ./from /to
Shell
복사
CMD
컨테이너가 실행되면 명령을 내리기 위해 사용
CMD는 하나의 Dockerfile에서 한 가지만 설정되며 여러 개일 경우 맨 마지막 CMD만 적용됨
#방법1 CMD ["executable", "param1", "param2", ...] CMD ["/bin/sh", "-c", "echo", "Hello"] #방법2 (ENTRYPOINT에 executable을 설정해두고 인자만 넘겨주는 방법) CMD ["param1", "param2", ...] #방법3 (쉘 명령처럼 작성하는 방법) CMD <command> <param1> <param2> ...
Shell
복사
ENTRYPOINT
CMD 명령에 덮어씌워지지 않고 반드시 실행해야 하는 명령을 설정할 때 사용
ENTRYPOINT는 컨테이너 실행 시 반드시 실행돼야 하는 명령을 넣고 별도로 각 컨테이너 생성 시 필요한 인자는 docker run에 넣는 식으로 활용
ENTRYPOINT → CMD 순으로 명령이 실행
ENTRYPOINT ["/bin/sh"]
Shell
복사
RUN
Dockerfile 안에서 사용하는 명령으로 이미지 생성 시 layer를 만들 수 있는 명령
RUN apt-get update RUN apt-get install -y apache2
Shell
복사
EXPOSE
docker 컨테이너의 특정 포트를 외부에 오픈하는 설정
docker run -p 옵션처럼 해당 포트를 Host PC의 특정 포트와 매핑시키진 않음
EXPOSE [포트번호]
Shell
복사
ENV
컨테이너 내의 환경변수를 설정하고 설정된 환경변수는 다른 명령에도 적용
ENV MYSQL_ROOT_PASSWORD=password ENV MYSQL_DATABASE=dbname
Shell
복사
WORKDIR
RUN, CMD, ENTRYPOINT 명령이 실행될 디렉토리 설정
WORKDIR [경로]
Shell
복사
ADD
파일, 디렉토리 또는 특정 URL의 데이터를 docker 이미지에 추가
추가할 파일이 압축 파일일 경우 자동으로 압축을 풀어줌
동일한 이름의 파일 또는 디렉토리가 이미 docker 이미지에 있을 시 덮어씌우지 않음
COPY 명령이 더 명시적이므로 COPY 명령을 사용하는 것을 추천
ADD file /var/www/html
Shell
복사
SHELL
쉘 프로그램을 지정하는 명령이지만 CMD 등으로 대체 가능
SHELL ['/bin/bash','-c']
Shell
복사
ARG
이미지/컨테이너에서 사용하는 변수를 설정하는 ENV와 달리 Dockerfile 내에서 스크립트 작성을 위해 필요한 변수를 설정하는 명령
ARG env=dev
Shell
복사
USER
이미지/컨테이너에서 작업을 하는 사용자 ID를 지정함
USER dave
Shell
복사
ONBUILD
생성한 이미지를 기반으로 새로운 이미지를 생성 시 실행하는 명령을 지정
ONBUILD ADD image.tar /var/www/html
Shell
복사
VOLUME
이미지를 위한 볼륨 생성

Docker Compose

여러 컨테이너를 모아서 관리하기 위한 툴
docker-compose.yml 파일을 작성하여 실행할 수 있음

Docker Compose 포맷

#Docker Compose 파일 포맷 버전 지정 version: "3" #컨테이너 설정 services: #컨테이너에서 사용하는 volume 설정으로 대체 가능 (옵션) volumes: #컨테이너간 네트워크 분리를 위한 추가 설정 부분 (옵션) networks:
YAML
복사
version
Docker Compose 버전을 지정하며 일반적으로 3을 사용
docker 버전과 docker compose 버전 호환성을 확인해야함
services
하위의 여러개 또는 하나의 컨테이너를 설정
services: [컨테이너명]: #컨테이너 정의 image: [이미지명:태그] #Docker Hub의 이미지 사용 restart: always #컨테이너가 다운될 경우 항상 재시작 volumes: #볼륨 설정 - [Host PC 경로]:[컨테이너 경로] environment: #환경변수 설정 - key=value env_file: #환경변수 파일 설정 - [경로] ports: #포트 매핑 - "[외부포트]:[내부포트]" [컨테이너명]: build: #이미지 직접 빌드 context: [폴더 경로] dockerfile: [Dockerfile 이름] links: #다른 컨테이너 연결 - "[컨테이너명]:[사용할 호스트명]" container_name: [사용할 컨테이너명] depends_on: #컨테이너 생성 선행관계 설정 - [컨테이너명]
YAML
복사

Docker Compose 명령

Docker Compose 실행
$ docker-compose up #실행 $ docker-compose stop #중지 $ docker-compose down #컨테이너 삭제 $ docker-compose logs #로그 출력 $ docker-compose config #docker-compose.yml 출력 $ docker-compose exec [컨테이너명] [명령] #실행 중인 컨테이너에 명령어를 실행
YAML
복사
-d : 백그라운드 실행
—build : 이미지 재빌드