Запускаем полноценный кластер на Kubernetes с нуля на Ubuntu 16.04

Уже довольно много написано статей, по установке и запуску Kubernetes, однако, не всё так гладко (я потратил несколько суток на запуск своего кластера).

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

Что нужно знать


Серверы:
Кластер подразумевает, что у Вас более одного физического сервера, между которыми и будут распределятся ресурсы. Серверы называются нодами (nodes).

Диски:
Обычные харды в k8s не поддерживаются. Работа с дисками происходит по средствам распределенных файловых хранилищ. Это необходимо для того, чтобы k8s мог «перемещать» контейнеры docker на другие ноды в случае необходимости, без потери данных (файлов).

Начинать создание кластера нужно именно с создания своего распределенного файлового хранилища. Если вы уверены, что диски вам никогда не понадобятся, то этот шаг можно пропустить.
Я выбрал Ceph. А еще рекомендую почитать эту замечательную статью.

Минимальное разумное количество серверов для Ceph — 3 (можно построить и на одном, но в этом мало смысла из-за высокой вероятности потерять данные).

Сеть:
Нам понадобится Flannel — он позволяет организовать программно определяемую сеть (Software Defined Network, SDN). Именно SDN позволяет всем нашим контейнерам общаться с друг другом внутри кластера (установка Flannel производится вместе с k8s и описана ниже).

Подготовка серверов


В нашем примере мы используем 3 физических сервера. Установите Ubuntu 16.04 на все сервера. Не создавайте swap партиции (требование k8s).

Предусмотрите в каждом сервере как минимум один диск (или партицию) для Ceph.

Не включайте поддержку SELinux (в Ubuntu 16.04 он выключен по-умолчанию).

Мы назвали сервера так: kub01 kub02 kub03. Партиция sda2 на каждом сервере создана для Ceph (форматировать не обязательно).

Установка и настройка Ceph


Установку Ceph я опишу довольно кратко. В сети много примеров и на самом сайте Ceph довольно хорошая документация.

Все операции производим из под привелигированого пользователя root.

Создадим временную директорию:

mkdir ~/ceph-admin
cd ~/ceph-admin

Установим Ceph:

apt install ceph-deploy ceph-common

Необходимо создать ключ и разложить его по всем серверам. Это нужно для утилиты ceph-deploy:

ssh-keygen
ssh-copy-id kub01
ssh-copy-id kub02
ssh-copy-id kub03


(возможно, вам понадобится поправить конфиг ssh для разрешения логинится под пользователем root).

Проверьте, что kub01 не прописан в вашем /etc/hosts как 127.0.0.1 (если прописан, удалите эту строку).

Создаем дисковый кластер и инициализируем его:

ceph-deploy new kub01 kub02 kub03
ceph-deploy install kub01 kub02 kub03
ceph-deploy mon create-initial
ceph-deploy osd prepare kub01:sda2 kub02:sda2 kub03:sda2
ceph-deploy osd activate kub01:sda2 kub02:sda2 kub03:sda2

Проверяем наш дисковый кластер:

ceph -s
    cluster 363a4cd8-4cb3-4955-96b2-73da72b63cf5
    health HEALTH_OK

Можно взять на вооружение следующие полезные команды:

ceph -s
ceph df
ceph osd tree

Теперь, когда мы убедились, что Ceph работает, мы создадим отдельный пул (pool) для k8s:

ceph osd pool create kube 100 100

(можно посмотреть все существующие пулы командой: ceph df)

Теперь создадим отдельного пользователя для нашего пула kube и сохраним ключи:

ceph auth get-or-create client.kube mon 'allow r' osd 'allow rwx pool=kube'
ceph auth get-key client.admin > /etc/ceph/client.admin
ceph auth get-key client.kube > /etc/ceph/client.kube

(ключи понадобятся для доступа k8s к хранилищу)

Устанавливаем Kubernetes


Добавим репозиторий k8s в нашу систему:

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main  
EOF

Теперь установим основные пакеты:

apt update
apt install -y docker.io kubelet kubeadm kubernetes-cni

Инициализируем и запускаем k8s

kubeadm init --pod-network-cidr=10.244.0.0/16

(именно такая сеть 10.244.0.0/16 необходима для работы flannel — не изменяйте ее)

Сохраните напечатанную скриптом команду для присоединения нод к кластеру.

Для работы с k8s удобно использовать отдельного непривилегированного пользователя. Создадим его и скопируем в него конфигурационный файл k8s:

useradd -s /bin/bash -m kube
mkdir ~kube/.kube
cp /etc/kubernetes/admin.conf ~kube/.kube/config
chown kube: ~kube/.kube/config

Для работы с k8s используется утилита: kubectl. Используем ее только из под нашего пользователя kube. Для перехода под пользователя выполним:

su - kube

Разрешаем запуск контейнеров на мастере:

kubectl taint nodes --all node-role.kubernetes.io/master-

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

kubectl create clusterrolebinding add-on-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default

Устанавливаем flannel (сетевую подсистему):

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Как проверить что всё работает
Выполните команду:

kubectl -n kube-system get pods

Вывод должен быть примерно следующим:

NAME                                      READY     STATUS    RESTARTS   AGE
etcd-kub01.domain.com                      1/1       Running   1          4d
kube-apiserver-kub01.domain.com            1/1       Running   1          4d
kube-controller-manager-kub01.domain.com   1/1       Running   0          4d
kube-dns-7c6d8859cb-dmqrn                  3/3       Running   0          1d
kube-flannel-ds-j948h                      1/1       Running   0          1d
kube-proxy-rmbqq                           1/1       Running   0          1d
kube-scheduler-kub01.domain.com            1/1       Running   1          4d


Устанавливаем и настраиваем веб-интерфейс


kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml

Создаем пользователя для доступа в веб интерфейс:
cat << EOF > account.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system
EOF

kubectl -n kube-system create -f account.yaml

Запустим kube-proxy, сделать это можно так:

kubectl proxy &

И пробросим порт 8001 с вашей рабочей машины до сервера kub01:

ssh -L 8001:127.0.0.1:8001 -N kub01 &

Теперь мы можем зайти в веб интерфейс со своей рабочей машины по адресу:

http://127.0.0.1:8001/ui
(откроется веб интерфейс, где нужно указать токен)

Получить токен для доступа в веб интерфейс можно так:

kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')

Настраиваем Kubernetes и Ceph


В текущем контроллере kube-controller-manager-amd64:v1.9.2 отсутствует бинарник rbd, необходимый для работы с Ceph, поэтому создадим свой собственный kube-controller-manager:

Что такое RBD, зачем он нужен и почему отсутствует?
RBD (Rados Block Device) — блочное устройство, которое как раз и используется k8s для создания и монтирования партиций Docker контейнеров. В данном случае, это бинарник, входящий в состав пакета: ceph-common.

k8s не включает этот пакет в свой контроллер видимо потому, что он зависит от дистрибутива операционной системы, которую вы используете. Поэтому, при сборке своего контроллера обязательно указывайте именно Ваш дистрибутив, чтобы RBD был актуальным.

Для создания нашего kube-controller-manager сделайте следующее:
(все команды выполняем из под пользователя root)

mkdir docker
cat << EOF > docker/Dockerfile
FROM ubuntu:16.04

ARG KUBERNETES_VERSION=v1.9.2

ENV DEBIAN_FRONTEND=noninteractive \
   container=docker \
   KUBERNETES_DOWNLOAD_ROOT=https://storage.googleapis.com/kubernetes-release/release/${KUBERNETES_VERSION}/bin/linux/amd64 \
   KUBERNETES_COMPONENT=kube-controller-manager

RUN set -x \
   && apt-get update \
   && apt-get install -y \
       ceph-common \
       curl \
   && curl -L ${KUBERNETES_DOWNLOAD_ROOT}/${KUBERNETES_COMPONENT} -o /usr/bin/${KUBERNETES_COMPONENT} \
   && chmod +x /usr/bin/${KUBERNETES_COMPONENT} \
   && apt-get purge -y --auto-remove \
       curl \
   && rm -rf /var/lib/apt/lists/*
EOF

docker build -t "my-kube-controller-manager:v1.9.2" docker/

(обязательно указывайте актуальные версии k8s и дистрибутива ОС)

Проверяем, что наш контроллер успешно создан:

docker images | grep my-kube-controller-manager

Проверяем, что в нашем образе есть rbd:

docker run my-kube-controller-manager:v1.9.2 whereis rbd

Должны увидеть что-то вида: rbd: /usr/bin/rbd /usr/share/man/man8/rbd.8.gz

Заменяем стандартный контроллер нашим, для этого правим файл:
/etc/kubernetes/manifests/kube-controller-manager.yaml

Заменяем строку:
image: gcr.io/google_containers/kube-controller-manager-amd64:v1.9.2
на:
image: my-kube-controller-manager:v1.9.2
imagePullPolicy: IfNotPresent

(обязательно добавляем директиву imagePullPolicy, чтобы k8s не пытался скачивать этот образ из интернета)

Переходим под пользователя kube и дожидаемся пока наш контроллер запустится (ничего делать не нужно).

kubectl -n kube-system describe pods | grep kube-controller

Должны увидеть, что используется наш образ:
Image: my-kube-controller-manager:v1.9.2

Теперь, когда запустился наш контроллер с поддержкой RBD, мы можем приступить к настройке связки k8s и Ceph.

Настройка связки дисковой подсистемы (k8s + Ceph)


Добавляем ключи в k8s, для доступа к Ceph:

kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" --from-file=/etc/ceph/client.admin --namespace=kube-system
kubectl create secret generic ceph-secret-kube --type="kubernetes.io/rbd" --from-file=/etc/ceph/client.kube --namespace=default

Создаем StorageClass (default):

cat << EOF > ceph_storage.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-rbd
  annotations: {"storageclass.kubernetes.io/is-default-class":"true"}
provisioner: kubernetes.io/rbd
parameters:
  monitors: kub01:6789,kub02:6789,kub03:6789
  pool: kube
  adminId: admin
  adminSecretName: ceph-secret
  adminSecretNamespace: "kube-system"
  userId: kube
  userSecretName: ceph-secret-kube
  fsType: ext4
  imageFormat: "2"
  imageFeatures: "layering"
EOF

kubectl create -f ceph_storage.yaml

Как проверить работу дисковой подсистемы?
Проверяем наличие StorageClass:

kube@kub01:~$ kubectl get storageclass
NAME                      PROVISIONER         AGE
ceph-rbd (default)        kubernetes.io/rbd   4d

Создадим тестовый pod с диском:

cat << EOF > test_pod.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: claim1
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: test-pod-with-pvc
spec:
  volumes:
    - name: test-pvc-storage
      persistentVolumeClaim:
        claimName: claim1
  containers:
    - name: test-container
      image: kubernetes/pause
      volumeMounts:
       - name: test-pvc-storage
         mountPath: /var/lib/www/html
EOF

kubectl create -f test_pod.yaml

Проверим, что создался Pod (нужно дождаться создания и запуска):

kube@kub01:~$ kubectl get pods
NAME                READY     STATUS    RESTARTS   AGE
test-pod-with-pvc   1/1       Running   0          15m

Проверим, что создался Claim (запрос на предоставление диска):

kube@kub01:~$ kubectl get pvc
NAME      STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
claim1    Bound     pvc-076df6ee-0ce9-11e8-8b93-901b0e8fc39b   1Gi        RWO            ceph-rbd       12m

Проверим, что создался и сам диск:

kube@kub01:~$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                        STORAGECLASS   REASON    AGE
pvc-076df6ee-0ce9-11e8-8b93-901b0e8fc39b   1Gi        RWO            Delete           Bound     default/claim1               ceph-rbd        

И наконец, проверим, что диск примонтирован в системе:

root@kub01:~$ mount | grep pvc-076df6ee-0ce9-11e8-8b93-901b0e8fc39b
/dev/rbd0 on /var/lib/kubelet/pods/076fff13-0ce9-11e8-8b93-901b0e8fc39b/volumes/kubernetes.io~rbd/pvc-076df6ee-0ce9-11e8-8b93-901b0e8fc39b type ext4 (rw,relatime,stripe=1024,data=ordered)


Добавление новых (дополнительных) нод в кластер k8s


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

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main  
EOF

apt update
apt install -y  docker.io kubelet kubeadm kubernetes-cni ceph-common python

Присоединяем ноду к мастеру:
Нам нужен ключ. Его можно получить на мастере, выполнив команду:

kubeadm token list

Либо, создать его:
kubeadm token create --print-join-command


Пример команды для присоединения (выполняем на новой ноде):

kubeadm join --token cb9141.6a912d1dd7f66ff5 8.8.8.8:6443 --discovery-token-ca-cert-hash sha256:f0ec6d8f9699169089c89112e0e6b5905b4e1b42db22815186240777970dc6fd

Установка и настройка Helm


Для быстрой и простой установки приложений в k8s был придуман Helm.

Список доступных приложений можно найти здесь.

Устанавливаем и инициализируем Helm:

curl https://storage.googleapis.com/kubernetes-helm/helm-v2.8.0-linux-amd64.tar.gz | tar -xz
./linux-amd64/helm init

P.S.: на написание этой статьи ушло 6 часов. Не судите строго, если где-то есть опечатки. Задавайте вопросы, с радостью отвечу и помогу.
Поделиться публикацией
Ммм, длинные выходные!
Самое время просмотреть заказы на Фрилансим.
Мне повезёт!
Реклама
Комментарии 42
  • 0

    Советую посмотреть на Rook для развертывания Ceph

    • 0

      Rook пока очень сырой чтобы на него смотреть как мне кажется. Что-то пойдет не так и все, все хранилище мертво.

    • 0
      Подскажите что почитать по сетям в контейнерах… сколько всего перечитал, но кроме проброса портов в контейнер с ноды, так ничего для себя и не открыл :( Так и не могу понять, как это должно правильно работать с большом кластере
      • 0
        А что именно вы хотите для себя открыть?
        Есть какая-то задача, которую вы не можете решить? Тогда опишите конкретнее о задаче.
        • 0
          Я просто хочу понять, как работать с контейнерами через сеть. Допустим простой пример: 3 ноды докера, там пара контейнеров с БД и веб-сервером, между собой контейнеры работают, это понятно, а как осуществлять правильно внешний доступ к веб-серверу? Пробрасывать порт через ноду кластера? Использовать балансер, где указывать все ноды кластера, что бы это работало отказоустойчиво?
    • +2
      А можите больше рассказать о сетевой подсистеме? Почему выбрали Flannel? Делали какие-то тесты скорости между нодами на разных серверах? Отличаются ли время пингов между контейнерами от пингов между серверами?
      • 0

        У flannel есть режим работы host-gw, когда все ваши машины в пределах одного сегмента L2, там минимальный оверхед — по сути он просто все забивает в таблицу маршрутизации.


        С другой стороны, calico так тоже может, но у calico еще и NetworkPolicy есть.

        • 0
          host-gw это ни для всех. Хочется кластер на недорогом арендном железе/в разных дц/или просто в облаке.
      • 0

        А почему не https://github.com/kubernetes-incubator/external-storage/tree/master/ceph/rbd? Зачем патчить контроллер?

        • 0
          Я рассматривал и этот вариант, но мне нравится и спокойнее, использовать тот вариант, который я понимаю.
          Мне видится мой вариант проще и надежнее. Не нужно клонировать стороннюю репу, не нужно разбираться с Go и ловить баги сторонних разработчиков.
          • 0
            ловить баги сторонних разработчиков

            Так это все те же rootfs / cofyc, по большему счету :-)

        • 0
          Вы пошли по похожему, как и я делал.
          У меня есть пара замечаний.
          Ваш k8s получился с одним мастером, что при трёх серверах как-то не понятно. Я устанавливал через kubespray, плюс тут в том, что у меня получаеся кластер с мультимастером и есть лёгкая возможность добавлять новые ноды (путём записи в inventory файл). Так-же можно позже делать обновления всего кластера, я так делал, когда обновлял с 1.7 на 1.8.
          И второй момент это StorageClass, с этим пунктом я не очень уверен и может быть путаю. Как я помню, для использования rbd, перед этим его (rbd) надо сперва создать. В принципе в этом нет ничего сложного, но для этого его надо в ручную создать (или через скрипты), что вроде не очень удобно. Может быть использовать лучше cephfs и её потом монтировать в поды, для каждого можно создавать отдельные папки. Как-то так:
                  volumeMounts:
                  - name: icingaweb2
                    mountPath: /icingaweb2
          ...
                volumes:
                - name: icingaweb2
                  hostPath:
                    path: /a/data/monitoring.adito.de/icingaweb2
          

          То есть "/a/data" это папка на cephfs, а остальное создаётся при запуске pod/deployment
          • 0

            и для rbd и для cephfs есть контроллеры StorageClass, которые создают хранилище сами.

            • 0
              Ничего, кроме того, что я описал в статье, создавать не нужно)
              Разделы создаются, форматируются и монтируются автоматически.
              CephFS и Ceph (RBD) это немного разные вещи, даже сильно разные)

              CephFS требует создания раздела для данных и мета-данных (да, их нужно создавать самостоятельно). Далее, такие разделы монтируются с помощью обычного mount, например так:
              mount -t cehp kub01:.....:/ /mnt/, либо через fuse.

              Ceph (RBD) — создает раздел и устройство автоматически c помощью утилиты rbd, выглядит это так:
              rbd create rbd/aaa  --size 100M  # создаем раздел
              rdb map rbd/aaa # создаем устройство, вида: /dev/rbd0
              mkfs.ext3 /dev/rbd0 # форматируем
              mount /dev/rbd0 /mnt/disk # монтируем
              

              Я использую именно RBD, и k8s эти команды выполняет самостоятельно)
              • 0
                Я смотрел в сторону kubespray, но он под капотом использует всё тот-же kubeadm, он за вас его запускает с нужными аргументами. Этот путь имеет право на жизнь, но мне нравится путь, когда я сам делаю то, что мне нужно, так я лучше контролирую весь процесс и систему в целом. Я пока не поднимал второго мастера, но уверен, что kubeadm для этого будет достаточно)
              • 0

                Для контейнеров типа MySQL где предполагается их постоянные данные хранить?

                • 0
                  Это сложная и большая тема. Если БД не сильно нагружена, то можно разместить ее в Ceph. Но если БД требует большого кол-ва дисковых операций, то придется запустить ее где-то в другом месте, даже на другом сервере и ВНЕ k8s. На данный момент в k8s ведется разработка для local storage, но в данный момент это alpfa и перспективы весьма туманны.
                  Резюмирую: k8s не готов к работе с сервисами, требующих больших дисковых ресурсов (производительности).
                • 0
                  Здравствуйте.
                  Рассматривали ли вы альтернативы Ceph? Какой-либо glusterfs или иное?
                  Да, можете еще рассказать о сетевой инфраструктуре в вашем случае? Как будет себя чувствовать дисковый кластер (и k8s) при высокой нагрузке и слабым uplink между серверами?
                  • 0
                    Кроме непосредственно поднятия кластера до состояния «заработало» было бы еще интересно почитать основы по защите кластера — т.е. что нужно учитывать, когда настраиваешь кубернетс на серверах с прямым доступом из интернет: чтобы и внутренние сервисы можно было наружу отдавать и условно не выставлять базу с админским доступом без пароля во внешнюю сеть.
                    • 0
                      Данная статья всё таки больше о том, как запустить кластер до рабочего состояния.
                      При всём желании не получится описать в одной статье всё и про всё.
                      Не очень понятен вопрос о базе без пароля выставленную во внешнюю сеть. О чем это?
                      Если вы запустите какую либо БД (или вообще любое ПО) через k8s, то она не выставляется во внешнюю сеть, а наличие в ней пароля зависит от деплоя.
                      Для того, чтобы понять как работает k8s со внешней средой, советую почитать про Ingress.
                      • 0
                        Я имею ввиду доступ к самому kubernetes.
                        Например при настройках по умолчанию может остаться доступ к API без пароля или с каким-то известным паролем, заданным при установке по умолчанию.

                        Тогда без дополнительной настройки (смены пароля, закрытие всех путей доступа к API и методов авторизации, кроме тех что заданы явно) — кластер получается открытым для для внешних систем и кто угодно сможет запускать там свои образы.
                        • 0
                          kubernetes хорошо продуманна. Пароли не применяются. Доступы осуществляются с помощью ключей. Но Вы правы, безопасности нужно уделять внимание. Думаю, будет не лишним заняться более глубоким изучением сервисов, торчащих во внешний мир.
                    • 0
                      k8s требует распределенного файлового хранилища.
                      я может что то пропустил, но с каких пор k8s стал именно требовать распределенное хранилище? Сама суть кубернетиса в том, что у вас запускаются контейнеры и потеря контейнера никак не должна влиять на работу кластера. При потере контейнера/ноды scheduler k8s просто запустит их на другой ноде(подах)

                      Не увидел настройку докера для работы с flannel. Каким образом в вашем случае поды запущенные на разных нодах, а по дефолту докер использует подсеть 172.17.0.0/16, будут общаться между собой?

                      Если БД не сильно нагружена, то можно разместить ее в Ceph
                      да вы батенька знаете толк в извращениях
                      • 0
                        я может что то пропустил, но с каких пор k8s стал именно требовать распределенное хранилище?

                        Это написано в разделе про «Диски». Если приложению нужен диск (storage), то да, я повторюсь: «требует», и в статье я объяснил почему. Если приложению диск не нужен, то и требования не возникает.

                        Не увидел настройку докера для работы с flannel. Каким образом в вашем случае поды запущенные на разных нодах, а по дефолту докер использует подсеть 172.17.0.0/16, будут общаться между собой?

                        Когда k8s запускает pod (докер), он выделяет свободный IP адрес из диапазона flannel, и назначает его контейнеру. Ничего дополнительно конфигурировать не нужно.
                        • 0
                          Когда k8s запускает pod (докер), он выделяет свободный IP адрес из диапазона flannel
                          очень странно, а откуда докер вообще узнает о существовании flannel? Насколько я помню, то по дефолту pod'ы поднимались в дефолтной подсети docker и только после явной правки конфига docker оно начинало работать как надо.

                          У них собственно и в документации об этом говорится. И именно поэтому flannel генерирует файл /var/run/flannel_docker_opts.env. Например у меня в тестовой среде он имеет вид

                          # cat /var/run/flannel_docker_opts.env
                          DOCKER_OPT_BIP="--bip=172.16.2.1/24"
                          DOCKER_OPT_IPMASQ="--ip-masq=true"
                          DOCKER_OPT_MTU="--mtu=1450"


                          Соответственно на каждой ноде flannel получает свою подсеть /24, запрашивая ее у etcd

                          Если приложению нужен диск (storage), то да, я повторюсь: «требует», и в статье я объяснил почему
                          лично мне не понятна формулировка «Если приложению нужен диск (storage)» — в каких случаях приложение будет требовать диск? Например при запуске nginx диск будет востребован? При этом нигде не упоминается stateful/stateless приложения и их отличия.

                          И пробросим порт 8001 с вашей рабочей машины до сервера kub01:
                          ssh -L 8001:127.0.0.1:8001 -N kub01 &
                          для этих вещей специально придумали kubectl proxy --port=8001
                          • 0
                            очень странно, а откуда докер вообще узнает о существовании flannel?

                            Этого я не знаю. К счастью, k8s работает очень прозрачно, и многое от нас скрыто под капотом (да, туда можно залезть, но если всё и так работает, то зачем?). Хотите верьте, хотите нет, но k8s запускает pod-ы c уже настроенной сетью, и нам ничего дополнительного делать не нужно.
                            Если у вас есть желание разобраться в этом глубже, добро пожаловать на Хабр со своей статьей)

                            лично мне не понятна формулировка «Если приложению нужен диск (storage)» — в каких случаях приложение будет требовать диск?

                            Тут два пути:
                            1) Вы сами создаете нужный вам контейнер, и пишите к нему YAML файл, где и просите у k8s (claim) о диске (если он вам нужен).
                            2) Используете helm, где для каждого проекта описана необходимость в диске
                            Вообще, постановка вопроса странная: мне кажется, вы просто обязаны понимать, что делаете и как это должно работать, и нужен ли вам диск.

                            для этих вещей специально придумали kubectl proxy --port=8001

                            Спасибо, не знал)
                            • +2
                              мне кажется, вы просто обязаны понимать, что делаете и как это должно работать, и нужен ли вам диск.

                              Не все разработчики понимают нужен ли им диск, по крайней мере диск с rw правами. На прямой вопрос нужен ли rw доступ куда-то на диск, говорят "нет, мы не используем в приложении работу с файлами, у нас всё в базе". А потом выясняется, по логам ошибок, что они -то не использует, а вот рантайм под капотом использует: сессии, временные файлы какие-то, иногда даже исполняемые. Ну и собственно логи :)

                      • +1
                        Спасибо за вашу статью, во многом полезная для новичка, но до полного howto не хватает подробностей и нюансов.

                        С чем столкнулся я:
                        1) Прежде всего нужно удалить из /etc/hosts связку хостнейма и 127.0.0.1, в противном случае команда ceph-deploy не пройдет и упадет с ошибкой:
                        [ceph_deploy][ERROR ] UnableToResolveError: Unable to resolve host: kub01

                        2) На всех тачках нужно поставить python. Без него все тот же ceph-deploy будет валиться с ошибкой, только уже с другой:
                        [kub02][INFO  ] Running command: ssh -CT -o BatchMode=yes kube02
                        bash: python: command not found

                        3) В пункте про обмен ssh ключами было бы не лишним указать от имени какого юзера мы обмен ключами делаем. Потому что если мы распыляем ключ рута и коннектимся от имени рута, то нужно разрешить ssh коннект от рута, потому что в Ubuntu 16.04 по дефолту он запрещен.
                        4) После правки конфига контроллера нужно производить какие либо операции? У меня спустя даже полчаса ничего не произошло. В итоге помог ребут тачки.
                        5) На шаге присоединения нод не хватает однозначности. Что мы в итоге делаем, новый токен или используем старый. Если используем старый то как собрать команду приведенную вами? А самое главное IP 8.8.8.8 очень путает.
                        6) Еще было бы интересно организовать доступ к подам снаружи без проброса через ssh.
                        • 0
                          Пункты 1-3: Можно например почитать официальную документацию по установке кластера ceph. В котором все нормально расписано.
                          6)Что бы можно было ходить к подам снаружи можно взять другой сетевой плагин, например calico.
                          Отдельно стоит отметить, что kube-adm решение не для production.
                          p.s. Самую активную помощь по продуктам описанным в статье можно получить в каналах телеграм.
                          t.me/kubernetes_ru
                          t.me/ceph_ru
                          • 0
                            1) Прежде всего нужно удалить из /etc/hosts связку хостнейма и 127.0.0.1, в противном случае команда ceph-deploy не пройдет и упадет с ошибкой:

                            Вы что-то делали не так) Разумеется, если вы используете домен вида: kub01, то он должен резолвится. Если он прописан в /etc/hosts как 127.0.0.1, то он будет резолвится, и такой ошибки быть не должно. И да, наверное его лучше не прописывать как 127.0.0.1.
                            Я на эту проблему не попадал, так как hostname серверу задавал уже после инсталляции сервера.

                            2) На всех тачках нужно поставить python. Без него все тот же ceph-deploy будет валиться с ошибкой, только уже с другой:

                            У вас Ubunta? Странно, что python не поставился по зависимостям, при установке самого ceph-deploy…
                            Я python ставил отдельно, так как была необходимость запускать ansible (для своих целей).

                            коннектимся от имени рута, то нужно разрешить ssh коннект от рута, потому что в Ubuntu 16.04 по дефолту он запрещен.

                            Спасибо за замечание. Подумаю как это решить по изящнее)

                            В итоге помог ребут тачки.

                            Это какой-то windows-way. Всегда бейте себя по рукам за такое)
                            У меня нет четкого ответа на это. Обычно, k8s сам замечает изменения и перезапускает controller. Но если этого не произошло, то можно перезапустить: kubelet и docker. Если кто знает, как это сделать красиво, отпишитесь.

                            5) На шаге присоединения нод не хватает однозначности. Что мы в итоге делаем, новый токен или используем старый. Если используем старый то как собрать команду приведенную вами? А самое главное IP 8.8.8.8 очень путает.

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

                            Чем пугает 8.8.8.8? его нужно заменить на IP вашего мастера.

                            6) Еще было бы интересно организовать доступ к подам снаружи без проброса через ssh.

                            Зачем так? Делайте сервис + Ingress.
                            Но если очень хочется, то iptables вам в помощь (PREROUTING, POSTROUTING).
                            • 0
                              Вы что-то делали не так) Разумеется, если вы используете домен вида: kub01, то он >должен резолвится. Если он прописан в /etc/hosts как 127.0.0.1, то он будет резолвится, >и такой ошибки быть не должно. И да, наверное его лучше не прописывать как 127.0.0.1.

                              Да я просто наткнулся на ошибку и первое что посоветовал гугл это как раз: "In /etc/hosts, remove the hostname of loopback address. Add a line of real IP address and hostname correspondence, then problem solved."


                              У вас Ubunta? Странно, что python не поставился по зависимостям, при установке самого >ceph-deploy…
                              Я python ставил отдельно, так как была необходимость запускать ansible (для своих >целей).

                              Да Ubuntu 16.04. Питон автоматом поставился только на мастер. А на остальных тачках команды python нет, только python3 из коробки.


                              Это какой-то windows-way. Всегда бейте себя по рукам за такое)

                              Я хочу чтоб вы правильно понимали мой подход к данной статье)
                              Я рассчитывал просто на copy-paste без напряга мозгов, что покрутить/посмотреть.
                              Поскольку для серьезного деплоя есть тот де kubespray.


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

                              ИМХО если нам нужен токен, тогда нужно описать на этапе init о том что нужно сохранить команду присоединения либо уж однозначно создавать новый токен на этапе коннекта нод.


                              Чем пугает 8.8.8.8? его нужно заменить на IP вашего мастера.

                              Пугает тем что это гугловый DNS. Вводит в заблуждение тем что не понятно, толи автор реально просто юзает гугловый DNS для каких то целей присоединения (ну мало ли что там может понадобиться), толи его надо заменить на мастер. Вот реально, лучше измените на какой нибудь 1.2.3.4 или вообще %master_ip%.


                              Зачем так? Делайте сервис + Ingress.
                              Но если очень хочется, то iptables вам в помощь (PREROUTING, POSTROUTING).

                              Да в том что и дело что я и еще не малый процент аудитории не знает как правильно. И понятия не имеет о том что такое Ingress :)
                              Отсюда и вопросы такие.


                              Еще кстати момент. На этапе создания конфига kube-controller-manager copy-paste сработает не правильно, потому что при вставке баш попытается отрезолвить переменные ${KUBERNETES_DOWNLOAD_ROOT},${KUBERNETES_COMPONENT} и тп, а их нет в том окружении в котором делаем вставку, они появятся только при сборке, но на этапе сборки на их месте будет уже пустота.

                          • 0
                            Как раз проверял вчера надстройку над ceph под kubernetes: rook.io

                            Весь план сводится к запуску собственно кубернетеса любым способом и дальше через kubectl деплоится ceph за счет «родного» PVC ну и использует относительно новую абстракцию операторов.

                            Если интересно, могу в песочницу написать howto на базе любого облака.
                            • +1
                              Конечно пишите статью, это всегда полезно)
                              Лично мне пока боязно «запихивать» ceph в контейнеры. Опять же, тут нужно пояснить, какую часть ceph мы собираемся запускать в контейнерах.
                              • 0
                                В том то и дело, что они абстрагировали все уровни. То есть мониторы, метаданные и собственно диски. Всё в контейнерах с автодискавери на основе метаданных самого кубернетеса.

                                Раньше были приблуды типа только клиентов для маунта экспортированной вне кубернетеса файловой системы, но это не тру контейнер вей.

                                Тут же интеграция на основе и в рамках API самого кубернетеса. Для примера можете посмотреть как coreos написали операторы для кубернетеса.

                                Напишу статью – сюда линк положу, если не забуду.
                                • 0

                                  У меня ceph в контейнерах (официальный контейнер) в виде статических манифестов kubelet. С одной стороны удобно и изоляция, и обновлять приятно, и мониторить можно из k8s, с другой — хранилище полностью отделено от control plane куба (и управляется ансиблой).

                              • 0
                                Даниил, пробовали работать с iSCSI?
                                • 0
                                  Нет, не пробовал. Я решал конкретную задачу, и не было возможности попробовать всё. А пробовать там есть что, и ох как много)

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.