RKE K8S Cluster

RKE ile Kubernetes Cluster Kurulumu (HA)

Öncelikle Kubernetes cluster'ınızı yöneteceğiniz bir (management) sunucu belirleyelim. Bu ayrıca kurduğunuz bir sanal sunucu veya lokal cihazınız da olabilir. Tam hakimiyet açısından Linux bir sunucu üzerinden işlemleri yapmanız daha sağlıklı olacaktır. Windows bir cihaza sahipseniz Microsoft Store üzerinden hızlı ve ücretsiz bir şekilde Ubuntu 18 indirerek adımlara devam edebilirsiniz.

Ön Şartlar

İlk olarak kurulumu yapacağımız sunucu üzerine RKE (Rancher Kubernetes Engine) indirmemiz gerekiyor. RKE GitHub sayfasından işletim sisteminiz ve mimariniz için geçerli olan en güncel sürümü indirebiliriz.

  • macOS: rke_darwin-amd64
  • Linux (Intel/AMD): rke_linux-amd64
  • Linux (ARM 32-bit): rke_linux-arm
  • Linux (ARM 64-bit): rke_linux-arm64
  • Windows (32-bit): rke_windows-386.exe
  • Windows (64-bit): rke_windows-amd64.exe

Yazının başında da belirttiğim gibi Linux üzerinden devam ediyoruz. wget komutu ile konsol üzerinde aşağıdaki gibi indirme işlemini gerçekleştiriyoruz.

root@kubernetesturkey:~# wget https://github.com/rancher/rke/releases/download/v1.1.4/rke_linux-amd64
--2020-07-28 18:47:40--  https://github.com/rancher/rke/releases/download/v1.1.4/rke_linux-amd64
Resolving github.com (github.com)... 
Connecting to github.com (github.com)|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: ...
Saving to: ‘rke_linux-amd64’

rke_linux-amd64               100%[=================================================>]  37.95M  12.2MB/s    in 4.1s

2020-07-28 18:47:46 (9.15 MB/s) - ‘rke_linux-amd64’ saved [39793294/39793294]

root@kubernetesturkey:~#

Akabinde mv rke_linux-amd64 rke komutu ile indirdiğimiz klasörün adını rke olarak değiştiriyoruz ve chmod +x rke komutu ile dosyayı çalıştırabilir hale getiriyoruz.

Bulunduğumuz dizinde ./rke -v komutu ile sürüm kontrolümüzü yapıp RKE'nin çalıştığını doğruluyoruz.

root@kubernetesturkey:~# ./rke -v
rke version v1.1.4

NOT: Aşağıdaki gibi bir hata alırsanız uyumsuz bir rke paketi indirmiş olabilirsiniz. İndirdiğiniz dosyayı silip, işletim sisteminiz ve mimarinize göre kontrol ederek tekrar yükleyiniz.

root@kubernetesturkey:~# ./rke -v
bash: ./rke: cannot execute binary file: Exec format error

Kubernetes Cluster'ına Bağlanacak Sunucuları Hazırlama

Öncelikle mimarinize göre bir node (sunucu) sayısı belirleyip sunucu kurulumlarını yapmanız gerekmektedir. Ben örnek olarak 3 master (controlplane, etcd) ve 3 worker node'u olan bir yapı kuracağım. Load Balancer olarak da NGINX kullanacağım. Eğer kullanabileceğiniz bir fiziksel cihaz var ise Load Balancing işlemini oradan da yapabilirsiniz. NGINX ile isteklerin worker node'lara Layer 4 yük dengeleyici (TCP) olarak iletmesini sağlayacağız. Buradaki Load Balancer görevini cluster node'larımızın dışında bir sunucu üzerine kurmamız daha sağlıklı olacaktır. Dolayısıyla 1 adet de NGINX (Load Balancer) için sunucu kuracağız.

Node işletim sistemlerini Linux - Centos7 olarak tercih ediyorum. 7 adet Centos 7 sunucu (3 master, 3 worker, 1 LB) kurulumunu tamamlayıp adımlara devam ediyoruz. Cluster'ımızı ayağa kaldırmadan önce bağlanacak node'lar üzerinde yapılması gereken çalışmalar mevcuttur. Bunları sizler için komut satırları halinde aşağıda paylaşıyorum.

  • Node üzerine docker yükleme ve gerekli konfigürasyon ayarları;

Her Kubernetes sürümü farklı Docker sürümlerini destekler. Kubernetes sürüm notlarında güncel desteklenen Docker sürümlerini bulabilirsiniz. Yüklemeden önce Docker sürümü uyumluluğunu kontrol etmenizde fayda olacaktır.

yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum update -y && yum install -y containerd.io-1.2.13 docker-ce-19.03.8 docker-ce-cli-19.03.8
mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
  "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
mkdir -p /etc/systemd/system/docker.service.d
systemctl enable docker
systemctl daemon-reload
systemctl restart docker
  • RKE için kullanıcı oluşturma, grup ataması, SSH Key ve gerekli sysctl konfigürasyonları;
useradd rke
sudo usermod -aG docker rke
mkdir /home/rke/.ssh
chown rke. /home/rke/.ssh
cp -r /root/.ssh/authorized_keys /home/rke/.ssh/.
chown rke. /home/rke/.ssh/authorized_keys

cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

NOT: Docker grubuna eklenen kullanıcılara, Docker API aracılığıyla sunucuda root izinleri verilir. Bu yüzden buradaki rke kullanıcısını yalnızca bu amaç doğrultusunda kullanıp bu user'ı güvenli tutarak başka bir yerde kullanmamalısınız. Bunu istemiyor ve root erişimini kullanmadan bir user üzerinden ilerlemek istiyor iseniz bu makale üzerinden non-root user ile ilerleyebilirsiniz.

  • Kurulum aşamasında güvenlik duvarına takılmamak için güvenlik duvarlarını kapatma ve gerekli linux konfigürasyonları;
systemctl disable firewalld
systemctl stop firewalld
systemctl disable iptables
systemctl stop iptables
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
echo '1' > /proc/sys/net/ipv4/ip_forward

Platformunuzda fiziksel güvenlik duvarları üzerinden erişimler varsayılan olarak kapalı ise Rancher dokümanlarında verilen bu ilgili port'ların gerekli kurallar ile açılması sağlanmalıdır. Yazılımsal olarak düzenleme yapacaksanız da aynı şekilde portlar için iptables veya firewalld üzerinde gerekli kural tanımlamalarını yapabilirsiniz.

  • Node SSH Konfigürasyonu;

/etc/ssh/sshd_config konumunda bulunan SSH yapılandırma dosyanızda, TCP yönlendirmesine izin veren bu satır bulunmalıdır;
AllowTcpForwarding yes

Bu komutları tüm node'larımıza tek tek gönderdiğimizde cluster'a bağlanacak node'ları hazırlamış oluyoruz.

  • NGINX - Load Balancing işlemi için kurduğumuz sunucu üzerinde;

NGINX kurulumunu yaptıktan sonra /etc/nginx/nginx.conf dosyamızı aşağıdaki gibi güncelliyoruz;

worker_processes 4;
worker_rlimit_nofile 40000;

events {
    worker_connections 8192;
}

stream {
    upstream rancher_servers_http {
        least_conn;
        server <WORKER_NODE1_IP>:80 max_fails=3 fail_timeout=5s;
        server <WORKER_NODE2_IP>:80 max_fails=3 fail_timeout=5s;
        server <WORKER_NODE3_IP>:80 max_fails=3 fail_timeout=5s;
    }
    server {
        listen 80;
        proxy_pass rancher_servers_http;
    }

    upstream rancher_servers_https {
        least_conn;
        server <WORKER_NODE1_IP>:443 max_fails=3 fail_timeout=5s;
        server <WORKER_NODE2_IP>:443 max_fails=3 fail_timeout=5s;
        server <WORKER_NODE3_IP>:443 max_fails=3 fail_timeout=5s;
    }
    server {
        listen     443;
        proxy_pass rancher_servers_https;
    }

}

Conf dosyamızı düzenledikten sonra nginx -s reload komutu ile yeniden yüklenmesini sağlıyoruz.

NOT: Daha spesifik Load Balancing işlemleri için NGINX dokümanlarını inceleyebilirsiniz.

Şimdi ise cluster konfigürasyon dosyamızı (cluster.yml) hazırlamaya geçiyoruz.

Cluster Konfigürasyon Dosyası (cluster.yml) Oluşturma

RKE, bizden cluster'a ekleyeceğimiz node'ların bilgilerini ve rollerini nasıl dağıtacağımızı vb. bilgileri içeren bir yml dosyası beklemektedir. Deploy yapabilmek için bu dosyamızı hazırlamamız gerekiyor.

cluster.yml oluşturmanın iki kolay yolu vardır:

  • Rancher'ın sunmuş olduğu cluster.yml dosyalarını kendimize göre güncellemek.
  • rke config komutunu kullanarak gerekli tüm bilgileri doldurmak.
rke config kullanarak cluster.yml oluşturma;

Yazının başında yüklediğimiz rke'nin dizinine giderek ./rke config --name cluster.yml komutunu yazdığımızda bize gerekli tüm bilgileri tek tek soracaktır. Soruları yanıtladığımızda ise aynı dizinde yml dosyamızın oluştuğunu göreceğiz.

root@kubernetesturkey:~# ./rke config --name cluster.yml
[+] Cluster Level SSH Private Key Path [~/.ssh/id_rsa]:
[+] Number of Hosts [1]: 6
[+] SSH Address of host (1) [none]: 10.10.10.1
[+] SSH Port of host (1) [22]:
[+] SSH Private Key Path of host (10.10.10.1) [none]:
[-] You have entered empty SSH key path, trying fetch from SSH key parameter
[+] SSH Private Key of host (10.10.10.1) [none]:
[-] You have entered empty SSH key, defaulting to cluster level SSH key: ~/.ssh/id_rsa
[+] SSH User of host (10.10.10.1) [ubuntu]:
[+] Is host (10.10.10.1) a Control Plane host (y/n)? [y]: y
[+] Is host (10.10.10.1) a Worker host (y/n)? [n]: n
[+] Is host (10.10.10.1) an etcd host (y/n)? [n]: y
[+] Override Hostname of host (10.10.10.1) [none]:
[+] Internal IP of host (10.10.10.1) [none]:
[+] Docker socket path on host (10.10.10.1) [/var/run/docker.sock]:
[+] SSH Address of host (2) [none]:
[+] SSH Port of host (2) [22]:
[+] SSH Private Key Path of host () [none]:
[-] You have entered empty SSH key path, trying fetch from SSH key parameter
[+] SSH Private Key of host () [none]:
[-] You have entered empty SSH key, defaulting to cluster level SSH key: ~/.ssh/id_rsa
[+] SSH User of host () [ubuntu]:
[+] Is host () a Control Plane host (y/n)? [y]:
[+] Is host () a Worker host (y/n)? [n]:
[+] Is host () an etcd host (y/n)? [n]:
[+] Override Hostname of host () [none]:
[+] Internal IP of host () [none]:
[+] Docker socket path on host () [/var/run/docker.sock]:
...
...
...
[+] SSH Port of host (6) [22]:
[+] SSH Private Key Path of host () [none]:
[-] You have entered empty SSH key path, trying fetch from SSH key parameter
[+] SSH Private Key of host () [none]:
[-] You have entered empty SSH key, defaulting to cluster level SSH key: ~/.ssh/id_rsa
[+] SSH User of host () [ubuntu]:
[+] Is host () a Control Plane host (y/n)? [y]:
[+] Is host () a Worker host (y/n)? [n]:
[+] Is host () an etcd host (y/n)? [n]:
[+] Override Hostname of host () [none]:
[+] Internal IP of host () [none]:
[+] Docker socket path on host () [/var/run/docker.sock]:
[+] Network Plugin Type (flannel, calico, weave, canal) [canal]:
[+] Authentication Strategy [x509]:
[+] Authorization Mode (rbac, none) [rbac]:
[+] Kubernetes Docker image [rancher/hyperkube:v1.18.6-rancher1]:
[+] Cluster domain [cluster.local]:
[+] Service Cluster IP Range [10.43.0.0/16]:
[+] Enable PodSecurityPolicy [n]:
[+] Cluster Network CIDR [10.42.0.0/16]:
[+] Cluster DNS Service IP [10.43.0.10]:
[+] Add addon manifest URLs or YAML files [no]:

Soruları görmeniz adına birçoğunu boş bırakıp bir yml dosyası oluşturdum. Başka bir tercih ise ./rke config --empty --name cluster.yml komutu ile boş bir yml oluşturup içini düzenlemek olabilir.

Benim hazırladığım örnek minimal cluster.yml'ım aşağıdaki gibidir;

nodes:
  - address: 10.10.10.1
    user: rke
    role: [controlplane,etcd]
  - address: 10.10.10.2
    user: rke
    role: [controlplane,etcd]
  - address: 10.10.10.3
    user: rke
    role: [controlplane,etcd]
  - address: 10.10.10.4
    user: rke
    role: [worker]
  - address: 10.10.10.5
    user: rke
    role: [worker]
  - address: 10.10.10.6
    user: rke
    role: [worker]

ssh_key_path: ~/.ssh/id_rsa
cluster_name: k8s-kubernetesturkey

services:
  etcd:
    backup_config:
      enabled: true
      interval_hours: 12
      retention: 6
      safe_timestamp: false
    creation: 12h
    retention: 72h
    snapshot: true
  kube-api:
    service_cluster_ip_range: 10.43.0.0/16
  kube-controller:
    cluster_cidr: 10.42.0.0/16
    service_cluster_ip_range: 10.43.0.0/16
  kubelet:
    cluster_domain: k8s.kubernetesturkey.local
    cluster_dns_server: 10.43.0.10
    generate_serving_certificate: false
    
network:
  plugin: flannel
ingress:
  provider: nginx

Buradaki değerler ve anlamlarını detaylı bir şekilde görmek için ilgili sayfayı ziyaret edebilirsiniz.

RKE ile Kubernetes Deploy Etme

cluster.yml dosyamızı hazırladıktan sonra aynı dizinde ./rke up komutu ile deploy işlemini başlatabilirsiniz.

root@kubernetesturkey:~# ./rke up

INFO[0000] Building Kubernetes cluster
INFO[0000] [dialer] Setup tunnel for host [10.10.10.1]
INFO[0000] [network] Deploying port listener containers
INFO[0000] [network] Pulling image [alpine:latest] on host [10.10.10.1]
...
...
...
INFO[0101] Finished building Kubernetes cluster successfully

"Finished building Kubernetes cluster successfully" yazısını gördüğümüzde işlem tamam!

Aynı dizine kube_config_cluster.yml dosyası oluşacak ve içerisinde kubeconfig'inizi görebileceksiniz. Bu kubeconfig ile cluster'ınızı yönetebilirsiniz.

NOT: Cluster'ı korumak, sorun gidermek ve sürüm yükseltmek gibi işlemlerde ihtiyaç olabileceği için aşağıdaki 3 dosyayı bir yere yedeklemenizi tavsiye ederim.

  • cluster.yml
  • kube_config_cluster.yml
  • cluster.rkestate

RKE ile Kubernetes Cluster kurulum işlemimiz tamamlandı. Uygulamalarınızı deploy etmeye başlayabilirsiniz. 🙂

Yorum Yapın