Занятие №1
Pod - минимально запущенное абстракция в кластере кубернетеса
Внутри пода запускается как минимум два контейнера. основной контейнер под, который несет в себе базовую настройку(network namspaces). С контейнерами напрямую кубер не работает. Для запуска двух реплик приложения, нужно создать два пода.

Контейнеры внутри одного пода:
- Если их нужно запускать на одном физ.хосте
- Если масштабир. линейно
- Если компоненты имеют сильную связь
Базовые команды для работы с подами:
kubectl describe pod # Полное описание пода
kubectl delete pod --all # Полное удаление подов, вместо --all можно указать конкретный под
kubectl get pod # Получение списка имеющихся подов
kubectl apply -f ~/school-dev-k8s/practice/2.application-abstractions/1.pod/pod.yaml # Создание или обновление пода
kubectl run # Для создания развертываний + (-f *.yml) Для каждой программы за которой нужно следить, Кубернетес создает соответствующий объект Deployment, записывающий некоторую связанную с ней информацию: имя образа контейнера, количество реплик и любые другие параметры для запуска контейнера.
На самом деле deployment не управляет репликами напрямую, оно автоматически создает сопутствующий объект под названием ReplicaSet
Для просмотра имеющихся развертываний:
kubectl get deploymentsРазвертывания не управляют Под оболочками напрямую, это обязанность ReplicaSet
Занятие №2
ReplicaSet - является следующей абстракцией над Pod-ами и необходим для поддержания их количества, установленного в файле конфигурации
kubectl get rsОбновление образа
-
Можно заменить название образа в ямле и после чего выполнить команду apply
-
Ввод команды
k set image replicaset my-replicaset nginx=[quay.io/testing-farm/nginx:1.13](http://quay.io/testing-farm/nginx:1.13)
# Можно использовать регулярки для получение образов
k set image replicaset my-replicaset '*=[quay.io/testing-farm/nginx:1.13](http://quay.io/testing-farm/nginx:1.13)'# Команда для получения описания к деплойменту
k explain deployment.spec
k explain deployment.spec.strategyStrategy - The deployment strategy to use to replace existing pods with new ones.
strategy:
- RollingUpdate - плавный перезапуск под of pods
maxSurge 1 - (The maximum number of pods that can be scheduled above the desired number)
maxUnavailable 0
Значения maxSurge и maxUnavailable могут быть выражены в числах или процентах
- Recreate - полностью сносим поды с наличием даунтайма
Ресурсы:
Limits:
Количество ресурсов которые под может использовать, верхняя граница, выше этих лимитов просто не получится
Омкиллер(out of memory killer, в ядре линукс) убивает образы которые съедают больше памяти, чем под них выделили. После чего replicaset поднимет инстанс приложения заново.
Requests:
количество ресурсов, которые резервируются для Пода на ноте
не делятся с другими Подами на ноде
Check this:
k rollout history deployment my-deployment
k rollout undo deployment my-deploymentЗанятие №3
Для хранение переменных используется специальный ресурс ConfigMap (не для конфиденциальных данных)
k apply -f configmap.yml # создается как и любой другой ресурс
k get po cm # получение списка конфигмапов
k get po cm my-configmap-env -o json # в конкретно заданном форматеДля того, чтобы зайти в под и посмотреть его переменные (аналогично докеру, только для входа в контейнер добавляется — bash, —env):
k exec -it my-deployment-7d7cff784b-9rvkl -- envSECRETS:
- generic - пароли/токены приложений
- docker-registry - Данные авторизации в docker-registry
- tls - TLS сертификаты для Ingress
- Создаем секрет Для этого выполним команду:
kubectl create secret generic test --from-literal=test1=asdf --from-literal=dbpassword=1q2w3e
kubectl get secret
kubectl get secret test -o yaml
В Кубернетес есть специальная утилита для ограничения прав доступа к определенным сервисам. Например, разработчикам можно выдать стандартную роль Edit и они смогут смотреть ConfigMap-ы, администраторы же смогут иметь доступ к секретам.
Для того, чтобы пробросить порты энжинкса наружу, можно использовать следующую команду:
k port-forward my-deployment-5dbbd56b95-r4nbm 8873:80 &Пример использования: разрабатывая какой то сервис локально, нам может понадобиться тестирование интеграции с каким либо сервисом, пробросив порт сервиса на нашу локальную машину, можно будет с ним взаимодействовать
Для изменений конфигмапа:
kubectl edit configmap my-configmapВнутри контейнера с подом можно посмотреть доп.информацию о поде в виде аннотаций и лейблов по пути /etc/podinfo
Занятие №4
Работа с кубернетес подразумевает оперирование stateless приложениями, состояние которых не изменится при падении реплики
Все необходимые данные нужно хранить в хранилищах данных и не допускать наличия state
- Один из возможных способов маунта данных реализован с помощью директивы hostPath
volumeMounts:
- name: data
mountPath: /files
volumes:
- name: data
hostPath:
path: /data_podЕго использование крайне не рекомендуется в связи с его не безопасностью, используется только некоторыми внутренними сервисами, возможность его использования лучше блокировать при помощи политик безопасности
- Emptydir - создает временный диск и этот временный диск прокидывается в содержимое контейнера, после ребута пода все данные с него удаляются
volumeMounts:
- name: data
mountPath: /files
volumes:
- name: data
emptyDir: {}- PersistantVolumeClaim - постоянный вольюм указанной в спеке директории, какого-либо стороннего ресурса(например s3), для определения его характеристик описывается отдельным манифест.
volumes:
- name: data
persistentVolumeClaim:
claimName: fileshareДля того, чтобы разрешить нескольким ресурсам иметь доступ к pvc, нужно указать следующие данные в спеке: accessModes: - ReadWriteMany (ReadWriteMany), но есть одно “но”, если указанный в storageClassName диск не поддерживает множественное чтение-запись, то доступ к нему получит первый “урвавший” его под.
Provisioner - может ходить в облако и нарезать имеющиеся ресурсы на диски и соотвественно получать айди этих дисков, создавать манифесты PV в кубернетесе
Provisioner создает диски именно того размера, который указан в PVC

Provisioner можно использовать встроенный и предоставляемый сторонними ресурсами, например от openstack
k edit pvc fileshare # Команда для внесения правок в конфиг персистант вольюма
k get pwc # команда для получения информации о имеющихся персистанс вольюмахinitcontainers - позволяет выполнить настройки перед запуском основного приложения
- выполняются по порядку определения в манифесте
- можно монтировать те же тома, что и в основных контейнерах
- можно запускать от другого пользователя
- должен выполнить действие и остановиться
Занятие №5
Probes
Нужны для проверки работоспособности приложения в поде
Делятся на:
-
Liveness Probe
-
Контроль за состоянием приложения во время его жизни
-
Исполняется постоянно
-
-
Readiness Probe
-
Проверяет, готово ли приложение принимать трафик
-
В случае неудачного выполнения приложение убирается из балансировки
-
-
Startup Probe
-
Проверяет, запустилось ли приложение
-
Исполняется при старте
-
readinessProbe:
failureThreshold: 3 # Допустимое количество провальных попыток, дойдя до которых, кубер не будет убирать под из балансировки
httpGet: # Помимо проверки на httpGet, может быть использована команда exec, будет вызвана внутри контейнера(например, select 1 внутри контейнера с бд), tcpsocket
path: /
port: 80
periodSeconds: 10 # Указывает на то, с какой периодичностью нужно проверять приложение
successThreshold: 1 # Какое количество успешно выполненных попыток сбросит failureThreshold
timeoutSeconds: 1
initialDelaySeconds: 10 # Указывает, сколько нужно подождать перед запуском первой пробы. Использовался активно до того как внедрили startup probe
Сетевое взаимодействие
Можно посмотреть айпи адреса подов и в переменных окружения фронтенда указать DB_HOST=x.x.x.x.x и это будет работать до тех пор пока под не перезапустится, так как каждый перезапуск пода влечет за собой смену айпи адреса. Поэтому полагаться на айпи адреса и поды мы не можем и будем полагаться на абстракцию сервис.
k get svc # получение активных сервисов
k describe svc my-service # подробное описание сервиса, для получения инфы о сервисе в другом namespace, нужно добавить название namespace через "." после имени сервиса
k get pod --show-labels # получение информации с лейблами
kubectl run test --image=centosadmin/utils:0.3 -it bash # дебаг под
k get ing # получение активных ingress-
Service (L3 OSI, NAT, kube-proxy)
-
Это какой то статический ip адрес
-
DNS имя в kube-dns на этот IP(myservice.mynamespace.svc.cluster.local)
-
Правила для роутинга iptables(Service на низком уровне представляет собой набор правил iptables, которые с равной вероятностью распределяют трафик по подам)
-
Service - это не прокси!

Типы сервисов, которые есть в кубернетес:
-
ClusterIP
apiVersion: v1 kind: Service metadata: name: my-service # на основе имени сервиса будет создаваться днс запись в кластере кубернетем spec: ports: - port: 80 targetPort: 80 selector: app: my-app # Указываем лейблы тех подов, на которые мы хотим отправлять трафик с этого сервиса type: ClusterIPТип сервиса, который используется для того, чтобы наладить внутрикластерное взаимодействие.
Выставляется по умолчанию.
Чтобы сервис работал правильно нужно:
1). чтобы селектор сервиса совпадал с лейблами подов раздела spec.
2). поды и сервисы должны находиться в одном неймспейсе (при этом мы можем обратиться к сервису из другого неймспейса, после чего сервис отправит траффик на поды из того же неймспейса, где и сервис)
При помощи clusterip действительно можно пробросить порты приложения в поде наружу и тем самым опубликовать приложение.
Например, с помощью:
kubectl proxy —port=8000 http://localhost:8080/api/v1/proxy/ namespacesdefault/services/my-service:http/ # уже не используется kubectl port-forward service/my-service 10000:80 # активно используется для того, чтобы прокинуть порт приложения с кластера на локальную машину (избавляет от необходходимости разворачивать лишние зависимости на своей локальной машине) -
NodePort
С его помощью можно опубликовать сервисы наружу
Его selector: app также, как и для clusterip должен совпадать с лейблами подов
apiVersion: v1 kind: Service metadata: name: hello-service spec: selector: app: hello ports: - name: hello-port port: 5678 # CLUSTER-IP PORT targetPort: 50001 # PORT WHICH YOUR APPLICATION IS RUNNING ON nodePort: 30051 # NODEPORT PORT type: NodePortУ вас будет доступ к вашему приложению по адресу::
NodeIP:NodePort(30051)(внешний доступ)ClusterIP:port(5678)(внутренний доступ)PodIP:targetPort(50001)(внутренний доступ)
Задав данный тип сервиса, у нас на мастер и воркер нодах создастся правило, которое будет транслировать входящий трафик, приходящий на порт снаружи в наше приложение, порт будет открываться из заранее заданного диапазона 30000-32767

Если вы хотите выставить свое приложение на порт
6001для внешнего использования, вы можете попробовать тип службыLoadBalancer.NodePort используется преимущественно для двух кейсов:
1). Если снаружи кластера есть балансировщик вроде nginx, в котором мы прописываем конкретные locations, порты, которые нужно пробросить в кластер
2). Служебный. Данный тип сервиса используется при работе LoadBalancer, который в свою очередь используется у облачных провайдеров.
Можно использовать, например, при переносе монолита в кубернетес. В данном случае через внешний балансировщик нагрузки часть траффика будет идти на монолит и часть на кубернетес.
-
LoadBalancer
В манифесте можно можно указать loadBalancerIP: “1.1.1.1” статический айпи адрес, который будет являться входной точкой в кластер

-
ExternalName
Позволяет сделать хитрость с днс записью. Обращаясь на имя сервиса мы в итоге попадем на некий хост, который описан в манифесте сервиса

-
ExternalIPs
По схеме работы очень похож на NodePort, но если в NodePort создаются правила трансляции для работы с портом, то в externalPs происходит работа с айпи адресом
Кейсы использования могут быть также связаны с наличием внешнего балансировщика
Полезен при работе с плавающим айпи адресом
Например, айпи адрес находится на первой ноде и с ней что-то происходит и тогда KeepAlive этот адрес переносит на другую ноду и мы можем быть уверены что на новой ноде все необходимые правила трансляции есть и мы можем продолжить работу

-
Headless
У этого сервиса CluserIP=none, это означает что у этого сервиса не будет создан айпи адрес, но будет создана днс за
При создания сервиса в кластере происходит две вещи:
1). Создается днс запись в днс сервере кластера кубернетес

StatefullSet - абстракция, которая реализует поддержку stateful приложений, подключать pv, pvc. Является заменой деплойменту, когда нам нужно запустить базу данныхДля дебаггинга можно поднимать под на базе образа с набором необходимых сетевых утилит:
kubectl run test --image=centosadmin/utils:0.3 -it bash
-
-
Ingress (L7 OSI, HTTP и HTTPS, nginx, envoy, traefik, haproxy):
Изучив services приходим к выводу, что для полноценной публикации типового веб приложения они не подходят. NodePort предлагает небольшой диапазон портов большого значения, LoadBalancer работает только в облаках
Если же необходимо опубликовать приложение, то можно использовать Ingress
Ingress controller - по сути представляет собой балансировщик нагрузки, например, nginx-haproxy-traefik


Внутри ингресс контроллер видит имеющийся сервис, он достает оттуда айпи адреса, который стоят за этим сервисом и отправляет на них трафик
Для указания дополнительных характеристик в ингрес, необходимо указывать annotations
По умолчанию ингресс работает через http протокол и выставить https можно с помощью annotations, также может быть grpc и т.д.
Занятие №6
Уcтройство кластера Kubernetes
Для проверки состояния всех компонентов кластера используется следующая команда:
k get componentstatuses
-
Etcd
Является базой данных кластера кубернетес(key-value). Хранит в себе всю информацию о кластере.
Обычно в отказоустойчивом кластере кубернетеса есть три разных ноды с etcd, называемых мастер нодами. В рамках дев разработки можно работать и с одной нодой.
-
API server
Центральный компонент кластера.
Единственный кто общается с etcd.
Работает по протоколу REST.
Authentication and authorization

-
Controller manager

Контроллер для кластера кубернетеса - это практически то, что реализует абстракции кубернетеса - создает поды из репликасетов, запускает джобы, занимается gc
Набор базовых контроллеров:
-
Node controller
Все ноды кластера периодически пингуют api server о том, что они еще живы. Если вдруг какая то из нод перестанет это делать, по дефолту в настройках в рамках пяти минут, то Node controller передаст информацию в апи сервер о том, что эта нода недоступна и начнет процесс переноса подов этой ноды на другие ноды кластера.
Т.е. он не ходит и не опрашивает ноды как обычные хэлсчек утилиты, а просто проверяет факт того, что ноды постят свой статус на апи сервер.
-
ReplicaSet controller
Деплоймент и репликасет являются просто абстракцией(кусочком ямла), а процедуру создания и обработки реплик реализует данный контроллер
-
Endpoint controller
Автоматическое создание эндпоинтов для сервиса
Garbage collector: при внесение изменений деплоймент, изменяется репликасет и старые репликасеты не удаляются
RevisionHistoryLimit по умолчанию равен 10, показывает сколько необходимо хранить старых версий репликасетов
Если RevisionHistoryLimit равен 10 и появляется 11 репликасет, который принадлежит одному и тому же деплойменту, то он будет удален при помощи gc
-
-
Scheduler

Назначает поды на ноды, учитывая:
- QoS(Quality of Service) политики. В зависимости от ресурсов(limits, requests), scheduler будет решать на какую ноду назначать поды
- Affinity/ anti-affinity. Фактическое указание запуска подов на определенной группе нод.
- Requested resources
- Priority class
Если в scheduler что-то произойдет, то при попытке создать новый деплоймент, его поды будет висеть в состоянии pending
До этого момента рассматривались мастер комоненты, которые располагаются на мастер нодах -
Kubelet

Работает на каждой ноде
Единственный компонент, который работает не в докере
Он непосредственно взаимодействует с системами контейнеризации, обменивается с ними информацией о том, что какие то контейнеры нужно запускать, останавливать и тд
Работает просто как процесс на хосте и отдает команды докер демону
Дополнительно выполняет проверки probes
kubelet выполняя проверки приложения, делает это с той же ноды, где находится приложения и если вдруг нода отвалилась от кластера кубелет этого знать не будет, в то время как NodeController уже отрубит ноду из балансировки
Кубелет занимается отправкой информации о своей ноде в куб апи сервер о том что он жив, нода на месте, сколько контейнеров запущено и в каком они статусе
Кубелет имеет встроенный gc, как только на ноде организуется 90% занятого образами места, кубелет запускает механизм очистки устаревших образов до тех пор, пока количество занимаемой ими памяти не снизится на 10%, т.е. до 80%.
-
Kube-proxy
Стоит на всех серверах и смотрит в kube api и читает оттуда информацию и подписывается на события
Занимается управлением сетевыми правилами на нодах
Сервисы представляют собой несколько правил в iptables на каждой ноде, а эти правила в iptables создает компонент kube proxy
Kube proxy также живет в контейнере
-
Контейнеризация, Сеть, DNS
Занятие №7
Локальная разработка в minikube
k get pod -A - для получения информации о всех подах, даже системных
minikube addons list - список имеющихся расширений для миникуба
minikube addons enable ingress - пример подключение аддона игресса
Для получения доступа к встроенным дашбордам кубернетеса, нужно добавить аддон:
minikube addons enable dashboards
после чего его можно запустить, указав его имя и нэймспейс
minikube service kubernetes-dashboard -n kubernetes-dashboard
для просмотра имеющихся внутри миникуба образов:
minikube image ls
после подключения миникуба к докеру с помощью следующей команды: eval $(minikube docker-env)(эвалы живут в рамках одной сессии).
можно билдить образы напрямую с интерфейса миникуба:
minikube image build . -t myapp:dev
далее можно обращаться к данным образам в манифестах для запуска приложений
Чтобы замаунтить директории при локальной разработке в миникубе, необходимо ввести следующую команду:
minikube mount .:/app
где также, как и в докере первая часть маунта это директория в основной файловой системе, а вторая часть в контейнере
Для автоматизации задач локальной разработки, можно воспользоваться skaffold
Для работы с дополнительными нодами в кластере на миникуб:
minikube node [add|start|stop|delete|list]
Занятие №8
Job
- Создает под для выполнения задачи
- Перезапускает поды до успешного выполнения задачи или истечения таймаута
- activeDeadLineSeconds. - временной лимит на исполнение задачи (после чего джоба будет прибита и под удален)
- backoffLimit. - лимит количественный, сколько попыток будет выдано джобе на исполнение задачи
У джобы поля неизменяемые и его нельзя обновить командой apply
Получение джобы:
k get job
k decribe job hello
Для того, чтобы удалить джобу после выполнения, необходимо указывать параметр ttlSecondsAfterFinished
.spec.completions и .spec.parallelismотвечают за желаемое количество успешно выполненных Pod’ов в рамках Job’а и за параллельный запуск Pod’ов в рамках Job’а соответственно.
CronJob
Позволяет запускать джобы по расписанию
Важной опцией является concurrencyPolicy, при помощи которой можно согласовать выполнение джоб в случае, если одна джоба не успела завершиться за минуту, а вторая уже должна начать отрабатывать в это время
Есть три варианта запуска concurrencyPolicy :
- “Allow” (default): allows CronJobs to run concurrently;
- “Forbid”: forbids concurrent runs, skipping next run if previous run hasn’t finished yet; (best practise)
- “Replace”: cancels currently running job and replaces it with a new one
Для указания количества сохраненных успешных джоб после их выполнения используется - successfulJobsHistoryLimit. (best practise)
Для указания количества сохраненных упавших джоб - failedJobsHistoryLimit (best practise)
Важным параметром является startingDeadlineSeconds (best practise)
Каждый раз при запуске кронджобы может происходить какая то задержка по времени и он отработает не в 0.0, а в 0.05 и допустимое время отставания может явно указать вышеупомянутым ключом
Может произойти ситуация, когда что-то произошло с кластером(например, упал controller manager или scheduler не понимает как назначить под) и тогда кронджоба перестает выполнять задачи, но как только кластер придет в норму, кронджоба высчитает количество невыполненных задач в пропущенный промежуток времени и если это значение превышает 100, то кронджоба будет считаться сломанной и выполняться больше не будет
Кронджоб нельзя запускать с учетом секунд, минимальная величина между запусками минута
Занятие №9
Альтернатива Deployment
DaemonSet
В манифестах не имеют replicas, вместо этого запускают по одному поду на всех узлах кластера При добавлении ноды, добавляет под При удалении ноды GC, также удаляет под
В спеке пода можно указать следующую опцию для выбора ноды на которой поднимать под, кубелет проставляет эту метку kubernetes.io/os автоматически
nodeSelector:
kubernetes.io/os: linuxStatefulSet
В отличие от деплойментов, в стейтфулсете каждый из подов уникальный
Позволяет запускать группу подов(как деплоймент):
-
Гарантирует их уникальность
-
Гарантирует их последовательность(после удаления пода mysql-1 и создания заново, под будет называться mysql1, а не mysql2)
PVC Template - При удалении пода стейтфулсета, pvc этого пода остается
Используется для запуска с сохранением состояния → Rabbit, DBs, Redis, Kafka
В случае падения пода, деплоймент поднимает +1 под и из-за того, что все поды одинаковы, нам абсолютно все равно куда идет трафик
Affinity - раздел в ямл манифесте пода, который позволяет потребовать у scheduler то, каким образом он должен запускать поды по узлам кластера
Занятие №10
Авторизация в кластере
RBAC
- Role
- RoleBinding
- ClusterRole
- ClusterRoleBinding
- ServiceAccount
Role - это список прав на объект
Role и RoleBinding являются объектами namespace-зависимыми
Для получения информации о имеющихся кластерных ролях используется следующая команда:
k get clusterrole
Для обращения к сервис аккаунтам:
k get sa <account-name> -o yaml
RoleBinding:
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nginx-ingress
subjects:
- kind: ServiceAccount
name: nginx-ingress
namespace: ingress-nginx
- kind: User
name: jane # "name" is case sensitive
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: developer # for example organization in user certificate apiGroup: rbac.authorization.k8s.ioВ кубернетес доступ можно выдать либо на уровне кластера (ClusterRole, ClusterRoleBinding), либо точечно к отдельным неймспейсам. Как пример, нельзя выдать доступы ко всем неймспейсам которые начинаются с stage-, dev-, prod- и т.д. Так как в кубе нет юзеров и групп, то для авторизации пользователей и проверки наличия у них каких-либо прав в кластере(rolebindings) используются внешние сервисы Например, гитлаб может взаимодействовать с апи куба для отдачи данных об имеющихся пользователях
Команды для выставления конфига при подключении к кластеру:

Дополнительные инструменты для ограничения прав пользователей в kubernetes:
Resource Quota
Устанавливает количество доступных ресурсов и объектов для нэймспейса в кластере
k get resourcequotas
Limit Range
k get limitranges limit-range -o yaml
Решает две задачи:
- Выдает defalult для тех подов у которых не описаны requests и limits
- Позволяет ограничить потребление для конкретного контейнера в каждом поде
Особенно полезно когда в конкретном неймспейсе разработчик забыл указать ресурсы или же указал их некорректно. Там можно задать параметры min и max, чтобы ограничить в минимально значение(так как если под потребляет слишком мало ресурсов, высока вероятность ошибки запуска приложения) и максимально значение(если разработчик ошибся и задал слишком большое или вовсе не задал и приложение начало потреблять больше чем положено. В случае указания разработчиком слишком большим значений ресурсов для пода, приложение потребляеющее много ресурсов пройдет валидацию на ресурсы указанные в манифесте пода, но не пройдет валидацию Limit Range).
Pod Security Policy
Контролирует аспекты безопасности в описании подов Включается как admission controller plugin “PodSecurityPolicy” - при включении запрещает запуск подов без PSP.
Применяется к подам, которые используют различные небезопасные механизмы. Например, поды которые подключают тома типа HostPath, т.е. поды, которые могут подключить любой каталог с узла к себе внутрь контейнера и каким-либо образом получить доступ к данным, к которым доступа быть не должно.
Также можно указать, чтобы нельзя было запускать поды от рута. Запретить подам использование секретов, системные capabilities вроде отсутствие админа. Является deprecated и в будущем будет заменена.
Занятие №11
Дебаг приложений в кластере
Что усложняет дебаг приложений:
- Отсутствие в контейнере нужных команд
- Запрет на exec. в проде
- Readonly файловая система
Три главные команды дебага:
- k describe …
- k get events
- k logs
[—previous] - ключ помогает посмотреть логи предыдущего запущенного контейнера
Если в выводе describe в termination reason омкилл - нужно изменять выделенную память, так как омкиллер убил под из-за превышение установленных ограничений по памяти. Если же в выводе error, гарантированно что у приложения произошла какая то ошибка и само приложение завершилось в контейнере.
Если что то не так пошло в кубернетесе, можно проверить их командой на events(нужно учитывать что ивенты хранятся один часи )
Профилировщики/дебаггеры:
- Большинство могут работать по сети
- Нужно использовать отдельный порт, либо роутинг на ингрессе
Для Java: Actuator, Jprofiler Для Python: Prometheus, Rookout Для Golang: Pprof
Дебаг из контейнера: Можно сделать exec, но очень аккуратно (кейс, когда разработчик заходит в контейнер и коннектится к базе, отсылая запросы не допустим, так как в оперативная память загружается и можно легко выйти за лимиты и используемый под будет убит омкиллером) Лучше сделать run c образом приложения (со всеми прод.кредами)
Занятие №12
Horizontal Pod Autoscaler
- HPA
Увеличивает количество подов в деплойменте в зависимости от поступающей нагрузки
- Metrics server
Для запуска HPA так же воспользуемся возможностями kubectl. Для создания абстракции HPA без манифеста можно использовать ключ autoscale.
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=5
В результате выполнения команды будет создан HPA, который отслеживает состояние Deployment с именем php-apache. При достижении средней нагрузки на все Pod 50% (для расчетов суммируется процент нагрузки на каждый Pod и делится на их количество) scaling будет производиться в границах от 1-го Pod до 5 Pod.
Смотрим на HPA
kubectl get hpa
Она будет скейлить Pod, как только их использование cpu начнет составлять 50% от request.
После того как нагрузка спадет, автоскейлер дает пять минут на down scale, т.е. только через пять начнет прибивать поды до минимального количества.
- Дефолтные и кастомные метрики
Метрики автоскейлер получает с metric server. Metric server из себя представляет отдельный под, который раз в минуту ходит ко всем кублетами кластера и собирает данные с кадвизоров. Данные он не хранит и предоставляет только данные за минуту.





- Cluster autoscaler

Занятие №13
Templating. Helm.

При работе с хэлмом можно создавать стартовый шаблон с заготовкой чарта следующей командой:
helm create <chart_name>




При создании джобы или пода для тестов релиза, нужно убедиться что имеется хук “helm.sh/hook-delete-policy”: hook-succeeded, чтобы удалить выполненный тест, так как хуки не входят в релиз и даже после его удаления под или джоба останутся висеть в кластере.
Занятие №14
Kubernetes CI/CD
Устновка ранера гитлаб в кластер:
helm repo add gitlab https://charts.gitlab.io
Далее нужно указать токен Settings - CI/CD - Runners - Specific runners - registration token. Скопируйте его из Gitlab и вставьте в файл values.yaml, в переменную runnerRegistrationToken.
gitlabUrl: https://gitlab.com/
runnerRegistrationToken: <token>
runners:
config: |
[[runners]]
[runners.kubernetes]
image = "alpine:3.14"
cpu_request = "100m"
cpu_limit = "1000m"
memory_limit = "2048Mi"
memory_request = "1024Mi"
tags: slurm-k8s
## For RBAC support:
rbac:
create: true
## Run the gitlab-bastion container with the ability to deploy/manage containers of jobs
## cluster-wide or only within namespace
clusterWideAccess: false
## Use the following Kubernetes Service Account name if RBAC is disabled in this Helm chart (see rbac.create)
##
# serviceAccountName: gitlabrunnersa
## Use podSecurity Policy
## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/
podSecurityPolicy:
enabled: false
resourceNames:
- gitlab-runner
## Configure resource requests and limits
## ref: http://kubernetes.io/docs/user-guide/compute-resources/
##
resources:
limits:
memory: 256Mi
cpu: 200m
requests:
memory: 128Mi
cpu: 50mДалее нужно запустить команду хэлма в директории с файлом values.yaml указанным выше:
helm upgrade -i gitlab-runner gitlab/gitlab-runner -f values.yaml -n gitlab-runner --create-namespace
После чего можно проверить что раннер установлен в том разделе, где получали токен.
Памятка:
Создание объектов:
kubectl apply -f ./my-manifest.yaml # создать ресурсы
kubectl apply -f ./my1.yaml -f ./my2.yaml # создать ресурсы из нескольких файлов
kubectl apply -f ./dir # создать ресурсы из всех файлов манифеста в директории
kubectl apply -f https://git.io/vPieo # создать ресурсы из URL-адреса
kubectl create deployment nginx --image=nginx # запустить один экземпляр nginx
kubectl explain pods # посмотреть документацию по манифестам подовПросмотр и поиск ресурсов
# Get-команды с основном выводом
kubectl get services # Вывести все сервисы в пространстве имён
kubectl get pods --all-namespaces # Вывести все поды во всех пространств имён
kubectl get pods -o wide # Вывести все поды в текущем пространстве имён с подробностями
kubectl get deployment my-dep # Вывести определённое развёртывание
kubectl get pods # Вывести все поды в пространстве имён
kubectl get pod my-pod -o yaml # Получить информацию по поду в формате YAML
# Посмотреть дополнительные сведения команды с многословным выводом
kubectl describe nodes my-node
kubectl describe pods my-pod
# Вывести сервисы, отсортированные по имени
kubectl get services --sort-by=.metadata.name
# Вывести поды, отсортированные по количеству перезагрузок
kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'
# Вывести постоянные тома (PersistentVolumes), отсортированные по емкости
kubectl get pv --sort-by=.spec.capacity.storage
# Получить метку версии всех подов с меткой app=cassandra
kubectl get pods --selector=app=cassandra -o \
jsonpath='{.items[*].metadata.labels.version}'
# Получить все рабочие узлы (с помощью селектора исключаем узлы с меткой 'node-role.kubernetes.io/master')
kubectl get node --selector='!node-role.kubernetes.io/master'
# Получить все запущенные поды в пространстве имён
kubectl get pods --field-selector=status.phase=Running
# Показать метки всех подов (или любого другого объекта Kubernetes, которым можно прикреплять метки)
kubectl get pods --show-labels
Обновление ресурсов
kubectl set image deployment/frontend www=image:v2 # Плавающее обновление контейнеров "www" развёртывания "frontend", обновление образа
kubectl rollout history deployment/frontend # Проверить историю развёртывания, включая ревизии.
kubectl rollout undo deployment/frontend # Откатиться к предыдущему развёртыванию
kubectl rollout undo deployment/frontend --to-revision=2 # Откатиться к определённой ревизии
kubectl rollout status -w deployment/frontend # Отслеживать статус плавающего развёртывания "frontend" до его завершения
kubectl rollout restart deployment/frontend # Перезапуск плавающего развёртывания "frontend"
# Принудительно заменить, удалить, а затем пересоздать ресурс. Это приведет к простою приложения
kubectl replace --force -f ./pod.json
# Создать сервис с реплицированным nginx на порту 80, который подключается к контейнерам на порту 8000.
kubectl expose rc nginx --port=80 --target-port=8000
kubectl label pods my-pod new-label=awesome # Добавить метку
kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq # Добавить аннотацию
kubectl autoscale deployment foo --min=2 --max=10 # Автоматически промасштабировать развёртывание "foo"Масштабирование ресурсов
kubectl scale --replicas=3 rs/foo # Промасштабировать набор реплик (replicaset) 'foo' до 3
kubectl scale --replicas=3 -f foo.yaml # Промасштабировать ресурс в "foo.yaml" до 3
kubectl scale --current-replicas=2 --replicas=3 deployment/mysql # Если количество реплик в развёртывании mysql равен 2, промасштабировать его до 3
kubectl scale --replicas=5 rc/foo rc/bar rc/baz # Промасштабировать несколько контроллеров репликацииУдаление ресурсов
kubectl delete -f ./pod.json # Удалить под по типу и имени в pod.json
kubectl delete pod,service baz foo # Удалить поды и сервисы с одноимёнными именам "baz" и "foo"
kubectl delete pods,services -l name=myLabel # Удалить поды и сервисы с именем метки myLabel
kubectl -n my-ns delete pod,svc --all # Удалить все поды и сервисы в пространстве имен my-nsРабота с запущенными подами
kubectl logs my-pod # вывести логи пода (в stdout)
kubectl logs -l name=myLabel # вывести логи пода с меткой myLabel (в stdout)
kubectl logs my-pod --previous # вывести логи пода (в stdout) по предыдущему экземпляру контейнера
kubectl logs my-pod -c my-container # вывести логи контейнера пода (в stdout, при работе с несколькими контейнерами)
kubectl logs -l name=myLabel -c my-container # вывести логи пода с меткой myLabel (в stdout)
kubectl logs my-pod -c my-container --previous # вывести логи контейнера пода (в stdout, при работе с несколькими контейнерами) по предыдущему экземпляру контейнера
kubectl logs -f my-pod # вывести логи пода в режиме реального времени (в stdout)
kubectl logs -f my-pod -c my-container # вывести логи контейнера пода в режиме реального времени (в stdout, при работе с несколькими контейнерами)
kubectl logs -f -l name=myLabel --all-containers # вывести логи всех подов с меткой myLabel (в stdout)
kubectl run -i --tty busybox --image=busybox -- sh # запустить под как интерактивную оболочку
kubectl run nginx --image=nginx --restart=Never -n
mynamespace # Запустить под nginx в заданном пространстве имён
kubectl run nginx --image=nginx --restart=Never # Запустить под nginx и записать его спецификацию в файл pod.yamlРабота с узлами и кластером
kubectl cordon my-node # Отметить узел my-node как неназначаемый
kubectl drain my-node # Вытеснить узел my-node, чтобы подготовиться к эксплуатации
kubectl uncordon my-node # Отметить узел my-node как назначаемый
kubectl top node my-node # Показать метрики по заданному узлу
kubectl cluster-info # Показать адреса главного узла и сервисов
kubectl cluster-info dump # Вывести состояние текущего кластера в stdoutТипы ресурсов
kubectl api-resources
kubectl api-resources --namespaced=true *# Все ресурсы с пространством имён*
kubectl api-resources --namespaced=false *# Все ресурсы без пространства имён*
kubectl api-resources -o name *# Все ресурсы с простым выводом (только имя ресурса)*
kubectl api-resources -o wide *# Все ресурсы с расширенным (с неограниченной длинной) выводом*
kubectl api-resources --verbs=list,get *# Все ресурсы, которые поддерживают глаголы запроса "list" и "get"*
kubectl api-resources --api-group=extensions *# Все ресурсы в API-группе "extensions"*