-
kubeadm 으로 local kubernetes 환경 구축kubernetes 2021. 9. 8. 14:44반응형
kubernetes 를 제공해 주는 서비스가 많지만 때로는 직접 구축해야 할 필요가 있다. 그런데 막상 설치해보려니 신경 쓸 것도 많고, 선택을 해야 하는 것이 많아서 쉽지가 않았다. 과정을 기록해 보려고 한다.
- 선택1 - 컨테이너 런타임: docker
kubernetes 는 요구하는 스펙이 맞으면 굳이 특정 컨테이너 런타임을 사용할 필요는 없다. 다만 docker 가 가장 익숙하기 때문에 이를 사용하도록 하였다.
참고: 컨테이너 런타임
- 선택2 - 설치 도구: kubeadm
kubernetes 환경 설치를 위해 사용할 수 있는 도구들이 있다: kubeadm, kOps, kubespray 등. 이 중 공식 사이트에 가장 설명이 잘 되어 있는 것은 kubeadm 인 것 같아서 이를 선택했다.
- 선택3 - 네트워크 애드온: calico
kubernetes 의 네트워크를 사용하기 위해서는 kubernetes 네트워크 모델을 구현한 애드온을 실행할 필요가 있다. 많으 종류가 있는데, 그 중 calico 가 간단하고, 많이 사용하고 있어서 선택하였다.
참고: 네트워크 애드온 kubernetes network model
- 환경
서버1: 컨트롤 플레인 (10.10.1.101)
- CentOS 7.9
- Docker 20.10.8
- kubernetes: 1.22.1
서버2: 워커 (10.10.1.102)
- CentOS 7.9
- Docker20.10.8
- kubernetes: 1.22.1
kubernetes 네트워크:
- 서버 네트워크 대역: 10.10.1.0/24
- kubernetes 네트워크 서비스 대역: 172.22.0.0/16
- kubernetes 네트워크 파드 대역(calico): 192.168.0.0/16
이하 내용에서 별도로 명시하지 않은 과정은 컨트롤플레인 서버와 워커 서버에 모두 적용해야 하는 과정이다.
1. Docker 준비
사실 kubernetes 에서는 컨테이너 런타임이 필요한거지 반드시 Docker 를 사용해야 할 필요는 없다. 그러나 Docker 가 가장 익숙하기 때문에 그대로 사용하도록 했다.
1-1. enabled 설정
docker 서비스가 enabled 상태가 아니면 kubeadm 실행시 warning 이 뜬다. 어차피 docker 는 늘 사용할 것이기 때문에, enabled 로 등록하여 부팅시 docker 가 실행되도록 하자.
$ sudo systemctl enable docker.service
확인
$ systemctl list-unit-files | grep "docker.service"
1-2. Docker cgroup 드라이버 설정
kubernetes 에서는 도커의 cgroup 관리에 systemd 를 사용하는 것을 권장하고 있다. systemd 가 아니면 kubeadm 구동시 warning 이 뜬다. 무시해도 동작은 하는 것 같지만 맞춰주자.
도커를 중지시키고 디렉토리를 만든다. (디렉토리가 이미 존재할 수 있는데 이 경우 생략)
$ sudo mkdir /etc/docker
여기에 daemon.json 을 작성하자.
$ 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
도커를 다시 실행하고 확인
$ docker info | grep Cgroup
2. iptables 설정
br_netfilter 모듈이 활성화 되어야 한다고 한다. CentOS 7.9 기준으로 이미 활성화 되어 있는데, 명시적으로 추가해 주자.
$ cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf br_netfilter EOF
또한, iptables 관련 sysctl 설정을 수정해야 한다. 역시 CentOS 7.9 기준으로 활성화 되어 있긴 한데, 영구적용을 위해 sysctl.d 에 설정을 추가하자.
$ cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF
리로딩 하여 적용한다.
$ sudo sysctl --system
3. swap 끄기
kubelet 사용을 위해서는 swap 을 비활성화 하는 것을 권장한다고 한다. 켜 있어도 kubernetes 실행은 가능하지만, 실제 swap 하는 시점에 예상과 다른 동작이 발생할 수 있다고 한다.
$ sudo swapoff -a
결과 확인
$ free -h
재부팅시에도 반영하려면
/etc/fstab
도 수정하자.4. SELinux 비활성화
현재 kublet 스펙에서는 꺼야 한다고 한다.
먼저 비활성화
$ sudo setenforce 0
확인
$ sestatus | grep "Current mode"
Current mode 가
enforcing
에서permissive
로 변경되었다.이후 재부팅 등의 상황에도 적용되도록
/etc/selinux/config
를 고친다.$ sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
SELINUX=enforcing
로 되어 있던 라인이SELINUX=permissive
로 변경되었다.5. firewalld 설정 (포트 열기)
kubernetes 에서 필요한 포트가 있고 calico 에서 필요한 포트가 있다.
참고
- kubernetes 필수 포트: https://kubernetes.io/ko/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
- calico 필수 포트: https://docs.projectcalico.org/getting-started/kubernetes/requirements
(주의) 컨트롤 플레인 노드와 워커 노드에서 필요로 하는 포트가 다르다. 이하 각각 설명한다.
6-1. 컨트롤 플레인 (싱글 컨트롤 패널)
컨트롤플레인 서버에서 열지 않으면 문제가 생기는 포트가 있다. firewall-cmd 를 통해 열어준다.
$ sudo firewall-cmd --permanent --add-port=179/tcp $ sudo firewall-cmd --permanent --add-port=6443/tcp $ sudo firewall-cmd --permanent --add-port=10250/tcp
- 179 포트가 안열리면 calico-node 관련 pod 가 ready 상태가 되지 않는다. ready 상태가 아니면, calico 가상 network (예를 들어
192.168.62.129
) 에 접근하려고 하면 접근되지 않는다. kubernetes 내부로 가야할 것이 외부 게이트웨이로 빠져버린다. - 6443 은 kubelete api 를 위한 포트이다.
- 10250 을 안열어주면 해당 노드에 돌고 있는 pod 에 대한
kubectl exec
가 동작하지 않는다. 컨트롤 플레인 에서도 필요한지는 모르겠는데, waring 에 나와서 그냥 열어줬다.
공식 페이지에는 10251, 10252 포트도 필요하다고 하는데, 최소한 현재 구성중인 환경 기준으로는 열지 않아도 실행할 때는 문제가 없었다.
firewalld 를 재시작 하여 반영한다. (주의: permanent 로 설정하지 않은 설정값들이 있다면 사라진다.)
$ sudo systemctl restart firewalld
6-2. 워커
워커에서 열어야 하는 포트들이 있다.
$ sudo firewall-cmd --permanent --add-port=179/tcp $ sudo firewall-cmd --permanent --add-port=10250/tcp $ sudo firewall-cmd --permanent --add-port=30000-32767/tcp $ sudo firewall-cmd --permanent --add-masquerade
- 179 포트가 안열리면 calico-node 관련 pod 가 ready 상태가 되지 않는다. ready 상태가 아니면, calico 가상 network (예를 들어
192.168.62.129
) 에 접근하려고 하면 접근되지 않는다. kubernetes 내부로 가야할 것이 외부 게이트웨이로 빠져버린다. - 10250 을 안열어주면 해당 노드에 돌고 있는 pod 에 대한
kubectl exec
가 동작하지 않는다. - 30000-32767 는 NodePort 서비스 실행시 사용된다.
- masquerade 를 안하면 calico 네트워크 대역(
192.168
) ip 주소로 들어오는 요청을 처리하지 못한다. (물리 네트워크 대역10.10
이 아닌192.168
로 들어온다.)
firewalld 를 재시작 하여 반영한다. (주의: permanent 로 설정하지 않은 설정값들이 있다면 사라진다.)
$ sudo systemctl restart firewalld
7. 설치
먼저 레포지토리를 추가한다.
$ 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
yum 을 통해 설치한다.
$ sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
먼저 kubelet 을 띄워놓자. 우선 systemctl 에 등록한다.
$ sudo systemctl enable --now kubelet
버전에 따라서 enable 명령시 --now 옵션이 안먹을 때가 있다. 그럴 때는 그냥 아래처럼 리로드 해준다.
$ sudo systemctl daemon-reload
실행
$ sudo systemctl restart kubelet
systemctl
로 확인해 보면 서비스 실행이 실패했다고 뜨는데, 나중에 kubeadm 이 다 구성되면 자동으로 해결된다.8. 초기화 및 조인
(주의) 이하 진행은 컨트롤 패널 서버와 노드가 다르다.
먼저 컨트롤 플레인에서 kubernetes 를 초기화하고 워커를 추가하는 개념이다.
8-1. 컨트롤 플레인 노드 (싱글 컨트롤 플레인 초기화)
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
여기 보면 옵션이 많은데 하나를 제외하고는 모두 디폴트 값을 사용한다.
--service-cidr
값만 수정해 주자. 이것은 서비스에 대하여 kubernetes 에서 할당할 ip 범위이다. 기본적으로10.96.0.0/16
을 사용하고 있다. 그런데 현재 사설망이10.
으로 시작해서 헷갈릴 것 같아서172.22.0.0/16
으로 수정한다. (주의: 비슷한 옵션--pod-network-cidr
이 있는데, 이건 다른 옵션이다.)$ sudo kubeadm init --service-cidr=172.22.0.0/16
실행하면 아래와 같은 로그가 나오는데, 워커 노드에서 사용해야 하니 기억해 두자
(...) Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config Alternatively, if you are the root user, you can run: export KUBECONFIG=/etc/kubernetes/admin.conf You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ Then you can join any number of worker nodes by running the following on each as root: kubeadm join 10.10.1.101:6443 --token cmhczt.dqkpcn0fnytprotj \ --discovery-token-ca-cert-hash sha256:733ec3943111f0bb91e5f37c9afeb878e638af6767e1c9b70e0689e10fec9d10
먼저 현재 사용자 기준으로 위 안내에 나온 걸 실행해 준다.
$ mkdir -p $HOME/.kube $ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config $ sudo chown $(id -u):$(id -g) $HOME/.kube/config
이러면 root 가 아니더라도
kubectl
명령어를 사용할 수 있다. (원래도 단순 호출을 할 수는 있었는데, 실행을 하려면 막혔다.)이렇게 kubeadm 을 통한 컨트롤플레인 초기화가 완료되었다. 다만 컨트롤플레인에는 calico 설치도 필요하다.
calico 의 경우 노드 서버 수 50개 기준으로 다른 가이드를 주고 있다.
https://docs.projectcalico.org/getting-started/kubernetes/self-managed-onprem/onpremises
이 경우는 50 개 미만의 가이드를 따른다.
먼저 설정 파일을 받는다.
$ curl https://docs.projectcalico.org/manifests/calico.yaml -O
그리고 적용한다.
$ kubectl apply -f calico.yaml
적용 후 시간이 지나면 pending 상태였던 coredns 도 Running 을 바뀌고 calico 관련 서비스가 돌고 있는 것을 확인할 수 있다.
8-2. 워커 노드 (조인하기)
위에서 컨트롤플레인 초기화시 나온 로그를 참고하여 적용한다.
$ sudo kubeadm join 10.10.1.101:6443 --token cmhczt.dqkpcn0fnytprotj \ --discovery-token-ca-cert-hash sha256:733ec3943111f0bb91e5f37c9afeb878e638af6767e1c9b70e0689e10fec9d10
아래와 같은 로그가 나오며 완료된다.
This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
9. 확인
컨트롤 플레인 서버에서 확인해 보자.
$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME server1 Ready control-plane,master 12h v1.22.1 10.10.1.101 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://20.10.8 server2 Ready <none> 12h v1.22.1 10.10.1.102 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://20.10.8
잘 적용되었다.
참고:
- 현 구조상, 컨트롤 플레인에는 pod 가 뜨지 않는다. pod 를 뜨게 설정할 수 있지만 생략한다.
반응형'kubernetes' 카테고리의 다른 글
[kubernetes] Ingress-nginx --enable-ssl-passthrough 옵션 적용해보기 (with argocd) (1) 2023.12.21