Syntax highlighting of lib/luksa

[TOC]

[Примеры манифестов](https://github.com/luksa/kubernetes-in-action)

# Глава 1. Знакомство с Kubernetes

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

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

 ![Использование ВМ для изоляции групп приложений по сравнению с контейнерной изоляцией](lib/luksa/luksa_pic_1_4.png)

## Изоляция контейнеров

Для изоляции контейнеров используется два механизма:

* *пространства имен Linux*, гарантирует, что каждый процесс видит свое персональное представление о системе (файлы, процессы, сетевые интерфейсы, hostname и т. д.);
* *контрольные группы Linux* (cgroups), ограничивающие объем ресурсов, которые может потреблять процесс (ЦП, оперативная память, пропускная способность сети и т. д.).

### Пространство имен Linux

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

Существуют следующие виды пространств имен:

* файловая система (mnt);
* ид-р процессов (pid);
* сеть (net);
* межпроцессное взаимодействие (ipc);
* UTS;
* пользовательские идентификаторы.


Каждый вид пространства имен используется для изоляции определенной группы ресурсов. Например, пространство имен UTS определяет, какой хостнейм и доменное имя видит процесс, запущенный внутри этого пространства имен. Назначив двум процессам два разных пространства имен UTS, можно заставить их видеть разные локальные хостнеймы. Другими словами, для двух процессов это будет выглядеть так, как будто они выполняются на двух разных машинах (по крайней мере, в том, что касается хостнеймов).

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

### Контрольные группы

Другая половина изоляции контейнеров связана с ограничением объема системных ресурсов, которые может потреблять контейнер. Это достигается с помощью cgroups, функционального средства ядра Linux, которое ограничивает использование ресурсов процессом (или группой процессов). Процесс не может использовать больше, чем настроенный объем ЦП, оперативной памяти, пропускной способности сети и т. д. Благодаря этому процессы не могут перехватывать ресурсы, зарезервированные для других процессов, что аналогично тому, когда каждый процесс выполняется на отдельной машине.

## Первое знакомство с Kubernetes

Kubernetes – это программная система, которая позволяет легко развертывать контейнеризированные приложения и управлять ими. Она использует возможности контейнеров Linux для запуска разнородных приложений без необходимости знать какие-либо внутренние детали этих приложений и без необходимости вручную развертывать эти приложения на каждом хосте.

Система состоит из ведущего узла (мастера) и любого количества рабочих узлов. Когда разработчик отправляет список приложений ведущему узлу, Kubernetes развертывает их в кластере рабочих узлов. То, на какой узел приземляется компонент, не имеет (и не должно иметь) значения ни для разработчика, ни для системного администратора.

Kubernetes можно рассматривать как операционную систему для кластера. Она избавляет разработчиков приложений от необходимости внедрять в свои приложения определенные службы, связанные с инфраструктурой;

### Архитектура Kubernetes

На аппаратном уровне кластер Kubernetes состоит из множества узлов, которые можно разделить на два типа:

* *ведущий узел (мастер)*, на котором размещена плоскость управления (Control Plane) Kubernetes, контролирующая и управляющая всей системой Kubernetes;
* *рабочие узлы*, на которых выполняются развертываемые приложения.

Плоскость управления – это то, что управляет кластером и заставляет его функционировать. Она состоит из нескольких компонентов, которые могут работать на одном ведущем узле либо быть распределены по нескольким узлам и реплицированы для обеспечения высокой доступности. Эти компоненты следующие:

* *сервер Kubernetes API*, с которым взаимодействуете вы и другие компоненты плоскости управления;
* *планировщик*, который распределяет приложения (назначает рабочий узел каждому развертываемому компоненту приложения);
* *менеджер контроллеров*, выполняющий функции кластерного уровня, такие как репликация компонентов, отслеживание рабочих узлов, обработка аварийных сбоев узлов и т. д.;
* *etcd*, надежное распределенное хранилище данных, которое непрерывно сохраняет конфигурацию кластера.

Рабочие узлы – это машины, на которых выполняются контейнеризированные приложения. Задача выполнения, мониторинга и предоставления служб приложениям выполняется следующими компонентами:

* Docker, rkt или другая среда выполнения контейнеров, в которой выполняются контейнеры;
* Kubelet, агент, который обменивается с сервером API и управляет контейнерами на своем узле;
* служебный прокси Kubernetes (kube-proxy), который балансирует нагрузку сетевого трафика между компонентами приложения.

 ![Компоненты, составляющие кластер Kubernetes](lib/luksa/luksa_pic_1_9.png)


# Глава 2. Первые шаги с Docker и Kubernetes


В разделе описывается:

* установка Docker и упаковка приложения;
* запуск контейнеров Docker;
* запуск minikube и установка kubectl;
* запуск модуля (pod) с приложением в minikube.

# Глава 3. Модули: запуск контейнеров в Kubernetes

В главе описано:
* определение и описание модулей
* дескрипторы модулей
* метки
* пространства имен

Модуль - размещенная рядом группа контейнеров
Контейнеры в модуле изолированы частично: они используют общие сетевые ресурсы.
Файловые системы контейнеров разделены.

Все модули в кластере находятся в одном плоском общем пространстве сетевых адресов. Каждый модуль может получить доступ к другому модулю по его IP-адресу.

Дескриптор (описание в формате yaml или json) модуля состоит из следующих секций:
* метаданные - пространство имен, метки и прочее;
* спецификация - описание содержимого: контейнеры, тома
* статус - текущая информация о работе

```bash
# --- создание модуля
kubectl create -f kubia-manual.yaml
# --- получение запущенных модулей
kubectl get pods
# --- получение полного дескриптора
kubectl get po kubia-manual -o yaml
# --- получение логов модуля
kubectl logs kubia-manual
# --- получение контейнера из модуля
kubectl logs kubia-manual -c kubia
```

Для получения доступа к модулю можно воспользоваться *переадресацией портов*
```bash
# port-on-localhost:port-on-pod
kubectl port-forward kubia-manual 8888:8000
```

Метка - это произвольная пара "ключ-значение", которая может быть назначена произвольному ресурсу. Ресурсу может быть назначено множество меток.

```bash
# --- получение всех модулей с отображением всех меток
kubectl get po --show-labels
# --- получение модулей с отображением заданных меток
kubectl get po -L creation_method,env
# --- фильтр модулей по меткам
kubectl get po -l creation_method=manual
```

Метки можно присваивать "узлам" и привязывать модули к этим узлам через селектор меток в дескрипторе.

Использование нескольких пространств имен позволяет разбить сложные системы со множеством компонентов на более мелкие отдельные группы.
Имена ресурсов должны быть уникальны в пределах пространства имен.
```bash
# --- получение пространств имен
kubectl get ns
# --- получение модулей из заданного пространства имен
kubectl get po -n my-namespace
```
Дескриптор пространства имен состоит только из секции *metadata*
```bash
# --- создание пространства имен
kubectl create -f create-namespace.yaml
# --- создание ПИ без дескриптора
kubectl create namespace custom-namespace
```