주녁, DevNote
article thumbnail

개요

On-premise에서 kubernetes(= k8s) 환경을 직접 구성해보며 학습하는 Hands On 시리즈입니다. 

목표

  • On-premise 환경에서 Linux 위에 Kubernetes 클러스터 환경 구성
    • Linux CentOS 7.x
    • Kubernetes 1.25.5
    • CRI : CRI-O 1.19
    • CNI : Calico 3.25
    • Master 1대, Worker 5대 → Worker에만 GPU 설치

여정

공통 - 마스터 & 워커

CRI-O 설치 (CRI-O Docs | CRI-O 기반 쿠버네티스 설치)

 

1.24.0부터 Dockershim이 제거가 되었다. (참고 : 흔들리는 도커(Docker)의 위상 - OCI와 CRI)

때문에, Container를 실행할 런타임 인터페이스 CRI가 필요하다.

 

CRI의 종류에는 CRI-O, Containerd 등이 있다. → CRI-O로 설치를 진행한다.

다른 CRI를 설치는 다음 공식문서(컨테이너 런타임 종류별 설치방법)를 참고하면 된다.

CRI-O를 선택한 이유?
CRI-O를 사용하는 이유는 실행에 필요한 최소한의 기능만을 포함하기 때문이다.
컨테이너 이미지 빌드 기능은 여전히 Docker를 사용가능하다.

반면, Containerd를 사용하지 않는 이유는 Docker 내장형 Containerd와 같은 설정을 공유하기 때문에
Containerd를 단독으로 따로 설치하기 어렵다고 생각했다.
# 부팅 시 모듈 시작 설정
cat <<EOF | sudo tee /etc/modules-load.d/crio.conf
overlay
br_netfilter
EOF

# 모듈 적재
sudo modprobe overlay
sudo modprobe br_netfilter

# sysctl 매개 변수 설정 (재부팅 후 유지 용도)
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

sudo sysctl --system
# 환경변수 설정
OS=CentOS_7
VERSION=1.19

# 원격 저장소에서 파일 다운로드
sudo curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/devel:kubic:libcontainers:stable.repo
sudo curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/devel:kubic:libcontainers:stable:cri-o:$VERSION.repo

# 설치
# sudo yum install containernetworking-plugins
sudo yum -y install cri-o

# 서비스 활성화
sudo systemctl enable --now crio

k8s 설치

# k8s 도구 설치

# repo_gpgcheck=1이면 Repo 유효성 검사에서 실패할 수 있음
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF

# permissive 모드로 SELinux 설정(효과적으로 비활성화), ubuntu 20 동작 안됨
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config


sudo su # 일반 계정으로 편집 불가한 커맨드
# iptables 커널 설정
cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

#방화벽 해제(가능하다면 특정 포트만 해제)
systemctl stop firewalld
systemctl start ntpd
systemctl enable ntpd

# swap 비활성화 (재부팅 시 다시 활성화됨)
swapoff -a
sudo sysctl --system

# --disableexcludes=kubernetes : kubernetes 특정버전 패키지를 설치하기 위한 옵션
sudo yum install -y kubelet-1.25.5 kubeadm-1.25.5 kubectl-1.25.5 --disableexcludes=kubernetes

# 설치 버전 고정
sudo yum -y install yum-versionlock
sudo yum versionlock add kubelet kubeadm kubectl

# 쿠버네티스 시작
sudo systemctl enable --now kubelet

설정 적용

# 재부팅
reboot

swapoff -a
sudo sysctl -a

sudo systemctl enable --now crio
sudo systemctl enable --now kubelet

마스터 노드

k8s 클러스터 구성

# 마스터 노드 초기화
sudo kubeadm init --pod-network-cidr=192.168.0.0/16 

# 종료 시, 이 노드에 조인 할 수 있는 토큰값을 포함한 kubeadm 명령어가 노출된다.
# ex) kubeadm join IP:PORT --token ${value} --discovery-token-ca-cert-hash sha256:${value}

# 초기화 이후 설정
# root 유저라면 
export KUBECONFIG=/etc/kubernetes/admin.conf

# root 유저가 아니라면
# 유저별 환경설정 등록
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Calico 설치

# Calico Operator 생성
sudo kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/tigera-operator.yaml

# Calico Resource 생성
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/custom-resources.yaml
# Calico 설치 완료 확인
# 모든 상태가 Ready가 되면 정상
# 1분 가량 소요되므로 기다려보자 (종료 : Ctrl + C)
watch kubectl get pods -n calico-system
노드의 상태가 NotReady, Pending에서 1분 이상 변하지 않는다면?
1. kubelet 실행여부
2. CNI 정상 설치 여부
3. 방화벽 확인 → 항목 별 내용은 Q&A에서 확인 가능하다.
# Calico 전용 ctl 설치
cd /usr/local/bin
sudo curl -L https://github.com/projectcalico/calico/releases/download/v3.23.3/calicoctl-linux-amd64 -o calicoctl
sudo chmod +x calicoctl

# BGP Protocol Check
sudo calicoctl node status

# Node Endpoint Check
calicoctl get workloadendpoint -A

워커 노드

Join 명령어 실행

master에서 생성된 join 명령어를 복사한 뒤, 아래 옵션 두 줄을 추가하면 된다.

# master에서 생성된 join 명령어 실행
# cri-socket 옵션 : CRI 구현체를 지정하는 옵션
# ignore-preflight-errors : 사전 작업에서 발생하는 기타에러 무시
sudo kubeadm join IP:PORT --token ${value} --discovery-token-ca-cert-hash sha256:${value}
--cri-socket="var/run/crio/crio.sock" \
--ignore-preflight-errors=cri

Q & A

  • Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? (도커 실행 시 에러) 
더보기

Cannot Connect to a Docker Daemon | Baeldung

docker daemon이 실행되지 않아 발생하는 에러입니다.

아래 코드로 docker daemon을 재시작할 수 있습니다

rm -f /var/run/docker.pid # 비정상 종료된 도커 pid 파일 삭제
sudo service docker start
sudo dockerd
  • 노드의 상태를 조회하면 Status가 NotReady로 나옵니다
더보기
# NotReady인 워커노드에서 active 상태인지 확인
sudo systemctl status kubelet

# inactive라면 kubelet 재시작
sudo restart kubelet
  • No package kubelet-1.25.0 available. (k8s 설치 중 에러)
더보기

yum repogitory가 업데이트 되지 않았거나, repo의 유효성 검사를 통과하지 못했습니다.

/etc/yum.repos.d/kubernetes.repo 파일을 열어 아래 항목을 확인하세요

  1. yum repolist 명령으로 repository가 등록되어 있는지 확인
  2. repo_gpgcheck 값이 0으로 설정되어 있는지 확인
  3. baseurl의 주소가 잘못 적혀있지 않은지 확인 (직접 접속하면 페이지가 나옵니다)
  • x509: certificate signed by unknown authority (kubectl 실행 시 에러)
더보기

주로 쿠버네티스를 재설정, 초기화한 경우 인증서가 갱신되지 않아서 발생하는 문제입니다.

# 방법1 : 인증서를 새로 생성한 인증서를 복사한다
sudo cp /etc/kubernetes/admin.conf /root/.kube/config

# 방법2 : 환경변수 위치 재설정
sudo unset KUBECONFIG
sudo export KUBECONFIG=/etc/kubernetes/admin.conf
  • The connection to the server localhost:8080 was refused - did you specify the right host or port? (kubectl 실행 시 에러)
더보기
# 아래 명령어 실행 시 아래와 같은 결과가 나온다면
# config 설정이 제대로 되어있지 않은 것이다.
kubectl config view

apiVersion: v1
clusters: null
contexts: null
current-context: ""
kind: Config
preferences: {}
users: nul

쿠버네티스를 현재 유저정보가 쿠버네티스 config 파일에 반영되지 않은 경우에 발생한다.

(보통, 재설정, 초기화한 경우 인증서가 갱신되지 않아서 발생하는 문제이다.)

# 인증서를 새로 생성한 인증서를 복사한다
sudo cp /etc/kubernetes/admin.conf /root/.kube/config
  • Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused. (워커 노드 join시 에러)
더보기

kubelet이 제대로 동작하지 않을 때 발생하는 에러이다.

  • kubelet을 실행하지 않았음
  • sudo systemctl status kubelet
  • kubelet이 인터넷과 연결되지 않았음
    • NAT Gateway 설정이 되지 않았거나,
    • 방화벽이 열려있지 않거나,
    • CNI가 제대로 설치되지 않았거나
  • Found multiple CRI endpoints on the host(kubectl 실행 시 에러)
더보기

노드에서 여러개의 CRI가 존재해서 발생하는 에러이다.

클러스터 런타임을 1개만 남기거나 or 클러스터 구성시에 cri-socket을 지정해주면 된다.

# 방법1. 에러 내용에 나온 sock 파일 2개중 하나를 지운다
sudo rm -f ${sock파일명}

# 방법2. cri-socket 지정
kubeadm init --apiserver-advertise-address=<api 서버 IP> --pod-network-cidr=192.168.0.0/16 --cri-socket /var/run/crio/crio.sock

마무리

다음 글에서는 이렇게 구성한 kubernetes 환경에서 간단한 application을 배포해볼 것이다.

 


참고자료

Quickstart for Calico on Kubernetes (tigera.io)

Known errors and solutions - DevOps Buzz

[Kubernetes] 깔끔하게 kubeadm reset 하기 (wookiist.dev)

[linux] 쿠버네티스 삭제 가이드.(ubuntu & centos) (tistory.com)

[kubeadm] 노드 삭제 (tistory.com)

How to Run Kubernetes with Calico | phoenixNAP KB

[kubernetes-실습] 기본 Node 의 maintenance (유지보수) - 메모하며 성장하기 (psnote.co.kr)

[Kubernetes] 쿠버네티스 설치 및 환경구성(CentOS 7.9) (tistory.com)

[Kubernetes] Calico CNI 개념 알아보기 (tistory.com)

Quickstart for Calico on Kubernetes (tigera.io) <<<

How to Run Kubernetes with Calico | phoenixNAP KB

쿠버네티스 Taint, Toleration 정리 (sarc.io)

k8s Calico CNI와 Calico Network Policy — 노오력을해라 (tistory.com)

[기타] CentOS 7 에 Kubernetes 기본 Install - HOSTWAY Tech Blog

Kubernetes 1.24 + cri-docker Installation ( kubeadm ) - HOSTWAY Tech Blog

Cent OS 7.x Linux Nvidia 그래픽 드라이버 설치 가이드 - [Linux] (tistory.com)

소소한 일상 및 업무TIP 다루기 :: CentOS 7 docker 설치 및 컨테이너 사용 방법 (tistory.com)

profile

주녁, DevNote

@junwork

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!