EC2 서버 스펙
Master
OS image: ubuntu 18.04 LTS
Instance type: t2.medium( 2vCPU, 4GiB Mem)
volume: 20GiB root volume
port : 22(ssh),6443(API),2380,2370(etcd)
kubernetes 실행에 필요한 필수 포트(SG group 설정,중요★)
https://kubernetes.io/ko/docs/reference/ports-and-protocols/
+BGP peering을 위한 TCP 179 port open
1. SSH Key 생성 및 배포
- SSH key 기반의 인증을 사용할 수 있도록 master node에서 RSA 공개키를 생성한 후, master node를 포함한 모든 node에 복사합니다.
- kubespray는 Ansible(ansible)를 이용하여 kubernetes cluster를 설치합니다. ansible은 일반적으로 SSH 프로토콜을 통해 원격 시스템과 통신하기 때문에 모든 node에 SSH 구성이 필요합니다.
1.1. SSH Key 생성(master node 에서)
$ ssh-keygen -t rsa
RSA 공개키 조회
$ cat ~/.ssh/id_rsa.pub
(아래의 사진은 rsa 공개키의 일부)
1.2 RSA 공개키 복사(Master, worker node)
$ vi ~/.ssh/authorized_keys
# nano 도가능 편하신 에디터로
# ssh-copy-id {USER}@{HOST} 로 복사하는 방법도 있음
1.3. ssh-keyscan 명령어로 모든 node의 호스트(host) 등록(Master node)
- master node를 포함한 모든 worker node도 host를 등록합니다.
- 아래 과정을 진행하지 않을 경우, kubespray 설치 과정에서 worker node의 인증 권한 설정에 따라 RSA key fingerprint 확인이 발생할 수 있습니다.
- master node에서 모든 worker,master node(자신의 ip포함)에 직접 ssh를 연결하면서 RSA key fingerprint를 등록해도 됩니다.
$ ssh-keyscan -t rsa {HOST} >> ~/.ssh/known_hosts
$ ssh-keyscan -t rsa 172.31.40.250 >> ~/.ssh/known_hosts
# 172.31.40.250:22 SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.5
1.4. ssh 명령어로 worker node 접속 확인(Master node)
$ ssh {USER}@{HOST}
# 예시
$ ubuntu@ip-172.31.33.120:~$ ssh ubuntu@172.31.40.250
2. kubespray 내려받기(Master node)
2.1. workspace 디렉터리 생성
$ export SPIDYWEB_WORKSPACE=${HOME}/workspace
$ mkdir -p ${SPIDYWEB_WORKSPACE}
2.2. git clone 명령어로 kubespray 내려받기
$ git clone https://github.com/kubernetes-sigs/kubespray.git -b v2.15.0 ${SPIDYWEB_WORKSPACE}/kubespray
3. python 설치 및 kubespray python package 설치(Master)
3.1. package index 업데이트
$ sudo apt update
3.2. python 설치
$ sudo apt install -y python3-pip
3.3 kubespray python package 설치
$ sudo pip3 install -r ${SPIDYWEB_WORKSPACE}/kubespray/requirements.txt
requirements.txt 파일
4. kubespray 설정 구성(Master node)
4.1. inventory 구성
4.1.1. inventory 파일 생성
- sample 디렉터리(directory)를 복사하여 inventory directory를 생성합니다.
$ cp -r ${SPIDYWEB_WORKSPACE}/kubespray/inventory/sample ${SPIDYWEB_WORKSPACE}/kubespray/inventory/spidyweb-cluster
4.1.2. inventory 파일 수정
$ nano ${SPIDYWEB_WORKSPACE}/kubespray/inventory/spidyweb-cluster/inventory.ini
마스터 노드 worker노드를 구분해서 kube-master와 etcd에 마스터노드 ip주소를, kube-node에 worker 노드 주소를 입력
5. kubespray 설치(Master node)
5.1 inventory builder로 inventory 구성
$ declare -a IPS=({MASTER_NODE_IP} {WORKER_NODE_IP1} {WORKER_NODE_IP2} {WORKER_NODE_IP3}...)
$ CONFIG_FILE=${SPIDYWEB_WORKSPACE}/kubespray/inventory/spidyweb-cluster/hosts.yaml python3 ${SPIDYWEB_WORKSPACE}/kubespray/contrib/inventory_builder/inventory.py ${IPS[@]}
5.2 master node 개수 설정
- kubespray의 기본 설정은 master node 개수가 2개
- inventory.ini 설정과 상관없이 worker node에도 master role을 부여
- 아래 hosts.yaml을 수정하여 master node 개수를 1개로 수정할 수 있음
- 이 포스트에서는 master node 개수를 1개 설정하여 설치
$ nano ${SPIDYWEB_WORKSPACE}/kubespray/inventory/spidyweb-cluster/hosts.yaml
children-kube-master-hosts에 node1만 남기고 지운다.
5.3 inventory 설정 확인
$ cat ${SPIDYWEB_WORKSPACE}/kubespray/inventory/spidyweb-cluster/group_vars/all/all.yml
$ cat ${SPIDYWEB_WORKSPACE}/kubespray/inventory/spidyweb-cluster/group_vars/k8s-cluster/k8s-cluster.yml
5.4 ansible playbook으로 kubernetes cluster 설치
ansible-playbook 명령어를 root 사용자로 실행하기 위해서는 ‘–become’ 옵션과 ‘–become-user=root’ 옵션은 필수
$ ansible-playbook -i ${SPIDYWEB_WORKSPACE}/kubespray/inventory/spidyweb-cluster/hosts.yaml --become --become-user=root ${SPIDYWEB_WORKSPACE}/kubespray/cluster.yml
다음과 같이 나오면 정상적으로 설치됨.
여기서 ubuntu의 버전이 18.04 LTS 가 아닐 때 버전의 차이로 인한 아래와 같은 에러들이 뜹니다.
"""
*ERROR 'RETRYING: Install packages requirements' 하면서 실패로 뜬다.
원인은 ubuntu 20.04 이기 때문에 python3-apt여야 하지만 ${SPIDYWEB_WORKSPACE}/kubespray/roles
/kubernetes/preinstall/vars/ubuntu.yml 에서는 python-apt를 시도하고 있어서 그렇다.
해결:
python-apt를 python3-apt로 수정
뿐만 아니라 찾아보니 20.04 버전에서 수정해줘야 할 것들이 4가지 더 있었다
- ${SPIDYWEB_WORKSPACE}/kubespray/roles/kubernetes/node/tasks/main.yml 모든 “nf_conntrack_ipv4” 를 “nf_conntrack”로 수정
- 최근의 도커버전으로 설치해서 apt 충돌을 피하려면, ${SPIDYWEB_WORKSPACE}/kubespray/roles/container-engine/docker/vars/ubuntu.yml 에서 stable을 latest로 바꿔줍니다. 그리고 ${SPIDYWEB_WORKSPACE}/kubespray/roles/container-engine/docker/defaults/main.yml 파일에서 "docker_version:'19.03'" 에서 "docker_version: latest"로 바꿔줍니다.
- ${SPIDYWEB_WORKSPACE}/kubespray/roles/container-engine/containerd/defaults/main.yml 에서 ‘containerd_ubuntu_repo_component: “stable”’를 ‘containerd_ubuntu_repo_component: “latest”’로 바꿔줍니다.
- "No package matching 'aufs-tools' is available" 에러가 나올 떄는, sudo add-apt-repository universe, sudo apt-get update도 쳐줘야 한다
"""
error: TASK [etcd : Configure | Wait for etcd cluster to be healthy] fail
I found that if you change the addresses and rerun the playbook, etcd will still try to connect to the previous members.
주소를 변경하고 playbook을 재실행 한다면, etcd는 이전의 멤버로 연결을 시도할 것.
-> /var/lib/etcd/member etcd data directory를 지우고, etcd1 도커 컨테이너를 각 etcd host에서 종료시키면 도커가 컨테이너를 재시작하고 data directory도 rebuild 할것
아마 ansible-playbook -i ${SPIDYWEB_WORKSPACE}/kubespray/inventory/spidyweb-cluster/hosts.yaml --become --become-user=root ${SPIDYWEB_WORKSPACE}/kubespray/cluster.yml 명령어를 여러번 시도해서 이전의 멤버로 연결을 시도 하는 문제 인 것 같았다. 위의 문제로도 나는 해결이 되지 않았고, 서버를 새로 생성해 처음부터 다시 작업하니 완료됐습니다.
6. kubernetes cluster 설치 확인(Master node)
6.1 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
6.2. node 목록 조회
kubectl get nodes -o wide
6.3. pod 목록 조회
kubectl get pods --all-namespaces
*calico-node들이 READY되지 않은 문제
아래의 명령어로 문제의 calico-node가 어떤 문제인지 확인
kubectl describe pod calico-pod-name -n kube-system
BIRD? BGP?
- BIRD calico의 모듈 중 하나로, kubernetes의 모든 노드에서 실행되는 BGP 데몬
- BGP는 Border Gateway Protocol의 약자로, 네트워크 상의 A지점에서 B지점으로 가는 최단 경로를 탐색하기 위해 라우터들이 주고받는 라우팅 정보를 정의한 프로토콜
- BIRD는 calico에서 노드 별로 네트워크 라우팅 정보를 갱신
BGP는 우리가 일상 생활 속에서 사용하고 있는 GPS앱에 비유할 수 있습니다. GPS 기반의 네비게이션 앱들은 사용자가 목적지로 가기 위한 최적의 경로를 내부적으로 분석하여 빠른 길을 알려줍니다. 이와 유사하게, BGP는 거대한 네트워크 망에서 목적지로 갈 수 있는 안전하고 빠른 경로를 계산하기 위해 활용되는 프로토콜이라고 할 수 있습니다. BGP는 대규모 네트워크 그룹(Autonomous System, AS)을 운영하는 대규모 ISP(Ineteret Service Provider)들이 서로의 네트워크 트래픽을 주고 받기 위한 피어링(Peering) 계약을 기반으로 합니다. BGP 라우터는 서로 다른 AS들이 주고 받은 피어링 계약을 기반으로 패킷을 보낼 최적 경로를 계산합니다. 일반적으로 네트워크 홉이 가장 작은 경로가 선택됩니다.
BGP in Calico
- Ssup2 blog, IP-in-IP, GRE Tunneling
- calico는 라우팅 옵션의 기본 값으로 IP-in-IP 프로토콜을 사용
- IP-in-IP 프로토콜은 기존의 IP 헤더에 터널의 IP 주소 정보가 포함된 Outer IP 헤더를 추가하여 터널링을 구현한 프로토콜로, calico는 이를 활용하여 overlay 네트워크를 구성
- calico는 내부적으로 목적지 팟이 위치한 노드를 찾기 위해 BGP 프로토콜이 활용
- 따라서, BGP 피어링을 위해 179번 포트에 대한 방화벽 정책을 허용
$ sudo apt install firewalld -y
$ sudo firewall-cmd --permanent --zone=public --add-port=179/tcp
$ sudo firewall-cmd --reload
SG group 에 179 tcp 포트를 열고, 위와같이 방화벽을 연후에 아래의 kubespray삭제, kubespray 재설치를 통해 calico-node pod가 정상적으로 떴습니다.
*에러해결 Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")
삭제 후 재설치시 위와 같은 에러 문구가 나온다면 아래 명령어로 해결합니다.
unset KUBECONFIG
export KUBECONFIG=/etc/kubernetes/admin.conf
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
7. kubespray 삭제(선택)
$ ansible-playbook -i ${SPIDYWEB_WORKSPACE}/kubespray/inventory/spidyweb-cluster/hosts.yaml --become --become-user=root ${SPIDYWEB_WORKSPACE}/kubespray/reset.yml
이것으로 kubernetes cluster with kubespray on AWS ec2 포스팅을 마치겠습니다.
다음 포스트에는 설치한 kubernetes 클러스터로 사용 예시에 대해 포스트하겠습니다.
*ansible-playbook 명령어 사용 방법 - https://docs.ansible.com/ansible/latest/user_guide/playbooks.html
*ansible playbook에 대한 자세한 설명 - https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html
참조:
https://lindarex.github.io/kubernetes/ubuntu-kubernetes-installation-with-kubespray/
https://velog.io/@seokbin/Kubernetes-%EC%84%A4%EC%B9%98With-kubespray
https://github.com/kubernetes-sigs/kubespray/blob/master/docs/ansible.md#installing-ansible