CentOS7-based Kubernetes Cluster Setup using Ansible (ko)

1. 소개

본 매뉴얼은 CentOS 7에서 Ansible 자동화 도구를 사용하여 multi-node kubernetes cluster의 과정을 설명합니다. master 1개, minion 2개를 설정하겠습니다.

2. 클러스터 설정

시스템 스펙과 네트워크 정보는 다음과 같습니다.

  • 시스템 스펙
Role Hostname Model CPU RAM HDD
master dns-man1 HP ProLia nt DL380p Gen8 24C HT Xeon E5-2 667@ 2.90 GHz 16GB 300GB
minion ares68 HP ProLia nt DL380p Gen8 24C HT Xeon E5-2 667@ 2.90 GHz 16GB 300GB
minion ares70 N/A 8C HT Xeon E560 6@2. 13GH z 8GB 299GB
minion ares-k26 N/A 32C HT Xeon E5-2 667v 3@3. 20GH z 32GB 600GB
  • 네트워크 정보
            |Internet|
                |
            |ext. switch|
                |
  |-------------|----------------|-----------------|
  .63          .68(10.5.4.68)  .70(10.5.4.70)  .26(10.5.6.26)
dns-man1     ares68            ares70           ares-k26
.254.189    .200.67            .200.70           .200.16
   |------------|----------------|-----------------|
                |
            |int. switch|
  • 외부 IP prefix: x.x.x (작성자가 일부러 숨김)
  • LB IP 범위: 10.5.4.0/24, 10.5.6.0/24
  • 내부 IP 범위: 192.168.0.0/16

3. 컴포넌트 설치

Kubernetes 설치는 매우 복잡하고 지루합니다. Kubernetes Cluster 설치를 자동화하기 위해 Ansible을 사용하겠습니다.

3.1. Ansible master 설정

Ansible은 기본적으로 SSH 프로토콜을 사용해서 서버들을 관리합니다.

  • no database, no daemons
  • 4개월의 릴리즈 주기
  • python-based (pip 사용이 가능합니다.)
  • Python 2.6/2.7 based (아직 python3와 호환되지 않습니다.)

ansible master를 dns-man1에 설치하도록 하겠습니다. ansible master를 설치하기 전에, 필수로 설치해야 할 패키지들이 있습니다.

  • git: git repo에서 ansible 소스를 가져오기 위해서 필요합니다.

  • python-virtualenv: 가상의 ansible 환경을 구축하기 위해서 필요합니다.

    # yum install git python-virtualenv gcc python-devel libffi-devel openssl-devel
    

이제 ansible을 설치하고 virtualenv를 설정하겠습니다.

# git clone git://github.com/ansible/ansible.git --recursive
# virtualenv ansible
# source ansible/bin/activate
(ansible)# cd ./ansible
(ansible)# source ./hacking/env-setup
(ansible)# pip install paramiko PyYAML Jinja2 httplib2 six

3.2. Ansible minions 설정

Ansible은 minion 들을 관리하기 위해 ssh 프로토콜을 사용합니다. 각각의 minion들이 인증키로서 master ssh public key를 가졌을 때 관리하는 것은 쉽습니다. 자 이제 설정해보겠습니다.

우선 master에서 ssh key를 생성해야 합니다.

# ssh-keygen

두 번째로 각각의 minion 들의 public key를 복사합니다.

# ssh-copy-id root@area68
# ssh-copy-id root@ares70

이제 ansible 환경으로 들어가 보게습니다!!!

3.3. Ansible playbook 생성

Kubernetes 컴포넌트들을 설치하고 설정하기 위해서 ansible playbook을 설치했습니다.

우선 playbook의 파일들을 받습니다.

# git clone https://our_repo/path/to/k8s_cent7.git

Playbook 파일들은 우리의 git repo에 있습니다. 이 것들은 public이 아닙니다.

k8s_cent7 디렉토리로 이동합니다. minion의 설정이 올바르게 되었는지 확인하기 위해서 master에서 minion으로 ansible ping을 실행합니다.

(ansible)# cd k8s_cent7
(ansible)# ansible -i hosts ares68 -m ping
ares68 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

README.md

kubernetes cluster를 위해 playbook은 컴포넌트를 배치합니다.

playbook은 아래와 같은 순서대로 역할을 수행합니다.

  • common role: common tasks (ntp 설정, firewalld 비활성화, 기타등등)
  • etcd role: ETCD key-value datastore on the master
  • flannel role: flannel overlay network on each minion
  • master role: kubernetes master
  • docker role: docker container engine
  • registry role: a private docker registry on the master
  • minion role: kubernetes minions

순서는 매우 중요합니다. etcd role은 반드시 flannel role 전에 play해야 합니다. 왜냐하면 flannel role이 etcd role에 의존하기 때문입니다.

The default storage backend of docker on CentOS is loopback-lvm which is not production-ready. direct-lvm을 사용하는 것을 권장합니다. 왜냐하면 docket role이 direct-lvm 저장소를 설치하기 때문입니다. docker lvm이 파티션을 사용할 수 있도록 roles/docker/vars/main.yml 파일을 수정합니다.

사용하기 위해서, 1. ‘hosts.example’ 파일을 ‘hosts’ 파일로 복사한 뒤 ‘hosts’ 파일을 편집합니다. 2. 최신 kubernetes 바이너리 파일들을 다운받아 적당한 디렉토리로 옮깁니다.

roles/minion/files/kubelet
roles/minion/files/kube-proxy
roles/master/files/kube-apiserver
roles/master/files/kube-scheduler
roles/master/files/kubectl
roles/master/files/kube-controller-manager

최신 kubernetes 바이너리 파일들은 https://github.com/kubernetes/kubernetes/releases/ 에서 다운받을  있습니다.
  1. 각각의 role, global group_vars, host_vars 파일과 같은 vars 파일들을 수정합니다.

  2. playbook 실행:

    ansible-playbook -i hosts site.yml
    

3.4. 컴포넌트 검증

클러스터가 올라왔고 실행 중인지를 검증합니다.

  • k8s 버전 얻기

    # su - ucim
    $ uc version
    Client Version: version.Info{Major:"1", Minor:"4", GitVersion:"v1.4.4", GitCommit:"3b417cc4ccd1b8f38ff9ec96bb50a81ca0ea9d56", GitTreeState:"clean", BuildDate:"2016-10-21T02:48:38Z", GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"}
    Server Version: version.Info{Major:"1", Minor:"4", GitVersion:"v1.4.4", GitCommit:"3b417cc4ccd1b8f38ff9ec96bb50a81ca0ea9d56", GitTreeState:"clean", BuildDate:"2016-10-21T02:42:39Z", GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"}
    

    k8s의 버전이 1.4.4 임을 확인할 수 있습니다.

  • master 컴포넌트가 healthy 상태인지 확인

    $ uc get cs
    NAME                 STATUS    MESSAGE              ERROR
    controller-manager   Healthy   ok
    scheduler            Healthy   ok
    etcd-0               Healthy   {"health": "true"}
    

    Kubernetes master의 모든 컴포넌트(apiserver, scheduler, controller-manager, etcd)들이 healthy 상태입니다.

  • minion들의 상태 얻기

    $ uc get nodes
    NAME          STATUS    AGE
    x.x.x.68   Ready     1m
    x.x.x.70   Ready     1m
    

    두 개의 minion 들이 master에 추가되었고 사용될 준비가 되었습니다.

결론

Ansible은 devops에게 swiss-army knife와 같습니다. Ansible을 사용한 Kubernetes cluster(master 1개, minion 2개) setup에는 약 10분이 소요됩니다.

  1. 서버를 셋팅하기 위한 시간을 줄일 수 있습니다. 모든 서버에 boiler-plate 설정을 할 필요가 없습니다.
  2. 서버들을 관리하기 위해 Infrastructure as Code(IaC)를 구현할 수 있습니다.
  3. 셋팅이 변경될 필요가 있을 때 마다 간단한 playbook을 반환합니다. 이를 통해 minion 들을 바람직한 상태로 변경할 수 있습니다.

References