Kubernetes
Kubernetes 구축
흥부가귀막혀
2024. 1. 29. 15:25
공통(Master/Worker Node)
Docker 설치
- Docker Engine Install 을 참고하여 사용하는 OS 에 맞게 설치 진행한다.
- centos 버전으로 설치 진행
- root 권한이 필요하기 때문에
root
계정으로 진행한다.
yum-utils
설치 및 docker repository 등록
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
필요한 Docker Package 설치(특정 버전을 설치하고자 한다면,
yum list docker-ce --showduplicates | sort -r
로 원하는 버전 확인 후 설치를 진행한다)
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y
Docker 실행
sudo systemctl start docker
Kubernetes 설치
- kubeadm 설치 를 참고하여 진행한다.
- root 권한이 필요하기 때문에
root
계정으로 진행한다.
1. swap 비활성화
sudo /sbin/swapoff -a && sudo sed -i '/swap/s/^/#/' /etc/fstab
2. IPv4 포워딩 및 iptables에서 브리지된 트래픽 확인
- Container Runtime 가이드에 따라 IPv4 포워딩 및 iptables에서 브리지된 트래픽 확인을 진행한다.
- root 권한이 필요하기 때문에
root
계정으로 진행한다.
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
# 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 /sbin/sysctl --system
3. Container Runtime Interface 설치
- Kubernetes 와 Container Runtime 을 연결해주기 위한 Container Runtime Interface 가 설치되야 하는데 종류가 몇가지 있다.
- 현재 구축한 kubernetes 는
cri-dockerd
로 설치
1) Containerd
- Docker 설치 과정에서 설치된다. 다만, 정상적인 동작을 위해 Kubernetes 에서 제공하는 containerd 가이드 에 따라 추가로 작업을 진행해야 한다.
/etc/containerd/config.toml
설정 파일에서 cri disabled 제거
sed -i '/"cri"/ s/^/#/' /etc/containerd/config.toml
/etc/containerd/config.toml
설정 파일에서 runc 설정 추가
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
2) cri-dockerd
- cri-dockerd README 를 참고하여 설치를 진행한다.
# Run these commands as root ###Install GO### wget https://storage.googleapis.com/golang/getgo/installer_linux chmod +x ./installer_linux ./installer_linux source ~/.bash_profile
git clone [https://github.com/Mirantis/cri-dockerd.git](https://github.com/Mirantis/cri-dockerd.git)
cd cri-dockerd
mkdir bin
go build -o bin/cri-dockerd
sudo mkdir -p /usr/local/bin
sudo install -o root -g root -m 0755 bin/cri-dockerd /usr/local/bin/cri-dockerd
sudo cp -a packaging/systemd/\* /etc/systemd/system
sudo sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service
sudo systemctl daemon-reload
sudo systemctl enable cri-docker.service
sudo systemctl enable --now cri-docker.socket
4. kubeadm, kubelet, kubectl 설치
kubernetes repository 등록
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF
SELinux mode 변경
# Set SELinux in permissive mode (effectively disabling it)
sudo /sbin/setenforce 0
# 가이드에서는 permissive 모드로 변경하였지만, 효과적으로 하려면 disabled 로 설정해도 된다.(현재 구축된 kubernetes 는 disabled 로 설정)
# sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config # permissive 로 변경
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config # disabled 로 변경
kubeadm, kubelet, kubectl 설치 및 kubelet 실행
sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
sudo systemctl enable --now kubelet
Master Node 구축(⚠️ Worker 노드에서는 하면 안됨!)
- Creating a cluster with kubeadm 을 참고하여 Master Node 를 구축한다.
1. kubeadm init 실행
- Container Network Interface 를 어떤걸 쓰냐에 따라 init 수행시
--pod-network-cidr
설정을 다르게 가야한다. - 현재 구축된 kubernetes 는 flannel 을 설치하였고 이에 맞게 init 설정을 진행함
- 원래는 calico 를 초기에 셋팅했었으나, ncloud 장비의 bpf 관련 이슈로 정상적으로 동작하지 않아 변경함.
- CRI 로
Containerd
,cri-dockerd
둘다 설치했을 경우 어떤 CRI 를 사용할 것인지 정해줘야 한다. init 실행시--cri-socket
옵션을 추가하여 사용할 CRI 가 어떤건지 설정한다.
init command 실행
# flannel 의 기본 cidr 설정값인 10.244.0.0/16 을 설정한다.
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --cri-socket=unix:///var/run/cri-dockerd.sock
init 호출 후 stdout 에 출력된 Worker node 추가에 필요한 join command 내용을 잘 기록해둔다. 이거 안하면 Worker Node 추가가 불가능하기 때문에 다시 reset 해야함.
vi token.txt
kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>
sudo 권한 없이 kubectl 사용을 위한 설정 추가
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
❔ 혹시나 init 과정에서 실패가 발생했거나 master node 설정을 초기화 하고 싶다면? reset command 를 호출한다.
# 어떤 CRI 로 구축했는지 알아야 해서 --cri-socket 옵션을 넣어준다.
sudo kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock
2. CNI 설치(flannel)
- 다음 명령어를 통해 flannel 을 설치한다.
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
- 간혹 flannel 설치 이후
/run/flannel
디렉토리 안subnet.env
파일이 생성되지 않아 오류가 발생할 수 있다. 파일이 생성되었는지 확인하고 혹시 생성이 안되어있다면 다음과 같이 생성해준다. sudo vi /run/flannel/subnet.env
FLANNEL\_NETWORK=10.244.0.0/16
FLANNEL\_SUBNET=10.244.0.1/24
FLANNEL\_MTU=1450
FLANNEL\_IPMASQ=true
3. Master Node 에 필요한 pod 이 정상인지 확인
- kubectl 을 통해 node 상태 및 control-plane 이 정상적으로 운영중인지 확인한다.
kubectl get nodes
NAME STATUS ROLES AGE VERSION
dev-k8s-node-002 Ready control-plane 179m v1.26.1
- 혹여 node 의 STATUS 가 NotReady 일 경우 정확한 확인을 위해 pod 상태를 확인해본다.
kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-787d4945fb-2f9f7 1/1 Running 0 179m
coredns-787d4945fb-ksp7d 1/1 Running 0 179m
etcd-dev-k8s-node-002 1/1 Running 0 3h
kube-apiserver-dev-k8s-node-002 1/1 Running 0 3h
kube-controller-manager-dev-k8s-node-002 1/1 Running 0 3h
kube-proxy-98thd 1/1 Running 0 174m
kube-proxy-d5ddx 1/1 Running 0 179m
kube-scheduler-dev-k8s-node-002 1/1 Running 0 3h
- STATUS 가 Running 이 아닌 Pod 이 있을 경우 다음 명령어를 통해 log 및 pod event 내용을 확인한다.
log 확인
kubectl logs coredns-787d4945fb-2f9f7 -n kube-system
pod event 확인
kubectl describe pod coredns-787d4945fb-2f9f7 -n kube-system
Name: coredns-787d4945fb-2f9f7
Namespace: kube-system
Priority: 2000000000
Priority Class Name: system-cluster-critical
Service Account: coredns
Node: dev-k8s-node-002/10.113.137.19
Start Time: Thu, 02 Feb 2023 12:09:20 +0900
Labels: k8s-app=kube-dns
pod-template-hash=787d4945fb
Annotations: <none>
Status: Running
IP: 10.244.0.3
IPs:
IP: 10.244.0.3
Controlled By: ReplicaSet/coredns-787d4945fb
Containers:
coredns:
Container ID: docker://bb053af27773abb6622792d75f56835f1530ca435601337b9afd68910309790c
Image: registry.k8s.io/coredns/coredns:v1.9.3
Image ID: docker-pullable://registry.k8s.io/coredns/coredns@sha256:8e352a029d304ca7431c6507b56800636c321cb52289686a581ab70aaa8a2e2a
Ports: 53/UDP, 53/TCP, 9153/TCP
Host Ports: 0/UDP, 0/TCP, 0/TCP
Args:
-conf
/etc/coredns/Corefile
State: Running
Started: Thu, 02 Feb 2023 12:09:21 +0900
Ready: True
Restart Count: 0
Limits:
memory: 170Mi
Requests:
cpu: 100m
memory: 70Mi
Liveness: http-get http://:8080/health delay=60s timeout=5s period=10s #success=1 #failure=5
Readiness: http-get http://:8181/ready delay=0s timeout=1s period=10s #success=1 #failure=3
Environment: <none>
Mounts:
/etc/coredns from config-volume (ro)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-4xgx5 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
config-volume:
Type: ConfigMap (a volume populated by a ConfigMap)
Name: coredns
Optional: false
kube-api-access-4xgx5:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: Burstable
Node-Selectors: kubernetes.io/os=linux
Tolerations: CriticalAddonsOnly op=Exists
node-role.kubernetes.io/control-plane:NoSchedule
node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: <none>
Worker Node 구축
1. Master Node 구축시 출력된 join 명령어를 수행한다.
# CRI 가 여러개 설치되었을 경우 join 명령어 수행시 --cri-socket 설정을 추가하여 CRI 를 설정한다.
sudo kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash> --cri-socket=unix:///var/run/cri-dockerd.sock
2. Master Node 에서 Worker Node 가 정상적으로 Join 되었는지 확인한다.
kubectl get nodes
NAME STATUS ROLES AGE VERSION
dev-k8s-node-002 Ready control-plane 3h9m v1.26.1
dev-k8s-node-003 Ready <none> 3h3m v1.26.1