Ssoon

[1주차] Sysbox Container Runtime : Docker-in-Docker 본문

쿠버네티스 네트워크 스터디 3기

[1주차] Sysbox Container Runtime : Docker-in-Docker

구구달스 2024. 8. 26. 16:40
CloudNet@ 가시다님이 진행하는 쿠버네티스 네트워크 스터디 3기

 Docker-in-Docker (DinD)

  • DinD는 Docker(CLI + 데몬)를 Docker 컨테이너 안에 배포하는 것을 의미합니다.
  • Sysbox는 복잡한 Docker 실행 명령이나 특수한 이미지를 사용할 필요 없이, 잘 격리된(비권한) 컨테이너를 사용해 DinD를 지원합니다.

  • 보안이 취약한 권한 컨테이너 없이 호스트의 Docker 소켓을 마운트하지 않고도 컨테이너 또는 포드 내에서 쉽게 Docker를 실행할 수 있습니다.
  • 컨테이너 내부의 Docker와 호스트의 Docker를 완전히 격리합니다.
  • 내부 Docker 컨테이너 이미지는 컨테이너 내부에 임시로 존재하거나 호스트에 캐시될 수 있습니다.

🧿 내부에 Docker를 사용하여 System Container 배포하기

  • Alpine + Docker가 포함된 시스템 컨테이너 이미지를 사용
  • System Container를 시작합니다
docker run --runtime=sysbox-runc -it --hostname=syscont nestybox/alpine-docker:latest

  • 내부 도커를 시작합니다:
  • Docker가 올바르게 시작되었는지 확인합니다:
dockerd > /var/log/dockerd.log 2>&1 &

  • 내부 컨테이너를 시작합니다:
docker run -it busybox

  • Docker는 보안 시스템 컨테이너 내에서 정상적으로 실행되며 내부 컨테이너(busybox)를 문제 없이 배포할 수 있습니다.

 

  • Sysbox 런타임을 사용하면 이 작업을 쉽고 안전하게 수행할 수 있습니다(복잡한 Docker 실행 명령이나 안전하지 않은 Docker 권한 컨테이너가 필요 없습니다!).

🧿 내부에 Systemd, sshd 및 Docker가 포함된 시스템 컨테이너 배포

  • 이전 예제에서는 컨테이너에 Systemd(또는 다른 프로세스 관리자)가 없었기 때문에 컨테이너 내부에서 Docker를 수동으로 시작해야 했습니다.
  • 이 예제에서는 Systemd와 Docker가 모두 포함된 시스템 컨테이너를 배포하여 이 문제를 개선했습니다.
  • 또한 System Container 이미지에 SSH 데몬을 추가하여 물리적 호스트나 가상 머신에서와 마찬가지로 원격으로 로그인할 수 있도록 했습니다.

 

  • System Container 를 시작합니다
docker run --runtime=sysbox-runc -it --rm -P --hostname=syscont nestybox/ubuntu-bionic-systemd-docker:latest

  • 컨테이너에 로그인합니다:
    • 기본 콘솔 로그인 및 비밀번호를 admin/admin

  • Systemd가 Docker를 시작했는지 확인합니다.
systemctl status docker.service

  • 내부 컨테이너를 시작합니다:
docker run -it busybox

  • 이제 System Container 에 ssh로 접속합니다.
  • 이렇게 하려면 호스트의 IP 주소와 시스템 컨테이너의 sshd 포트에 매핑된 호스트 포트가 필요합니다.
  • 제 경우 호스트의 IP 주소는 192.168.56.10 입니다. ssh 데몬은 호스트 컴퓨터의 임의의 포트에 매핑된 시스템 컨테이너의 포트 22에서 수신 대기 중입니다.

  • 다른 컴퓨터에서 System Container 에 ssh로 접속합니다:

  • 이제 가상 호스트처럼 작동하는 System Container 가 Systemd 및 sshd와 함께 작동합니다.
  • 또한 내부에 Docker가 포함되어 있어 기본 호스트와 완전히 격리된 상태로 애플리케이션 컨테이너를 배포할 수 있습니다.

🧿 Supervisord와 Docker가 포함된 시스템 컨테이너 배포하기

  • Systemd는 훌륭하지만 일부 사용 사례에서는 너무 무거울 수 있습니다.
  • 좋은 대안은 시스템 컨테이너 내부에서 경량 프로세스 관리자로 Supervisord를 사용하는 것입니다.
  • 여기서는 nestybox/alpine-supervisord-docker:latest라는 시스템 컨테이너 이미지를 사용

 

  • System Container  를 시작합니다:
docker run --runtime=sysbox-runc -d --rm -P --hostname=syscont nestybox/alpine-supervisord-docker:latest

 

  • 슈퍼바이저가 System Container  내에서 모든 서비스를 시작했는지 확인합니다.

 

  • 표시된 것처럼 supervisord가 초기화 프로세스로 실행 중이며 sshd 및 dockerd를 생성했습니다
  • 이제 시스템 컨테이너에 ssh로 접속해 보겠습니다.
  • System Container  의 ssh 포트는 위의 docker ps 출력에 표시된 대로 호스트 포트 32769에 매핑되어 있습니다.
    • 로그인은 이미지의 Docker파일에 구성된 대로 root:root입니다.

  • System Container  내에서 Docker 컨테이너를 실행합니다:


🧿 Docker 볼륨을 사용한 내부 컨테이너 이미지의 지속성

  • System Container  내부에서 실행 중인 Docker 인스턴스는 컨테이너 내부의 /var/lib/docker 디렉터리에 있는 캐시에 이미지를 저장합니다.
  • System Container 가 제거되면(docker rm을 통해) 해당 디렉터리의 내용도 제거됩니다.
  • 즉, 연결된 시스템 컨테이너가 제거되면 내부 Docker의 이미지 캐시가 삭제됩니다.
  • System Container  수명 주기 동안 내부 Docker의 이미지 캐시를 유지하기 위해 호스트 스토리지를 시스템 컨테이너의 /var/lib/docker에 마운트하여 이 동작을 재정의할 수 있습니다.
  • 실제로 내부 Docker 이미지만 지속되는 것이 아니라 내부 컨테이너도 지속됩니다

 

  • System Containe 너 내부의 Docker 데몬에 대한 영구 이미지 캐시 역할을 할 Docker 볼륨을 호스트에 생성합니다.

  • System Containe 를 실행하고 볼륨을 시스템 컨테이너의 /var/lib/docker 디렉터리에 마운트합니다.

  • System Containe  에서 Docker를 시작합니다:
dockerd > /var/log/dockerd.log 2>&1 &

  • 내부 컨테이너 이미지 를 가져옵니다:

  • 내부 컨테이너를 만듭니다:

  • System Container 를 종료합니다.
    • 그러면 내부 컨테이너가 자동으로 중지됩니다.
    • 시스템 컨테이너의 /var/lib/docker의 콘텐츠는 볼륨 myvol에 저장되므로 계속 유지됩니다.
  • System Container  를 시작하고 그 안에 myvol을 마운트합니다:
docker run --runtime=sysbox-runc -it --rm --hostname syscont --mount source=myvol,target=/var/lib/docker nestybox/alpine-docker

  • 내부에서 Docker를 시작합니다:
dockerd > /var/log/dockerd.log 2>&1 &

  • 내부 Docker 이미지가 유지되는지 확인합니다:

  • 내부 Docker 컨테이너가 지속되었는지 확인합니다:

 

  • 내부 컨테이너 이미지와 심지어 내부 컨테이너는 시스템 컨테이너의 수명 주기 동안 지속되었습니다.
    이는 시스템 컨테이너가 호스트의 어딘가에 저장된 기존 Docker 이미지 캐시를 활용할 수 있으므로 새 시스템 컨테이너가 시작될 때마다 네트워크에서 내부 Docker 이미지를 가져올 필요가 없다는 것을 의미하기 때문에 멋진 기능입니다.


몇 가지 유의해야 할 중요한 주의 사항이 있습니다:

  • 시스템 컨테이너의 /var/lib/docker에 마운트된 Docker 볼륨은 한 번에 하나의 시스템 컨테이너에만 마운트되어야 합니다.
    • 이미지 캐시를 여러 데몬 인스턴스 간에 동시에 공유할 수 없는 Docker 데몬에 의해 부과된 제한 사항입니다.
    • Sysbox는 시스템 컨테이너를 생성하는 동안 이 규칙을 위반하는지 확인하고 적절한 오류를 보고합니다.
  • 시스템 컨테이너의 /var/lib/docker에 마운트된 Docker 볼륨은 시스템 컨테이너 이미지의 일부로 동일한 디렉터리에 있는 모든 파일을 상속합니다. 이러한 파일은 내부 컨테이너 이미지가 미리 로드된  System Container 를 사용할 때 존재할 수 있습니다.
    • 시스템 컨테이너에 내부 이미지가 미리 로드되어 있는 경우  System Container 가 시작될 때 해당 이미지가 자동으로 Docker 볼륨으로 전송되며  System Container 수명 주기 동안 지속됩니다.
    • 이 동작은 호스트 디렉터리를 시스템 컨테이너 /var/lib/docker에 바인드 마운트할 때와는 다릅니다

🧿 바인드 마운트를 사용한 내부 컨테이너 이미지의 지속성

  • 이 섹션은 이전 섹션과 유사하지만 시스템 컨테이너를 시작할 때 Docker 볼륨 대신 바인드 마운트를 사용합니다.

 

  • 호스트에 System Container 내부의 Docker 데몬에 대한 영구 이미지 캐시 역할을 할 디렉토리를 만듭니다.
sudo mkdir /home/ubuntu/image-cache

  • System Container 를 실행하고 새로 생성된 디렉터리를 System Container 의 /var/lib/docker 디렉터리에 바인드 마운트합니다.
 docker run --runtime=sysbox-runc -it --rm --hostname syscont --mount type=bind,source=/home/ubuntu/image-cache,target=/var/lib/docker nestybox/alpine-docker

  • System Container 에서 Docker를 시작하고 이미지를 가져옵니다.

  • System Container 를 종료합니다.
  • 새 System Container 를 시작하고 이전과 마찬가지로 my-image-cache 디렉터리를 바인드 마운트합니다:
 docker run --runtime=sysbox-runc -it --rm --hostname syscont --mount type=bind,source=/home/ubuntu/image-cache,target=/var/lib/docker nestybox/alpine-docker

  • System Container  내에서 Docker를 시작하고 바인드 마운트된 캐시에서 이미지가 표시되는지 확인합니다:


여기서 유의해야 할 몇 가지 주의 사항이 있습니다:

  • System Container  의 /var/lib/docker에 바인드 마운트된 호스트 디렉토리는 주어진 시간에 하나의 System Container  에만 마운트되어야 합니다. 이는 이미지 캐시를 여러 데몬 인스턴스 간에 동시에 공유할 수 없는 내부 Docker 데몬에 의해 부과된 제한 사항입니다. Sysbox는 System Container  를 생성하는 동안 이 규칙을 위반하는지 확인하고 적절한 오류를 보고합니다.
  • System Container /var/lib/docker에 바인드 마운트된 호스트 디렉터리는 System Container  이미지의 일부로 동일한 디렉터리에 있는 모든 파일을 “마스킹”합니다. 이러한 파일은 내부 컨테이너 이미지가 미리 로드된 System Container  를 사용할 때 존재할 수 있습니다.
    • 이 동작은 Docker 볼륨 마운트가 System Container  의 /var/lib/docker에 마운트되는 경우와 다릅니다.
Comments