김가은-4

김가은-4

1. Kubernetes (쿠버네티스)소개

2-1. 쿠버네티스 설치 / 설치없이 웹에서 실습하기

2-2. 쿠버네티스 설치 / PC에 직접 설치하기

  • 사전 지식

  • 환경 구성


Kubernetes (쿠버네티스)소개

  1. 쿠버네티스란

구글이 수십억 개의 컨테이너를 운영하며 쌓은 경험을 기반으로 개발한 컨테이너 오케스트레이션 플랫폼

2015년 구글이 CNCF (Cloud Native Computing Foundation) 에 기부하며 오픈소스화됨

 

  1. 왜 쿠버네티스를 사용해야 하나

  • 단일 도커 시스템의 한계

    • 하나의 서버(호스트)에서 도커만으로 컨테이너를 운영하는 경우,

    • 해당 서버(도커 엔진 포함)가 장애나 다운되면 → 모든 컨테이너가 중단됨 → 가용성 문제 발생

  • 멀티호스트 도커 플랫폼으로 극복하게 됨

    • 하나의 서버(호스트)에 도커를 설치해 컨테이너를 운영하는 것이 아니라,
      여러 대의 서버(호스트)에 도커를 설치하고, 이 서버들을 하나의 플랫폼처럼 묶어서 컨테이너를 분산 운영하는 구조

    • 특정 서버(Docker 데몬 포함)가 죽으면 → 그 서버의 컨테이너들은 중단됨 → 운영자가 직접 다른 서버에 컨테이너를 재배포 해야 함. → 그렇기 때문에 컨테이너 오케스트레이션이 필요해짐

image-20250624-053145.png
  1. 쿠버네티스와 컨테이너 오케션

여러 서버(호스트)에서 수많은 컨테이너를 자동으로 배치, 스케일링, 복구, 업데이트 하도록 관리하는 기술 또는 시스템

  • 쿠버네티스의 역할

    • 여러 호스트(서버)에 걸쳐 도커(또는 다른 컨테이너 엔진)를 관리

    • 특정 서버(노드)가 다운되면, 다른 서버에서 자동으로 컨테이너를 재실행

    • 서비스가 무중단으로 유지되도록 보장

image-20250624-053535.png

 

  1. 쿠버네티스 기본 구조

image-20250624-053743.png
[ 인프라 (하드웨어 + OS) ] [ 컨테이너 엔진 (Docker 등) ] [ Kubernetes (컨트롤 플레인 + 워커 노드) ] [ 컨테이너 앱 (웹 서버, DB, 결제 시스템 등) ]

 

  1. 쿠버네티스 특징

  • 수평 스케일링: 컨테이너 수를 빠르게 늘리고 줄임

  • 장애 복구: 노드 다운 시 자동으로 다른 노드에 컨테이너 재배치

  • 환경 호환: AWS, Azure, GCP, 온프렘 등 어디서나 실행 환경 제공

  • API 기반 선언적 관리: 원하는 상태만 선언, 나머지는 자동

image-20250624-071511.png

쿠버네티스 웹에서 실습하기

  1. 카다코다 쿠버네티스 플레이그라운드 (폐쇄됨)

 

  1. Play with Kubernetes

  • https://labs.play-with-k8s.com/

  • 4시간 사용 가능. Master, worker Node를 직접 구성한 후 사용가능

  • docker에서 제공. docker hub 계정으로 로그인 후 Start

image-20250624-075333.png

쿠버네티스 설치하기

  1. 사전 지식

  • CNI (Container Network Interface)

    • 컨테이너 간 통신을 지원하는 소프트웨어 인터페이스

    • VxLAN, Pod Network라고도 부름

    • 플라넬(flannel), 칼리코(calico), 위브넷(weavenet) 등이 있음

  • Control Plane(Master Node)

    • Worker node의 상태를 관리하고 제어

  • Worker Node

    • 도커 플랫폼을 통해 컨테이너를 동작하며 실제 서비스 제어

 

  1. 환경 구성

  • control plane 1대, worker node 2대 를 Azure 가상머신으로 준비

image-20250701-041333.png

 

  • VM 생성 정보

구분

구분

구독

Virtual Studio Enterprise - 구독 MPN

리소스 그룹

RG-ContainerTest-KGE

Region

Korea Central

VM 이름

Control Plane : svr-control-plane

Worker Node : svr-worker01, svr-worker02

VM 이미지

Ubuntu Server 22.04 LTS - x64 Gen2

VM 크기

Standard_D2s_v3 - (2 vcpu, 8GiB 메모리)

VNet 정보

Vnet : VNet-MGMT (10.0.0.0/16)

Subnet : default(10.0.0.0/24)

IP 정보

svr-control-plane (20.194.10.132 / 10.0.0.4)

svr-worker01 (40.82.128.73 / 10.0.0.7)

svr-worker02 (20.196.136.72 / 10.0.0.8)

 

  • 실습 구성

image-20250701-052351.png

 

3. 설치 진행

3-1 설치 전 환경설정

Docker Install

  • Control Plane, Worker Node에 Docker 를 모두 설치

  • 하기 매뉴얼대로 진행

김가은-3 | Docker Install on VM(Ubuntu 22.04)

image-20250701-062530.png

쿠버네티스에서 Docker 설치해도 됨. 단, kubeadm에서 쓰려면 CRI-Dockerd도 함께 설정해야 함.
따라서 실무나 신규 설치에서는 Docker Engine대신 containerd를 쓰는 게 더 권장

 

Disable Memory Swap

kubelet을 설치하기 위해서는 모든 VM의 스왑 메모리를 Disable 전환해주어야 함

하지만, Azure 기본 이미지(Ubuntu 22.04/24.04 기준) 에서는 스왑을 아예 만들지 않기 때문에 그대로 진행 가능. (다른 환경이라면 아래 명령어로 비활성 진행 필요)

swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab

 

Runtime 구성 (Containerd)

# 1. 부팅 시 자동 로드할 커널 모듈 지정 cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf overlay br_netfilter EOF # 2. 모듈 즉시 적용 sudo modprobe overlay sudo modprobe br_netfilter # 3. 네트워크 관련 sysctl 파라미터 설정 (재부팅 시에도 유지됨) cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF # 4. 설정 적용 sudo sysctl --system

 

  • containerd 설치 및 설정

# 1. containerd 설치 sudo apt-get update sudo apt-get install -y containerd # 2. 기본 config.toml 생성 sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml # 3. Systemd cgroup 드라이버 사용 설정 (SystemdCgroup = true 로 수정) sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml # 값이 True인지 확인 cat /etc/containerd/config.toml | grep SystemdCgroup # 4. containerd 재시작 및 부팅 시 자동 시작 설정 sudo systemctl restart containerd sudo systemctl enable containerd

 

3-2. Kubernetes 패키지 설치 (kubeadm, kubelet, kubectl)

# 필수 도구 설치 sudo apt-get install -y apt-transport-https ca-certificates curl gpg # GPG 키 저장 디렉토리 생성 sudo mkdir -p /etc/apt/keyrings # Kubernetes GPG 키 등록 (ASCII 형식 그대로 저장) curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key | \ sudo tee /etc/apt/keyrings/kubernetes-apt-keyring.gpg > /dev/null # APT 저장소 추가 echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \ https://pkgs.k8s.io/core:/stable:/v1.33/deb/ /" | \ sudo tee /etc/apt/sources.list.d/kubernetes.list # 패키지 목록 갱신 sudo apt-get update # kubelet, kubeadm, kubectl 설치 sudo apt-get install -y kubelet kubeadm kubectl # 자동 업데이트 방지 sudo apt-mark hold kubelet kubeadm kubectl # 자동 시작 systemctl enable kubelet

 

3-3. control-plane 구성

kubeadm init은 Kubernetes 클러스터의 첫 번째 control-plane 노드를 세팅하는 필수 명령

즉, 이제 이 VM을 마스터(제어 노드)로 만들고 싶다kubeadm init 수행 필수

명령어 결과, Master Node에 API, Controller Schduler, etcd, CoreDNS 가 구성되어짐

image-20250702-042306.png

 

  • 명령어 실행

kubeadm init

 

kubeadm init 실행 결과 마지막의 “kubeadm join” 관련 명령어를 아래처럼 저장해두자

cat > token.txt kubeadm join 10.0.0.4:6443 --token i2tvhu.d14ulgs9hdzzu9ww \ --discovery-token-ca-cert-hash sha256:a7363d6bf66d3faa65d102babe9752dab7d88cba467afba38548ef1ace78fe0d

root@svr-control-plane:~# kubeadm init
[init] Using Kubernetes version: v1.33.2
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action beforehand using 'kubeadm config images pull'
W0702 04:04:20.871141 7789 checks.go:846] detected that the sandbox image "registry.k8s.io/pause:3.8" of the container runtime is inconsistent with that used by kubeadm.It is recommended to use "registry.k8s.io/pause:3.10" as the CRI sandbox image.

[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local svr-control-plane] and IPs [10.96.0.1 10.0.0.4]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [localhost svr-control-plane] and IPs [10.0.0.4 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [localhost svr-control-plane] and IPs [10.0.0.4 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "super-admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests"
[kubelet-check] Waiting for a healthy kubelet at http://127.0.0.1:10248/healthz. This can take up to 4m0s
[kubelet-check] The kubelet is healthy after 1.501096764s
[control-plane-check] Waiting for healthy control plane components. This can take up to 4m0s
[control-plane-check] Checking kube-apiserver at https://10.0.0.4:6443/livez
[control-plane-check] Checking kube-controller-manager at https://127.0.0.1:10257/healthz
[control-plane-check] Checking kube-scheduler at https://127.0.0.1:10259/livez
[control-plane-check] kube-controller-manager is healthy after 9.150410869s
[control-plane-check] kube-apiserver is healthy after 10.503314527s
[control-plane-check] kube-scheduler is healthy after 10.601689886s
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node svr-control-plane as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
[mark-control-plane] Marking the node svr-control-plane as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]
[bootstrap-token] Using token: i2tvhu.d14ulgs9hdzzu9ww
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 10.0.0.4:6443 --token i2tvhu.d14ulgs9hdzzu9ww \
--discovery-token-ca-cert-hash sha256:a7363d6bf66d3faa65d102babe9752dab7d88cba467afba38548ef1ace78fe0d

 

 

 

  • 완료 후 노드 조회 명령어 실행

  • 현재 Kubernetes 클러스터에 등록된 모든 노드(Node)의 목록과 상태를 확인하는 명령어

  • Status가 NotReady인 이유? → 컨테이너 네트워크 인터페이스 (CNI) 가 설치되어있지 않아서

kubectl get nodes
image-20250702-050234.png

오류 발생한 경우 아래 참고

kubectl클러스터와 통신할 수 있는 설정 파일 (kubeconfig)을 못 찾았거나, 적절한 환경변수가 설정되지 않아서 발생하는 전형적인 현상

image-20250702-044330.png
  • 해결 1 : root가 아닌 일반 사용자 (gekim) 계정에서 명령어 실행 중인 경우

mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config

 

  • 해결 2 : root 사용자로 명령어 실행 중인 경우

echo 'export KUBECONFIG=/etc/kubernetes/admin.conf' >> /root/.bashrc source /root/.bashrc

 

 

kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml
  • 위브넷 설치 후 Status 가 NotReady → Ready로 잘 변경됨

image-20250702-085426.png

 

3-4. Worker-node 구성