IT 정보/쿠버네티스

Ubuntu 22.04에서 쿠버네티스(Kubernetes)부터 대시보드까지 설치하기

린아저씨 2024. 5. 10. 15:44

1. 환경 설정


1-1. overlay 파일시스템 모듈과 br_netfilter 모듈 로드

overlaybr_netfilter 커널 모듈을 활성화하는 이유는 쿠버네티스가 컨테이너 관리 및 네트워킹을 효과적으로 수행할 수 있도록 해주기 위해서이다. 각 모듈의 역할은 다음과 같다.

  • overlay(overlayfs) : overlayfs는 여러 개의 파일 시스템을 겹쳐서 하나처럼 보이게 하는 유닉스 파일 시스템의 유형 중 하나이다. 쿠버네티스에서는 다음과 같은 목적으로 overlayfs를 사용한다.
    • 효율적인 이미지 저장 및 관리: 컨테이너는 이미지를 기반으로 실행된다. 이 이미지들은 다양한 레이어로 구성되어 있으며, overlayfs는 이 레이어들을 효율적으로 관리하고 저장공간을 절약할 수 있도록 돕는다. 여러 컨테이너가 동일한 이미지 레이어를 공유할 수 있으므로, 중복을 방지하고 저장 공간을 최적화 할 수 있다.
    • 빠른 컨테이너 시작: 컨테이너를 시작할 때, 기존 이미지 레이어 위에 새로운 쓰기 가능한 레이어를 추가하기만 하면 된다. 이 과정이 매우 빠르기 때문에 컨테이너의 시작 시간이 대폭 줄일 수 있다
  • .br_netfilter : br_netfilter 모듈은 리눅스 브리지와 네트워크 필터링 기능을 연결한다. 이 모듈이 쿠버네티스에서 중요한 이유는 다음과 같다.
    • 네트워크 트래픽 관리: 이 모듈은 리눅스 브리지를 통과하는 트래픽에 대한 IP 테이블 룰을 적용할 수 있게 해준다. 이를 통해 특정 트래픽을 차단하거나 특정 포트로만 트래픽을 허용하는 등의 정교한 네트워크 트래픽 관리가 가능해진다.
    • 네트워크 보안 강화: 컨테이너 간의 격리와 보안을 강화한다. 컨테이너가 동일한 물리적 호스트 또는 가상 머신 상에서 실행되더라도, br_netfilter 설정을 통해 각 컨테이너의 네트워크 통신을 세밀하게 제어할 수 있다.
    • 컨테이너 네트워크 인터페이스(CNI) 플러그인과의 호환성: 많은 CNI 플러그인들이 br_netfilter의 기능을 활용하여 네트워크 정책을 구현한다. 쿠버네티스 네트워크 정책은 이 모듈을 사용하여 네트워크 트래픽을 조정하고 각 컨테이너 또는 서비스의 접근을 제어한다.
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter

 

 

1-2. IPv4 / IPv6를 포워딩하여 iptables가 브리디된 트래픽을 처리할 수 있도록 활성화

  • net.bridge.bridge-nf-call-iptables  = 1 : 리눅스 브릿지가 iptables를 통한 IPv4 트래픽 처리를 할 수 있도록 활성화한다. 즉, 브리지를 통과하는 모든 ip 패킷이 iptables의 규칙에 의해 필터링 된다. 투버네티스는 이 기능을 사용하여 네트워크 정책을 통한 트래픽 제어와 각 파드(POD)간의 격리를 구현한다.

  • net.bridge.bridge-nf-call-ip6tables = 1 : IPv6 트래픽에 대해서도 브리지를 통과하는 패킷이 ip6tables의 규칙에 따라 처리되도록 한다. IPv6를 사용하는 환경에서는 이 설정이 필수적이다. 쿠버네티스가 IPv6를 지원하기 때문에, IPv6 네트워킹을 사용하는 경우에 이 설정을 반드시 활성화해야 한다.

  • net.ipv4.ip_forward = 1 : 호스트에서 IPv4 패킷 포워딩을 활성화한다. 즉, 쿠버네티스 노드가 네트워크 라우터처럼 작동하여 다른 노드나 포드로 트래픽을 전달할 수 있게 해준다. 이 설정은 포드 간 통신 뿐만 아니라 외부 네트워크와의 통신에도 필요하다. 클러스터 내 다른 노드나 포드에 도달해야 하는 트래픽을 적절히 라우팅하는 데 중요한 역할을 한다.
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF
# 재부팅하지 않고 sysctl 파라미터 적용하기
sudo sysctl --system
 
 

2. 컨테이너 런타임 설치(containerd)


step 1: `containerd.io` 설치

1. Index of linux/ubuntu/dists/로 이동
2. 리스트 중 Ubuntu 버전 선택(22.04의 경우 jammy)
3. pool/stable/에서 OS 아키텍쳐 선택(`amd64`)
4. containerd.io_<version>_<arch>.deb 다운로드
5. containerd.io 설치

sudo dpkg -i ./containerd.io_<version>_<arch>.deb 

 

step 2: `systemd` cgroup 드라이버 환경 설정(CRI 활성화)

systemd cgroup 드라이버를 runc에서 사용하려면, /etc/containerd/config.toml를 다음과 같이 설정해야 한다.

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/ SystemdCgroup = false/ SystemdCgroup = true/' /etc/containerd/config.toml
 
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  .....
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true
 
SystemdCgroup이 false 일 경우 cgroup 드라이버를 cgroupfs로 사용

 

systemd cgroup 드라이버를 runc로 변경하였다면, 다음과 같이 containerd를 재시작해준다.

sudo systemctl restart containerd
 

step 3: CNI plugin 설치

CNI_PLUGINS_VERSION="v1.1.1"
ARCH="amd64"
DEST="/opt/cni/bin"
sudo mkdir -p "$DEST"
curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_PLUGINS_VERSION}/cni-plugins-linux-${ARCH}-${CNI_PLUGINS_VERSION}.tgz" | sudo tar -C "$DEST" -xz

 

 

3. kubeadm / kubelet / kubectl 설치


  • kubeadm : 쿠버네티스를 쉽게 bootstrap하는데 사용되는 도구이다. kubeadm의 주요 목적은 클러스터의 초기화와 관리르 단순화하는 것이다. kubeadm을 사용하면 다음과 같은 작업을 수행할 수 있다.
    • 클러스터 초기화: kubeadm init 명령을 통해 컨트롤 플레인 노드를 설정하고, 필수 구성 요소들을 설치하여 클러스터를 초기한다.
    • 노드 추가: kubeadm join 명령을 사용하여 새로운 워커 노드를 클러스터에 추가할 수 있다.
    • 클러스터 업그레이드: 클러스터의 쿠버네티스 버전을 업그레이드하는 기능을 제공한다.
    • 클러스터 구성: 클러스터의 기본 구성을 설정하고, 네트워킹, 보안 설정, 쿠버네티스 구성 요소의 옵션을 관리할 수 있다.
  • kubelet : 각 노드에서 실행되는 에이전트로, 쿠버네티스 클러스터의 워커 노드에서 컨테이너를 관리하는 핵심 구성 요소이다. kubelet의 주된 역할은 다음과 같다.
    • 파드 관리: API 서버에서 파드에 대한 명령을 받아 해당 파드가 정의한 대로 컨테이너가 실행되고 유지되도록 합니다.
    • 자원 모니터링 및 관리: 노드의 사용 가능한 리소스(예: CPU, 메모리)를 모니터링하고, 각 파드의 자원 할당을 관리한다.
    • 상태 보고: 노드와 파드(POD)의 상태를 주기적으로 쿠버네티스 API 서버에 보고한다.
    • 자동 복구: 파드 (POD) 의 컨테이너가 실패할 경우 자동으로 재시작하여 파드의 상태를 유지한다.
  • kubectl : 쿠버네티스 클러스터와 상호 작용하기 위한 command 도구이다. 사용자와 클러스터 간의 주된 인터페이스 역할을 하며, 다양한 작업을 수행할 수 있다.
    • 리소스 관리: 파드, 서비스, 볼륨 등 쿠버네티스 리소스를 생성, 수정, 삭제한다.
    • 클러스터 모니터링: 클러스터의 상태를 조회하고, 리소스와 노드의 상태를 확인할 수 있다.
    • 디버깅 및 로그 관리: 파드의 로그를 조회하거나, 실행 중인 컨테이너로 진입하여 문제를 진단할 수 있다.
    • 자동화 스크립트: 복잡한 작업을 자동화하기 위해 쉘 스크립트 내에서 사용될 수 있다.

 

패키지 매니저(apt)를 사용해서 설치

sudo apt-get install -y apt-transport-https ca-certificates curl
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://dl.k8s.io/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update -y
sudo apt-cache madison kubelet
sudo apt install -y kubelet=1.27.6-00 kubeadm=1.27.6-00 kubectl=1.27.6-00
sudo apt-mark hold kubelet kubeadm kubectl

 

 

 

4. 쿠버네티스 클러스터 생성


클러스터 초기화는 kubeadm init 명령어를 사용하면 된다.

sudo kubeadm init --pod-network-cidr=10.1.0.0/16 --apiserver-advertise-address 192.168.235.101

 

  • --pod-network-cidr : 쿠버네티스 클러스터 내의 파드(POD) 네트워크에 대한 CIDR 범위를 지정한다. CIDR (Classless Inter-Domain Routing) 표기는 IP 주소 할당 및 라우팅을 위해 사용됩니다. 10.1.0.0/16에서 /16은 네트워크에 속하는 IP 주소가 약 65,536개임을 의미합니다. 이 범위는 포드 간에 할당될 IP 주소를 정의하며, 파드(POD) 네트워킹을 위한 CNI(컨테이너 네트워크 인터페이스) 플러그인이 이 정보를 사용하여 네트워크를 구성한다.

  • --apiserver-advertise-address : API 서버가 자신의 서비스를 광고하는 데 사용할 IP 주소를 지정한다. 일반적으로 이는 클러스터 내의 다른 노드나 외부 클라이언트가 API 서버에 접속할 때 사용하는 주소이다. 이 주소는 컨트롤 플레인의 주소를 넣어주면 된다.

 

kubeadm init은 컨트롤 플레인 노드(master)에서만 실행해주면 된다. 

정상적으로 클러스터 구성 및 초기화가 완료될 경우 다음과 같은 메시지가 표시된다.

sudo kubeadm join 192.168.235.101:6443 --token pxx1uy.w4nsqjetbvxflvs6 \
        --discovery-token-ca-cert-hash sha256:aaa0785ee73362d703632453e3cffe068db5a8c9e4a05d5ebe9ad70d4d3b4871
		
		
=============================================================

To access Dashboard run:
  kubectl -n kubernetes-dashboard port-forward svc/kubernetes-dashboard-kong-proxy 8443:443 --address 0.0.0.0

NOTE: In case port-forward command does not work, make sure that kong service name is correct.
      Check the services in Kubernetes Dashboard namespace using:
        kubectl -n kubernetes-dashboard get svc

Dashboard will be available at:
  https://localhost:8443

==============================================================

 

이때 가장 윗줄의 kubeadm join 명령어에 포함되어 있는 토큰은 추후 워커 노드를 추가하기 위해 필요하므로 별도로 저장해 놓은 것이 좋다.

 

 

5. CNI Plugin 설치(Calico)


CNU Plugin으로 Calico를 설치해준다. calico는 tigera-operator를 이용하여 설치하는 방법과 단일 manifests를 사용하여 설치하는 방법이 있다. 여기서는 tigera-operator를 이용하여 설치한다.

 

설치를 위해 두개의 manifests 파일을 받아준다.

wget https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/tigera-operator.yaml
wget https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/custom-resources.yaml

 

그리고 cusom-resource.yaml 파일을 열어 cidr을 클러스터 init에 사용했던 cidr로 수정해 준다.

# 아래와 같이 registry 추가 및 cidr 수정

apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  # Configures Calico networking.
  calicoNetwork:
    # Note: The ipPools section cannot be modified post-install.
    ipPools:
    - blockSize: 26
#      cidr: 192.168.0.0/16
      cidr: 10.1.0.0/16
      encapsulation: VXLANCrossSubnet
      natOutgoing: Enabled
      nodeSelector: all()

 

두개의 mainifests 파일을 이용하여 파드(POD)를 생성해준다.

kubectl create -f tigera-operator.yaml
kubectl create -f custom-resources.yaml

 

CNI Plugin까지 설치가 완료되었다면, 컨트롤 플레인 노드에서도 파드(POD)를 생성할 수 있도록 Untainted 해준다.

kubectl taint nodes --all node-role.kubernetes.io/control-plane-

 

 

6. 쿠버네티스 대시보드(Dashboard) 설치


kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

# 로그인 생략 옵션 추가
kubectl patch deployment kubernetes-dashboard -n kubernetes-dashboard --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--enable-skip-login"}]'

k apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard2
  labels:
    k8s-app: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
EOF

 

* 쿠버네티스 대시보드 7.x 버전부터는 helm을 이용한 설치방법을 권고한다.

 

대시보드에서 metrics 정보를 표시하기 위해 metrics server를 설치한다.

kubectl create -f https://raw.githubusercontent.com/k8s-1pro/install/main/ground/k8s-1.27/metrics-server-0.6.3/metrics-server.yaml

 

쿠버네티스 대시보드는 기본적으로 대시보드가 설치한 장비에서 밖에 접속이 안되기 때문에, 다른 장비에서 접속하기 위해서는 포트포워딩을 해주어야한다.

kubectl -n kubernetes-dashboard port-forward svc/kubernetes-dashboard-kong-proxy 8443:443 --address 0.0.0.0

 

이렇게 포트포워딩을 해주면 대시보드가 실행되는 장비가 아닌 장비에서도 접근할 수 있다.