Bu doküman, RHEL (Red Hat Enterprise Linux) 8.x / 9.x işletim sistemine sahip bir sunucuya Kubernetes versiyon 1.31 kurulumunu anlatmaktadır. Red Hat 8.6 İşletim sisteminin olması tavsiye edilir.

Kuruluma Başlamadan Önce Yapılması Gereken Kontroller


Çok Önemli

Kurulumlara başlamadan önce mutlaka sunucunun hostname'nin localhost.localdomain olmadığından ve her birinin eşsiz olduğundan (hostname komutu ile) emin olun. Eğer bu şekilde ise mutlaka işlemlere başlamadan önce değiştirin.

#(Gerekirse) Hostname değiştirme

hostnamectl set-hostname your-new-hostname
POWERSHELL

/etc/hosts dosyasında 127.0.1.1 gibi ip'li blok hostname assign olmasın.

/etc/resolv.conf dosyasında "nameserver 127.0.1.1" şeklinde bir girdi olmamalıdır.


Çok Önemli

Eğer internete erişim için Proxy gerekiyorsa aşağıdaki kodlar çalıştırılmalıdır.


#Linux Shell üzerinde aşağıdakileri çalıştırın:

export http_proxy=http://proxyIp:port/ 
export https_proxy=http://proxyIp:port/
export no_proxy=localhost,127.0.0.1,SERVERIP,*.hostname
POWERSHELL


#Aşağıdaki dosyalara altındaki kodları ekleyiniz:

sudo vi /etc/apt/apt.conf

Acquire::http::Proxy "http://username:password@proxyIp:port";
Acquire::https::Proxy "https://username:password@proxyIp:port";
POWERSHELL

sudo vi /etc/systemd/system/docker.service.d/proxy.conf

[Service]
Environment="HTTP_PROXY=http://proxyIp:port"
Environment="HTTPS_PROXY=https://proxyIp:port"
Environment="NO_PROXY="localhost,127.0.0.1,::1,SERVERIP,*.hostname"
POWERSHELL


#1) İşletim Sistemi Konfigürasyonları (Tüm Sunucularda Yapılacaktır)

# Refresh your cache of enabled yum repositories.
dnf makecache --refresh

# Execute following dnf command to update your Rocky Linux server.
dnf update -y

# Aşağıdaki araçların tüm sunucular üzerinde kurulu olması tavsiye edilmektedir.
sudo dnf install -y net-tools yum-utils bind-utils  device-mapper-persistent-data lvm2 telnet wget zip curl lsof

# Apinizer kullanıcısı oluşturulur ve yetkilendirilir.
sudo adduser apinizer
sudo passwd apinizer
sudo usermod -aG wheel apinizer  

# Kullanıcıya geçilerek işlemlere devam edilir
su - apinizer

# Güvenlik duvarı kapatılır
sudo systemctl stop firewalld
sudo systemctl disable firewalld

# Sunuculardaki iletişim sorunlarını önlemek için SELinux'u devre dışı bırakılır.
sudo setenforce 0 
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

# Swap kapatılır ve yeniden başlamasının önlenmesi için /etc/fstab dosyası içindeki swap satırı silinir.
sudo swapoff -a
sudo vi /etc/fstab
# Daha sonra vi dosyasını kapatılır (:wq) 
POWERSHELL

#2) Kubernetes Kurulumu

#2.1) Konteyner Kurulumu (Tüm Kubernetes Sunucularında Yapılacaktır)


Kubernetes kurulumuna geçmeden önce sistemi hazırlamak ve Docker'ı yüklemek için aşağıdaki adımlar izlenir.

#Modüllerin çalışmakta olan sistemde yüklenmeleri için
sudo modprobe overlay
sudo modprobe br_netfilter

sudo tee /etc/modules-load.d/k8s.conf <<EOF
overlay
br_netfilter
EOF


#sysctl ayarları
sudo vi /etc/sysctl.d/k8s.conf
POWERSHELL

Buradaki ilk üç satır zorunlu olup, diğerleri ihtiyaca göre değiştirilebilinir.

net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward=1
net.ipv4.tcp_max_syn_backlog=40000
net.core.somaxconn=40000
net.core.wmem_default=8388608
net.core.rmem_default=8388608
net.ipv4.tcp_sack=1
net.ipv4.tcp_window_scaling=1
net.ipv4.tcp_fin_timeout=15
net.ipv4.tcp_keepalive_intvl=30
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_moderate_rcvbuf=1
net.core.rmem_max=134217728
net.core.wmem_max=134217728
net.ipv4.tcp_mem=134217728 134217728 134217728
net.ipv4.tcp_rmem=4096 277750 134217728
net.ipv4.tcp_wmem=4096 277750 134217728
net.core.netdev_max_backlog=300000
YML

Gerekli modüller yüklenir.

#Konfigürasyonların yüklenmesi
sudo sysctl --system

#Docker deposunun tanımlanması
sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo

sudo dnf makecache

#containerd modülünün yüklenmesi
sudo dnf install -y containerd.io


#containerd modülünün ayarları
sudo mkdir -p /etc/containerd  

sudo containerd config default | sudo tee /etc/containerd/config.toml
  
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

#containerd modülünün başlatılması
sudo systemctl restart containerd

sudo systemctl enable containerd

systemctl status containerd

POWERSHELL

Not

 # package runc-1:1.1.4-1.module+el8.7.0+16520+2db5507d.x86_64 is filtered out by modular filtering benzeri hatalar ile karşılaşılırsa aşağıdaki komut satırı uygulanır.


sudo yum remove containerd.io | sudo yum remove runc 

#2.2) Kubernetes Kurulumu (Master ve Worker sunucularda)

Kubernetes anahtarlarını ve depo adresleri sisteme yüklenir, kubernetes kurulur ve başlatılır.

sudo vi /etc/yum.repos.d/kubernetes.repo
POWERSHELL
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.31/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.31/rpm/repodata/repomd.xml.key
POWERSHELL
#Kubernetes kurulumu
sudo dnf makecache --refresh
sudo dnf install -y kubeadm-1.31.0 kubelet-1.31.0 kubectl-1.31.0

systemctl enable --now kubelet.service

#Kubernetes kurulum kontrolü ve başlatılması
kubectl version --client && kubeadm version
POWERSHELL

#2.2.1) Bash Auto-Completion (İsteğe Bağlı, Herhangi Bir Kubernetes Master Sunucusunda)

Bu işlem ile kubernetes komutlarının yazımında hız kazanılabilir.

yum install bash-completion
echo 'source <(kubectl completion bash)' >>~/.bashrc
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -o default -F __start_kubectl k' >>~/.bashrc
source ~/.bashrc
POWERSHELL

#2.2.2) Kubernetes Control Plane (Master) Başlatma

Kubernetes Kümesi oluşturmak için gerekli olan container image'lerini indirmek için aşağıdaki komutu yürütün.

Bu Node, kümedeki ilk Node olduğu için Kubernetes Control Plane olarak seçilecektir.

kubeadm config images pull

sudo kubeadm init --pod-network-cidr "10.244.0.0/16" --control-plane-endpoint "<MASTER_SERVER_HOSTNAME>" --upload-certs
POWERSHELL

Multi-Master yapısını kullanmak için diğer Master olacak node'lar aşağıdaki kod ile bağlanmalıdır.

sudo kubeadm join <MASTER_SERVER_HOSTNAME>:6443 --token <XXX> --discovery-token-ca-cert-hash sha256:<YYY> --control-plane --certificate-key <ZZZ>
BASH

Çok Önemli

#Eğer bağlantı komutu yeniden oluşturulmak istenirse aşağıdaki kodlardan ikincisinin çıktısı ilkine eklenmelidir;

kubeadm token create --print-join-command

sudo kubeadm init phase upload-certs --upload-certs


#Sonuç olarak aşağıdaki gibi bir görünümde olmalıdır:

<1. adımdaki join komutunun çıktısı> --control-plane --certificate-key <2. adımın çıktısı olan key değeri>


#Eğer kod manuel olarak oluşturulmak istenirse, aşağıdakiler kullanılır:

XXX için → kubeadm token list

YYY için → openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

ZZZ için → sudo kubeadm init phase upload-certs --upload-certs

#2.2.3) Kubernetes Master Sunucusunda Kubectl Komutunun Kullanıcı Konfigürasyonunu Ayarlama (Kubernetes Master Sunucularında)

kubectl komutlarını çalıştıracak kullanıcıda iken gerekli ayarlar yapılır.


mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown -R $(id -u):$(id -g) $HOME/.kube
POWERSHELL

Tüm oturumlar için KUBECONFIG değişkenini ayarlamak için aşağıdaki komutu yürütün.

echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> /etc/profile.d/k8s.sh
POWERSHELL

#2.2.4) Kubernetes Ağ Eklentisini Kurun (Kubernetes Master Sunucularında)


Bu kılavuzda Flannel ağ eklentisini kullanacağız. Desteklenen diğer ağ eklentilerini seçebilirsiniz. Flannel, Kubernet'ler için tasarlanmış bir Layer-3 ağ yapısını yapılandırmanın basit ve kolay bir yoludur.

vi kube-flannel.yml
POWERSHELL
---
kind: Namespace
apiVersion: v1
metadata:
  name: kube-flannel
  labels:
    k8s-app: flannel
    pod-security.kubernetes.io/enforce: privileged
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: flannel
  name: flannel
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes/status
  verbs:
  - patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: flannel
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: flannel
  name: flannel
  namespace: kube-flannel
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-flannel
  labels:
    tier: node
    k8s-app: flannel
    app: flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "EnableNFTables": false,
      "Backend": {
        "Type": "vxlan"
      }
    }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds
  namespace: kube-flannel
  labels:
    tier: node
    app: flannel
    k8s-app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
      hostNetwork: true
      priorityClassName: system-node-critical
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni-plugin
        image: docker.io/flannel/flannel-cni-plugin:v1.6.0-flannel1
        command:
        - cp
        args:
        - -f
        - /flannel
        - /opt/cni/bin/flannel
        volumeMounts:
        - name: cni-plugin
          mountPath: /opt/cni/bin
      - name: install-cni
        image: docker.io/flannel/flannel:v0.26.1
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: docker.io/flannel/flannel:v0.26.1
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
            add: ["NET_ADMIN", "NET_RAW"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: EVENT_QUEUE_DEPTH
          value: "5000"
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
        - name: xtables-lock
          mountPath: /run/xtables.lock
      volumes:
      - name: run
        hostPath:
          path: /run/flannel
      - name: cni-plugin
        hostPath:
          path: /opt/cni/bin
      - name: cni
        hostPath:
          path: /etc/cni/net.d
      - name: flannel-cfg
        configMap:
          name: kube-flannel-cfg
      - name: xtables-lock
        hostPath:
          path: /run/xtables.lock
          type: FileOrCreate
YML

Önemli

Eğer Master'ı initialize ederken podCIDR olarak 10.244.0.0/16 değerini kullanmadıysanız yukarıdaki yaml dosyasında network ayarlarını düzenlemelisiniz.

kubectl apply -f kube-flannel.yml
POWERSHELL

#2.2.5) Master Sunucu Aynı Zamanda Worker Olarak da Kullanılmak İstenirse  (Opsiyonel)

Canlı ortamlar için tavsiye edilen bir yöntem değildir.

Master'dan Worker görevini eklemek için

# Tüm Master'ları Worker yapmak için
kubectl  taint nodes --all node-role.kubernetes.io/control-plane:NoSchedule-

# Tüm Master'lara Worker görevi vermek için, bazı durumlarda master yazmak gerekiyor
kubectl taint nodes --all node-role.kubernetes.io/master:NoSchedule-

# Sadece bir Master'a Worker görevi vermek için
kubectl taint nodes <NODE_NAME> node-role.kubernetes.io/control-plane:NoSchedule-
POWERSHELL

Master'dan Worker görevini kaldırmak için

# Tüm Master'lardan Worker'lık görevini kaldırmak için
kubectl taint nodes --all node-role.kubernetes.io/control-plane:NoSchedule 

# Bazı durumlar için control-plane yerine master yazmak gerekiyor
kubectl taint nodes --all node-role.kubernetes.io/master:NoSchedule

# Sadece bir Master'dan Worker görevini kaldırmak için
kubectl taint nodes <NODE_NAME> node-role.kubernetes.io/control-plane:NoSchedule
POWERSHELL


#2.2.6) Kubernetes Worker Sunucularını Master'a Kaydetmek (Kubernetes Worker Sunucularında)


Worker sunucusunu Master'a bağlamak için bir token bilgisine ihtiyaç vardır. Bu kurulum aşamasında master node'da yazılı olarak görülecektir. Ama atlanırsa ya da tekrar görüntülemek isterseniz aşağıdaki komut kullanılabilir.

Master Node üzerinde

sudo kubeadm token create --print-join-command
POWERSHELL

Worker olacak Node(lar) üzerinde

sudo kubeadm join <MASTER_SERVER_HOSTNAME>:6443 --token xxx --discovery-token-ca-cert-hash sha256:yyy
BASH


#2.2.7) Kurulum Kontrol (Herhangi Bir Kubernetes Master Sunucusunda)


Master'dan aşağıdaki kod çalıştırıldığında Master'a ek olarak oluşturulan Node da görünüyorsa kurulum başarıyla tamamlanmış demektir.

İki dakika sonunda NotReady durumundan Ready durumuna geçmezse "kubectl describe node <NODE_NAME>" komutu ile sorun incelenmelidir.

kubectl get node

NAME         STATUS   ROLES    AGE   VERSION
k8s-master   Ready    master   5d    v1.31.0
k8s-worker1  Ready    <none>   5d    v1.31.0

BASH

#2.3) DNS Test (İsteğe Bağlı, Herhangi Bir Kubernetes Master Sunucusunda)

https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#inheriting-dns-from-the-node

kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml

kubectl get pods --namespace=kube-system -l k8s-app=kube-dns

kubectl -n kube-system get configmap coredns -oyaml

kubectl exec -i -t dnsutils -- nslookup kubernetes.default

kubectl exec -ti dnsutils -- cat /etc/resolv.conf
POWERSHELL