Запуск кластерів etcd як Kubernetes StatefulSet
Нижче показано, як виконати статичний процес завантаження як Kubernetes StatefulSet.
Приклад маніфесту
Цей маніфест містить сервіс та statefulset для розгортання статичного кластера etcd у Kubernetes.
Якщо ви скопіюєте вміст маніфесту у файл з назвою etcd.yaml
, його можна застосувати до кластера за допомогою цієї команди.
$ kubectl apply --filename etcd.yaml
Після застосування, зачекайте, поки podʼи стануть готовими.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
etcd-0 1/1 Running 0 24m
etcd-1 1/1 Running 0 24m
etcd-2 1/1 Running 0 24m
Контейнер, використаний у прикладі, включає etcdctl і може бути викликаний безпосередньо всередині podʼів.
$ kubectl exec -it etcd-0 -- etcdctl member list -wtable
+------------------+---------+--------+-------------------------+-------------------------+------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER |
+------------------+---------+--------+-------------------------+-------------------------+------------+
| 4f98c3545405a0b0 | started | etcd-2 | http://etcd-2.etcd:2380 | http://etcd-2.etcd:2379 | false |
| a394e0ee91773643 | started | etcd-0 | http://etcd-0.etcd:2380 | http://etcd-0.etcd:2379 | false |
| d10297b8d2f01265 | started | etcd-1 | http://etcd-1.etcd:2380 | http://etcd-1.etcd:2379 | false |
+------------------+---------+--------+-------------------------+-------------------------+------------+
Щоб розгорнути з самопідписним сертифікатом, зверніться до коментованих заголовків конфігурації, що починаються з ## TLS
, щоб знайти значення, які можна розкоментувати. Додаткові інструкції щодо створення сертифіката за допомогою cert-manager наведені в розділі нижче.
# file: etcd.yaml
---
apiVersion: v1
kind: Service
metadata:
name: etcd
namespace: default
spec:
type: ClusterIP
clusterIP: None
selector:
app: etcd
##
## В ідеалі ми мали б використовувати SRV-записи для виявлення однорангових систем для ініціалізації.
## На жаль, виявлення не працюватиме без логіки очікування, поки вони
## заповнять контейнер. Цю проблему відносно легко вирішити шляхом
## внесенням змін, щоб запобігти запуску процесу etcd до того, як записи
## не буде заповнено. У документації до statefulsets коротко описано, як це зробити.
## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id
publishNotReadyAddresses: true
##
## Схема іменування портів клієнта і сервера відповідає схемі, яку використовує etcd
## використовує при виявленні за допомогою SRV-записів.
ports:
- name: etcd-client
port: 2379
- name: etcd-server
port: 2380
- name: etcd-metrics
port: 8080
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
namespace: default
name: etcd
spec:
##
## Імʼя сервісу встановлюється для того, щоб використовувати сервіс headless.
## https://kubernetes.io/docs/concepts/services-networking/service/#headless-services
serviceName: etcd
##
## Якщо ви збільшуєте кількість реплік існуючого кластера, вам слід
## також оновити прапорець --initial-cluster-state, як зазначено нижче у
## конфігурації контейнера.
replicas: 3
##
## Для ініціалізації, podʼів etcd повинні бути доступні один одному до того, як
## як вони будуть "ready" для трафіку. Політика "Parallel" робить це можливим.
podManagementPolicy: Parallel
##
## Для забезпечення доступності кластера etcd, використовується стратегія
## rolling update. Для доступності необхідно, щоб принаймні 51% вузлів etcd
## онлайн у будь-який момент часу.
updateStrategy:
type: RollingUpdate
##
## Це запит міток поверх podʼів, які мають відповідати кількості реплік.
## Він має відповідати міткам шаблону pod. Для отримання додаткової інформації зверніться до
## наступної документації:
## https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
selector:
matchLabels:
app: etcd
##
## Шаблон для конфігурації pod.
template:
metadata:
##
## Маркування тут привʼязано до “matchLabels" цього StatefulSet та
## конфігурації "affinity" podʼа, що буде створено.
##
## Ця схема міток у прикладі підходить для одного кластера etcd на
## простір імен, але якщо вам потрібно декілька кластерів для одного простору імен,
## вам потрібно буде оновити схему міток, щоб вона була унікальною для кожного кластера etcd.
labels:
app: etcd
annotations:
##
## На нього посилаються у конфігурації контейнера etcd як на частину
## імені DNS. Воно має відповідати імені служби, створеної для кластера etcd
## Вирішено розмістити його в анотації, а не у параметрах env
## пояснюється тим, що на одному кластері etcd має бути лише 1 служба.
serviceName: etcd
spec:
##
## Налаштування спорідненості вузлів необхідне для того, щоб etcd-сервери
## не опинилися на одному апаратному забезпеченні.
##
## Докладнішу інформацію про це наведено у документації з планування:
## https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity
affinity:
## podAntiAffinity - це набір правил для планування, які описують
## коли НЕ розміщувати на вузлі pod з цього StatefulSet.
podAntiAffinity:
##
## При підготовці до розміщення podʼа на вузлі, планувальник перевірить
## на наявність інших podʼів, що відповідають правилам, описаним у labelSelector
## відокремлених обраним ключем топології.
requiredDuringSchedulingIgnoredDuringExecution:
## Цей селектор міток шукає app=etcd
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- etcd
## Цей ключ топології позначає спільну мітку, яка використовується на вузлах у
## кластері. Конфігурація podAntiAffinity передбачає, що
## якщо інший pod має мітку app=etcd на вузлі, то
## планувальник не повинен розміщувати на цьому вузлі інший pod.
## https://kubernetes.io/docs/reference/labels-annotations-taints/#kubernetesiohostname
topologyKey: "kubernetes.io/hostname"
##
## Контейнери в podʼі
containers:
## У цьому прикладі є тільки цей контейнер etcd.
- name: etcd
image: quay.io/coreos/etcd:v3.5.15
imagePullPolicy: IfNotPresent
ports:
- name: etcd-client
containerPort: 2379
- name: etcd-server
containerPort: 2380
- name: etcd-metrics
containerPort: 8080
##
## Ці проби не зможуть пройти через TLS для самопідписних сертифікатів, тому etcd
## налаштовано на передачу метрик через порт 8080 і далі.
##
## Як зазначено на сторінці «Моніторинг etcd», /readyz та /livez було
## додано у версії 3.5.12. До цього моніторинг вимагав додаткового інструментарію
## всередині контейнера, щоб змусити ці проби працювати.
##
## Значення у цій перевірці готовності слід додатково перевірити,
## це лише приклад конфігурації.
readinessProbe:
httpGet:
path: /readyz
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 30
## Значення у цій конфігурації слід додатково перевірити, це
## це лише приклад конфігурації.
livenessProbe:
httpGet:
path: /livez
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
env:
##
## Змінні оточення, визначені тут, можуть бути використані іншими частинами
## конфігурації контейнера. Вони інтерпретуються Kubernetes, а не
## у середовищі контейнера.
##
## Ці змінні env передають інформацію про контейнер.
- name: K8S_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: HOSTNAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: SERVICE_NAME
valueFrom:
fieldRef:
fieldPath: metadata.annotations['serviceName']
##
## Налаштування etcdctl всередині контейнера для підключення до вузла etcd
## у контейнері зменшує плутанину під час налагодження.
- name: ETCDCTL_ENDPOINTS
value: $(HOSTNAME).$(SERVICE_NAME):2379
##
## Конфігурація TLS-клієнта для etcdctl у контейнері.
## Шляхи до цих файлів є частиною монтування тому "etcd-client-certs".
# - name: ETCDCTL_KEY
# value: /etc/etcd/certs/client/tls.key
# - name: ETCDCTL_CERT
# value: /etc/etcd/certs/client/tls.crt
# - name: ETCDCTL_CACERT
# value: /etc/etcd/certs/client/ca.crt
##
## Використовуйте це значення URI_SCHEME для не-TLS кластерів.
- name: URI_SCHEME
value: "http"
## TLS: Використовуйте цей URI_SCHEME для кластерів TLS.
# - name: URI_SCHEME
# value: "https"
##
## Якщо ви використовуєте інший контейнер, виконуваний файл може знаходитися у
## іншому місці. У цьому прикладі використано повний шлях, щоб усунути
## двозначності для вас, читача.
## Часто замість "/usr/local/bin/etcd" можна просто використати "etcd", і це
## працюватиме, оскільки у $PATH є тека, яка містить "etcd".
command:
- /usr/local/bin/etcd
##
## Аргументи, що використовуються з командою etcd всередині контейнера.
args:
##
## Вкажіть імʼя сервера etcd.
- --name=$(HOSTNAME)
##
## Налаштуйте etcd на використання постійного сховища, налаштованого нижче.
- --data-dir=/data
##
## У цьому прикладі ми консолідуємо WAL для спільного використання простору з
## текою даних. Це не є ідеальним варіантом у промислових середовищах, і
## слід розміщувати у власному томі.
- --wal-dir=/data/wal
##
## Конфігурації URL-адрес тут параметризовано, і вам не потрібно
## нічого з ними робити.
- --listen-peer-urls=$(URI_SCHEME)://0.0.0.0:2380
- --listen-client-urls=$(URI_SCHEME)://0.0.0.0:2379
- --advertise-client-urls=$(URI_SCHEME)://$(HOSTNAME).$(SERVICE_NAME):2379
##
## Для початкового завантаження кластера має бути встановлено значення "new". Для масштабування
## кластера, цей параметр слід змінити на "existing", коли кількість реплік
## збільшується. Якщо параметр встановлено неправильно, etcd спробує
## запуск, але беспечно зазнає невдачі.
- --initial-cluster-state=new
##
## Токен, який використовується для ініціалізації кластера. Для цього рекомендується
## використовувати унікальний токен для кожного кластера. У цьому прикладі задано параметр
## на унікальність для простору імен, але якщо ви розгортаєте декілька кластерів etcd
## у тому самому просторі імен, вам слід зробити щось додаткове, щоб
## щоб забезпечити унікальність серед кластерів.
- --initial-cluster-token=etcd-$(K8S_NAMESPACE)
##
## Початковий прапорець кластера потрібно оновити відповідно до кількості
## налаштованих реплік. У поєднанні вони трохи важко читаються.
## Ось як виглядає один параметризований одноранговий кластер:
## etcd-0=$(URI_SCHEME)://etcd-0.$(SERVICE_NAME):2380
- --initial-cluster=etcd-0=$(URI_SCHEME)://etcd-0.$(SERVICE_NAME):2380,etcd-1=$(URI_SCHEME)://etcd-1.$(SERVICE_NAME):2380,etcd-2=$(URI_SCHEME)://etcd-2.$(SERVICE_NAME):2380
##
## Прапорець peer urls має бути без змін.
- --initial-advertise-peer-urls=$(URI_SCHEME)://$(HOSTNAME).$(SERVICE_NAME):2380
##
## Це дозволяє уникнути збою проби, якщо ви вирішите налаштувати TLS.
- --listen-metrics-urls=http://0.0.0.0:8080
##
## Ось деякі конфігурації, які ви можете спробувати увімкнути, але
## варто вивчити докладніше, щоб визначити, які налаштування найкраще підходять саме вам.
# - --auto-compaction-mode=periodic
# - --auto-compaction-retention=10m
##
## Конфігурація TLS-клієнта для etcd, повторне використання змінних etcdctl env.
# - --client-cert-auth
# - --trusted-ca-file=$(ETCDCTL_CACERT)
# - --cert-file=$(ETCDCTL_CERT)
# - --key-file=$(ETCDCTL_KEY)
##
## Налаштування сервера TLS для etcdctl у контейнері.
## Шляхи до цих файлів є частиною монтування тому "etcd-server-certs".
# - --peer-client-cert-auth
# - --peer-trusted-ca-file=/etc/etcd/certs/server/ca.crt
# - --peer-cert-file=/etc/etcd/certs/server/tls.crt
# - --peer-key-file=/etc/etcd/certs/server/tls.key
##
## Це конфігурація монтування.
volumeMounts:
- name: etcd-data
mountPath: /data
##
## Конфігурація TLS-клієнта для etcdctl
# - name: etcd-client-tls
# mountPath: "/etc/etcd/certs/client"
# readOnly: true
##
## Конфігурація сервера TLS
# - name: etcd-server-tls
# mountPath: "/etc/etcd/certs/server"
# readOnly: true
volumes:
##
## Конфігурація TLS-клієнта
# - name: etcd-client-tls
# secret:
# secretName: etcd-client-tls
# optional: false
##
## Конфігурація сервера TLS
# - name: etcd-server-tls
# secret:
# secretName: etcd-server-tls
# optional: false
##
## Цей StatefulSet використовує поле volumeClaimTemplate для створення PVC у
## кластері для кожної репліки. Ці PVC не можуть бути легко змінені пізніше.
volumeClaimTemplates:
- metadata:
name: etcd-data
spec:
accessModes: ["ReadWriteOnce"]
##
## У деяких кластерах потрібно явно задавати клас сховища.
## У цьому прикладі буде використано стандартний клас сховища.
# storageClassName: ""
resources:
requests:
storage: 1Gi
Генерація сертифікатів
У цьому розділі ми використовуємо Helm для встановлення оператора з назвою cert-manager.
З встановленим cert-manager у кластері можна генерувати самопідписні сертифікати в кластері. Ці згенеровані сертифікати розміщуються всередині обʼєкта секрету, який можна прикріпити як файли в контейнерах.
Це команда helm для встановлення cert-manager.
$ helm upgrade --install --create-namespace --namespace cert-manager cert-manager cert-manager --repo https://charts.jetstack.io --set crds.enabled=true
Це приклад конфігурації ClusterIssuer для генерації самопідписних сертифікатів.
# file: issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned
spec:
selfSigned: {}
Цей маніфест створює обʼєкти сертифікатів для клієнтських і серверних сертифікатів, посилаючись на ClusterIssuer “selfsigned”. dnsNames повинні бути вичерпним списком дійсних імен хостів для сертифікатів, які створює cert-manager.
# file: certificates.yaml
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: etcd-server
namespace: default
spec:
secretName: etcd-server-tls
issuerRef:
name: selfsigned
kind: ClusterIssuer
commonName: etcd
dnsNames:
- etcd
- etcd.default
- etcd.default.svc.cluster.local
- etcd-0
- etcd-0.etcd
- etcd-0.etcd.default
- etcd-0.etcd.default.svc
- etcd-0.etcd.default.svc.cluster.local
- etcd-1
- etcd-1.etcd
- etcd-1.etcd.default
- etcd-1.etcd.default.svc
- etcd-1.etcd.default.svc.cluster.local
- etcd-2
- etcd-2.etcd
- etcd-2.etcd.default
- etcd-2.etcd.default.svc
- etcd-2.etcd.default.svc.cluster.local
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: etcd-client
namespace: default
spec:
secretName: etcd-client-tls
issuerRef:
name: selfsigned
kind: ClusterIssuer
commonName: etcd
dnsNames:
- etcd
- etcd.default
- etcd.default.svc.cluster.local
- etcd-0
- etcd-0.etcd
- etcd-0.etcd.default
- etcd-0.etcd.default.svc
- etcd-0.etcd.default.svc.cluster.local
- etcd-1
- etcd-1.etcd
- etcd-1.etcd.default
- etcd-1.etcd.default.svc
- etcd-1.etcd.default.svc.cluster.local
- etcd-2
- etcd-2.etcd
- etcd-2.etcd.default
- etcd-2.etcd.default.svc
- etcd-2.etcd.default.svc.cluster.local
Відгук
Чи це було корисним?
Раді чути! Будь ласка, повідомте нам, як ми можемо зробити краще.
Дуже шкода це чути. Будь ласка, повідомте нам, як ми можемо зробити краще.