diff --git a/.gitignore b/.gitignore index e0c9c9f..c83cb6d 100644 --- a/.gitignore +++ b/.gitignore @@ -39,5 +39,15 @@ terraform.rc # End of https://www.toptal.com/developers/gitignore/api/terraform +# Created by https://www.toptal.com/developers/gitignore/api/ansible +# Edit at https://www.toptal.com/developers/gitignore?templates=ansible + +### Ansible ### +*.retry + +# End of https://www.toptal.com/developers/gitignore/api/ansible + # Other .vscode +.DS_Store +ansible/secrets diff --git a/README.md b/README.md index ab04a2e..41f54f6 100644 --- a/README.md +++ b/README.md @@ -1 +1,13 @@ -# learn-devops \ No newline at end of file +# learn-devops + +## Мы стремимся подходу **Инфраструктура как код** + +Основная идея **Infrastructure as Code (IaC)** в том, чтобы **описать инфраструктуру кодом** и сделать её доступной для понимания. IaC работает со всеми компонентами инфраструктуры так, будто это просто данные. Такое стало возможно благодаря умению платформ виртуализации и облачных провайдеров разделять инфраструктуру и оборудование, а для управления серверами, хранилищами и сетевыми устройствами предоставлять специальное API. + +## Структура проекта + +0. [kubeadm](./kubeadm/) - это инструмент для простого и быстрого развёртывания кластера Kubernetes. + +1. [OpenTofu](./opnetofu) — программное обеспечение с **открытым исходным кодом**, используемое для **управления внешними ресурсами** (например, в рамках модели **инфраструктура как код**). Проект Linux Foundation. Пользователи определяют и предоставляют инфраструктуру центра обработки данных с помощью **декларативного языка конфигурации**, известного как HashiCorp Configuration Language (HCL) или JSON. + +2. [Ansible](./ansible) — система управления конфигурациями, написанная на языке программирования **Python**, с использованием **декларативного языка разметки** для **описания конфигураций**. Применяется для **автоматизации настройки и развёртывания программного обеспечения**. diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 0000000..73d5cdc --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,8 @@ +[defaults] +timeout=60 +roles_path=./roles +inventory=./inventory.yml +forks=100 +serial=10 +host_key_checking=False +callbacks_enabled=ansible.posix.profile_tasks diff --git a/ansible/inventory.yml b/ansible/inventory.yml new file mode 100644 index 0000000..d9bdbd2 --- /dev/null +++ b/ansible/inventory.yml @@ -0,0 +1,21 @@ +kubeadm: + children: + kubeadm_control_plane: + hosts: + kubeadm-cp-01: + ansible_host: 10.0.70.70 + kubeadm-cp-02: + ansible_host: 10.0.70.78 + kubeadm-cp-03: + ansible_host: 10.0.70.79 + kubeadm_nodes: + hosts: + kubeadm-node-01: + ansible_host: 10.0.70.71 + kubeadm-node-02: + ansible_host: 10.0.70.77 + kubeadm-node-03: + ansible_host: 10.0.70.74 + vars: + ansible_user: infra + ansible_port: 22 diff --git a/ansible/kubeadm.yml b/ansible/kubeadm.yml new file mode 100644 index 0000000..96344e0 --- /dev/null +++ b/ansible/kubeadm.yml @@ -0,0 +1,101 @@ +# Запустите сервисы как статические подсистемы +# 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 кластер + become: true + hosts: + - kubeadm + handlers: + - name: Перезагружаю виртуальные машины + ansible.builtin.reboot: + tasks: + - name: Добавляю модули br_netfilter и overlay + community.general.modprobe: + name: '{{ item }}' + state: present + with_items: + - br_netfilter + - overlay + # notify: + # - Перезагружаю виртуальные машины + + - name: Добавляю модули br_netfilter и overlay в /etc/modules + ansible.builtin.lineinfile: + path: /etc/modules + line: '{{ item }}' + create: true + with_items: + - br_netfilter + - overlay + # notify: + # - Перезагружаю виртуальные машины + + - name: Включаю маршрутизацию IP и iptables для моста + ansible.posix.sysctl: + name: '{{ item }}' + value: 1 + state: present + with_items: + - net.ipv4.ip_forward + - net.bridge.bridge-nf-call-iptables + + - name: Устанавливаю пакеты + ansible.builtin.apt: + name: + - apt-transport-https + - ca-certificates + - curl + - gpg + - software-properties-common + update_cache: true + + - name: Добавляю gpg ключ для репозиториев Kubernetes и cri-o + ansible.builtin.apt_key: + url: '{{ item["url"] }}' + 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"} + + - name: Добавляю репозитории Kubernetes и cri-o + ansible.builtin.apt_repository: + 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/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ / + + - name: Устанавливаю пакеты kubelet, kubeadm, kubectl и cri-o + ansible.builtin.apt: + name: + - kubelet + - kubeadm + - kubectl + - cri-o + state: present + update_cache: true + + - name: Предотвращаю обновление kubelet, kubeadm и kubectl + ansible.builtin.dpkg_selections: + name: '{{ item }}' + selection: hold + with_items: + - kubelet + - kubeadm + - kubectl + + - name: Включаю и запускаю службы kubelet и cri-o + ansible.builtin.systemd: + name: '{{ item }}' + enabled: true + state: started + with_items: + - kubelet + - crio diff --git a/ansible/roles/haproxy_static_pods/files/check_apiserver.sh b/ansible/roles/haproxy_static_pods/files/check_apiserver.sh new file mode 100644 index 0000000..487d43e --- /dev/null +++ b/ansible/roles/haproxy_static_pods/files/check_apiserver.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +errorExit() { + echo "*** $*" 1>&2 + 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/" +fi diff --git a/ansible/roles/haproxy_static_pods/files/haproxy.cfg b/ansible/roles/haproxy_static_pods/files/haproxy.cfg new file mode 100644 index 0000000..9369876 --- /dev/null +++ b/ansible/roles/haproxy_static_pods/files/haproxy.cfg @@ -0,0 +1,52 @@ +# /etc/haproxy/haproxy.cfg +#--------------------------------------------------------------------- +# Global settings +#--------------------------------------------------------------------- +global + log /dev/log local0 + log /dev/log local1 notice + daemon + +#--------------------------------------------------------------------- +# common defaults that all the 'listen' and 'backend' sections will +# use if not designated in their block +#--------------------------------------------------------------------- +defaults + mode http + log global + option httplog + option dontlognull + option http-server-close + option forwardfor except 127.0.0.0/8 + option redispatch + retries 1 + timeout http-request 10s + timeout queue 20s + timeout connect 5s + timeout client 20s + timeout server 20s + timeout http-keep-alive 10s + timeout check 10s + +#--------------------------------------------------------------------- +# apiserver frontend which proxys to the control plane nodes +#--------------------------------------------------------------------- +frontend apiserver + bind *:7443 + mode tcp + option tcplog + default_backend apiserverbackend + +#--------------------------------------------------------------------- +# round robin balancing for apiserver +#--------------------------------------------------------------------- +backend apiserverbackend + option httpchk GET /healthz + http-check expect status 200 + 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 + # [...] diff --git a/ansible/roles/haproxy_static_pods/files/haproxy.yaml b/ansible/roles/haproxy_static_pods/files/haproxy.yaml new file mode 100644 index 0000000..5c8f679 --- /dev/null +++ b/ansible/roles/haproxy_static_pods/files/haproxy.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: Pod +metadata: + name: haproxy + 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 + hostNetwork: true + volumes: + - hostPath: + path: /etc/haproxy/haproxy.cfg + type: FileOrCreate + name: haproxyconf +status: {} diff --git a/ansible/roles/haproxy_static_pods/files/keepalived.yaml b/ansible/roles/haproxy_static_pods/files/keepalived.yaml new file mode 100644 index 0000000..e70c60b --- /dev/null +++ b/ansible/roles/haproxy_static_pods/files/keepalived.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: null + name: keepalived + 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 + hostNetwork: true + volumes: + - hostPath: + path: /etc/keepalived/keepalived.conf + name: config + - hostPath: + path: /etc/keepalived/check_apiserver.sh + name: check +status: {} diff --git a/ansible/roles/haproxy_static_pods/tasks/main.yml b/ansible/roles/haproxy_static_pods/tasks/main.yml new file mode 100644 index 0000000..d9cc95f --- /dev/null +++ b/ansible/roles/haproxy_static_pods/tasks/main.yml @@ -0,0 +1,40 @@ +# tasks file for haproxy_static_pods +- name: Создать директории /etc/kubernetes/manifests и /etc/keepalived + ansible.builtin.file: + path: '{{ item }}' + state: directory + mode: '755' + with_items: + - /etc/kubernetes/manifests + - /etc/keepalived + - /etc/haproxy + +- name: Наливаю конфигурацию keepalived + ansible.builtin.template: + src: keepalived.conf.j2 + dest: /etc/keepalived/keepalived.conf + mode: "644" + +- name: Наливаю check_apiserver.sh + ansible.builtin.copy: + src: check_apiserver.sh + dest: /etc/keepalived/check_apiserver.sh + mode: '644' + +- name: Наливаю haproxy.cfg + ansible.builtin.copy: + src: haproxy.cfg + dest: /etc/haproxy/haproxy.cfg + mode: '644' + +- name: Наливаю keepalived static pods manifest + ansible.builtin.copy: + src: keepalived.yaml + dest: /etc/kubernetes/manifests/keepalived.yaml + mode: '644' + +- name: Наливаю haproxy static pods manifest + ansible.builtin.copy: + src: haproxy.yaml + dest: /etc/kubernetes/manifests/haproxy.yaml + mode: '644' diff --git a/ansible/roles/haproxy_static_pods/templates/keepalived.conf.j2 b/ansible/roles/haproxy_static_pods/templates/keepalived.conf.j2 new file mode 100644 index 0000000..b853b0a --- /dev/null +++ b/ansible/roles/haproxy_static_pods/templates/keepalived.conf.j2 @@ -0,0 +1,29 @@ +! /etc/keepalived/keepalived.conf +! Configuration File for keepalived +global_defs { + router_id LVS_DEVEL +} +vrrp_script check_apiserver { + script "/etc/keepalived/check_apiserver.sh" + interval 3 + weight -2 + fall 10 + rise 2 +} + +vrrp_instance VI_1 { + state MASTER + interface eth0 + virtual_router_id 51 + priority 101 + authentication { + auth_type PASS + auth_pass {{ lookup('password', 'secrets/kubeadm/keepalived/auth_pass length=64') }} + } + virtual_ipaddress { + 10.0.70.85/24 + } + track_script { + check_apiserver + } +} diff --git a/kubeadm/README.md b/kubeadm/README.md new file mode 100644 index 0000000..c52b102 --- /dev/null +++ b/kubeadm/README.md @@ -0,0 +1,506 @@ +# Настройка kubernetes кластера после чистой установки при помощи **kubeadm** + +## Подготовка ВМ + +Тестирование проводилось на **Ubuntu 22.04** + +Подготавливаем ВМ при помощи [плейбука](../ansible/kubeadm.yml) + +Плейбук настроит все что нудно для работы **Kubernetes**. +Добавит необходимые **модули ядра**, установит **kubelet**, **kubeadm**, **kubectl**, **cri-o**... и перезапустит машинки если это необходимо. + +Запускаем плейбук + +```sh +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 + +вторник 23 апреля 2024 09:29:22 +0300 (0:00:41.104) 0:02:19.111 ******** +=============================================================================== +Устанавливаю пакеты 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 +``` + +## Инициализация кластера + +Первый вариант подходит для тестирования, или создания не отказоустоичивого кластера, +Второй вариант создаст отказоустойчивый кластер готовый для прода. + +### Non HA (Подходит для тестирования, не рекомендуется для прода) + +Для инициализации кластера запускаем на **control-plane** машинке команду + +```sh +sudo kubeadm init --pod-network-cidr=10.244.0.0/16 +``` + +Команда инициализирует кластер Kubernetes с указанием диапазона подсети для сети плагина CNI (Container Network Interface). +В результате выполнения вы увидите лог выполнения и получите краткую инструкцию по дальнейшей работе. + +В результате мы должны получить что-то подобное + +```sh +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 2m9s v1.30.0 10.0.70.70 Ubuntu 22.04.4 LTS 5.15.0-105-generic cri-o://1.30.0 +kubeadm-node-01 Ready 27s v1.30.0 10.0.70.71 Ubuntu 22.04.4 LTS 5.15.0-105-generic cri-o://1.30.0 +kubeadm-node-02 Ready 13s v1.30.0 10.0.70.77 Ubuntu 22.04.4 LTS 5.15.0-105-generic cri-o://1.30.0 +``` + +### HA (Production Ready решение, рекомендуется) + +Мы разместим **haproxy** и **keepalived** на **control-plane** узлах. Конфигурации налиты при помощи Ansible на этапе подготовки. +Наш виртуальный IP: **10.0.70.85:7443** для взаимодействия с **Kube Api Server** + +```sh +sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=10.0.70.85:7443 --upload-certs +``` + +При успешном выполнении мы увидим примерно следующее + +```output +Your Kubernetes control-plane has initialized successfully! + +To start using your cluster, you need to run the following as a regular user: + + mkdir -p $HOME/.kube + sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config + sudo chown $(id -u):$(id -g) $HOME/.kube/config + +Alternatively, if you are the root user, you can run: + + export KUBECONFIG=/etc/kubernetes/admin.conf + +You should now deploy a pod network to the cluster. +Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: + https://kubernetes.io/docs/concepts/cluster-administration/addons/ + +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 \ + --discovery-token-ca-cert-hash sha256:cacb3c674f63d7f261c4fed403f59ce6e7d4c869c3748e301c98b2b9f17f7786 \ + --control-plane --certificate-key 31ba08487b6899c2ebe43dd3857e168840a98d1077a7998c79f6f4838b4c08f7 + +Please note that the certificate-key gives access to cluster sensitive data, keep it secret! +As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use +"kubeadm init phase upload-certs --upload-certs" to reload certs afterward. + +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 \ + --discovery-token-ca-cert-hash sha256:cacb3c674f63d7f261c4fed403f59ce6e7d4c869c3748e301c98b2b9f17f7786 +``` + +Добавляем узлы и проверяем. + +В результате мы должны получить что-то подобное + +```sh +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 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 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 Ubuntu 22.04.4 LTS 5.15.0-105-generic cri-o://1.30.0 +kubeadm-node-01 Ready 53s v1.30.0 10.0.70.71 Ubuntu 22.04.4 LTS 5.15.0-105-generic cri-o://1.30.0 +kubeadm-node-02 Ready 27s v1.30.0 10.0.70.77 Ubuntu 22.04.4 LTS 5.15.0-105-generic cri-o://1.30.0 +kubeadm-node-03 Ready 37s v1.30.0 10.0.70.74 Ubuntu 22.04.4 LTS 5.15.0-105-generic cri-o://1.30.0 +``` + +## Настройка CNI + +**CNI (Container Network Interface)** - это спецификация, которая определяет, как контейнеры в сети взаимодействуют друг с другом и с внешним миром. +Она позволяет плагинам сети в Kubernetes управлять сетевыми настройками контейнеров. + +Мы установим простой плагин **Flannel** + +**Flannel** - это один из плагинов сети для Kubernetes, который обеспечивает сетевую подсистему для контейнеров. +Он позволяет контейнерам в кластере общаться друг с другом и с внешним миром, обеспечивая сетевую изоляцию и маршрутизацию. + +Настраиваем **Flannel**: + +```sh +kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml +``` + +Проверяем + +```sh +kubectl get pods -o wide -n kube-flannel +``` + +Должны увидеть, что-то подобное + +```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 +kube-flannel-ds-8fzzw 1/1 Running 0 26s 10.0.70.74 kubeadm-node-03 +kube-flannel-ds-9hrcj 1/1 Running 0 26s 10.0.70.78 kubeadm-cp-02 +kube-flannel-ds-gm24r 1/1 Running 0 26s 10.0.70.70 kubeadm-cp-01 +kube-flannel-ds-rd7jr 1/1 Running 0 26s 10.0.70.77 kubeadm-node-02 +kube-flannel-ds-rjsl9 1/1 Running 0 26s 10.0.70.79 kubeadm-cp-03 +``` + +## Установка тестового приложения + +Для проверки работоспособности кластера установим **kube-prometheus-stack** при помощи **helm** + +```sh +helm upgrade \ + --install \ + --namespace monitoring \ + --create-namespace \ + kube-prometheus-stack \ + prometheus-community/kube-prometheus-stack \ + --version 58.2.2 +``` + +Проверяем, что все запустилось + +```sh +kubectl get pods -o wide -n monitoring +``` + +Должны увидеть + +```output +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +alertmanager-kube-prometheus-stack-alertmanager-0 2/2 Running 0 34s 10.244.2.5 kubeadm-node-02 +kube-prometheus-stack-grafana-67997d8bd4-7s2fq 3/3 Running 0 50s 10.244.1.2 kubeadm-node-01 +kube-prometheus-stack-kube-state-metrics-6fb5dddbdb-48l45 1/1 Running 0 50s 10.244.2.3 kubeadm-node-02 +kube-prometheus-stack-operator-775b5fb784-gpn94 1/1 Running 0 50s 10.244.1.3 kubeadm-node-01 +kube-prometheus-stack-prometheus-node-exporter-9d6ks 1/1 Running 0 50s 10.0.70.71 kubeadm-node-01 +kube-prometheus-stack-prometheus-node-exporter-d74z8 1/1 Running 0 50s 10.0.70.77 kubeadm-node-02 +kube-prometheus-stack-prometheus-node-exporter-fzgq2 1/1 Running 0 50s 10.0.70.70 kubeadm-cp-01 +prometheus-kube-prometheus-stack-prometheus-0 2/2 Running 0 34s 10.244.2.6 kubeadm-node-02 +``` + +Зайдем на веб интерфейс графаны + +```sh +kubectl port-forward -n monitoring svc/kube-prometheus-stack-grafana 8000:80 +``` + +Заходим на [localhost:8000](http://localhost:8000/login) и вводим + +```grafana +Логин: admin +Пароль: prom-operator +``` + +## Настройка CSI + +**CSI (Container Storage Interface)** - это спецификация, которая позволяет контейнерам в **Kubernetes** взаимодействовать с различными хранилищами данных, +такими как блочные и файловые системы, через стандартизированный интерфейс. Это позволяет управлять хранилищем данных более гибко и эффективно в среде контейнеров. + +Для организации системы хранения в кластере, мы будем использовать **[Longhorn](https://longhorn.io/)**. + +**Longhorn** - это легкая, надежная и мощная система хранения распределенных блоков для **Kubernetes**. + +**Longhorn** реализует распределенное блочное хранилище с помощью **контейнеров** и **микросервисов**. +**Longhorn** создает выделенный контроллер хранения для каждого тома блочного устройства и синхронно реплицирует том на несколько реплик, +хранящихся на нескольких узлах. Контроллер хранилища и реплики сами оркеструются с помощью **Kubernetes**. + +### Характеристики + +- **Распределенное блочное хранилище** корпоративного класса без единой точки отказа +- **Инкрементный снимок** блочного хранилища +- Резервное копирование на вторичное хранилище (**NFS** или **S3-совместимое** объектное хранилище), основанное на эффективном обнаружении блоков изменений +- **Повторяющиеся снимки** и **резервное копирование** +- **Автоматизированное обновление без сбоев**. Вы можете обновить весь стек программного обеспечения **Longhorn**, не нарушая работу томов хранения. +- Интуитивно понятная приборная панель с **графическим интерфейсом** + +### Пререквизиты + +- Кластер Kubernetes: Убедитесь, что каждый узел соответствует требованиям к установке. +- Ваша рабочая станция: Установите Helm версии 3.0 или более поздней. + +### Установка Longhorn + +Примечание: + +- Начальные настройки для **Longhorn** можно найти в пользовательских опциях **Helm** или отредактировав файл конфигурации развертывания. +- Для **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 см. в этом разделе. +- Поддержка RWX требует, чтобы на каждом узле был установлен клиент NFSv4. + Об установке клиента NFSv4 читайте в этом разделе. +- Файловая система узла поддерживает функцию расширения файлов для хранения данных. В настоящее время мы поддерживаем: + ext4 + XFS +- Должны быть установлены bash, curl, findmnt, grep, awk, blkid, lsblk. +- Распространение монтирования должно быть включено. + +Рабочие нагрузки Longhorn должны иметь возможность запускаться от имени root, чтобы Longhorn был развернут и работал должным образом. + +Этот сценарий можно использовать для проверки среды Longhorn на наличие потенциальных проблем. + +Минимальное рекомендуемое аппаратное обеспечение см. в руководстве по передовому опыту. + +1. Добавьте репозиторий Longhorn Helm: + + ```sh + helm repo add longhorn https://charts.longhorn.io + ``` + +2. Получите список последних чартов из репозитория: + + ```sh + helm repo update + ``` + +3. Установите Longhorn в пространстве имен longhorn-system. + + ```sh + helm upgrade \ + --install \ + longhorn longhorn/longhorn \ + --namespace longhorn-system \ + --create-namespace \ + --version 1.6.1 + ``` + +4. Чтобы убедиться, что развертывание прошло успешно, выполните команду: + + ```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 + ``` + +5. Чтобы включить доступ к пользовательскому интерфейсу Longhorn, необходимо настроить контроллер Ingress. + + По умолчанию аутентификация в пользовательском интерфейсе Longhorn не включена. + Информацию о создании контроллера NGINX Ingress с базовой аутентификацией см. в [этом разделе](https://longhorn.io/docs/1.6.1/deploy/accessing-the-ui/longhorn-ingress). + +6. Войдите в пользовательский интерфейс Longhorn, выполнив [следующие действия](https://longhorn.io/docs/1.6.1/deploy/accessing-the-ui). + +Посмотреть на веб интерфейс можно так: + +```sh +kubectl port-forward -n longhorn-system svc/longhorn-frontend 8000:80 +``` + +## Ingress Controller + +Ingress Controller - это компонент в Kubernetes, который управляет входящими HTTP и HTTPS запросами в кластер. +Он обеспечивает балансировку нагрузки, маршрутизацию трафика и обеспечивает доступ к службам внутри кластера извне. + +Ingress Controller работает на уровне приложения и использует информацию из объекта Ingress, который определяет правила маршрутизации для входящего трафика. +Это позволяет настраивать маршрутизацию трафика без изменения конфигурации службы или приложения. + +### Установка при помощи helm + +Добавьте репозиторий Traefik Labs в Helm: + +```sh +helm repo add traefik https://traefik.github.io/charts +``` + +Вы можете обновить хранилище, выполнив команду: + +```sh +helm repo update +``` + +И установите его с помощью командной строки Helm: + +```sh +helm upgrade \ + --install \ + --namespace traefik \ + --create-namespace \ + traefik traefik/traefik +``` + +### Проброс дашборда Traefik + +```sh +kubectl port-forward -n traefik $(kubectl get pods -n traefik --selector "app.kubernetes.io/name=traefik" --output=name) 9000:9000 +``` + +Его ним можно увидеть по адресу: [127.0.0.1:9000/dashboard/](http://127.0.0.1:9000/dashboard/) + +## Удаляем узел из кластера + +В Kubernetes, для удаления узла (node) из кластера, вы можете использовать следующую команду kubectl + +```sh +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 +``` + +## Просмотр списка join ссылок в Kubernetes + +Для просмотра списка join ссылок в Kubernetes, вы можете использовать команду kubeadm token list. +Эта команда отобразит список всех активных join токенов, которые могут быть использованы для присоединения новых узлов к кластеру. + +Вот пример использования: + +```sh +kubeadm token list +``` + +Для получения join ссылки в Kubernetes, вы можете использовать команду kubeadm token create --print-join-command. +Эта команда создаст новый join токен и напечатает команду, которую вы можете использовать для присоединения новых узлов к кластеру. + +Вот пример использования: + +```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 +``` diff --git a/opentofu/kubeadm/.terraform.lock.hcl b/opentofu/kubeadm/.terraform.lock.hcl new file mode 100644 index 0000000..b67ed60 --- /dev/null +++ b/opentofu/kubeadm/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "tofu init". +# Manual edits may be lost in future updates. + +provider "registry.opentofu.org/bpg/proxmox" { + version = "0.54.0" + constraints = ">= 0.51.0" + hashes = [ + "h1:xgDrDol/cYu93YOPTL0UVpURchPzdxPXaHjcoieoXXI=", + "zh:4521f8893b4645c93e75ffc3545ea59d3f31aed7cea4c26dcd0fbd7c0cce6ca8", + "zh:520e56abd10d888935047ef07a7577c2a1cce5bc54e25b03a0dbdc4356997ca9", + "zh:53469dd058ef8b2ea29577f69a2681f8ffb9f79494b8c1d1594dd42ad314d7bd", + "zh:6948adb6e088fe652b7273906a5c11032528f84eb5a5ca797534ab3b6076a8c6", + "zh:72655e9765b7791e3e37508c70a847172561bff348c7d5f916794e5823a84efe", + "zh:7faa281319d90026ad9b2dce00ac059896f451cb9305ed11bb90fcfda7c5d143", + "zh:8fe20fa893e9545aa30672392f76948ed56a93a2decb1d3bd8693c5e1d2dd85a", + "zh:b175411aa820c1a47473ef691c743670eeb900999576c6cdcb113d14a7c499aa", + "zh:b59205ad7981f263ff287d3eb0a93296f8cd6b166a01ddd3b16606fc39d456ec", + "zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597", + "zh:f3524bc67d995e98ad9d7e17f3be91f7a975608180fad6b227fc42087b5facc1", + "zh:f4bf087717e1b0f5f3ee7d3b6b47fb66e5f821097f15ec0cf6714a39c7d80959", + "zh:fc14a29b1aef50872d60f338af89f7cbbac307c630f973c07a7951bdde8be2a5", + "zh:fc72da3d651bf0f0e20a0860e9217a94797b4c1d5cae1742f1b8e15d28f8ceeb", + "zh:fff2299a427e1590775611bf186220686795af966772e61e44234f0df44b6c22", + ] +} diff --git a/opentofu/kubeadm/control-plane-01.tf b/opentofu/kubeadm/control-plane-01.tf new file mode 100644 index 0000000..bf52ebf --- /dev/null +++ b/opentofu/kubeadm/control-plane-01.tf @@ -0,0 +1,70 @@ +# Машинка +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..." + ] + } + } +} diff --git a/opentofu/kubeadm/control-plane-02.tf b/opentofu/kubeadm/control-plane-02.tf new file mode 100644 index 0000000..af4c73e --- /dev/null +++ b/opentofu/kubeadm/control-plane-02.tf @@ -0,0 +1,70 @@ +# Машинка +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..." + ] + } + } +} diff --git a/opentofu/kubeadm/control-plane-03.tf b/opentofu/kubeadm/control-plane-03.tf new file mode 100644 index 0000000..cd6809c --- /dev/null +++ b/opentofu/kubeadm/control-plane-03.tf @@ -0,0 +1,70 @@ +# Машинка +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..." + ] + } + } +} diff --git a/opentofu/kubeadm/node-01.tf b/opentofu/kubeadm/node-01.tf new file mode 100644 index 0000000..8e3304d --- /dev/null +++ b/opentofu/kubeadm/node-01.tf @@ -0,0 +1,70 @@ +# Машинка +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..." + ] + } + } +} diff --git a/opentofu/kubeadm/node-02.tf b/opentofu/kubeadm/node-02.tf new file mode 100644 index 0000000..806e1c4 --- /dev/null +++ b/opentofu/kubeadm/node-02.tf @@ -0,0 +1,70 @@ +# Машинка +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..." + ] + } + } +} diff --git a/opentofu/kubeadm/node-03.tf b/opentofu/kubeadm/node-03.tf new file mode 100644 index 0000000..5011423 --- /dev/null +++ b/opentofu/kubeadm/node-03.tf @@ -0,0 +1,70 @@ +# Машинка +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..." + ] + } + } +} diff --git a/opentofu/kubeadm/provider.tf b/opentofu/kubeadm/provider.tf new file mode 100644 index 0000000..912ac71 --- /dev/null +++ b/opentofu/kubeadm/provider.tf @@ -0,0 +1,17 @@ +terraform { + required_providers { + proxmox = { + source = "bpg/proxmox" + version = ">= 0.51.0" + } + } +} + +provider "proxmox" { + endpoint = var.virtual_environment_endpoint + api_token = var.virtual_environment_api_token + insecure = true + ssh { + agent = false + } +} diff --git a/opentofu/kubeadm/terraform.tfvars.example b/opentofu/kubeadm/terraform.tfvars.example new file mode 100644 index 0000000..b1c8e8e --- /dev/null +++ b/opentofu/kubeadm/terraform.tfvars.example @@ -0,0 +1,2 @@ +virtual_environment_api_token = "root@pam!for-terraform-provider=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +virtual_environment_endpoint = "https://10.0.70.116:8006/" diff --git a/opentofu/kubeadm/variables.tf b/opentofu/kubeadm/variables.tf new file mode 100644 index 0000000..4508554 --- /dev/null +++ b/opentofu/kubeadm/variables.tf @@ -0,0 +1,9 @@ +variable "virtual_environment_endpoint" { + type = string + description = "The endpoint for the Proxmox Virtual Environment API (example: https://host:port)" +} + +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)" +}