kubeadm을 활용한 쿠버네티스 고가용성 클러스터 구축(Creating Highly Available clusters with kubeadm)
2020, Sep 10
구성목표
- 마스터 노드 3개의 클러스터 구성
- 가상 네트워크 (Calico) 적용
사전 작업하기
가상 머신 세팅
- Windows 10 Hyper-V로 3개의 가상머신 생성
- OS: CentOS7 Minimal
- RAM : 2048MB
- HDD : 20GB
- CPU : 2
마스터, 워커에 대한 가상머신 최소 요구 사항
- 다음 중 하나를 실행하는 하나 이상의 머신 :
- Ubuntu 16.04 이상
- Debian 9 이상
- CentOS 7
- RHEL (Red Hat Enterprise Linux) 7
- Fedora 25 이상
- HypriotOS v1.0.1 이상
- Flatcar Container Linux (2512.3.0으로 테스트 됨)
- 컴퓨터 당 2GB 이상의 RAM (그보다 적 으면 앱을위한 공간이 거의 남지 않음)
- CPU 2 개 이상
- 클러스터의 모든 시스템 간의 전체 네트워크 연결 (공용 또는 사설 네트워크는 괜찮음)
-
모든 노드에 대한 고유 한 호스트 이름, MAC 주소 및 product_uuid. 자세한 내용은 여기
를 참조하십시오.
-
컴퓨터에서 특정 포트가 열려 있습니다. 자세한 내용은 여기
를 참조하십시오.
-
스왑이 비활성화되었습니다. 당신은 반드시
제대로 작동하려면 kubelet 위해서는 스왑을 사용하지 않도록 설정합니다.
## 방화벽 해제 및 종료
[root@localhost ~]# systemctl disable firewalld && sudo systemctl stop firewalld
## paging과 swap 기능 종료
[root@localhost ~]# swapoff -a
## 커널 속성 변경 (swap disable)
[root@localhost ~]# echo 0 > /proc/sys/vm/swappiness
## swap을 하는 파일 시스템을 찾아 disable 처리
[root@localhost ~]# sed -e '/swap/ s/^#*/#/' -i /etc/fstab
## RHEL, CentOS 7 기준 iptables 이슈로 인한 커널 매개변수 수정
## iptables가 브리지 된 트래픽을 보게하기
[root@localhost ~]# cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
## 수정된 매개변수 확인
[root@localhost ~]# sysctl --system
* Applying /usr/lib/sysctl.d/00-system.conf ...
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
* Applying /usr/lib/sysctl.d/10-default-yama-scope.conf ...
kernel.yama.ptrace_scope = 0
* Applying /usr/lib/sysctl.d/50-default.conf ...
kernel.sysrq = 16
kernel.core_uses_pid = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.promote_secondaries = 1
net.ipv4.conf.all.promote_secondaries = 1
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
* Applying /etc/sysctl.d/99-sysctl.conf ...
* Applying /etc/sysctl.d/k8s.conf ...
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
* Applying /etc/sysctl.conf ...
## br_netfilter 모듈 활성화
[root@localhost ~]# modprobe br_netfilter
## 모듈 추가 확인
[root@localhost ~]# lsmod | grep br_netfilter
br_netfilter 22256 0
bridge 151336 1 br_netfilter
## 도커 설치 (도커로 인해 진행이 잘 안되는 경우가 있으니 설치되어있을 경우 삭제하고 다시 설치)
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum update
sudo yum install yum-utils device-mapper-persistent-data lvm2
[root@localhost ~]# yum install docker-ce -y
## 부팅시 도커 자동으로 실행하게 설정
[root@localhost ~]# systemctl start docker.service
Docker cgroup setting
cat <<EOF > /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF
systemctl daemon-reload
systemctl enable docker
systemctl restart docker
## 쿠버네티스 리셋할 경우 (처음부터 하고싶을 때)
kubeadm reset -f
rm -rf /etc/kubernetes
rm -rf /etc/cni
rm -rf /var/lib/etcd
rm -rf /var/lib/kubenet
rm -rf /var/lib/kubelet
rm -rf /root/.kube
rm -rf /var/lib/rook
- 쿠버네티스가 사용하는 포트들이므로 비워둬야 하며 모두 열려있어야 한다.
kubeadm, kubelet 및 kubectl 설치하기
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
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF
## SELinux(Security-Enhanced Linux) 리눅스 보안 모듈(액세스 권한 제어) 해당 기능 끄기
[root@localhost ~]# setenforce 0
[root@localhost ~]# sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
## kubelet, kubeadm, kubectl 설치
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
## kubelet 활성화
[root@localhost ~]# systemctl enable --now kubelet
Created symlink from /etc/systemd/system/multi-user.target.wants/kubelet.service to /usr/lib/systemd/system/kubelet.service.
고가용성 클러스터 구축 시작
호스트네임 설정
- 각각의 가상머신 마다 hostname을 다르게 설정
- 재부팅을 하지 않으면 이후 진행시 문제가 생길 수 있음
## CentOS1
[root@localhost ~]# hostnamectl set-hostname node1
## CentOS2
[root@localhost ~]# hostnamectl set-hostname node2
## CentOS3
[root@localhost ~]# hostnamectl set-hostname node3
kube-apiserver용 로드 밸런서 설치
- node1에만 haproxy 설치
yum install haproxy -y
- node1 IP의 26643 포트로 전달받은 데이터를 node1 ~ node3의 6443 포트로 포워드 시키기
[root@localhost ~]# vi /etc/haproxy/haproxy.cfg
frontend kubernetes-master-lb
bind 0.0.0.0:26443
option tcplog
mode tcp
default_backend kubernetes-master-nodes
backend kubernetes-master-nodes
mode tcp
balance roundrobin
option tcp-check
option tcplog
server node1 172.31.218.71:6443 check ## node1
server node2 172.31.211.174:6443 check ## node2
server node3 172.31.220.154:6443 check ## node3
## haproxy 재시작
[root@localhost ~]# systemctl restart haproxy
node1 클러스터 생성
kubeadm init --control-plane-endpoint "172.31.218.71:26443" \
--upload-certs \
--pod-network-cidr=192.168.0.0/16 ## container의 아이피 할당 범위 설정 Calico on Kubernetes 기준
## 싱글로 할 때 (멀티로 하다가 잘 안 될때 그냥 싱글로 테스트하는 용도로 사용함)
kubeadm init --upload-certs --pod-network-cidr=192.168.0.0/16
node2, node3 image pull
kubeadm config images pull
config 생성
- 권한이 필요하다면 사용자 디렉토리 하위에
.kube/config
생성 (master node에서 모두 실행)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
master node 연결
kubeadm join 172.31.218.71:26443 --token q4nwtd.4gz9ertus6c1sb3s \
--discovery-token-ca-cert-hash sha256:4dcd823eb577d2efd08a9b269e3c546785b521a9146ae748d1420e5fcc51be9d \
--control-plane --certificate-key bea375424cf6fa409e8f4812d8da575922cc4c8c3520873263ea08f954d607cc
work node 연결
kubeadm join 172.31.218.71:26443 --token q4nwtd.4gz9ertus6c1sb3s \
--discovery-token-ca-cert-hash sha256:4dcd823eb577d2efd08a9b269e3c546785b521a9146ae748d1420e5fcc51be9d
node 상태 확인
[root@node1 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
node1 NotReady master 3m14s v1.19.1
node2 NotReady master 68s v1.19.1
node3 NotReady master 64s v1.19.1
Calico yaml 파일 실행
kubectl create -f https://docs.projectcalico.org/manifests/tigera-operator.yaml
kubectl create -f https://docs.projectcalico.org/manifests/custom-resources.yaml
taint 삭제 (pod 생성을 막으므로 삭제)
kubectl taint nodes --all node-role.kubernetes.io/master-
pod 조회
-A
: 전부 조회
[root@node1 ~]# kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
calico-system calico-kube-controllers-69fbbf7967-ltqvx 1/1 Running 0 59s
calico-system calico-node-pdd8n 0/1 Running 0 59s
calico-system calico-node-tgm7d 0/1 Running 0 59s
calico-system calico-node-v6zz6 0/1 Running 0 59s
calico-system calico-typha-7f44c5b874-mfhnd 1/1 Running 0 59s
kube-system coredns-f9fd979d6-dbbqg 1/1 Running 0 5m2s
kube-system coredns-f9fd979d6-r2bs9 1/1 Running 0 5m2s
kube-system etcd-node1 1/1 Running 0 5m11s
kube-system etcd-node2 1/1 Running 0 3m11s
kube-system etcd-node3 1/1 Running 0 3m
kube-system kube-apiserver-node1 1/1 Running 0 5m11s
kube-system kube-apiserver-node2 1/1 Running 0 3m14s
kube-system kube-apiserver-node3 1/1 Running 0 101s
kube-system kube-controller-manager-node1 1/1 Running 1 5m11s
kube-system kube-controller-manager-node2 1/1 Running 0 3m10s
kube-system kube-controller-manager-node3 1/1 Running 0 113s
kube-system kube-proxy-6m5kb 1/1 Running 0 2m33s
kube-system kube-proxy-n8zpl 1/1 Running 0 5m2s
kube-system kube-proxy-xhhfc 1/1 Running 0 3m15s
kube-system kube-scheduler-node1 1/1 Running 1 5m11s
kube-system kube-scheduler-node2 1/1 Running 0 3m14s
kube-system kube-scheduler-node3 1/1 Running 0 98s
tigera-operator tigera-operator-646f758f9b-2l9hg 1/1 Running 0 69s