CloudNet@ 가시다님이 진행하는 Kubernetes Advanced Networking Study 2주차 정리입니다.

 

 

1. 쿠버네티스 소개

▶ 기초 이론

  • master (control-plane, leader) : 마스터, 컨트롤 플레인, 리더
  • node(worker node) : 노드, 워커노드

▶ k8s (kubernetes, k-s 사이에 8글자 == k8s) : 쿠버네티스, 케이에잇츠, 케이팔에스

  • kubectl : 큐브 컨트롤(control), 큐버 컨트롤, 큐브 시티엘, 큐버 시티엘
  • etcd : 엣시디, 이티시디
  • flannel : 플라넬
  • calico : 칼리코, 캘리코
  • cilium : 실리움
  • istio : 이스티오
  • helm : 헬름
  • pod : 파드, 포드
  • label : 레이블, 라벨
  • De facto(라틴어) : 데 팍토, 사실상의 의미 - Kubernetes has become a de facto standard.

▶ Kubernetes Components : K8S 클러스터는 Control Plane(마스터)와 Node(노드)로 구성

 

Control Plane(마스터 노드) 핵심 컴포넌트 : 마스터는 단일 서버 혹은 고가용성을 위한 클러스터 마스터로 구축

  • kube-apiserver : 마스터로 전달되는 모든 요청을 받아 드리는 API 서버
  • etcd : 클러스터내 모든 메타 정보를 저장하는 서비스
  • kube-scheduler : 사용자의 요청에 따라 적절하게 컨테이너를 워커 노드에 배치하는 스케줄러
  • kube-controller-manager : 현재 상태와 바라는 상태를 지속적으로 확인하며 특정 이벤트에 따라 특정 동작을 수행하는 컨트롤러
  • cloud-controller-manager : 클라우드 플랫폼(AWS, GCP, Azure 등)에 특화된 리소스를 제어하는 클라우드 컨트롤러

워커 노드

  • kubelet : 마스터의 명령에 따라 컨테이너의 라이프 사이클을 관리하는 노드 관리자
  • kube-proxy : 컨테이너의 네트워킹을 책임지는 프록시, 네트워크 규칙을 유지 관리
  • Container Runtime : 실제 컨테이너를 실행하는 컨테이너 실행 환경 (containerD & CRI-O)

Add on

    • CNI : Container Network Interface는 k8s 네트워크 환경을 구성해준다 (다양한 플러그인 존재)
      * K8S 클러스터 네트워킹 (k8S가 해결해야될 4가지 네트워크 문제)
      1. Highly-coupled container-to-container communications : this is solved by Pods and localhost communications
      : 파드에 여러개의 컨테이너가 동작 시, pause 컨테이너의 netns를 공유하여 컨테이너들간 통신은 localhost로 통신 가능
      2. Pod-to-Pod communications : this is the primary focus of this document.
      : 파드 <> 파드 간 NAT 없이 통신할 수 있다
      3. Pod-to-Service communications : this is covered by services
      : 파드 <> 서비스 간 통신 가능
      4. External-to-Service communications : this is covered by services.
      : 외부 <> 서비스 간 통신 가능

      * k8s 네트워크 동작 기준
      1. pods on a node can communicate with all pods on all nodes without NAT
      : 파드 <> 파드 간 NAT 없이 통신할 수 있다
      2. agents on a node (e.g. system daemons, kubelet) can communicate with all pods on that node
      : 노드의 에이전트(예: 시스템 데몬, kubelet)는 모든 파드와 통신할 수 있다
      3. pods in the host network of a node can communicate with all pods on all nodes without NAT
      : 노드의 호스트 네트워크에 있는 파드는 NAT 없이 모든 노드에 있는 모든 파드와 통신할 수 있다
      4. IP range from which to assign service cluster IPs. This must not overlap with any IP ranges assigned to nodes for pods
      : 서비스 클러스터 IP 대역은 각 노드의 파드 IP 대역과 겹치지 않아야 한다.
      : 리눅스 컨테이너의 네트워크 인터페이스를 설정할 수 있도록 도와주는 일련의 명세와 라이브러리로 구성
      : CNI는 오직 '컨테이너의 네트워크 연결성'과 '컨테이너 삭제 시 관련된 네트워크 리소스 해제'에 대해서만 관여. 그 외의 구체적인 사안에 대한 제한이 없음
      : 이를 실행하는 runtime는 어떤 것이든 상관없음(k8s, podman, cloud foundry 등)
    • DNS : 쿠버네티스 서비스를 위해 DNS 레코드를 제공해주며, Service Discovery 기능을 제공을 한다. 대표적으로 CoreDNS가 있다
      - Service Discovery (서비스 탐색)
      : 쿠버네티스는 클러스터내에서 통신하기 위해 노드 위치와는 상관없이 어디서든 접근할 수 있는 서비스 끝점(Service Endpoint)이 필요합니다.
      : 사용자(또는 Pod)는 서비스 끝점을 통해 다른 컨티에너(Pod)와 통신할 수 있습니다.
      : 이를 위해 사용자는 서비스에 접근하기 위한 끝점의 접속 정보(예를 들면 IP)를 알아야 합니다.
      : 이를 서비스 탐색(Service Discovery)이라 합니다.
      : 쿠버네티스에서는 DNS 기반의 서비스 탐색을 지원하기에 사용자가 매번 새로운 서비스의 IP를 찾을 필요 없이 도메인 주소를 기반으로 서비스에 접근할 수 있습니다.
      : 쿠버네티스에서는 서비스 탐색 기능을 Service 라는 리소스를 이용하여 제공합니다.
    • 그 외 대시보드, 모니터링, 로깅 등
    • ETCD 기본 동작 원리의 이해

▶ 쿠버네티스 핵심 개념

1. 서버마다 특별한 이름을 부여하지 않습니다.
: 특정 서버의 역할을 빌드 서버, 웹 서버, 모니터링 서버 등으로 구분하지 않습니다. 모든 서버들은 워커 서버로 동작합니다.
2. 한두 개의 서버(워커 노드)가 망가져도 문제 없습니다.
: 마스터에서는 쿠버네티스를 운용하기 위한 필수적인 핵심 컴포넌트가 존재하고, 나머지 워커 노드들은 단순히 컨테이너를 실행하는 환경으로 사용.
워커마다 특별한 역할을 맡지 않기 때문에 마스터가 죽지 않은 이상 특정 워커가 수행했던 역할을 나머지 워커들에 맡겨도 문제 없습니다.
이것은 컨테이너라는 고립화된 가상실행 환경을 통해 이식성을 높였기에 가능한 일입니다.

 

▶ 바라는 상태(Desired State) <- 컨트롤러(특정 리소스를 지속적으로 바라보며 리소스의 생명주기에 따라 미리 정해진 작업을 수행하는 주체)
: 쿠버네티스는 사용자의 요청에 따라 현재 상태가 바라는 상태와 동일해지도록 사전에 미리 정의된 특정 작업을 수행.
쿠버네티스에서 바라는 상태란 사용자가 생각하는 최종 애플리케이션 배포 상태

 

▶ 네임스페이스(Namespace)
: 네임스페이스마다 서로 다른 권한 설정을 할 수 있으며, 네트워크 정책 등을 설정할 수 있다.
Pod, Deployment, Service와 같이 대부분의 쿠버네티스 리소스가 네임스페이스 안에 포함됩니다.

 

▶ 쿠버네티스 리소스(Resource), 오브젝트
: Pod, ReplicaSet, Deployment 등 다양한 리소스가 존재하고 각각 역할이 있습니다.
컨테이너의 집합(Pods), 컨테이너의 집합을 관리하는 컨트롤러(Replica Set), 사용자(Service Account), 노드(Node) 까지도 하나의 오브젝트로 표현 가능합니다.
쿠버네티스의 가장 기본적인 리소스는 Pod 이며 Pod는 하나 이상의 컨테이너를 가지는 쿠버네티스의 최소 실행 단위입니다. 쿠버네티스에서 프로세스(컨테이너)를 실행한다는 의미는 Pod 리소스를 생성하는 것과 같다고 볼수 있습니다.

▶ 선언형 커맨드(Declarative Command)
: 선언형 커맨드란 사용자가 직접 시스템의 상태를 바꾸지 않고 사용자가 바라는 상태를 선언적으로 기술하여 명령을 내리는 방법.
쿠버네티스는 YAML 형식을 이용하여 선언형 명령을 내립니다.

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx:latest

 

사용자는 각 리소스마다의 모든 설정값을 외울 필요가 없으며 최소한의 필수값을 채워서 리소스를 생성하면, 나머지는 쿠버네티스가 기본값으로 리소스를 생성합니다.

 

▶ Highly Available 구성

  • Control Plane(마스터 노드) HA 설정 : 마스터 노드 3대 구성 및 외부 LB(혹은 keepalived)를 통한 API 단일 진입점 구성
  • kubeadm HA topology - stacked etcd

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/

  • kubeadm HA topology-external etcd

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/

 

▶ [sam.0] 쿠버네티스 딥다이브

https://netpple.github.io/docs/deepdive-into-kubernetes/

 

쿠버네티스 딥다이브

목차 안내

netpple.github.io

정리

 

 

 

2. Kind 소개 및 설치

▶ 도커IN도커 로 쿠버네티스 클러스터 환경을 구성

  • kind or kubernetes in docker is a suite of tooling for local kubernetes "clusters" where each "node" is a Docker container
  • kind is targeted at testing kubernetes, kind supports multi-node (including HA) clusters
  • kind uses kubeadm to configure cluster nodes

 

[ 환경 구성 ] - Windows

1. virtualBox 설치

2. Vagrant 버전 확인

3. Vagrant로 ubuntu 가상 머신 배포

: 폴더 생성 후 Vagrantfile 및 init_cfg.sh 파일 생성

- Vagrantfile

# Base Image : https://portal.cloud.hashicorp.com/vagrant/discover?query=ubuntu%2Fjammy64

Vagrant.configure("2") do |config|
    config.vm.box = "ubuntu/jammy64"
    config.vm.box_version = "20240823.0.1"
    config.vm.hostname = "kind"
    config.vm.synced_folder "./", "/vagrant", disabled: true
    config.vm.provision "shell", path: "init_cfg.sh"
    config.vm.provider "virtualbox" do |vb1|
      vb1.customize ["modifyvm", :id, "--nested-hw-virt", "on"]
      vb1.memory = 8192
      vb1.cpus = 4
      vb1.name = "kind"
      vb1.linked_clone = true
    end
    config.vm.network "private_network", ip: "192.168.50.10"
    config.vm.network "forwarded_port", guest: 22, host: 60000, auto_correct: true, id: "ssh"
  end

- init_cfg.sh

#!/usr/bin/env bash

echo "[TASK 0] Setting SSH with Root"
printf "qwe123\nqwe123\n" | passwd >/dev/null 2>&1
sed -i "s/^#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/g" /etc/ssh/sshd_config.d/60-cloudimg-settings.conf
systemctl restart sshd  >/dev/null 2>&1

echo "[TASK 1] Profile & Bashrc"
echo 'alias vi=vim' >> /etc/profile
echo "sudo su -" >> .bashrc
ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime

echo "[TASK 2] Disable AppArmor"
systemctl stop ufw && systemctl disable ufw >/dev/null 2>&1
systemctl stop apparmor && systemctl disable apparmor >/dev/null 2>&1

echo "[TASK 3] Install Packages"
apt update -qq >/dev/null 2>&1
apt-get install bridge-utils net-tools jq tree unzip kubecolor -y -qq >/dev/null 2>&1

echo "[TASK 4] Install Kind"
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.24.0/kind-linux-amd64 >/dev/null 2>&1
chmod +x ./kind
mv ./kind /usr/bin

echo "[TASK 5] Install Docker Engine"
curl -fsSL https://get.docker.com | sh >/dev/null 2>&1

echo "[TASK 6] Install kubectl"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" >/dev/null 2>&1
install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

echo "[TASK 7] Install Helm"
curl -s https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash >/dev/null 2>&1

echo "[TASK 8] Source the completion"
source <(kubectl completion bash)
echo 'source <(kubectl completion bash)' >> /etc/profile

echo "[TASK 9] Alias kubectl to k"
echo 'alias k=kubectl' >> /etc/profile
echo 'complete -F __start_kubectl k' >> /etc/profile

echo "[TASK 10] Install Kubectx & Kubens"
git clone https://github.com/ahmetb/kubectx /opt/kubectx >/dev/null 2>&1
ln -s /opt/kubectx/kubens /usr/local/bin/kubens
ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx

echo "[TASK 11] Install Kubeps & Setting PS1"
git clone https://github.com/jonmosco/kube-ps1.git /root/kube-ps1 >/dev/null 2>&1
cat <<"EOT" >> ~/.bash_profile
source /root/kube-ps1/kube-ps1.sh
KUBE_PS1_SYMBOL_ENABLE=true
function get_cluster_short() {
  echo "$1" | cut -d . -f1
}
KUBE_PS1_CLUSTER_FUNCTION=get_cluster_short
KUBE_PS1_SUFFIX=') '
PS1='$(kube_ps1)'$PS1
EOT

echo "[TASK 12] To increase Resource limits"
# cat /proc/sys/fs/inotify/max_user_watches >> 8192
# cat /proc/sys/fs/inotify/max_user_instances >> 128
sysctl fs.inotify.max_user_watches=524288 >/dev/null 2>&1
sysctl fs.inotify.max_user_instances=512 >/dev/null 2>&1
echo 'fs.inotify.max_user_watches=524288' > /etc/sysctl.d/99-kind.conf
echo 'fs.inotify.max_user_instances=512'  > /etc/sysctl.d/99-kind.conf
sysctl -p >/dev/null 2>&1
sysctl --system >/dev/null 2>&1

ubuntu ssh 접속
기본 정보 확인
htop
ip -c a
툴 설치 확인
외부 통신 확인
클러스터 배포 확인
노드 정보 확인
파드 정보 확인
컨트롤플레인 노드 1대가 실행
nginix 파드 배포 및 확인

 

▶ 기본 사용 : kind 동작 원리 (Docker in Docker) 확인

  • 기본 정보 확인

kind는 별도 도커 네트워크 생성 후 사용

 

 

 

 

    • 쿠버네티스 관련 정보 조사

 

 

 

  • 파드 생성 및 확인

 

 

  • 컨트롤플레인 컨테이너 정보 확인 : 아래 "Node" Container은 'myk8s-control-plane' 컨테이너
    - 해당 "Node" 컨테이너 내부에 쿠버네티스 관련 파드(컨테이너)가 기동되는 구조 -> Docker in Docker (DinD)

 

도커 컨테이너확인

 

컨트롤플레인 컨테이너 접속 후 확인

 

프로세스 확인
컨테이너 런타임 정보 확인

 

DinD 컨테이너 확인 : crictl 사용

 

▶ Multi-Node Cluster(Control-plane, Nodes) with kube-ops-view & Mapping ports

컨트롤 플레인, 워커 노드 1대 배포

 

Mapping ports to the host machine

  • kube-ops-view : NodePort 31000

 

 

  • nginx : NodePort 31001