CH6. 컨테이너와 호스트 간에 파일 복사하기 [그림으로 배우는 도커 & 쿠버네티스]
SECTION 2. 컨테이너와 호스트 간에 파일 복사하기
파일 복사
프로그램만으로 구성된 시스템은 그리 많지 않다.
5장에서도 나왔듯이 프로그램 외에도 프로그래밍 언어의 런타임이나 웹 서버, 데이터베이스 등이 함께 시스템을 구성한다.
이들은 시스템이 동작하는 데 필요하지만, 그 외에도 화면을 구성하는 이미지, 입력받은데이터 본체 등이 있을 수 있다. 이러한 파일은 서버에 저장되기도 하지만 때로는 SW의 개입 없이 서버와 로컬 컴퓨터 간에 파일을 주고방아야 할 때가 있다. 이럴 때를 위해 파일 복사하는 방법을 알아둬야 한다.
docker cp(container cp)
1
2
3
4
docker cp 호스트_경로 컨테이너_이름:컨테이너_경로
docker cp 컨테이너_이름:컨테이너_경로 호스트_경로
docker cp 원본_경로 복사할_경로
실습
1
2
3
4
5
6
<html>
<meta chrset="utf-8"/>
<body>
<div>안녕하세요!</div>
</body>
</html>
1
2
3
4
5
C:\Users\Kwon>docker run --name apa000ex19 -d -p 8089:80 httpd
4c037b31d34ea7c0b500b3f84b53b67e04eb1d466ebb0be26dfa6c655b0df72b
C:\Users\Kwon>docker cp C:\Users\Kwon\Desktop\repositories\SSAFY-Docker-Study\members\kwon\index.html apa000ex19:/usr/local/apache2/htdocs/
Successfully copied 2.05kB to apa000ex19:/usr/local/apache2/htdocs/
위 html 파일을 복사해서 localhost에 접속해보면 아래와 같이 화면이 나오는 것을 확인할 수 있다.
인코딩이 문제가 생겼는데… 일단 html에 대해 다루는 것이 목적이 아니므로 넘어가도록 하자.
SECTION 3. 볼륨 마운트
볼륨이란 스토리지의 한 영역을 분할한 것
볼륨 마운트란 이런 볼륨을 연결하여 운령체제 또는 소프트웨어의 관리하게 두는 일을 말한다.
컨테이너는 쓰고 버리는 것이라 이 내부에 데이터가 있다면, 언젠가는 삭제되기 마련이다. 데이터가 이렇게 사라지는 것을 막기 위해 마운트를 해서 외부에 데이터를 안전하게 보관한다. (Data persistency)
Data Persist
“Data Persist”는 데이터를 “영구적으로 저장하거나 유지”하는 것을 의미한다.
이는 주로 휘발성 데이터(예: 메모리에만 존재하는 데이터)와 반대되는 개념으로 영구적인 저장소(예:하드웨어)에 데이터를 저장하여 시스템이 재시작하거나 전원 종료 이후에도 데이터가 사라지지 않는 것을 뜻한다.
Storage Mount
도커에서 스토리지 마운트는 두 가지 종류가 있다.
Volmune Mount
볼륨 마운트는 도커 엔진이 관리하는 영력 내에 만들어진 볼륨을 컨테이너에 디스크 형태로 마운트한다.
이름만으로 관리가 가능하므로 다루기 쉽지만 볼륨에 비해 직접 조작하기 어려우므로 ‘임시 목적의 사용’이나 ‘자주 쓰지는 않지만 지우면 안 되는 파일’을 목적으로 많이 사용한다.
Bind Mount
바인드 마운트는 도커가 설치된 컴퓨터의 문서 폴더 등의 도커 엔진에서 관리하지 않는 영역의 기존 디렉터리를 컨테이너에 마운트 하는 방식이다. 파일 단위 마운트도 가능하다.
폴더 속에 파일을 직접 넣어두거나 열어 볼 수 있기 때문에 자주 사용하는 파일을 두는 데 사용한다.
항목 | 볼륨 마운트 | 바인트 마운트 |
---|---|---|
스토리지 영역 | 볼륨 | 디렉터리 또는 파일 |
물리적 위치 | 도커 엔진의 관리 영역 | 어디든지 가능 |
마운트 절차 | 볼륨을 생성한 후 마운트 | 기존 파일 또는 폴더를 마운트 |
내용 편집 | 도커 컨테이너를 통해 | 일반적인 파일과 같이 |
백업 | 절차가 복잡함 | 일반적인 파일과 같이 |
파일을 직접 편집해야 할 일이 많다면 바인드 마운트를, 그렇지 않다면 볼륨 마운트를 사용하면 된다.
스토리지 영역을 마운트하는 커맨드
run 커맨드의 옵션 형태로 지정한다.
마운트 이전에 volume을 먼저 만들어야 한다.
1
2
3
4
5
6
7
8
9
10
# 생성
docker volume create volume_name
# 삭제
docker volume rm volume_name
# 상세정보
docker volume inspect volume_name
# 목록
docker volume ls
# 마운트되지 않은 볼륨 모두 삭제
docker volume prune
이후 스토리지를 마운트한다
1
2
3
4
# 바인드 마운트
-v 스토리지_실제_경로:컨테이너_마운트_경로
# 볼륨 마운트
-v 볼륨_이름:컨테이너_마운트_경로
SECTION 4. 컨테이너로 이미지 만들기
이미지 만들기
commit 커맨드로 컨테이너를 이미지로 변환
1
docker commit container_name new_image_name
Dockerfile 스크립트로 이미지 만들기
Dockerfile 스크립트에는 토대가 될 이미지나 실행할 명령어 등을 기제한다.
이 파일을 호스트 컴퓨터의 이미지 재료가 들어있는 폴더에 넣는다. 재료 폴더에는 그 외 컨테이너에 넣을 파일을 함께둔다.
1
docker build -t new_image_name 재료_폴더_경로
1
2
3
4
FROM 이미지_이름
COPY 원본_경로 대상_경로
RUN 리눅스_명령어
...
인스트럭션 | 내용 |
---|---|
FROM | 토대가 되는 이미지를 지정 |
ADD | 이미지에 파일이나 폴더를 추가 |
COPY | 이미지에 파일이나 폴더를 복사 |
RUN | 이미지를 빌드할 때 실행할 명령어 지정 |
CMD | 컨테이너를 실행할 때 실행할 명령어 지정 |
ENTRYPOINT | 컨테이너를 실행할 때 실행할 명령어 강제 지정 |
ONBUILD | 이 이미지를 기반으로 다른 이미지를 빌드할 때 실행할 명령어를 지정 |
EXPOSE | 이미지가 통신에 사용할 포트를 명시적으로 지정 |
VOLUME | persistency data를 저장할 경로를 명시적으로 지정 |
ENV | 환경변수 정의 |
WORKDIR | RUN , CMD , ENTRYPOINT , ADD , COPY 에 정의된 명령어를 실행하는 작업 디렉터리를 지정 |
SHELL | 빌드 시 사용할 shell을 변경 |
LABEL | 이름이나 버전, 저작자 정보를 설정 |
USER | RUN , CMD , ENTRYPOINT 에 정의된 명령어를 실행하는 사용자 또는 그룹을 지정 |
ARG | docker build 커맨드를 사용할 때 입력받을 수 있는 인자를 선언 |
STOPSIGNAL | docker build 커맨드를 사용할 때 컨테이너 안에서 실행 중인 프로그램에 전달되는 시그널을 변경 |
HEALTHCHECK | 컨테이너 health check 방법을 커스터마이징 |
이미지 옮기기
컨테이너는 먼저 이미지로 변환하지 않으면 옮기거나 복사할 수 없다. 하지만 이미지 역시 이미지 상태 그대로는 옮기거나 복사할 수 없으므로 도커 레지스트리를 통하거나 save
커맨드를 사용해 tar 포맷으로 도커 엔진의 관리 영역 밖으로 내보내야 한다. 파일은 호스트 컴퓨터의 파일 시스템에 생성된다. 파일을 다시 도커 엔진에 가져 오려면 load
커맨드를 사용한다.
1
docker save -o file_name.tar image_name
SECTION 5. 컨테이너 개조
도커를 실제 운용하는 현장에서는 사내에서 개발한 시스템을 운영하는 경우가 많다. 사내 개발 시스템이 아니더라도 공식 배포되는 SW 역시 수정해야 할 필요가 종종 있다.
컨테이너를 개조하는 방법에는 두 가지 방법이 있으며, 대부분 이를 혼용하여 사용한다.
- 파일 복사와 마운트를 사용하는 방법
- 컨테이너에서 리눅스 명령어를 실행하는 방법
container에서 명령어 실행
container의 bash에 접근해 명령을 실행하기 위해서는 /bin/bash
인자를 사용한다.
1
2
docker exec (options) container_name /bin/bash
docker run (options) image_name /bin/bash
container가 이미 실행 중이라면 exec
를 사용해서 접근하고, 새로 시작하는 경우 run으로 실행한다.
하지만 run
에 인자를 붙여 사용하는 경우 컨테이너에 들어있는 SW(아파치 같은)를 실행하는 대신 bash가 실행된다. 그래서 container는 실행 중인데 SW는 실행 중이 아닌 상태가 된다. 즉, bash 조작이 끝나고 다시 docker start
로 재시작해야 한다.
1
2
3
4
5
6
7
docker exec -it apa000ex23 /bin/bash
# 아파치 실행 안됨
docker run --name apa000ex23 -it -p 8089:80 httpd /bin/bash
# 나가기
exit
이런 식으로 사용할 수 있다. 이렇게 bash에 접근하면 container에 직접 명령을 내릴 수 있게 된다.
도커 엔진을 통한 명령과 컨테이너 내부에서 실행하는 명령
| 도커 엔진 | 컨테이너 내부 | | :————————-: | :————: | | 도커 엔진의 시작 / 종료 | SW 설치 | | 컨테이너의 시작 / 종료 | SW 실행 / 종료 | | 컨테이너 안팎의 파일을 복사 | SW 설정 변경 | | | 파일 작업 | —
SECTION 6. 도커 허브 로그인
직접 만든 이미지도 도커 허브에 올릴 수 있으며, 비공개로 사용하는 도커 허브 같은 장소도 만들 수 있다.
도커 허브와 레지스트리
이미지를 배포하는 장소를 도커 레지스트리라고 한다. 일반에 공개되어 있든 말든 상관없이 이미지가 배포되는 곳은 모두 도커 레지스트리이다.
도커 허브는 도커 제작사에서 운영하는 공식 도커 레지스트리를 말한다. 우리가 run
커맨드를 사용할 때 내려받는 이미지는 이렇게 제공된다.
레지스트리와 리포지토리
레지스트리는 이미지를 배포하는 장소이고, 리포지토리는 레지스트리를 구성하는 단위이다.
즉 레지스트리는 회사나 부서 단위로 만들지만, 리포지토리는 SW를 단위로 한다.
태그와 이미지 업로드
태그는 다음과 같은 형태를 띈다
1
resistry_addr(docker_hub_id)/reporitory_name:ver
태그 부여는 다음과 같이 한다.
1
docker tag 원래_이미지_이름 레지스트리_주소/리포지토리_이름:버전
이미지를 업로드 할 때는 push
를 사용한다.
1
docker push 레지스트리_주소/리포지토리_이름:버전