참고
Vagrant로 쿠버네티스 환경 IAC 구축
Vagrant로 가상머신 클러스터 생성
NOTE
# 변수
domain = "kubernetes.lab"
control_plane_endpoint = "k8s-master." + domain + ":6443"
pod_network_cidr = "10.244.0.0/16"
version = "v1.29"
master_node_ip = "192.168.32.20"
Vagrant.configure("2") do |config|
config.ssh.insert_key = false
# 마스터/워커노드 공통 프로비저닝
config.vm.provision :shell, path: "kubeadm/bootstrap.sh", env: { "VERSION" => version }
# 마스터 노드 설정
config.vm.define "master" do |master|
master.vm.box = "generic/ubuntu2204" # Ubuntu 22.04 LTS
master.vm.hostname = "k8s-master.#{domain}"
master.vm.network "private_network", ip: master_node_ip
master.vm.network "forwarded_port", guest: 80, host: 10080
master.vm.network "forwarded_port", guest: 8080, host: 18080
master.vm.network "forwarded_port", guest: 9000, host: 19000
master.vm.network "forwarded_port", guest: 3000, host: 13000
master.vm.network "forwarded_port", guest: 8088, host: 18088
master.vm.disk :disk, size: "100GB", name: "master_disk1"
master.vm.disk :disk, size: "100GB", name: "master_disk2"
master.vm.provider "virtualbox" do |vb|
vb.memory = "8192"
vb.cpus = "3"
vb.customize ["modifyvm", :id, "--nic1", "nat"]
end
master.vm.provision "shell", env: {"DOMAIN" => domain, "MASTER_NODE_IP" => master_node_ip} ,inline: <<-SHELL
echo "#{master_node_ip} k8s-master.#{domain} k8s-master" >> /etc/hosts
SHELL
(1..2).each do |nodeIndex|
master.vm.provision "shell", env: {"DOMAIN" => domain, "NODE_INDEX" => nodeIndex}, inline: <<-SHELL
echo "192.168.32.#{20+nodeIndex} k8s-worker-#{nodeIndex}.#{domain} k8s-worker-#{nodeIndex}" >> /etc/hosts
SHELL
end
master.vm.provision "shell", path: "kubeadm/init-master.sh", env: {
"K8S_CONTROL_PLANE_ENDPOINT" => control_plane_endpoint,
"K8S_POD_NETWORK_CIDR" => pod_network_cidr,
"MASTER_NODE_IP" => master_node_ip
}
end
# 워커노드 설정
(1..2).each do |nodeIndex|
config.vm.define "worker-#{nodeIndex}" do |worker|
worker.vm.box = "generic/ubuntu2204" # Ubuntu 22.04 LTS
worker.vm.hostname = "k8s-worker-#{nodeIndex}.#{domain}"
worker.vm.network "private_network", ip: "192.168.32.#{20+nodeIndex}"
worker.vm.disk :disk, size: "100GB", name: "worker#{nodeIndex}_disk1"
worker.vm.disk :disk, size: "100GB", name: "worker#{nodeIndex}_disk2"
worker.vm.provider "virtualbox" do |vb|
vb.memory = "8192"
vb.cpus = "3"
vb.customize ["modifyvm", :id, "--nic1", "nat"]
end
worker.vm.provision "shell", env: {"DOMAIN" => domain, "MASTER_NODE_IP" => master_node_ip} ,inline: <<-SHELL
echo "#{master_node_ip} k8s-master.#{domain} k8s-master" >> /etc/hosts
SHELL
(1..2).each do |hostIndex|
worker.vm.provision "shell", env: {"DOMAIN" => domain, "NODE_INDEX" => hostIndex}, inline: <<-SHELL
echo "192.168.32.#{20+hostIndex} k8s-worker-#{hostIndex}.#{domain} k8s-worker-#{hostIndex}" >> /etc/hosts
SHELL
end
worker.vm.provision "shell", path: "kubeadm/init-worker.sh"
end
end
end
Ruby
복사
mkdir -p ~/.kube
cp /etc/kubernetes/kubelet.conf ~/.kube/config
BootStrap 설정( 마스터/워커 공통설정)
NOTE
echo ">>> 시스템 업데이트 & 업그레이드"
sudo apt-get update
# 네트워크 설정
echo ">>> IPV4 포워드 설정 / IP테이블 & 브릿지 트래픽"
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfiliter
EOF
sudo modprobe overlay
sudo modprobe br_netfiliter
# 커널 파라미터 수정
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
sudo sysctl --system
Bash
복사
IPV4 포워딩 및 네트워크 설정
•
쿠버네티스 클러스터 내에서 컨테이너/노드 간 통신을 위해 필요한 네트워크 모듈 overlay, br_netfilter을 활성화하는 코드
•
overlay: 여러 호스트 간에 컨테이너를 연결
•
br_netfilter: 브리지된 네트워크 트래픽을 netfilter을 통해 처리할 수 있게 해준다.
커널 파라미터 수정
•
브리지 네트워크를 통한 트래픽이 iptables 규칙에 따라 처리되도록 한다.
◦
net.bridge.bridge-nf-call-iptabse, net.bridge.bridge-nf-call-ip6tables 설정은 iptables을 사용해서 브리지 네트워크 트래픽을 필터링하게 해준다.
◦
net.ipv4.ip_forward는 시스템 패킷 포워딩을 할 수 있도록 해준다.
echo ">>> 컨테이너D 설치"
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done
sudo apt-get install ca-certificates curl gnupg -y
# 도커 설치 및 저장소 설정
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# docker & containerd 설치
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
cat <<EOF | sudo tee -a /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
EOF
sudo sed -i 's/^disabled_plugins \=/\#disabled_plugins \=/g' /etc/containerd/config.toml
# CNI 설치
sudo mkdir -p /opt/cni/bin/
sudo wget -nv https://github.com/containernetworking/plugins/releases/download/v1.4.0/cni-plugins-linux-amd64-v1.4.0.tgz
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.4.0.tgz
systemctl enable containerd
systemctl restart containerd
Bash
복사
컨테이너 런타임 설치
•
for pkg in docker ~: 기존에 설치된 Docker 관련 패키지나 컨테이너 런타임 제거
•
docker 저장소 설정
•
docker & containerd 설치
•
containerd 설정
CNI 설치
•
CNI 플러그인 설치 및, containerd를 시스템 부팅 시 자동으로 시작하게 설정한다.
echo ">>> 쿠버네티스 설치준비"
sudo apt-get update
# apt-transport-https may be a dummy package; if so, you can skip that package
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
# If the folder `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/${VERSION}/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/${VERSION}/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
echo ">>> 쿠버네티스 구성요소 설치"
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
echo ">>> 스왑 비활성화"
sudo sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab
sudo swapoff -a
Bash
복사
쿠버네티스 설치준비
•
쿠버네티스 공식 저장소 키 및 저장소 추가(GPG 키)
쿠버네티스 설치
•
kubelet, kubeadm, kubectl 설치
•
자동 업데이트 방지를 위해 hold설정
스왑 비활성화
•
쿠버네티스는 스왑을 지원하지 않으므로 비활성화
마스터 노드 설정
NOTE
Bash
복사
워커 노드 설정
NOTE
Bash
복사
공식문서 참조
쿠버네티스 클러스터 환경구축
NOTE
# kubeadm, kubelet, kubectl 설치 및 활성화
apt-get install -y apt-transport-https ca-certificates curl
# Key 추가 및 apt udpate
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-get update
# 최신 버전 설치 (2023-06-07 기준 1.27 버전)
apt-get install -y kubelet kubeadm kubectl
# 버전 확인
kubeadm version
kubelet --version
kubectl version
# 최신 버전 업데이트 방지
apt-mark hold kubelet kubeadm kubectl
# K8s 1.22부터는 systemd와 cgroup을 맞추는 작업 필요
sudo mkdir /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker
# containerd 및 kubeadm 최신 업데이트
rm /etc/containerd/config.toml
systemctl restart containerd
kubeadm config images pull
Bash
복사
# Kubernetes 설정 - Master
# 초기화 (apiserver-advertise-address는 Master ipaddress -> 192.168.32.10)
kubeadm reset
kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.32.10
# Kubeadm 실행 후 생성 된 아래 명령어를 복사해 놓고, Worker Node에서 실행 (생성되는 IP, Token 값은 본인의 환경에 따라 다름)
kubeadm join 192.168.32.10:6443 --token reamrl.2ulzzfy3are6e3xx \
--discovery-token-ca-cert-hash sha256:75192971e8a50f909f3929c80849702eabb5f1173ade11a35639f198744f1cd2
# kubectl을 root 계정없이 실행 (반드시 실행)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# Network add-on - Calico 기본 설치 (Kubernetes Cluster Networking plugin, 2023-06-07 기준 3.25버전)
curl https://docs.projectcalico.org/archive/v3.25/manifests/calico.yaml -O --insecure
kubectl apply -f calico.yaml
kubectl get pods --all-namespaces
# Kubernetes 노드 연결 - Node
# 연결 (Master의 init 작업에서 복사 한 커맨드를 사용)
kubeadm join 192.168.32.10:6443 --token x1qogf.3i1d8zc267sm4gq8 \
--discovery-token-ca-cert-hash sha256:1965b56832292d3de10fc95f92b8391334d9404c914d407baa2b6cec1dbe5322
# 연결 시 오류 발생하면 kubeadm reset 명령어로 초기화 후 다시 실행 (Node 모두 초기화)
kubeadm reset
# 확인 (Master에서)
kubectl get nodes
Bash
복사
# Pod 실행
kubectl run nginx-test --image=nginx --port 80
# Service 실행
kubectl expose pod nginx-test
kubectl get services
# Service Type 변경
kubectl edit service nginx-test # (ClusterIp -> NodePort)
# 확인 (port는 service에서 forwarding 된 port 사용)
http://192.168.32.10:30039/ # (<- port forwarding)
http://192.168.32.11:30039/ # (<- port forwarding)
Bash
복사
# Kubernetes 클러스터 초기화 기본 명령
kubeadm init
# Pod 네트워크 CIDR 설정
kubeadm init --pod-network-cidr=10.244.0.0/16
# API 서버 광고 주소 설정
kubeadm init --apiserver-advertise-address=192.168.32.10
# Kubernetes 버전 지정
kubeadm init --kubernetes-version="v1.22.0"
# HA 클러스터를 위한 컨트롤 플레인 엔드포인트 설정
kubeadm init --control-plane-endpoint="my-cluster-endpoint.example.com"
# 노드 이름 지정
kubeadm init --node-name="my-node-name"
# 클러스터 조인을 위한 토큰 지정
kubeadm init --token="yourtoken1234.0123456789abcdef"
# API 서버에 대한 추가 인증서 SANs 지정
kubeadm init --apiserver-cert-extra-sans="example.com,192.168.32.10"
# 서비스 네트워크 CIDR 설정
kubeadm init --service-cidr=10.96.0.0/12
# 기능 게이트 활성화 또는 비활성화
kubeadm init --feature-gates="FeatureName=true"
# 드라이런 실행으로 실제 적용 없이 결과 확인
kubeadm init --dry-run
# 이미지 리포지토리 변경
kubeadm init --image-repository="myregistry.example.com"
# 사용자 지정 API 서버 포트 설정
kubeadm init --apiserver-bind-port=6443
# cri 소켓 경로 지정 (컨테이너 런타임 인터페이스)
kubeadm init --cri-socket="/var/run/crio/crio.sock"
# 사용자 정의 kubelet 구성 파일 사용
kubeadm init --kubelet-config-file="/path/to/kubelet-config.yaml"
# 초기화 과정에서 사용할 사용자 정의 kubeadm 구성 파일 지정
kubeadm init --config="/path/to/kubeadm-config.yaml"
# 실행 명령 예시
kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=192.168.32.10 \
--kubernetes-version="v1.22.0" \
--control-plane-endpoint="my-cluster-endpoint.example.com" \
--node-name="my-node-name" \
--token="yourtoken1234.0123456789abcdef" \
--dry-run
Bash
복사
Bash
복사
쿠버네티스 클러스터 환경구축
NOTE
공통
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# sysctl params required by setup, params persist across reboots
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
# Apply sysctl params without reboot
sudo sysctl --system
lsmod | grep br_netfilter
lsmod | grep overlay
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
Bash
복사
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker run hello-world
systemctl status containerd
Bash
복사
sudo vi /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
systemctl restart containerd
Bash
복사
sudo apt-get update
# apt-transport-https may be a dummy package; if so, you can skip that package
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
# If the folder `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | 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
Bash
복사
마스터
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=192.168.56.11
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 워커노드에 실행해야하는 명령어
kubeadm join 192.168.56.11:6443 --token p3txxt.ckoqcl2l7l52mqll \
--discovery-token-ca-cert-hash sha256:3a5396bd859ab95749a5b4703af2aa2312dc88339538c836f9f57148f16116fb
Bash
복사
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.2/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.2/manifests/custom-resources.yaml
watch kubectl get pods -n calico-system
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
kubectl taint nodes --all node-role.kubernetes.io/master-
kubectl get nodes -o wide
Ruby
복사
git clone https://github.com/kubernetes-sigs/kubespray.git
sudo apt updaet -y
sudo apt install -y python3-pip
cd kubespray
sudo pip3 install -r requirements.txt
cp -rfp inventory/sample inventory/mycluster
Bash
복사
all:
hosts:
master:
ansible_host: master
worker-1:
ansible_host: worker-1
worker-2:
ansible_host: worker-2
children:
kube_control_plane:
hosts:
master:
worker-1:
worker-2:
kube_node:
hosts:
master:
worker-1:
worker-2:
etcd:
hosts:
master:
worker-1:
worker-2:
k8s_cluster:
children:
kube_control_plane:
kube_node:
calico_rr:
calico_rr:
hosts: {}
YAML
복사
/inventory/mycluster/hosts.yaml
vi inventory/mycluster/groups_vars/kus_cluster/k8s-cluster.yaml
ansible-playbook -i inventory/mycluster/hosts.yaml --become --become-user=root -v cluster.yaml
Bash
복사
kube_proxy_strict_arp: true # Metallb 설정
container_manager: containerd # 컨테이너 디 설정
kubernetes_audit: true # 감사 로그
YAML
복사
declare -a IPS=(192.168.32.20 192.168.32.21 192.168.32.22)
CONFIG_FILE=inventory/mycluster/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}
YAML
복사