2주차 [1] - 쿠버네티스와 Kind 소개

  • 네트워크 관련 CNI에 대한 실습을 하기 앞서, k8s 지식들을 점검해보자

1. 쿠버네티스 소개

  • 쿠버네티스의 목적성은 다수의 컨테이너를 운영해야 될때, 도커의 부족한점을 해결하기 위함이다. (컨테이너 오케스트레이션)

  • 쿠버네티스는 컨트롤 플레인, 노드로 구성되어있다.

  • 쿠버네티스는 컨테이너 애플리케이션의 기본 단위를 파드라고 부르고, 파드는 1개 이상의 컨테이너로 구성된 컨테이너의 집합이다.

1.1 Kubernetes 구성요소들

1.1.1 Control Plane 컴포넌트

  • kube-api server 은 kubectl에서 전달되는 모든 요청을 받는 API 서버

    • (kubectl -> api -> node의 kubelet)

  • etcd는 클러스터 내 모든 메타정보(설정정보)를 저장하는 서비스

  • kube-scheduler는 요청에 따라 컨테이너를 워커 노드에 배치하는 스케줄러

  • kube-controller-manager는 현재 상태와 바라는 상태를 확인하며, 특정 이벤트에 따라 특정 동작을 수행하는 컨트롤러

  • cloud-controller-manager는 클라우드 플랫폼에 특화된 리소스를 제어하는 클라우드용 컨트롤러

1.1.2 워커노드 컴포넌트

  • kubelet은 kubectl의 명령에 따라, 컨테이너의 라이프사이클을 관리하는 노드 관리자

  • kube-proxy는 컨테이너 네트워킹을 책임지는 프록시, 네트워크 규칙에 대한 유지 관리

  • Container Runtime은 컨테이너를 실행하는 환경 (ContainerD, CRI-0)

1.1.3 Add On

  • CNI는 컨테이너 네트워크 인터페이스로 K8S 네트워크 환경 구성을 위함

  • DNS는 쿠버네티스 서비스를 위한 DNS 레코드를 제공하고, Service Discovery 기능을 제공한다. (CoreDNS)

  • 그외에는 대시보드, 모니터링, 로깅 등이 있다.

1.2 k8s 아키텍처 소개

1.2.1 Object

  • 쿠버네티스는 모든것을 리소스로 표현합니다.

    • 최소 실행 단위인 Pod

    • 설정 정보인 configmaps

    • 클러스터를 논리적 단위로 분리하는 namespaces (다른 권한 설정 및 다른 네트워크 정책)

      • namespace 단위로 분리되는 리소스들

        • pod, service, deployments

      • namespace와 상관없이 cluster 단위로 분리되는 리소스들

        • Persistent Volume

        • Storage Class

        • Node

    • kubectl api-resources 의 실행 결과를 확인해보면 모두 확인할 수 있습니다.

root@manager:~# kubectl api-resources
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
bindings                                       v1                                     true         Binding
componentstatuses                 cs           v1                                     false        ComponentStatus
configmaps                        cm           v1                                     true         ConfigMap
endpoints                         ep           v1                                     true         Endpoints
events                            ev           v1                                     true         Event
limitranges                       limits       v1                                     true         LimitRange
namespaces                        ns           v1                                     false        Namespace
nodes                             no           v1                                     false        Node
persistentvolumeclaims            pvc          v1                                     true         PersistentVolumeClaim
persistentvolumes                 pv           v1                                     false        PersistentVolume
pods                              po           v1                                     true         Pod

1.2.2 Controller

  • 컨테이너의 집합을 관리하는 컨트롤러 Replica Set

  • 그 컨트롤러 집합을 관리하는 Deployment

  • 별개의 DaemonSet 으로 별개의 라이프사이클을 가진 node를 관리합니다.

  • CronJob으로 job의 형태로도 관리할 수 있습니다.

1.2.3 Components

  • Components

    • 위의 그림과 같이 Components들은 앞서 언급되었던 모든 구성요소들을 나열합니다.

      • Control Plane Components

      • Worker Components

  • Networking

    • Service 레벨의 Networking

      • kube-proxy를 통해 Service Network가 어떻게 Pod Network로 통신을 하는지 확인할 예정이다.

    • Pod 레벨의 Networking

      • pod 에서는 CNI 라는 인터페이스를 통해 무엇을 할 수 있고 어떤 방식으로 통신하는지 확인할 수 있다.

2. kind 소개 및 설치

  • kind 를 사용해서 로컬에서 Docker in Docker으로 쿠버네틴스 클러스터 환경을 구성합니다.

    • kind 란?

      • kubernetes in docker 의 줄임말로, node가 docker container로 생성한 경우 입니다.

      • 테스트환경을 구성하는데 사용합니다.

2.1 kind의 동작 원리

  • Node 컨테이너가 쿠버네티스 관련 파드가 기동이 되게 합니다.

  • 장점은 HA 환경도 조성해볼수 있습니다. 또, ingress나 scaling도 테스트 해볼 수 있습니다.

  • 단점은 보안상으로 좋지 않습니다. 호스트의 /boot를 컨테이너에 마운트가 됩니다. 또, 호스트의 대부분의 권한을 컨테이너가 가지게 됩니다.

2.2 kind를 통한 설치

# 1. vagrant를 통한 설치
# 2. kind 기본 사용

# '컨트롤플레인, 워커 노드 1대' 클러스터 배포 : 파드에 접속하기 위한 포트 맵핑 설정
cat <<EOT> kind-2node.yaml
# two node (one workers) cluster config
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
  extraPortMappings:
  - containerPort: 30000
    hostPort: 30000
    listenAddress: "0.0.0.0" # Optional, defaults to "0.0.0.0"
    protocol: tcp # Optional, defaults to tcp
  - containerPort: 30001
    hostPort: 30001
EOT

CLUSTERNAME=myk8s
kind create cluster --config kind-2node.yaml --name $CLUSTERNAME


# 배포 확인
kind get clusters

# 노드 확인
kubectl get nodes -o wide
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get nodes -o wide
NAME                  STATUS   ROLES           AGE    VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                         KERNEL-VERSION       CONTAINER-RUNTIME
myk8s-control-plane   Ready    control-plane   104s   v1.31.0   172.18.0.3    <none>        Debian GNU/Linux 12 (bookworm)   5.15.0-119-generic   containerd://1.7.18
myk8s-worker          Ready    <none>          88s    v1.31.0   172.18.0.2    <none>        Debian GNU/Linux 12 (bookworm)   5.15.0-119-generic   containerd://1.7.18

# 컨트롤플레인, 워커 컨테이너 각각 1대씩 실행
# 컨테이너 확인 : 컨테이너 갯수, 컨테이너 이름 확인
# kind yaml 에 포트 맵핑 정보 처럼, 자신의 PC 호스트에 30000 포트 접속 시, 워커노드(실제로는 컨테이너)에 TCP 30000 포트로 연결
# 즉, 워커노드에 NodePort TCP 31000 설정 시 자신의 PC 호스트에서 접속 가능!
docker ps
docker port $CLUSTERNAME-worker
(⎈|kind-myk8s:N/A) root@kind:~# docker ps
docker port $CLUSTERNAME-worker
CONTAINER ID   IMAGE                  COMMAND                  CREATED         STATUS         PORTS                                  NAMES
3bd64486d018   kindest/node:v1.31.0   "/usr/local/bin/entr…"   4 minutes ago   Up 4 minutes   127.0.0.1:35355->6443/tcp              myk8s-control-plane
2f720e3de20f   kindest/node:v1.31.0   "/usr/local/bin/entr…"   4 minutes ago   Up 4 minutes   0.0.0.0:30000-30001->30000-30001/tcp   myk8s-worker
(⎈|kind-myk8s:N/A) root@kind:~# docker port $CLUSTERNAME-worker
30000/tcp -> 0.0.0.0:30000
30001/tcp -> 0.0.0.0:30001

# 컨테이너 내부 정보 확인 bash로 접속
docker exec -it $CLUSTERNAME-control-plane ip -br -c -4 addr
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it $CLUSTERNAME-control-plane ip -br -c -4 addr
lo               UNKNOWN        127.0.0.1/8
veth171107a6@if2 UP             10.244.0.1/32
veth47c46a98@if2 UP             10.244.0.1/32
veth3f544aef@if2 UP             10.244.0.1/32
eth0@if9         UP             172.18.0.3/16

docker exec -it $CLUSTERNAME-worker  ip -br -c -4 addr
(⎈|kind-myk8s:N/A) root@kind:~# docker exec -it $CLUSTERNAME-worker  ip -br -c -4 addr
lo               UNKNOWN        127.0.0.1/8
eth0@if7         UP             172.18.0.2/16

Last updated