도커 볼륨
 도커 컨테이너에서 데이터를 저장하는 방식을 제공하는 방법
 컨테이너 삭제시 컨테이너 내의 데이터도 같이 삭제되므로 영구적으로 저장할 데이터는 별도의 저장 공간에 데이터를 저장할 필요가 있음

도커 볼륨
 - Bind Mount
     도커 호스트의 파일 시스템의 디렉터리를 컨테이너의 저장 공간으로 제공하는 방법

 - Volume
     도커의 볼륨을 컨테이너에 연결하여 저장공간을 제공하는 방법

Bind Mount 연결
$ docker container run -d -t --volume DOCKER_HOST_PATH:/CONTAINER/PATH --name CONTAINER IMAGE

Volume 연결 (얘는 Volume 객체를 사용하는 것. 도커 호스트에 볼륨을 하나 만들구, 그걸 컨테이너에 연결.)
$ docker container run -d --volume VOLUME:/CONTAINER/PATH --name CONTAINER IMAGE

호스트에 있는 hello-world 파일을 docker container cp 명령어로 컨테이너에 넣고, docker container exec 명령어로 직접 /bin/bash로 컨테이너로 들어가지 않고도 명령어 결과를 확인 가능!!!!!!!!!!!!!!!!!!!!!!!!!


[실습 : Bind Mount]

 

도커 컨테이너를 실행하는 시점에서 연결할 수 있어. 컨테이너 실행 된 이후에는 연결 못해!

도커 컨테이너에 제공할 디렉터리 생성 (기존에 있는거 사용했다가 잘못해서 보안 이슈 생길 수도 있으니)
$ mkdir HOST_DIR
$ docker container run -d -t --volume DOCKER_HOST_PATH:/CONTAINER/PATH --name CONTAINER IMAGE

(컨테이너는 폴더 PATH가 없어도 만들어주지만, 호스트는 안그러나바?)

ㄴ 확인해보니까, docker의 host에 폴더가 없어도 에러는 안뜨는데, docker host에 폴더가 새로 생기진 않아.

 

컨테이너의 /var/www/html과 docker host의 /home/devops/website를 연결해서, curl http://localhost:8080을 하면 docker host의 website/index.html의 파일을 불러오게 된다.

잘 보면, docker host는 똑같은 포트로 열면 안되는데, 컨테이너는 동일한 포트로 여러 개 열어도 된다.

(linux namespace 때문인듯?) -> 이거 놓쳤었음.

 

docker host의 디렉토리와 컨테이너의 디렉토리가 bind 되어있다고 나온다. RW : Read Write. 마운트를 RO (Read Only로 할 수도 있다.)
이거는 bind 말구 Volume object로 한건데... 잘 보면 /var/lib/docker/volumes/ 밑에 저장이 되네.
잘 보면, docker container ls를 쳤을 때 나오는 컨테이너 ID는 /var/lib/docker/containers 들어갔을 때 나오는 container 명을 일부 자른거였다.

 

나는 Volume 객체에 저장될 때, 파일이 분산되어서 저장된다든가 hash로 저장된다든가 이럴 줄 알았는데, 그냥 그대로 저장이 된다. 그냥 Volume 객체가 디렉토리임.

처음에는 Bind Mount를 사용해서 연결했는데, 이제 Docker에서는 Volume 오브젝트를 사용하는 방식을 권장한대.

Docker에서 매니지 하는거니까.

이제 뭐가 가능해지냐하면, 공유 스토리지에 연결된 다수의 정적 웹 호스팅이 가능해져.

질문)

볼륨 경로를 다르게 하여 한 컨테이너 안에 여러 개 볼륨을 연결해서 사용할 수 있나요? -> 그렇다.

+ 생성하는 단계에서 Volume을 잡아줘야 한다.

<=> 중간에 Volume을 추가하거나 해제하는건 불가능하다. 생성 시점에만 가능하다.

잘못 연결했으면 컨테이너 삭제하고 다시 생성해야해.


$ docker container exec -it CONTAINER /bin/bash
[root@CONTAINER] # touch docker_rootfile.txt

 (Docker Host에서)
$ ls -l HOST_DIR
$ cat HOST_DIR/docker_rootfile.txt

------
[실습 : Volume 사용]

$ docker volume create vol1

$ docker container run -d -p 8082:80 --volume vol1:/var/www/html --name web3 ubuntu/apache2:latest
$ docker container run -d -p 8083:80 --volume vol1:/var/www/html --name web4 ubuntu/apache2:latest

$ curl http://localhost:8082
$ curl http://localhost:8083

------

컨테이너 이미지 생성 방법
 1. 도커 명령어
 2. Dockerfile

실행중인 컨테이너를 기반으로 도커 컨테이너 이미지 생성
$ docker container commit CONTAINER NEW_IMAGE_REPO:TAG

작동중인 컨테이너를 이미지로 만들기
centos7_1 컨테이너 꺼임
요거는 centos:7 꺼임

 

베이스 이미지 레이어 위에 다른 레이어가 있는걸 확인할 수 있음. (Union File System)

+ 각각의 레이어들은, 이미지가 만들어지는 시점으로 Read Only로 바뀜.

 


생성된 이미지를 이미지 목록에서 확인
$ docker image ls

컨테이너를 별도로 백업하고 싶을 때는? (로컬에서 백업할 때는?)
도커 컨테이너 데이터를 추출하여 tar 아카이브로 저장
$ docker container export -o TAR_FILE CONTAINER


추출한 데이터가 있는 tar 파일로 도커 컨테이너 이미지 생성
$ docker image import TAR_FILE CONTAINER

import를 하면, 모든 레이어들을 뭉쳐서 하나의 레이어로 만듦.
이렇게 레이어 하나가 댐


$ docker container run -d -t --name CONTAINER IMAGE [PROCESS]


도커 컨테이너 이미지 레이어 단위로 tar 파일로 저장 (이건 이미지 백업의 개념)
$ docker image save -o TAR_FILE IMAGE

-> /var/lib/docker/overlay2 들어가면 

이런식으로 나옴.


도커 컨테이너 이미지 레이어 단위로 저장된 tar 파일에서 도커 컨테이너 이미지 로드
$ docker image load -i TAR_FILE -> 이거 하면 레이어가 있는 상태로 되는듯??

($ docker image import TAR_FILE CONTAINER 이거랑 차이가 뭐임?)

 

차이는..

export는 import로, save는 load로 불러옴..... 이미지 레이어를 낱개로 저장하느냐 통채로 저장하느냐 차이임.

저 두 개가 각 쌍임.

 

export&import는 데이터를 백업할 때만 사용되지, 컨테이너를 백업할 때 사용되지는 않는다.

데이터만 가져왔기 때문에 시작프로세스 정보/ 컨테이너 이미지의 속성들이 일부 손실되는 경우가 있어서, 처음 이미지를 만들 때 사용.

save&load는 컨테이너를 tar 파일로 백업한 후에, 다른 시스템에서 그대로 불러와서 쓸 때 사용한다.

-----

2. Dockerfile을 사용한 이미지 작성

명령어를 가지고 실행되는 컨테이너를 이미지로 저장할 수 있었지.

근데 보통은 사용하는 컨테이너 이미지를 docker container commit으로 저장하기보다는, Dockerfile로 만들게 돼. 왜? 불필요한 파일이 더 생기게 돼. 그래서 Dockerfile로 만드는게 더 일반적이야.

왜 불필요한 파일들이 더 생겨?

커맨드를 치면 캐시파일도 생기고(.bash_history), 오타로 잘못된 설정이 입력될 수도 있으니까.

 

 Dockerfile
  - 컨테이너 이미지를 정의하고 컨테이너가 생성될 때 실행될 작업 등을 정의하는 구성 파일

 Dockerfile에 포함되는 내용
  - 베이스 이미지
  - 컨테이너에서 실행될 작업(명령어)
  - 환경변수
  - 컨테이너 안에서 동작시킬 데몬 (컨테이너는 안에 프로세스가 계속 실행이 되어야만 컨테이너가 켜져있게됨)

그래서 서비스를 제공하려면 항상 떠있는 프로세스가 있어야 함.

$ docker image build -t IMG_REPO:TAG BUILD_DIR

항상 docker image build --help 이렇게 직접 찾아보는 습관을 들여야한다.
Dockerfile로 이미지 만들었어. 내용 한줄임. FROM centos:7 ㅋㅋ
이미지가 만들어졌다.

근데 Image ID가 왜 같을까?

왜냐하면 Dockerfile에서 뭔가 이미지 수정을 하지 않았잖아. 그래서 사실 이 케이스는 build는 아니고

기존에 있던 이미지를 tag 하는거야. 그래서 이미지 ID가 같은거임 ㅋㅋ

Dockerfile로 build한 image로 container를 실행시켰다. 얘가 ㄹㅇ centos인지 확인하고 싶어서 yum repolist로 확인해보았다.
centos7이 맞다. (이렇게도 확인을 할 수 있구만..)

Fedora, CentOS 가 Redhat 계열이라 할 수 있으며

Ubuntu 가 Debian 계열이라고 할 수 있다.

출처: https://luyin.tistory.com/321 [Luyin]

 

참고)

Dockerfile 만들 때는, 별도의 디렉토리를 만들고 그 안에 넣는게 좋다. (이미지 작성할 때, 다른 파일들도 있으니까... 하여간..........)
 
FROM 이미지
FROM 이미지:태그
FROM 이미지@다이제스트

digest


RUN 명령어 (build시에 사용 할 명령어. 이미지를 build 하는 과정에서 뭘 설치한다든지 어떤 명령어를 수행한다든지 할 때.)

RUN yum install vim -y (프롬프트를 요구하는 명령어의 경우 -y 같은거 입력 안해주면 진행이 안돼)

RUN mkdir /home/devops/abc/hello

CMD 명령어 (이미지가 빌드되고 나서, 컨테이너가 실행된 후에 실행 될 명령어들)

ENTRYPOINT 명령어 (컨테이너가 실행되는 시점에, 맨 처음 기본적으로 한번 실행되어야 할 명령들. 데몬들. )

 

(CMD & ENTRYPOINT가 세세한 차이가 있기는 한데, 지금은 그냥 비슷하다고 알고 넘어가래....)

근데 이제 제대루 알아야 할 것 같은데?

->


ONBUILD 명령어
 * 이미지가 빌드된 후 다른 이미지에서 이 이미지를 사용하여 이미지를 빌드할 때 실행되는 작업 정의

 

Dockerfile A에 있던 ONBUILD echo "Sample App-dev-environment"는 이 이미지가 빌드되어서 실행되더라도 출력되지 않는다. 언제 출력되냐하면, 이미지 A를 활용해서 빌드되는 이미지 B가 실행되는 시점에 출력된다. (왜 굳이 이런게 필요할까?)

 

EXPOSE : 컨테이너에서 어떤 포트를 사용할 것인지에 대한 번호. 80번. 이런거 ㅋㅋ


ADD 호스트_파일_경로  도커_이미지_내의_파일_경로

 

예를 들어, ONBUILD ADD website.tar /var/www/html 이면

이 이미지를 바탕으로한 어떤 이미지가 실행될 때, website.tar를 풀어서 /var/www/html에 풀어주겠다는 뜻이다.


COPY 호스트_파일_경로  도커_이미지_내의_파일_경로

 

COPY는 단순히 로컬 호스트에서 파일 복사해주는 역할

ADD는 로컬 호스트에서 파일 복사 + 원격지에 있는 파일도 복사 (URL경로) + 아카이브 파일 (*.tar)파일도 가능 

그래서 ADD http://test.com/test.html; /var/www/html 이렇게 해도 됨.

 

 

 

도커 파일 이름 지정
ONBUILD 시에 website.tar가 필요해서, 해당 디렉토리에 가져왔어.
여기서 Executing 1 build trigger 라고 하잖아. 이게 website.tar가 압축 풀렸단 소리야.
원래 index.html 말고 아무 것도 없어야 하는데, 다른 파일들이 생겼다!
잘 보면 port가 80번 뚫렸지? (이거 확인도 docker container ls로 한다)

ENV. 컨테이너에서 사용할 환경 변수.

WORKDIR. 작업 디렉토리 경로 변경.

USER. (사용자 지정)

LABEL. 이미지에 대한 메타 데이터를 기록.

ARG. 컨테이너 이미지 빌드 시에 사용.

VOLUME. 임의의 Volume 객체 생성해서, /xxx/fddd/ 이거랑 연결해주는거임.

ㄴ 이거 해버리면 Volume 이름이 이상한 hash값으로 저장이 돼.

그래서 꿀팁!)

Dockerfile에다가 하지말고, 그냥 RUN 커맨드로 컨테이너 시작할 시점에 그냥 Volume을 bind로 마운트 하는게 나아. 

그렇게 하면 이름도 정할 수 있잖아.

 

따라해보자. 

여기서 LABEL은 그냥 메타 데이터래. 나중에 식별하기 위한건듯.

 

docker image build -t centos-httpd:1.0 .

 

궁금)

왜 EXPOSE 80도 해주고 -p 8080:80도 해줘야돼?

-p 8080:80은 알겠는데, EXPOSE 80은 왜 써줘야됨?

-------

도커 허브 이용

도커 허브 로그인
$ docker login

 

docker image tag centos-http devops2341/centos-httpd (만약에 docker hub에 업로드할 때, 이미지 이름 바꾸구 싶으면. 사실 근데 이거 이름 바꾸는거 아니구 걍 tag 건거임 ㅋㅋ)

도커 이미지 다운로드(pull)
$ docker image pull IMG_REPO:TAG

도커 이미지 업로드(push)
$ docker image push IMG_REPO:TAG


'System Engineering > Kubernetes' 카테고리의 다른 글

kubernetes 1/17 (docker 6/6과 같은 날 강의)  (0) 2022.03.23
docker 6/6 도커 사설 레지스트리  (0) 2022.03.23
docker 4/5  (0) 2022.03.21
Docker (Build, Ship, Run)?  (0) 2022.03.18
docker 3/5  (0) 2022.03.17
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기