Tech Recipe Book
My Services
  • Book
    • About the author
    • Architect
      • Algorithms
        • DB index algorithms
          • How does database indexing work
        • Neural network optimization
          • Neural Network Optimization
        • Route search
          • Road network in a database to build a route
          • Traveling Salesman Problem (TSP)
      • Architecture Frameworks
        • DODAF
        • TOGAF
        • Enterprise Architecture (EA) Tools Reviews 2023 | Gartner
      • Zero Trust
      • Billing
        • SHM billing system
      • Bots
        • Discord
        • Telegram
          • Chat GPT Telegram bot
          • Получаем статистику Telegram-канала при помощи api и python или свой tgstat с регистрацией и смс
          • Как хостить телеграм-бота (и другие скрипты на Python) на Repl.it бесплатно 24/7
          • Создание Telegram бота на PHP #1: основные понятия для работы с API
          • Создание Telegram бота на PHP #2: создание первого бота для Telegram
          • Создание Telegram бота на PHP #3: примеры отправки сообщений с кнопками в Telegram
          • Создание Telegram бота на PHP #4: отправка файлов и изображений в Telegram
          • Создание Telegram бота на PHP #5: работа с хуками
      • Business intelligence
      • Cloud Storage
        • Ceph
        • Virtual Distributed File System
      • Cryptography
        • Open Source PKI Software
        • OpenPGP
          • Email Encryption
          • Kleopatra
          • Miscellaneous Tools
          • Server side applications
      • Message broker
        • Kafka
          • Kafka UI-tools
          • Kafka streams ksqlDb
        • RabbitMQ
      • DB
        • MySQL
          • Auto sharding
          • MariaDB Zabbix monitoring
          • MySQL and MariaDB replication with Zabbix monitoring
        • Postgres
          • HA PostgreSQL with Patroni, Haproxy, Keepalived
          • Mass parallel requests - Greenplum
          • PostgreSQL cluster for development and testing
        • Vitess - Scalable. Reliable. MySQL-compatible. Cloud-native. Database.
      • Identity and Access Management (IDM)
        • FreeIPA - Identity, Policy, Audit
        • FreeIPA as an Enterprise solution
        • Keycloak
          • Keycloak HA cluster
        • Open Identity Platform
        • SSO
          • Keycloak for Java app
          • OpenAM
          • OpenIG
      • Firewall
        • nftables
      • Infrastructure As a Code
        • Ansible
        • IaC Packer Ansible Teraform
        • Installing Jenkins using terraform in Kubernetes in Yandex Cloud with letsencypt
        • Teraform Crosplan Pulumi
        • Yandex IaC solutions
      • Kubernetes
        • Installation
          • Install Kubernetes cluster
          • Deploying a Kubespray cluster to OpenStack using Terraform
          • Kube deploy in Yandex cloud
        • Frameworks
          • Deckhouse
            • LDAP authentification
            • On premise Install
            • Yandex Cloud Install
          • K3S
          • OpenShift OKD
          • RKE2
          • Rancher
            • Rancher Install
        • Auth
          • Keycloak in k8s
          • LDAP
        • GUI management Lens
        • Monitoring
          • Monitoring with Falco
          • Network monitoring
          • Nginx ingress
          • Prometheus Graphana for sample Nodejs app
          • Rsource monitoring Avito
        • Exposing services
          • Exposing Kubernetes Services
          • Cilium BGP
        • CNCF
        • Helm
          • Repositories
            • Artifact Hub | official
            • Bitnami | vmware
          • Awesome helm charts and resources
          • Essential Services for Modern Organizations
          • Security and Compliance
          • Additional charts
        • Isolation
          • vcluster - Virtual Kubernetes Clusters
          • Kiosk
          • KubeArmor
          • Control Plane Hardening
          • Hierarchical namespaces
        • Security Center
          • Minesweeper
          • NeuVector by SUSE
          • SOAR in Kubernetes
          • Security Сenter for Kubernetes
        • Terraform CI security
          • Terraform plan analysis with Checkov and Bridgecrew
          • Yandex Terraform scan
        • Vulnerability management
          • Aqua
          • Sysdig
          • Kyverno
          • GitLab
          • NeuVector by SUSE
        • Image scanning
          • Snyk
          • Sysdig
          • Harbor
          • Trivy
        • Signature verification
          • Sigstore
        • Control plane security
          • Gatekeeper
            • Applying OPA Gatekeeper
          • Kyverno
            • Policy as a code. Kyverno
        • Runtime Security
          • Osquery
          • Falco
          • ClamAV
        • Network security
          • Cilium
          • Control Plane Hardening (API restriction)
          • Network policy recipes
          • Service mesh
            • Istio HA, LoadBalance, Rate limit
          • mTLS Autocert
        • Honeypot
          • Building honeypot using vcluster and Falco
        • Backup
          • Kasten K10
        • Secrets
          • Vault CSI Driver
      • Load Balance
        • Nginx
        • HAProxy
          • Proxy methods
          • HAProxy for RDP
          • Payment gateway A/B test with HAProxy
          • HAPRoxy for Percona or Galera
      • Monitoring
        • Zabbix
          • Apache Zabbix
          • Disc Quota
          • Nginx Zabbix
          • SSL certificates Zabix
          • Zabbix notifications
        • Nagios
          • Datacenter monitoring
        • Prometheus and Grafana
      • Windows
        • Sysmon enhanced Windows audit
        • Sysmon to Block Unwanted File
      • Linux
        • Rsync
        • Debian based
          • Apt-Cacher NG
          • Unattended Upgrades in Debian / Ubuntu
        • RedHat basede
          • RPM Server
        • Logs analysis
        • Build armhf qemu
      • NGFW
      • CI/CD
        • DevSecOps
          • DAST
            • Burp
              • Dastardly
            • StackHawk
            • ZAP and GitHub Actions
          • SAST
            • Checkmarx
            • OSV by Google
            • Snyk
            • SonarQube
        • GitLab Runner in Yandex Cloud
        • Dynamic Gitlab Runners in Yandex Cloud
        • GitLab runner in Kubernetes with Werf
        • Kubernetes deploy strategies
        • Kubernetes highload deploy. part 1
        • Kubernetes highload deploy. part 2
        • Kubernetes Argo Rollouts
        • Jenkins in Kubernetes
        • Ansible Semaphore
        • Image storage, scaning and signing
        • Install WireGuard with Gitlab and Terraform
        • CI/CD example fror small web app
        • Threat matrix for CI CD Pipeline
      • SIEM / SOC
        • Datadog
        • Splunk
          • Splunk — general description
        • MaxPatrol
          • MaxPatrol 8 and RedCheck Enterprise
        • QRadar IBM
        • Cloud Native Security Platform (CNAPP) - Aqua
        • OSSIM | AT&T
          • AlienVault (OSSIM) install
        • Wazuh
        • EDR
          • Cortex XDR | Palo Alto Networks
          • Cynet
          • FortiEDR | Fortinet
          • Elastic
        • Elastic
          • Install Elasticsearch, Logstash, and Kibana (Elastic Stack) on Ubuntu 22.04
          • Setting Up Elastic 8 with Kibana, Fleet, Endpoint Security, and Windows Log Collection
        • Threat Intelligence
          • MISP
          • msticpy Microsoft
          • X-Force | IBM
          • Elastic
      • VPN
        • Full-Mesh VPN fastd, tinc, VpnCloud
        • Wireguard
          • WireGuard for Internet access
          • WireGuard on MikroTik and Keenetic
          • WireGuard site to site
        • SoftEther VPN Project
        • Cisco AnyConnect client
        • OpenConnect
        • SSTP python server
      • OS hardening
        • CIS Benchmarks
      • Cloud Providers
      • OpenNebula
        • OpenNebula Edge Cloud - Open Source Cloud & Edge Computing
        • Discover OpenNebula – Open Source Cloud & Edge Computing Platform
        • OpenNebula Multi-Cloud
        • Kubernetes on OpenNebula
        • The Open Source Alternative to Nutanix
        • The Simple Alternative to OpenStack
        • OpenNebula Partner Ecosystem
      • OpenStack
        • Install manual
        • Install with DevStack
      • VM
        • Create a VHD file from a Linux disk
        • Backup / Migration
          • Coriolis
          • Proxmox Backup Server
        • oVirt
        • VMware vCenter
        • Proxmox
      • Docker
        • Container optimization
        • Ubuntu RDP container
      • LXC
        • LXD on Ubuntu 18.04
        • Install, Create and Manage LXC in Ubuntu/Debian
    • Big Data
      • OLAP data qubes
      • Storage and autoscale in Lerua
    • Machine Learning
      • Yandex YaLM 100B. GPT model
      • Kaggle Community Datasts Models
      • AI in video production
      • Image search
      • Chat bots
        • You.com
        • Chat GPT
          • Implementing GPT in NumPy
        • Jailbreak Chat
      • Coding plugins CodeWhisperer
    • Malware
      • Isiaon/Pitraix: Modern Cross-Platform Peer-to-Peer Botnet over TOR
      • theZoo A repository of LIVE malwares
    • Pentest
      • Red Team
        • MITRE ATT&CK matrix
        • C2 Frameworks
          • Brute Ratel C4
          • Cobalt Strike
          • Covenant
          • Havoc Framework
          • Merlin
          • Metasploit
          • Sillenttrinity
          • Sliver
        • Manage and report
          • Dradis Framework
          • Hexway
        • Underground
      • Social engineering
        • Social Engineer Toolkit setoolkit
      • OSINT
        • OSINT for comapny
        • Instagram fishing
      • Forensics
        • Forensics tools
      • Pentesting Methodology
      • Web
      • CI/CD Methodology
      • Cloud Methodology
        • Hacking The Cloud
      • Kubernetes Pentesting
      • Android
        • SSL Unpinning for Android applications
      • iOS
        • SSL unpinning iOS and macOS applications
      • HackBar tool
      • CyberChef Tools
      • Python virtualenv
      • IppSec - YouTube
      • Hacktricks.xyz
    • Compliance
      • 152 ФЗ. Personal data
      • PCI DSS and ГОСТ Р 57580.1-2017
      • Cloud compliance
      • ГОСТ Р 57580.1-2017 для Kubernetes
      • Kubernets as DevSecOps and NIST compliance
      • NIST SP 800-61 cyberincidece control
      • CIS Kubernetes Benchmark v1.6 - RKE2 v1.20
      • CIS Kubernetes Benchmark v1.23 - RKE2
      • Requirements for Russian Banks
      • Tools
        • Chef InSpec
        • Elastic SIEM
    • Asset management
      • CMDBuild
    • Project management
    • Incident management SRE
    • Risk management
      • IT risk management
      • BSI-Standard 200-3
    • Web Dev
      • Cookie security
      • OWASP Top 10 2021
      • Docker nginx php mysql
      • Docker tor hiddenservice nginx
      • Docker Compose wp nginx php mariadb
      • Dependency Checking
        • Nexus Analyzer
        • OWASP dependency-check
      • Yii skeeks cms
      • YiiStudio
    • Art
      • GTK Themes
      • Themes for Xfce Desktop
      • XFCE / Xubuntu Windows 95
      • Moscow events
      • Photo goods
      • Russian style gifts
    • Cryptocurrency
      • News
      • Arbitrage
      • Stocks
      • Exchange aggregators
      • Where to use
      • Prepaid cards
        • BitFree
        • Pyypl Your Money at Your Fingertips
    • IT magazines
      • WIKI and Writeups tools
        • BookStack
        • GitBook
        • MkDocs
        • Wiki.js
        • DokuWiki
    • Languages
    • Learning
      • (ISC)2
        • CISSP
      • Offensive Security
        • OSCP
        • OSEP
        • OSED
      • DevSecOps
        • Certified DevSecOps Professional (CDP)
        • Certified DevSecOps Expert (CDE)
      • Web Security Academy: PortSwigger
    • Relocation
      • London experience
      • IT visas in 2022
      • Remote work
      • Running business in UAE
    • Freenet
      • Independent online services: the philosophy of a free Internet
      • Tor Project Anonymity Online
      • I2P Anonymous Network
    • Services
      • SMS Registration
        • Registering ChatGPT in Russia
      • Local and regional eSIMs for travellers - Airalo
      • Digital busines cards
      • No KYC services and exchanges
Powered by GitBook
On this page
  • В предыдущих статьях
  • Проблема
  • Выбор инструментов
  • Архитектура
  • Инфраструктура
  • Реализация
  • Подготовка
  • Инит конфиг
  • Запускаем
  • Наполнение
  • Внимание
  • Планы
  • Контакты

Was this helpful?

  1. Book
  2. Architect
  3. Kubernetes
  4. Installation

Kube deploy in Yandex cloud

Last updated 1 year ago

Was this helpful?

Всем привет. Меня зовут Путилин Дмитрий (Добрый Кот) .

От коллектива и при поддержке : Продолжаем серию статей о K8S.

В этой статье мы поделимся своим опытом разработки Managed K8S под Yandex Cloud и расскажем, как мы создали конфигурацию, которую можно легко адаптировать для запуска в любом облаке или on-premises решении, изменяя только некоторые настройки. Если вы заинтересованы в построении гибких и масштабируемых Kubernetes-кластеров, то этот материал обязательно для вас.

В предыдущих статьях

Проблема

Из моего личного опыта могу сказать, что Managed решения в облаках или в онпрем‑серверах — это отличный инструмент для создания своего продукта, и зачастую этого достаточно. Однако, бывают ситуации, когда нужно больше гибкости и возможностей настройки, а Managed решение предоставляет ограниченный набор функций.

Для нас было критично использовать сетевой плагин Cilium с нашими настройками, также нам требовались флаги feature‑gates, которых по дефолту нет в Yandex K8S API.

В принципе, не беда, мы всегда можем развернуть стационарный K8S и закастомизировать его как нам угодно. Возникли следующие вопросы: какие инструменты взять, какой выстроить процесс и как сделать так, что бы создаваемые кластера были одинаковыми?

Выбор инструментов

Для данной задачи однозначно требуются cloud native инструменты, поэтому выбор пал на Terraform. Остались вопросы: как настраивать узлы, нужен ли нам Ansible, Puppet, SaltStack? После 3 месяцев поиска золотой пилюли мы поняли, что для создания кластера нам потребуется только Terraform и cloud‑init.

Архитектура

Так как в основе нашего продукта лежит Terraform, то одно из условий работы с ним — Сервисно‑ресурсная модель (СРМ).

Ресурсами выступают все его компоненты, от балансировщика нагрузки до конфигураци cloud‑init для нашего кластера.

Также CPM позволяет менять одинаковые типы ресурсов без потребности в смене процесса деплоя кластера, таким образом, описав модули создания инфраструктуры под Yandex Cloud, VK Cloud и т. п., и, поменяв намеример модуль Yandex cloud на модуль VK Cloud, получим тот же результат, но в другом окружении.

  • Для получения secret_id и role_id от Approle можно использовать временный токен, который имеет ограниченный доступ. Для этого токен должен иметь достаточно длительный срок жизни, чтобы виртуальная машина успела запустить клиента, или можно указать, что использование токена допустимо только один раз.

  • Использование сервиса IAM от облачного провайдера для сохранения secret_id/role_id для каждой машины в облаке. Затем, можно использовать cloud-cli для получения необходимых секретов прямо с хоста.

Мы предпочли второй вариант и выбрали его, так как он лучше подходил для нашего случая. Однако первый вариант может быть полезен в тех облаках, где нет поддержки сервиса IAM.

variable "k8s_global_vars" {
  description = "module:K8S-GLOBAL VARS"
  type        = any
  default     = {}
}

При создании структуры этого модуля мы также уделяли внимание принципу "записал - забыл" - это означает, что если мы хотим добавить только переменную, но нехотим добавлять соответствующий вывод в OUTPUT, нам нужно использовать структурные массивы, в которые мы добавляем только нужные нам переменные, а глобальный вывод остается единым на блок. Например:

locals {

  k8s-addresses = {
    local_api_address           = format("%s.1",  join(".", slice(split(".",local.k8s_network.service_cidr), 0, 3)) )
    dns_address                 = format("%s.10", join(".", slice(split(".",local.k8s_network.service_cidr), 0, 3)) )

    idp_provider_fqdn           = format("auth.%s"          , local.cluster_metadata.base_domain)
    base_cluster_fqdn           = format("%s.%s"            , local.cluster_metadata.cluster_name, local.cluster_metadata.base_domain)
    wildcard_base_cluster_fqdn  = format("%s.%s.%s", "*"    , local.cluster_metadata.cluster_name, local.cluster_metadata.base_domain)
    etcd_server_lb_fqdn         = format("%s.%s.%s", "etcd" , local.cluster_metadata.cluster_name, local.cluster_metadata.base_domain)
  }
}

output "k8s-addresses" {
  value = local.k8s-addresses
}

Генерация cloud-init конфигурации является не менее важным аспектом, поскольку эта конфигурация передается виртуальной машине при ее создании.

В первых версиях мы были вынуждены описывать каждый файл, создавать шаблоны для них и выносить их в отдельные модули по логическому смыслу, например, модуль containerd" включал в себя конфигурационные файлы и шаблоны для systemd сервисов. Однако, такой подход был слишком трудоемким в поддержке из-за большого количества модулей.

Мы решили использовать подход, подобный kubeadm. Сначала мы попытались развернуть кластер с помощью kubeadm, но выяснилось, что он не может выполнить первоначальную настройку системы, такую как установка пакетов, добавление конфигурационных файлов и запуск сервисов. Поэтому мы начали разработку инструмента, который бы мог настроить систему до требуемого состояния. Результатом этой работы стал fraimctl - инструмент, который заменил множество шаблонов одной командой fraimctl init.

Таким образом, нам оставалось описать:

У нас есть несколько задач, которые мы должны выполнить, чтобы полностью отказаться от kubeadm. Мы планируем перенести этап создания конфигурационных файлов key-keeper, kubeconfig и static pod manifests в fraimctl. Кроме того, мы добавим функционал для проверки готовности сертификатов и кластера, а также этап маркировки узлов. Это позволит нам полностью отказаться от использования kubeadm и не зависеть от этого инструмента.

Как уже упоминалось ранее, этот инструмент создан для возможности полного отказа от использования kubeadm и настройки кластеров без его использования.

Пример конфигурациооного файла:

fraimctl.conf
- apiVersion: fraima.io/v1alpha
  kind: Containerd
  spec:

    service:
      extraArgs:
        # This document provides the description of the CRI plugin configuration. 
        # The CRI plugin config is part of the containerd config
        # Default: /etc/containerd/config.toml
        config: /etc/kubernetes/containerd/config.toml

    configuration:
      extraArgs:
        version: 2
        plugins:
          io.containerd.grpc.v1.cri:
            containerd:
              runtimes:
                runc:
                  # Runtime v2 introduces a first class shim API for runtime authors to integrate with containerd. 
                  # The shim API is minimal and scoped to the execution lifecycle of a container.
                  runtime_type: "io.containerd.runc.v2"
                  options:
                    # While containerd and Kubernetes use the legacy cgroupfs driver for managing cgroups by default, 
                    # it is recommended to use the systemd driver on systemd-based hosts for compliance of the "single-writer" rule of cgroups. 
                    # To configure containerd to use the systemd driver, set the following option:
                    SystemdCgroup: true

    downloading:
      - name: containerd
        src: https://github.com/containerd/containerd/releases/download/v1.6.6/containerd-1.6.6-linux-amd64.tar.gz
        checkSum:
          src: https://github.com/containerd/containerd/releases/download/v1.6.6/containerd-1.6.6-linux-amd64.tar.gz.sha256sum
          type: "sha256"
        path: /usr/bin/
        owner: root:root
        permission: 0645
        unzip:
          status: true
          files: 
            - bin/containerd
            - bin/containerd-shim
            - bin/containerd-shim-runc-v1
            - bin/containerd-shim-runc-v2
            - bin/containerd-stress
            - bin/ctr

      - name: runc
        src: https://github.com/opencontainers/runc/releases/download/v1.1.3/runc.amd64
        path: /usr/bin/
        owner: root:root
        permission: 0645

    starting:
      - systemctl enable containerd
      - systemctl start containerd

Каждый компонент имеет четыре стадии:

  • downloading (загружает бинарные файлы, проверяет контрольные суммы, распаковывает необходимые компоненты и размещает их в соответствующих папках.)

  • service (генерирует службу systemd, и с помощью параметра extraArgs можно настроить ее поведение под свои нужды.)

  • configuration (генерирует конфигурацию для службы systemd, и с помощью параметра extraArgs можно настроить ее поведение под свои нужды.)

  • starting (выполняет необходимые команды после первых трех этапов.)

Одной из ключевых особенностей этого инструмента является этап загрузки (Downloading), который загружает бинарные файлы компонентов. Это позволяет не зависеть от производителя операционной системы и разворачивать единым подходом на любом хосте, не нужно думать о множестве условий (if else) и о том какая операционная система в основе.

Также предусмотрены отдельные конфигурационные файлы для настройки sysctl и modprobe.

fraimctl.conf
- apiVersion: fraima.io/v1alpha
  kind: Sysctl
  spec:
    configuration:
      extraArgs:
        net.ipv4.ip_forward: 1
    starting:
      - sudo sysctl --system

- apiVersion: fraima.io/v1alpha
  kind: Modprob
  spec:
    configuration:
      extraArgs:
      - br_netfilter
      - overlay
    starting:
      - sudo modprobe overlay
      - sudo modprobe br_netfilter
      - sudo sysctl --system

Инфраструктура

Каждый кубик в Terraform представляет собой ресурс и логически определяется как класс в языке программирования. Мы можем определить класс, например, loadBalancer, который принимает определенный набор аргументов и возвращает структуру, которая также заранее определена. Это означает, что мы можем изменять кубики по нашему усмотрению, а при смене облака все компоненты будут взаимодействовать друг с другом благодаря структуре входных и выходных параметров.

Благодаря этой архитектуре мы можем обновлять операционные системы без проблем и даже менять производителя операционной системы на лету.

kubectl get no -o wide

root@master-2-cluster-2:/home/dkot# kubectl get nodes -o wide
NAME                 STATUS   ROLES                  AGE     VERSION    INTERNAL-IP   EXTERNAL-IP     OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
master-1-cluster-2   Ready    control-plane,master   2m50s   v1.23.12   10.1.0.11     51.250.66.122   Ubuntu 20.04.4 LTS   5.4.0-124-generic   containerd://1.6.8
master-2-cluster-2   Ready    control-plane,master   2m53s   v1.23.12   10.2.0.33     84.201.139.95   Ubuntu 20.04.4 LTS   5.4.0-124-generic   containerd://1.6.8
master-3-cluster-2   Ready    control-plane,master   2m55s   v1.23.12   10.3.0.21     51.250.40.244   Ubuntu 20.04.4 LTS   5.4.0-124-generic   containerd://1.6.8

root@master-2-cluster-2:/home/dkot# kubectl get nodes -o wide
NAME                 STATUS   ROLES                  AGE   VERSION    INTERNAL-IP   EXTERNAL-IP     OS-IMAGE                       KERNEL-VERSION    CONTAINER-RUNTIME
master-1-cluster-2   Ready    control-plane,master   37s   v1.23.12   10.1.0.12     62.84.119.244   Debian GNU/Linux 10 (buster)   4.19.0-18-amd64   containerd://1.6.8
master-2-cluster-2   Ready    control-plane,master   12m   v1.23.12   10.2.0.16     51.250.27.187   Debian GNU/Linux 10 (buster)   4.19.0-18-amd64   containerd://1.6.8
master-3-cluster-2   Ready    control-plane,master   12m   v1.23.12   10.3.0.13     51.250.45.49    Debian GNU/Linux 10 (buster)   4.19.0-18-amd64   containerd://1.6.8

Для каждого облака необходимо написать модуль, который повторяет структуру выше, чтобы у нас всегда была одинаковая архитектура на всех кластерах.

Реализация

Давайте рассмотрим базовый проект и то, как можно начать использовать этот инструмент.

  1. В этом репозитории есть несколько разделов

  2. Заходим в каждый раздел по очереди и применяем, что прописано в Readme.

Подготовка

Для начала работы вам понадобятся переменные для подключения к Vault, YC и Keycloak.

environments
export TF_VAR_YC_CLOUD_ID=""
export TF_VAR_YC_FOLDER_ID=""
export TF_VAR_YC_TOKEN=""
export TF_VAR_YC_ZONE=""
export TF_VAR_VAULT_TOKEN=""
export TF_VAR_VAULT_ADDR=""
export TF_VAR_KEYCLOAK_REALM=""
export TF_VAR_KEYCLOAK_CLIENT_ID=""
export TF_VAR_KEYCLOAK_USER=""
export TF_VAR_KEYCLOAK_PASSWORD=""
export TF_VAR_KEYCLOAK_URL=""
Этот подход позволяет использовать Terraform в контейнере через инструмент CI/CD, не указывая реальные значения переменных в провайдерах.

Если вы работаете с чистым Terraform, не забывайте выделять каждый кластер в отдельный workspace.

terraform workspace new example

terraform plan    -var-file vars/example.tfvars
terraform apply   -var-file vars/example.tfvars
terraform destroy -var-file vars/example.tfvars

Инит конфиг

Основная конфигурация зависит от двух файлов в проекте.

  • locals.defaults.tf - базовые значения, которые определены для всех наших кластеров.

  • vars/${cluster_name}.tf - переменные, которые специально указаны для конкретного кластера.

vars/${cluster_name}.tf
global_vars = {
    cluster_name    = "example"
    pod_cidr        = "10.102.0.0/16"

    serviceaccount_k8s_controllers_name = "yandex-k8s-controllers"

    kube_apiserver_flags = {
        oidc-issuer-url         = "https://auth.dobry-kot.ru/auth/realms/master"
        oidc-client-id          = "kubernetes-clusters"
        oidc-username-claim     = "sub"
        oidc-groups-claim       = "groups"
        oidc-username-prefix    = "-"
    }

    kube_controller_manager_flags = {
        cluster-name = "kubernetes"
    }

    kube_scheduler_flags = {
        
    }

    addons = {
        cilium = {
            enabled = true
            extra_values = {
                cluster = {
                    name = "example"
                    id = 12
                }
            }
        }

        vault-issuer = {
            enabled = true
            extra_values = {}
        }

        coredns = {
            enabled = true
            extra_values = {}
        }

        gatekeeper = {
            enabled = true
            extra_values = {}
        }

        certmanager = {
            enabled = true
            extra_values = {}
        }

        machine-controller-manager = {
            enabled = true
            extra_values = {}
        }

        yandex-cloud-controller = {
            enabled = true
            extra_values = {}
        }

        yandex-csi-controller = {
            enabled = true
            extra_values = {}
        }

        compute-instance = {
            enabled = true
            custom_values = {
                subnet_id   = "e9bndv0b3c5asheadg09"
                zone        = "ru-central1-a"
                image_id    = "fd8ingbofbh3j5h7i8ll"
                replicas    = 1
            }
            extra_values = {
                metadata = {
                    nodeLabels = {
                        "node-role.kubernetes.io/worker" = ""
                        "provider" = "yandex"    
                    }
                    cloudLabels = {
                        tair = "critical"
                    }
                }
            }
        }
    }

}

cloud_metadata = {
    cloud_name  = "cloud-uid-vf465ie7"
    folder_name = "example"
}

master_group = {
    name                = "master"
    count               = 3

    default_subnet      = "10.0.0.0/24"
    default_zone        = "ru-central1-a"

    metadata = {
        # user_data_template = "fraima-hbf"
        user_data_template = "fraima"
    }
}

Этот ENV-параметр дает возможность изменить значения, которые будут использованы в конфигурационных файлах или ресурсах в будущем.

Например, мы можем изменить или добавить флаги Kube-apiserver с помощью переменной "kube_apiserver_flags".

В файле с переменными на данный момент определены три группы.

  1. "master_group" определяет, какие мастера следует заказать, в какой подсети они будут находиться, в какой зоне, будут ли они в разных зонах или нет, а также количество мастер-нод (это значение можно определить только один раз, изменить его с 1 на 3 в настоящее время невозможно).

  2. "global_vars" определяет будущую конфигурацию кластера, включая его имя, подсети для подов, флаги для компонент, которые будут использоваться, а также какие аддоны будут добавлены.

  3. "cloud_metadata" содержатся указатели на облачный провайдер, такие как cloud_name" и "folder_name".

Запускаем

time terraform apply -var-file vars/example.tfvars  -auto-approve

По умолчанию будет развернут кластер с тремя мастер-нодами, каждая из которых имеет 6 CPU, 12 ГБ оперативной памяти и 100 ГБ дискового пространства, а также 10 ГБ для ETCD.

Для каждого кластера будет создан внешний балансер, к которому вы сможете подключиться. Также будут созданы аддоны, которые настроят сеть, базовые интеграции с YC, такие как CSI driver, Cloud Controller и Machine Controller Manager для заказа воркер-нод в облаке.

Через шесть минут вы получите полностью готовый кластер и инструкции о том, как подключиться к нему.

Apply complete! Resources: 86 added, 0 changed, 0 destroyed.

Outputs:

LB-IP = "kubectl config set-cluster  cluster --server=https://158.160.63.64:443 --insecure-skip-tls-verify"

real    6m4,698s
user    0m24,182s
sys     0m1,582s

dk@dobry-kot-system:~/workspace/fraima/kubernetes/k8s-yandex-cluster-naked$ kubectl get nodes -o wide
NAME                STATUS   ROLES                  AGE     VERSION    INTERNAL-IP   EXTERNAL-IP      OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
master-50d858e0-1   Ready    control-plane,master   9m34s   v1.23.12   10.0.0.12     158.160.51.95    Ubuntu 20.04.4 LTS   5.4.0-124-generic   containerd://1.6.6
master-50d858e0-2   Ready    control-plane,master   9m33s   v1.23.12   10.0.0.6      158.160.38.139   Ubuntu 20.04.4 LTS   5.4.0-124-generic   containerd://1.6.6
master-50d858e0-3   Ready    control-plane,master   9m34s   v1.23.12   10.0.0.19     158.160.42.200   Ubuntu 20.04.4 LTS   5.4.0-124-generic   containerd://1.6.6

Вы можете заметить, что кластер успешно запущен и функционирует. Кроме того, у узлов теперь есть внешние IP-адреса и свидетельствует о том, что интеграция с YC работает.

Если вы используете keycloak для подключения, не забудьте установить плагин "kubectl login" и воспользоваться универсальным kubeconfig.

kubeconfig
apiVersion: v1
clusters:
- cluster:
    insecure-skip-tls-verify: true
    server: https://158.160.63.64:443
  name: cluster
contexts:
- context:
    cluster: cluster
    namespace: kube-fraima-machine-controller-manager
    user: cluster
  name: cluster
current-context: cluster
kind: Config
preferences: {}
users:
- name: cluster
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - oidc-login
      - get-token
      - --oidc-issuer-url=https://$KEYCLOAK-SERVER/auth/realms/master
      - --oidc-client-id=kubernetes-clusters
      - --oidc-client-secret=kube-client-secret
      - --certificate-authority=/usr/local/share/ca-certificates/oidc-ca.pem
      - --skip-open-browser
      - --grant-type=password
      - --username=$USERNAME
      - --password=$PASSWORD
      command: kubectl
      env:
      - name: context
        value: $(kubectl config current-context)
      interactiveMode: IfAvailable
      provideClusterInfo: false

Наполнение

NAME                                     STATUS   AGE
default                                  Active   11m
kube-fraima-certmanager                  Active   8m48s # CERTMANAGER
kube-fraima-dns                          Active   9m57s # COREDNS
kube-fraima-machine-controller-manager   Active   8m55s
kube-fraima-opa                          Active   9m44s # GATEKEEPER
kube-fraima-sdn                          Active   10m   # CILIUM
kube-fraima-yandex-cloud-controller      Active   11m
kube-fraima-yandex-csi-controller        Active   9m54s
kube-node-lease                          Active   11m
kube-public                              Active   11m
kube-system                              Active   11m

Внимание

Одной из важных особенностей этих кластеров является отсутствие приватных ключей от СА на мастерах, так как они хранятся в VAULT. Однако, такой подход приводит к определенным проблемам.

Вы можете добавить любую ноду в кластер через csr bootstraping, где нода генерирует запрос на сертификат и отправляет его в API, а затем вы подтверждаете этот запрос и нода получает свои сертификаты и добавляется в кластер. Однако, в данной инсталляции это нельзя сделать стандартными средствами.

dk@dobry-kot-system:~/Downloads$ kubectl get csr
NAME                                                   AGE     SIGNERNAME                                    REQUESTOR                       REQUESTEDDURATION   CONDITION
csr-52cx7                                              12m     kubernetes.io/kubelet-serving                 system:node:master-50d858e0-3   <none>              Pending
csr-lbhqf                                              12m     kubernetes.io/kubelet-serving                 system:node:master-50d858e0-1   <none>              Pending
csr-n27p4                                              12m     kubernetes.io/kubelet-serving                 system:node:master-50d858e0-2   <none>              Pending
node-csr-3l5VT-i7YinQWaTvbCY467d27GQLnSqnT_BYgk_PFII   8m17s   clusterissuers.cert-manager.io/vault-issuer   system:bootstrap:663273         <none>              Pending

запроса Certmanager выдаст сертификат, который будет храниться во внешнем хранилище Vault.

kubectl certificate approve node-csr-3l5VT-i7YinQWaTvbCY467d27GQLnSqnT_BYgk_PFII

После этого появится еще один запрос на сертификат, который также нужно подтвердить, и после этого узел будет добавлен в кластер.

dk@dobry-kot-system:~/Downloads$ kubectl get no -o wide
NAME                                         STATUS   ROLES                  AGE   VERSION    INTERNAL-IP   EXTERNAL-IP      OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
master-50d858e0-1                            Ready    control-plane,master   24m   v1.23.12   10.0.0.12     158.160.51.95    Ubuntu 20.04.4 LTS   5.4.0-124-generic   containerd://1.6.6
master-50d858e0-2                            Ready    control-plane,master   24m   v1.23.12   10.0.0.6      158.160.38.139   Ubuntu 20.04.4 LTS   5.4.0-124-generic   containerd://1.6.6
master-50d858e0-3                            Ready    control-plane,master   24m   v1.23.12   10.0.0.19     158.160.42.200   Ubuntu 20.04.4 LTS   5.4.0-124-generic   containerd://1.6.6
worker-yandex-compute-instance-68ffc-f2sd2   Ready    worker                 11m   v1.23.12   10.154.0.11   51.250.72.216    Ubuntu 22.04.1 LTS   5.15.0-46-generic   containerd://1.6.6

Планы

  1. Расширить функционал Fraimctl, чтобы отказаться от использования Kubeadm.

  2. Написать инфраструктурные модули для AWS и VK-Cloud.

  3. Покрыть Terraform тестами.

  4. Организовать модули более четко и удалить ненужное.

  5. Перейти с использования Terraform + Helm на Terraform + Flux.

  6. Написать расширение для K8S API для добавления нашего кастомного функционала.

  7. Добавить инструмент для настройки узлов как Day2 операций.

У нашего коллектива амбициозные планы и мы нацелены на получение статуса CNCF.

Если вы оценили наш контент, присоединяйтесь к нашему чату, где вы сможете задать любые интересующие вас вопросы. Мы также будем рады любой помощи в нашем проекте.

Контакты

Базовая организации сертификатов в kubeadm — .

Как начать использовать внешний PKI сторедж Vault для хранения и выписывания сертификатов для k8s control‑plane — .

Как развернуть Kubernetes кластер по принципу Hard Way — .

Наиболее значимым и сложным этапом было разработать подход работы с сертификатами, проблема была упомянута в предыдущих статьях. Мы определили основные спецификации для сертификатов и описали ресурсы Vault, которые создаются на основе содержимого . Однако возник вопрос доставки ключей/токенов на мастер-узлы, чтобы клиент на узле мог запросить сертификаты, указанные в спецификации. Было рассмотрено несколько вариантов решения этой проблемы:

****При написании кода мы поняли, что описывать каждый модуль с его входными и выходными переменными - это трудоемкий процесс, особенно когда возникают повторы. Через некоторое время мы решили, что имеет смысл выделить отдельный модуль, содержащий переменные, которые используются в нескольких модулях. Таким образом, мы смогли уменьшить объем входных аргументов каждого модуля и привести их к более компактному формату:

базовый fraimctl (устанавливает все компоненты и готовит конфиги к ним);

базовый kubeadm (генерит статик под манифесты и чекает, что кластер поднят);

базовый key-keeper (клиент который запрашивает сертификаты).

Скачиваем репозиторий

(создает рут PKI в Vault)

(создает базовую конфигурацию в YC, которая включает в себя создание VPC, таблицы маршрутизации и создание сервисных аккаунтов по умолчанию)

(устанавливает базовую конфигурацию для Keycloak, которая позволяет авторизоваться в кластере через этот инструмент)

(проект-шаблон, который используется для создания кластера.)

Поскольку kube-controller-manager занимается выдачей сертификатов для узлов, то без доступа к приватному ключу CA этот функционал теряется. Однако, мы нашли способ получить сертификаты, установив Certmanager и Gatekeeper, а затем настроив ClusterIssuer в Certmanager для интеграции с VAULT. С помощью этого ClusterIssuer можно будет выписывать сертификаты только для worker/master узлов. Затем в Gatekeeper настраиваем мутацию ресурса CSR, который изменит базовый SIGNERNAME с "" на "". Таким образом, мы сможем получить необходимые сертификаты.

Как вы можете заметить, новый узел запросил сертификат через CSR, но SIGNERNAME у него установлен как "". После подтверждения этого

terraform modules:

terraform cluster:

telegram community: telegram me:

Сертификаты K8S или как распутать вермишель Часть 1
Сертификаты K8S или как распутать вермишель Часть 2
Kubernetes the hard way
Сертификаты
спецификации
Переменные окружения
каталог
Cloud init
конфиг
конфиг
конфиг
Fraimctl
https://github.com/fraima/kubernetes
infrastructure-vault
infrastructure-yandex
infrastructure-keycloak
k8s-yandex-cluster
kubernetes.io/kubelet-serving
clusterissuers.cert-manager.io/vault-issuer
clusterissuers.cert-manager.io/vault-issuer
https://github.com/fraima/terraform-modules
https://github.com/fraima/kubernetes
https://t.me/fraima_ru
https://t.me/Dobry_kot
https://habr.com/ru/articles/727820/
Telegram
FR-Solutions
@irbgeo
Telegram