История изменений
Исправление vbr, (текущая версия) :
В общем ладно, писать сюда уже больше не буду, всё расползлось по куче скриптов и конфигов, в одном месте это всё вываливать уже геморно.
Общая схема, к которой я в итоге пришёл.
-
Создаётся отдельный внутренний лоад-балансер, слушающий на 10.206.192.99:6443, в пуле которого 10.206.192.9x:6443 (это control planes).
-
kubeadm init –control-plane-endpoint «10.206.192.99:6443» …
-
Всё без исключения устанавливается через helm. Все (нужные мне) пакеты поддерживают его из коробки.
-
Некоторые пакеты требуют секреты. Хотя обычно можно через хельм их создать, я создаю отдельно, чтобы единообразно создавать/обновлять пакеты и не вбивать секреты каждый раз.
-
Устанавливаем calico, единственный конфиг это
{ cidr: "10.244.0.0/16", encapsulation: VXLAN }
. Убрал ebpf, плохо понимаю, как он работает, не думаю, что замечу разницу. -
Добавляем worker-ов или убираем taint с control plane.
-
Устанавливаем 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"
- Устанавливаем 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, :
В общем ладно, писать сюда уже больше не буду, всё расползлось по куче скриптов и конфигов, в одном месте это всё вываливать уже геморно.
Общая схема, к которой я в итоге пришёл.
-
Создаётся отдельный внутренний лоад-балансер, слушающий на 10.206.192.99:6443, в пуле которого 10.206.192.9x:6443 (это control planes).
-
kubeadm init –control-plane-endpoint «10.206.192.99:6443» …
-
Всё без исключения устанавливается через helm. Все (нужные мне) пакеты поддерживают его из коробки.
-
Некоторые пакеты требуют секреты. Хотя обычно можно через хельм их создать, я создаю отдельно, чтобы единообразно создавать/обновлять пакеты и не вбивать секреты каждый раз.
-
Устанавливаем calico, единственный конфиг это
{ cidr: "10.244.0.0/16", encapsulation: VXLAN }
. Убрал ebpf, плохо понимаю, как он работает, не думаю, что замечу разницу. -
Добавляем worker-ов или убираем taint с control plane.
-
Устанавливаем 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"
- Устанавливаем 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, :
В общем ладно, писать сюда уже больше не буду, всё расползлось по куче скриптов и конфигов, в одном месте это всё вываливать уже геморно.
Общая схема, к которой я в итоге пришёл.
-
Создаётся отдельный внутренний лоад-балансер, слушающий на 10.206.192.99:6443, в пуле которого 10.206.192.9x:6443 (это control planes).
-
kubeadm init –control-plane-endpoint «10.206.192.99:6443» …
-
Всё без исключения устанавливается через helm. Все (нужные мне) пакеты поддерживают его из коробки.
-
Некоторые пакеты требуют секреты. Хотя обычно можно через хельм их создать, я создаю отдельно, чтобы единообразно создавать/обновлять пакеты и не вбивать секреты каждый раз.
-
Устанавливаем calico, единственный конфиг это
{ cidr: "10.244.0.0/16", encapsulation: VXLAN }
. Убрал ebpf, плохо понимаю, как он работает, не думаю, что замечу разницу. -
Добавляем worker-ов или убираем taint с control plane.
-
Устанавливаем 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"
- Устанавливаем 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) для работы через логин-пароль, но это уже другая история.