Information Security Study

240130 도커(이미지 삭제, 가상머신 분리, 원격 레포지토리에 이미지 업로드, 이미지 검증, 도커허브 없이 이미지 옮기기) 본문

네트워크 캠퍼스/Docker

240130 도커(이미지 삭제, 가상머신 분리, 원격 레포지토리에 이미지 업로드, 이미지 검증, 도커허브 없이 이미지 옮기기)

gayeon_ 2024. 1. 30. 15:50

이미지 삭제

 

docker ps -a 해서 나온 컨테이너 전부 stop (컨테이너가 exited 상태가 된다.)

 

 

 

exited인 컨테이너 전부 삭제

 

 

 

전부 제거됨

 

 

 

 

docker images 해서 나오는 이미지들 전부 삭제

 

 

 

이름이 겹치는 이미지는 버전까지 작성해줘야 제거된다.

 

제거 후 조회하면 전부 삭제되어있다.

 

 

이미지 생성 가상머신과 테스트 가상머신 분리하기

현재 도커 내부에 받았던 모든 컨테이너와 이미지를 삭제하여 도커만 설치되어있는 가상머신만 남게 되었다.

 

가상머신 종료 후 virtual box 왼쪽 도구탭에서 우분투 호스트를 우클릭하고 복제를 누르고

 

ubuntu_host2로 이름을 정하고 MAC Address 주소 정책을 '모든 네트워크 어댑터의 새 MAC 주소 생성'으로 바꿔준다.

 

 

 

완전한 복제 선택 후 완료를 누르면 

스펙 및 여태까지 진행했던 내역이 동일한 가상머신이 생성된다.

 

 

실행 후 ip 주소를 101->102로 변경한 후 

sudo hostnamectl set-hostname hostos2로 hostname을 변경한다.

터미널을 재시작하면 host1에서 host2로 변경된 것을 확인할 수 있다.

ip 주소는 가상머신을 종료했다가 다시 켜야 적용된다.

 

 

 

그 후 가상머신 host, host2 둘 다 켜서 각각 ip 주소가 알맞는 상태인지 확인한다.

(host2의 ip만 102로 변경)

 

 

이미지 본인 원격 레포지토리에 업로드하기

본인 소유의 레포지토리에 본인이 생성한 이미지를 업로드하기 위해서는

 

  1. 이미지가 로컬에 생성되어 있어야 한다.
  2. 원격 레포지토리가 존재해야하고, 해당 레포지토리에 접근할 수 있는 아이디로 로그인이 되어있어야 한다.

 

위 요건을 만족시킨 상태에서 커스텀 이미지를 레포지토리에 올리기 위해

이제 이 상태에서 도커허브에 원격 레포지토리를 생성해 볼 것이다.

 

 

먼저 로그인 후 Create repository를 클릭한다.

 

 

 

오른쪽에 보면 업로드 로컬 이미지에 레포명을 부여하는 작업을 수행하는 것을 볼 수 있다.

 

저 명령어를 유심히 보고 Create를 누르면

 

 

 

위와같이 업로드된 내역은 없는 도커허브 레포지토리가 생성되는 것을 볼 수 있다.

아래에는 이번에 도커 명령어로 해당 레지스트리에 어떻게 이미지를 업로드하는지도 나와있다.

 

 

<로컬 환경에서 도커 다뤄보기 글 참고>

실습을 위해 실습용 이미지를 먼저 준비해 볼 것이다.

NGINX 기반으로 index.html을 수정한 myweb 이미지를 1.0버전과

그리고 해당 index.html을 한 번 더 수정한 1.1버전 2개로 준비한다.

 

 

 

markup 폴더 내부에 1.0버전을 빌드한다.

 

 

 

index.html 내용을 1.1로 수정한 뒤 저장한다.

 

 

 

1.1 버전을 빌드한다.

 

 

 

docker images로 두 버전 모두 정상적으로 생성되었는지 확인한다.

 

 

 

다음으로 로컬에 존재하는 이미지에 레포지토리명을 추가로 붙여볼 것이다.

 

$ docker image tag 이미지명:태그버전 레포지토리명/이미지명:태그버전

 

 

ID가 동일한 컨테이너가 생성되었다.

 

레포지토리가 붙은 이미지와 원본 이미지의 IMAGE ID값이 동일하다는것도 확인한다.

 

깊은 복사는 아니고 참조하는 정도이다.

 

그러면 원래 레포지토리로 분류되는 항목에 저장소 주소(내 계정 이름)가 추가된다.

 

 

 

위에서 수행한 일련의 작업을 통해 원격 레지스트리와 업로드 타겟 이미지가 모두 준비되었다면

 

$ docker push 계정명/이미지명:태그

 

 

을 하면 해당 레포지토리에 업로드된다.

 

 

 

도커허브 레포지토리 페이지를 새로고침하면 업로드된 것을 확인할 수 있다.

 

 

요구하는 양식을 정확하게 맞췄다면 레포지토리를 자동으로 생성해주기도 하지만 일반적으로는

도커허브에 레지스트리를 먼저 생성해놓고 거기에 맞춰서 업로드를 한다.

 

자동생성되는 레포지토리는 무조건 public으로 설정된다.

 

이번에는 도커허브에 방금 생성 및 업로드한 레포지토리를 삭제하고

다시 push를 그대로 수행해 볼 것이다.

 

 

 

삭제는 레포지토리 목록을 확인한 General 탭 맨 오른쪽에 Settings에서 수행할 수 있다.

 

 

 

삭제한 상태에서 다시 push를 수행해보면 자동으로 만들어주는 것을 볼 수 있다.

 

 

이번에는 1.1버전을 다시 업로드할 것이다.

 

$ docker tag 이미지명:태그 저장소명/이미지명:태그

형식으로 작성한 다음(docker image tag… → docker tag로 image 생략해도 동작함)

 

 

myweb:1.1 버전을 gayeoneez 레포지토리의 1.1버전으로 올리겠다는 의미이다.

 

image id가 같은데 이는 같은 레퍼런스를 갖고 있다는 뜻이다.

목록은 4개이지만 사실상 2개인 것이다.

 

 

 

push 해보면 전과 달리 Layer already exists라고 뜬다.

 

아까와 달리 나머지 레이어들은 모두 이미 존재한다고 나와서 최종적으로는 변경된 부분만

pushed 상태로 들어가는것을 볼 수 있다.

 

버전이 바뀌어도 기존에 사용하던 레이어는 불변이므로 특정 지점까지는 같은 레이어를 유지하고

넘어선 부분부터만 새롭게 등록하는것을 볼 수 있다.

 

전체적인 내용을 변경한 것이 아닌 index.html만 달라졌기에 나머지는 처음부터 받아서 처리할 필요가 없다.

 

위처럼 레이어를 나누는 이유

  • 자원을 재사용할 수 있다.
  • 속도도 빠르다.

 

 

1.1 버전을 push한 후 도커허브를 새로고침해주면 태그가 두 개로 늘어난 것을 확인할 수 있다.

 

 

올라간 이미지 타 host에서 검증하기

이제 이렇게 올라간 이미지가 현재 로컬에서만 돌아가는지

다른 환경에서도 돌아가는지에 대한 검증이 필요하기 때문에 테스트머신이 하나 더 있어야 한다.

 

이전에 만들어놓은 hostos2를 기준으로 진행해 볼 것이다.

 

 

host2는 내부에 myweb이 존재하지 않는 상태다.

 

myweb이 없는 시점에 복사를 수행했기 때문이다.

 

따라서 이제 여기에 도커허브에 아까 올린 이미지를 pull 받아서 컨테이너를 띄워볼 것이다.

 

 

$ docker pull 레포지토리명/이미지명:버전

수행 후 아래와 같이 이미지를 조회해보면 받아지는 것을 볼 수 있다.

 

 

익명으로 받아보기 위해 docker logout 후 pull 했으며 grep으로 잘 받아졌는지 확인했다.

 

 

이제 해당 이미지로 컨테이너를 띄워볼 것이다.

 

$ docker run -d -p 9001:80 받아온이미지명:버전

 

 

 

잘 돌아가고 있음을 확인할 수 있다.

 

 

 

가상머신이 아닌 윈도우에서 ip:포트번호로 접속하면 index.html이 잘 출력되는 것을 볼 수 있다.

(가상머신에서도 가능하다.)

 

현재 가상머신 구조

윈도우 내에 가상머신 host, host2 총 두 개가 있고

host2의 컨테이너 주소는 172.~~0.2이고 (이 주소는 가상머신 내 인터넷에서 접속할 시 index.html이 띄워지지만 가상머신 내의 주소이기 때문에 윈도우에서는 접속이 불가능하다.)

가상머신의 주소는 각각 192.~~101, ~~102로 다르다.

또한 host에서 172.~~.02로 index.html에 접근하는 것도 불가능하다.

 

 

가상머신 내에서 index.html을 띄우는 방법

1) 가상머신 주소:포트번호 (192~:포트번호)

2) 컨테이너에게 배정된 내부 172.~ 주소

 

윈도우에서 index.html을 띄우는 방법

1) 가상머신주소: 포트번호 (192~:포트번호)

 

 

도커허브 거치지 않고 이미지 옮겨보기

일반적으로는 이렇게 도커허브를 매개로 주고받아야 하는데

 

간헐적으로 이제 도커허브를 거치지 않고 전달해야 할 때에는

 

도커의 save 명령어를 통해 로컬 파일로 저장한 다음

 

물리 파일을 옮겨놓고 load 명령어로 불러와서 다른 호스트에 장착시킬 수 있다.

 

 

먼저 pull 없이 host1에서 받은 이미지를 host2로 전달해 그대로 load한 후 컨테이너를 띄워본다.

 

$ docker pull docker/getting-started

를 이용해서 먼저 이미지를 받는다.

 

해당 이미지를 이제 save로 옮길수 있는 파일화 시켜야 하는데

$ docker image save 이미지명:태그 > 저장할파일명.tar

여기서 압축형식인 tar형식을 사용하는 이유는 이미지 레이어가 여러계층이기 때문에

하나로 묶어서 저장해야 하기 때문이다.

 

단 이렇게 되면 파일 용량이 지나치게 크게 저장되는 경우가 있기 때문에

$ docker image save 이미지명:태그 | gzip > 저장할파일명.tar.gz

$ docker image save 이미지명:태그 | bzip2 > 저장할파일명.tar.bz2

위와 같이 gz나 bz2같은 양식을 이용하면 더욱 더 용량을 절약할 수 있다.

해당 이미지를 한 번 세 개 저장해 볼 것이다.

 

 

각각 용량을 보면 tar보다 bz2나 gz(위는 첫 파일을 tar로 묶지 않고 실수로 gz로 묶었다.)

가 훨씬 절약되는 것을 볼 수 있다.

 

압축파일 여부는 load 가/불 여부에 영향을 주지 않으므로 dgs.tar.gz파일을 보낼 것이다.

 

 

이미지 이전은

$ scp 파일명 가상머신유저@ip주소:/home/유저명/backup/파일명

형식으로 진행할 수 있다. 여기서 /home부터의 경로는 임의의 경로로 대체할 수 있다.

host2에게 보낼 것이다.

 

 

이렇게 뜨면 host2에서 backup 폴더를 만들어주면 된다.

 

 

 

그 후 host2에서

$ docker image load < 파일명.확장자명

형식을 사용해서 파일을 전달받은 호스트에서 마운트할 수 있게 된다.

 

 

 

 

이미지 삭제에 유용한 명령어들

이미지 전체 삭제(docker images -q가 이미지 이름만 전부 보여줌)

$ docker rmi $(docker images -q)

 

특정 이미지명을 포함한 것만 삭제하기

$ docker rmi $(docker images | grep 이미지명)

 

특정 이미지명이 포함되지 않은것만 삭제하기

$ docker rmi $(docker images | grep -v 이미지명)

 

상태가 exited인 container 전체 삭제

$ docker rm $(docker ps --filter ‘status=exited’ -a -q)