Содержание

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?


Архитектура.

В мире Kubernetes никто никому приказов не отдаёт , каждый элемент отвечает за свою часть инфраструктуры и всё что он делает это приводит свою часть вида в форму которая описана в хранилище ETCD.

Kubernetes-кластер состоит из одной или более Master node и из одной или более Worker node. Сервисы работающие на Worker node называются Kubernetes control plane при этом Master node используется только для административных задач а Worker node для запуска реальных контейнеров.

Минимальный набор компонентов кластера:

Разборка компонентов:

Etcd

Это Key-Value база данных в которых хоронятся вся информация о кластере и его объектах. Это очень важная база данных в которой содержится состояния всего кластера. Если мы теряем etcd и резервной копии нет, то по сути и кластер мы тоже теряем. Почему использовать именно etcd? потому что она создана в основе быть распределённой и отказоустойчивой а значит очень надёжной БД. Как правило в production используется как минимум три экземпляра etcd. Не смотря что это БД не стоит менять в ней что-то в ручную, так как ничего нигде не будет логгироватся и компоненты в кластере начнут «глючить». API-Server это единственный компонент который пишет на прямую в etcd.


Kube-apiserver

или просто Kubernetes API-сервер

API-сервер это по сути шлюз в наш кластер, он на прямую пишет в etcd-Хранилище, и все компоненты кластера не зависимо чем они занимаются общаются только через API-сервер прося его что-то поменять в etcd. API-сервер представляет из себя REST и gRPC Сервер. Все утилиты для управления и мониторинга Кластера также работают через API-сервер. Также утилита kubectl, при желание к API-сервер можно обратится через curl.

 curl http://localhost:8080/api/v1/namespace/default/pods   

Kube-controller-manager

отвечает за поддержание состояния кластера

Kube-controller-manager приводит текущие состояния кластера к желаемому. Например мы через утилиту kubectl сказали API что хотим запустили три новых контейнера. API нам отрапортовала что «ОК» всё сделано, но реально ничего никаких контейнеров нет и кластер только в этот момент начинает переводить себя к новому состоянию. То-есть в данный момент компонент controller-manager посмотрит в etcd через API и увидеть что нам нужно запустить три новых контейнера, а объекты этих контейнеров еще не созданы и он создаёт на манифестах новых контейнеров и сложит их в etcd тоже через API. Данный контролер создаёт точки доступа для контейнеров в кластере с помощью которой создаётся сетевая связность приватной сети kubernetes. Не смотря что это группа из нескольких service но физически они находятся в одном бинарнике controller-manager.


Kube-scheduler

Это компонент который определяет расположения контейнеров на нодах. По сути он отслеживает контейнеры у которых еще не назначен хост для запуска и выбирает ноду на которой они должны работать. Зачем это нужно ? в реальном сценарии у нас есть несколько рабочих нод на котором мы можем запускать наши контейнеры, причём контейнеры у нас все разные с ихними требованиями, например у некоторых контейнеров есть ограничение по нодам допустим контейнер надо запустить в определёной группе серверов например по географической локации, или же обиспечить требования контейнера запустится только на ноде где есть SSD-Диски или есть требования контейнера к памяти которая было создана при создание/декларации контейнера. Всем этим и занимается Kube-scheduler. По алгоритмам он создаст список нод с скорингом, и после выбора ноды для определённых контейнеров через API сохраняется значение node-name в etcd для определённого контейнера.


Среда выполнения контейнера (на рабочей ноде, на Worker node)


Kubelet

Управляет жизненным циклом локально работающего контейнера

Kubelet это основной компонент Kubernetes на каждой рабочей ноде кластера, проверяет API-сервер на предмет появления новых контейнеров которые долыжны быть развёрнуты на данной ноде. Зачем он вообще нужен? Дело в том что контейнеров runtime не знает ничего о Kubernetes или kube-API или хранилище etcd, поэтому нам нужна какая-то прослойка между нашими управляющими компонентами и средой выполнения контейнеров которая бы этой средой и управляла. Kubelet при нужде запускает, удаляет контейнеры на данной ноде, и передаёт статус о контейнере обратно в API-сервер, который вносит поправление в etcd, также он постоянно мониторит статус контейнера и репортует статус ноды в API-сервер.


Kube-proxy

Отвечает за перенаправление запросов к соответствующим сервисам в приватной сети кластера

Kube-proxy это сервис который отвечает за сетевое взаимодействие между контейнерами. Он конфигуриет правила iptables (в новой версии это IPVS) при помощи которых работают сетевые подключения к вашем подам с внутри и снаружи кластера.


Pod

Pod это основная логическая еденица Kubernetes. Физически он предстовляет из себя группу контейнеров запускаемых как единое целое.

Статусы запуска pod

Взаимодействие компонентов при создание нового объекта Kubernetes

  1. Пользователь отправляет запрос «создать новый под» с помощью утилиты kubctl на API Server
  2. API Server логирует его и передаёт его в etcd
  3. etcd сообщает обратно в API Server что запрос принят и сохранён
  4. API Server обращается к kube-scheduler
  5. kube-scheduler определяет Worker-node на которой будет создан pod и отправляет результат обратно в API Server
  6. API Server отправлявт эти сведенья в etcd
  7. etcd сообщает обратно API Server что запрос принят и сохранён
  8. API Server обращается к kubelet на соответствующей Worker-node
  9. kubelet обращается к docker-daemon (или другой Container-Runtime) через его API, задача на этой node запустить контейнер или несколько если их в поде их много
  10. kubelet отпровляет статус pod обратно на API Server
  11. API Server обновляет статус в etcd

Варианты установки кластера Kubernetes

Для лутшего понимания:
Продакшн реди решения:
Облака

Для тестирования/разработки

Подготовка рабочей среды на базе 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      

Первое приложение в kubernetes с помошью minikube