Kubernetes

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 19:02, 3 января 2018.
Kubernetes
Kubernetes small logo.png
Разработчики: Google
Выпущена: 6 June 2014 (2014-06-06)[1]
Постоянный выпуск: 1.2.4[2] / May 7, 2016 (2016-05-07)
Состояние разработки: Active
Написана на: Go
Операционная система: Кросс-платформенное
Тип ПО: Cluster management software
Лицензия: Apache License 2.0
Веб-сайт kubernetes.io

Kubernetes - [от греч. "рулевой", "кормчий"] платформа оркестровки контейнеров построенная на базе etcd и systemd, позволяющая управлять кластерами виртуальных машин и Linux-контейнеров созданными с использованием таких инструментариев как Docker и Rocket как единым целым. Проект был начат компанией Google. Код Kubernetes написан на языке Go и распространяется под лицензией Apache 2.0. Продукт позиционируется как развиваемое сообществом универсальное решение, не привязанное к отдельным решениям и способное работать с любыми приложениями в любых облачных окружениях.

Введение

Контейнеры

Вспомним два вида виртуализации (подробнее можно посмотреть тут):

  • Аппаратная виртуализация - виртуализация на основе гипервизора. Гипервизор (англ. Hypervisor) или Монитор виртуальных машин (в компьютерах) — программа или аппаратная схема, обеспечивающая одновременное, параллельное выполнение нескольких операционных систем на одном и том же хост-компьютере: операционная система хоста эмулирует аппаратное обеспечение, поверх которого уже запускаются гостевые операционные системы. Гипервизор также обеспечивает изоляцию операционных систем друг от друга, защиту и безопасность, разделение ресурсов между различными запущенными ОС и управление ресурсами.
  • Виртуализация на уровне операционной системы — метод виртуализации, при котором ядро операционной системы поддерживает несколько экземпляров (контейнеров) пространства пользователя, вместо одного. С точки зрения пользователя полностью идентичны реальному серверу. Виртуализация на уровне операционной системы позволяет запускать изолированные и безопасные виртуальные машины, но не позволяет запускать операционные системы с ядрами, отличными от типа ядра базовой операционной системы. При виртуализации на уровне операционной системы не существует отдельного слоя гипервизора. Вместо этого сама хостовая операционная система отвечает за разделение аппаратных ресурсов между несколькими виртуальными машинами и поддержку их независимости друг от друга.

Почему контейнеры стали популярны? В двух словах, гипервизор работает следующим образом: операционная система хоста эмулирует аппаратное обеспечение, поверх которого уже запускаются гостевые операционные системы. Это означает, что взаимосвязь между гостевой и хостовой операционными системами должна следовать «железной» парадигме (все, что умеет делать оборудование, должно быть доступно гостевой ОС со стороны хостовой).

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

К примеру, если Контейнер 1 и Контейнер 2 работают с одним и тем же файлом, то ядро хоста открывает этот файл и размещает страницы из него в страничный кэш ядра. Эти страницы затем передаются Контейнеру 1 и Контейнеру 2: если оба хотят прочитать одни и те же данные, то получают одну и ту же страницу. Если же гипервизорные виртуальные машины VM1 и VM2 выполняют такую же операцию, то сначала сам хост открывает запрашиваемый файл (создавая страницы в своем страничном кэше), а затем еще и каждое из ядер VM1 и VM2 делает то же самое. Это означает, что при чтении VM1 и VM2 одного и того же файла в памяти существует целых три одинаковых страницы (по одной в страничном кэше хоста и в ядрах VM1 и VM2) – потому, что они не умеют одновременно использовать одну и ту же страницу, как это делают контейнеры. Такое совместное использование ресурсов приводит к тому, что вычислительная плотность (это количество виртуальных сред, которые можно запустить на сервере) почти в 3 раза выше для контейнерной виртуализации, чем для гипервизорной.

История контейнеров

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

Сотрудники Google экспериментировали с традиционной виртуализацией для решения этой задачи, но быстро пришли к выводу, что она не подходит. Главной проблемой стало то, что потеря производительности слишком высока (а плотность, соответственно, слишком низка) и отклик недостаточно эластичен для массового предоставления веб-сервисов. Да и к тому же среднее время загрузки гипервизорной VM составляет десятки секунд, такой тип виртуализации не подходит для массового обслуживания запросов.

В то же самое время группа разработчиков экспериментировала с Linux и концепцией, основанной на механизме cgroups, называющейся «контейнеры процессов». В считанные месяцы Google наняла эту группу для работы над контейнеризацией своих дата-центров в целях решения проблемы эластичности при масштабировании. В январе 2008 года часть технологии cgroup, используемой в Google, перешла в ядро Linux. Так родился проект LXC (Linux Containers). Приблизительно в это же время компания Parallels выпустила OpenSource-версию своей виртуализации Virtuozzo под названием OpenVZ. В 2011-ом Google и Parallels пришли к соглашению о совместной работе над своими контейнерными технологиями. Результатом стал релиз ядра Linux версии 3.8 в 2013 году, в котором были объединены все актуальные на тот момент контейнерные технологии для Linux.

Для хостинг-провайдеров основное преимущество – плотность. При этом корпоративным клиентам она не слишком-то нужна. Виртуализация для них предлагалась как способ решить проблему низкой утилизации серверного оборудования и найти способ использования свободных вычислительных ресурсов. Таким образом, технология для этого сегмента не представляла ценности. Из-за этого контейнеры практически игнорировались корпоративным сегментом, представляющим 85% всего рынка виртуализации. Фактически - всем миром, кроме хостинг-провайдеров.

Ситуация начала меняться с 2010 года – с ростом облачного бизнеса. Облака обещали многое, но компании столкнулись ровно с теми же трудностями, что и Google - эластичное масштабирование ресурсов в дата-центрах плюс к необходимости обеспечивать хороший сервис. И здесь у гипервизоров время загрузки оказалось слишком медленным, чтобы обеспечить быстрый отклик системы, что приводило к неспособности адекватно менять объемы ресурсов. И контейнеры наконец-то начали привлекать внимание: потому что, если вы быстро масштабируетесь, то, в конце концов, истощите лимиты своей физической системы, в то время как контейнеры позволяют обслуживать больше (до 3 раз) клиентских запросов без необходимости добавлять оборудование.

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

Docker

Docker.jpg

В 2013 году на рынок пришел разработчик Docker (бывший dotCloud) с одноимённым решением и показал, что он может развернуть полноценное виртуальное окружение да запустить в нем приложение так же просто, как, например, перезапустить веб-сервер. И этот факт не мог не радовать ИТ-сообщество. Ведь по сути возможно объединить тысячи машин и запустить на них тысячи приложений, развернув сеть обмена данными - здравствуй прорыв в облачных технологиях.

Процессу, запущенному под Docker, кажется, что он работает в минимальном окружении, хотя при этом процесс работает в той же операционной системе, что и остальные. Docker просто позволяет изолировать просто один процесс. Соответственно, используя одно и то же железо, с помощью Docker вы можете создать кучу изолированных процессов практически моментально, так как в них не происходит загрузка отдельной ОС. К тому же, Docker использует «слоеную» файловую систему AuFS, благодаря которой контейнеры могут совместно использовать одинаковые части файловой системы, доступные только на чтение.

Kubernetes

Реакция не заставила ждать долго и в 2014 году свою руку к Docker приложила и Google, запустив проект Kubernetes. Компания открыла его код в июне 2014 года, и уже совсем скоро благодаря усилиям Mirantis он появится в каталоге приложений OpenStack.

Если говорить о назначении проекта, то это - менеджер для управления кластерами из контейнеров (хотя сама Google предпочитает говорить о нем как об импровизационном инструменте, а не сервисе оркестрации: в этом есть смысл, так как в отличие от систем оркестрации здесь нет «дирижера»). Система полностью динамическая в том смысле, что самостоятельно реагирует на события в реальном времени и позволяет поднять сервис, который просто будет работать и масштабироваться по запросу.

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

Архитектура

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

  • запускать большое количество контейнеров Docker или Rocket на большом количестве хостов;
  • отслеживать состояние;
  • управлять запущенными контейнерами, обеспечивая при этом совместное размещение и репликацию;
  • параллельно осуществлять масштабирование и балансировку большого количества хостов Docker или Rocket.

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

С точки зрения архитектуры проект Kubernetes состоит из главного сервера (master server) и большого количества подчиненных серверов, которые называются миньонами или нодами (minions/nodes). С помощью инструментальных средств командной строки осуществляется подключения к API на главном сервере, который управляет и дирижирует работой всех нод - хостов Docker, получающих инструкции от главного сервера и запускающих контейнеры.

8de5bea86458f0a50a18631e16b867f6.png

Master

Kubernetes Master

Сервер с сервисом Kubernetes API. Предполагается, что в будущем будут конфигурации с несколькими главными серверами. Мастер сервер содержит компоненты, которые обеспечивают уровень управления кластера. Например, мастер-компоненты несут ответственность за глобальные решения (например, планирования), выявление и реагирование на события внутри кластера (например, запуск нового pod'a). Мастер-компоненты сервера могут по идее запускаться на любом хосте кластера, и работать одновременно с компонентами пользователя, однако, для простоты, если хост выбран в роли мастера, на Мастере выключаются все компоненты пользователя и в рабочих остаются только компоненты уровня управления. К мастер-компонентам относятся: kube-apiserver, etcd, kube-controller-manager, kube-scheduler, разного рода аддоны (провайдеры DNS, kube-ui, fluentd-elasticsearch и система мониторинга cluster-monitoring). Конфигурация мастера может происходить через командную строку, для этого разворачивается сервис kubecfg.

Minion / Node / Узел

Kubernetes Node

Любой из многочисленных хостов Docker с сервисом Kubelet, который получает задания от главного сервера master и управляет тем, как контейнеры запускаются на конкретном хосте. Узел может быть VM-машиной или простой железкой, в зависимости от кластера. Каждый узел имеет услуги, необходимые для запуска pod'ов и управляется мастер-компонентами. На каждой ноде запускаются следующие услуги (компоненты):

  1. kubelet - агент ноды который:
    • наблюдает за контенерами запущенными на данной ноде (либо через apiserver, либо через локальный файл конфигурации) то есть:
      • монтирует необходимое пространство памяти;
      • загружает параметры POD'a;
      • запускает контейнеры стручка через докер;
      • периодически выполняет мониторинг контейнеров;
    • делает отчёты о статусе контейнеров для системы, путем создания "зеркального pod'a", если необходимо.*делает отчёты о статусе ноды для системы.
  2. kube-proxy - устанавливает абстрактные сетевые правила на хосте и обслуживает сетевые соединения;
  3. docker - используется для работы самих контейнеров;
  4. rkt - альтернатива docker'у;
  5. monit - "процесс нянечка" для поддержания kubelet и docker'а.

Каждый узел имеет свой статус, который описывает следующие параметры:

  1. Адрес узла: хост-имя, внешний IP, внутренний IP.
  2. Фаза узла: текущий этап жизненного цикла узла: выполняется, уничтожен, в ожидании.
  3. Состояние узла: описывает состояние выполняющегося узла. Существует одно состояние - Ready и его три свойства: True (готов к приёму pod'а), False (есть неполадки, не готов к приёму pod'а), или Unknown (контроллер узла не имеет информацию об узле).
  4. Мощность узла: описывает CPU, память и максимальное число под которые могут быть запущены.
  5. Общая информация об узле: версия ядра, версия Kubernetes (версия kubelet, версия kube-proxy), версия docker, название ОС.

Pod

Оболочка, которая определяет коллекцию контейнеров связанных друг с другом и развернутых на одном узле, например, контейнер с базой данных и веб-сервером. В оболочке pod можно указать несколько контейнеров, которые будут развернуты на одном и том же хосте Docker. Преимущество в этом случае состоит в том, что контейнеры, находящиеся в одной оболочке pod, могут вместе пользоваться одними и теми же ресурсами, такими как тома хранения данных, и тем же самый пространством имен сети и адресом IP. Ресурсы существуют в течение всего времени, пока существует оболочка pod, поскольку в контейнерах нет механизма постоянного хранения данных.

В пакете Kubernetes рассматриваются состояния, а не процессы. Когда вы определяете оболочку pod, то Kubernetes пытается сделать так, чтобы она всегда работала. По этому если контейнер будет уничтожен, то будет сделана попытка запустить новый контейнер. Если контроллер репликаций определяет, что должно быть три реплики, то Kubernetes будет пытаться всегда запустить именно такое их количество, запуская и останавливая контейнеры по мере их необходимости.

Контроллер репликаций

Определяет, какое количество должно быть запущено оболочек pod или контейнеров. Контейнеры размещаются на многочисленных серверах minion или иначе выражаясь, на узлах. В случае если количество оболочек или контейнеров отклоняется от установленного значения, то производятся работы по запуску или деактивации оболочек или узлов.

Сервис

Сервис в Kubernetes это абстракция которая определяет:

  • логический объединённый набор pod и политику доступа к ним;
  • как внутри контейнера публикуются сервисы / порты и происходит взаимодействие через прокси со внешней средой.

Сервис отображает связь между портами контейнеров, работающих внутри оболочек pod на различных серверах minion, и портами, которые доступны извне. Если мы используем несколько оболочек pod, относящихся к некоторому определению сервиса, то будет осуществляться балансировка нагрузки по трафику, проходящему через них.

Ярлыки

Ярлыки это - пары ключ/значение, которые прикреплены к объектам, например, pod'ам. Они предназначены для быть использованы для:

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

Ярлыки могут быть присоединены к объектам на момент создания и в дальнейшем добавлены и изменены в любое время. Каждый объект может иметь набор ярлыков. Каждый ключ должен быть уникальным для данного объекта.

Более подробно об ярлыках

Основные особенности

Итак, подытожим основные особенности Kubernetes:

  • Предоставление базовых функций для развёртывания и управления инфраструктурой, таких как ведение базы DNS, балансировка нагрузки, проверка работоспособности на уровне приложений, управление аккаунтами;
  • Поддержка динамической миграции приложений, для хранения данных которых могут применяться как локальные хранилища, так и сетевые системы, такие как Google Compute Engine, AWS Elastic Block Store и NFS;
  • Возможность развёртывания групп контейнеров с выполнением операций обновлений и отмены изменений сразу для всей группы;
  • Средства для инспектирования и отладки приложений с поддержкой в CLI- и web-интерфейсах выполнения произвольных команд, перенаправления сетевых портов, сбором логов и мониторингом за потреблением ресурсов.
  • Средства для обновления и динамического масштабирования работающего кластера, без его остановки;
  • Использование пространств имён для логического разбиения кластера на части с более гранулированным разделением ресурсов. Например, определённые части кластера можно выделить для обслуживания различных приложений или разделить кластер на разделы для тестирования и рабочего выполнения.
  • Высокое время отклика на обращение к API, например, перепланирование выполнения контейнера осуществляется менее чем в течение 5 секунд;
  • Автоматизированное управление работой контейнеров и их восстановление.Если по какой-нибудь причине, например, из-за того, некоторый процесс закончится аварийно, контейнер остановится, Kubernetes заметит это и через несколько секунд создаст новый контейнер.
  • Система протестирована в конфигурациях с тысячами узлов в кластере с сотнями контейнеров на узле.

Разворачиваем Kubernetes

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

Local-machine решения

Проще всего ознакомиться с Kubernetes на локальной машине. В подобных решениях создают один кластер с одним или несколькими узлами на одной физической машине. Настройка полностью автоматизирована.

Hosted решения

Если есть желание оценить платформу на хостинге, то можно использовать облачные сервисы Google.

Облачные решения под ключ

Если есть желание побыть в роли IaaS-провайдера.

Кастомные решения

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

Облачный провайдер + ОС

ОС развернутые на виртуальных машинах

На чистых серверах

Чистый сервер CoreOS+Kubernetes. Пошаговая инструкция

1. Для установки нам необходимо два или более сервера. Первым делом установим на них CoreOS.

1.1 Скачать образ CoreOS последней версии "Stable" с официального сайта CoreOS/releases и создать загрузочную флешку.

1.2 Загрузить сервер с флешки и создать файл с содержимым:

#cloud-config
hostname: CoreOS_1
ssh_authorized_keys:
- ssh-rsa 
****

Вместо звездочек поставить свой открытый rsa ключ. Это необходимо для первой авторизации на сервере.

1.3 Для установки CoreOS на сервер выполнить команду:

coreos-install -d *путь, куда устанавливаем* -с *название файла, с первоначальными настройками*

1.4 После установки, загрузить систему с жесткого диска. Проделать шаги 1-4 с остальными серверами.

2. Переходим к установки Kubernetesa. Для начала необходимо выбрать какая машина будет мастером, т.е. дирижировать остальными машинами. Следующие шаги выполняем на master-машине.

2.1 С помощью скрипта создаем ssl ключи для обеспечения безопасности системы. Эти ключи будут использоваться для передачи терминальной информации внутри кластера. *ip master-машины*и *ip worker-машины* вписать свои.

#!/bin/bash
set -e
cat > openssl.cnf << EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
IP.1 = 10.3.0.1
IP.2 = *ip master-машины*
EOF
echo "Wrote master"
openssl genrsa -out ca-key.pem 2048
openssl req -x509 -new -nodes -key ca-key.pem -days 10000 -out ca.pem -subj "/CN=kube-ca"
openssl genrsa -out apiserver-key.pem 2048
openssl req -new -key apiserver-key.pem -out apiserver.csr -subj "/CN=kube-apiserver" -config openssl.cnf
openssl x509 -req -in apiserver.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out apiserver.pem -days 365 -extensions v3_req -extfile openssl.cnf
cat > worker-openssl.cnf << EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
IP.1 = *ip worker-машины*
EOF
echo "Wrote worker1"
openssl genrsa -out CoreOS_2-worker-key.pem 2048
WORKER_IP=*ip worker-машины* openssl req -new -key CoreOS_2-worker-key.pem -out CoreOS_2-worker.csr -subj "/CN=CoreOS_2" -config worker-openssl.cnf
WORKER_IP=*ip worker-машины* openssl x509 -req -in CoreOS_2-worker.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out CoreOS_2-worker.pem -days 365 -extensions v3_req -extfile worker-openssl.cnf
rm worker-openssl.cnf
mkdir -p /etc/kubernetes/ssl
cp ca.pem apiserver.pem apiserver-key.pem /etc/kubernetes/ssl
chmod 600 /etc/kubernetes/ssl/*-key.pem
chown root:root /etc/kubernetes/ssl/*-key.pem
echo "DONE"

2.2 Далее необходимо сгенерировать токен по ссылке https://discovery.etcd.io/new?size=2, где цифра - количество серверов в кластере и изменить файл /var/lib/coreos-install/user_data, внести свой токен, ключ оставить свой, не забыть изменить *ip master-машины внутри сети*. Внести в него следующее содержимое:

#cloud-config

hostname: CoreOS_1
coreos:
  etcd2:
    discovery: *токен*
    advertise-client-urls: http://*ip master-машины внутри сети*:2379,http://*ip master-машины внутри сети*:4001
    initial-advertise-peer-urls: http://*ip master-машины внутри сети*:2380
    listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
    listen-peer-urls: http://*ip master-машины внутри сети*:2380
  units:
    - name: etcd2.service
      command: start
ssh_authorized_keys:
  - ssh-rsa 
*****

2.3 Создать файл /etc/systemd/system/flanneld.service.d/40-ExecStartPre-symlink.conf с содержимым:

ExecStartPre=/usr/bin/ln -sf /etc/flannel/options.env /run/flannel/options.env

2.4 Создать файл /etc/systemd/system/docker.service.d/40-flannel.conf содержимым:

[Unit]
Requires=flanneld.service
After=flanneld.service
[Service]
EnvironmentFile=/etc/kubernetes/cni/docker_opts_cni.env

2.5 Создать файл /etc/kubernetes/cni/docker_opts_cni.env содержимым:

DOCKER_OPT_BIP=""
DOCKER_OPT_IPMASQ=""

2.6 Создать файл /etc/flannel/options.env с содержимым:

{
    "name": "podnet",
    "type": "flannel",
    "delegate": {
        "isDefaultGateway": true
    }
}

2.7 Создать файл /etc/kubernetes/manifests/kube-apiserver.yaml с содержимым, *ip master-машины внутри сети* и *ip worker-машины внутри сети* соответственно заменить на свои:

apiVersion: v1
kind: Pod
metadata:
  name: kube-apiserver
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: kube-apiserver
    image: quay.io/coreos/hyperkube:v1.6.1_coreos.0
    command:
    - /hyperkube
    - apiserver
    - --storage-backend=etcd2
    - --storage-media-type=application/json
    - --bind-address=0.0.0.0
    - --etcd-servers=http://*ip master-машины внутри сети*:2379,http://*ip worker-машины внутри сети*:2379
    - --allow-privileged=true
    - --service-cluster-ip-range=10.3.0.0/24
    - --secure-port=443
    - --advertise-address=*ip master-машины внутри сети*
    - --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota
    - --tls-cert-file=/etc/kubernetes/ssl/apiserver.pem
    - --tls-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem
    - --client-ca-file=/etc/kubernetes/ssl/ca.pem
    - --service-account-key-file=/etc/kubernetes/ssl/apiserver-key.pem
    - --runtime-config=extensions/v1beta1/networkpolicies=true
    - --anonymous-auth=false
    - --service-node-port-range=9090-32767
    livenessProbe:
      httpGet:
        host: 127.0.0.1
        port: 8080
        path: /healthz
      initialDelaySeconds: 15
      timeoutSeconds: 15
    ports:
    - containerPort: 443
      hostPort: 443
      name: https
    - containerPort: 8080
      hostPort: 8080
      name: local
    volumeMounts:
    - mountPath: /etc/kubernetes/ssl
      name: ssl-certs-kubernetes
      readOnly: true
    - mountPath: /etc/ssl/certs
      name: ssl-certs-host
      readOnly: true
  volumes:
  - hostPath:
      path: /etc/kubernetes/ssl
    name: ssl-certs-kubernetes
  - hostPath:
      path: /usr/share/ca-certificates
    name: ssl-certs-host

2.8 Создать файл /etc/kubernetes/manifests/kube-proxy.yaml с содержимым:

apiVersion: v1
kind: Pod
metadata:
  name: kube-proxy
  namespace: kube-system
  annotations:
    rkt.alpha.kubernetes.io/stage1-name-override: coreos.com/rkt/stage1-fly
spec:
  hostNetwork: true
  containers:
  - name: kube-proxy
    image: quay.io/coreos/hyperkube:v1.6.1_coreos.0
    command:
    - /hyperkube
    - proxy
    - --master=http://127.0.0.1:8080
    securityContext:
      privileged: true
    volumeMounts:
    - mountPath: /etc/ssl/certs
      name: ssl-certs-host
      readOnly: true
  volumes:
  - hostPath:
      path: /usr/share/ca-certificates
    name: ssl-certs-host

2.9 Создать файл /etc/kubernetes/manifests/kube-controller-manager.yaml с содержимым:

apiVersion: v1
kind: Pod
metadata:
  name: kube-controller-manager
  namespace: kube-system
spec:
  containers:
  - name: kube-controller-manager
    image: quay.io/coreos/hyperkube:v1.6.1_coreos.0
    command:
    - /hyperkube
    - controller-manager
    - --master=http://127.0.0.1:8080
    - --leader-elect=true
    - --service-account-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem
    - --root-ca-file=/etc/kubernetes/ssl/ca.pem
    resources:
      requests:
        cpu: 200m
    livenessProbe:
      httpGet:
        host: 127.0.0.1
        path: /healthz
        port: 10252
      initialDelaySeconds: 15
      timeoutSeconds: 15
    volumeMounts:
    - mountPath: /etc/kubernetes/ssl
      name: ssl-certs-kubernetes
      readOnly: true
    - mountPath: /etc/ssl/certs
      name: ssl-certs-host
      readOnly: true
  hostNetwork: true
  volumes:
  - hostPath:
      path: /etc/kubernetes/ssl
    name: ssl-certs-kubernetes
  - hostPath:
      path: /usr/share/ca-certificates
    name: ssl-certs-host

2.10 Создать файл /etc/kubernetes/manifests/kube-scheduler.yaml с содержимым:

apiVersion: v1
kind: Pod
metadata:
  name: kube-scheduler
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: kube-scheduler
    image: quay.io/coreos/hyperkube:v1.6.1_coreos.0
    command:
    - /hyperkube
    - scheduler
    - --master=http://127.0.0.1:8080
    - --leader-elect=true
    resources:
      requests:
        cpu: 100m
    livenessProbe:
      httpGet:
        host: 127.0.0.1
        path: /healthz
        port: 10251
      initialDelaySeconds: 15
      timeoutSeconds: 15

2.11 Далее все запускаем с помощью команд:

sudo systemctl daemon-reload
sudo systemctl start flanneld
sudo systemctl enable flanneld
sudo systemctl start kubelet
sudo systemctl enable kubelet

3. Переходим к настройке worker-машины. 3.1 Переносим ключи с master-машины, в следующие папки.

/etc/kubernetes/ssl/ca.pem
/etc/kubernetes/ssl/CoreOS_2-worker.pem
/etc/kubernetes/ssl/CoreOS_2-worker-key.pem

3.2 Настраиваем права:

sudo chmod 600 /etc/kubernetes/ssl/*-key.pem
sudo chown root:root /etc/kubernetes/ssl/*-key.pem

3.3 Далее необходимо сизменить файл /var/lib/coreos-install/user_data, заменяя при этом данные ip адресов, внести свой токен, полученный на шаге 2,2 и записать свой открытый ключ.

#cloud-config

hostname: CoreOS_2
coreos:
  etcd2:
    discovery: *токен*
    advertise-client-urls: http://*ip worker-машины внутри сети*:2379,http://*ip worker-машины внутри сети*:4001
    initial-advertise-peer-urls: http://*ip worker-машины внутри сети*:2380
    listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
    listen-peer-urls: http://*ip worker-машины внутри сети*:2380
  units:
    - name: etcd2.service
      command: start
ssh_authorized_keys:
  - ssh-rsa 
*****

3.4 Создать файл /etc/flannel/options.env с содержимым (*ip worker-машины* и *ip master-машины* заменить):

FLANNELD_IFACE=*ip master-машины*
FLANNELD_ETCD_ENDPOINTS=http://*ip master-машины*:2379,http://*ip worker-машины*:2379

3.5 Создать файл /etc/systemd/system/flanneld.service.d/40-ExecStartPre-symlink.conf с содержимым:

[Service]
ExecStartPre=/usr/bin/ln -sf /etc/flannel/options.env /run/flannel/options.env

3.6 Создать файл /etc/systemd/system/docker.service.d/40-flannel.conf с содержимым:

[Unit]
Requires=flanneld.service
After=flanneld.service
[Service]
EnvironmentFile=/etc/kubernetes/cni/docker_opts_cni.env

3.7 Создать файл /etc/kubernetes/cni/docker_opts_cni.env с содержимым:

DOCKER_OPT_BIP=""
DOCKER_OPT_IPMASQ=""

3.7 Создать файл /etc/kubernetes/cni/net.d/10-flannel.conf с содержимым:

{
    "name": "podnet",
    "type": "flannel",
    "delegate": {
        "isDefaultGateway": true
    }
}

3.8 Создать файл /etc/systemd/system/kubelet.service с содержимым (заменить *ip worker-машины* и *ip master-машины*):

[Service]
Environment=KUBELET_IMAGE_TAG=v1.6.1_coreos.0
Environment=KUBELET_IMAGE_URL=quay.io/coreos/hyperkube
Environment="RKT_RUN_ARGS=--uuid-file-save=/var/run/kubelet-pod.uuid   --volume dns,kind=host,source=/etc/resolv.conf   --mount volume=dns,target=/etc/resolv.conf   --volume rkt,kind=host,source=/opt/bin/host-rkt   --mount volume=rkt,target=/usr/bin/rkt   --volume var-lib-rkt,kind=host,source=/var/lib/rkt   --mount volume=var-lib-rkt,target=/var/lib/rkt   --volume stage,kind=host,source=/tmp   --mount volume=stage,target=/tmp   --volume var-log,kind=host,source=/var/log   --mount volume=var-log,target=/var/log   "
ExecStartPre=/usr/bin/mkdir -p /etc/kubernetes/manifests
ExecStartPre=/usr/bin/mkdir -p /var/log/containers
ExecStartPre=-/usr/bin/rkt rm --uuid-file=/var/run/kubelet-pod.uuid
ExecStartPre=/usr/bin/mkdir -p /opt/cni/bin
ExecStart=/usr/lib/coreos/kubelet-wrapper  --hostname-override=*ip worker-машины*   --api-servers=https://*ip master-машины*:443   --cni-conf-dir=/etc/kubernetes/cni/net.d   --network-plugin=cni   --container-runtime=docker   --rkt-path=/usr/bin/rkt   --rkt-stage1-image=coreos.com/rkt/stage1-coreos   --register-node=true   --allow-privileged=true   --pod-manifest-path=/etc/kubernetes/manifests   --cluster_dns=10.3.0.10   --cluster_domain=cluster.local   --kubeconfig=/etc/kubernetes/worker-kubeconfig.yaml   --tls-cert-file=/etc/kubernetes/ssl/worker.pem   --tls-private-key-file=/etc/kubernetes/ssl/worker-key.pem
ExecStop=-/usr/bin/rkt stop --uuid-file=/var/run/kubelet-pod.uuid
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

3.9 Создать файл /etc/kubernetes/manifests/kube-proxy.yaml с содержимым (заменить *ip master-машины*):

apiVersion: v1
kind: Pod
metadata:
  name: kube-proxy
  namespace: kube-system
spec:
  hostNetwork: true
  containers:
  - name: kube-proxy
    image: quay.io/coreos/hyperkube:v1.6.1_coreos.0
    command:
    - /hyperkube
    - proxy
    - --master=https://*ip master-машины*
    - --kubeconfig=/etc/kubernetes/worker-kubeconfig.yaml
    securityContext:
      privileged: true
    volumeMounts:
    - mountPath: /etc/ssl/certs
      name: "ssl-certs"
    - mountPath: /etc/kubernetes/worker-kubeconfig.yaml
      name: "kubeconfig"
      readOnly: true
    - mountPath: /etc/kubernetes/ssl
      name: "etc-kube-ssl"
      readOnly: true
  volumes:
  - name: "ssl-certs"
    hostPath:
      path: "/usr/share/ca-certificates"
  - name: "kubeconfig"
    hostPath:
      path: "/etc/kubernetes/worker-kubeconfig.yaml"
  - name: "etc-kube-ssl"
    hostPath:
      path: "/etc/kubernetes/ssl"

3.10 Создать файл /etc/kubernetes/worker-kubeconfig.yaml с содержимым:

apiVersion: v1
kind: Config
clusters:
- name: local
  cluster:
    certificate-authority: /etc/kubernetes/ssl/ca.pem
users:
- name: kubelet
  user:
    client-certificate: /etc/kubernetes/ssl/worker.pem
    client-key: /etc/kubernetes/ssl/worker-key.pem
contexts:
- context:
    cluster: local
    user: kubelet
  name: kubelet-context
current-context: kubelet-context

3.11 Вводим команды:

sudo systemctl daemon-reload
sudo systemctl start flanneld
sudo systemctl start kubelet
sudo systemctl enable flanneld
sudo systemctl enable kubelet

4. Переходим обратно к Master-машине 4.1 Скачиваем и преобразовываем службу kubectl

curl -O https://storage.googleapis.com/kubernetes-release/release/v1.6.1/bin/linux/amd64/kubectl
chmod +x kubectl

4.2 Настраиваем службу ( внутри звездочек прописываем свои ip адреса и пути к ключам )

kubectl config set-cluster default-cluster --server=https://*ip адресса master-машины* --certificate-authority=$*путь к ca_pem* 
kubectl config set-credentials default-admin --certificate-authority=$*путь к ca_pem*  --client-key=$*путь к admin_key*  --client-
certificate=$*путь к admin.crt*  
kubectl config set-context default-system --cluster=default-cluster --user=default-admin 
kubectl config use-context default-system 
kubectl get nodes

4.3 Создать файл dns-addon.yml с содержимым:

apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "KubeDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP: 10.0.0.1
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP


---


apiVersion: v1
kind: ReplicationController
metadata:
  name: kube-dns-v20
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    version: v20
    kubernetes.io/cluster-service: "true"
spec:
  replicas: 1
  selector:
    k8s-app: kube-dns
    version: v20
  template:
    metadata:
      labels:
        k8s-app: kube-dns
        version: v20
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ''
        scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
    spec:
      containers:
      - name: kubedns
        image: gcr.io/google_containers/kubedns-amd64:1.8
        resources:
          limits:
            memory: 170Mi
          requests:
            cpu: 100m
            memory: 70Mi
        livenessProbe:
          httpGet:
            path: /healthz-kubedns
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
        readinessProbe:
          httpGet:
            path: /readiness
            port: 8081
            scheme: HTTP
          initialDelaySeconds: 3
          timeoutSeconds: 5
        args:
        - --domain=cluster.local.
        - --dns-port=10053
        ports:
        - containerPort: 10053
          name: dns-local
          protocol: UDP
        - containerPort: 10053
          name: dns-tcp-local
          protocol: TCP
      - name: dnsmasq
        image: gcr.io/google_containers/kube-dnsmasq-amd64:1.4
        livenessProbe:
          httpGet:
            path: /healthz-dnsmasq
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
        args:
        - --cache-size=1000
        - --no-resolv
        - --server=127.0.0.1#10053
        - --log-facility=-
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
      - name: healthz
        image: gcr.io/google_containers/exechealthz-amd64:1.2
        resources:
          limits:
            memory: 50Mi
          requests:
            cpu: 10m
            memory: 50Mi
        args:
        - --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1 >/dev/null
        - --url=/healthz-dnsmasq
        - --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1:10053 >/dev/null
        - --url=/healthz-kubedns
        - --port=8080
        - --quiet
        ports:
        - containerPort: 8080
          protocol: TCP
      dnsPolicy: Default

4.4 Ввести следующие команды:

kubectl create -f dns-addon.yml
kubectl get pods --namespace=kube-system | grep kube-dns-v20

4.5 Создать файлы kube-dashboard-rc.yaml и kube-dashboard-svc.yaml соответственно содержащие:

apiVersion: v1
kind: ReplicationController
metadata:
  name: kubernetes-dashboard-v1.6.0
  namespace: kube-system
  labels:
    k8s-app: kubernetes-dashboard
    version: v1.6.0
    kubernetes.io/cluster-service: "true"
spec:
  replicas: 1
  selector:
    k8s-app: kubernetes-dashboard
  template:
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
        version: v1.6.0
        kubernetes.io/cluster-service: "true"
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ''
        scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
    spec:
      containers:
      - name: kubernetes-dashboard
        image: gcr.io/google_containers/kubernetes-dashboard-amd64:v1.6.0
        resources:
          limits:
            cpu: 100m
            memory: 50Mi
          requests:
            cpu: 100m
            memory: 50Mi
        ports:
        - containerPort: 9090
        livenessProbe:
          httpGet:
            path: /
            port: 9090
          initialDelaySeconds: 30
          timeoutSeconds: 30

и

apiVersion: v1
kind: Service
metadata:
  name: kubernetes-dashboard
  namespace: kube-system
  labels:
    k8s-app: kubernetes-dashboard
    kubernetes.io/cluster-service: "true"
spec:
  selector:
    k8s-app: kubernetes-dashboard
  ports:
  - port: 80
    targetPort: 9090

4.6 Выполнить:

kubectl create -f kube-dashboard-rc.yaml
kubectl create -f kube-dashboard-svc.yaml

4.7 Убедиться в работе dashboard`а

kubectl get pods --namespace=kube-system
kubectl port-forward kubernetes-dashboard-v1.6.0-*SOME-ID* 9090 --namespace=kube-system

Ссылки по теме

Сноски

  1. "First GitHub commit for Kubernetes". github.com. 2014-06-07. 
  2. "GitHub Releases page". github.com. 2016-05-07.