Search
moon
sun

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