Infra/Kubernetes
K8s from scratch - 1. AWS 에서 쿠버네티스 환경 구축하기
J's Note
2023. 10. 25. 15:38
AWS의 VPC환경에 EC2를 생성하여 쿠버네티스 클러스터를 쉽게 구축하는법입니다.
준비사항
- Kubeadm을 사용하기위해 최소스펙인 2vCPU, 4G Mem의 인스턴스가 필요하며 비용대비 가장 저렴한 인스턴스는 2023년 10월 25일 기준 t3.small 타입입니다.
- 클러스터 내 모든 마스터/워커 노드가 통신이 가능하도록 인바운드 설정이 필요합니다. 모든 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 클러스터가 생성되었습니다.
