본문 바로가기
인프런/쿠버네티스 지상편-스프린트1과2

섹션4-쿠버네티스 무게감 있게 설치하는 방법 – 2번째방법

by book_lover 2024. 12. 26.

시작하기 전 확인 사항

  • 데비안 기반 배포판, 레드햇 기반 배포판, 그리고 패키지 매니저를 사용하지 않는 경우에 대한 일반적인 가이드를 제공
  • MAC 주소 및 product_uuid가 모든 노드에 대해 고유한지 확인
    • product_uuid는 sudo cat /sys/class/dmi/id/product_uuid 명령을 사용하여 확인
    • ip link 또는 ifconfig -a 명령을 사용하여 네트워크 인터페이스의 MAC 주소를 확인할 수 있다
  • 2 GB 이상의 램을 장착한 머신
  • 2 이상의 CPU
  • 포트확인(인바운드)
    • 마스터
      • 6443, 2379-2380, 10250, 10259, 10257
    • 워커
      • 10250, 30000-32767

  • 스왑의 비활성화. kubelet이 제대로 작동하게 하려면 반드시 스왑을 사용하지 않도록 설정

쿠버네티스 설치(모든 노드)

  • kubeadm 설치 전 사전 작업 : 포트 열어주던가 방화벽 해제, 스왑 비활성화
  • 컨테이너 런타임 설치
    • 사전세팅
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# 필요한 sysctl 파라미터를 설정하면, 재부팅 후에도 값이 유지된다.
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
  • cgroup 드라이버 - 쿠버네티스 설치,런타임설치할 때 똑같이 맞춰 줘야함.
    • 컨테이너 런타임과 kubelet(Kubernetes 에이전트)이 서로 다른 cgroup 드라이버를 사용할 경우, 시스템 리소스 관리를 담당하는 방식이 충돌하거나 일관성이 깨질 수 있습니다. 이는 다음과 같은 문제로 이어질 수 있습니다:
      • 리소스 관리 충돌: 두 구성 요소가 동일한 방식으로 cgroup을 관리하지 않으면, CPU, 메모리 등의 리소스 제한이 제대로 작동하지 않을 수 있습니다.
      • 성능 저하: 잘못된 리소스 할당으로 인해 컨테이너의 성능 문제가 발생할 수 있습니다.
      • 시스템 불안정: 리소스 충돌이 누적되면, 노드가 다운되거나 클러스터가 불안정해질 수 있습니다.
    • Kubernetes와 런타임의 cgroup 드라이버 설정
      • cgroupfs: 기본적으로 Linux cgroup 파일 시스템을 직접 사용하는 방식.
      • systemd: systemd 서비스 매니저를 통해 cgroup을 관리하는 방식.
      Kubernetes는 기본적으로 kubelet과 런타임 모두 cgroupfs 또는 systemd 중 하나를 선택해야 합
    • 주요 cgroup 드라이버는 다음 두 가지가 있습니다
      • cgroupfs: 기본적으로 Linux cgroup 파일 시스템을 직접 사용하는 방식.
      • systemd: systemd 서비스 매니저를 통해 cgroup을 관리하는 방식.
    • Kubernetes 권장 설정
      • Kubernetes는 기본적으로 systemd 드라이버를 권장합니다. 이는 systemd가 현대 Linux 배포판에서 기본적으로 사용되며, 더 나은 통합성과 안정성을 제공하기 때문
      • 특히 kubelet이 systemd를 사용하는 경우 런타임도 같은 드라이버(systemd)를 사용하도록 설정
    • cgroup 드라이버 확인 및 설정 방법
      • Container Runtime(Docker/Containerd 등):
    • (1) 현재 cgroup 드라이버 확인
docker info | grep -i cgroup
or
crictl info | grep -i cgroup
  • kublet
cat /var/lib/kubelet/config.yaml | grep -i cgroupDriver

설정 방법

  • Container Runtime: 런타임 설정 파일에서 cgroup 드라이버를 지정합니다.
    • Docker의 경우 /etc/docker/daemon.json에서 설정
    • Containerd의 경우 /etc/containerd/config.toml에서 설정
    • kubelet: /var/lib/kubelet/config.yaml에서 설정:

containerd 설치

https://github.com/containerd/containerd/blob/main/docs/getting-started.md

 

containerd/docs/getting-started.md at main · containerd/containerd

An open and reliable container runtime. Contribute to containerd/containerd development by creating an account on GitHub.

github.com

Option 2: From apt-get or dnf

요약

  • rocky linux 기본 설정 : 패키지 업데이트, 타임존 설정
  • kubeadm 설치 전 사전작업 : 방화벽 해제, 스왑 비활성화
  • 컨테이너 런타임 설치
    • 컨테이너 런타임 설치 전 사전작업 : iptables 세팅
    • 컨테이너 런타임 (containerd 설치)
      • containerd 패키지 설치 (option2)
        • docker engine 설치 : repo 설정, containerd 설치
    •   컨테이너 런타임 : cri 활성화
  •  kubeadm 설치 : repo 설정, SELinux 설정 kubelet, kubeadm, kubectl 패키지 설치

마스터 노드 세팅

  • kubeadm으로 클러스터 생성
    • 클러스터 초기화 (Pod Network 세팅)
    • kubectl 사용 설정
    • CNI Plugin 설치 (calico)
    • Master에 Pod를 생성 할수 있도록 설정 
  • 쿠버네티스 편의 기능 설치
    • kubectl 자동완성 기능
    • Dashboard 설치
    • Metrics Server 설치

 

#패키지 업데이트 및 타임존 설정
sudo yum update -y
sudo timedatectl set-timezone Asia/Seoul
timedatectl

#마스터 포트
sudo firewall-cmd --zone=public --add-port=6443/tcp --permanent
sudo firewall-cmd --zone=public --add-port=2379-2380/tcp --permanent
sudo firewall-cmd --zone=public --add-port=10250/tcp --permanent
sudo firewall-cmd --zone=public --add-port=10251/tcp --permanent
sudo firewall-cmd --zone=public --add-port=10252/tcp --permanent
sudo firewall-cmd --reload


#워커 노드 포트
sudo firewall-cmd --zone=public --add-port=10250/tcp --permanent
sudo firewall-cmd --zone=public --add-port=30000-32767/tcp --permanent
sudo firewall-cmd --reload

# 방화벽 설정 확인
sudo firewall-cmd --list-all

# 편하게 할려면 방화벽을 끄면 됨
sudo systemctl stop firewalld
sudo systemctl disable firewalld

# Swap 비활성화
sudo swapoff -a
sudo sed -i '/swap/d' /etc/fstab

# iptables 설정
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
sudo modprobe br_netfilter

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

# SELinux 비활성화
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

containerd 기본설정파일 만들기

sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml

마스터 노드 pod 생성 설정

# 1. 마스터 노드의 Taint 제거
kubectl taint nodes <마스터_노드_이름> node-role.kubernetes.io/master:NoSchedule-

# 2. 모든 마스터 노드에서 Taint 제거 (선택)
# 주석을 제거하고 실행하면 클러스터 내 모든 마스터 노드에서 Taint를 제거합니다.
# kubectl taint nodes --all node-role.kubernetes.io/master:NoSchedule-

# 3. 설정 확인
kubectl describe node <마스터_노드_이름> | grep Taints

# 4. 테스트용 Pod 생성 (nginx 이미지 사용)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: test-container
    image: nginx
EOF

# 5. Pod 생성 확인
kubectl get pods -o wide

저장소

https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/change-package-repository/

 

Changing The Kubernetes Package Repository

This page explains how to enable a package repository for the desired Kubernetes minor release upon upgrading a cluster. This is only needed for users of the community-owned package repositories hosted at pkgs.k8s.io. Unlike the legacy package repositories

kubernetes.io

[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.32/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.32/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni

설치

sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

sudo systemctl enable --now kubelet

calico 설치

https://docs.tigera.io/calico/latest/getting-started/kubernetes/quickstart

 

Quickstart for Calico on Kubernetes | Calico Documentation

Install Calico on a single-host Kubernetes cluster for testing or development in under 15 minutes.

docs.tigera.io

 

sudo kubeadm init --pod-network-cidr=192.168.0.0/16
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.1/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.1/manifests/custom-resources.yaml

# Wait until each pod has the STATUS of Running.
watch kubectl get pods -n calico-system

#Remove the taints on the control plane so that you can schedule pods on it.
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
##node/<your-hostname> untainted

참고사이트

https://cafe.naver.com/kubeops/28

 

쿠버네티스 무게감 있게 설치하기 > 구간별 상태 확인 (2/2)

사실 1/2는 몸 풀기죠!? 여기서부터가 중요합니다! [4]부터 [7]까지는 쿠버네티스 기본 설치이고 모든 node(master or worker)에 동일하게 적용되고 [8]...

cafe.naver.com


[k8s, 트러블슈팅] kubelet 이 동작하지 않는 현상

https://velog.io/@sororiri/k8s-%ED%8A%B8%EB%9F%AC%EB%B8%94%EC%8A%88%ED%8C%85-kubelet-%EC%9D%B4-%EB%8F%99%EC%9E%91%ED%95%98%EC%A7%80-%EC%95%8A%EB%8A%94-%ED%98%84%EC%83%81

 

[k8s, 트러블슈팅] kubelet 이 동작하지 않는 현상

kubelet 이 active 상태가 되지 않고 멈추는 현상kebelet 은 시작 시 아래의 Config 를 Load 한다.그런데 이중 /var/lib/kubelet/config.yaml 가 존재하지 않아 Error 가 났다.https://github.com/

velog.io

  • 에러내용
    • /var/log/message에 로그를 확인하면 config.yaml이 없다고 에러 뜸.
 error: failed to load Kubelet config file /var/lib/kubelet/config.yaml, error failed to read kubelet config file \"/var/lib/kubelet/config.yaml\", error: open /var/lib/kubelet/config.yaml: no such file or directory"

 

  • kebelet 은 시작 시 아래의 Config 를 Load 한다.
# /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
===
...
Environment="...--kubeconfig=/etc/kubernetes/kubelet.conf"
...

그런데 이중 /var/lib/kubelet/config.yaml 가 존재하지 않아 Error 가 났다.
/var/lib/kubelet/config.yaml  kubeadm init 이후에나 만들어지는 것인데, 그냥 kubelet 의 역할에 대해 크게 고민하지 않고 왜 안되는 지만 찾았던 것이 나의 문제였다.

참고 사이트 : https://github.com/kubernetes/kubernetes/issues/66108#issuecomment-502265575

 

kubelet 1.11 won't start because /var/lib/kubelet/config.yaml is missing/empty on brand new install · Issue #66108 · kubernete

Is this a BUG REPORT or FEATURE REQUEST?: Uncomment only one, leave it on its own line: /kind bug /kind feature What happened: no /var/lib/kubelet/config.yaml after brand new install of kubelet 1.1...

github.com

해결

  • kubeadm init 을 통해 /var/lib/kubelet/config.yaml 이 생성


metric server 설치

https://github.com/kubernetes-sigs/metrics-server?tab=readme-ov-file

 

GitHub - kubernetes-sigs/metrics-server: Scalable and efficient source of container resource metrics for Kubernetes built-in aut

Scalable and efficient source of container resource metrics for Kubernetes built-in autoscaling pipelines. - kubernetes-sigs/metrics-server

github.com

위 사이트가서 보고 설치

Running 안될 시

# 오류시 config 수정

kubectl edit deployment metrics-server -n kube-system

# 아래와같이 없는 플래그 설정
containers:
  - args:
      - --cert-dir=/tmp
      - --secure-port=4443
      - --kubelet-preferred-address-types=InternalIP,Hostname,ExternalIP
      - --kubelet-insecure-tls
      
# 재시작
kubectl rollout restart deployment metrics-server -n kube-system

대시보드 설치

https://kubernetes.io/ko/docs/tasks/access-application-cluster/web-ui-dashboard/

 

쿠버네티스 대시보드를 배포하고 접속하기

웹 UI(쿠버네티스 대시보드)를 배포하고 접속한다.

kubernetes.io

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.6.1/aio/deploy/recommended.yaml
#type clusterIP에서 NodePort로변경
kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard


#토큰 안보일시
kubectl create serviceaccount dashboard-admin -n kubernetes-dashboard
kubectl create token dashboard-admin -n kubernetes-dashboard
kubectl create clusterrolebinding dashboard-admin-binding --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:dashboard-admin

 

앱배포테스트해보기

https://cafe.naver.com/kubeops/28

 

쿠버네티스 무게감 있게 설치하기 > 구간별 상태 확인 (2/2)

사실 1/2는 몸 풀기죠!? 여기서부터가 중요합니다! [4]부터 [7]까지는 쿠버네티스 기본 설치이고 모든 node(master or worker)에 동일하게 적용되고 [8]...

cafe.naver.com

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-1-2-2-1
spec:
  selector:
    matchLabels:
      app: '1.2.2.1'
  replicas: 2
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: '1.2.2.1'
    spec:
      containers:
        - name: app-1-2-2-1
          image: 1pro/app
          imagePullPolicy: Always
          ports:
            - name: http
              containerPort: 8080
          startupProbe:
            httpGet:
              path: "/ready"
              port: http
            failureThreshold: 20
          livenessProbe:
            httpGet:
              path: "/ready"
              port: http
          readinessProbe:
            httpGet:
              path: "/ready"
              port: http
          resources:
            requests:
              memory: "100Mi"
              cpu: "100m"
            limits:
              memory: "200Mi"
              cpu: "200m"
---
apiVersion: v1
kind: Service
metadata:
  name: app-1-2-2-1
spec:
  selector:
    app: '1.2.2.1'
  ports:
    - port: 8080
      targetPort: 8080
      nodePort: 31221
  type: NodePort
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: app-1-2-2-1
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: app-1-2-2-1
  minReplicas: 2
  maxReplicas: 4
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 40

#App에 Memory Leak 나게 하기
curl 192.168.50.101:31221/memory-leak
  • 재시작 되었고 로그를확인해보니 app-1-2-2-1-849c897b5c-5fjwb : memoryLeak is starting

#App에 부하주기 (AutoScaling 테스트)
curl 192.168.50.101:31221/cpu-load