해당 문서는 회사 노션에 기록해둔 도커 개인 학습 페이지를 옮겨온 것입니다. 이후 정리가 다시 한번 필요합니다.
흔들리는 도커(Docker)의 위상 - OCI와 CRI 중심으로 재편되는 컨테이너 생태계
Docker Engine API v1.41 Reference
목차
1. 도커
2. 역사
3. 사용 예시
배운 것
실행중인 컨테이너에 접속하여 명령어도 입력가능하며 패키지도 추가로 설치 가능하다.
CPU, 메모리 사용량 제한, 특정 포트 연결 등등 편리하게 사용 가능하다.
2. 레이어 저장 방식
도커 이미지는 컨테이너를 실행하기 위한 모든 정보가 담겨 있어 보통 수백 MB에 육박하는 용량을 가진다.
그래서 업데이트 때 마다 이미지를 다시 받는다면 비효율 적이다.
도커는 이러한 문제의 해결을 위해 레이어 방식을 사용한다.
여러개의 레이어를 하나의 파일 시스템으로 사용하게해준다.
이미지는 여러개의 read only 레이어로 구성되고 파일이 추가되거나 수정되면 새로운 레이어가 생성된다.
만약 새로운 업데이트가 있으면 해당 업데이트 내용만 레이어로 되어 추가 다운 받으면 되기 때문에 효율적으로 이미지를 관리 할 수 있다.
컨테이너 생성 시에도 해당 방식을 채택하여, 기존의 이미지 레이어 위에 읽기/쓰기 레이어를 추가한다. 이미지 레이어를 그대로 사용하면서 컨테이너가 실행 중에 생성하는 파일이나 변경된 내용은 읽기/쓰기 레이어에 저장되므로 여러개의 컨테이너를 생성해도 최소한의 용량만 사용한다.
이미지에는 컨테이너를 실행하기 위한 모든 정보가 들어 있기 때문에, 추가로 필요한 설치 요소가 없다.
새로운 서버가 추가된다면 미리 만들어둔 이미지를 다운 받고 컨테이너만 생성하면 되는 것이다.
운영체계를 기반으로 만들어진 대부분의 소프트웨어는 실행을 위해 OS와 Software가 사용하는 동적 라이브러리에 대해 의존성을 가진다. 하지만 한 시스템 위에서 둘 이상의 소프트웨어를 동시에 실행 시키려는데 동일한 라이브러리지만 버젼이 다르다면 ? 또는 소프트웨어의 운영 체제가 다르다면? 이러한 문제를 해결 하기위해 각 소프트웨어에 대한 시스템을 각각 준비하면, 너무 고비용이다.
이것을 효율적으로 해결해준 것이 컨테이너 개념이다.
컨테이너는 어플리케이션을 실제 구동 환경으로부터 추상화 할 수 있는 논리 패키징 매커니즘을 제공한다.
애플리케이션과 바이너리, 라이브러리 등을 패키지로 묶어 배포 가능하게 한다.
장점
→ 서로 다른 컴퓨팅 환경에서 애플리케이션을 안정적으로 실행 가능하다.
→ 개발 환경에 구애 받지 않고 빠른 개발과 배포가 가능하다.
단점
→ 포맷과 런타임에 대한 특정한 규격이 없다.
기존의 가상화 방식 vs 컨테이너 방식
기존 : 호스트 OS위에 게스트 OS 전체를 가상화하여 사용하는 방식
→ 사용법은 비교적 간단하지만 무겁고 느리다.
컨테이너 방식 : 기존의 방식에서 성능문제를 개선하기 위해 프로세스를 격리 하는 방식이 등장하였고, 리눅스에서는 이 방식을 컨테이너라고 하게 된다.
→ 가볍고 빠르다.
Container Runtime
컨테이너 실행단계 : 1.이미지 다운로드 → 2.이미지를 번들로 압축 해제 → 3.번들에서 컨테이너를 실행
도커는 런타임의 표준화를 위해 세번째 단계인 컨테이너 실행 부분만 표준화 하였다.
→ 컨테이너의 런타임은 저수준, 고수준 컨테이너 런타임으로 나뉘게 된다.
저수준 : 실제 컨테이너를 실행 | OCI 런타임
고수준 : 컨테이너 이미지의 전송, 관리, 이미지 압축 풀기
고수준 컨테이너 런타임은 컨테이너 실행을 위해 저수준 런타임 위에서 배치되며 컨테이너의 실행 및 모니터링에 쓰이는 데몬 및 API 를 제공한다.
도커는 docker-containered 라는 고수준 컨테이너 런타임을 제공한다.
CRI(Container Runtime Interface)
Kubernetes에서 만든 컨테이너 런타임 인터페이스
→ 개발자들의 컨테이너 런타임 구축을 쉽게 해준다.
초기 쿠버네티스는 컨테이너를 실행하기 위해 도커를 사용했다.
쿠버네티스 클러스터 워커 노드의 에이전트인 Kubelet 소스코드 내부에 통합되어 있었다.
→ 통합된 프로세스 형태로, kubelet에 대한 깊은 이해와, 유지보수가 힘들게 되었다.
그래서 CRI를 만들어 추상화 계층을 제공함으로써 개발자가 컨테이너 런타임 구축에 집중하게 해주었다.
도커의 단점
도커는 클라이언트/서버 애플리케이션으로 클라이언트인 Docker CLI와 서버인 Docker daemon 으로 구성된다.
서버는 컨테이너 이미지 빌드, 광리, 공유, 실행 및 컨테이너 인스턴스 관와 같이 너무 많은 기능을 담당하는 데몬으로 모든 컨테이너를 자식 프로세스로 소유한다.
→ 무겁고, 장애가 발생하면 모든 자식 프로세스에 영향을 끼친다.
모든 도커 명령은 루트 권한을 가진 사용자에 의해서만 실행되기 때문에 보안 문제가 발생할 수 있다.
도커는 독립된 컨테이너에서 프로세스를 실행한다. 그리고 그 컨테이너는 호스트에서 실행되는 프로세스이다. 그리고 그 호스트는 로컬 일수도, 원격 일수도 있다.
docker run되는 컨테이너 프로세스는 자체 파일 시스템, 자체 네트워킹 및 호스트와 분리된 자체 독립적인 프로세스 트리가 있다는 전제하에 격리가 된다.
사용 예제
**$ docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]**
docker run -d -e INSTACHART_SETTINGS_MODULE=staging registry.gitlab.com/gsstory/marketing/insta-chart/crew:1.4.172
옵션
—add-host=[] : /etc/hosts에 호스트 이름과 IP 주소를 추가
-d : Detached 모드. 데몬 모드 라고 불리우며, 컨테이너가 백그라운드로 실행
-e, -env=[] : 컨테이너에 환경 변수를 설정, 주로 설정 값이나 비밀번호를 전달
—env-file=[] : 컨테이너에 환경 변수가 설정된 파일을 적용
-h, —hostname="" : 컨테이너의 호스트 이름을 설정
-m, —memory="" : 메모리 한계를 설정, <숫자 단위> 형식이며 단위는 b,k,m,g
—name : 컨테이너에 이름을 설정
—restart="" : 컨테이너 안의 프로세스 종료 시 재시작 정책을 설정
-w, —workdir="" : 컨테이너 안의 프로세스가 실행 될 디렉토리를 설정
docker ps : 컨테이너 목록 보기 (default : 가동중인 컨테이너)
Pull an image or a repository from a registry
$ docker pull [OPTIONS] NAME[:TAG|@DIGEST]
docker pull [registry.gitlab.com/gsstory/insta-factory/mgp-snshelper-server/worker:0.1.](http://registry.gitlab.com/gsstory/insta-factory/mgp-snshelper-server/worker:0.1.23)68
docker search
docker stop
docker stop [option] CONTAINER [CONTAINER...]
도커 ID의 전체 길이는 64자리이다. 하지만 명령어를 인자로 전달할 때는 전체를 전달 하지 않아도된다. 앞부분이 겹치지 않는다면, 1~2자만 입력해도 된다..!
docker start
docker restart
컨테이너 명령어 실행하기
실행중인 컨테이너에 들어가 컨테이너 내의 파일을 실행할 때.
docker exec [OPTIONS] container command [ARG...]
ex) ssh -i "nouveau.pem" ec2-user@ec2-3-35-231-7.ap-northeast-2.compute.amazonaws.com
docker ps
sudo docker exec -it e3f bash
-i : STDIN 표준 입출력을 연다.
-t : 가상 tty(pseudo-TTY)를 통해 접속
합쳐서 -it
하나 또는 하나 이상의 컨테이너를 삭제한다.
docker rm [OPTIONS] CONTAINER [CONTAINER...]
멈춰진 컨테이너들을 전부 삭제 한다.
docker container prune [OPTIONS]
removes containers created more than 5 minutes ago:
$docker container prune --force --filter "until=5m"
removes containers created before 2017-01-04T13:10:00:
$docker container prune --force --filter "until=2017-01-04T13:10:00"
하나 또는 하나이상의 이미지를 삭제한다.
$docker rmi [OPTIONS] IMAGE [IMAGE...]
주의할 점은 이미지에 하나 또는 그 이상의 태그가 걸려 있다면, 그 태그 까지 같이 이미지가 삭제되기 전에 삭제를 해주어야 한다. -f 옵션을 주면 해당 기능을 해주기는 한다.
docker history
docker build
docker inspect
docker —help
컨테이너가 정상적으로 동작하는지 확인하는 방법
docker logs [OPTIONS] CONTAINER
이미지 생성을 위한 설정 파일
컨테이너에 반드시 설치해야하는 패키지, 소스코드, 명령어, 환경 변수 설정 등을 기록한 파일이다. 이것을 build하면 이미지가 생성되며, 애플리케이션 빌드 와 배포를 자동화 시킬 수 있다.
예시
[findeadple repo 의 docker file]
FROM python:3.7-slim
ENV LANG ko_KR.utf-8
RUN set -ex \
&& ln -s -f /usr/share/zoneinfo/Asia/Seoul /etc/localtime
RUN set -ex \
&& apt-get update \
&& apt-get -y install libpq-dev gcc nginx supervisor cron logrotate
WORKDIR /fineadple
COPY docker/images/manager/nginx/nginx.conf /etc/nginx/nginx.conf
COPY docker/images/manager/nginx/conf.d/manager.conf /etc/nginx/conf.d/manager.conf
COPY docker/images/manager/cron/root /var/spool/cron/crontabs/root
COPY docker/images/manager/supervisor /etc/supervisor/conf.d
COPY docker/images/manager/logrotate.d/ /etc/logrotate.d/
COPY VERSION VERSION
COPY README.md README.md
COPY setup.py setup.py
COPY app/core app/core
COPY app/manager app/manager
COPY app/cli.py app/cli.py
COPY app/__init__.py app/__init__.py
RUN set -ex \
&& chmod 600 /var/spool/cron/crontabs/root \
&& chown root.crontab /var/spool/cron/crontabs/root \
&& chmod 644 /etc/logrotate.d/nginx \
&& chmod 644 /etc/logrotate.d/request \
&& chmod 644 /etc/logrotate.d/query \
&& pip install -e .[manager]
EXPOSE 80
[fineadple-web]
# docker build -t eb . -f .dockerfiles/Dockerfile
# FROM 계정/eb_release
FROM herren/release
MAINTAINER assavictory@gmail.com
ENV LANG C.UTF-8
ENV TZ 'Asia/Seoul'
RUN echo $TZ > /etc/timezone && apt-get update && apt-get install -y tzdata && rm /etc/localtime && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && dpkg-reconfigure -f noninteractive tzdata && apt-get clean
# 현재경로의 모든 파일들을 컨테이너의 /srv/release 폴더에 복사
COPY . /srv/release
# cd /srv/release와 같은 효과
WORKDIR /srv/release
# requirements 설치 ( requirements.txt 에 기록해 둔 pip list 를 모두 install )
RUN /root/.pyenv/versions/release/bin/pip install wheel
RUN /root/.pyenv/versions/release/bin/pip install -U setuptools
RUN /root/.pyenv/versions/release/bin/pip install -r requirements.txt
# supervisor 파일 복사
COPY .config/supervisor/gunicorn.conf /etc/supervisor/conf.d/
COPY .config/supervisor/nginx.conf /etc/supervisor/conf.d/
RUN env
ENTRYPOINT /bin/sh config.sh
EXPOSE 80 8000
From
생성할 이미지의 베이스가 되는 이미지. 반드시 필요
<이미지이름>:<태그>
RUN
이미지 생성을 위해 컨테이너 내부에서 실행할 쉘 명령어
chown
"change owner" : 파일, 또는 폴더의 소유권을 변경하는 명령어
chmod
"change mode" : 파일이나 폴더의 권한(읽기, 쓰기, 실행)를 변경
순서대로 사용자, 사용자그룹, 다른모든 사용자에 대한 권한
8진수 777은 사용자, 사용자그룹, 다른모든 사용자들이 rwx권한을 가지게 되므로, rwxrwxrwx 권한 문자열을 의미
ENTRYPOINT
컨테이너의 어플 지정 (컨테이너 시작 시 실행 할 명령어)
COPY
로컬의 파일을 이미지에 추가한다.
WORKDIR
도커 이미지 내부에서 RUN, CMD, ENTRYPOINT의 명령을 실행할 디렉토리에 대한 설정 = 컨테이너 작업 디렉토리 지정
RUN, CMD, ENTRYPOINT 는 exec, shell 명령어 형식으로 사용해야 한다. exec 형식은 쉘을 통해 실행하지 않고 양식이 존재한다.
exec -> ["yum","-y","install","httpd"]
shell -> yum -y install httpd
MAINTAINER
이미지 작성자
ENV
컨테이너의 환경 변수 지정
USER
컨테이너의 사용자 지정
EXPOSE
이미지에서 노출시킬 포트에 대한 값 = 컨테이너의 포트 지정
도커 파일을 생성하면 서버에 도커파일을 추가해준다.
$mkdir dockerfile
$cd dockerfile
$echo test >> test.html
그리고 도커파일을 빌드한다.[이미지 생성]
위의 설명과 같이 도커는 레이어 저장 방식을 사용하기 때문에, 이전의 이미지 레이어를 사용해 이미지를 생성할때 문제가 될 수도 있다.
코드가 변경이 되었더라도 레이어의 캐쉬를 사용하게 되어 코드 변경이 안될수 있다.
이럴 때 사용하는 옵션이 —no-cache이다.
$docker build -t
컨테이너를 생성하고 실행한다.
$docker run
echo
echo는 도스, OS/2, 유닉스 및 유닉스 계열 운영 체제에서 문자열을 컴퓨터 터미널에 출력하는 명령어이다. 일반적으로 셸 스크립트와 배치 파일에서 화면이나 파일로 상황을 알리는 문자열을 출력할 때에 사용된다.
$ echo This is a test.
This is a test.
$ echo "This is a test." > ./test.txt
$ cat ./test.txt
This is a test.