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
복사
•
•
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 : 이미지 재빌드