강의 정보

강의 필기록 원본이라 글이 좀 어수선할 수 있습니다.

4주차 회고 (및 썰들)

  • (옛날 카카오) ingress nginx 를 커스텀해서 사용자 인증 쿠키를 ingress controller 에서 검사하도록 했었다
    • 다만 버그가 있으면 500 에러가 뜨기 때문에 디버깅이 어려움
  • (네이버) 네이버는 사내에 10개의 클러스터로 모든 서비스를 소화중이고, AWS 처럼 overlay network 를 사용하지 않고 Routing table 을 건든다
    • 물론 버그가 많아 고생했다고 하네
  • 원래 개발하던 KubeDNS 가 확률상으로 질의가 잘 되지 않는 문제가 있었는데, 별개의 프로젝트로 진행되던 CoreDNS 가 쿠버네티스에서 사용하기 편해보여 추가적으로 plugin 을 개발하여 쿠버네티스에서 사용하게 되었다
  • (옛날 카카오) CoreDNS 가 버그가 있어 7000개가 넘는 클러스터가 사내 중앙 DNS 서버를 바라보게 했는데, 이것이 장애가 나서 클러스터가 전부 죽은적이 있었다고 한다.

OCI (Open Container Initiative)

  • Linux Foundation 에 대한 썰들
    • 리누스 토발즈를 내쫒았다
    • 중국을 싫어한다: 중국 오픈소스 프로젝트를 배제하는 경향이 있다

Docker run nginx 를 실행하면 어떤일이 일어나는가

  1. 이미지가 레지스트리에 있는지 확인
  2. 이미지를 로컬에 다운로드 (tar)
  3. 이미지 압축해제
  4. 로컬 어딘가에 파일시스템을 생성
  5. 해당 파일시스템으로 프로세스 실행
  6. 프로세스 (PID?), 파일시스템 격리

실습

  • 실습 코드) iwanhae/learningspoons-kubernetes
  • 위의 실습에서는
    1. ubuntu 이미지의 root dir 을 tmp 라는 로컬 폴더로 다 옮긴다
    2. 그리고 로컬폴더의 tmp 를 chroot 를 사용해서 (chroot tmp) 루트를 속여준 후에 bash 를 실행시키면
    3. 실제로는 tmp 라는 파일에 데이터들이 담겨있지만 bash 에서 pwd 를 때리면 root 로 나온다 + 따라서 당연히 bash 로는 root 의 상위로 올라갈 수는 없다
      • 즉, 파일시스템이 격리되게 되는 것

OCI Spec

  • OCI 에서는 컨테이너를 어떻게 만들고 관리하고 삭제할건지

Runtime Spec

Image Spec

  • image spec 은 변경점이 많아져서 옛날 docker spec 과 oci spec 이 호환되지 않을 수 있다
    • 즉, 오래된 이미지면 호환성문제가 생길 수 있다
  • Image 는 아래의 네개로 구성되어 있다
    1. index json
      • manifest json 들의 shasum 저장?
    2. manifest json
      • layer tar 들의 shasum 저장
    3. config json
      • 이미지를 실행시키기 위한 방법이 기술
    4. layer tar
      • rootfs 가 tar 파일로 묶여있는 것
      • 이미지 tar 의 blobs 에 각 layer 들이 tar 로 들어있는데
      • layer(N) 은 layer(N-1) 에서 변경된 것들만 저장한다 (뭐가 삭제되었고 뭐가 생성되었는지 등)

Distribution Spec

  • HTTP API 로 이미지를 어떻게 배포하는지에 대해 기술
  • auth 를 어떻게 구현하는지는 정의하지 않는다
  • Docker hub 에서 Docker pull 을 했을 때 우선 token 이 없으니까 401을 주는데
    • 여기에는 www-authenticate: Bearer realm=”$URL” 헤더가 포함되어 있음
      • 그럼 Docker 는 $URL 에서 token 을 받아와서 다시 요청을 날린다고 한다
  • Layer 를 다운로드할 때에는 registry 에서 직접 주는게 아니라 301 을 줘서 딴곳에서 받아오도록 한다

CNCF (Cloud Native Computing Foundation)

  • CNCF 가 관여하고 있는 프로젝트 오버뷰
  • CNCF 가 내린 Cloud Native 의 정의
  • Linux Foundation 이 관리하는 클라우드 관련 단체
  • OCI 도 좋지만 이것은 컨테이너에 대한 low level 의 정의만을 내림
  • 따라서 실제 Production 에서 컨테이너를 사용하기 위해 필요한 추가적인 것들을 CNCF 에저 정의함
  • Spec 보다는 Interface 를 정의
  • 다양한 환경을 지원하기 위해 + K8s 의 책임범위를 명확하게 하기 위해 정의

CNI

  • runc 처럼 커맨드로 작동하는 내용이 기술됨
  • CNCF 의 CNI 설명: Deep Dive: CNI - Bryan Boreham, Weaveworks & Bruce Ma, Ant Financial
  • CNI 에는 garbage collection 이 정의되어있지 않다
    • 컨테이너가 정상종료되면 Container runtime 이 네트워크 세팅도 지운다
    • exit 1 등으로 종료돼도 Container runtime 이 네트워크 세팅을 지운다
    • 하지만 node OOM 등으로 비정상 종료되면 CNI 설정이 남아있을 수도 있다
      • 종종 발생한다고 한다
      • 이때는 노드 재부팅으로 말끔히 해결할 수 있다
  • CNI Plugin
    • Pod 의 net ns 에 ip 를 부여하고, 해당 net ns 끼리 통신이 잘 될 수 있도록 중간 네트워크 구성을 자동화하는 놈
  • CNI 는 Container 가 아니라 VM 에서도 사용 가능하다
    • id 만 잘 설정해주면 된다

Flannel deep dive

  • hostpath
    • /run/flannel: 노드 하나에서 여러개의 flannel container 가 뜨지 못하게 함
    • /opt/cni/bin: flannel binary 를 host 에 설치
      • CNI 스펙에서는 여기에 어떤 바이너리가 있어야 하고, 각 바이너리는 어떤 인자와 환경변수를 가져야 하는지 정의해놓았다
      • 이 디렉토리에는 flannel 같은 cni plugin 의 binary 뿐 아니라 kubelet 이 복사 혹은 apt install 한 binary 들이 들어간다
    • /etc/cni/net.d: /opt/cni/bin 속의 binary 를 실행시키기 위한 설정파일 저장

CRI

  • Container runtime 과 UNIX Socket (UDS, UNIX Domain Socket) 로 gRPC 소통하는 서버의 성격이 강하다
  • RunC -(래핑)-> ContainerD -(래핑)-> Docker
  • CRI-O: ContainerD 는 다양한 요구사항을 맞추기 위한 다양한 기능을 제공하지만 Kubernetes 에만 집중한 기능들을 제공하는 더 가벼운 런타임을 제공하기 위해 redhat 에서 개발
  • Pod 와 Container 의 차이
    • pod 는 6 개의 LNS(Linux namespace) 중에 2개 (mnt, pid) 만 빼고 나머지 (net, ipc, uts, uid) 를 공유한다
    • 즉, pod 에서 돌아가는 container 들은 저 둘 빼고 나머지는 공유한다는 소리
  • Pod sandbox: pod 에서 공유하는 LNS 들을 생성해주기 위한 sandbox container
    • 이놈이 장애날일을 별로 없다: 보통 kubelet 이 알아서 복구해줌
    • Pod sandbox 를 생성해서 공유 ns 에 대한 자원들 (IP 등) 을 할당받고 pod 의 container 들이 이 ns 에서 작동할 수 있도록 함
  • Protobuf
    • gRPC
  • cAdvisor
    • CRI 에는 container 의 사용량을 모니터링하는 인터페이스가 없다
      • 최근에 추가되었다고 하긴 함; 아직 alpha 단계
    • 따라서 Kubelet 은 CRI 를 통해 container 를 생성 및 관리하지만
    • Container 를 모니터링하는 것은 CRI 를 통하지 않고 cgroup 으로 메트릭을 수집하는 cAdvisor 프로세스를 fork 해서 모니터링하게 함
  • CRI 에는 ImageService API 가 있어서 사용하지 않는 이미지를 자동으로 지운다
  • K8s 에서 dind 파드 띄우기
    • dind 파드에서의 docker process 는 moby namespace 로 ContinerD 에 접근하니까 k8s 에서는 보이지 않는다
    • 추가적으로 CRI 는 image flush 를 제공하는데 docker 는 지원하지 않기 때문에 k8s 입장에서는 보이지 않는 이미지가 계속 쌓일 수도 있다

CSI

  • Storage 쪽 interface
  • CSI Controller 는 k8s 에서 pv 와 pvc 의 reconcile 을 담당: watch 하고 있다가 event 가 생기면 CSI Driver 에 gRPC 로 API 를 찌른다

CPI

  • 나머지는 약간 cli 인자를 뭘 줘야 하고 이런 것들에 대해 정의되어있었다면
  • 이건 진짜 인터페이스
  • Provider 쪽에 강제되는 인터페이스쪽이다: AWS, GCP 모두 따르고 있다
    • Availability Zone 간의 트래픽을 최소화하기 위한 Inner zone first 설정도 있다더라