====0002 Знакомство с Kubernetes- основные понятия и архитектура==== __С именами всё в порядке__.
**k8s**
Название идёт от слова Kubernetes где между буквой K и s ровно 8 символов. Разработчик Google выпуск первой версии в 2014 г. до этого разробатывался как Borg.
**k3s**
Название идёт по аналогии формата имени k8s. k3s является разработкой [[https://www.rancher.com/|Ranger Labs]] и представляет из себя лёгкую версию k8s выпушен в 2019 г.
Хорошая статья от [[https://traefik.io/glossary/k3s-explained/|traefik]] сравнения k3s с k8s на английском.
Статья от [[https://habr.com/ru/companies/nixys/articles/658985/| habr.ru]] "k3s младший брат k8s".

**k9s**
В Америке "K-9" называют служебных собак полиции, по аналогии для помощи k8s придумали утилиту k9s которая в консольном режиме помогает быстро работать с кластером Kubernetes.[[https://k9scli.io/| Who Let The Pods Out?]]
---- __Архитектура.__ * Контрольный Узел (Control plane)
* Рабочий Узел (Worker node)
* Хранилище ETCD * Kubectl (CLI) В мире Kubernetes __ **никто никому приказов не отдаёт** __, каждый элемент отвечает за свою часть инфраструктуры и всё что он делает это приводит свою часть вида в форму которая описана в хранилище ETCD.
**Kubernetes-кластер** состоит из одной или более Master node и из одной или более Worker node. Сервисы работающие на Worker node называются Kubernetes control plane при этом Master node используется только для административных задач а Worker node для запуска реальных контейнеров.
**Минимальный набор компонентов кластера:** * **Control plane**: *apiserver *controller-manager *kube-scheduler *etcd * **Worker nodes**: * kubelet * kube-proxy ==== Разборка компонентов: ==== === Etcd === * Распределённая и высоконадёжная БД * Хранит состояния всего кластера Это [[https://aws.amazon.com/ru/nosql/key-value/|Key-Value]] база данных в которых хоронятся вся информация о кластере и его объектах. Это очень важная база данных в которой содержится состояния всего кластера. Если мы теряем etcd и резервной копии нет, то по сути и кластер мы тоже теряем. Почему использовать именно etcd? потому что она создана в основе быть распределённой и отказоустойчивой а значит очень надёжной БД. Как правило в __production используется как минимум три экземпляра etcd__. Не смотря что это БД не стоит менять в ней что-то в ручную, так как ничего нигде не будет логгироватся и компоненты в кластере начнут "глючить". API-Server это единственный компонент который пишет на прямую в etcd. ---- === Kube-apiserver === == или просто Kubernetes API-сервер == * Точка входа для всех запросов в кластер * Обрабатывает все запросы и обновляет информацию в etcd * Выполняет аутентификацию и авторизацию клиентов API-сервер это по сути шлюз в наш кластер, он на прямую пишет в etcd-Хранилище, и все компоненты кластера не зависимо чем они занимаются общаются только через API-сервер прося его что-то поменять в etcd. API-сервер представляет из себя **REST** и [[https://grpc.io/| gRPC]] Сервер. Все утилиты для управления и мониторинга Кластера также работают через API-сервер. Также утилита **kubectl**, при желание к API-сервер можно обратится через **curl**. curl http://localhost:8080/api/v1/namespace/default/pods ---- === Kube-controller-manager === == отвечает за поддержание состояния кластера == * Сервис который включает в себя множество других сервисов, таких как: * node controller - обнаружение и контролирование нод * replication controller - поддерживает нужное количество контейнеров приложения * endpoints controller - обслуживает объекты Endpoints * account controller - * token controller - создаёт токены для API * Проверяет состояние кластера через API-сервер и выполняет необходимые изменения Kube-controller-manager приводит текущие состояния кластера к желаемому. Например мы через утилиту kubectl сказали API что хотим запустили три новых контейнера. API нам отрапортовала что "ОК" всё сделано, но реально ничего никаких контейнеров нет и кластер только в этот момент начинает переводить себя к новому состоянию. То-есть в данный момент компонент **controller-manager** посмотрит в etcd через API и увидеть что нам нужно запустить три новых контейнера, а объекты этих контейнеров еще не созданы и он создаёт на манифестах новых контейнеров и сложит их в etcd тоже через API. Данный контролер создаёт точки доступа для контейнеров в кластере с помощью которой создаётся сетевая связность приватной сети kubernetes. Не смотря что это группа из нескольких service но физически они находятся в одном бинарнике controller-manager. ---- === Kube-scheduler === * Получает список всех рабочих нод в кластера * Скоринг (оценивает ноды по множеству параметров) * Выбирает лучшую и записывает это в API Это компонент который определяет расположения контейнеров на нодах. По сути он отслеживает контейнеры у которых еще не назначен хост для запуска и выбирает ноду на которой они должны работать. Зачем это нужно ? в реальном сценарии у нас есть несколько рабочих нод на котором мы можем запускать наши контейнеры, причём контейнеры у нас все разные с ихними требованиями, например у некоторых контейнеров есть ограничение по нодам допустим контейнер надо запустить в определёной группе серверов например по географической локации, или же обиспечить требования контейнера запустится только на ноде где есть SSD-Диски или есть требования контейнера к памяти которая было создана при создание/декларации контейнера. Всем этим и занимается Kube-scheduler. По алгоритмам он создаст список нод с скорингом, и после выбора ноды для определённых контейнеров через API сохраняется значение node-name в etcd для определённого контейнера. ---- === Среда выполнения контейнера (на рабочей ноде, на Worker node)=== * Docker (наиболее распрострянёный [[https://www.docker.com/| docker.com]]) * Containerd ([[https://www.cncf.io/projects/containerd/|CNF.io]]) * CRI-O (RedHat использует её в OpenShift [[https://cri-o.io/|cri-o.io]]) ---- === Kubelet=== == Управляет жизненным циклом локально работающего контейнера == * Общается с Docker (или другой системой контейнеризации) через API для управления контейнерами * Передаёт информацию о статусе обратно с API-сервер * Мониторинг состояние контейнеров Kubelet это основной компонент Kubernetes на каждой рабочей ноде кластера, проверяет API-сервер на предмет появления новых контейнеров которые долыжны быть развёрнуты на данной ноде. Зачем он вообще нужен? Дело в том что контейнеров runtime не знает ничего о Kubernetes или kube-API или хранилище etcd, поэтому нам нужна какая-то прослойка между нашими управляющими компонентами и средой выполнения контейнеров которая бы этой средой и управляла. Kubelet при нужде запускает, удаляет контейнеры на данной ноде, и передаёт статус о контейнере обратно в API-сервер, который вносит поправление в etcd, также он постоянно мониторит статус контейнера и репортует статус ноды в API-сервер. ---- === Kube-proxy=== == Отвечает за перенаправление запросов к соответствующим сервисам в приватной сети кластера == * Конфигурирует правила сети на узлах * Обычно использует iptables на worker-ноде Kube-proxy это сервис который отвечает за сетевое взаимодействие между контейнерами. Он конфигуриет правила iptables (в новой версии это [[https://kubernetes.io/blog/2018/07/09/ipvs-based-in-cluster-load-balancing-deep-dive/| IPVS]]) при помощи которых работают сетевые подключения к вашем подам с внутри и снаружи кластера. ---- === Pod === Pod это основная логическая еденица Kubernetes. Физически он предстовляет из себя группу контейнеров запускаемых как единое целое. == Статусы запуска pod == * **Pending** - объект был создан, и возможно для него уже назначен хост для запуска, но сам контейнер еще не был запущен. * **Running** - все контейнеры Poda запущены и работают. * **Succeeded** - все контейнеры завершили работу * **Failed** - все контейнеры остановлены, как минимум один контейнер не корректно завершил работу * **Unknown** - kube-apiserver не в курсе, что происходит с подом, обычно бывает когда **kublet** долга не репoртует статус пода. ---- ==== Взаимодействие компонентов при создание нового объекта Kubernetes ==== - **Пользователь** отправляет запрос "создать новый под" с помощью утилиты **kubctl** на **API Server** - **API Server** логирует его и передаёт его в **etcd** - **etcd** сообщает обратно в **API Server** что запрос принят и сохранён - **API Server** обращается к **kube-scheduler** - **kube-scheduler** определяет Worker-node на которой будет создан pod и отправляет результат обратно в **API Server** - **API Server** отправлявт эти сведенья в **etcd** - **etcd** сообщает обратно **API Server** что запрос принят и сохранён - **API Server** обращается к **kubelet** на соответствующей Worker-node - **kubelet** обращается к **docker-daemon** (или другой Container-Runtime) через его API, задача на этой node запустить контейнер или несколько если их в поде их много - **kubelet** отпровляет статус pod обратно на **API Server** - **API Server** обновляет статус в **etcd** === Варианты установки кластера Kubernetes === == Для лутшего понимания: == * Kubernetes the hard way. Он вас научит поднимать кубернетс с нуля, и всё настраивать руками.[[https://github.com/kelseyhightower/kubernetes-the-hard-way |ссылка]] == Продакшн реди решения: == * **kubeadm** Утилита для развёртываня кластера, много чего придётся делать руками, подходит для продакшн. в Сертификации CKA тоже могут попастся вопросы про kubeadm. [[https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/|ссылка]] * **kubespray** сценарий на Ansible, который поставит Kubernetes и всё сделает за вас, едиственное что вам нужно это прописать инвентарь, тоесть на каких серверах ставить какие IP использовать, что нужно дополнительного добавить. А на выходе получаем рабочий кластер, автоматизирует много действий которые мы бы делали с kubeadm. [[https://github.com/kubernetes-sigs/kubespray|ссылка]] * **kops** прадкшен готовае решиние, оно в большенстве отточено запускать кубернетес в облaках. == Облака == * **EKS** [[ https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html| Amazon Elastic Kubernetes Service (Amazon EKS)]] * **GKE** [[https://cloud.google.com/kubernetes-engine?hl=en| Google Kubernetes Engine]] * **AKS** [[https://azure.microsoft.com/en-us/products/kubernetes-service | Azure Kubernetes Service]] * **DigitalOcean** [[https://www.digitalocean.com/products/kubernetes | DigitalOcean.com]] ---- == Для тестирования/разработки == * **Kind** поможет зарвернуть кластер кубернетес на локальном компьютере, поддержывает мулти-ноде, мастер-ноде [[https://kind.sigs.k8s.io/|ссылка]] * **Minikube** это один из самых распространённых способов локально развернуть кубернетес , минус что развернуть можно только одну ноду [[https://minikube.sigs.k8s.io/docs/start/| ссылка]] * **Microk8s** пакет в репозиториях ubuntu итд. который устанавливает локально сервисы кубернетес как systemd service. Минусы тоже только одна нода, и нужен менеджер пакетов snap. * **Docker destop** для Windows и MacOS ---- === Подготовка рабочей среды на базе minikube === На Ubuntu Server "22.04.4 LTS (Jammy Jellyfish)" устанавливаем docker deamon по инструкции с [[https://docs.docker.com/engine/install/ubuntu/| docs.docker.com]] == удаляем уже инсталлированные пакеты == for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done == побавляем новый репозиторий == # Add Docker's official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc # Add the repository to Apt sources: echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update == Устанавливаем docker == sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin == Автостарт и запуск docker-deamon == systemctl enable docker systemctl start docker == добавляем своего пользователя в группу "docker" == sudo usermod -aG docker sergej # sergej это мой пользователь, выяснить можно с whoami == проверяем == sergej@minikube:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS == устанавливаем minikube == Обратите внимание на минимальные требования 2CPU,4GB RAM,20GB HDD в [[https://minikube.sigs.k8s.io/docs/start/|официальной документации minikube]] curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 sudo install minikube-linux-amd64 /usr/local/bin/minikube && rm minikube-linux-amd64 ---- == проверяем / запускаем == # ... команда нужна для запуска кластера, может занять некоторое время sergej@minikube:~$ minikube start # ... проверяем status sergej@minikube:~$ minikube status minikube type: Control Plane host: Running kubelet: Running apiserver: Running kubeconfig: Configured == делаем алиас == Так как работа с kubernetes идёт через **kubectl**, и так как у нас minikube нам постоянно надо обрашатся к кубернетес через **minikube kubectl ...** можно создать на эту длинную команду алиас. в **"~/.bashrc"** у пользователя и добавить в самый низ строку alias kubectl="minikube kubectl --" == проверяем == # загружем новый алиас в окружающею среду sergej@minikube:~$ source ~/.bashrc # проверяем алиас sergej@minikube:~$ kubectl version # выдаст чтото на подобие kubectl version Client Version: v1.30.0 Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3 Server Version: v1.30.0 == смотрим на компоненты миникуба == sergej@minikube:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 57faf071dcd9 gcr.io/k8s-minikube/kicbase:v0.0.44 "/usr/local/bin/entr…" 3 hours ago Up 3 hours 127.0.0.1:32768->22/tcp, 127.0.0.1:32769->2376/tcp, 127.0.0.1:32770->5000/tcp, 127.0.0.1:32771->8443/tcp, 127.0.0.1:32772->32443/tcp minikube видно что присутствует один контейнер с ID "57faf071dcd9" давайте посмотрим что там в нутри. sergej@minikube:~$ docker exec -i -t 57faf071dcd9 /bin/bash root@minikube:/# # здесь можно посмотреть все контейнеры с помощью "docker ps" # выходим root@minikube:/# exit Но не обизательно делать этот долгий путь для проникновения в рабочею среду minikube! можно также туда попасть набрав : sergej@minikube:~$ minikube ssh # выходим root@minikube:/# exit == проверяем конфигурацию кластера == # дириктория ".kube" будет создана после установки minikube афтоматически cd ~/.kube/ # смотрим конфигурацию cat config или та же самая актуальная конфигурация: kubectl config view проверяем информаьию про кластер sergej@minikube:~$ kubectl cluster-info Kubernetes control plane is running at https://192.168.49.2:8443 CoreDNS is running at https://192.168.49.2:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. показываем все ноды (no сокращённо node) sergej@minikube:~$ kubectl get no # output NAME STATUS ROLES AGE VERSION minikube Ready control-plane 174m v1.30.0 показываем все поды (po сокращённо pods) sergej@minikube:~$ kubectl get po # output === Первое приложение в kubernetes с помошью minikube ===