[ru] Add RU localization - manage-deployment.md
Apply suggestions from code review Co-authored-by: Dmitry Shurupov <dmitry.shurupov@palark.com> Add examples/application files to RUpull/36466/head
parent
e6fe643008
commit
340e974df5
|
|
@ -0,0 +1,452 @@
|
|||
---
|
||||
reviewers:
|
||||
title: Управление ресурсами
|
||||
content_type: concept
|
||||
weight: 40
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
Итак, вы развернули приложение и настроили доступ к нему с помощью сервиса. Что дальше? Kubernetes предоставляет ряд инструментов, помогающих управлять развертыванием приложений, включая их масштабирование и обновление. Среди особенностей, которые мы обсудим более подробно, — [конфигурационные файлы](/docs/concepts/configuration/overview/) и [лейблы](/docs/concepts/overview/working-with-objects/labels/).
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## Организация конфигураций ресурсов
|
||||
|
||||
Многие приложения требуют создания нескольких ресурсов типа Deployment и Service. Управление ими можно упростить, сгруппировав в один YAML-файл (со строкой "---" в качестве разделителя). Например:
|
||||
|
||||
{{< codenew file="application/nginx-app.yaml" >}}
|
||||
|
||||
Можно создавать сразу несколько ресурсов:
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/application/nginx-app.yaml
|
||||
```
|
||||
|
||||
```shell
|
||||
service/my-nginx-svc created
|
||||
deployment.apps/my-nginx created
|
||||
```
|
||||
|
||||
Ресурсы будут создаваться в порядке, в котором они описаны в файле. Таким образом, первым лучше всего описать сервис — это позволит планировщику распределять Pod'ы этого сервиса по мере их создания контроллером (контроллерами), например, Deployment'ом.
|
||||
|
||||
`kubectl apply` также может принимать сразу несколько аргументов `-f`:
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/application/nginx/nginx-svc.yaml -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
|
||||
```
|
||||
|
||||
Кроме того, можно указывать директории вместо отдельных файлов или в дополнение ним:
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/application/nginx/
|
||||
```
|
||||
|
||||
`kubectl` прочитает все файлы с расширениями `.yaml`, `.yml` или `.json`.
|
||||
|
||||
Рекомендуется размещать ресурсы, имеющие отношение к одному микросервису или уровню приложения, в одном файле, а также группировать все файлы, связанные с приложением, в одной директории. Если уровни вашего приложения связываются друг с другом через DNS, можно развернуть все компоненты стека совместно.
|
||||
|
||||
Также в качестве источника конфигурации можно указать URL — это удобно при создании/настройке с использованием конфигурационных файлов, размещенных на GitHub:
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/application/nginx/nginx-deployment.yaml
|
||||
```
|
||||
|
||||
```shell
|
||||
deployment.apps/my-nginx created
|
||||
```
|
||||
|
||||
## Пакетные операции в kubectl
|
||||
|
||||
Создание ресурсов — не единственная операция, которую `kubectl` может выполнять в рамках одной команды. Этот инструмент также способен извлекать имена ресурсов из конфигурационных файлов для выполнения других операций, в частности, для удаления созданных ресурсов:
|
||||
|
||||
```shell
|
||||
kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml
|
||||
```
|
||||
|
||||
```shell
|
||||
deployment.apps "my-nginx" deleted
|
||||
service "my-nginx-svc" deleted
|
||||
```
|
||||
|
||||
В случае двух ресурсов их можно перечислить в командной строке, используя синтаксис вида resource/name:
|
||||
|
||||
```shell
|
||||
kubectl delete deployments/my-nginx services/my-nginx-svc
|
||||
```
|
||||
|
||||
При большем количестве ресурсов удобнее указать селектор (запрос по лейблу) с помощью `-l` или `--selector`, который отфильтрует ресурсы по их лейблам:
|
||||
|
||||
```shell
|
||||
kubectl delete deployment,services -l app=nginx
|
||||
```
|
||||
|
||||
```shell
|
||||
deployment.apps "my-nginx" deleted
|
||||
service "my-nginx-svc" deleted
|
||||
```
|
||||
|
||||
Поскольку `kubectl` выводит имена ресурсов в том же синтаксисе, что и получает, можно выстраивать цепочки операций с помощью `$()` или `xargs`:
|
||||
|
||||
```shell
|
||||
kubectl get $(kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service)
|
||||
kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service | xargs -i kubectl get {}
|
||||
```
|
||||
|
||||
```shell
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
my-nginx-svc LoadBalancer 10.0.0.208 <pending> 80/TCP 0s
|
||||
```
|
||||
|
||||
Приведенные выше команды сначала создают ресурсы в разделе `examples/application/nginx/`, выводят о них информацию в формате `-o name` (то есть в виде пары resource/name). Затем в результатах производится поиск по "service" (`grep`), и информация о найденных ресурсах выводится с помощью `kubectl get`.
|
||||
|
||||
Если ресурсы хранятся в нескольких поддиректориях в пределах одной директории, можно рекурсивно выполнять операции и в этих поддиректориях, указав `--recursive` или `-R` наряду с флагом `--filename`, `-f`.
|
||||
|
||||
Предположим, что существует директория `project/k8s/development`, в которой хранятся все {{< glossary_tooltip text="манифесты" term_id="manifest" >}}, необходимые для dev-окружения, организованные по типу ресурсов:
|
||||
|
||||
```
|
||||
project/k8s/development
|
||||
├── configmap
|
||||
│ └── my-configmap.yaml
|
||||
├── deployment
|
||||
│ └── my-deployment.yaml
|
||||
└── pvc
|
||||
└── my-pvc.yaml
|
||||
```
|
||||
|
||||
По умолчанию при выполнении массовых операций над `project/k8s/development` команда остановится на первом уровне, не обрабатывая поддиректории. К примеру, попытка создать ресурсы, описанные в этой директории, приведет к ошибке:
|
||||
|
||||
```shell
|
||||
kubectl apply -f project/k8s/development
|
||||
```
|
||||
|
||||
```shell
|
||||
error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin)
|
||||
```
|
||||
|
||||
Вместо этого следует указать флаг `--recursive` или `-R` с флагом `--filename`, `-f`:
|
||||
|
||||
```shell
|
||||
kubectl apply -f project/k8s/development --recursive
|
||||
```
|
||||
|
||||
```shell
|
||||
configmap/my-config created
|
||||
deployment.apps/my-deployment created
|
||||
persistentvolumeclaim/my-pvc created
|
||||
```
|
||||
|
||||
Флаг `--recursive` работает с любыми операциями, принимающими флаг `--filename`, `-f`, например: `kubectl {create, get, delete, describe, rollout}` и т.д.
|
||||
|
||||
Флаг `--recursive` также работает для нескольких аргументов `-f`:
|
||||
|
||||
```shell
|
||||
kubectl apply -f project/k8s/namespaces -f project/k8s/development --recursive
|
||||
```
|
||||
|
||||
```shell
|
||||
namespace/development created
|
||||
namespace/staging created
|
||||
configmap/my-config created
|
||||
deployment.apps/my-deployment created
|
||||
persistentvolumeclaim/my-pvc created
|
||||
```
|
||||
|
||||
В разделе [Инструмент командной строки kubectl](/docs/reference/kubectl/) доступна дополнительная информация о `kubectl`.
|
||||
|
||||
## Эффективное использование лейблов
|
||||
|
||||
Во всех примерах, рассмотренных до этого момента, к ресурсам прикреплялся лишь один лейбл. Однако существуют сценарии, когда необходимо использовать несколько лейблов, чтобы отличить наборы ресурсов друг от друга.
|
||||
|
||||
Например, разные приложения могут использовать разные значения для лейбла `app`, а в случае многоуровневого приложения вроде [гостевой книги](https://github.com/kubernetes/examples/tree/master/guestbook/) лейблы могут указывать на соответствующий уровень. Например, у фронтенда могут быть следующие лейблы:
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
```
|
||||
|
||||
в то время как у master'а и slave'а Redis будут лейблы `tier` и, возможно, даже дополнительный лейбл `role`:
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
app: guestbook
|
||||
tier: backend
|
||||
role: master
|
||||
```
|
||||
|
||||
и
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
app: guestbook
|
||||
tier: backend
|
||||
role: slave
|
||||
```
|
||||
|
||||
Лейблы позволяют группировать ресурсы по любому параметру с соответствующим лейблом:
|
||||
|
||||
```shell
|
||||
kubectl apply -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
|
||||
kubectl get pods -Lapp -Ltier -Lrole
|
||||
```
|
||||
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE APP TIER ROLE
|
||||
guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend <none>
|
||||
guestbook-fe-ght6d 1/1 Running 0 1m guestbook frontend <none>
|
||||
guestbook-fe-jpy62 1/1 Running 0 1m guestbook frontend <none>
|
||||
guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master
|
||||
guestbook-redis-slave-2q2yf 1/1 Running 0 1m guestbook backend slave
|
||||
guestbook-redis-slave-qgazl 1/1 Running 0 1m guestbook backend slave
|
||||
my-nginx-divi2 1/1 Running 0 29m nginx <none> <none>
|
||||
my-nginx-o0ef1 1/1 Running 0 29m nginx <none> <none>
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl get pods -lapp=guestbook,role=slave
|
||||
```
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
guestbook-redis-slave-2q2yf 1/1 Running 0 3m
|
||||
guestbook-redis-slave-qgazl 1/1 Running 0 3m
|
||||
```
|
||||
|
||||
## Канареечные развертывания
|
||||
|
||||
Еще один сценарий, в котором применение нескольких лейблов как нельзя кстати, — дифференциация развертываний отдельных релизов или конфигураций одного и того же компонента. Как правило, новая версия приложения (указанная с помощью тега образа в шаблоне Pod'а) запускается в так называемом *канареечном* (canary) развертывании параллельно с предыдущей версией. Далее на нее направляется часть реального production-трафика.
|
||||
|
||||
В примере ниже лейбл `track` помогает различить релизы.
|
||||
|
||||
У основного, стабильного релиза он будет иметь значение `stable`:
|
||||
|
||||
```yaml
|
||||
name: frontend
|
||||
replicas: 3
|
||||
...
|
||||
labels:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
track: stable
|
||||
...
|
||||
image: gb-frontend:v3
|
||||
```
|
||||
|
||||
У нового релиза фронтенда гостевой книги значение этого лейбла будет другим (`canary`), чтобы два набора Pod'ов не пересекались:
|
||||
|
||||
```yaml
|
||||
name: frontend-canary
|
||||
replicas: 1
|
||||
...
|
||||
labels:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
track: canary
|
||||
...
|
||||
image: gb-frontend:v4
|
||||
```
|
||||
|
||||
Чтобы охватить оба набора реплик, сервис фронтенда следует настроить на выбор общего подмножества их лейблов (т.е. опустить лейбл `track`). В результате трафик будет поступать на обе версии приложения:
|
||||
|
||||
```yaml
|
||||
selector:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
```
|
||||
|
||||
При этом число стабильных и канареечных реплик можно менять, регулируя долю production-трафика, которую будет получать каждая версия приложения (три к одному в нашем случае). Убедившись в стабильности новой версии, можно поменять значение ее лейбла `track` с `canary` на `stable`.
|
||||
|
||||
Более подробный пример доступен в [руководстве по развертыванию Ghost](https://github.com/kelseyhightower/talks/tree/master/kubecon-eu-2016/demo#deploy-a-canary).
|
||||
|
||||
## Обновление лейблов
|
||||
|
||||
Иногда возникает необходимость поменять лейблы у существующих Pod'ов и других ресурсов перед созданием новых. Сделать это можно с помощью команды `kubectl label`. Например, чтобы промаркировать все Pod'ы NGINX как имеющие отношение к фронтенду, выполните следующую команду:
|
||||
|
||||
```shell
|
||||
kubectl label pods -l app=nginx tier=fe
|
||||
```
|
||||
|
||||
```shell
|
||||
pod/my-nginx-2035384211-j5fhi labeled
|
||||
pod/my-nginx-2035384211-u2c7e labeled
|
||||
pod/my-nginx-2035384211-u3t6x labeled
|
||||
```
|
||||
|
||||
Сначала она выберет все Pod'ы с лейблом `app=nginx`, а затем пометит их лейблом `tier=fe`. Чтобы просмотреть список этих Pod'ов, выполните:
|
||||
|
||||
```shell
|
||||
kubectl get pods -l app=nginx -L tier
|
||||
```
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE TIER
|
||||
my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe
|
||||
my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe
|
||||
my-nginx-2035384211-u3t6x 1/1 Running 0 23m fe
|
||||
```
|
||||
|
||||
Будут выведены все Pod'ы `app=nginx` с дополнительным столбцом `tier` (задается с помощью `-L` или `--label-columns`).
|
||||
|
||||
Дополнительную информацию можно найти в разделах [Лейблы](/docs/concepts/overview/working-with-objects/labels/) и [kubectl label](/docs/reference/generated/kubectl/kubectl-commands/#label).
|
||||
|
||||
## Обновление аннотаций
|
||||
|
||||
Иногда возникает потребность навесить на ресурсы аннотации. Аннотации — это произвольные неидентифицирующие метаданные для извлечения клиентами API (инструментами, библиотеками и т.п.). Добавить аннотацию можно с помощью команды `kubectl annotate`. Например:
|
||||
|
||||
```shell
|
||||
kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx'
|
||||
kubectl get pods my-nginx-v4-9gw19 -o yaml
|
||||
```
|
||||
|
||||
```shell
|
||||
apiVersion: v1
|
||||
kind: pod
|
||||
metadata:
|
||||
annotations:
|
||||
description: my frontend running nginx
|
||||
...
|
||||
```
|
||||
|
||||
Для получения дополнительной информации обратитесь к разделу [Аннотации](/docs/concepts/overview/working-with-objects/annotations/) и описанию команды [kubectl annotate](/docs/reference/generated/kubectl/kubectl-commands/#annotate).
|
||||
|
||||
## Масштабирование приложения
|
||||
|
||||
Для масштабирования приложения можно воспользоваться инструментом `kubectl`. Например, следующая команда уменьшит число реплик с 3 до 1:
|
||||
|
||||
```shell
|
||||
kubectl scale deployment/my-nginx --replicas=1
|
||||
```
|
||||
|
||||
```shell
|
||||
deployment.apps/my-nginx scaled
|
||||
```
|
||||
|
||||
После ее применения количество Pod'ов под управлением соответствующего объекта Deployment сократится до одного:
|
||||
|
||||
```shell
|
||||
kubectl get pods -l app=nginx
|
||||
```
|
||||
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
my-nginx-2035384211-j5fhi 1/1 Running 0 30m
|
||||
```
|
||||
|
||||
Чтобы система автоматически выбирала необходимое количество реплик NGINX в диапазоне от 1 до 3, выполните следующую команду:
|
||||
|
||||
```shell
|
||||
kubectl autoscale deployment/my-nginx --min=1 --max=3
|
||||
```
|
||||
|
||||
```shell
|
||||
horizontalpodautoscaler.autoscaling/my-nginx autoscaled
|
||||
```
|
||||
|
||||
Теперь количество реплик NGINX будет автоматически увеличиваться и уменьшаться по мере необходимости.
|
||||
|
||||
Для получения дополнительной информации см. разделы [kubectl scale](/docs/reference/generated/kubectl/kubectl-commands/#scale), [kubectl autoscale](/docs/reference/generated/kubectl/kubectl-commands/#autoscale) и [horizontal pod autoscaler](/docs/tasks/run-application/horizontal-pod-autoscale/).
|
||||
|
||||
## Обновление ресурсов "на месте"
|
||||
|
||||
Иногда возникает необходимость внести мелкие обновления в созданные ресурсы, не требующие их пересоздания.
|
||||
|
||||
### kubectl apply
|
||||
|
||||
Хранить конфигурационные файлы рекомендуемтся в системе контроля версий (см. [конфигурация как код](https://martinfowler.com/bliki/InfrastructureAsCode.html)). В этом случае их можно будет поддерживать и версионировать вместе с кодом ресурсов, которые те конфигурируют. Далее с помощью команды [`kubectl apply`](/docs/reference/generated/kubectl/kubectl-commands/#apply) изменения, внесенные в конфигурацию, можно применить к кластеру.
|
||||
|
||||
Она сравнит новую версию конфигурации с предыдущей и применит внесенные изменения, не меняя параметры, установленные автоматически, не затронутые новой редакцией конфигурации.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
|
||||
deployment.apps/my-nginx configured
|
||||
```
|
||||
|
||||
Обратите внимание, что `kubectl apply` добавляет к ресурсу аннотацию, помогающую отслеживать изменения в конфигурации с момента предыдущего вызова. При вызове `kubectl apply` проводит трехстороннее сравнение (three-way diff) предыдущей конфигурации, ее текущей и новой версий, которое определяет, какие правки следует внести в ресурс.
|
||||
|
||||
На данный момент ресурсы в Kubernetes создаются без данной аннотации, поэтому при первом вызове `kubectl apply` проведет двустороннее сравнение входных данных и текущей конфигурации ресурса. Кроме того, она не cможет определить, какие свойства, заданные при создании ресурса, требуют удаления (соответственно, не будет их удалять).
|
||||
|
||||
При всех последующих вызовах `kubectl apply` и других команд, меняющих конфигурацию, таких как `kubectl replace` и `kubectl edit`, аннотация будет обновляться. В результате `kubectl apply` сможет проводить трехстороннее сравнение (three-way diff), определяя, какие свойства требуют удаления, и удалять их.
|
||||
|
||||
### kubectl edit
|
||||
|
||||
Ресурсы также можно обновлять с помощью команды `kubectl edit`:
|
||||
|
||||
```shell
|
||||
kubectl edit deployment/my-nginx
|
||||
```
|
||||
|
||||
По сути, `kubectl edit` объединяет в себе логику нескольких команд, упрощая жизнь пользователям: сначала она получает (`get`) ресурс, вызывает текстовый редактор, а затем применяет (`apply`) обновленную конфигурацию:
|
||||
|
||||
```shell
|
||||
kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml
|
||||
vi /tmp/nginx.yaml
|
||||
# внесите правки и сохраните файл
|
||||
|
||||
kubectl apply -f /tmp/nginx.yaml
|
||||
deployment.apps/my-nginx configured
|
||||
|
||||
rm /tmp/nginx.yaml
|
||||
```
|
||||
|
||||
Обратите внимание, что задать предпочитаемый текстовый редактор можно с помощью переменных окружения `EDITOR` или `KUBE_EDITOR`.
|
||||
|
||||
За дополнительной информацией обратитесь к разделу [kubectl edit](/docs/reference/generated/kubectl/kubectl-commands/#edit).
|
||||
|
||||
### kubectl patch
|
||||
|
||||
Команда `kubectl patch` обновляет объекты API "на месте". Она поддерживает форматы JSON patch, JSON merge patch и strategic merge patch. См. разделы [Обновление объектов API "на месте" с помощью kubectl patch](/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/) и [kubectl patch](/docs/reference/generated/kubectl/kubectl-commands/#patch).
|
||||
|
||||
## Обновления, требующие перерыва в работе
|
||||
|
||||
Иногда может понадобиться обновить поля ресурса, которые нельзя изменить после инициализации, или возникнет необходимость немедленно внести рекурсивные изменения, например, "починить" сбойные Pod'ы, созданные Deployment'ом. Для этого можно воспользоваться командой `replace --force`, которая удалит и пересоздаст ресурс. Вот как можно внести правки в исходный файл конфигурации в нашем примере:
|
||||
|
||||
```shell
|
||||
kubectl replace -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml --force
|
||||
```
|
||||
|
||||
```shell
|
||||
deployment.apps/my-nginx deleted
|
||||
deployment.apps/my-nginx replaced
|
||||
```
|
||||
|
||||
## Обновление приложения без перерыва в работе
|
||||
|
||||
В какой-то момент возникнет необходимость обновить развернутое приложение. Обычно это делают, указывая новый образ или тег образа, как в приведенном выше сценарии канареечного развертывания. `kubectl` поддерживает несколько видов обновлений, каждый из которых подходит для разных сценариев.
|
||||
|
||||
Ниже будет рассказано, как создавать и обновлять приложения с помощью объектов Deployment.
|
||||
|
||||
Предположим, что в кластере используется версия NGINX 1.14.2:
|
||||
|
||||
```shell
|
||||
kubectl create deployment my-nginx --image=nginx:1.14.2
|
||||
```
|
||||
|
||||
```shell
|
||||
deployment.apps/my-nginx created
|
||||
```
|
||||
|
||||
с тремя репликами (чтобы старые и новые ревизии могли сосуществовать):
|
||||
|
||||
```shell
|
||||
kubectl scale deployment my-nginx --current-replicas=1 --replicas=3
|
||||
```
|
||||
|
||||
```
|
||||
deployment.apps/my-nginx scaled
|
||||
```
|
||||
|
||||
Чтобы перейти на версию 1.16.1, измените значение параметра `.spec.template.spec.containers[0].image` с `nginx:1.14.2` на `nginx:1.16.1`:
|
||||
|
||||
```shell
|
||||
kubectl edit deployment/my-nginx
|
||||
```
|
||||
|
||||
Вот и все! Deployment декларативно обновит развернутое приложение NGINX "за кулисами". При этом Kubernetes проследит, чтобы число недоступных реплик в каждый момент времени не превышало определенного значения, а также за тем, чтобы количество новых реплик не превышало определенного предела, установленного для желаемого числа Pod'ов. Более подробную информацию об этом можно получить в разделе [Deployment](/docs/concepts/workloads/controllers/deployment/).
|
||||
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
|
||||
- Узнайте о том, [как использовать `kubectl` для интроспекции и отладки приложений](/docs/tasks/debug/debug-application/debug-running-pod/).
|
||||
- Ознакомьтесь с [Лучшими практиками и советами по конфигурированию](/docs/concepts/configuration/overview/).
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: cassandra
|
||||
name: cassandra
|
||||
spec:
|
||||
clusterIP: None
|
||||
ports:
|
||||
- port: 9042
|
||||
selector:
|
||||
app: cassandra
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: cassandra
|
||||
labels:
|
||||
app: cassandra
|
||||
spec:
|
||||
serviceName: cassandra
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cassandra
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: cassandra
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 1800
|
||||
containers:
|
||||
- name: cassandra
|
||||
image: gcr.io/google-samples/cassandra:v13
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 7000
|
||||
name: intra-node
|
||||
- containerPort: 7001
|
||||
name: tls-intra-node
|
||||
- containerPort: 7199
|
||||
name: jmx
|
||||
- containerPort: 9042
|
||||
name: cql
|
||||
resources:
|
||||
limits:
|
||||
cpu: "500m"
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: "500m"
|
||||
memory: 1Gi
|
||||
securityContext:
|
||||
capabilities:
|
||||
add:
|
||||
- IPC_LOCK
|
||||
lifecycle:
|
||||
preStop:
|
||||
exec:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- nodetool drain
|
||||
env:
|
||||
- name: MAX_HEAP_SIZE
|
||||
value: 512M
|
||||
- name: HEAP_NEWSIZE
|
||||
value: 100M
|
||||
- name: CASSANDRA_SEEDS
|
||||
value: "cassandra-0.cassandra.default.svc.cluster.local"
|
||||
- name: CASSANDRA_CLUSTER_NAME
|
||||
value: "K8Demo"
|
||||
- name: CASSANDRA_DC
|
||||
value: "DC1-K8Demo"
|
||||
- name: CASSANDRA_RACK
|
||||
value: "Rack1-K8Demo"
|
||||
- name: POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- /bin/bash
|
||||
- -c
|
||||
- /ready-probe.sh
|
||||
initialDelaySeconds: 15
|
||||
timeoutSeconds: 5
|
||||
# These volume mounts are persistent. They are like inline claims,
|
||||
# but not exactly because the names need to match exactly one of
|
||||
# the stateful pod volumes.
|
||||
volumeMounts:
|
||||
- name: cassandra-data
|
||||
mountPath: /cassandra_data
|
||||
# These are converted to volume claims by the controller
|
||||
# and mounted at the paths mentioned above.
|
||||
# do not use these in production until ssd GCEPersistentDisk or other ssd pd
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: cassandra-data
|
||||
spec:
|
||||
accessModes: [ "ReadWriteOnce" ]
|
||||
storageClassName: fast
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
---
|
||||
kind: StorageClass
|
||||
apiVersion: storage.k8s.io/v1
|
||||
metadata:
|
||||
name: fast
|
||||
provisioner: k8s.io/minikube-hostpath
|
||||
parameters:
|
||||
type: pd-ssd
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: patch-demo
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: patch-demo-ctr
|
||||
image: nginx
|
||||
tolerations:
|
||||
- effect: NoSchedule
|
||||
key: dedicated
|
||||
value: test-team
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: retainkeys-demo
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 30%
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: retainkeys-demo-ctr
|
||||
image: nginx
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
replicas: 4 # Update the replicas from 2 to 4
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
replicas: 2
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.16.1 # Update the version of nginx from 1.14.2 to 1.16.1
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: apps/v1 # до версии 1.9.0 нужно использовать apps/v1beta2
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
|
|
@ -6,7 +6,7 @@ spec:
|
|||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
replicas: 2 # запускает 2 пода, созданных по шаблону
|
||||
replicas: 2 # tells deployment to run 2 pods matching the template
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: frontend
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: php-redis
|
||||
image: gcr.io/google_samples/gb-frontend:v5
|
||||
env:
|
||||
- name: GET_HOSTS_FROM
|
||||
value: "dns"
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: frontend
|
||||
labels:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
spec:
|
||||
# if your cluster supports it, uncomment the following to automatically create
|
||||
# an external load-balanced IP for the frontend service.
|
||||
# type: LoadBalancer
|
||||
#type: LoadBalancer
|
||||
ports:
|
||||
# the port that this service should serve on
|
||||
- port: 80
|
||||
selector:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis-follower
|
||||
labels:
|
||||
app: redis
|
||||
role: follower
|
||||
tier: backend
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
role: follower
|
||||
tier: backend
|
||||
spec:
|
||||
containers:
|
||||
- name: follower
|
||||
image: gcr.io/google_samples/gb-redis-follower:v2
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redis-follower
|
||||
labels:
|
||||
app: redis
|
||||
role: follower
|
||||
tier: backend
|
||||
spec:
|
||||
ports:
|
||||
# the port that this service should serve on
|
||||
- port: 6379
|
||||
selector:
|
||||
app: redis
|
||||
role: follower
|
||||
tier: backend
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis-leader
|
||||
labels:
|
||||
app: redis
|
||||
role: leader
|
||||
tier: backend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
role: leader
|
||||
tier: backend
|
||||
spec:
|
||||
containers:
|
||||
- name: leader
|
||||
image: "docker.io/redis:6.0.5"
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redis-leader
|
||||
labels:
|
||||
app: redis
|
||||
role: leader
|
||||
tier: backend
|
||||
spec:
|
||||
ports:
|
||||
- port: 6379
|
||||
targetPort: 6379
|
||||
selector:
|
||||
app: redis
|
||||
role: leader
|
||||
tier: backend
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
apiVersion: autoscaling/v1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: php-apache
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: php-apache
|
||||
minReplicas: 1
|
||||
maxReplicas: 10
|
||||
targetCPUUtilizationPercentage: 50
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: hello
|
||||
spec:
|
||||
schedule: "* * * * *"
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: hello
|
||||
image: busybox:1.28
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- date; echo Hello from the Kubernetes cluster
|
||||
restartPolicy: OnFailure
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: 'indexed-job'
|
||||
spec:
|
||||
completions: 5
|
||||
parallelism: 3
|
||||
completionMode: Indexed
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: 'worker'
|
||||
image: 'docker.io/library/busybox'
|
||||
command:
|
||||
- "rev"
|
||||
- "/input/data.txt"
|
||||
volumeMounts:
|
||||
- mountPath: /input
|
||||
name: input
|
||||
volumes:
|
||||
- name: input
|
||||
downwardAPI:
|
||||
items:
|
||||
- path: "data.txt"
|
||||
fieldRef:
|
||||
fieldPath: metadata.annotations['batch.kubernetes.io/job-completion-index']
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: 'indexed-job'
|
||||
spec:
|
||||
completions: 5
|
||||
parallelism: 3
|
||||
completionMode: Indexed
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
initContainers:
|
||||
- name: 'input'
|
||||
image: 'docker.io/library/bash'
|
||||
command:
|
||||
- "bash"
|
||||
- "-c"
|
||||
- |
|
||||
items=(foo bar baz qux xyz)
|
||||
echo ${items[$JOB_COMPLETION_INDEX]} > /input/data.txt
|
||||
volumeMounts:
|
||||
- mountPath: /input
|
||||
name: input
|
||||
containers:
|
||||
- name: 'worker'
|
||||
image: 'docker.io/library/busybox'
|
||||
command:
|
||||
- "rev"
|
||||
- "/input/data.txt"
|
||||
volumeMounts:
|
||||
- mountPath: /input
|
||||
name: input
|
||||
volumes:
|
||||
- name: input
|
||||
emptyDir: {}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: process-item-$ITEM
|
||||
labels:
|
||||
jobgroup: jobexample
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
name: jobexample
|
||||
labels:
|
||||
jobgroup: jobexample
|
||||
spec:
|
||||
containers:
|
||||
- name: c
|
||||
image: busybox:1.28
|
||||
command: ["sh", "-c", "echo Processing item $ITEM && sleep 5"]
|
||||
restartPolicy: Never
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# Specify BROKER_URL and QUEUE when running
|
||||
FROM ubuntu:18.04
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y curl ca-certificates amqp-tools python \
|
||||
--no-install-recommends \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
COPY ./worker.py /worker.py
|
||||
|
||||
CMD /usr/bin/amqp-consume --url=$BROKER_URL -q $QUEUE -c 1 /worker.py
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: job-wq-1
|
||||
spec:
|
||||
completions: 8
|
||||
parallelism: 2
|
||||
template:
|
||||
metadata:
|
||||
name: job-wq-1
|
||||
spec:
|
||||
containers:
|
||||
- name: c
|
||||
image: gcr.io/<project>/job-wq-1
|
||||
env:
|
||||
- name: BROKER_URL
|
||||
value: amqp://guest:guest@rabbitmq-service:5672
|
||||
- name: QUEUE
|
||||
value: job1
|
||||
restartPolicy: OnFailure
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Just prints standard out and sleeps for 10 seconds.
|
||||
import sys
|
||||
import time
|
||||
print("Processing " + sys.stdin.readlines()[0])
|
||||
time.sleep(10)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
FROM python
|
||||
RUN pip install redis
|
||||
COPY ./worker.py /worker.py
|
||||
COPY ./rediswq.py /rediswq.py
|
||||
|
||||
CMD python worker.py
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: job-wq-2
|
||||
spec:
|
||||
parallelism: 2
|
||||
template:
|
||||
metadata:
|
||||
name: job-wq-2
|
||||
spec:
|
||||
containers:
|
||||
- name: c
|
||||
image: gcr.io/myproject/job-wq-2
|
||||
restartPolicy: OnFailure
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: redis-master
|
||||
labels:
|
||||
app: redis
|
||||
spec:
|
||||
containers:
|
||||
- name: master
|
||||
image: redis
|
||||
env:
|
||||
- name: MASTER
|
||||
value: "true"
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redis
|
||||
spec:
|
||||
ports:
|
||||
- port: 6379
|
||||
targetPort: 6379
|
||||
selector:
|
||||
app: redis
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Based on http://peter-hoffmann.com/2012/python-simple-queue-redis-queue.html
|
||||
# and the suggestion in the redis documentation for RPOPLPUSH, at
|
||||
# http://redis.io/commands/rpoplpush, which suggests how to implement a work-queue.
|
||||
|
||||
|
||||
import redis
|
||||
import uuid
|
||||
import hashlib
|
||||
|
||||
class RedisWQ(object):
|
||||
"""Simple Finite Work Queue with Redis Backend
|
||||
|
||||
This work queue is finite: as long as no more work is added
|
||||
after workers start, the workers can detect when the queue
|
||||
is completely empty.
|
||||
|
||||
The items in the work queue are assumed to have unique values.
|
||||
|
||||
This object is not intended to be used by multiple threads
|
||||
concurrently.
|
||||
"""
|
||||
def __init__(self, name, **redis_kwargs):
|
||||
"""The default connection parameters are: host='localhost', port=6379, db=0
|
||||
|
||||
The work queue is identified by "name". The library may create other
|
||||
keys with "name" as a prefix.
|
||||
"""
|
||||
self._db = redis.StrictRedis(**redis_kwargs)
|
||||
# The session ID will uniquely identify this "worker".
|
||||
self._session = str(uuid.uuid4())
|
||||
# Work queue is implemented as two queues: main, and processing.
|
||||
# Work is initially in main, and moved to processing when a client picks it up.
|
||||
self._main_q_key = name
|
||||
self._processing_q_key = name + ":processing"
|
||||
self._lease_key_prefix = name + ":leased_by_session:"
|
||||
|
||||
def sessionID(self):
|
||||
"""Return the ID for this session."""
|
||||
return self._session
|
||||
|
||||
def _main_qsize(self):
|
||||
"""Return the size of the main queue."""
|
||||
return self._db.llen(self._main_q_key)
|
||||
|
||||
def _processing_qsize(self):
|
||||
"""Return the size of the main queue."""
|
||||
return self._db.llen(self._processing_q_key)
|
||||
|
||||
def empty(self):
|
||||
"""Return True if the queue is empty, including work being done, False otherwise.
|
||||
|
||||
False does not necessarily mean that there is work available to work on right now,
|
||||
"""
|
||||
return self._main_qsize() == 0 and self._processing_qsize() == 0
|
||||
|
||||
# TODO: implement this
|
||||
# def check_expired_leases(self):
|
||||
# """Return to the work queueReturn True if the queue is empty, False otherwise."""
|
||||
# # Processing list should not be _too_ long since it is approximately as long
|
||||
# # as the number of active and recently active workers.
|
||||
# processing = self._db.lrange(self._processing_q_key, 0, -1)
|
||||
# for item in processing:
|
||||
# # If the lease key is not present for an item (it expired or was
|
||||
# # never created because the client crashed before creating it)
|
||||
# # then move the item back to the main queue so others can work on it.
|
||||
# if not self._lease_exists(item):
|
||||
# TODO: transactionally move the key from processing queue to
|
||||
# to main queue, while detecting if a new lease is created
|
||||
# or if either queue is modified.
|
||||
|
||||
def _itemkey(self, item):
|
||||
"""Returns a string that uniquely identifies an item (bytes)."""
|
||||
return hashlib.sha224(item).hexdigest()
|
||||
|
||||
def _lease_exists(self, item):
|
||||
"""True if a lease on 'item' exists."""
|
||||
return self._db.exists(self._lease_key_prefix + self._itemkey(item))
|
||||
|
||||
def lease(self, lease_secs=60, block=True, timeout=None):
|
||||
"""Begin working on an item the work queue.
|
||||
|
||||
Lease the item for lease_secs. After that time, other
|
||||
workers may consider this client to have crashed or stalled
|
||||
and pick up the item instead.
|
||||
|
||||
If optional args block is true and timeout is None (the default), block
|
||||
if necessary until an item is available."""
|
||||
if block:
|
||||
item = self._db.brpoplpush(self._main_q_key, self._processing_q_key, timeout=timeout)
|
||||
else:
|
||||
item = self._db.rpoplpush(self._main_q_key, self._processing_q_key)
|
||||
if item:
|
||||
# Record that we (this session id) are working on a key. Expire that
|
||||
# note after the lease timeout.
|
||||
# Note: if we crash at this line of the program, then GC will see no lease
|
||||
# for this item a later return it to the main queue.
|
||||
itemkey = self._itemkey(item)
|
||||
self._db.setex(self._lease_key_prefix + itemkey, lease_secs, self._session)
|
||||
return item
|
||||
|
||||
def complete(self, value):
|
||||
"""Complete working on the item with 'value'.
|
||||
|
||||
If the lease expired, the item may not have completed, and some
|
||||
other worker may have picked it up. There is no indication
|
||||
of what happened.
|
||||
"""
|
||||
self._db.lrem(self._processing_q_key, 0, value)
|
||||
# If we crash here, then the GC code will try to move the value, but it will
|
||||
# not be here, which is fine. So this does not need to be a transaction.
|
||||
itemkey = self._itemkey(value)
|
||||
self._db.delete(self._lease_key_prefix + itemkey)
|
||||
|
||||
# TODO: add functions to clean up all keys associated with "name" when
|
||||
# processing is complete.
|
||||
|
||||
# TODO: add a function to add an item to the queue. Atomically
|
||||
# check if the queue is empty and if so fail to add the item
|
||||
# since other workers might think work is done and be in the process
|
||||
# of exiting.
|
||||
|
||||
# TODO(etune): move to my own github for hosting, e.g. github.com/erictune/rediswq-py and
|
||||
# make it so it can be pip installed by anyone (see
|
||||
# http://stackoverflow.com/questions/8247605/configuring-so-that-pip-install-can-work-from-github)
|
||||
|
||||
# TODO(etune): finish code to GC expired leases, and call periodically
|
||||
# e.g. each time lease times out.
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import time
|
||||
import rediswq
|
||||
|
||||
host="redis"
|
||||
# Uncomment next two lines if you do not have Kube-DNS working.
|
||||
# import os
|
||||
# host = os.getenv("REDIS_SERVICE_HOST")
|
||||
|
||||
q = rediswq.RedisWQ(name="job2", host=host)
|
||||
print("Worker with sessionID: " + q.sessionID())
|
||||
print("Initial queue state: empty=" + str(q.empty()))
|
||||
while not q.empty():
|
||||
item = q.lease(lease_secs=10, block=True, timeout=2)
|
||||
if item is not None:
|
||||
itemstr = item.decode("utf-8")
|
||||
print("Working on " + itemstr)
|
||||
time.sleep(10) # Put your actual work here instead of sleep.
|
||||
q.complete(item)
|
||||
else:
|
||||
print("Waiting for work")
|
||||
print("Queue empty, exiting")
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mongo
|
||||
labels:
|
||||
app.kubernetes.io/name: mongo
|
||||
app.kubernetes.io/component: backend
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: mongo
|
||||
app.kubernetes.io/component: backend
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: mongo
|
||||
app.kubernetes.io/component: backend
|
||||
spec:
|
||||
containers:
|
||||
- name: mongo
|
||||
image: mongo:4.2
|
||||
args:
|
||||
- --bind_ip
|
||||
- 0.0.0.0
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
ports:
|
||||
- containerPort: 27017
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mongo
|
||||
labels:
|
||||
app.kubernetes.io/name: mongo
|
||||
app.kubernetes.io/component: backend
|
||||
spec:
|
||||
ports:
|
||||
- port: 27017
|
||||
targetPort: 27017
|
||||
selector:
|
||||
app.kubernetes.io/name: mongo
|
||||
app.kubernetes.io/component: backend
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
app: mysql
|
||||
app.kubernetes.io/name: mysql
|
||||
data:
|
||||
primary.cnf: |
|
||||
# Apply this config only on the primary.
|
||||
[mysqld]
|
||||
log-bin
|
||||
replica.cnf: |
|
||||
# Apply this config only on replicas.
|
||||
[mysqld]
|
||||
super-read-only
|
||||
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
ports:
|
||||
- port: 3306
|
||||
selector:
|
||||
app: mysql
|
||||
clusterIP: None
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mysql
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mysql
|
||||
spec:
|
||||
containers:
|
||||
- image: mysql:5.6
|
||||
name: mysql
|
||||
env:
|
||||
# Use secret in real usage
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
value: password
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
name: mysql
|
||||
volumeMounts:
|
||||
- name: mysql-persistent-storage
|
||||
mountPath: /var/lib/mysql
|
||||
volumes:
|
||||
- name: mysql-persistent-storage
|
||||
persistentVolumeClaim:
|
||||
claimName: mysql-pv-claim
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: mysql-pv-volume
|
||||
labels:
|
||||
type: local
|
||||
spec:
|
||||
storageClassName: manual
|
||||
capacity:
|
||||
storage: 20Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
hostPath:
|
||||
path: "/mnt/data"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mysql-pv-claim
|
||||
spec:
|
||||
storageClassName: manual
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# Headless service for stable DNS entries of StatefulSet members.
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
app: mysql
|
||||
app.kubernetes.io/name: mysql
|
||||
spec:
|
||||
ports:
|
||||
- name: mysql
|
||||
port: 3306
|
||||
clusterIP: None
|
||||
selector:
|
||||
app: mysql
|
||||
---
|
||||
# Client service for connecting to any MySQL instance for reads.
|
||||
# For writes, you must instead connect to the primary: mysql-0.mysql.
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mysql-read
|
||||
labels:
|
||||
app: mysql
|
||||
app.kubernetes.io/name: mysql
|
||||
readonly: "true"
|
||||
spec:
|
||||
ports:
|
||||
- name: mysql
|
||||
port: 3306
|
||||
selector:
|
||||
app: mysql
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mysql
|
||||
app.kubernetes.io/name: mysql
|
||||
serviceName: mysql
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mysql
|
||||
app.kubernetes.io/name: mysql
|
||||
spec:
|
||||
initContainers:
|
||||
- name: init-mysql
|
||||
image: mysql:5.7
|
||||
command:
|
||||
- bash
|
||||
- "-c"
|
||||
- |
|
||||
set -ex
|
||||
# Generate mysql server-id from pod ordinal index.
|
||||
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
|
||||
ordinal=${BASH_REMATCH[1]}
|
||||
echo [mysqld] > /mnt/conf.d/server-id.cnf
|
||||
# Add an offset to avoid reserved server-id=0 value.
|
||||
echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
|
||||
# Copy appropriate conf.d files from config-map to emptyDir.
|
||||
if [[ $ordinal -eq 0 ]]; then
|
||||
cp /mnt/config-map/primary.cnf /mnt/conf.d/
|
||||
else
|
||||
cp /mnt/config-map/replica.cnf /mnt/conf.d/
|
||||
fi
|
||||
volumeMounts:
|
||||
- name: conf
|
||||
mountPath: /mnt/conf.d
|
||||
- name: config-map
|
||||
mountPath: /mnt/config-map
|
||||
- name: clone-mysql
|
||||
image: gcr.io/google-samples/xtrabackup:1.0
|
||||
command:
|
||||
- bash
|
||||
- "-c"
|
||||
- |
|
||||
set -ex
|
||||
# Skip the clone if data already exists.
|
||||
[[ -d /var/lib/mysql/mysql ]] && exit 0
|
||||
# Skip the clone on primary (ordinal index 0).
|
||||
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
|
||||
ordinal=${BASH_REMATCH[1]}
|
||||
[[ $ordinal -eq 0 ]] && exit 0
|
||||
# Clone data from previous peer.
|
||||
ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
|
||||
# Prepare the backup.
|
||||
xtrabackup --prepare --target-dir=/var/lib/mysql
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/mysql
|
||||
subPath: mysql
|
||||
- name: conf
|
||||
mountPath: /etc/mysql/conf.d
|
||||
containers:
|
||||
- name: mysql
|
||||
image: mysql:5.7
|
||||
env:
|
||||
- name: MYSQL_ALLOW_EMPTY_PASSWORD
|
||||
value: "1"
|
||||
ports:
|
||||
- name: mysql
|
||||
containerPort: 3306
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/mysql
|
||||
subPath: mysql
|
||||
- name: conf
|
||||
mountPath: /etc/mysql/conf.d
|
||||
resources:
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
livenessProbe:
|
||||
exec:
|
||||
command: ["mysqladmin", "ping"]
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
readinessProbe:
|
||||
exec:
|
||||
# Check we can execute queries over TCP (skip-networking is off).
|
||||
command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 2
|
||||
timeoutSeconds: 1
|
||||
- name: xtrabackup
|
||||
image: gcr.io/google-samples/xtrabackup:1.0
|
||||
ports:
|
||||
- name: xtrabackup
|
||||
containerPort: 3307
|
||||
command:
|
||||
- bash
|
||||
- "-c"
|
||||
- |
|
||||
set -ex
|
||||
cd /var/lib/mysql
|
||||
|
||||
# Determine binlog position of cloned data, if any.
|
||||
if [[ -f xtrabackup_slave_info && "x$(<xtrabackup_slave_info)" != "x" ]]; then
|
||||
# XtraBackup already generated a partial "CHANGE MASTER TO" query
|
||||
# because we're cloning from an existing replica. (Need to remove the tailing semicolon!)
|
||||
cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql.in
|
||||
# Ignore xtrabackup_binlog_info in this case (it's useless).
|
||||
rm -f xtrabackup_slave_info xtrabackup_binlog_info
|
||||
elif [[ -f xtrabackup_binlog_info ]]; then
|
||||
# We're cloning directly from primary. Parse binlog position.
|
||||
[[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
|
||||
rm -f xtrabackup_binlog_info xtrabackup_slave_info
|
||||
echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
|
||||
MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
|
||||
fi
|
||||
|
||||
# Check if we need to complete a clone by starting replication.
|
||||
if [[ -f change_master_to.sql.in ]]; then
|
||||
echo "Waiting for mysqld to be ready (accepting connections)"
|
||||
until mysql -h 127.0.0.1 -e "SELECT 1"; do sleep 1; done
|
||||
|
||||
echo "Initializing replication from clone position"
|
||||
mysql -h 127.0.0.1 \
|
||||
-e "$(<change_master_to.sql.in), \
|
||||
MASTER_HOST='mysql-0.mysql', \
|
||||
MASTER_USER='root', \
|
||||
MASTER_PASSWORD='', \
|
||||
MASTER_CONNECT_RETRY=10; \
|
||||
START SLAVE;" || exit 1
|
||||
# In case of container restart, attempt this at-most-once.
|
||||
mv change_master_to.sql.in change_master_to.sql.orig
|
||||
fi
|
||||
|
||||
# Start a server to send backups when requested by peers.
|
||||
exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
|
||||
"xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root"
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/mysql
|
||||
subPath: mysql
|
||||
- name: conf
|
||||
mountPath: /etc/mysql/conf.d
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
volumes:
|
||||
- name: conf
|
||||
emptyDir: {}
|
||||
- name: config-map
|
||||
configMap:
|
||||
name: mysql
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: data
|
||||
spec:
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: my-nginx-svc
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- port: 80
|
||||
selector:
|
||||
app: nginx
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: my-nginx
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
replicas: 2
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
resources:
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
cpu: "500m"
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: my-nginx
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: my-nginx-svc
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- port: 80
|
||||
selector:
|
||||
app: nginx
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: php-apache
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
run: php-apache
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
run: php-apache
|
||||
spec:
|
||||
containers:
|
||||
- name: php-apache
|
||||
image: k8s.gcr.io/hpa-example
|
||||
ports:
|
||||
- containerPort: 80
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
requests:
|
||||
cpu: 200m
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: php-apache
|
||||
labels:
|
||||
run: php-apache
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
selector:
|
||||
run: php-apache
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: shell-demo
|
||||
spec:
|
||||
volumes:
|
||||
- name: shared-data
|
||||
emptyDir: {}
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
volumeMounts:
|
||||
- name: shared-data
|
||||
mountPath: /usr/share/nginx/html
|
||||
hostNetwork: true
|
||||
dnsPolicy: Default
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
minReadySeconds: 5
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
replicas: 3
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.16.1 # update the image
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
name: web
|
||||
clusterIP: None
|
||||
selector:
|
||||
app: nginx
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: web
|
||||
spec:
|
||||
serviceName: "nginx"
|
||||
podManagementPolicy: "Parallel"
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: k8s.gcr.io/nginx-slim:0.8
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: web
|
||||
volumeMounts:
|
||||
- name: www
|
||||
mountPath: /usr/share/nginx/html
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: www
|
||||
spec:
|
||||
accessModes: [ "ReadWriteOnce" ]
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
name: web
|
||||
clusterIP: None
|
||||
selector:
|
||||
app: nginx
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: web
|
||||
spec:
|
||||
serviceName: "nginx"
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: k8s.gcr.io/nginx-slim:0.8
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: web
|
||||
volumeMounts:
|
||||
- name: www
|
||||
mountPath: /usr/share/nginx/html
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: www
|
||||
spec:
|
||||
accessModes: [ "ReadWriteOnce" ]
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: wordpress-mysql
|
||||
labels:
|
||||
app: wordpress
|
||||
spec:
|
||||
ports:
|
||||
- port: 3306
|
||||
selector:
|
||||
app: wordpress
|
||||
tier: mysql
|
||||
clusterIP: None
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mysql-pv-claim
|
||||
labels:
|
||||
app: wordpress
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: wordpress-mysql
|
||||
labels:
|
||||
app: wordpress
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: wordpress
|
||||
tier: mysql
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: wordpress
|
||||
tier: mysql
|
||||
spec:
|
||||
containers:
|
||||
- image: mysql:5.6
|
||||
name: mysql
|
||||
env:
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mysql-pass
|
||||
key: password
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
name: mysql
|
||||
volumeMounts:
|
||||
- name: mysql-persistent-storage
|
||||
mountPath: /var/lib/mysql
|
||||
volumes:
|
||||
- name: mysql-persistent-storage
|
||||
persistentVolumeClaim:
|
||||
claimName: mysql-pv-claim
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: wordpress
|
||||
labels:
|
||||
app: wordpress
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
selector:
|
||||
app: wordpress
|
||||
tier: frontend
|
||||
type: LoadBalancer
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: wp-pv-claim
|
||||
labels:
|
||||
app: wordpress
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: wordpress
|
||||
labels:
|
||||
app: wordpress
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: wordpress
|
||||
tier: frontend
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: wordpress
|
||||
tier: frontend
|
||||
spec:
|
||||
containers:
|
||||
- image: wordpress:4.8-apache
|
||||
name: wordpress
|
||||
env:
|
||||
- name: WORDPRESS_DB_HOST
|
||||
value: wordpress-mysql
|
||||
- name: WORDPRESS_DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mysql-pass
|
||||
key: password
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: wordpress
|
||||
volumeMounts:
|
||||
- name: wordpress-persistent-storage
|
||||
mountPath: /var/www/html
|
||||
volumes:
|
||||
- name: wordpress-persistent-storage
|
||||
persistentVolumeClaim:
|
||||
claimName: wp-pv-claim
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: zk-hs
|
||||
labels:
|
||||
app: zk
|
||||
spec:
|
||||
ports:
|
||||
- port: 2888
|
||||
name: server
|
||||
- port: 3888
|
||||
name: leader-election
|
||||
clusterIP: None
|
||||
selector:
|
||||
app: zk
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: zk-cs
|
||||
labels:
|
||||
app: zk
|
||||
spec:
|
||||
ports:
|
||||
- port: 2181
|
||||
name: client
|
||||
selector:
|
||||
app: zk
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: zk-pdb
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: zk
|
||||
maxUnavailable: 1
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: zk
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: zk
|
||||
serviceName: zk-hs
|
||||
replicas: 3
|
||||
updateStrategy:
|
||||
type: RollingUpdate
|
||||
podManagementPolicy: OrderedReady
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: zk
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: "app"
|
||||
operator: In
|
||||
values:
|
||||
- zk
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
containers:
|
||||
- name: kubernetes-zookeeper
|
||||
imagePullPolicy: Always
|
||||
image: "k8s.gcr.io/kubernetes-zookeeper:1.0-3.4.10"
|
||||
resources:
|
||||
requests:
|
||||
memory: "1Gi"
|
||||
cpu: "0.5"
|
||||
ports:
|
||||
- containerPort: 2181
|
||||
name: client
|
||||
- containerPort: 2888
|
||||
name: server
|
||||
- containerPort: 3888
|
||||
name: leader-election
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- "start-zookeeper \
|
||||
--servers=3 \
|
||||
--data_dir=/var/lib/zookeeper/data \
|
||||
--data_log_dir=/var/lib/zookeeper/data/log \
|
||||
--conf_dir=/opt/zookeeper/conf \
|
||||
--client_port=2181 \
|
||||
--election_port=3888 \
|
||||
--server_port=2888 \
|
||||
--tick_time=2000 \
|
||||
--init_limit=10 \
|
||||
--sync_limit=5 \
|
||||
--heap=512M \
|
||||
--max_client_cnxns=60 \
|
||||
--snap_retain_count=3 \
|
||||
--purge_interval=12 \
|
||||
--max_session_timeout=40000 \
|
||||
--min_session_timeout=4000 \
|
||||
--log_level=INFO"
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- "zookeeper-ready 2181"
|
||||
initialDelaySeconds: 10
|
||||
timeoutSeconds: 5
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- "zookeeper-ready 2181"
|
||||
initialDelaySeconds: 10
|
||||
timeoutSeconds: 5
|
||||
volumeMounts:
|
||||
- name: datadir
|
||||
mountPath: /var/lib/zookeeper
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
fsGroup: 1000
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: datadir
|
||||
spec:
|
||||
accessModes: [ "ReadWriteOnce" ]
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
Loading…
Reference in New Issue