[Docker] 2장 : 도커엔진_이미지

post-thumbnail

이전글에서 살펴봤듯이, 모든 컨테이너는 이미지를 기반으로 생성되므로 이미지 관리는 중요하다!

apt-get install을 실행하면 apt 레포에서 패키지를 내려받듯이, 도커는 도커 허브 라는 중앙 이미지 저장소에서 이미지를 내려받는다.

docker create, docker run, docker pull 등으로 이미지를 생성할 때 도커는 도커 허브에서 이미지를 검색한 뒤 내려받는다. 도커에서 공식적으로 제공하는 이미지도 있고, 사람들이 올려놓은 이미지도 있기 때문에 대부분의 이미지는 도커허브에 있어서 손쉽게 사용할 수 있다.
❗ 다만, 누구나 이미지를 도커 허브에 올릴 수 있기 때문에 공식적이지 않은 이미지는 잘 동작하지 않을 수도 있다.

이미지 검색

$ docker search 이미지 키워드

예를 들어, docker search ubuntu를 입력하면 도커 허브에서 ubuntu와 관련된 이미지를 검색해서 알려준다.


1. 이미지 생성

(1) 컨테이너로 이미지 생성

이미지로 만들 컨테이너를 생성하고, 컨테이너 내부에 변경사항을 만들고, 호스트로 빠져나와 commit명령어를 통해 컨테이너를 이미지로 만드는 것이다.

예제로 ubuntu 이미지로부터 commit_test라는 컨테이너를 만들고, 내부에서 first파일을 만들어 변경사항을 만들어보자.

호스트로 빠져나와서 커밋 명령어로 이미지를 생성한다.

// commit 명령어 형식
docker commit [옵션] 컨테이너 이름 [repository:tag]

## -a 옵션 : author. 이미지의 작성자를 나타낸다.
## -m 옵션 : 커밋 메세지. 이미지의 부가설명을 나타낸다.

// 이미지 목록 확인
docker images

아래 사진과 같이 commit_test 이미지가 생성된 것을 볼 수 있다. 해당 이미지는 최상위 디렉토리에 first 파일이 있는 이미지다.


(2) 이미지로 이미지 생성

위에서 만든 commit_test:first 이미지로부터 새로운 이미지를 생성해보자. commit_test:first 이미지로부터 새로운 컨테이너를 생성한 뒤, second 파일을 추가하여 commit_test:second 이미지를 생성해보자.




2. 이미지 구조

아래 명령어 출력결과에서 layers를 확인해보면, 이미지의 레이어 구조를 볼 수 있다.

// 이미지 레이어 확인
docker inspect 이미지 이름

예시로 위에서 만들었던 commit_test:first 이미지와 commit_test:second의 이미지 구조를 보면 아래와 같다. 비교해보면 태그명이 second인 이미지의 레이어는 first인 이미지의 레이어보다 한 층 더 있는것을 확인할 수 있다.

이는, 이미지를 커밋할 때 컨테이너에서 변경된 사항만 새로운 레이어로 저장하고, 컨테이너를 만들때 사용했던 이미지의 원래 레이어를 포함해서 새로운 이미지를 생성하기 때문이다.

따라서 second이미지를 생성할 때 추가했던 second파일이 레이어로 추가된 것이다.

commit_test:first 이미지 레이어

commit_test:second 이미지 레이어

이미지의 레이어 구조를 더 쉽게 확인하고자 하면 아래 명령어를 참고하자.

// 특정 이미지의 레이어 구조 확인
docker history 이미지 이름:tag




3. 이미지 삭제

이미지를 사용중인 컨테이너가 존재하면 이미지를 삭제할때 오류가 뜬다. 물론 -f 옵션을 써서 강제로 삭제하면 되지 않을까? 생각도 들지만, 이렇게 하면 실제로 이미지 레이어 파일이 삭제되는것이 아니라 이미지 이름만 삭제되며, 이러한 이미지를 dangling 이미지라고 한다. 따라서 아래와 같이 삭제하자!

// 이미지 삭제
docker stop 컨테이너명
docker rm 컨테이너명
docker rmi 이미지명:태그명

위에서 우리가 실습한 이미지 파들을 고려했을 때, commit_test:first 이미지만 삭제하면 어떻게 될까?

실제 이미지의 레이어 파일이 삭제되지는 않는다. 왜?? 해당 이미지를 포함하는 commit_test:second 이미지가 있기 때문이다. 따라서 레이어에 부여된 이름만 삭제 된다.

위에 보이는 Untagged 표시가 레이어에서 이름만 삭제됐다는 의미이다.

commit_test:second 이미지를 사용하는 컨테이너는 없기 때문에 바로 삭제된다.




4. 이미지 추출

이미지를 옮기거나 다른 곳에 저장하려면 단일 바이너리 파일로 추출해야될 필요가 있다.

(1) save, load

// 이미지 파일 추출
docker save -o [추출할 파일명] [추출할 이미지명]

물론 추출한 이미지는 load 명령어를 통해 도커엔진에 이전과 동일한 이미지를 생성할 수 있다.

// 이미지 로드
docker load -i [로드할 파일명] [저장할 이미지명]

(2) export, import

save, load와 비슷하게 export, import 명령어가 있다.

save, loadexport, import
컨테이너 및 이미지에 대한 설정 포함O컨테이너 및 이미지에 대한 설정 포함X

이미지를 단일 파일로 저장하는건 효율적이지 X
이미지를 추출하게 되면 레이어 구조가 아니고 단일파일이기 때문에 이미지 용량을 각각 차지하게 된다.




5. 이미지 배포

생성한 이미지를 다른 도커 엔진에 배포할 수 있어야겠지?? 하지만 save나 export를 사용하면 도커의 이미지 구조인 레이어형태도 아니고, 용량도 너무 크면 비효율적일 것이다.

따라서 이미지 배포의 방식이 여러가지가 있다.

(1) 도커 허브 저장소 이용 (개인)

참고로 도커 허브는 비공개 저장소를 1개 까지만 무료로 이용할 수 있고, 그 이상은 유료이다. 공개는 무료이고!
깃허브랑 비슷한 방식으로 이용할 수 있다. 도커 허브에 레포를 파고, 거기에 이미지를 올리는 방식이다.

① 도커허브에 repo 만들기

lewdus7749/my_first_image 라는 저장소에 이미지를 만들었다.

② 저장소에 이미지 올리기

예제로, ubuntu 이미지로 컨테이너를 하나 만들고 거기에 test 파일 하나를 만들어서 이미지를 생성해보자. 그리고 그 이미지를 도커허브 저장소에 올려보자!

이때 주의해야 할 점은, 컨테이너를 커밋할 때 이미지 이름 앞에 도커허브 사용자 이름을 붙여주어야 한다. 왜냐하면 이미지 이름의 접두어를 통해 저장소 이름을 구분하기 때문이다. 그래서 아무것도 적지 않으면 그냥 도커허브에서 가져오는걸로 인식한다.

커밋으로 이미지를 만들었으면, 도커 허브 서버에 로그인 하자!

// 로그인
docker login
// 로그아웃
docker logout

로그인을 하게 되면 도커엔진에 정보가 남게 되는데, 이를 없애고 싶으면 로그아웃하면 된다.

// 저장소에 이미지 올리기
docker push 저장소이름:태그명

출력결과를 보면, 하나의 레이어만 pushed 된것을 확인할 수 있다. 우리가 만든 my_first_image는 ubuntu 이미지로 만든 컨테이너로 만든것이다. 따라서 ubuntu 이미지에서 생성된 레이어는 도커허브 중앙 이미지 저장소에 이미 존재하기 때문에 전송되지 않은것이고, 변경한 test 파일 레이어만 전송된것이다.

저장소에 잘 올려진것을 확인할 수 있다!

③ 저장소에서 이미지 내려받름

이미지를 내려받을때는 별도의 로그인 과정이 필요없다.

// 저장소에서 이미지 내려받기
docker pull 저장소이름:태그명


(2) 도커 허브 저장소 이용 (조직)

도커로 협업하는 방식도 실습을 진행해보자!

① 도커허브에 organization 생성

create organization버튼을 통해 jyorg를 만들고, add teams로 developers 팀을 만들었다! 연습해보기 위해 jyorg/test_img 레포를 파서, permissions에서 developers팀에게 읽고 쓰기 권한을 주었다.

② 저장소에 이미지 올리기

개인이 도커 허브를 이용하는 예시에서 사용했던 lewndus7749/my_first_image:0.0을 한번 더 사용하고자 한다.

현재 저장소의 이름이 jyorg/test_img 이므로, 이미지 이름을 바꿔주어야 하기 때문에 tag 명령어를 사용한다. 이름을 바꿔주는 개념보다는 같은 이미지를 가리키는 새로운 이름을 추가해주는 것이다.

// 이미지 이름 추가
docker tag [기존 이미지 이름] [추가할 이름]

조직 도커 허브 저장소에 잘 올라간것을 확인할 수 있다.


저장소 웹훅(webhook)

웹훅은 저장소에 이미지가 push 됐을때 특정 url로 http요청을 전송하는 기능이다. 이 기능은 저장소에 추가된 새로운 이미지를 서버에 배포하는 애플리케이션을 만들때 유용하다.



(3) 도커 사설 레지스트리

도커 허브에서는 비공개 저장소를 무료로 하나만 이용할 수 있으므로, 사용자가 직접 이미지 저장소를 만들어서 사용할 수도 있다. 물론, 사용자가 직접 이미지 저장소나 서버, 저장공간 등을 관리해야 되기 때문에 사용법이 조금 더 어렵다.

사설 레지스트리는 컨테이너로 구현된다. 따라서 이에 대응하는 이미지가 있겠지?? 바로 그 이미지는 도커에서 공식적으로 registry 라는 이름으로 제공한다.

① 컨테이너 생성

레지스트리 컨테이너는 기본적으로 5000번 포트를 사용한다. 해당 포트로 레지스트리의 RESTful API를 사용할 수 있다.

레지스트리 컨테이너가 잘 동작하는지 curl 명령어를 사용한다!
curl은 http 요청을 보내는 도구 중 하나라는데, 잘 몰라서 구글링 좀 해봐야겠다...

② 레지스트리 컨테이너에 push

컨테이너에 이미지를 올리려면, 이미지 이름을 아래와 같이 추가해줘야 한다.

// 이미지 추가
docker tag [기존 이미지 이름] [호스트의 ip]:5000/이미지명:태그명

이미지가 push되지 않는것을 확인할 수 있다. 왜냐하면 기본적으로 도커 데몬은 https를 사용하지 않은 컨테이너에 접근하지 못하도록 설정하기 때문이다. https를 사용하려면 인증서를 적용해서 별도로 설정해야 하는데, 이는 뒤에서 다시 하도록 하겠다.
(2020년 여름방학에 클러그 웹 심화 멘토링에서 https 보안을 적용하는걸 배웠는데 이를 참고하여 공부해보자!!)

지금은 https 안써도 할 수 있도록 별도로 도커 시작옵션을 변경해보자...
/etc/default/docker를 열면 아래와 같은데

DOCKER_OPTS 부분을 이렇게 바꿔주자!

DOCKER_OPTS="--insecure-registry=172.30.1.4:5000

0개의 댓글