Установка одноузлового Kubernetes кластера

Пошаговая инструкция по установке и настройке одноузлового Kubernetes кластера с использованием kubeadm на Rocky Linux с containerd в качестве CRI.

Подготовка системы

Отключение systemd-resolved

Первым делом необходимо отключить systemd-resolved, так как он может конфликтовать с настройками DNS:

systemctl disable systemd-resolved.service --now
rm -rf /etc/resolv.conf
systemctl restart NetworkManager

Установка компонентов

Установка containerd

На Rocky Linux с containerd выполните следующие шаги:

dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf install containerd.io -y
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
sudo systemctl restart containerd

Важно: Обновите версию pause-контейнера:

sudo sed -i 's/sandbox_image \= "registry.k8s.io/pause:3.8"/sandbox_image \= "registry.k8s.io/pause:3.10"/g' /etc/containerd/config.toml

Добавление репозитория Kubernetes

Добавьте официальный репозиторий Kubernetes:

cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.34/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.34/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF

Установка kubelet, kubeadm и kubectl

sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
sudo systemctl enable --now kubelet

Настройка сети и firewall

Настройка правил firewall

Если используется firewall, добавьте необходимые порты:

firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --add-port=6443/tcp --permanent
firewall-cmd --add-port=10250/tcp --permanent
sudo firewall-cmd --permanent --add-port={6443,2379,2380,10250,10251,10252,10257,10259,179}/tcp
firewall-cmd --reload

Настройка параметров ядра

Добавьте необходимые параметры ядра:

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sudo sysctl --system

Установка утилит и загрузка модулей ядра

Установите утилиты для управления трафиком (опционально):

dnf install iproute-tc

Загрузите необходимые модули ядра:

sudo sh -c 'echo "br_netfilter" > /etc/modules-load.d/br_netfilter.conf'
sudo sh -c 'echo "overlay" > /etc/modules-load.d/overlay.conf'
sudo modprobe overlay
sudo modprobe br_netfilter

Инициализация кластера

Запуск kubeadm init

Инициализируйте кластер:

kubeadm init --pod-network-cidr 10.244.0.0/16

Или используйте другой CIDR:

kubeadm init --pod-network-cidr 10.250.0.0/16

После успешной инициализации выполните команды, которые выведет kubeadm для настройки kubectl.

Снятие taint с control plane ноды

Для однопузлового кластера необходимо снять taint, чтобы на control plane ноде могли запускаться обычные поды:

kubectl taint nodes --all node-role.kubernetes.io/control-plane-

Настройка CNI для REDOS

Для REDOS создайте символические ссылки:

for i in $(ls /usr/libexec/cni/); do ln -s /usr/libexec/cni/$i /opt/cni/bin/$i; done

Установка сетевого плагина

Установка Flannel

Установите Flannel CNI:

kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

Примечание: Если возникнут проблемы с Flannel, выполните:

rm -f /etc/cni/net.d/*flannel*
# Удалите поды Flannel
kubectl delete pods -n kube-flannel --all
systemctl restart kubelet

Установка Kubernetes Dashboard

Установка через Helm

Рекомендуется устанавливать Dashboard через Helm:

helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/

Получите значения по умолчанию:

helm show values kubernetes-dashboard/kubernetes-dashboard > 10-k8s-dashboard.yml

Настройка Metrics Server

Добавьте конфигурацию для включения metrics-server в файл значений:

metrics-server:
  enabled: true
  args:
    - --kubelet-preferred-address-types=InternalIP
    - --kubelet-insecure-tls=true

Настройка Ingress

Настройте Ingress для Dashboard:

ingress:
  enabled: true
  hosts:
    - k8s-dashboard.faz.local
  useDefaultIngressClass: true
  useDefaultAnnotations: true
  pathType: ImplementationSpecific
  path: /
  issuer:
    name: default
    scope: default
  tls:
    secretName: "k8s-dashboard-faz-local-secret"

Создание административного пользователя

Создайте ServiceAccount для администратора:

kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
EOF

Создайте ClusterRoleBinding:

kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system
EOF

Создайте токен для доступа:

kubectl -n kube-system create token admin-user --duration=31536000s

Сохраните полученный токен для входа в Dashboard.

Установка Metrics Server

Установка через манифесты

Скачайте манифесты Metrics Server:

wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

Отредактируйте файл и добавьте следующие параметры в args контейнера:

- --kubelet-insecure-tls=true
- --kubelet-preferred-address-types=InternalIP

Примените манифест:

kubectl apply -f components.yaml

Или отредактируйте deployment напрямую:

kubectl edit deployment.apps/metrics-server -n kube-system

Добавьте параметр --kubelet-insecure-tls в конфигурацию.

Установка Ingress Controller

Установка ingress-nginx

Скачайте манифесты ingress-nginx:

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.13.1/deploy/static/provider/cloud/deploy.yaml

Добавьте hostNetwork: true в спецификацию deployment:

spec:
  hostNetwork: true
  containers:
  - args:
    - /nginx-ingress-controller
    - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller

Настройка IngressClass по умолчанию

Создайте или обновите IngressClass, чтобы сделать его классом по умолчанию:

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  labels:
    app.kubernetes.io/component: controller
  name: nginx
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"
spec:
  controller: k8s.io/ingress-nginx

Примените манифест:

kubectl apply -f deploy.yaml

Установка OpenEBS LVM PVC Provisioner

Установка оператора

Установите OpenEBS LVM оператор:

kubectl apply -f https://openebs.github.io/charts/lvm-operator.yaml

Создание Volume Group

Создайте Volume Group на узле:

vgcreate lv-csi /dev/sdb

Примечание: Замените /dev/sdb на ваш диск.

Создание StorageClass

Создайте StorageClass:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: lvm-sda
provisioner: local.csi.openebs.io
parameters:
  storage: "lvm"
  volgroup: "ssd_sda"
reclaimPolicy: Retain

Или для нескольких узлов:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: openebs-lvmpv
allowVolumeExpansion: true
parameters:
  storage: "lvm"
  volgroup: "lvmvg"
provisioner: local.csi.openebs.io
allowedTopologies:
- matchLabelExpressions:
  - key: kubernetes.io/hostname
    values:
      - lvmpv-node1
      - lvmpv-node2

Установка StorageClass по умолчанию

Установите StorageClass по умолчанию:

kubectl patch storageclass openebs-lvmpv -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

Создание PVC

Создайте PersistentVolumeClaim для тестирования:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: csi-lvmpv
spec:
  storageClassName: openebs-lvmpv
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi

Установка cert-manager

Установка cert-manager

Установите cert-manager для управления TLS сертификатами:

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.3/cert-manager.yaml

Настройка DNS для cert-manager

Если возникают проблемы с генерацией сертификатов, измените параметры DNS в deployment cert-manager:

kubectl edit deployment.apps/cert-manager -n cert-manager

Добавьте параметры:

spec:
  containers:
  - args:
    - --v=2
    - --cluster-resource-namespace=$(POD_NAMESPACE)
    - --leader-election-namespace=kube-system
    - --acme-http01-solver-image=quay.io/jetstack/cert-manager-acmesolver:v1.17.2
    - --max-concurrent-challenges=60
    - --acme-http01-solver-nameservers="172.20.3.8:53"

Настройка Dashboard с Ingress и cert-manager

Создание namespace и сертификата

Создайте namespace для Dashboard:

kubectl create namespace k8s-dashboard

Создайте Certificate с использованием cert-manager:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: k8s-dashboard
  namespace: k8s-dashboard
spec:
  commonName: 'k8s-dashboard.faz.local'
  dnsNames:
    - k8s-dashboard.faz.local
  issuerRef:
    name: ipa
    kind: ClusterIssuer
  privateKey:
    algorithm: RSA
    encoding: PKCS1
    size: 4096
  secretName: k8s-dashboard-faz-local-secret

Примечание: Убедитесь, что у вас настроен ClusterIssuer с именем ipa или измените issuerRef на ваш.

Пример: Создание PostgreSQL для Keycloak

Пример создания ConfigMap для PostgreSQL:

apiVersion: v1
kind: ConfigMap
metadata:
  name: pgsql-keycloak-secret
  labels:
    app: postgres
data:
  POSTGRES_DB: keycloak-db
  POSTGRES_USER: keycloak-user
  POSTGRES_PASSWORD: P@ssw0rd@987

Важно: В production используйте Secret вместо ConfigMap для хранения паролей.

Заключение

После выполнения всех шагов у вас будет полностью настроенный однопузловой Kubernetes кластер с:

  • Kubernetes Dashboard
  • Metrics Server
  • Ingress Controller (nginx)
  • OpenEBS LVM для динамического выделения хранилища
  • cert-manager для управления TLS сертификатами

Кластер готов к развертыванию приложений и дальнейшей настройке.