Содержание
0002 Знакомство с Kubernetes- основные понятия и архитектура
С именами всё в порядке.
k8s Название идёт от слова Kubernetes где между буквой K и s ровно 8 символов. Разработчик Google выпуск первой версии в 2014 г. до этого разробатывался как Borg.
k3s Название идёт по аналогии формата имени k8s. k3s является разработкой Ranger Labs и представляет из себя лёгкую версию k8s выпушен в 2019 г.
Хорошая статья от traefik сравнения k3s с k8s на английском. Статья от habr.ru «k3s младший брат k8s». k9s В Америке «K-9» называют служебных собак полиции, по аналогии для помощи k8s придумали утилиту k9s которая в консольном режиме помогает быстро работать с кластером Kubernetes. 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
- Распределённая и высоконадёжная БД
- Хранит состояния всего кластера
Это Key-Value база данных в которых хоронятся вся информация о кластере и его объектах. Это очень важная база данных в которой содержится состояния всего кластера. Если мы теряем etcd и резервной копии нет, то по сути и кластер мы тоже теряем. Почему использовать именно etcd? потому что она создана в основе быть распределённой и отказоустойчивой а значит очень надёжной БД. Как правило в production используется как минимум три экземпляра etcd. Не смотря что это БД не стоит менять в ней что-то в ручную, так как ничего нигде не будет логгироватся и компоненты в кластере начнут «глючить». API-Server это единственный компонент который пишет на прямую в etcd.
Kube-apiserver
или просто Kubernetes API-сервер
- Точка входа для всех запросов в кластер
- Обрабатывает все запросы и обновляет информацию в etcd
- Выполняет аутентификацию и авторизацию клиентов
API-сервер это по сути шлюз в наш кластер, он на прямую пишет в etcd-Хранилище, и все компоненты кластера не зависимо чем они занимаются общаются только через API-сервер прося его что-то поменять в etcd. API-сервер представляет из себя REST и 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 (наиболее распрострянёный docker.com)
- Containerd (CNF.io)
- CRI-O (RedHat использует её в OpenShift 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 (в новой версии это 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. Он вас научит поднимать кубернетс с нуля, и всё настраивать руками.ссылка
Продакшн реди решения:
- kubeadm Утилита для развёртываня кластера, много чего придётся делать руками, подходит для продакшн. в Сертификации CKA тоже могут попастся вопросы про kubeadm. ссылка
- kubespray сценарий на Ansible, который поставит Kubernetes и всё сделает за вас, едиственное что вам нужно это прописать инвентарь, тоесть на каких серверах ставить какие IP использовать, что нужно дополнительного добавить. А на выходе получаем рабочий кластер, автоматизирует много действий которые мы бы делали с kubeadm. ссылка
- kops прадкшен готовае решиние, оно в большенстве отточено запускать кубернетес в облaках.
Облака
- DigitalOcean DigitalOcean.com
Для тестирования/разработки
- Kind поможет зарвернуть кластер кубернетес на локальном компьютере, поддержывает мулти-ноде, мастер-ноде ссылка
- Minikube это один из самых распространённых способов локально развернуть кубернетес , минус что развернуть можно только одну ноду ссылка
- Microk8s пакет в репозиториях ubuntu итд. который устанавливает локально сервисы кубернетес как systemd service. Минусы тоже только одна нода, и нужен менеджер пакетов snap.
- Docker destop для Windows и MacOS
Подготовка рабочей среды на базе minikube
На Ubuntu Server «22.04.4 LTS (Jammy Jellyfish)» устанавливаем docker deamon по инструкции с 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 в официальной документации 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