bxm's IT Story
Docker (#5. 도커 이미지, 도커 허브, 도커 파일) 본문
## 도커 이미지 ##
## 먼저 숙지하고 가야할 내용은 도커 이미지는 실체가 없고 레이어 정보만 있다!! 그래서 tar 파일을 추출하는 것이다.
// 도커는 기본적으로 도커 허브라는 중앙 이미지 저장소에서 이미지를 내려받는다. 도커 계정을 가지고 있다면
누구든지 이미지를 올리고 내려받을 수 있기 때문에, 다른 사람들에게 이미지를 쉽게 공유할 수 있다.
단, 도커 허브는 누구나 이미지를 올릴 수 있기 때문에 공식(Official) 라벨이 없는 이미지는 사용법이 제각각이다.
도커 허브에 어떤 이미지가 있는지 확인하기 위해 도커 허브 사이트를 직접 접속해서 찾아볼 수도 있지만,
도커 엔진에서 'docker search' 명령어를 사용할 수도 있다.
Docker1]
docker search ubuntu
docker search centos
## 도커 이미지 생성 ##
(이전에 했기 때문에 간단히 넘어갈 것임을 미리 말함.)
// 특정 개발 환경을 직접 구축한 뒤에 사용자만의 이미지를 직접 생성해야할 경우, 컨테이너 안에서 작업한 내용을
이미지로 만들어보자.
docker run -i -t --name commit_test ubuntu:14.04
Docker1 - commit_test]
echo test_frist! >> first
exit
// 이제 컨테이너를 이미지로 만든다. 문법은 다음과 같다. 다음 명령은 commit_test라는 컨테이너를 commit_test:first
라는 이름의 이미지로 생성한다.
docker commit [OPTION] CONTAINER [REPOSITORY[:TAG]]
Docker1]
docker commit -a "bxmsta0820" -m "my first commit" commit_test commit_test:first
// -a : authen(저작자), TAG는 말 그대로 꼬리표이다. : 하고 붙이면 된다.
// 이미지는 실체가 없기 때문에 복사를 할 수가 없음!! 사용하고 싶다면 추출을 해야한다!! 그래서 백업용도로 사용함.
docker images
// 이번엔 commit_test:first 이미지로 컨테이너를 생성한 뒤 second 라는 파일을 추가해서 commit_test:second라는
이미지를 새롭게 생성해 보자.
Docker1]
docker run -it --name commit_test2 commit_test:first
Docker1 - commit_test2]
echo test_second! >> second
exit
Docker1]
docker commit -a "bxmsta0820" -m "my second commit" commit_test2 commit_test:second
// 실제로 ID가 없어도 만들 수 있다. 그래서 -a옵션을 안써줘도 된다. 왜냐면 이게 모두가 사용할 수 있는 곳에 올리는 것이 아니라 내 PC에 올리는 것이기에!! 하지만 누가 만들었는지는 알 수 있게 써주면 좋다.
그리고 -m 옵션도 실제로는 안써줘도 되는데, 출처가 불문명하므로 써주는 것이 좋다.
docker images
## 레이어 확인해보기
// 주의 깊게 살펴볼 항목은 아랫부분에 있는 Layer항목이다. 요컨대, 전체 이미지의 실제 크기는 197MB+first 파일의 크기 + second 파일의 크기이다.
docker inspect ubuntu:14.04
docker inspect commit_test:first
docker inspect commit_test:second
## 결론적으로 한 이미지에 압축해서 때려 넣는 것이 아니라, 이렇게 1개씩 추가 되는 것이라서 컨테이너 동작이 빠름
docker history commit_test:second
## 참조하는 이미지 삭제는 가능한가?
docker rmi commit_test:first
// docker rm -f [컨테이너 이름]과 같이 강제로 삭제할 수도 있지만, 이는 이미지 이름만 삭제하기 때문에 의미가 없다.
삭제는 다음과 같은 절차를 거친다.
docker stop commit_test2 && docker rm commit_test
docker rmi -f commit_test:first
docker rmi -f commit_test:second
docker images
// 댕글링 이미지가 있는지, 그리고 있다면 그게 무엇인지 보여준다.
docker images -f dangling=true

## 도커 이미지 추출 ##
도커 이미지를 별도로 저장하거나 옮기는 등 필요에 따라 이미지를 단일 바이너리 파일로 저장해야할 때가 있다.
'docker save' 명령어를 사용하면 컨테이너의 커맨드, 이미지 이름과 태그 등 이미지의 모든 메타데이터를 포함해 하나의
파일로 추출할 수 있다. -o 다음에는 추출될 파일명을 입력한다.
Docker1]
cd /temp
docker save -o ubuntu_14.04.tar ubuntu:14.04
-o | --output string Write to a file, instead of STDOUT |
ls -l
// 추출된 이미지는 load 명령어로 모든 매타데이터와 함게 도커에 이미지로 로드할 수 있다.
## 모든 컨테이너, 이미지 삭제
docker container prune
docker images
docker rmi moon682/stress
docker rmi ubuntu_owncloud:20.04
docker rmi nginx:latest
docker rmi mysql:5.7
docker rmi ubuntu:14.04
docker rmi -f 0087287e8469 // 댕글링 이미지라서 16진수로 삭제하였음.
docker ps -a
docker images
## 이미지 로드
docker load -i ubuntu_14.04.tar
-i | --input string Read from tar archive file. |
## 로드한 이미지로 컨테이너 생성
docker run -itd --name export_test ubuntu:14.04
## 컨테이너로 tar 파일을 추출할 수도 있다.
// export 명령어는 컨테이너의 파일시스템을 tar 파일로 추출하지만, Docker 이미지의 Layer에 대한 설정 정보를
저장하지 않는다. import 명령어는 추출된 파일을 여러 이미지로 다시 저장한다.
docker export -o export_test.tar export_test
// 결론적으로 아래와 같이 사용하면 된다!!
이미지를 tar 파일로 추출 | docker save |
컨테이너를 tar 파일로 추출 | docker export |
tar 파일을 이미지로 만들기 | docker import |
## 그렇다면 추출한 tar 파일을 이미지로 다시 원상복구 시켜보자!!!!
docker images
docker import export_test.tar export_test:0.0
docker images
## 단점!!
// 참고로 컨테이너를 export한 tar 파일에는 Layer 정보가 없으므로, 역으로 import한 이미지에도 Layer 정보가
없다.
이미지를 tar로 만들 때는 문제가 없지만, 그 tar 파일을 가지고 컨테이너를 생성 뒤에 다시 tar 파일로 만들어
(export), 그 tar 파일로 이미지를 만들면(import) Layer 정보가 없기때문에(이미지 파일이 깨졌다는 것임)
문제가 생긴다!!!! ==> 그렇다면 왜 컨테이너로 tar 파일을 만들고 그 tar 파일로 이미지 파일을 만드나요??
"편하니까!!", 그리고 "그 이미지 파일을 사용하는 방법이 있으니까!!"
따라서 import한 이미지로 컨테이너를 작성할 때는 앞으로 배울 Docker 파일을 사용해야 컨테이너가 정상동작한다.


## 과제. ##
// 과연 tar 파일로 이미지 생성 뒤에, 그 이미지로 만들어진 컨테이너에서 tar파일로 추출 및 이미지로 변환 시키면,
그 이미지 파일로 컨테이너가 생성되는지 확인해보자.
[로드] - [이미지 파일로 컨테이너 생성] - [그것을 tar로 추출] - [그것을 이미지로 바꾸기] - [이미지로 컨테이너 만들기]
owncloud 컨테이너를 생성하여 클라이언트에서 접속하는 등 실제 동작여부를 테스트한 후 이 컨테이너를 직접 tar 파일로 추출한 후, 다시 이미지로 import 해 보자. import 한 owncloud 이미지로 컨테이너를 생성하면 다음과 같은 오류가
발생할 것이다.
## 이미지 로드
docker load -i ubuntu_owncloud.tar
docker images
## owncloud 컨테이너 생성
docker run -it --name owncloud -p 80:80 ubuntu_owncloud:20.04
docker ps -a
## 컨테이너를 tar 파일로 추출
docker export -o owncloud2.tar owncloud
## tar 파일을 이미지로 변환
docker images
docker import owncloud2.tar ubuntu_owncloud2:20.04
docker images
## 이미지 파일로 owncloud2 컨테이너 만들어보기.
// docker: Error response from daemon: No command specified. See 'docker run --help' 가 떠야한다!!
docker run -it --name owncloud2 -p 80:80 ubuntu_owncloud2:20.04
여기서 살펴볼 점은 바로 도커 export 로 추출하여 로드한 docker image의 역우 docker container를 단순히 아카이빙
한 이미지 라는 것이다. 즉 압축한 파일 자체를 이미지로 로드해 둔 것이라고 볼 수 있다. 이를 정상적으로 기동하기
위해서는 import 이미지를 기반으로 새롭게 Dockerfile을 작성하거나, import 시점에 명령어를 주입시켜 주어야 한다.



## 도커 이미지 배포 ##
1) 첫번째 방법은 도커에서 공식으로 제공하는 도커 허브 이미지 저장소를 사용하는 것이다. 'docker push', 'dockr pull' 만 하면 되므로 매우 간단하다. 단, 결재를 하지 않으면 비공개(Private) 저장소의 수에 제한이 있다.
2) 두 번째 방법은 도커 사설 레지스트리(Docker Private Registry)를 사용하는 것으로서 사용자가 직접 이미지 저장소를 만드는 것이다. 그러나 이미지 저장소 및 서버, 저장공간 등을 사용자가 직접 관리해야 하므로 비용이 많이 들뿐더러 사용법이 까다롭다.
1) 도커 허브 저장소 (이미지 저장소_Repository_생성)
도커 허브 사이트(https://hub.docker.com) 에서도 'docker search' 명령어를 입력했을 때와 같이 이미지를 검색할 수
있으며, 이미지 저장소를 클릭하면 해당 이미지에 대한 자세한 설명을 볼 수 있다.
'docker inspect' 명령어를 사용하면 해당 이미지가 어느 CPU 아키텍쳐에서 사용되도록 설정 되었는지 알 수 있다.
'docker pull'과 같은 명령어를 사용하면 자동으로 호스트의 CPU 아키텍처에 해당하는 이미지를 내려받기 때문에
이를 신경쓸 필요가 없다.
docker inspect ubuntu | grep Architecture
// 도커 허브에 이미지를 올리기 위해 내 저장소를 생성해 보자. 저장소를 생성하려면 로그인이 필요하므로 'Sign up'을
클릭해 가입한다.
2) 저장소에 이미지 올리기
// 그렇다면 이미지를 한번 올려보자!!
Docker1]
docker run -i -t --name commit_container1 ubuntu:14.04
Docker1 - commit_container1]
echo my first push >> test
exit
Docker1]
docker commit commit_container1 my-image-name:0.0
// 현재 만들어진 이미지 "my-image-name:0.0" 라는 이름으로 저장소에 올릴 수 없다. 즉, 특정 이름의 저장소에
이미지를 올리려면 저장소 이름(사용자의 이름)을 이미지 앞에 접두어로 추가해야 한다.
docker tag my-image-name:0.0 cnb0820/my-image-name:0.0
docker login
docker push cnb0820/my-image-name:0.0
## 이미지를 전부 지우고 도커에서 이미지 받아와보기!!
// 반대로 도커 허브에서 이미지를 다운받으려면 다음과 같이 한다. 다운받을 시는 별도의 로그인 절차가 필요없다.
이미지를 다운받기에 앞서 태깅한 이미지를 제거한 뒤에 다시 받아보기.
docker images
docker rmi cnb0820/my-image-name:0.0
docker pull cnb0820/my-image-name:0.0
docker images
3) 조직, 팀 생성 - 유료됐다 ㅋㅋㅋ... 패스
hub.docker.com 에서 [Create Organization]을 눌러 조직을 생성한다. 조직의 이름은 bxmstasorg이고, 이름은
bxmstasorg/my-image-name:0.0 과 같이 설정된다.
[Repositories] 탭을 클릭하면 조직에 소속되는 저장소를 생성할 수 있다. 저장소를 생성한 뒤 Team의 [Permissions]
탭에 들어가 저장소에 대한 멤버의 권한을 다르게 부여할 수 있다.
나중에 회사를 운영하는 사장이 된다면, 회사 사람들이 마음 놓고 데이터를 다운받을 수 있도록 이렇게 설정하면 된다.
4) 저장소 웹훅(Webhook) 추가
저장소에 이미지가 push 되었을 때 특정 URL로 http 요청을 전송하도록 설정할 수 있다. 이 기능을 웹 훅이라 한다.
이 기능은 저장소에 추가된 새로운 이미지를 각 서버에 배포하는 애플리케이션을 작성할 때 유용하게 활용할 수 있다.
저장소 페이지의 [Webhooks] 탭에서 새로운 웹욱을 추가할 수 있다.
자기가 운영하는 홈페이지가 있다는 전제하에 사용이 가능하다!! 그 url로 이미지를 전송할 수 있음!!

'가상화 > Docker' 카테고리의 다른 글
Docker (#7. 기타 도커 명령어, Dockerfile로 빌드 할 때 주의할 점, 도커 데몬) (0) | 2021.09.29 |
---|---|
Docker (#6. 도커 사설 레지스트리, 도커 파일) (0) | 2021.09.28 |
Docker (#4. 컨테이너 로깅, 컨테이너 자원 할당) (0) | 2021.09.27 |
Docker (#3. 도커 네트워크-Bridge, Host, Non, Container, Bridge net-alias, MacVLAN) (0) | 2021.09.24 |
Docker (#2-wordpress, Docker Volume) (0) | 2021.09.23 |