Add L2 Load Balancer (#16)

Co-authored-by: Fedor Batonogov <f.batonogov@yandex.ru>
This commit is contained in:
github-actions[bot]
2024-07-27 11:35:15 +03:00
committed by GitHub
parent 55deb994c6
commit 52a3d0eb3b
31 changed files with 782 additions and 739 deletions

View File

@@ -1,6 +1,10 @@
skip_list:
- risky-file-permissions
- var-naming[no-role-prefix]
- yaml[indentation]
- run-once[task]
- no-changed-when
- partial-become[task]
exclude_paths:
- ansible/roles/haproxy_static_pods/files/haproxy.yaml

View File

@@ -3,27 +3,19 @@ kubeadm:
kubeadm_control_plane:
hosts:
kubeadm-cp-01:
ansible_host: 10.0.70.70
ansible_host: 10.0.75.81
kubeadm-cp-02:
ansible_host: 10.0.70.78
ansible_host: 10.0.75.82
kubeadm-cp-03:
ansible_host: 10.0.70.79
ansible_host: 10.0.75.83
kubeadm_nodes:
hosts:
kubeadm-node-01:
ansible_host: 10.0.70.71
ansible_host: 10.0.75.84
kubeadm-node-02:
ansible_host: 10.0.70.77
ansible_host: 10.0.75.85
kubeadm-node-03:
ansible_host: 10.0.70.74
vars:
ansible_user: infra
ansible_port: 22
test_hosts:
hosts:
kubeadm-cp-01:
ansible_host: 10.0.75.203
ansible_host: 10.0.75.86
vars:
ansible_user: infra
ansible_port: 22

View File

@@ -1,44 +1,29 @@
# Запустите сервисы как статические подсистемы
# https://github.com/kubernetes/kubeadm/blob/main/docs/ha-considerations.md#option-2-run-the-services-as-static-pods
- name: Настраиваю keepalived + haproxy
become: true
hosts:
- kubeadm_control_plane
roles:
- haproxy_static_pods
- name: Разворачиваю kubernetes кластер
# Подготовка к запуску Kubernetes кластера
- name: Подготоваливаю узлы для kubernetes кластера
become: true
hosts:
- kubeadm
handlers:
- name: Перезагружаю виртуальные машины
ansible.builtin.reboot:
tasks:
- name: Добавляю модули br_netfilter и overlay
community.general.modprobe:
name: '{{ item }}'
name: "{{ item }}"
state: present
with_items:
- br_netfilter
- overlay
# notify:
# - Перезагружаю виртуальные машины
- name: Добавляю модули br_netfilter и overlay в /etc/modules
ansible.builtin.lineinfile:
path: /etc/modules
line: '{{ item }}'
line: "{{ item }}"
create: true
with_items:
- br_netfilter
- overlay
# notify:
# - Перезагружаю виртуальные машины
- name: Включаю маршрутизацию IP и iptables для моста
ansible.posix.sysctl:
name: '{{ item }}'
name: "{{ item }}"
value: 1
state: present
with_items:
@@ -54,6 +39,9 @@
- gpg
- software-properties-common
update_cache: true
register: apt_res
retries: 5
until: apt_res is success
- name: Добавляю gpg ключ для репозиториев Kubernetes и cri-o
ansible.builtin.apt_key:
@@ -61,15 +49,21 @@
state: present
keyring: '{{ item["keyring"] }}'
with_items:
- {url: "https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key", keyring: "/etc/apt/keyrings/kubernetes-apt-keyring.gpg"}
- {url: "https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/Release.key", keyring: "/etc/apt/keyrings/cri-o-apt-keyring.gpg"}
- {
url: "https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key",
keyring: "/etc/apt/keyrings/kubernetes-apt-keyring.gpg",
}
- {
url: "https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/Release.key",
keyring: "/etc/apt/keyrings/cri-o-apt-keyring.gpg",
}
- name: Добавляю репозитории Kubernetes и cri-o
ansible.builtin.apt_repository:
repo: '{{ item }}'
repo: "{{ item }}"
state: present
with_items:
- deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/ /
- deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] https://pkgs.k8s.io/addons:/cri-o:/stable:/v1.30/deb/ /
- deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /
- name: Устанавливаю пакеты kubelet, kubeadm, kubectl и cri-o
@@ -84,7 +78,7 @@
- name: Предотвращаю обновление kubelet, kubeadm и kubectl
ansible.builtin.dpkg_selections:
name: '{{ item }}'
name: "{{ item }}"
selection: hold
with_items:
- kubelet
@@ -93,33 +87,88 @@
- name: Включаю и запускаю службы kubelet и cri-o
ansible.builtin.systemd:
name: '{{ item }}'
name: "{{ item }}"
enabled: true
state: started
with_items:
- kubelet
- crio
- name: Устанавливаю пакеты для Longhorn
# Запуск сервисов keepalived и haproxy как статических подсистем
# https://github.com/kubernetes/kubeadm/blob/main/docs/ha-considerations.md#option-2-run-the-services-as-static-pods
- name: Настраиваю keepalived + haproxy и инициализирую кластер
become: true
hosts:
- kubeadm_nodes
- kubeadm_control_plane
roles:
- haproxy_static_pods
tasks:
- name: Устанавливаю нужные пакеты
ansible.builtin.apt:
name:
- open-iscsi
- nfs-common
- bash
- curl
- grep
state: present
update_cache: true
- name: Инициализирую высокодоступный кластер
run_once: true
ansible.builtin.command: |
kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--control-plane-endpoint=10.0.75.80:8888 \
--upload-certs \
--skip-phases=addon/kube-proxy
args:
creates: /etc/kubernetes/kubelet.conf
notify:
- Создаю token для control-plane
- Создаю token для node
- Добавляю control-plane узлы в кластер
- Добавляю node узлы в кластер
handlers:
- name: Создаю token для control-plane
ansible.builtin.shell:
cmd: |
set -o pipefail
echo $(kubeadm token create --print-join-command) \
--control-plane \
--certificate-key \
$(kubeadm init phase upload-certs --upload-certs | grep -vw -e certificate -e Namespace)
executable: /bin/bash
register: join_control_plane_raw
- name: Создаю token для node
ansible.builtin.command: kubeadm token create --print-join-command
register: join_node_raw
- name: Добавляю control-plane узлы в кластер
ansible.builtin.command: "{{ join_control_plane_raw.stdout }}"
args:
creates: /etc/kubernetes/kubelet.conf
delegate_to: "{{ item }}"
loop: "{{ groups['kubeadm_control_plane'] }}"
- name: Добавляю node узлы в кластер
ansible.builtin.command: "{{ join_node_raw.stdout }}"
args:
creates: /etc/kubernetes/kubelet.conf
delegate_to: "{{ item }}"
loop: "{{ groups['kubeadm_nodes'] }}"
- name: Включаю и запускаю службы
ansible.builtin.systemd:
name: '{{ item }}'
enabled: true
state: started
with_items:
- iscsid
# Подготовка control-plane узлов
- name: Подготовка control-plane узлов для работы с kubectl
become: true
gather_facts: false
hosts:
- kubeadm_control_plane
tasks:
- name: Создаю директорию .kube
become_user: infra
ansible.builtin.file:
path: $HOME/.kube
state: directory
mode: "755"
- name: Копирую admin.conf в директорию .kube
ansible.builtin.copy:
src: /etc/kubernetes/admin.conf
dest: /home/infra/.kube/config
remote_src: true
owner: infra
group: infra
mode: "600"
- name: Копирую kube/config
run_once: true
ansible.posix.synchronize:
src: "~/.kube/config" # remote host
dest: "~/.kube/config" # localhost
mode: pull

View File

@@ -5,7 +5,7 @@ errorExit() {
exit 1
}
curl --silent --max-time 2 --insecure https://localhost:7443/ -o /dev/null || errorExit "Error GET https://localhost:7443/"
if ip addr | grep -q 10.0.70.85; then
curl --silent --max-time 2 --insecure https://10.0.70.85:7443/ -o /dev/null || errorExit "Error GET https://10.0.70.85:7443/"
curl --silent --max-time 2 --insecure https://localhost:8888/ -o /dev/null || errorExit "Error GET https://localhost:8888/"
if ip addr | grep -q 10.0.75.80; then
curl --silent --max-time 2 --insecure https://10.0.75.80:8888/ -o /dev/null || errorExit "Error GET https://10.0.75.80:8888/"
fi

View File

@@ -32,7 +32,7 @@ defaults
# apiserver frontend which proxys to the control plane nodes
#---------------------------------------------------------------------
frontend apiserver
bind *:7443
bind *:8888
mode tcp
option tcplog
default_backend apiserverbackend
@@ -46,7 +46,7 @@ backend apiserverbackend
mode tcp
option ssl-hello-chk
balance roundrobin
server 10.0.70.70 10.0.70.70:6443 check
server 10.0.70.78 10.0.70.78:6443 check
server 10.0.70.79 10.0.70.79:6443 check
server 10.0.75.81 10.0.75.81:6443 check
server 10.0.75.82 10.0.75.82:6443 check
server 10.0.75.83 10.0.75.83:6443 check
# [...]

View File

@@ -5,23 +5,23 @@ metadata:
namespace: kube-system
spec:
containers:
- image: haproxy:2.9.7
name: haproxy
livenessProbe:
failureThreshold: 8
httpGet:
host: localhost
path: /healthz
port: 7443
scheme: HTTPS
volumeMounts:
- mountPath: /usr/local/etc/haproxy/haproxy.cfg
name: haproxyconf
readOnly: true
- image: haproxy:3.0.2
name: haproxy
livenessProbe:
failureThreshold: 8
httpGet:
host: localhost
path: /healthz
port: 8888
scheme: HTTPS
volumeMounts:
- mountPath: /usr/local/etc/haproxy/haproxy.cfg
name: haproxyconf
readOnly: true
hostNetwork: true
volumes:
- hostPath:
path: /etc/haproxy/haproxy.cfg
type: FileOrCreate
name: haproxyconf
- hostPath:
path: /etc/haproxy/haproxy.cfg
type: FileOrCreate
name: haproxyconf
status: {}

View File

@@ -6,26 +6,26 @@ metadata:
namespace: kube-system
spec:
containers:
- image: osixia/keepalived:2.0.20
name: keepalived
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_BROADCAST
- NET_RAW
volumeMounts:
- mountPath: /usr/local/etc/keepalived/keepalived.conf
name: config
- mountPath: /etc/keepalived/check_apiserver.sh
name: check
- image: ghcr.io/batonogov/docker-keepalived:2.0.20
name: keepalived
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_BROADCAST
- NET_RAW
volumeMounts:
- mountPath: /usr/local/etc/keepalived/keepalived.conf
name: config
- mountPath: /etc/keepalived/check_apiserver.sh
name: check
hostNetwork: true
volumes:
- hostPath:
path: /etc/keepalived/keepalived.conf
name: config
- hostPath:
path: /etc/keepalived/check_apiserver.sh
name: check
- hostPath:
path: /etc/keepalived/keepalived.conf
name: config
- hostPath:
path: /etc/keepalived/check_apiserver.sh
name: check
status: {}

View File

@@ -1,9 +1,9 @@
# tasks file for haproxy_static_pods
- name: Создать директории /etc/kubernetes/manifests и /etc/keepalived
ansible.builtin.file:
path: '{{ item }}'
path: "{{ item }}"
state: directory
mode: '755'
mode: "755"
with_items:
- /etc/kubernetes/manifests
- /etc/keepalived
@@ -19,22 +19,22 @@
ansible.builtin.copy:
src: check_apiserver.sh
dest: /etc/keepalived/check_apiserver.sh
mode: '644'
mode: "644"
- name: Наливаю haproxy.cfg
ansible.builtin.copy:
src: haproxy.cfg
dest: /etc/haproxy/haproxy.cfg
mode: '644'
mode: "644"
- name: Наливаю keepalived static pods manifest
ansible.builtin.copy:
src: keepalived.yaml
dest: /etc/kubernetes/manifests/keepalived.yaml
mode: '644'
mode: "644"
- name: Наливаю haproxy static pods manifest
ansible.builtin.copy:
src: haproxy.yaml
dest: /etc/kubernetes/manifests/haproxy.yaml
mode: '644'
mode: "644"

View File

@@ -21,7 +21,7 @@ vrrp_instance VI_1 {
auth_pass {{ lookup('password', 'secrets/kubeadm/keepalived/auth_pass length=64') }}
}
virtual_ipaddress {
10.0.70.85/24
10.0.75.80/24
}
track_script {
check_apiserver

View File

@@ -1,13 +1,18 @@
# Настройка kubernetes кластера после чистой установки при помощи **kubeadm**
## Создание ВМ
Наш кластер работает на 6 виртуальных машинах (3 control-plane и 3 node) и разворачивается с помощью [OpenTofu](../opentofu/kubeadm).
## Подготовка ВМ
Тестирование проводилось на **Ubuntu 22.04**
Тестирование проводилось на **Ubuntu 24.04**
Подготавливаем ВМ при помощи [плейбука](../ansible/kubeadm.yml)
Плейбук настроит все что нудно для работы **Kubernetes**.
Плейбук настроит все что нужно для работы **Kubernetes**.
Добавит необходимые **модули ядра**, установит **kubelet**, **kubeadm**, **kubectl**, **cri-o**... и перезапустит машинки если это необходимо.
Также произойдет инициализация кластера в HA режиме без **kube-proxy**.
Запускаем плейбук
@@ -19,40 +24,46 @@ ansible-playbook kubeadm.yml
```output
PLAY RECAP *******************************************************************************************************
kubeadm-cp-01 : ok=19 changed=16 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
kubeadm-cp-02 : ok=19 changed=16 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
kubeadm-cp-03 : ok=19 changed=16 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
kubeadm-node-01 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
kubeadm-node-02 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
kubeadm-node-03 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
kubeadm-cp-01 : ok=28 changed=23 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
kubeadm-cp-02 : ok=22 changed=17 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
kubeadm-cp-03 : ok=22 changed=17 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
kubeadm-node-01 : ok=13 changed=11 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
kubeadm-node-02 : ok=13 changed=11 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
kubeadm-node-03 : ok=13 changed=11 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
вторник 23 апреля 2024 09:29:22 +0300 (0:00:41.104) 0:02:19.111 ********
четверг 02 мая 2024 19:33:56 +0500 (0:00:02.841) 0:04:44.638 ***********
===============================================================================
Устанавливаю пакеты kubelet, kubeadm, kubectl и cri-o ---------------------------------------------------- 51.97s
Перезагружаю виртуальные машины -------------------------------------------------------------------------- 41.10s
Добавляю репозитории Kubernetes и cri-o ------------------------------------------------------------------ 12.58s
Устанавливаю пакеты --------------------------------------------------------------------------------------- 6.54s
upgrade_packages : Обновляю все пакеты до актуальных версий ----------------------------------------------- 3.54s
Добавляю gpg ключ для репозиториев Kubernetes и cri-o ----------------------------------------------------- 2.61s
Gathering Facts ------------------------------------------------------------------------------------------- 2.53s
Gathering Facts ------------------------------------------------------------------------------------------- 2.53s
Включаю маршрутизацию IP и iptables для моста ------------------------------------------------------------- 2.19s
Включаю и запускаю службы kubelet и cri-o ----------------------------------------------------------------- 2.09s
Предотвращаю обновление kubelet, kubeadm и kubectl -------------------------------------------------------- 1.87s
haproxy_static_pods : Создать директории /etc/kubernetes/manifests и /etc/keepalived ---------------------- 1.64s
Добавляю модули br_netfilter и overlay -------------------------------------------------------------------- 1.21s
Добавляю модули br_netfilter и overlay в /etc/modules ----------------------------------------------------- 1.20s
haproxy_static_pods : Наливаю keepalived.conf ------------------------------------------------------------- 1.19s
haproxy_static_pods : Наливаю haproxy.cfg ----------------------------------------------------------------- 1.11s
haproxy_static_pods : Наливаю haproxy static pods manifest ------------------------------------------------ 1.09s
haproxy_static_pods : Наливаю check_apiserver.sh ---------------------------------------------------------- 1.07s
haproxy_static_pods : Наливаю keepalived static pods manifest --------------------------------------------- 1.03s
Добавляю control-plane узлы в кластер ------------------------------------------------ 67.74s
Инициализирую высокодоступный кластер ------------------------------------------------ 50.23s
Устанавливаю пакеты kubelet, kubeadm, kubectl и cri-o -------------------------------- 44.44s
Добавляю репозитории Kubernetes и cri-o ---------------------------------------------- 14.60s
Устанавливаю нужные пакеты ----------------------------------------------------------- 13.38s
Добавляю node узлы в кластер --------------------------------------------------------- 11.06s
Устанавливаю пакеты ------------------------------------------------------------------- 7.83s
Предотвращаю обновление kubelet, kubeadm и kubectl ------------------------------------ 4.89s
Добавляю gpg ключ для репозиториев Kubernetes и cri-o --------------------------------- 4.74s
haproxy_static_pods : Наливаю конфигурацию keepalived --------------------------------- 4.62s
haproxy_static_pods : Создать директории /etc/kubernetes/manifests и /etc/keepalived -- 4.48s
Gathering Facts ----------------------------------------------------------------------- 4.44s
Включаю и запускаю службы kubelet и cri-o --------------------------------------------- 4.30s
upgrade_packages : Обновляю все пакеты до актуальных версий --------------------------- 4.20s
Gathering Facts ----------------------------------------------------------------------- 3.70s
haproxy_static_pods : Наливаю check_apiserver.sh -------------------------------------- 3.52s
haproxy_static_pods : Наливаю haproxy.cfg --------------------------------------------- 3.31s
haproxy_static_pods : Наливаю haproxy static pods manifest ---------------------------- 3.31s
haproxy_static_pods : Наливаю keepalived static pods manifest ------------------------- 3.23s
Добавляю модули br_netfilter и overlay ------------------------------------------------ 3.21s
```
Если все прошло успешно, то можно перейти к [настройке CNI](README.md#%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-cni).
## Инициализация кластера
Первый вариант подходит для тестирования, или создания не отказоустоичивого кластера,
Второй вариант создаст отказоустойчивый кластер готовый для прода.
Ansible Playbook создает второй вариант.
Дальше описаны варианты для понимания работы.
### Non HA (Подходит для тестирования, не рекомендуется для прода)
@@ -81,10 +92,19 @@ kubeadm-node-02 Ready <none> 13s v1.30.0 10.0.70.77 <none>
### HA (Production Ready решение, рекомендуется)
Мы разместим **haproxy** и **keepalived** на **control-plane** узлах. Конфигурации налиты при помощи Ansible на этапе подготовки.
Наш виртуальный IP: **10.0.70.85:7443** для взаимодействия с **Kube Api Server**
Наш виртуальный IP: **10.0.70.85:8888** для взаимодействия с **Kube Api Server**
Обратите внимание, что мы не устанавливаем **kube-proxy**, для этого мы указали ключ **--skip-phases=addon/kube-proxy**,
этот вариант подходит при использовании **Kubernetes** без **kube-proxy** и позволяет использовать **Cilium** для его полной замены.
Если вы планируете использовать **Flannel**, нужно оставить **kube-proxy**.
```sh
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=10.0.70.85:7443 --upload-certs
sudo kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--control-plane-endpoint=10.0.70.85:8888 \
--upload-certs \
--skip-phases=addon/kube-proxy
```
При успешном выполнении мы увидим примерно следующее
@@ -108,7 +128,7 @@ Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join 10.0.70.85:7443 --token r120zn.za3vq0au6kzgoepu \
kubeadm join 10.0.70.85:8888 --token r120zn.za3vq0au6kzgoepu \
--discovery-token-ca-cert-hash sha256:cacb3c674f63d7f261c4fed403f59ce6e7d4c869c3748e301c98b2b9f17f7786 \
--control-plane --certificate-key 31ba08487b6899c2ebe43dd3857e168840a98d1077a7998c79f6f4838b4c08f7
@@ -118,7 +138,7 @@ As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you c
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 10.0.70.85:7443 --token r120zn.za3vq0au6kzgoepu \
kubeadm join 10.0.70.85:8888 --token r120zn.za3vq0au6kzgoepu \
--discovery-token-ca-cert-hash sha256:cacb3c674f63d7f261c4fed403f59ce6e7d4c869c3748e301c98b2b9f17f7786
```
@@ -131,13 +151,13 @@ kubectl get nodes -o wide
```
```output
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
kubeadm-cp-01 Ready control-plane 2m26s v1.30.0 10.0.70.70 <none> Ubuntu 22.04.4 LTS 5.15.0-105-generic cri-o://1.30.0
kubeadm-cp-02 Ready control-plane 68s v1.30.0 10.0.70.78 <none> Ubuntu 22.04.4 LTS 5.15.0-105-generic cri-o://1.30.0
kubeadm-cp-03 Ready control-plane 64s v1.30.0 10.0.70.79 <none> Ubuntu 22.04.4 LTS 5.15.0-105-generic cri-o://1.30.0
kubeadm-node-01 Ready <none> 53s v1.30.0 10.0.70.71 <none> Ubuntu 22.04.4 LTS 5.15.0-105-generic cri-o://1.30.0
kubeadm-node-02 Ready <none> 27s v1.30.0 10.0.70.77 <none> Ubuntu 22.04.4 LTS 5.15.0-105-generic cri-o://1.30.0
kubeadm-node-03 Ready <none> 37s v1.30.0 10.0.70.74 <none> Ubuntu 22.04.4 LTS 5.15.0-105-generic cri-o://1.30.0
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
kubeadm-cp-01 Ready control-plane 46m v1.30.0 10.0.70.70 <none> Ubuntu 24.04 LTS 6.8.0-31-generic cri-o://1.31.0
kubeadm-cp-02 Ready control-plane 45m v1.30.0 10.0.70.78 <none> Ubuntu 24.04 LTS 6.8.0-31-generic cri-o://1.31.0
kubeadm-cp-03 Ready control-plane 45m v1.30.0 10.0.70.79 <none> Ubuntu 24.04 LTS 6.8.0-31-generic cri-o://1.31.0
kubeadm-node-01 Ready <none> 45m v1.30.0 10.0.70.71 <none> Ubuntu 24.04 LTS 6.8.0-31-generic cri-o://1.31.0
kubeadm-node-02 Ready <none> 45m v1.30.0 10.0.70.77 <none> Ubuntu 24.04 LTS 6.8.0-31-generic cri-o://1.31.0
kubeadm-node-03 Ready <none> 45m v1.30.0 10.0.70.74 <none> Ubuntu 24.04 LTS 6.8.0-31-generic cri-o://1.31.0
```
## Настройка CNI
@@ -145,33 +165,121 @@ kubeadm-node-03 Ready <none> 37s v1.30.0 10.0.70.74 <none
**CNI (Container Network Interface)** - это спецификация, которая определяет, как контейнеры в сети взаимодействуют друг с другом и с внешним миром.
Она позволяет плагинам сети в Kubernetes управлять сетевыми настройками контейнеров.
Мы установим простой плагин **Flannel**
### Cilium
**Flannel** - это один из плагинов сети для Kubernetes, который обеспечивает сетевую подсистему для контейнеров.
Он позволяет контейнерам в кластере общаться друг с другом и с внешним миром, обеспечивая сетевую изоляцию и маршрутизацию.
**Cilium** - это проект с открытым исходным кодом для обеспечения сетевого взаимодействия, безопасности и наблюдаемости для облачных сред,
таких как кластеры **Kubernetes** и другие платформы для оркестровки контейнеров.
Настраиваем **Flannel**:
В основе **Cilium** лежит новая технология ядра **Linux** под названием **eBPF**,
которая позволяет динамически вставлять в ядро Linux мощную логику управления безопасностью, видимостью и сетями.
**eBPF** используется для обеспечения высокопроизводительных сетей, мультикластерных и мультиоблачных возможностей,
расширенной балансировки нагрузки, прозрачного шифрования, широких возможностей сетевой безопасности, прозрачной наблюдаемости и многого другого.
Есть несколько вариантов установки **Cilium**
#### **Cilium CLI**
Установите последнюю версию **Cilium CLI**. **Cilium CLI** можно использовать для установки **Cilium**, проверки состояния установки **Cilium**,
а также для включения/выключения различных функций (например, кластерной сетки, Hubble).
```sh
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
brew install cilium-cli
```
Проверяем
Установите Cilium в кластер Kubernetes, на который указывает ваш текущий контекст kubectl:
```sh
kubectl get pods -o wide -n kube-flannel
cilium install --version 1.16.0
```
Должны увидеть, что-то подобное
#### **Helm Chart**
Установка Cilium на кластер без kube-proxy
```sh
helm upgrade cilium cilium/cilium --version 1.16.0 \
--namespace kube-system \
--install \
--values cilium/values.yaml
```
После развертывания **Cilium** с помощью приведенного выше руководства мы можем сначала убедиться, что агент **Cilium** работает в нужном режиме:
```sh
kubectl -n kube-system exec ds/cilium -- cilium-dbg status | grep KubeProxyReplacement
```
Для получения подробной информации используйте --verbose:
```sh
kubectl -n kube-system exec ds/cilium -- cilium-dbg status --verbose
```
```output
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-flannel-ds-6hm2g 1/1 Running 0 26s 10.0.70.71 kubeadm-node-01 <none> <none>
kube-flannel-ds-8fzzw 1/1 Running 0 26s 10.0.70.74 kubeadm-node-03 <none> <none>
kube-flannel-ds-9hrcj 1/1 Running 0 26s 10.0.70.78 kubeadm-cp-02 <none> <none>
kube-flannel-ds-gm24r 1/1 Running 0 26s 10.0.70.70 kubeadm-cp-01 <none> <none>
kube-flannel-ds-rd7jr 1/1 Running 0 26s 10.0.70.77 kubeadm-node-02 <none> <none>
kube-flannel-ds-rjsl9 1/1 Running 0 26s 10.0.70.79 kubeadm-cp-03 <none> <none>
KubeProxyReplacement Details:
Status: True
Socket LB: Enabled
Socket LB Tracing: Enabled
Socket LB Coverage: Full
Devices: eth0 10.0.75.83 fe80::be24:11ff:fee9:819e (Direct Routing)
Mode: SNAT
Backend Selection: Random
Session Affinity: Enabled
Graceful Termination: Enabled
NAT46/64 Support: Disabled
XDP Acceleration: Disabled
Services:
- ClusterIP: Enabled
- NodePort: Enabled (Range: 30000-32767)
- LoadBalancer: Enabled
- externalIPs: Enabled
- HostPort: Enabled
```
Больше информации о работе без **kube-proxy** в [официальной документации](https://docs.cilium.io/en/stable/network/kubernetes/kubeproxy-free/).
Проверяем статус установки
```sh
cilium status --wait
```
Мы должны увидеть что-то подобное
```output
/¯¯\
/¯¯\__/¯¯\ Cilium: OK
\__/¯¯\__/ Operator: OK
/¯¯\__/¯¯\ Envoy DaemonSet: disabled (using embedded mode)
\__/¯¯\__/ Hubble Relay: disabled
\__/ ClusterMesh: disabled
DaemonSet cilium Desired: 6, Ready: 6/6, Available: 6/6
Deployment cilium-operator Desired: 2, Ready: 2/2, Available: 2/2
Containers: cilium Running: 6
cilium-operator Running: 2
Cluster Pods: 2/2 managed by Cilium
Helm chart version:
Image versions cilium quay.io/cilium/cilium:v1.15.6@sha256:6aa840986a3a9722cd967ef63248d675a87add7e1704740902d5d3162f0c0def: 6
cilium-operator quay.io/cilium/operator-generic:v1.15.6@sha256:5789f0935eef96ad571e4f5565a8800d3a8fbb05265cf6909300cd82fd513c3d: 2
```
Выполните следующую команду, чтобы убедиться, что ваш кластер имеет правильное сетевое подключение (опционально):
```sh
cilium connectivity test
```
Пример вывода
```output
✅ [cilium-test] All 52 tests (600 actions) successful, 28 tests skipped, 0 scenarios skipped.
```
Можно удалить неймспейс **cilium-test**
```sh
kubectl delete namespaces cilium-test
```
## Установка тестового приложения
@@ -185,7 +293,8 @@ helm upgrade \
--create-namespace \
kube-prometheus-stack \
prometheus-community/kube-prometheus-stack \
--version 58.2.2
--values ./kube-prometheus-stack/values.yaml \
--version 61.3.2
```
Проверяем, что все запустилось
@@ -226,6 +335,8 @@ kubectl port-forward -n monitoring svc/kube-prometheus-stack-grafana 8000:80
**CSI (Container Storage Interface)** - это спецификация, которая позволяет контейнерам в **Kubernetes** взаимодействовать с различными хранилищами данных,
такими как блочные и файловые системы, через стандартизированный интерфейс. Это позволяет управлять хранилищем данных более гибко и эффективно в среде контейнеров.
### **Longhorn**
Для организации системы хранения в кластере, мы будем использовать **[Longhorn](https://longhorn.io/)**.
**Longhorn** - это легкая, надежная и мощная система хранения распределенных блоков для **Kubernetes**.
@@ -234,7 +345,7 @@ kubectl port-forward -n monitoring svc/kube-prometheus-stack-grafana 8000:80
**Longhorn** создает выделенный контроллер хранения для каждого тома блочного устройства и синхронно реплицирует том на несколько реплик,
хранящихся на нескольких узлах. Контроллер хранилища и реплики сами оркеструются с помощью **Kubernetes**.
### Характеристики
#### Характеристики
- **Распределенное блочное хранилище** корпоративного класса без единой точки отказа
- **Инкрементный снимок** блочного хранилища
@@ -243,32 +354,32 @@ kubectl port-forward -n monitoring svc/kube-prometheus-stack-grafana 8000:80
- **Автоматизированное обновление без сбоев**. Вы можете обновить весь стек программного обеспечения **Longhorn**, не нарушая работу томов хранения.
- Интуитивно понятная приборная панель с **графическим интерфейсом**
### Пререквизиты
#### Пререквизиты
- Кластер Kubernetes: Убедитесь, что каждый узел соответствует требованиям к установке.
- Ваша рабочая станция: Установите Helm версии 3.0 или более поздней.
### Установка Longhorn
#### Установка Longhorn
Примечание:
- Начальные настройки для **Longhorn** можно найти в пользовательских опциях **Helm** или отредактировав файл конфигурации развертывания.
- Для **Kubernetes** < v1.25, если в вашем кластере все еще используется контроллер допуска Pod Security Policy, установите значение helm enablePSP в true,
чтобы установить ресурс longhorn-psp PodSecurityPolicy, который позволит запускать привилегированные поды **Longhorn**.
- Для **Kubernetes** \< v1.25, если в вашем кластере все еще используется контроллер допуска Pod Security Policy, установите значение helm enablePSP в true,
чтобы установить ресурс longhorn-psp PodSecurityPolicy, который позволит запускать привилегированные поды **Longhorn**.
### Требования к установке
#### Требования к установке
Каждый узел в кластере **Kubernetes**, на котором установлен **Longhorn**, должен отвечать следующим требованиям:
- Контейнерная среда выполнения, совместимая с Kubernetes (Docker v1.13+, containerd v1.3.7+ и т. д.)
- Kubernetes >= v1.21
- Установлен open-iscsi, и на всех узлах запущен демон iscsid.
Это необходимо, поскольку Longhorn полагается на iscsiadm на узле для предоставления постоянных томов Kubernetes. Помощь в установке open-iscsi см. в [этом разделе](https://longhorn.io/docs/1.6.1/deploy/install/#installing-open-iscsi).
Это необходимо, поскольку Longhorn полагается на iscsiadm на узле для предоставления постоянных томов Kubernetes. Помощь в установке open-iscsi см. в [этом разделе](https://longhorn.io/docs/1.6.2/deploy/install/#installing-open-iscsi).
- Поддержка RWX требует, чтобы на каждом узле был установлен клиент NFSv4.
Об установке клиента NFSv4 читайте в [этом разделе](https://longhorn.io/docs/1.6.1/deploy/install/#installing-nfsv4-client).
Об установке клиента NFSv4 читайте в [этом разделе](https://longhorn.io/docs/1.6.2/deploy/install/#installing-nfsv4-client).
- Файловая система узла поддерживает функцию расширения файлов для хранения данных. В настоящее время мы поддерживаем:
ext4
XFS
ext4
XFS
- Должны быть установлены bash, curl, findmnt, grep, awk, blkid, lsblk.
- Распространение монтирования должно быть включено.
@@ -280,72 +391,72 @@ kubectl port-forward -n monitoring svc/kube-prometheus-stack-grafana 8000:80
1. Добавьте репозиторий Longhorn Helm:
```sh
helm repo add longhorn https://charts.longhorn.io
```
```sh
helm repo add longhorn https://charts.longhorn.io
```
2. Получите список последних чартов из репозитория:
1. Получите список последних чартов из репозитория:
```sh
helm repo update
```
```sh
helm repo update
```
3. Установите Longhorn в пространстве имен longhorn-system.
1. Установите Longhorn в пространстве имен longhorn-system.
```sh
helm upgrade \
--install \
longhorn longhorn/longhorn \
--namespace longhorn-system \
--create-namespace \
--version 1.6.1
```
```sh
helm upgrade \
--install \
longhorn longhorn/longhorn \
--namespace longhorn-system \
--create-namespace \
--version 1.6.2
```
4. Чтобы убедиться, что развертывание прошло успешно, выполните команду:
1. Чтобы убедиться, что развертывание прошло успешно, выполните команду:
```sh
kubectl -n longhorn-system get pod
```
```sh
kubectl -n longhorn-system get pod
```
Результат должен выглядеть следующим образом:
Результат должен выглядеть следующим образом:
```output
NAME READY STATUS RESTARTS AGE
csi-attacher-799967d9c-nx4f9 1/1 Running 0 3m10s
csi-attacher-799967d9c-vsz7g 1/1 Running 0 3m10s
csi-attacher-799967d9c-zh6vq 1/1 Running 0 3m10s
csi-provisioner-58f97759c-676jf 1/1 Running 0 3m10s
csi-provisioner-58f97759c-fxsb5 1/1 Running 0 3m10s
csi-provisioner-58f97759c-krfs2 1/1 Running 0 3m10s
csi-resizer-6c9b8598f4-dzxwp 1/1 Running 0 3m10s
csi-resizer-6c9b8598f4-kkfn4 1/1 Running 0 3m10s
csi-resizer-6c9b8598f4-wq47f 1/1 Running 0 3m10s
csi-snapshotter-5c5f9b754d-4pdbg 1/1 Running 0 3m10s
csi-snapshotter-5c5f9b754d-7n7wf 1/1 Running 0 3m10s
csi-snapshotter-5c5f9b754d-q4rzx 1/1 Running 0 3m10s
engine-image-ei-5cefaf2b-8j4j9 1/1 Running 0 3m14s
engine-image-ei-5cefaf2b-94g2f 1/1 Running 0 3m14s
engine-image-ei-5cefaf2b-g5bg5 1/1 Running 0 3m14s
instance-manager-3af1ba7167264c2020df4d36d77d3905 1/1 Running 0 3m14s
instance-manager-8452580cb8e2bc9ad134bb6a1c2806cc 1/1 Running 0 3m12s
instance-manager-a006e8fdef719ff0b5aee753abbe1dd8 1/1 Running 0 3m14s
longhorn-csi-plugin-bswvc 3/3 Running 0 3m10s
longhorn-csi-plugin-fmlrd 3/3 Running 0 3m10s
longhorn-csi-plugin-tpnqm 3/3 Running 0 3m10s
longhorn-driver-deployer-68b5879955-7tkrs 1/1 Running 0 3m31s
longhorn-manager-5psrc 1/1 Running 0 3m31s
longhorn-manager-5qjbd 1/1 Running 0 3m31s
longhorn-manager-rwzbb 1/1 Running 0 3m31s
longhorn-ui-9ccf5c989-bxdv2 1/1 Running 0 3m31s
longhorn-ui-9ccf5c989-dsvz6 1/1 Running 0 3m31s
```
```output
NAME READY STATUS RESTARTS AGE
csi-attacher-799967d9c-nx4f9 1/1 Running 0 3m10s
csi-attacher-799967d9c-vsz7g 1/1 Running 0 3m10s
csi-attacher-799967d9c-zh6vq 1/1 Running 0 3m10s
csi-provisioner-58f97759c-676jf 1/1 Running 0 3m10s
csi-provisioner-58f97759c-fxsb5 1/1 Running 0 3m10s
csi-provisioner-58f97759c-krfs2 1/1 Running 0 3m10s
csi-resizer-6c9b8598f4-dzxwp 1/1 Running 0 3m10s
csi-resizer-6c9b8598f4-kkfn4 1/1 Running 0 3m10s
csi-resizer-6c9b8598f4-wq47f 1/1 Running 0 3m10s
csi-snapshotter-5c5f9b754d-4pdbg 1/1 Running 0 3m10s
csi-snapshotter-5c5f9b754d-7n7wf 1/1 Running 0 3m10s
csi-snapshotter-5c5f9b754d-q4rzx 1/1 Running 0 3m10s
engine-image-ei-5cefaf2b-8j4j9 1/1 Running 0 3m14s
engine-image-ei-5cefaf2b-94g2f 1/1 Running 0 3m14s
engine-image-ei-5cefaf2b-g5bg5 1/1 Running 0 3m14s
instance-manager-3af1ba7167264c2020df4d36d77d3905 1/1 Running 0 3m14s
instance-manager-8452580cb8e2bc9ad134bb6a1c2806cc 1/1 Running 0 3m12s
instance-manager-a006e8fdef719ff0b5aee753abbe1dd8 1/1 Running 0 3m14s
longhorn-csi-plugin-bswvc 3/3 Running 0 3m10s
longhorn-csi-plugin-fmlrd 3/3 Running 0 3m10s
longhorn-csi-plugin-tpnqm 3/3 Running 0 3m10s
longhorn-driver-deployer-68b5879955-7tkrs 1/1 Running 0 3m31s
longhorn-manager-5psrc 1/1 Running 0 3m31s
longhorn-manager-5qjbd 1/1 Running 0 3m31s
longhorn-manager-rwzbb 1/1 Running 0 3m31s
longhorn-ui-9ccf5c989-bxdv2 1/1 Running 0 3m31s
longhorn-ui-9ccf5c989-dsvz6 1/1 Running 0 3m31s
```
5. Чтобы включить доступ к пользовательскому интерфейсу Longhorn, необходимо настроить контроллер Ingress.
1. Чтобы включить доступ к пользовательскому интерфейсу Longhorn, необходимо настроить контроллер Ingress.
По умолчанию аутентификация в пользовательском интерфейсе Longhorn не включена.
Информацию о создании контроллера NGINX Ingress с базовой аутентификацией см. в [этом разделе](https://longhorn.io/docs/1.6.1/deploy/accessing-the-ui/longhorn-ingress).
По умолчанию аутентификация в пользовательском интерфейсе Longhorn не включена.
Информацию о создании контроллера NGINX Ingress с базовой аутентификацией см. в [этом разделе](https://longhorn.io/docs/1.6.2/deploy/accessing-the-ui/longhorn-ingress).
6. Войдите в пользовательский интерфейс Longhorn, выполнив [следующие действия](https://longhorn.io/docs/1.6.1/deploy/accessing-the-ui).
1. Войдите в пользовательский интерфейс Longhorn, выполнив [следующие действия](https://longhorn.io/docs/1.6.2/deploy/accessing-the-ui).
Посмотреть на веб интерфейс можно так:
@@ -382,7 +493,20 @@ helm upgrade \
--install \
--namespace traefik \
--create-namespace \
traefik traefik/traefik
traefik traefik/traefik \
--values traefik/values.yaml
```
```sh
helm upgrade \
--install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
--set controller.kind=DaemonSet \
--set controller.hostNetwork=false \
--set controller.hostPort.enabled=false \
--set controller.service.loadBalancerIP=10.0.70.199
```
### Проброс дашборда Traefik
@@ -404,16 +528,16 @@ kubectl get nodes -o wide
Эти команды выполняют следующие действия:
- kubectl drain - этот шаг убеждается, что все поды, которые могут быть перезапущены в другом месте, были перезапущены.
Он также удаляет все пустые директории, которые были созданы подами на узле,
и удаляет все поды, которые не могут быть перезапущены в другом месте (например, поды, которые имеют локальные данные).
Он также удаляет все пустые директории, которые были созданы подами на узле,
и удаляет все поды, которые не могут быть перезапущены в другом месте (например, поды, которые имеют локальные данные).
```sh
kubectl drain kubeadm-node-01 --delete-local-data --force --ignore-daemonsets
```
- kubectl delete node - этот шаг удаляет узел из кластера.
Обратите внимание, что эти команды могут привести к потере данных,
поэтому убедитесь, что вы понимаете, что делаете, и что у вас есть резервное копирование данных, если это необходимо.
Обратите внимание, что эти команды могут привести к потере данных,
поэтому убедитесь, что вы понимаете, что делаете, и что у вас есть резервное копирование данных, если это необходимо.
```sh
kubectl delete node kubeadm-node-01
@@ -438,69 +562,3 @@ kubeadm token list
```sh
kubeadm token create --print-join-command
```
## Тестирование кластера
Отчет **sonobuoy**
```txt
Plugin: e2e
Status: failed
Total: 7201
Passed: 384
Failed: 20
Skipped: 6797
Failed tests:
[sig-network] DNS should provide DNS for pods for Subdomain [Conformance]
[sig-network] Services should be able to change the type from ExternalName to ClusterIP [Conformance]
[sig-network] Services should be able to switch session affinity for service with type clusterIP [LinuxOnly] [Conformance]
[sig-cli] Kubectl client Guestbook application should create and stop a working application [Conformance]
[sig-network] Services should be able to switch session affinity for NodePort service [LinuxOnly] [Conformance]
[sig-network] Services should serve multiport endpoints from pods [Conformance]
[sig-network] Services should have session affinity work for NodePort service [LinuxOnly] [Conformance]
[sig-architecture] Conformance Tests should have at least two untainted nodes [Conformance]
[sig-network] DNS should provide DNS for services [Conformance]
[sig-network] Services should be able to change the type from NodePort to ExternalName [Conformance]
[sig-network] DNS should resolve DNS of partial qualified names for services [LinuxOnly] [Conformance]
[sig-network] Services should be able to change the type from ExternalName to NodePort [Conformance]
[sig-network] Services should serve a basic endpoint from pods [Conformance]
[sig-apps] Daemon set [Serial] should rollback without unnecessary restarts [Conformance]
[sig-network] DNS should provide DNS for ExternalName services [Conformance]
[sig-network] DNS should provide DNS for the cluster [Conformance]
[sig-network] Services should be able to create a functioning NodePort service [Conformance]
[sig-network] Services should be able to change the type from ClusterIP to ExternalName [Conformance]
[sig-auth] ServiceAccounts ServiceAccountIssuerDiscovery should support OIDC discovery of service account issuer [Conformance]
[sig-network] Services should have session affinity work for service with type clusterIP [LinuxOnly] [Conformance]
Plugin: systemd-logs
Status: passed
Total: 2
Passed: 2
Failed: 0
Skipped: 0
Run Details:
API Server version: v1.30.0
Node health: 2/2 (100%)
Pods health: 13/14 (92%)
Details for failed pods:
sonobuoy/sonobuoy-e2e-job-c23b74c9b2004efd Ready:False: :
Errors detected in files:
Warnings:
754 podlogs/kube-system/kube-controller-manager-kubeadm-cp-01/logs/kube-controller-manager.txt
90 podlogs/kube-system/kube-apiserver-kubeadm-cp-01/logs/kube-apiserver.txt
29 podlogs/kube-system/kube-scheduler-kubeadm-cp-01/logs/kube-scheduler.txt
7 podlogs/sonobuoy/sonobuoy-e2e-job-c23b74c9b2004efd/logs/e2e.txt
3 podlogs/kube-system/etcd-kubeadm-cp-01/logs/etcd.txt
1 podlogs/sonobuoy/sonobuoy/logs/kube-sonobuoy.txt
Errors:
6268 podlogs/sonobuoy/sonobuoy-e2e-job-c23b74c9b2004efd/logs/e2e.txt
1742 podlogs/kube-system/kube-controller-manager-kubeadm-cp-01/logs/kube-controller-manager.txt
350 podlogs/kube-system/kube-apiserver-kubeadm-cp-01/logs/kube-apiserver.txt
63 podlogs/kube-system/kube-scheduler-kubeadm-cp-01/logs/kube-scheduler.txt
9 podlogs/kube-system/coredns-7db6d8ff4d-lkwk9/logs/coredns.txt
9 podlogs/kube-system/coredns-7db6d8ff4d-bdvht/logs/coredns.txt
8 podlogs/kube-system/kube-proxy-4g6fl/logs/kube-proxy.txt
8 podlogs/kube-system/kube-proxy-p5vr5/logs/kube-proxy.txt
```

View File

@@ -0,0 +1,8 @@
---
apiVersion: "cilium.io/v2alpha1"
kind: CiliumLoadBalancerIPPool
metadata:
name: "pool"
spec:
blocks:
- cidr: "10.0.75.199/32"

View File

@@ -0,0 +1,16 @@
apiVersion: "cilium.io/v2alpha1"
kind: CiliumL2AnnouncementPolicy
metadata:
name: policy1
spec:
serviceSelector:
matchLabels:
color: blue
nodeSelector:
matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: DoesNotExist
interfaces:
- ^eth[0-9]+
externalIPs: true
loadBalancerIPs: true

View File

@@ -0,0 +1,6 @@
kubeProxyReplacement: true
k8sServiceHost: 10.0.75.80
k8sServicePort: 8888
l2announcements:
enabled: true
devices: eth+

View File

@@ -0,0 +1,9 @@
grafana:
ingress:
enabled: true
hosts:
- grafana.example.local
tls:
- secretName: grafana-general-tls
hosts:
- grafana.example.local

View File

@@ -0,0 +1,36 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: development
labels:
app: frontend
spec:
revisionHistoryLimit: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
replicas: 3
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: python:3.12.4-alpine
command: ["python3", "-m", "http.server", "80"]
imagePullPolicy: IfNotPresent
resources:
requests:
memory: "16Mi"
cpu: "10m"
limits:
memory: "1Gi"
cpu: "1000m"

View File

@@ -0,0 +1,28 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend
namespace: development
spec:
# В кластере может быть несколько Ingress Controllers, мы используем NGINX
ingressClassName: "traefik"
tls:
- hosts:
- "frontend.example.local"
rules:
# Хост определяет правило направления траффика по доменному имени
- host: "frontend.example.local"
http:
# Для различных путей в URL можно указать различные бэкенд-сервисы
paths:
- path: /
pathType: Prefix
backend:
service:
# Заранее создан сервис типа ClusterIP
# Он выступает в качестве бэкенда нашего Ingress
name: frontend
port:
# У сервиса может быть несколько портов, указываем нужный нам
number: 80

View File

@@ -0,0 +1,7 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
name: development

View File

@@ -0,0 +1,16 @@
---
apiVersion: v1
kind: Service
metadata:
name: frontend
namespace: development
labels:
app: frontend
spec:
type: ClusterIP
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: frontend

View File

@@ -0,0 +1,8 @@
deployment:
kind: DaemonSet
service:
labels:
color: blue
spec:
externalTrafficPolicy: Local

View File

@@ -2,24 +2,24 @@
# Manual edits may be lost in future updates.
provider "registry.opentofu.org/bpg/proxmox" {
version = "0.54.0"
constraints = ">= 0.51.0"
version = "0.61.1"
constraints = ">= 0.61.1"
hashes = [
"h1:xgDrDol/cYu93YOPTL0UVpURchPzdxPXaHjcoieoXXI=",
"zh:4521f8893b4645c93e75ffc3545ea59d3f31aed7cea4c26dcd0fbd7c0cce6ca8",
"zh:520e56abd10d888935047ef07a7577c2a1cce5bc54e25b03a0dbdc4356997ca9",
"zh:53469dd058ef8b2ea29577f69a2681f8ffb9f79494b8c1d1594dd42ad314d7bd",
"zh:6948adb6e088fe652b7273906a5c11032528f84eb5a5ca797534ab3b6076a8c6",
"zh:72655e9765b7791e3e37508c70a847172561bff348c7d5f916794e5823a84efe",
"zh:7faa281319d90026ad9b2dce00ac059896f451cb9305ed11bb90fcfda7c5d143",
"zh:8fe20fa893e9545aa30672392f76948ed56a93a2decb1d3bd8693c5e1d2dd85a",
"zh:b175411aa820c1a47473ef691c743670eeb900999576c6cdcb113d14a7c499aa",
"zh:b59205ad7981f263ff287d3eb0a93296f8cd6b166a01ddd3b16606fc39d456ec",
"h1:SQSHTHj2ThcF08cON2gHYcnkS/XLmoF8E4cRIgpagtE=",
"zh:27d8b589a2dc1e0a5b0f8ab299b9f3704a2f0b69799d1d4d8845c68056986d1f",
"zh:46dfa6b33ddd7007a2144f38090457604eb56a59a303b37bb0ad1be5c84ddaca",
"zh:47a1b14a759393c5ecc76f2feb950677c418c910b8c677fde0dd3e4675c41579",
"zh:582e49d109d1c2b1f3b1268a7cbc43548f3c6d96a87c92a5428767097a5e383e",
"zh:5e98ad6afae5969a4c3ffb14c0484936550c66c8313d7686551c29b633ff32f2",
"zh:7b9e24b76f947ab8f1e571cf61beefc983b7d2aa1b85df35c4f015728fe37a38",
"zh:8255ca210f279a0f7b8ca2762df26d2ea1a01704298c5e3d5cf601bd39a743f0",
"zh:85d7655fdc95dedced9cf8105a0beeb0d7bc8f668c55f62019a7215a76d60300",
"zh:8aeea5a1d001b06baaf923b754e1a14d06c75eb8c8b87a7f65a3c8205fc8b079",
"zh:a9cfab6c06f613658c5fdd83742cd22c0eb7563778924b1407965ef8c36c1ce0",
"zh:ceaab67801d49a92eb5858b1ddae6df2569462e5ffbe31f9dbd79dcb684ea142",
"zh:dc25b506d5c55d1d78a335d3ebd03213c99b4b2a5859812349a955c2f746ff7e",
"zh:e04b477fd77a0d37a0bdb76a7cf69184dad9e7fbba9b4f3a378a8901b82b75e5",
"zh:f1e6838d9141557f73340df9b21fce5a82b41cc16ae36f063a920ccc36bc0758",
"zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597",
"zh:f3524bc67d995e98ad9d7e17f3be91f7a975608180fad6b227fc42087b5facc1",
"zh:f4bf087717e1b0f5f3ee7d3b6b47fb66e5f821097f15ec0cf6714a39c7d80959",
"zh:fc14a29b1aef50872d60f338af89f7cbbac307c630f973c07a7951bdde8be2a5",
"zh:fc72da3d651bf0f0e20a0860e9217a94797b4c1d5cae1742f1b8e15d28f8ceeb",
"zh:fff2299a427e1590775611bf186220686795af966772e61e44234f0df44b6c22",
]
}

View File

@@ -1,70 +0,0 @@
# Машинка
resource "proxmox_virtual_environment_vm" "kubeadm-cp-01" {
name = "kubeadm-cp-01"
migrate = true
description = "Managed by OpenTofu"
tags = ["kubeadm", "test"]
on_boot = true
# Указываем целевой узел, на котором будет запущена ВМ
node_name = "pve-01"
# Шоблон из которого будет создавать ВМ
clone {
vm_id = "2204"
node_name = "pve-01"
retries = 2
}
# Активируем QEMU для этов ВМ
agent {
enabled = true
}
operating_system {
type = "l26"
}
cpu {
cores = 4
type = "host"
numa = true
}
memory {
dedicated = 4096
}
disk {
size = "50"
interface = "virtio0"
datastore_id = "k8s-data-01"
file_format = "raw"
}
network_device {
bridge = "vmbr0"
model = "virtio"
}
initialization {
datastore_id = "k8s-data-01"
ip_config {
ipv4 {
address = "10.0.70.70/24"
gateway = "10.0.70.101"
}
}
dns {
servers = [
"77.88.8.8"
]
}
user_account {
username = "infra"
keys = [
"ssh-rsa..."
]
}
}
}

View File

@@ -1,70 +0,0 @@
# Машинка
resource "proxmox_virtual_environment_vm" "kubeadm-cp-02" {
name = "kubeadm-cp-02"
migrate = true
description = "Managed by OpenTofu"
tags = ["kubeadm", "test"]
on_boot = true
# Указываем целевой узел, на котором будет запущена ВМ
node_name = "pve-02"
# Шоблон из которого будет создавать ВМ
clone {
vm_id = "2204"
node_name = "pve-01"
retries = 2
}
# Активируем QEMU для этов ВМ
agent {
enabled = true
}
operating_system {
type = "l26"
}
cpu {
cores = 4
type = "host"
numa = true
}
memory {
dedicated = 4096
}
disk {
size = "50"
interface = "virtio0"
datastore_id = "k8s-data-01"
file_format = "raw"
}
network_device {
bridge = "vmbr0"
model = "virtio"
}
initialization {
datastore_id = "k8s-data-01"
ip_config {
ipv4 {
address = "10.0.70.78/24"
gateway = "10.0.70.101"
}
}
dns {
servers = [
"77.88.8.8"
]
}
user_account {
username = "infra"
keys = [
"ssh-rsa..."
]
}
}
}

View File

@@ -1,70 +0,0 @@
# Машинка
resource "proxmox_virtual_environment_vm" "kubeadm-cp-03" {
name = "kubeadm-cp-03"
migrate = true
description = "Managed by OpenTofu"
tags = ["kubeadm", "test"]
on_boot = true
# Указываем целевой узел, на котором будет запущена ВМ
node_name = "pve-03"
# Шоблон из которого будет создавать ВМ
clone {
vm_id = "2204"
node_name = "pve-01"
retries = 2
}
# Активируем QEMU для этов ВМ
agent {
enabled = true
}
operating_system {
type = "l26"
}
cpu {
cores = 4
type = "host"
numa = true
}
memory {
dedicated = 4096
}
disk {
size = "50"
interface = "virtio0"
datastore_id = "k8s-data-01"
file_format = "raw"
}
network_device {
bridge = "vmbr0"
model = "virtio"
}
initialization {
datastore_id = "k8s-data-01"
ip_config {
ipv4 {
address = "10.0.70.79/24"
gateway = "10.0.70.101"
}
}
dns {
servers = [
"77.88.8.8"
]
}
user_account {
username = "infra"
keys = [
"ssh-rsa..."
]
}
}
}

View File

@@ -0,0 +1,110 @@
variable "cp_vms" {
type = list(object({
name = string
address = string
node_name = string
}))
default = [
{
name = "kubeadm-cp-01"
address = "10.0.75.81/24"
node_name = "pve-01"
},
{
name = "kubeadm-cp-02"
address = "10.0.75.82/24"
node_name = "pve-02"
},
{
name = "kubeadm-cp-03"
address = "10.0.75.83/24"
node_name = "pve-02"
}
]
}
# Создание виртуальных машин
resource "proxmox_virtual_environment_vm" "control-plane" {
for_each = { for vm in var.cp_vms : vm.name => vm }
name = each.value.name
migrate = true
# protection = true
description = "Managed by OpenTofu"
tags = ["kubeadm", "kubernetes"]
on_boot = true
node_name = each.value.node_name
clone {
vm_id = "2404"
node_name = "pve-01"
retries = 3
}
agent {
enabled = true
}
operating_system {
type = "l26"
}
cpu {
cores = 4
type = "host"
numa = true
}
memory {
dedicated = 4096
}
vga {
memory = 4
type = "serial0"
}
disk {
size = "20"
interface = "virtio0"
datastore_id = "proxmox-data-01"
file_format = "raw"
}
network_device {
bridge = "vmbr0"
model = "virtio"
}
initialization {
datastore_id = "proxmox-data-01"
ip_config {
ipv4 {
address = each.value.address
gateway = "10.0.75.1"
}
}
dns {
servers = [
"10.0.75.65",
"10.0.75.66"
]
}
user_account {
username = "infra"
keys = [
var.ssh_public_key
]
}
}
}
# Создание ресурсов высокой доступности
# resource "proxmox_virtual_environment_haresource" "patroni" {
# for_each = { for vm in var.cp_vms : vm.name => vm }
# resource_id = "vm:${proxmox_virtual_environment_vm.patroni[each.key].vm_id}"
# state = "started"
# group = "prod"
# comment = "Managed by OpenTofu"
# }

View File

@@ -1,70 +0,0 @@
# Машинка
resource "proxmox_virtual_environment_vm" "kubeadm-node-01" {
name = "kubeadm-node-01"
migrate = true
description = "Managed by OpenTofu"
tags = ["kubeadm", "test"]
on_boot = true
# Указываем целевой узел, на котором будет запущена ВМ
node_name = "pve-01"
# Шоблон из которого будет создавать ВМ
clone {
vm_id = "2204"
node_name = "pve-01"
retries = 2
}
# Активируем QEMU для этов ВМ
agent {
enabled = true
}
operating_system {
type = "l26"
}
cpu {
cores = 4
type = "host"
numa = true
}
memory {
dedicated = 32768
}
disk {
size = "500"
interface = "virtio0"
datastore_id = "k8s-data-01"
file_format = "raw"
}
network_device {
bridge = "vmbr0"
model = "virtio"
}
initialization {
datastore_id = "k8s-data-01"
ip_config {
ipv4 {
address = "10.0.70.71/24"
gateway = "10.0.70.101"
}
}
dns {
servers = [
"77.88.8.8"
]
}
user_account {
username = "infra"
keys = [
"ssh-rsa..."
]
}
}
}

View File

@@ -1,70 +0,0 @@
# Машинка
resource "proxmox_virtual_environment_vm" "kubeadm-node-02" {
name = "kubeadm-node-02"
migrate = true
description = "Managed by OpenTofu"
tags = ["kubeadm", "test"]
on_boot = true
# Указываем целевой узел, на котором будет запущена ВМ
node_name = "pve-02"
# Шоблон из которого будет создавать ВМ
clone {
vm_id = "2204"
node_name = "pve-01"
retries = 2
}
# Активируем QEMU для этов ВМ
agent {
enabled = true
}
operating_system {
type = "l26"
}
cpu {
cores = 4
type = "host"
numa = true
}
memory {
dedicated = 32768
}
disk {
size = "500"
interface = "virtio0"
datastore_id = "k8s-data-01"
file_format = "raw"
}
network_device {
bridge = "vmbr0"
model = "virtio"
}
initialization {
datastore_id = "k8s-data-01"
ip_config {
ipv4 {
address = "10.0.70.77/24"
gateway = "10.0.70.101"
}
}
dns {
servers = [
"77.88.8.8"
]
}
user_account {
username = "infra"
keys = [
"ssh-rsa..."
]
}
}
}

View File

@@ -1,70 +0,0 @@
# Машинка
resource "proxmox_virtual_environment_vm" "kubeadm-node-03" {
name = "kubeadm-node-03"
migrate = true
description = "Managed by OpenTofu"
tags = ["kubeadm", "test"]
on_boot = true
# Указываем целевой узел, на котором будет запущена ВМ
node_name = "pve-03"
# Шоблон из которого будет создавать ВМ
clone {
vm_id = "2204"
node_name = "pve-01"
retries = 2
}
# Активируем QEMU для этов ВМ
agent {
enabled = true
}
operating_system {
type = "l26"
}
cpu {
cores = 4
type = "host"
numa = true
}
memory {
dedicated = 32768
}
disk {
size = "500"
interface = "virtio0"
datastore_id = "k8s-data-01"
file_format = "raw"
}
network_device {
bridge = "vmbr0"
model = "virtio"
}
initialization {
datastore_id = "k8s-data-01"
ip_config {
ipv4 {
address = "10.0.70.74/24"
gateway = "10.0.70.101"
}
}
dns {
servers = [
"77.88.8.8"
]
}
user_account {
username = "infra"
keys = [
"ssh-rsa..."
]
}
}
}

110
opentofu/kubeadm/node.tf Normal file
View File

@@ -0,0 +1,110 @@
variable "node_vms" {
type = list(object({
name = string
address = string
node_name = string
}))
default = [
{
name = "kubeadm-node-01"
address = "10.0.75.84/24"
node_name = "pve-01"
},
{
name = "kubeadm-node-02"
address = "10.0.75.85/24"
node_name = "pve-02"
},
{
name = "kubeadm-node-03"
address = "10.0.75.86/24"
node_name = "pve-02"
}
]
}
# Создание виртуальных машин
resource "proxmox_virtual_environment_vm" "node" {
for_each = { for vm in var.node_vms : vm.name => vm }
name = each.value.name
migrate = true
# protection = true
description = "Managed by OpenTofu"
tags = ["kubeadm", "kubernetes"]
on_boot = true
node_name = each.value.node_name
clone {
vm_id = "2404"
node_name = "pve-01"
retries = 3
}
agent {
enabled = true
}
operating_system {
type = "l26"
}
cpu {
cores = 16
type = "host"
numa = true
}
memory {
dedicated = 32768
}
vga {
memory = 4
type = "serial0"
}
disk {
size = "20"
interface = "virtio0"
datastore_id = "proxmox-data-01"
file_format = "raw"
}
network_device {
bridge = "vmbr0"
model = "virtio"
}
initialization {
datastore_id = "proxmox-data-01"
ip_config {
ipv4 {
address = each.value.address
gateway = "10.0.75.1"
}
}
dns {
servers = [
"10.0.75.65",
"10.0.75.66"
]
}
user_account {
username = "infra"
keys = [
var.ssh_public_key
]
}
}
}
# Создание ресурсов высокой доступности
# resource "proxmox_virtual_environment_haresource" "patroni" {
# for_each = { for vm in var.node_vms : vm.name => vm }
# resource_id = "vm:${proxmox_virtual_environment_vm.patroni[each.key].vm_id}"
# state = "started"
# group = "prod"
# comment = "Managed by OpenTofu"
# }

View File

@@ -2,7 +2,7 @@ terraform {
required_providers {
proxmox = {
source = "bpg/proxmox"
version = ">= 0.51.0"
version = ">= 0.61.1"
}
}
}

View File

@@ -1,2 +1,3 @@
virtual_environment_api_token = "root@pam!for-terraform-provider=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
virtual_environment_endpoint = "https://x.x.x.x:8006/"
ssh_public_key = "ssh-rsa ..."

View File

@@ -7,3 +7,8 @@ variable "virtual_environment_api_token" {
type = string
description = "The api roken the Proxmox Virtual Environment API (example: root@pam!for-terraform-provider=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)"
}
variable "ssh_public_key" {
type = string
description = "SSH Puclic key for VMs (example: ssh-rsa ...)"
}