Docker
- 리눅스 커널의 cgroups와 namespace에 의해 제공되는 기술
- 가상화 기능의 일종으로, 별도의 OS를 갖지 않아 VM(Virtual Machine) 보다 가볍다.
- 게스트는 호스트 OS와 자원을 공유한다.
- immutable infrastructure : 서비스 운영 환경을 통째로 이미지화 하여 배포하는 형태
Startup
설치
- 링크 참조
- docker api 리눅스 설치 :
sudo apt-get install docker
실행
DockerFile
이름의 파일을 생성하고 내용을 채워넣는다.python 서버 실행 예시
# python:3.10의 이미지로 부터 FROM python:3.9 # 제작자 및 author 기입 LABEL maintainer="huisam@naver.com" # 해당 디렉토리에 있는 모든 하위항목들을 '/app/server`로 복사한다 COPY . /app/server # image의 directory로 이동하고 WORKDIR /app/server # 필요한 의존성 file들 설치 RUN pip3 install -r requirements.txt # 환경 설정 세팅 RUN python setup.py install # container가 구동되면 실행 ENTRYPOINT ["python", "Server.py"]
리눅스 실행 예시
FROM ubuntu:18.04 ENV PATH="${PATH}:/usr/local/lib/python3.6/dist-packages/bin" ENV LC_CTYPE=C.UTF-8 RUN apt update RUN apt install -y \ gdb \ gcc \ git \ python3 \ python3-pip \ ruby \ sudo \ tmux \ vim \ wget RUN pip3 install pwntools # install pwndbg WORKDIR /root RUN git clone https://github.com/pwndbg/pwndbg WORKDIR /root/pwndbg RUN git checkout 2023.03.19 RUN ./setup.sh # install pwntools RUN pip3 install --upgrade pip RUN pip3 install pwntools # install one_gadget command RUN gem install one_gadget WORKDIR /root
별도의 이미지가 필요하다면 생성 혹은 다운로드 하고, DockerFile 에서 경로를 설정한다.
일반적인 iso 파일은 docker에서 자체 지원한다.
docker build <DOCKER_FILE_PATH> -t my_image
명령어로 빌드 수행.- ex)
docker build . -t version:ubuntu1804 .
: ubuntu1804 버전(version) 태그를 가진 docker 이미지 빌드 - ex)
docker build . -t my_image .
: my_image 이름(name)을 가진 docker 이미지 빌드 -t
: 빌드 한 이미지에 태그를 추가 (컨테이너 실행 혹은 이미지 관리에 태그를 이용)
- ex)
docker run -d -t -v ~:/volume --privileged --name=my_container my_image
--name=my_container
: ‘my_container’ 라는 이름으로 컨테이너 생성-t
: tty 설정-d
: background 실행-v .:/volume
: 현재 디렉터리를 /volume 경로의 폴더에 연결my_image
: docker build 명령어로 빌드한 이미지 중 my_image 라는 이름의 이미지를 사용
docker exec -it -u root my_container bash
- 생성된 ‘my_container’ 에 root 계정으로 bash 실행하여 접근
오류가 발생한다면 오류와 해결방법 참조
관리
이미지
docker images
: 로컬에 저장된 docker 이미지 확인docker search IMAGE_NAME
: 이미지 이름을 docker hub 에 검색docker image pull IMAGE_NAME:TAG
: 이미지 이름과 태그를 이용해 ‘IMAGE_NAME:TAG’ 에 해당하는 이미지를 docker hub에서 다운로드docker image rm IMAGE_NAME
: 이미지 이름이나 ID로 이미지를 삭제
컨테이너
- 실행시킨 docker 들은 (
docker run
명령 수행)는 컨테이너 형태로 남아있다. docker ps -a
: 컨테이너 목록 확인docker stop CONTAINER_NAME
: CONTAINER_NAME 컨테이너 중지docker rm CONTAINER_NAME
: CONTAINER_NAME 컨테이너 삭제docker container start CONTAINER_NAME
: CONTAINER_NAME 컨테이너 실행docker container top CONTAINER_NAME
: CONTAINER_NAME 컨테이너 동작 프로세스 정보 확인
오류와 해결방법
is docker daemon running? 에러
service docker status
입력시 docker daemon이 꺼져있는지 확인service docker start
명령으로 daemon 실행- 만약 명령은 수행되나 켜지지 않는다면 systemctl명령 수행
systemctl start docker
: docker를 daemon으로 실행systemctl enable docker
: OS실행시 docker daemon을 기본 실행
- systemctl 명령도 안된다면
/lib/systemd/system/docker.service
,/lib/systemd/system/docker.socket
이 제대로 있는지 확인하여 설치 여부를 재확인한다.
참조
- 만약 명령은 수행되나 켜지지 않는다면 systemctl명령 수행
init 프로세스(PID 1)이 /bin/bash로 실행되지 않을 때, docker 실행 방법
docker run -t -i ubuntu:16.04 /bin/bash
The container name "CONTAINER" is already in use by container
- 동일 한 이름의 컨테이너가 이미 존재해서 발생하는 에러
docker ps -l
로 컨테이너를 확인한다.docker stop CONTAINER_NAME
로 컨테이너 종료docker rm CONTAINER_NAME
로 컨테이너 삭제- 다시 docker를 실행시키면 문제가 해결된다.
container ~~~~ is not running
- 컨테이너가 실행되고 있지 않아서 발생하는 오류이다.
docker container start CONTAINER_NAME
명령으로 컨테이너를 실행시킨 후에는docker exec
명령으로 컨테이너에 정상 접속할 수 있다.
DockerFile 명령어
FROM
: base image를 지정하는 명령어- DockerFile의 시작은 무조건 FORM 이 필요하다.
FROM <IMAGE>:<VERSION>
형태로 사용한다.FROM base:${CODE_VERSION}
MAINTAINER
: 메인테이너 정보ARG
: 변수를 선언ARG CODE_VERSION=latest
- 선언한 변수는
${CODE_VERSION}
형태로 참조 가능하며, build시 자동으로 argument로 사용된다. ARG port
와 같이 값을 정의하지 않고 선언만 한 경우에는, –build-arg 옵션으로 값 설정이 가능하다.docker build --build-arg port=80
RUN
: 컨테이너가 이미지를 실행하기 전 수행할 쉘 명령어CMD
: 컨테이너 실행 시 디폴트로 실행할 커맨드를 설정CMD ["executable","param1","param2"]
형태로 사용- ENTRYPOINT와 조합하여 사용 가능하며, ENTRYPOINT에서 “executable”(명령어) 를 선언한 상태라면 CMD에서 executable 없이 param만 선언 가능하다.
CMD ["param1","param2"]
- 여러개의 CMD를 선언하면 가장 마지막의 것만 동작
CMD /code/run-app
와 같이 사용
COPY
: 호스트 컴퓨터의 디렉터리나 파일을 Docker 이미지의 파일 시스템으로 복사COPY: <SRC> <DEST>
COPY: ["<SRC1>", "<SRC2>", ... <DEST>]
ADD
: 현재 이미지의 파일들을 내부 이미지의 특정 디렉터리에 복사. 이미지 안에 해당 경로가 없으면 생성하여 추가ADD <DIR_SOURCE> <DIR_DEST>
- COPY의 상위호환 명령어로, 압축 파일이나 링크상의 파일도 추가 가능하다.
ENV
: 환경변수를 설정하기 위한 명령어EXPOSE
: 외부와 연결할 포트, 컨테이너 실행시 -p 옵션을 사용하여 컨테이너로 유입되는 트래픽을 관리하려면 설정해 두어야 함.EXPOSE <port> [<port>/<protocol>...]
- 프로토콜은 tcp,udp 중 선택 가능
ENTRYPOINT
: 컨테이너 시작시 수행할 명령어ENTRYPOINT ["<CMD>", "<PARAM1>", "<PARAM2>"]
형태로 사용ENTRYPOINT ["npm", "start"]
LABEL
: 이미지에 metadata를 정의하는 명령어LABEL <key>=<value> <key>=<value> <key>=<value> ...
STOPSIGNAL
: 시스템이 종료하기 위한 SIGNAL을 설정한다.- SIGINT, SIGKILL 등을 설정할 수 있으며, 이를 전달받으면 컨테이너가 종료하게 된다.
- 설정하지 않으면 SIGTERM 이 자동으로 세팅된다.
USER
:VOLUME
: 볼륨을 mount 하기 위한 자리를 세팅하는 명령어VOLUME ["경로1", "경로2", ...]
- run의 -v 옵션과 유사하지만, docker가 임의로 생성한 디렉터리에 volume을 연결한다. 이는 docker volume 명령어로 관리 가능하지만, 컨테이너가 삭제되고 나면 직접 접근하기 힘들다.
WORKDIR
: 컨테이너에서 작업 디렉터리 이동- 리눅스의 cd 명령과 유사
ONBUILD
: 빌드 후에 동작해야 할 명령들을 설정하는 명령어- DockerFile 명령어는 이미지 빌드를 위한 명령어이며, 빌드 할 때 마다 동일한 결과물을 산출한다. 하지만 빌드된 이미지의 결과물을 다음 빌드 때 사용하고 싶다면 이 명령을 사용한다.
ONBUILD Learn more about the "ONBUILD" Dockerfile command. ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src
- 다음 빌드 때 ONBUILD가 호출된 순서대로 명령이 동작한다.
docker inspect
명령어로 확인 가능
- DockerFile 명령어는 이미지 빌드를 위한 명령어이며, 빌드 할 때 마다 동일한 결과물을 산출한다. 하지만 빌드된 이미지의 결과물을 다음 빌드 때 사용하고 싶다면 이 명령을 사용한다.
Docker 라이브러리 명령어
- 이미지 : 특정 환경을 만들기 위해 세팅된 정보.
- 컨테이너 : 실행가능한 상태의 프로세스. 이미지를 컨테이너에 담아 실행시킬 수 있다.
생성 및 설정
- 버전 확인:
docker -v
- 이미지 다운:
docker pull <이미지명>[:태그]
- 이미지 생성 :
docker build . -t <이미지명> [태그]
- 현재 경로에서 Dockerfile을 찾아 그 안의 명세에 따라 빌드가 된다.
- 설치된 도커 이미지 확인:
docker images
실행
- 컨테이너 생성, 실행하지 않고 정지:
docker create [옵션] <이미지명>[:태그]
- 컨테이너 실행 후 CLI 접속:
docker attach <컨테이너 id 또는 이름>
- 컨테이너 실행. 지정된 작업 수행:
docker start <이미지명>
- 이미지 다운받아 실행:
docker run <이미지명>
- 환경변수 설정:
docker run -e <환경변수=설정값>
옵션
- 이미지 다운받아 실행 후 CLI 접속:
docker run -it <이미지명>
- 컨테이너 실행시 이름 지정:
docker run --name <컨테이너명> <이미지명>
- 디렉터리 연결:
docker run -v <로컬경로>:<컨테이너 내부 경로> <이미지명>
- 포트 연결:
docker run -p <로컬포트>:<컨테이너 포트> <이미지명>
- 백그라운드 실행:
docker run -d <이미지명>
- 프로세스 종료시 컨테이너 자동 삭제:
docker run -rm <이미지명>
관리
- 실행중인 컨테이너 확인:
docker ps
- 생성된 컨테이너 확인:
docker container list
- 컨테이너 종료:
docker stop <컨테이너 id 또는 이름>
- 일시중지:
docker container pause <컨테이너명>
- 일시중지 해제:
docker container unpause <컨테이너명>
- 컨테이너 삭제:
docker rm <컨테이너 id 또는 이름>
- 모든 컨테이너 삭제:
docker rm `docker ps -a -q
- 볼륨까지 같이 삭제:
docker rm -v <컨테이너 id 또는 이름>
- 이미지 삭제:
docker rmi [옵션] <이미지 id>
- 컨테이너 내부에서 커맨드라인을 수행하도록 외부에서 입력:
docker exec [옵션] <컨테이너 id 또는 이름> <커맨드>
- 컨테이너 실행 후 지정된 명령어 수행:
docker exec -it <컨테이너 id 또는 이름> [명령어]
- 백그라운드 실행중인 도커 로그 확인:
docker logs -f <컨테이너 id 또는 이름>
.dockerignore
- Docker 이미지 생성시 들어가지 않을 파일들을 지정 가능
docker-compose
- 각각의 Dockerfile들을 묶어 하나의 시스템을 구성하는 도구
- docker 실행시 명령어를 미리 작성해 놓은 스크립트라고 보면 된다.
docker-compose up
명령으로 docker-compose 파일 빌드 가능. 하위 경로에 Dockerfile들이 각각의 서비스에 해당됨
version: '3' // 도커 컴퍼즈 버전 3이상 요구
services: // 서비스 내용들이 아래에 옴
service1: // 서비스 이름으로, 마음대로 정의 가능
build: ./S1 // docker-compose 파일로부터 경로를 지정
volumes:
- ./S1:/home/root // docker run -v 옵션 적용과 동일
ports:
- "1234:1234" // docker run -p 옵션 적용과 동일
environment:
- DEBUG_LEVEL=debug // 환경변수 설정 가능
links: // docker-compose 3부터는 필요없어진 기능, 네트워크 연결을 위해 사용
- service2
service2: // 또다른 서비스, 위와 같이 작성 가능
...