LINUX.ORG.RU

История изменений

Исправление vbr, (текущая версия) :

В общем ладно, писать сюда уже больше не буду, всё расползлось по куче скриптов и конфигов, в одном месте это всё вываливать уже геморно.

Общая схема, к которой я в итоге пришёл.

  1. Создаётся отдельный внутренний лоад-балансер, слушающий на 10.206.192.99:6443, в пуле которого 10.206.192.9x:6443 (это control planes).

  2. kubeadm init –control-plane-endpoint «10.206.192.99:6443» …

  3. Всё без исключения устанавливается через helm. Все (нужные мне) пакеты поддерживают его из коробки.

  4. Некоторые пакеты требуют секреты. Хотя обычно можно через хельм их создать, я создаю отдельно, чтобы единообразно создавать/обновлять пакеты и не вбивать секреты каждый раз.

  5. Устанавливаем calico, единственный конфиг это { cidr: "10.244.0.0/16", encapsulation: VXLAN }. Убрал ebpf, плохо понимаю, как он работает, не думаю, что замечу разницу.

  6. Добавляем worker-ов или убираем taint с control plane.

  7. Устанавливаем openstack cinder csi. Это потому, что у меня openstack. Кто-нибудь просит persistent volume claim, этот csi создаёт persistent volume. Очень удобно. Сначала создаём секрет, потом устанавливаем хельмом. Приведу полную схему, всё остальное устанавливается так же.

#!/bin/sh

bin="$(dirname "$0")"
conf="$bin/../conf"

. "$conf/versions.sh"

if [ -z "$OS_APPLICATION_CREDENTIAL_ID" ] || [ -z "$OS_APPLICATION_CREDENTIAL_SECRET" ]
then
    echo >&2 "OS_APPLICATION_CREDENTIAL_ID and OS_APPLICATION_CREDENTIAL_SECRET must be set"
    exit $?
fi

cat "$conf/secret-cinder-csi-system-cloud-config.yaml" \
    | envsubst '$OS_APPLICATION_CREDENTIAL_ID $OS_APPLICATION_CREDENTIAL_SECRET' \
    | kubectl apply --filename=- \
    || exit $?

echo "success: apply secret-cinder-csi-system-cloud-config.yaml"

helm repo add "cloud-provider-openstack" "https://kubernetes.github.io/cloud-provider-openstack" \
    || exit $?

"$bin/upgrade-cinder-csi.sh" || exit $?
apiVersion: v1
kind: Namespace
metadata:
  name: "cinder-csi-system"
---
apiVersion: v1
kind: Secret
metadata:
  namespace: "cinder-csi-system"
  name: "cloud-config"
type: Opaque
stringData:
  cloud.conf: |
    [Global]
    auth-url="https://auth.pscloud.io/v3/"
    application-credential-id="$OS_APPLICATION_CREDENTIAL_ID"
    application-credential-secret="$OS_APPLICATION_CREDENTIAL_SECRET"
    region="kz-ala-1"
    [Metadata]
    search-order="metadataService"
    [BlockStorage]
    rescan-on-resize=true
#!/bin/sh

bin="$(dirname "$0")"
conf="$bin/../conf"

. "$conf/versions.sh"

helm upgrade "cinder-csi" "cloud-provider-openstack/openstack-cinder-csi" \
        --install \
        --namespace="cinder-csi-system" \
        --version "$CINDER_CSI_VERSION" \
        --values "$conf/helm-values-cinder-csi.yaml" \
    || exit $?

echo "success: upgrade cinder-csi"
  1. Устанавливаем ingress-nginx. Ох и поломал я тут голову, как лучше это сделать. И openstack controller устанавливал, чтобы он создавал LoadBalancer-ы автоматом. И через hostNetwork пробовал. Все варианты рабочие.

Но в итоге остановился на самом тупом и топорном.

controller:
  config: { use-proxy-protocol: true }
  ingressClassResource: { default: true }
  replicaCount: 2
  service:
    type: NodePort
    nodePorts:
      http: 30080
      https: 30443

Соответственно создаём отдельно через терраформ второй лоад-балансер и настраиваем его на worker адреса, :80 -> 30080, :443 -> 30443. Также у меня настроен он через протокол PROXYV2, чтобы получать адрес клиента. Nginx его передаёт потом через заголовки X-Forwarder-*.

Вообще можно всё на один лоад балансер повесить (исходный). Но мне показалось правильней сделать несколько. В моём понимании самое важное это обеспечить непрерывность работы control нод. Остальное как-нибудь работать будет. А если, например, внешний дудос перегрузит load balancer, через который общаются все узлы с control plane, то кластер точно развалится нафиг. Правда стоит больше денег. В общем если будете делать - на ваше усмотрение.

Такая конфигурация вносит лишнюю задержку (микроскопическую), вносит лишнюю нагрузку (запрос приходит на load balancer, с него идёт на случайный worker, с него идет на случайный worker, в котором запущен nginx-controller, с него идёт уже на worker, где запущен целевой сервис. Но плюс в том, что всё работает просто и понятно.

Далее устанавливаем cert-manager. Для него нужен cloudflare token. Через DNS домены будет подтверждать.

apiVersion: v1
kind: Namespace
metadata:
  name: "cert-manager"
---
apiVersion: v1
kind: Secret
metadata:
  namespace: "cert-manager"
  name: "cloudflare-api-token"
type: Opaque
stringData:
  "api-token": "$CLOUDFLARE_API_TOKEN"
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: "default"
spec:
  acme:
    email: "me@example.com"
    server: "https://acme-v02.api.letsencrypt.org/directory"
    privateKeySecretRef:
      name: "default-issuer-account-key"
    solvers:
      - dns01:
          cloudflare:
            apiTokenSecretRef:
              name: "cloudflare-api-token"
              key: "api-token"

В принципе на этом настройку основных компонентов кластера считаю завершённой. Пользователь может запрашивать хранилище, пользователь может публиковать свои сервисы через ingress и автоматически получать рабочий https. Пока не разобрался с публикацией произвольных портов, в частности для gitlab нужно будет опубликовать 22 порт, но вроде через тот же ingress-nginx должно работать.

Дальше на очереди установка KeyCloak, настройка kubectl и Dashboard (а в будущем gitlab, grafana) для работы через логин-пароль, но это уже другая история.

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

Исправление vbr, :

В общем ладно, писать сюда уже больше не буду, всё расползлось по куче скриптов и конфигов, в одном месте это всё вываливать уже геморно.

Общая схема, к которой я в итоге пришёл.

  1. Создаётся отдельный внутренний лоад-балансер, слушающий на 10.206.192.99:6443, в пуле которого 10.206.192.9x:6443 (это control planes).

  2. kubeadm init –control-plane-endpoint «10.206.192.99:6443» …

  3. Всё без исключения устанавливается через helm. Все (нужные мне) пакеты поддерживают его из коробки.

  4. Некоторые пакеты требуют секреты. Хотя обычно можно через хельм их создать, я создаю отдельно, чтобы единообразно создавать/обновлять пакеты и не вбивать секреты каждый раз.

  5. Устанавливаем calico, единственный конфиг это { cidr: "10.244.0.0/16", encapsulation: VXLAN }. Убрал ebpf, плохо понимаю, как он работает, не думаю, что замечу разницу.

  6. Добавляем worker-ов или убираем taint с control plane.

  7. Устанавливаем openstack cinder csi. Это потому, что у меня openstack. Кто-нибудь просит persistent volume claim, этот csi создаёт persistent volume. Очень удобно. Сначала создаём секрет, потом устанавливаем хельмом. Приведу полную схему, всё остальное устанавливается так же.

#!/bin/sh

bin="$(dirname "$0")"
conf="$bin/../conf"

. "$conf/versions.sh"

if [ -z "$OS_APPLICATION_CREDENTIAL_ID" ] || [ -z "$OS_APPLICATION_CREDENTIAL_SECRET" ]
then
    echo >&2 "OS_APPLICATION_CREDENTIAL_ID and OS_APPLICATION_CREDENTIAL_SECRET must be set"
    exit $?
fi

cat "$conf/secret-cinder-csi-system-cloud-config.yaml" \
    | envsubst '$OS_APPLICATION_CREDENTIAL_ID $OS_APPLICATION_CREDENTIAL_SECRET' \
    | kubectl apply --filename=- \
    || exit $?

echo "success: apply secret-cinder-csi-system-cloud-config.yaml"

helm repo add "cloud-provider-openstack" "https://kubernetes.github.io/cloud-provider-openstack" \
    || exit $?

"$bin/upgrade-cinder-csi.sh" || exit $?
apiVersion: v1
kind: Namespace
metadata:
  name: "cinder-csi-system"
---
apiVersion: v1
kind: Secret
metadata:
  namespace: "cinder-csi-system"
  name: "cloud-config"
type: Opaque
stringData:
  cloud.conf: |
    [Global]
    auth-url="https://auth.pscloud.io/v3/"
    application-credential-id="$OS_APPLICATION_CREDENTIAL_ID"
    application-credential-secret="$OS_APPLICATION_CREDENTIAL_SECRET"
    region="kz-ala-1"
    [Metadata]
    search-order="metadataService"
    [BlockStorage]
    rescan-on-resize=true
#!/bin/sh

bin="$(dirname "$0")"
conf="$bin/../conf"

. "$conf/versions.sh"

helm upgrade "cinder-csi" "cloud-provider-openstack/openstack-cinder-csi" \
        --install \
        --namespace="cinder-csi-system" \
        --version "$CINDER_CSI_VERSION" \
        --values "$conf/helm-values-cinder-csi.yaml" \
    || exit $?

echo "success: upgrade cinder-csi"
  1. Устанавливаем ingress-nginx. Ох и поломал я тут голову, как лучше это сделать. И openstack controller устанавливал, чтобы он создавал LoadBalancer-ы автоматом. И через hostNetwork пробовал. Все варианты рабочие.

Но в итоге остановился на самом тупом и топорном.

controller:
  config: { use-proxy-protocol: true }
  ingressClassResource: { default: true }
  replicaCount: 2
  service:
    type: NodePort
    nodePorts:
      http: 30080
      https: 30443

Соответственно создаём отдельно через терраформ второй лоад-балансер и настраиваем его на worker адреса, :80 -> 30080, :443 -> 30443. Также у меня настроен он через протокол PROXYV2, чтобы получать адрес клиента. Nginx его передаёт потом через заголовки X-Forwarder-*.

Вообще можно всё на один лоад балансер повесить (исходный). Но мне показалось правильней сделать несколько. В моём понимании самое важное это обеспечить непрерывность работы control нод. Остальное как-нибудь работать будет. А если, например, внешний дудос перегрузит load balancer, через который общаются все узлы с control plane, то кластер точно развалится нафиг. Правда стоит больше денег. В общем если будете делать - на ваше усмотрение.

Такая конфигурация вносит лишнюю задержку (микроскопическую), вносит лишнюю нагрузку (запрос приходит на load balancer, с него идёт на случайный worker, с него идет на случайный worker, в котором запущен nginx-controller, с него идёт уже на worker, где запущен целевой сервис. Но плюс в том, что всё работает просто и понятно.

Далее устанавливаем cert-manager. Для него нужен cloudflare token. Через DNS домены будет подтверждать.

apiVersion: v1
kind: Namespace
metadata:
  name: "cert-manager"
---
apiVersion: v1
kind: Secret
metadata:
  namespace: "cert-manager"
  name: "cloudflare-api-token"
type: Opaque
stringData:
  "api-token": "$CLOUDFLARE_API_TOKEN"
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: "default"
spec:
  acme:
    email: "me@example.com"
    server: "https://acme-v02.api.letsencrypt.org/directory"
    privateKeySecretRef:
      name: "default-issuer-account-key"
    solvers:
      - dns01:
          cloudflare:
            apiTokenSecretRef:
              name: "cloudflare-api-token"
              key: "api-token"

В принципе на этом настройку основных компонентов кластера считаю завершённой. Пользователь может запрашивать хранилище, пользователь может публиковать свои сервисы через ingress и автоматически получать рабочий https. Пока не разобрался с публикацией произвольных портов, в частности для gitlab нужно будет опубликовать 22 порт, но вроде через тот же ingress-nginx должно работать.

Дальше на очереди установка KeyCloak, настройка kubectl и Dashboard (а в будущем gitlab, grafana) для работы через логин-пароль, но это уже другая история.

Исходная версия vbr, :

В общем ладно, писать сюда уже больше не буду, всё расползлось по куче скриптов и конфигов, в одном месте это всё вываливать уже геморно.

Общая схема, к которой я в итоге пришёл.

  1. Создаётся отдельный внутренний лоад-балансер, слушающий на 10.206.192.99:6443, в пуле которого 10.206.192.9x:6443 (это control planes).

  2. kubeadm init –control-plane-endpoint «10.206.192.99:6443» …

  3. Всё без исключения устанавливается через helm. Все (нужные мне) пакеты поддерживают его из коробки.

  4. Некоторые пакеты требуют секреты. Хотя обычно можно через хельм их создать, я создаю отдельно, чтобы единообразно создавать/обновлять пакеты и не вбивать секреты каждый раз.

  5. Устанавливаем calico, единственный конфиг это { cidr: "10.244.0.0/16", encapsulation: VXLAN }. Убрал ebpf, плохо понимаю, как он работает, не думаю, что замечу разницу.

  6. Добавляем worker-ов или убираем taint с control plane.

  7. Устанавливаем openstack cinder csi. Это потому, что у меня openstack. Кто-нибудь просит persistent volume claim, этот csi создаёт persistent volume. Очень удобно. Сначала создаём секрет, потом устанавливаем хельмом. Приведу полную схему, всё остальное устанавливается так же.

#!/bin/sh

bin="$(dirname "$0")"
conf="$bin/../conf"

. "$conf/versions.sh"

if [ -z "$OS_APPLICATION_CREDENTIAL_ID" ] || [ -z "$OS_APPLICATION_CREDENTIAL_SECRET" ]
then
    echo >&2 "OS_APPLICATION_CREDENTIAL_ID and OS_APPLICATION_CREDENTIAL_SECRET must be set"
    exit $?
fi

cat "$conf/secret-cinder-csi-system-cloud-config.yaml" \
    | envsubst '$OS_APPLICATION_CREDENTIAL_ID $OS_APPLICATION_CREDENTIAL_SECRET' \
    | kubectl apply --filename=- \
    || exit $?

echo "success: apply secret-cinder-csi-system-cloud-config.yaml"

helm repo add "cloud-provider-openstack" "https://kubernetes.github.io/cloud-provider-openstack" \
    || exit $?

"$bin/upgrade-cinder-csi.sh" || exit $?
apiVersion: v1
kind: Namespace
metadata:
  name: "cinder-csi-system"
---
apiVersion: v1
kind: Secret
metadata:
  namespace: "cinder-csi-system"
  name: "cloud-config"
type: Opaque
stringData:
  cloud.conf: |
    [Global]
    auth-url="https://auth.pscloud.io/v3/"
    application-credential-id="$OS_APPLICATION_CREDENTIAL_ID"
    application-credential-secret="$OS_APPLICATION_CREDENTIAL_SECRET"
    region="kz-ala-1"
    [Metadata]
    search-order="metadataService"
    [BlockStorage]
    rescan-on-resize=true
#!/bin/sh

bin="$(dirname "$0")"
conf="$bin/../conf"

. "$conf/versions.sh"

helm upgrade "cinder-csi" "cloud-provider-openstack/openstack-cinder-csi" \
        --install \
        --namespace="cinder-csi-system" \
        --version "$CINDER_CSI_VERSION" \
        --values "$conf/helm-values-cinder-csi.yaml" \
    || exit $?

echo "success: upgrade cinder-csi"
  1. Устанавливаем ingress-nginx. Ох и поломал я тут голову, как лучше это сделать. И openstack controller устанавливал, чтобы он создавал LoadBalancer-ы автоматом. И через hostNetwork пробовал. Все варианты рабочие.

Но в итоге остановился на самом тупом и топорном.

controller:
  config: { use-proxy-protocol: true }
  ingressClassResource: { default: true }
  replicaCount: 2
  service:
    type: NodePort
    nodePorts:
      http: 30080
      https: 30443

Соответственно создаём отдельно через терраформ второй лоад-балансер и настраиваем его на worker адреса, :80 -> 30080, :443 -> 30443. Также у меня настроен он через протокол PROXYV2, чтобы получать адрес клиента. Nginx его передаёт потом через заголовки X-Forwarder-*.

Такая конфигурация вносит лишнюю задержку (микроскопическую), вносит лишнюю нагрузку (запрос приходит на load balancer, с него идёт на случайный worker, с него идет на случайный worker, в котором запущен nginx-controller, с него идёт уже на worker, где запущен целевой сервис. Но плюс в том, что всё работает просто и понятно.

Далее устанавливаем cert-manager. Для него нужен cloudflare token. Через DNS домены будет подтверждать.

apiVersion: v1
kind: Namespace
metadata:
  name: "cert-manager"
---
apiVersion: v1
kind: Secret
metadata:
  namespace: "cert-manager"
  name: "cloudflare-api-token"
type: Opaque
stringData:
  "api-token": "$CLOUDFLARE_API_TOKEN"
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: "default"
spec:
  acme:
    email: "me@example.com"
    server: "https://acme-v02.api.letsencrypt.org/directory"
    privateKeySecretRef:
      name: "default-issuer-account-key"
    solvers:
      - dns01:
          cloudflare:
            apiTokenSecretRef:
              name: "cloudflare-api-token"
              key: "api-token"

В принципе на этом настройку основных компонентов кластера считаю завершённой. Пользователь может запрашивать хранилище, пользователь может публиковать свои сервисы через ingress и автоматически получать рабочий https. Пока не разобрался с публикацией произвольных портов, в частности для gitlab нужно будет опубликовать 22 порт, но вроде через тот же ingress-nginx должно работать.

Дальше на очереди установка KeyCloak, настройка kubectl и Dashboard (а в будущем gitlab, grafana) для работы через логин-пароль, но это уже другая история.