이세개발
article thumbnail

뻘짓 기록

*OCI(Oracle Cloud Infrastructure) *에서 쿠버네티스클러스터를 구현하여 사용하고 있었다.
docker와 k8s 1.23 버전으로 클러스터를 구성하여 사용중에, 최신버전의 k8s를 사용해야 할 일이 생겼다.
설치를 하면서 여러 오류와 마주쳤다..

  • 어떤 이유에서인지 모르게 1.26 최신버전을 설치하면 *kube-apiserver *가 계속 꺼지는 오류 가 발생
  • 여러버전을 설치, 삭제 인스턴트 초기화 등을 반복하며 여러 방법으로 설치를 실행 및 반복
  • k8s 1.23, docker 조합에서 오류가 나지 않고 정상작동 확인, 계속 설치, 삭제를 반복하며 문제는 CRI(Container Runtime Interface) 의 종류에 관련이 있는것으로 확정.
  • 범용적으로 많이 사용하는 containerd 에서 arm arch를 지원하는것을 확인, containerd를 사용해서 어떻게든 k8s 설치를 해보려고 많은것을 시도.

며칠동안의 사투 끝에 ARM 환경에서 이전에 설치가 되지 않았던 최신버전을 설치완료하였다.

containerd 설치


containerd는 컨테이너 런타임으로, 컨테이너의 생명주기를 관리하는 역할을 합니다. 이는 이미지 관리, 컨테이너 실행, 태스크 관리, 네트워크 관리 등을 포함합니다.

containerdCloud Native Computing Foundation (CNCF)에서 관리하며, Kubernetes와 같은 다른 CNCF 프로젝트와 잘 통합됩니다.

ubuntu

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
  • apt-transport-https: HTTPS를 통해 패키지를 다운로드할 수 있게해줌
  • ca-certificates: SSL/TLS 연결을 위한 CA(인증 기관) 인증서를 설치합니다. 시스템이 SSL/TLS를 통해 안전하게 통신할 수 있게 해줌
  • software-properties-common: 소프트웨어 저장소를 추가하고 관리하는 데 필요한 스크립트를 제공합니다. 이는 add-apt-repository와 같은 명령을 사용할 수 있게 해줌

Docker GPG 키를 추가

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

Docker 저장소 추가

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

containerd.io 패키지 설치

sudo apt-get update
sudo apt-get install -y containerd.io

containerd 서비스를 시작

sudo systemctl start containerd

containerd가 제대로 작동하는지 확인

sudo systemctl status containerd

이 명령은 containerd 서비스의 상태를 출력합니다. 서비스가 활성 상태인 경우, 설치가 제대로 완료된 것

자동으로 ARM architecture를 인식해서 설치가 되었다.

sudo dpkg -l | grep containerd

다른 환경일때, apt 사용하지 않고 직접 설치
containerd 공식문서

containerd 사용해보기

ctr는 containerd 데몬과 상호작용하기 위한 디버그 및 관리 클라이언트이다. 이는 containerd를 제어하고 모니터링하는 데 사용된다.

  1. 컨테이너 생성 및 실행: alpine 이미지를 기반으로 새 컨테이너를 생성 및 실행
  2. ctr run --rm docker.io/library/alpine:latest hello-world
  3. 이미지 관리: 모든 로컬 이미지를 나열
  4. ctr images ls
  5. 컨테이너 관리: 모든 실행 중인 컨테이너를 나열
  6. ctr containers ls
  7. 플러그인 관리: 모든 플러그인을 나열
  8. ctr plugins ls

K8S 설치

k8s 클러스터에서 사용할 CRI(Container Runtime Interface) 를 설치 하였으니 k8s 설치로 들어간다.
(ubuntu) . 다른 os여도 대부분의 순서는 같다.

  • 방화벽 설정에서 오류가 날 수 있다.

호스트명 변경

호스트명을 변경하려면 /etc/cloud/cloud.cfg 파일을 열고preserve_hostname 값을 true로 변경

## 현재 호스트명
hostnamectl status

## (use-hostname) 사용할 호스트이름
sudo hostnamectl set-hostname (use-hostname)

메모리 스왑 비활성화

kubelet이 스왑을 사용할때에 swap memory를 많이 고려하지 않고 제작되었음

  • 안정성, 일관적인 컨테이너 성능 면에서 비활성화를 해주어야 한다.
    sudo swapoff -a && sudo sed -i '/swap/s/^/#/' /etc/fstab
    
### **필요한 모듈 로드**

모듈 로드

sudo modprobe br_netfilter

커널 모듈을 지정

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

커널에서 브리지에 묶여있는 Traffic들이 iptable을 바라보도록 설정

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

설정 확인

sudo sysctl --system

   그리고 `sudo reboot` 명령을 실행하여 시스템을 재부팅(~~안해도 되는것 같기는 함~~)

> br_netfilter :  k8s가 네트워크 트래픽을 제어하는 기능 제공
/etc/modules-load.d/k8s.conf : 시스템 부팅 시 로드할 커널 모듈을 지정
/etc/sysctl.d/: 적용할 커널 파라미터를 정의하는 설정 파일들을 저장하는 곳

### 방화벽 해제
이 예제에서는 그냥 꺼버렸지만 상황에 맞게 방화벽을 조절한다.

sudo systemctl stop firewalld
sudo systemctl disable firewalld

포트 확인 : 연결 실패 또는 타임아웃 되어야 정상

telnet: Unable to connect to remote host: Connection refused

sudo telnet 127.0.0.1 6443


### **kubeadm 설치**
kubelet kubeadm kubectl 을 설치한다.

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/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-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

--- 
여기부터는 controlplan node 와  worker node 따로

**control-plane**
### **클러스터 초기화**

kubeadm을 사용하여 클러스터를 초기화
CNI 플러그인으로는 kube-flannel을 사용하기위해 `pod-network-cidr`은 kube-flannel에서 제공하는 기본값을 사용

sudo kubeadm init --pod-network-cidr=10.244.0.0/16

kubeadm init --apiserver-advertise-address 10.0.0.108 --apiserver-cert-extra-sans 10.0.0.108 --pod-network-cidr=10.244.0.0/16

만약 `unknown service runtime.v1alpha2.RuntimeService`와 같은 오류가 발생하면, 컨테이너 런타임에서 CRI 기능을 비활성화 한 경우이므로 둘중에 하나 추가 작업을 진행
#### option 1

sudo vi /etc/containerd/config.toml

`disabled_plugins = ["cri"]` 줄을 주석 처리
#### option 2

sudo rm /etc/containerd/config.toml

명령을 실행하여 파일 삭제

이후
`sudo systemctl restart containerd.service` 명령을 실행하여 컨테이너 서비스를 재시작

이 과정을 완료하면 클러스터 초기화가 완료되고, _**콘솔에 표시되는 join 명령어를 복사**_

### CNI 설치 ( flannel )

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

Needs manual creation of namespace to avoid helm error

kubectl create ns kube-flannel
kubectl label --overwrite ns kube-flannel pod-security.kubernetes.io/enforce=privileged

helm repo add flannel https://flannel-io.github.io/flannel/
helm install flannel --set podCidr="10.244.0.0/16" --namespace kube-flannel flannel/flannel

cni 플러그인 설치 (arm은 amd arm 변경)

mkdir -p /opt/cni/bin
curl -O -L https://github.com/containernetworking/plugins/releases/download/v1.2.0/cni-plugins-linux-amd64-v1.2.0.tgz
sudo tar -C /opt/cni/bin -xzf cni-plugins-linux-amd64-v1.2.0.tgz

삭제

kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml


Deploying Flannel with helm
#### Needs manual creation of namespace to avoid helm error

kubectl create ns kube-flannel
kubectl label --overwrite ns kube-flannel pod-security.kubernetes.io/enforce=privileged

helm repo add flannel https://flannel-io.github.io/flannel/
helm install flannel --set podCidr="10.244.0.0/16" --namespace kube-flannel flannel/flannel

https://github.com/flannel-io/flannel

### 설치 확인

node ready 인지 확인

kubectl get nodes

모든 리소스 출력

kubectl get all -A

![](https://velog.velcdn.com/images/tkfka/post/88a5d1fa-0c2a-4aff-9a71-c04aceb13de8/image.png)



---
**worker node**

**cni 플러그인 설치 (arm은 amd arm 변경)**

mkdir -p /opt/cni/bin
curl -O -L https://github.com/containernetworking/plugins/releases/download/v1.2.0/cni-plugins-linux-amd64-v1.2.0.tgz
sudo tar -C /opt/cni/bin -xzf cni-plugins-linux-amd64-v1.2.0.tgz


control-plane 초기화 후 나왔던 _**콘솔에 표시되는 join 명령어를 붙여 넣는다.**_

#### join 명령어 만들기

token 값 확인

kubeadm token list

hash 값 추출

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

node ip 알기

kubectl get nodes -o wide

클러스터 join

sudo kubeadm join --token --discovery-token-ca-cert-hash sha256:


#### **troubleshoot** option 1

sudo vi /etc/containerd/config.toml

`disabled_plugins = ["cri"]` 줄을 주석 처리
#### **troubleshoot** option 2

sudo rm /etc/containerd/config.toml


이후
`sudo systemctl restart containerd.service`

---
### 설치 확인
node ready 인지 확인
`kubectl get nodes`
모든 리소스 출력
`kubectl get all -A`
nginx 실행 및 80포트
`kubectl run nginx --image=nginx --port=80`

![](https://velog.velcdn.com/images/tkfka/post/acf08edb-7a5f-4a6a-8a2f-1b102c0c29ff/image.png)


# troubleshoot

### api 서버가 계속 꺼졋다 켜졌다하는 문제
#### containerd 의 서비스를 시작했을때의 아키텍쳐별 차이 (양쪽 apt-get install containerd.io 으로 설치했을 때)

sudo dpkg -l | grep containerd


![](https://velog.velcdn.com/images/tkfka/post/7dd64bad-a41a-4b86-a8b4-02403e864de5/image.png)

![](https://velog.velcdn.com/images/tkfka/post/cf81c433-10e4-48d0-811c-22c7141bedf9/image.png)
서비스를 보았을 때 amd64에서는 containerd
daemon to control runC 가 있고, arm64은 없는 차이를 보였다.
> containerd가 runC를 제어하는 데몬 형태로 동작하며, 이를 통해 컨테이너의 생명 주기를 관리한다는 것을 의미합니다. 이는 containerd가 runC 인스턴스를 생성하고, 이를 통해 컨테이너를 실행하며, 필요에 따라 이를 중지하거나 삭제하는 역할을 수행한다는 것을 의미

이유를 자세히 알아보지는 못했지만
위의 이유로 ARM64에서 api 서버가 계속 꺼졋다 켜졌다하는 문제가 발생하는듯 싶다.
#Cgroup, #Systemd, #SystemdCgroup, #SystemdCgroup, #Cgroupfs, #Cgroup Driver
와 관련이 있는것 같다.

### 해결법

SystemdCgroup을 사용하게 바꾸기

mkdir -p /etc/containerd

containerd config default | tee /etc/containerd/config.toml

sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

systemctl restart containerd


https://discuss.kubernetes.io/t/apiserver-liveness-and-readiness-probes-fail-randomly-with-code-500/20719/2

혹은 공식문서에 설명된 대로 아키텍쳐를 주의하여 하나씩 받아가면서 설치하는 방법을 사용하면 될 것으로 보인다.


**`ip_forward`를 활성화**

sudo sysctl -w net.ipv4.ip_forward=1


이 명령은 `ip_forward` 값을 1로 설정합니다. `-w` 옵션은 설정을 즉시 적용하라는 의미

그러나 이 변경은 재부팅 후에는 사라집니다. 따라서 이 설정을 영구적으로 유지하려면 `/etc/sysctl.conf` 파일에 다음과 같은 줄을 추가

net.ipv4.ip_forward = 1

```

이렇게 하면 시스템이 재부팅될 때마다 ip_forward가 자동으로 활성

'Infra > Kubernetes' 카테고리의 다른 글

쿠버네티스 01-02 Pod_label  (0) 2023.09.06
쿠버네티스 01-01 Pod  (0) 2023.09.06
Helm 설치 및 사용  (0) 2023.09.05
WARNING: Kubernetes configuration admin.conf  (0) 2023.09.04
Kubernetes Dashboard with helm  (0) 2023.09.04
profile

이세개발

@print(name)

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