Ssoon

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

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

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

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

 

 

 Kubernetes-in-Docker (KinD)

  • KinD는 Kubernetes를 Docker 컨테이너 안에 배포하는 것을 의미합니다.
  • 각 Docker 컨테이너는 VM이나 물리적 호스트를 대신하여 Kubernetes 노드 역할을 합니다.
  • Kubernetes 클러스터는 이러한 컨테이너들로 구성되며, 오버레이 네트워크(예: Docker 브리지)를 통해 연결됩니다.
  • Sysbox는 복잡한 Docker 실행 명령이나 특수한 이미지를 사용할 필요 없이, 잘 격리된(비권한) 컨테이너를 사용해 높은 효율로 KinD를 지원합니다.

 


 컨테이너를 Kubernetes 노드로 사용하세요.

  • 컨테이너는 (Linux 사용자 네임스페이스를 통해) 적절하게 격리되고 (VM 또는 일반 호스트처럼) 기본적으로 Kubernetes를 실행하므로 사용자 정의 Docker 이미지나 까다로운 진입점이 필요하지 않습니다.
  • 완전한 유연성을 위해 docker 실행 명령으로 직접 배포하거나, 더 높은 수준의 도구(예: kindbox)를 사용하여 배포할 수 있습니다.
  • 또는 로컬 테스트와 적절한 격리를 위해 Sysbox 컨테이너 내에서 K8s.io KinD 도구를 실행하여 전체 Kubernetes 클러스터를 컨테이너화할 수 있습니다.
  • Sysbox를 사용하면 K8 노드에 사용되는 컨테이너 이미지를 완전히 제어할 수 있습니다. 원하는 경우 클러스터 노드마다 다른 이미지를 사용할 수 있으며, 내부 포드 이미지를 K8s 노드에 쉽게 미리 로드할 수 있습니다.
  • K8s-in-Docker에서 각 Docker 컨테이너는 K8s 노드 역할을 합니다. 이러한 여러 개의 컨테이너가 Docker 네트워크를 통해 연결되면 K8s 클러스터가 형성됩니다.
  • Sysbox는 특별한 구성 없이 간단한 Docker 이미지와 강력하게 격리된 컨테이너(즉, Linux 사용자 네임스페이스 사용)를 사용하여 K8s를 원활하게 실행할 수 있는 컨테이너를 생성할 수 있는 최초의 컨테이너 런타임입니다.
  • K8s-in-Docker 클러스터를 생성하는 다른 접근 방식(예: K8s.io KinD)도 좋지만 매우 안전하지 않은 권한 컨테이너를 사용하며 사용자 지정 이미지가 필요합니다. Sysbox를 사용하면 잘 격리된 컨테이너를 사용할 수 있으며 특별한 이미지 요구 사항이 없습니다(즉, 컨테이너 이미지를 완전히 제어할 수 있음).

🧿 사용 사례

Kubernetes-in-Docker의 몇 가지 샘플 사용 사례는 다음과 같습니다:

  • Testing and CI/CD :
    • 로컬 테스트 또는 CI/CD 파이프라인에서 사용
  • Infrastructure-as-code :
    • K8s 클러스터 자체가 컨테이너화되어 있어 애플리케이션에서 인프라까지 컨테이너의 강력한 성능을 제공
  • Increased host utilization :
    • 단일 호스트에서 여러 개의 K8s 클러스터를 실행하여 강력한 격리 기능을 갖추고 더 무거운 가상 머신에 의존하지 않아도 됩니다.

🧿 예비 지원 및 알려진 제한 사항

  • Sysbox의 Kubernetes-in-Docker 실행에 대한 지원은 현재 예비 단계입니다.
  • 아래는 작동하는 K8s 기능과 작동하지 않는 기능의 목록입니다. 목록에 표시되지 않은 것은 아직 테스트하지 않았다는 의미입니다(즉, 작동할 수도 있고 작동하지 않을 수도 있습니다).

Supported Functionality

  • Cluster deployment (single master, multi-worker).
  • Cluster on Docker's default bridge network.
  • Cluster on Docker's user-defined bridge network.
  • Deploying multiple K8s clusters on a single host (each on it's own Docker user-defined bridge network).
  • Kubeadm
  • Kubectl
  • Helm
  • K8s deployments, replicas, auto-scale, rolling updates, daemonSets, configMaps, secrets, etc.
  • K8s CNIs: Flannel, WeaveNet (Sysbox-EE), Calico (Sysbox-EE).
  • K8s services (ClusterIP, NodePort).
  • K8s service mesh (Istio).
  • K8s ingress controller (Traefik).
  • K8s volumes (emptyDir, hostPath, persistent).
  • Kube-proxy (iptables mode only).

Not yet supported

  • Kube-proxy ipvs mode.
  • K8s NFS volumes

 Sysbox로 K8s 클러스터 배포하기

  • K8s 클러스터를 배포하는 것은 Docker + Sysbox를 사용하여 하나 이상의 시스템 컨테이너(각각 Systemd, Docker 및 Kubeadm)를 배포하고 마스터 노드에서 kubeadm init을 실행하고 워커 노드에서 kubeadm join을 실행하는 것만큼이나 간단합니다.
  • 또한 kindbox와 같은 상위 레벨 도구를 사용하여 K8s 클러스터를 배포할 수도 있습니다

 

🧿 Docker를 사용하여 K8s 클러스터 배포하기

  • K8s 컨트롤 플레인 노드를 배포합니다:

https://hub.docker.com/r/nestybox/k8s-node/tags

 

https://hub.docker.com/r/nestybox/k8s-node/tags

 

hub.docker.com

docker run --runtime=sysbox-runc -d --rm --name=k8s-master --hostname=k8s-master nestybox/k8s-node:v1.20.2

  • K8s 컨트롤 플레인 노드 내에서 kubeadm을 시작합니다.
docker exec k8s-master sh -c "kubeadm init --kubernetes-version=v1.20.2 --pod-network-cidr=10.244.0.0/16"

  • 다음으로, 호스트에 kubectl을 설치합니다.

  • 컨테이너에서 호스트에 K8s admin.conf 파일을 복사한다
docker cp k8s-master:/etc/kubernetes/admin.conf $HOME/.kube/config

  • cp 에러가 나서 수동으로 k8s-master 의 admin.conf  내용을  복사하여 vi로 직접 입력하였습니다.

  • 이제 CNI 구성을 적용합니다. 이 예제에서는 Flannel을 사용합니다.
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

  • 컨트롤 플레인 노드에서 모든 것이 정상인지 확인합니다
kubectl get all --all-namespaces

  • Docker + Sysbox로 다른 시스템 컨테이너를 실행하여 K8의 " worker node"를 시작합니다.
docker run --runtime=sysbox-runc -d --rm --name=k8s-worker --hostname=k8s-worker nestybox/k8s-node:v1.20.2

  • 워커가 클러스터에 참여할 수 있도록 허용하는 명령을 가져옵니다.
join_cmd=$(docker exec k8s-master sh -c "kubeadm token create --print-join-command 2> /dev/null")
echo $join_cmd

  • 워커 노드에 클러스터에 참여하도록 알립니다
docker exec k8s-worker sh -c "$join_cmd"

  • 모든 것이 정상인지 확인합니다.

  • pod deployment 를 생성합니다.
    • kubectl을 사용하여 K8s 클러스터를 관리합니다. (파드, 서비스 배포 등).
kubectl create deployment nginx --image=nginx
kubectl scale --replicas=4 deployment nginx

  • K8s 노드가 unprivileged containers (권한이 없는 컨테이너) 인지 다시 확인할 수 있습니다
docker exec k8s-master cat /proc/self/uid_map

  • 첫 번째 숫자 (0):
    • 컨테이너 내에서의 사용자 ID (UID) 범위의 시작을 나타냅니다. 여기서는 컨테이너 내의 UID 0이 호스트의 UID 165536과 매핑됩니다. UID 0은 일반적으로 'root' 사용자입니다.
  • 두 번째 숫자 (165536):
    • 호스트 시스템에서 이 컨테이너의 UID 매핑을 시작하는 위치를 나타냅니다. 즉, 컨테이너의 UID 0이 호스트의 UID 165536에 매핑된다는 의미입니다.
  • 세 번째 숫자 (65536):
    • 매핑의 길이 또는 범위를 나타냅니다. 여기서는 UID 165536부터 65536개의 UID가 컨테이너의 UID 0부터 시작하는 범위에 매핑됩니다.
  • 컨테이너의 루트 사용자는 권한이 없는 호스트 사용자 ID 165536에 매핑됩니다.
Comments