본문 바로가기
Infra/Kubernetes

K8s from scratch - 1. AWS 에서 쿠버네티스 환경 구축하기

by J's Note 2023. 10. 25.

AWS의 VPC환경에 EC2를 생성하여 쿠버네티스 클러스터를 쉽게 구축하는법입니다.

준비사항

  1. Kubeadm을 사용하기위해 최소스펙인 2vCPU, 4G Mem의 인스턴스가 필요하며 비용대비 가장 저렴한 인스턴스는 2023년 10월 25일 기준 t3.small 타입입니다.
  2. 클러스터 내 모든 마스터/워커 노드가 통신이 가능하도록 인바운드 설정이 필요합니다. 모든 EC2 인스턴스를 동일한 보안그룹으로 설정 후 해당 보안그룹을 인바운드로 Anywhere 설정하는방법이 가장 간단합니다.

유저데이터

해당 포스트는 EC2의 유저데이터(UserData) 를 사용하여 쉽게 스크립트를 설치하는 방법을 다루고있습니다. 때문에 설정해야 하는

가지 존재합니다.

  • NODE_NAME 
    • 설정될 호스트네임입니다. VPC내에서 유니크해야합니다.
  • IS_MASTER
    • 마스터노드의 여부입니다. true로 설정한경우 Master Node로 생성되게 됩니다.
  • SLAVE_JOIN 
    • 마스토노드 생성 후 나오는 kubeadm join 명령어를 기입합니다.
    • 명령어는 마스터 노드 후 /vat/log/user-data.log 를 통해 확인이 가능합니다.

EC2 생성단계에서 인스턴스 타입, VPC등을 설정 한 후 고급세부정보의 사용자 데이터 항목에 다음 스크립트를 입력합니다.

 

Master Node 와 Worker Node 모두 유니크한 호스트네임을 설정합니다.

추가적으로 Master Node 인 경우 IS_MASTER 를 true로 설정합니다.

추가적으로 Slave Node 인 경우 Master Node 생성시에 기록된 kubeadm 명령어를 SLAVE_JOIN에 설정합니다.

#!/bin/bash
// 로그기록
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1

// 스왑 메모리 해제
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

// 호스트 네임 할당
NODE_NAME="master001"
// 마스터 노드 여부 설정
IS_MASTER=true
// 워커노드라면, kubeadm join 명령어 설정
SLAVE_JOIN="kubeadm join 10.0.128.225:6443 --token 7nzzqg.eotze874n183a2b2 \
	--discovery-token-ca-cert-hash sha256:05bd74f79866e072e8aa6864c79122d25bc70c999d24959105fcb1c65666e29c"

// 호스트네임 설정
hostnamectl set-hostname $NODE_NAME

// Containerd 설치하기 ** 더이상 Docker를 사용하지 않음
wget https://github.com/containerd/containerd/releases/download/v1.6.16/containerd-1.6.16-linux-amd64.tar.gz
tar Cxzvf /usr/local containerd-1.6.16-linux-amd64.tar.gz
wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
mkdir -p /usr/local/lib/systemd/system
mv containerd.service /usr/local/lib/systemd/system/containerd.service
systemctl daemon-reload
systemctl enable --now containerd

// runC 설치하기
wget https://github.com/opencontainers/runc/releases/download/v1.1.4/runc.amd64
install -m 755 runc.amd64 /usr/local/sbin/runc

// CNI 설치하기
wget https://github.com/containernetworking/plugins/releases/download/v1.2.0/cni-plugins-linux-amd64-v1.2.0.tgz
mkdir -p /opt/cni/bin
tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.2.0.tgz

// CRICTL 설치하기
VERSION="v1.26.0"
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz
tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-amd64.tar.gz
cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 2
debug: false
pull-image-on-create: false
EOF

// IPv4 포워딩하기. IP table 설정하기
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
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
net.ipv4.ip_forward = 1
EOF
sysctl --system
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
modprobe br_netfilter
sysctl -p /etc/sysctl.conf

// kubtctl, kubeclet, kubeadm 설치하기
apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt update -y
apt install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl

// kubeadm으로 클러스터 설정
if [ ${IS_MASTER} = true ]; then
echo "Inside first if"
kubeadm config images pull
kubeadm init
mkdir -p /home/ubuntu/.kube
cp -i /etc/kubernetes/admin.conf /home/ubuntu/.kube/config
else
echo "Inside first else"
eval ${SLAVE_JOIN}
fi
if [ ${IS_MASTER} = true ]; then
sudo -u ubuntu -i <<'EOF'
echo "Inside second if"
sudo chown $(id -u):$(id -g) $HOME/.kube/config
// CNI는 위브넷 사용하기
kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml
kubectl get nodes
EOF
fi

생성확인

인스턴스 생성만으로 K8s 클러스터가 생성되었습니다.