⭕ Ubuntu 5노드 Kubernetes 클러스터 구축 매뉴얼 (v1.30 기준)
: CPU/RAM 최소 스펙
master: 2 vCPU, 2GB 이상
worker: 1 vCPU, 1GB 이상
각 워커 아이피 설정
예) vi /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity' network: version: 2 renderer: networkd ethernets: ens33: dhcp4: false addresses: - 192.168.120.201/24 routes: - to: default via: 192.168.120.1 nameservers: addresses: [8.8.8.8, 1.1.1.1] ens34: dhcp4: true
# 1. 설정 적용 sudo netplan apply # 2. 적용 확인 ip addr show ping -c 3 8.8.8.8
Ubuntu에서 UFW 방화벽 열기
sudo ufw allow 6443/tcp sudo ufw allow 2379:2380/tcp sudo ufw allow 10250/tcp sudo ufw allow 10251/tcp sudo ufw allow 10252/tcp sudo ufw reload
✅ 모든 서버는 Ubuntu Server 22.04 LTS 기준이며, 네트워크 모드는 Host-Only로 설정하는 것을 권장합니다.
⭕ 1️⃣ 모든 노드 공통 설정
# 스왑 비활성화 sudo swapoff -a sudo sed -i '/ swap / s/^/#/' /etc/fstab # 시스템 업데이트 sudo apt update -y # containerd 및 필수 패키지 설치 sudo apt install -y containerd apt-transport-https ca-certificates curl gpg # Kubernetes 저장소 키 추가 sudo mkdir -p /etc/apt/keyrings curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | \ sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \ https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /" | \ sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt update # kubeadm, kubelet, kubectl 설치 sudo apt install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl # containerd 서비스 활성화 sudo systemctl enable containerd sudo systemctl start containerd
/proc/sys/net/ipv4/ip_forward가 1로 설정
1) IP 포워딩 활성화 (즉시 적용)
sudo sysctl -w net.ipv4.ip_forward=1
2) 재부팅 후에도 유지되도록 설정
sudo sed -i '/net.ipv4.ip_forward/c\net.ipv4.ip_forward=1' /etc/sysctl.conf sudo sysctl -p
2️⃣ 마스터 노드 초기화 (192.168.120.200)
다음 명령어 실행전 아래 Kubernetes는 Pod 간 통신을 위해 IP 포워딩이 반드시 활성화 처리 할것
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
⭕마서터 노드 및 워커노드 위 명령어 실행시 다음 오류 발생시
[ERROR FileContent--proc-sys-net-ipv4-ip_forward]: /proc/sys/net/ipv4/ip_forward contents are not set to 1 [preflight] If you know what you are doing, you can make a check non-fatal with --ignore-preflight-errors=... To see the stack trace of this error execute with --v=5 or higher
이 오류 메시지는 **IP 포워딩이 비활성화되어 있어서** Kubernetes 초기화(`kubeadm init`)가 실패한 경우입니다. Kubernetes는 Pod 간 통신을 위해 **IP 포워딩이 반드시 활성화되어야** 합니다. --- ## ???? 해결 방법 ### 1️⃣ 현재 설정 확인 ```bash cat /proc/sys/net/ipv4/ip_forward ``` > 결과가 `0`이면 비활성화 상태입니다. --- ### 2️⃣ 일시적으로 IP 포워딩 활성화 ```bash sudo sysctl -w net.ipv4.ip_forward=1 ``` > 이 설정은 재부팅 시 사라집니다. --- ### 3️⃣ 영구적으로 IP 포워딩 활성화 다음 파일을 수정합니다: ```bash sudo nano /etc/sysctl.conf ``` 아래 항목을 찾아서 수정 또는 추가합니다: ``` net.ipv4.ip_forward = 1 ``` 적용 명령: ```bash sudo sysctl -p ``` --- ### 4️⃣ containerd에도 적용 확인 (선택 사항) 일부 환경에서는 containerd의 네트워크 설정이 iptables나 IP 포워딩에 영향을 줍니다. 다음 설정 파일을 확인: ```bash sudo nano /etc/containerd/config.toml ``` 아래 항목이 존재하면 다음과 같이 설정: ``` [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] SystemdCgroup = true ``` 적용 후 containerd 재시작: ```bash sudo systemctl restart containerd ``` --- ### 5️⃣ 다시 초기화 시도 ```bash sudo kubeadm reset -f sudo kubeadm init --pod-network-cidr=10.244.0.0/16 ``` --- ✅ **정상 동작 확인** ```bash cat /proc/sys/net/ipv4/ip_forward ``` > 결과가 `1`이면 설정 완료! 이제 `kubeadm init`을 다시 실행하면 정상적으로 클러스터 초기화가 진행됩니다
✅ 성공 시 마지막에 출력되는 kubeadm join ... 명령어를 복사해 두세요.
이 명령은 워커 노드에서 클러스터에 참여할 때 사용합니다.
kubeconfig 설정
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
⭕ 3️⃣ 네트워크 플러그인 설치 (flannel)
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
⭕ 대안: Calico를 사용하면 고급 네트워크 정책 제어 가능 (kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml)
Flannel이나 Calico 같은 네트워크 플러그인(Network Plugin) 은 마스터 노드에서만 한 번 설치하면 됩니다.
설치 이후, 해당 네트워크 플러그인은 마스터가 관리하는 전체 클러스터에 자동으로 적용되며,
각 워커 노드들은 kubeadm join 으로 클러스터에 합류할 때 네트워크 설정을 자동으로 상속받습니다.
✅ 정리하자면
구분설치 위치설명
Flannel마스터 1대기본 오버레이 네트워크, 간단하고 가볍습니다
Calico마스터 1대고급 네트워크 정책, 성능 및 보안 제어 강화
⚠️ 워커 노드에서는 kubectl apply -f ... 명령을 실행할 필요 없습니다.
워커는 마스터의 설정을 자동으로 받아서 통신하게 됩니다.
⭕설치 예시 (Calico 버전 선택 시)
# 마스터 노드에서만 실행 kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
적용 후 상태 확인:
kubectl get pods -n kube-system
calico-node, calico-kube-controllers 등의 Pod가 Running 상태면 정상입니다.
⭕ 추가 팁
Flannel과 Calico는 동시에 설치하면 안 됩니다. (둘 중 하나만 선택)
Calico를 쓰면 나중에 NetworkPolicy 리소스로 Pod 간 통신을 세밀하게 제어할 수 있습니다.
4️⃣ 워커 노드 4대에서 클러스터 조인
각 워커 노드(worker1~worker4)에서 아래 명령 실행:
sudo kubeadm join 192.168.120.200:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
5️⃣ 클러스터 상태 확인 (마스터에서)
kubectl get nodes
정상 출력 예시
NAME STATUS ROLES AGE VERSION master Ready control-plane 5m v1.30.0 worker1 Ready <none> 3m v1.30.0 worker2 Ready <none> 2m v1.30.0 worker3 Ready <none> 2m v1.30.0 worker4 Ready <none> 1m v1.30.0
✅ 위와 같이 나오면 클러스터 구축 완료
실전 팁
/etc/hosts 파일에 모든 노드의 IP와 호스트명을 미리 등록하세요.
마스터 노드 스냅샷을 찍어두면 클러스터가 깨져도 빠르게 복구할 수 있습니다.
Calico 네트워크 플러그인을 쓰면 보안 정책 제어에 유리합니다.
워커 노드가 많을 경우, 로드밸런서나 Ingress Controller(NGINX 등) 설정을 추가하면 운영 환경에 가깝게 실습 가능합니다.
✅ 1.오류시 Kubernetes 프로세스 초기화후 재 설치
1️⃣ 모든 Kubernetes 프로세스 정리
sudo systemctl stop kubelet sudo systemctl stop containerd docker ps # (만약 containerd 대신 docker 사용 시)
2️⃣ 기존 Kubernetes 설정 초기화
sudo kubeadm reset -f sudo rm -rf /etc/cni/net.d sudo rm -rf /var/lib/cni/ sudo rm -rf /var/lib/kubelet/* sudo rm -rf /etc/kubernetes/ sudo rm -rf /var/lib/etcd
3️⃣ 네트워크 잔여 설정 제거 (필요시)
ip link show # cni0, flannel.1 등이 있다면 제거 sudo ip link delete cni0 sudo ip link delete flannel.1
4️⃣ containerd 및 kubelet 재시작
sudo systemctl restart containerd sudo systemctl restart kubelet
5️⃣ 다시 초기화 명령 실행
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
6️⃣ 성공 시 관리자 설정 복사 (필수)
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
7️⃣ Flannel 네트워크 설치
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
요약:
에러 원인: 이전 클러스터 잔재로 포트 점유
해결 방법: kubeadm reset + /etc/kubernetes / /var/lib/etcd 삭제 후 재시작
이후 kubeadm init 재실행하면 해결됩니다.
2. 마스터 노드에서 - 다음 오류일때
root@ubuntu:/home/master# kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml error: error validating "https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml": error validating data: failed to download openapi: Get "https://192.168.120.200:6443/openapi/v2?timeout=32s": dial tcp 192.168.120.200:6443: connect: connection refused; if you choose to ignore these errors, turn validation off with --validate=false
Kubernetes 문제 해결 순서
1. kubelet 상태 확인
sudo systemctl status kubelet journalctl -xeu kubelet | tail -n 50
2. containerd와 kubelet 재시작
sudo systemctl restart containerd sudo systemctl restart kubelet
3. 필요 시 kubeadm 초기화
sudo kubeadm reset -f sudo rm -rf /etc/kubernetes/ /var/lib/etcd /var/lib/kubelet/* /etc/cni/net.d sudo kubeadm init --pod-network-cidr=10.244.0.0/16
4. 초기화 후 kubeconfig 설정
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
5. 마스터 노드에서 Flannel 설치
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
6. 상태 확인
kubectl get nodes kubectl get pods -n kube-system
3. Ubuntu 22.04 전용 스크립트 형태로 만들어서 명령어 바로 구축
1.마스터 노드
1) sudo vi K8s-master-reinstall..sh
#!/bin/bash # Kubernetes Master Node 완전 자동화 재초기화 및 재설치 스크립트 # Ubuntu/Debian 계열 기준 (Ubuntu 20.04/22.04 등) # root 권한으로 실행하세요: sudo ./k8s-master-install-complete.sh set -euo pipefail log(){ printf "%s %s\n" "$(date +'%F %T')" "$*"; } ensure_cmd(){ command -v "$1" >/dev/null 2>&1 || return 1; } ########################### # 사용자 설정 (필요 시 수정) ########################### K8S_VERSION="1.30.14" # 기본 kubeadm/kubelet/kubectl 버전(apt 저장소에서 가용한 최신 안정버전 사용 가능) DEFAULT_POD_CIDR="10.244.0.0/16" # Flannel/Calico 등에 맞춰 변경 가능 CNI_DEFAULT="calico" # 자동으로 설치할 CNI: calico | flannel | none ########################### # 사전검증 ########################### log "=== Kubernetes Master 자동 재설치 스크립트 ===" if [ "$EUID" -ne 0 ]; then log "Must run as root. Use sudo." exit 1 fi # swap off if swapon --show | grep -q '^'; then log "Disabling swap..." swapoff -a || true cp /etc/fstab /etc/fstab.bak_$(date +%s) || true sed -i.bak '/\bswap\b/s/^/#/g' /etc/fstab || true fi # sysctl for k8s log "Applying required sysctl settings" modprobe br_netfilter || true cat >/etc/sysctl.d/k8s.conf <<'EOF' net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF sysctl --system || true ########################### # 패키지 설치 ########################### install_pkgs(){ log "Checking/Installing Docker and Kubernetes packages" # Install docker if ! ensure_cmd docker; then log "Installing docker.io..." apt update -y apt install -y docker.io systemctl enable --now docker else log "docker already installed: $(docker --version 2>/dev/null || echo 'unknown')" fi # Install kubeadm,kubelet,kubectl if ! ensure_cmd kubeadm || ! ensure_cmd kubelet || ! ensure_cmd kubectl; then log "Installing kubeadm/kubelet/kubectl" apt update -y apt install -y apt-transport-https ca-certificates curl gnupg lsb-release if [ ! -f /etc/apt/trusted.gpg.d/kubernetes-apt-keyring.gpg ]; then curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-apt-keyring.gpg fi if [ ! -f /etc/apt/sources.list.d/kubernetes.list ]; then echo "deb [signed-by=/etc/apt/trusted.gpg.d/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list fi apt update -y apt install -y kubelet kubeadm kubectl apt-mark hold kubelet kubeadm kubectl else log "kubeadm/kubelet/kubectl already present: $(kubeadm version -o short 2>/dev/null || echo '')" fi } install_pkgs ########################### # 기존 구성 정리 ########################### if [ -d /etc/kubernetes ] || ensure_cmd kubeadm; then log "Resetting existing kubeadm configuration (if any)" if ensure_cmd kubeadm; then kubeadm reset -f || true fi systemctl stop kubelet || true systemctl stop docker || true else log "No existing kubeadm config detected, continuing" fi # remove dirs log "Cleaning K8s directories" rm -rf /etc/cni/net.d || true rm -rf /var/lib/cni || true rm -rf /var/lib/kubelet || true rm -rf /var/lib/etcd || true rm -rf /etc/kubernetes || true rm -rf $HOME/.kube || true ########################### # kubeadm 이미지 사전풀 ########################### if ensure_cmd kubeadm; then log "Pre-pulling kubeadm images (may fail behind restricted networks)" kubeadm config images pull || log "Image pull failed, continuing" fi ########################### # systemd 서비스 활성화 ########################### log "Enabling docker/kubelet" systemctl daemon-reload || true if ensure_cmd docker; then systemctl enable --now docker || true fi if ensure_cmd kubelet; then systemctl enable --now kubelet || true systemctl restart kubelet || true fi ########################### # kubeadm init ########################### ALREADY_MASTER=false if [ -f /etc/kubernetes/manifests/kube-apiserver.yaml ] || [ -d /etc/kubernetes/pki ]; then ALREADY_MASTER=true fi if [ "$ALREADY_MASTER" = true ]; then log "Master manifests/pki detected - skipping kubeadm init" else read -p "Initialize control-plane on this node? (y/N): " DO_INIT DO_INIT=${DO_INIT:-N} if [[ "$DO_INIT" =~ ^[Yy]$ ]]; then DEFAULT_ADDR=$(hostname -I | awk '{print $1}') read -p "API server bind IP (default: $DEFAULT_ADDR): " APISERVER_ADDR APISERVER_ADDR=${APISERVER_ADDR:-$DEFAULT_ADDR} read -p "Pod network CIDR (default: $DEFAULT_POD_CIDR): " POD_CIDR POD_CIDR=${POD_CIDR:-$DEFAULT_POD_CIDR} log "Running kubeadm init --apiserver-advertise-address=$APISERVER_ADDR --pod-network-cidr=$POD_CIDR" kubeadm init --apiserver-advertise-address=$APISERVER_ADDR --pod-network-cidr=$POD_CIDR || true # configure kubeconfig for the current user mkdir -p $HOME/.kube if [ -f /etc/kubernetes/admin.conf ]; then cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config || true fi # Wait for API ready wait_for_api(){ log "Waiting for API server (max 300s)" local t=0 while ! kubectl version --short >/dev/null 2>&1; do sleep 5 t=$((t+5)) if [ $t -ge 300 ]; then log "API server timeout" return 1 fi done return 0 } if wait_for_api; then log "API server is ready" else log "API server did not become ready in time. Check 'journalctl -u kubelet -b' and container runtime logs. Proceeding but cluster may be unhealthy." fi # Auto-apply CNI if user wants read -p "Apply default CNI automatically? (calico/flannel/none) (default: $CNI_DEFAULT): " CNI_SEL CNI_SEL=${CNI_SEL:-$CNI_DEFAULT} if [[ "$CNI_SEL" =~ ^(calico|flannel)$ ]]; then if [ "$CNI_SEL" = "calico" ]; then log "Applying Calico CNI" kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml || log "Failed to apply Calico" else log "Applying Flannel CNI" kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml || log "Failed to apply Flannel" fi else log "Skipping automatic CNI installation" fi # Wait for CoreDNS ready (long timeout) if ensure_cmd kubectl; then log "Waiting for CoreDNS rollout (max 600s)" t=0 while true; do if kubectl -n kube-system get deployment coredns >/dev/null 2>&1; then kubectl -n kube-system rollout status deployment/coredns --timeout=120s && break || true fi sleep 10 t=$((t+10)) if [ $t -ge 600 ]; then log "CoreDNS did not become ready within 600s. Check pod logs and node networking." break fi done fi # print worker join command for convenience if ensure_cmd kubeadm; then log "Worker join command (if available):" kubeadm token create --print-join-command || log "Join token generation failed. You can run 'kubeadm token create --print-join-command' on the master later." fi else log "Skipping kubeadm init" fi fi ########################### # Firewall / port open ########################### log "Opening firewall ports if ufw present" if ensure_cmd ufw; then ufw allow 6443/tcp ufw allow 2379:2380/tcp ufw allow 10250/tcp ufw allow 30000:32767/tcp ufw reload || true else log "ufw not detected - ensure external firewalls/security groups allow 6443 from worker nodes" fi ########################### # Final checks ########################### log "Final health checks" if ensure_cmd kubectl; then kubectl get nodes -o wide || log "kubectl cannot reach API server - check master status" kubectl get pods -n kube-system -o wide || true else log "kubectl not available or kubeconfig missing" fi log "Script finished. If cluster isn't healthy, check: 'journalctl -u kubelet -b', 'docker ps -a', and 'kubectl -n kube-system get pods -o wide'"
2) 실행 권한 부여
sudo chmod +x K8s-master-reinstall.sh
3) 스크립트 실행
sudo ./K8s-master-reinstall.sh
실행 중에 마스터 노드에서 생성된 kubeadm join 명령어를 복사
예시:
kubeadm join 192.168.120.200:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
4) 확인
스크립트 완료 후:
워커 노드가 정상적으로 Ready 상태로 표시되는지 확인합니다.
스크립트는 다음을 처리합니다(간단 요약):
swap 비활성화, 필요한 sysctl 영구 적용
Docker 및 kubeadm/kubelet/kubectl 설치(중복 설치 방지)
기존 kubeadm 설정 안전 초기화 및 관련 디렉토리 정리
kubeadm 이미지 사전 풀링(가능한 경우)
kubeadm init 자동 실행(사용자 선택) — API 바인드 IP, Pod CIDR 입력 가능
자동 CNI 적용 옵션(Calico 또는 Flannel) — 기본은 Calico
CoreDNS 롤아웃을 위한 장시간 대기 로직(최대 600s)
마스터에서 워커가 사용할 kubeadm join 명령 자동 출력
UFW 기반 포트 개방(존재 시) 및 최종 헬스체크
워커노드
#!/bin/bash # Kubernetes Worker Node 자동 생성기 및 재설치 스크립트 (마스터 연동 지원) # Ubuntu/Debian 계열 기준 # root 권한으로 실행: sudo ./k8s-worker-install-robust.sh set -euo pipefail log(){ printf "%s %s\n" "$(date +'%F %T')" "$*"; } ensure_cmd(){ command -v "$1" >/dev/null 2>&1 || return 1; } if [ "$EUID" -ne 0 ]; then log "루트 권한으로 실행하세요 (sudo 필요)." exit 1 fi log "=== Kubernetes Worker 자동 재설치 스크립트 ===" # 0. swap off if swapon --show | grep -q '^'; then log "스왑 비활성화 중..." swapoff -a || true cp /etc/fstab /etc/fstab.bak_$(date +%s) || true sed -i.bak '/\bswap\b/s/^/#/g' /etc/fstab || true fi # 0-1. sysctl 네트워크 설정 log "필요한 sysctl 적용 (net.bridge, ip_forward)" modprobe br_netfilter || true cat >/etc/sysctl.d/99-k8s-worker.conf <<'EOF' net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF sysctl --system || true # 1. 패키지 설치 install_pkgs(){ log "필수 패키지 존재 여부 확인 및 설치(kubeadm,kubelet,kubectl,docker)" if ! ensure_cmd docker; then log "docker 설치중..." apt update -y apt install -y docker.io systemctl enable --now docker else log "docker: $(docker --version 2>/dev/null || echo 'version?')" fi if ! ensure_cmd kubeadm || ! ensure_cmd kubelet || ! ensure_cmd kubectl; then log "kubeadm/kubelet/kubectl 설치중..." apt update -y apt install -y apt-transport-https ca-certificates curl gnupg lsb-release if [ ! -f /etc/apt/trusted.gpg.d/kubernetes-apt-keyring.gpg ]; then curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-apt-keyring.gpg fi if [ ! -f /etc/apt/sources.list.d/kubernetes.list ]; then echo "deb [signed-by=/etc/apt/trusted.gpg.d/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list fi apt update -y apt install -y kubelet kubeadm kubectl apt-mark hold kubelet kubeadm kubectl else log "kubeadm/kubelet/kubectl 설치됨: $(kubeadm version -o short 2>/dev/null || echo '')" fi } install_pkgs # 2. 기존 kubeadm 구성 제거 (있을때만) if [ -d /etc/kubernetes ] || ensure_cmd kubeadm; then log "기존 kubeadm 구성 reset 시도(있을 경우)" if ensure_cmd kubeadm; then kubeadm reset -f || true fi systemctl stop kubelet || true systemctl stop docker || true else log "기존 kubeadm 구성 없음 - 초기화 단계 건너뜀" fi # 3. cleanup log "CNI 및 관련 디렉토리 정리(존재 여부 상관없이)" rm -rf /etc/cni/net.d || true rm -rf /var/lib/cni || true rm -rf /var/lib/kubelet || true rm -rf /var/lib/etcd || true rm -rf /etc/kubernetes || true rm -rf $HOME/.kube || true # 4. kubeadm 이미지 사전 풀링 log "kubeadm 이미지 사전 풀링 시도" if ensure_cmd kubeadm; then kubeadm config images pull || log "이미지 풀 실패(네트워크/레지스트리 문제 가능), 계속 진행" fi # 5. 서비스 재시작 log "Docker/kubelet 활성화 및 재시작" systemctl daemon-reload || true if ensure_cmd docker; then systemctl enable --now docker || true fi if ensure_cmd kubelet; then systemctl enable --now kubelet || true systemctl restart kubelet || true fi # 6. 조인 명령 준비 log "조인 정보를 입력받습니다. 두 가지 방식 지원:" log " - 1) 전체 join 명령어를 붙여넣기 (권장)" log " - 2) master:ssh_user@MASTER_IP 처럼 입력하면 SSH로 마스터에서 join 명령을 자동 생성하려 시도" read -p "마스터에서 생성된 kubeadm join 명령어 혹은 ssh:USER@MASTER_IP 를 입력하세요: " JOIN_INPUT JOIN_INPUT=${JOIN_INPUT:-} JOIN_CMD="" if [[ "$JOIN_INPUT" =~ ^ssh: ]]; then # 형식: ssh:user@host (예: ssh:ubuntu@192.168.120.200) MASTER_SSH=${JOIN_INPUT#ssh:} log "마스터에 SSH로 접속하여 join 명령을 생성합니다: $MASTER_SSH" if ensure_cmd ssh; then # 사용자에게 SSH 키/비밀번호 등의 준비를 요구함 (비대화형 환경에서는 실패할 수 있음) JOIN_CMD=$(ssh -o BatchMode=yes -o StrictHostKeyChecking=no "$MASTER_SSH" "kubeadm token create --print-join-command" 2>/dev/null || true) if [ -z "$JOIN_CMD" ]; then log "SSH로 자동 생성 실패: 비대화형 연결 실패 또는 권한 문제. 수동으로 join 명령을 입력하세요." else log "마스터에서 받은 join 명령: $JOIN_CMD" fi else log "ssh 명령을 찾을 수 없음. 수동으로 join 명령을 입력하세요." fi else JOIN_CMD="$JOIN_INPUT" fi if [ -z "$JOIN_CMD" ]; then read -p "수동으로 kubeadm join 전체 명령을 입력하세요: " JOIN_CMD fi # 안전히 실행: 앞뒤 공백 제거 JOIN_CMD=$(echo "$JOIN_CMD" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') if [ -z "$JOIN_CMD" ]; then log "join 명령이 제공되지 않았습니다. 스크립트를 종료합니다." exit 1 fi log "입력된 join 명령 실행: $JOIN_CMD" # eval은 필요하지만 사용자 입력이므로 주의. 일단 실행. set +e eval $JOIN_CMD RC=$? set -e if [ $RC -ne 0 ]; then log "kubeadm join 명령이 실패했습니다 (exit code $RC). kubelet/journal 및 네트워크 확인 필요" log "kubelet 로그: sudo journalctl -u kubelet -n 200" exit $RC fi # 7. 방화벽 포트 설정 if command -v ufw &>/dev/null; then log "UFW 감지: 필요한 포트 허용" ufw allow 10250/tcp || true ufw allow 30000:32767/tcp || true ufw reload || true else log "UFW 미설치: 외부 방화벽/보안그룹에서 포트 10250 및 NodePort 범위 허용 필요" fi # 8. 완료 및 검증 log "=== 완료: 노드가 클러스터에 조인되었는지 마스터에서 확인하세요 ===" if ensure_cmd kubectl; then kubectl get nodes -o wide || log "kubectl이 API 서버에 접속할 수 없습니다. 마스터에서 상태 확인 필요" else log "kubectl 미설치 또는 kubeconfig 미설정. 마스터에서 'kubectl get nodes'로 확인하세요." fi log "작업 종료: 문제가 있으면 'journalctl -u kubelet -b'와 'docker ps -a'를 확인하세요."
댓글 ( 0)
댓글 남기기