Kubespray로 k8s 클러스터 배포

Jul 21, 2018



k8s 클러스터를 구축하기 위한 방법이 여러가지가 있는데, Kubespray를 사용하여 간단히 k8s 클러스터를 구축하는 방법을 소개해본다.

Kubespray는 Ansible로 Deploy 하기 때문에, 기본적으로 Ansible에 대한 지식이 필요하다. 여기서는 별도로 Ansible에 대한 언급은 하지 않는다.

Step 1. Kubespray를 cloen 받는다.

우선 Kubespray를 clone 받고, requirements.txt 내의 디펜던시를 설치한다.

$ git clone https://github.com/kubernetes-incubator/kubespray.git
$ cd kubespray
$ pip install requirements.txt

Step 2. k8s 클러스터를 이룰 호스트들을 준비한다.

여기서는 master 노드 1대와 kubelet 노드 2대, 그리고 ingress 노드를 1대 준비하였다. OS는 모두 CentOS 7.5 이다.

- kube-master:
  - Hostname: k8s-master1
    IP: 192.168.11.100
- kube-node:
  - Hoestname: k8s-node1
    IP: 192.168.11.101
  - Hostname: k8s-node2
    IP: 192.168.11.102
- kube-ingress:
  - Hostname: k8s-ingress1
    IP: 192.168.11.103

Step 3. 인벤토리를 생성한다.

Kubespray는 인벤토리 빌더로 쉽게 인벤토리를 생성할 수 있다. 여기서는 git에 있는 예제와 동일하게 mycluster 라는 이름으로 인벤토리를 생성한다.

# Copy ``inventory/sample`` as ``inventory/mycluster``
$ cp -rfp inventory/sample inventory/mycluster

# Update Ansible inventory file with inventory builder
$ declare -a IPS=(192.168.11.100 192.168.11.101 192.168.11.102 192.168.11.103)
$ CONFIG_FILE=inventory/mycluster/hosts.ini python3 contrib/inventory_builder/inventory.py ${IPS[@]}

이 후, 다음과 같이 인벤토리가 생성된다.

$ tree inventory/mycluster/
inventory/mycluster/
├── group_vars
│   ├── all.yml
│   └── k8s-cluster.yml
└── hosts.ini

Step 4. hosts.ini에서 호스트 및 그룹를 정의한다.

Step 2에서 생성한 호스트에 맞춰 hosts.ini를 수정해준다. 여기서 ansible_ssh_user를 지정한 이유는 ssh에 root 계정을 사용하지 않기 때문이다.

[all]
k8s-master1     ansible_host=192.168.11.100 ansible_ssh_user=operator ansible_become=yes
k8s-node1       ansible_host=192.168.11.101 ansible_ssh_user=operator ansible_become=yes
k8s-node2       ansible_host=192.168.11.102 ansible_ssh_user=operator ansible_become=yes
k8s-ingress1    ansible_host=192.168.11.103 ansible_ssh_user=operator ansible_become=yes

[k8s-cluster:children]
kube-master
kube-node
kube-ingress

[kube-master]
k8s-master1

[kube-node]
k8s-node1
k8s-node2

[kube-ingress]
k8s-ingress1

[etcd]
k8s-master1

[vault]
k8s-master1

Step 5. group_vars 내의 설정을 변경한다.

여기서 모든 설정을 언급하기는 어려우므로, 최소한의 설정 변경만으로 배포해본다.

  • Path: inventory/mycluster/group_vars/all.yml
# Valid bootstrap options (required): ubuntu, coreos, centos, none
bootstrap_os: centos
  • Path: inventory/mycluster/group_vars/k8s-cluster.yml
# Users to create for basic auth in Kubernetes API via HTTP
kube_api_pwd: (패스워드를 입력해준다)

# change to 0.0.0.0 to enable insecure access from anywhere (not recommended)
# 테스트 목적이라면 API의 insecure 포트를 열어두면 편하다.
kube_apiserver_insecure_bind_address: 0.0.0.0

# Nginx ingress controller deployment
ingress_nginx_enabled: true

# fail with swap on (default true)
# 준비한 노드가 Swap 영역이 존재하기 때문에, Swap이 있으면 배포를 중단하는 구문을 무시한다.
kubelet_fail_swap_on: false

Step 6. 실제 배포를 진행한다.

호스트 및 인벤토리가 준비되었으므로, 이제 배포를 진행한다.

$ ansible-playbook -i inventory/mycluster/hosts.ini cluster.yml

호스트의 성능에 따라 다르나, 여기서는 4대 / SSD 구성으로 30분 정도 소요되었다.


Step 7. 배포된 k8s 클러스터를 점검한다.

Ansible이 끝까지 성공적으로 완료되었다면 ssh로 master 노드에 들어간 다음, 아래의 명령어들을 입력해본다.

$ kubectl cluster-info
Kubernetes master is running at https://192.168.11.100:6443
KubeDNS is running at https://192.168.11.100:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
kubernetes-dashboard is running at https://192.168.11.100:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy
...
$ kubectl -n kube-system get all
NAME                                        READY     STATUS    RESTARTS   AGE
pod/calico-node-l2sqn                       1/1       Running   0          8m
pod/calico-node-rtx9z                       1/1       Running   0          8m
pod/calico-node-scqmn                       1/1       Running   0          8m
pod/kube-apiserver-k8s-master1              1/1       Running   0          11m
...

배포가 정상적으로 완료되었다면, 큰 문제없이 API 요청에 성공한다.

참고로 kubectl을 사용하기 위한 config 파일은 master 노드의 ~/.kube/config에 존재한다.