Как развернуть приложение PHP с Kubernetes в Ubuntu 16.04
Автор выбрал программу Write for DOnations.
Введение
Kubernetes — это система оркестрации контейнеров с открытым исходным кодом. Он позволяет создавать, обновлять и масштабировать контейнеры, не беспокоясь о простоях.
Для запуска приложения PHP Nginx действует как прокси для PHP-FPM. Контейнеризация этой установки в одном контейнере может быть громоздким процессом, но Kubernetes поможет управлять обеими службами в отдельных контейнерах. Использование Kubernetes позволит вам поддерживать возможность повторного использования и замены ваших контейнеров, и вам не придется перестраивать образ контейнера каждый раз, когда появляется новая версия Nginx или PHP.
В этом руководстве вы развернете приложение PHP 7 в кластере Kubernetes с Nginx и PHP-FPM, работающими в отдельных контейнерах. Вы также узнаете, как хранить файлы конфигурации и код приложения вне образа контейнера с помощью системы блочного хранения DigitalOcean. Этот подход позволит вам повторно использовать образ Nginx для любого приложения, которому требуется веб-сервер или прокси-сервер, путем передачи тома конфигурации, а не перестроения образа.
Примечание. Это руководство было протестировано на кластере Kubernetes, созданном с использованием документации по продукту DigitalOcean Kubernetes, для получения актуальной информации и руководств.
Предпосылки
- Основное понимание объектов Kubernetes. Дополнительную информацию можно найти в нашей статье Введение в Kubernetes.
- Кластер Kubernetes, работающий в Ubuntu 16.04. Вы можете настроить это, следуя руководству Как создать кластер Kubernetes 1.10 с помощью Kubeadm в Ubuntu 16.04.
- Учетная запись DigitalOcean и токен доступа API с разрешениями на чтение и запись для создания тома хранилища. Если у вас нет токена доступа к API, вы можете создать его здесь.
- Код вашего приложения размещен на общедоступном URL-адресе, например на Github.
Шаг 1 — Создание служб PHP-FPM и Nginx
На этом шаге вы создадите службы PHP-FPM и Nginx. Служба позволяет получить доступ к набору модулей из кластера. Службы внутри кластера могут взаимодействовать напрямую через свои имена без необходимости использования IP-адресов. Служба PHP-FPM разрешает доступ к модулям PHP-FPM, а служба Nginx разрешает доступ к модулям Nginx.
Поскольку модули Nginx будут проксировать модули PHP-FPM, вам нужно будет сообщить службе, как их найти. Вместо использования IP-адресов вы воспользуетесь преимуществами автоматического обнаружения служб Kubernetes, чтобы использовать удобочитаемые имена для маршрутизации запросов к соответствующей службе.
Чтобы создать службу, вы создадите файл определения объекта. Каждое определение объекта Kubernetes представляет собой файл YAML, содержащий как минимум следующие элементы:
apiVersion
: версия API Kubernetes, к которой принадлежит определение.kind
: объект Kubernetes, который представляет этот файл. Например,pod
илиservice
.метаданные
: содержитимя
объекта вместе с любымиметками
, которые вы можете применить к нему.spec
: содержит определенную конфигурацию в зависимости от типа создаваемого вами объекта, например образа контейнера или портов, через которые контейнер будет доступен.
Сначала вы создадите каталог для хранения определений объектов Kubernetes.
SSH к вашему главному узлу и создайте каталог definitions
, в котором будут храниться ваши определения объектов Kubernetes.
- mkdir definitions
Перейдите во вновь созданный каталог definitions
:
- cd definitions
Создайте свой сервис PHP-FPM, создав файл php_service.yaml
:
- nano php_service.yaml
Установите kind
как Service
, чтобы указать, что этот объект является службой:
...
apiVersion: v1
kind: Service
Назовите сервис php
, так как он обеспечит доступ к PHP-FPM:
...
metadata:
name: php
Вы логически сгруппируете разные объекты с помощью меток. В этом руководстве вы будете использовать метки для группировки объектов по «уровням», таким как интерфейс или серверная часть. Модули PHP будут работать за этой службой, поэтому вы пометите ее как tier: backend
.
...
labels:
tier: backend
Служба определяет, к каким модулям получить доступ, используя метки selector
. Модуль, соответствующий этим меткам, будет обслуживаться независимо от того, был ли модуль создан до или после обслуживания. Вы добавите метки для своих модулей позже в этом руководстве.
Используйте метку tier: backend
, чтобы назначить модуль на уровень backend. Вы также добавите метку app: php
, чтобы указать, что этот модуль работает на PHP. Добавьте эти две метки после раздела metadata
.
...
spec:
selector:
app: php
tier: backend
Далее укажите порт, используемый для доступа к этому сервису. В этом руководстве вы будете использовать порт 9000
. Добавьте его в файл php_service.yaml
в разделе spec
:
...
ports:
- protocol: TCP
port: 9000
Готовый файл php_service.yaml
будет выглядеть так:
apiVersion: v1
kind: Service
metadata:
name: php
labels:
tier: backend
spec:
selector:
app: php
tier: backend
ports:
- protocol: TCP
port: 9000
Нажмите CTRL + o
, чтобы сохранить файл, а затем CTRL + x
, чтобы выйти из nano
.
Теперь, когда вы создали определение объекта для своей службы, для запуска службы вы будете использовать команду kubectl apply
вместе с аргументом -f
и указать свой файл php_service.yaml
.
Создайте свой сервис:
- kubectl apply -f php_service.yaml
Этот вывод подтверждает создание службы:
Outputservice/php created
Убедитесь, что ваша служба работает:
- kubectl get svc
Вы увидите, что ваша служба PHP-FPM работает:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10m
php ClusterIP 10.100.59.238 <none> 9000/TCP 5m
Kubernetes поддерживает различные типы сервисов. Ваша служба php
использует тип службы по умолчанию, ClusterIP
. Этот тип службы назначает внутренний IP-адрес и делает службу доступной только внутри кластера.
Теперь, когда служба PHP-FPM готова, вы создадите службу Nginx. Создайте и откройте в редакторе новый файл с именем nginx_service.yaml
:
- nano nginx_service.yaml
Эта служба будет нацелена на модули Nginx, поэтому назовите ее nginx
. Вы также добавите метку tier: backend
, поскольку она относится к внутреннему уровню:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
tier: backend
Как и в случае со службой php
, настройте таргетинг на модули с помощью ярлыков селектора app: nginx
и tier: backend
. Сделайте эту службу доступной через порт 80, порт HTTP по умолчанию.
...
spec:
selector:
app: nginx
tier: backend
ports:
- protocol: TCP
port: 80
Служба Nginx будет общедоступна в Интернете с общедоступного IP-адреса вашей капли. your_public_ip
можно найти в облачной панели DigitalOcean. В разделе spec.externalIPs
добавьте:
...
spec:
externalIPs:
- your_public_ip
Ваш файл nginx_service.yaml
будет выглядеть так:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
tier: backend
spec:
selector:
app: nginx
tier: backend
ports:
- protocol: TCP
port: 80
externalIPs:
- your_public_ip
Сохраните и закройте файл. Создайте службу Nginx:
- kubectl apply -f nginx_service.yaml
Вы увидите следующий вывод, когда служба запущена:
Outputservice/nginx created
Вы можете просмотреть все запущенные службы, выполнив:
- kubectl get svc
В выводе вы увидите службы PHP-FPM и Nginx:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13m
nginx ClusterIP 10.102.160.47 your_public_ip 80/TCP 50s
php ClusterIP 10.100.59.238 <none> 9000/TCP 8m
Обратите внимание, если вы хотите удалить службу, которую вы можете запустить:
- kubectl delete svc/service_name
Теперь, когда вы создали свои службы PHP-FPM и Nginx, вам нужно указать, где хранить код вашего приложения и файлы конфигурации.
Шаг 2 — Установка подключаемого модуля хранилища DigitalOcean
Kubernetes предоставляет различные подключаемые модули хранилища, которые могут создавать пространство для хранения данных в вашей среде. На этом этапе вы установите блочное хранилище в DigitalOcean. После завершения установки будет добавлен класс хранилища с именем do-block-storage
, который вы будете использовать для создания своего блочного хранилища.
Сначала вы настроите секретный объект Kubernetes для хранения вашего токена DigitalOcean API. Секретные объекты используются для обмена конфиденциальной информацией, такой как ключи и пароли SSH, с другими объектами Kubernetes в том же пространстве имен. Пространства имен предоставляют способ логического разделения ваших объектов Kubernetes.
Откройте файл с именем secret.yaml
в редакторе:
- nano secret.yaml
Вы назовете свой секретный объект digitalocean
и добавите его в kube-system
namespace
. Пространство имен kube-system
является пространством имен по умолчанию для внутренних служб Kubernetes, а также используется подключаемым модулем хранилища DigitalOcean для запуска различных компонентов.
apiVersion: v1
kind: Secret
metadata:
name: digitalocean
namespace: kube-system
Вместо ключа spec
секрет использует ключ data
или stringData
для хранения необходимой информации. Параметр data
содержит данные в кодировке base64, которые автоматически декодируются при извлечении. Параметр stringData
содержит незакодированные данные, которые автоматически кодируются во время создания или обновления и не выводят данные при получении секретов. В этом руководстве вы будете использовать stringData
для удобства.
Добавьте токен доступа
как stringData
:
...
stringData:
access-token: your-api-token
Сохраните и закройте файл.
Ваш файл secret.yaml
будет выглядеть так:
apiVersion: v1
kind: Secret
metadata:
name: digitalocean
namespace: kube-system
stringData:
access-token: your-api-token
Создайте секрет:
- kubectl apply -f secret.yaml
Вы увидите этот вывод при создании секрета:
Outputsecret/digitalocean created
Вы можете просмотреть секрет с помощью следующей команды:
- kubectl -n kube-system get secret digitalocean
Вывод будет выглядеть примерно так:
OutputNAME TYPE DATA AGE
digitalocean Opaque 1 41s
Тип Opaque
означает, что этот секрет доступен только для чтения, что является стандартным для секретов stringData
. Подробнее об этом можно прочитать в спецификациях секретного дизайна. Поле DATA
показывает количество элементов, хранящихся в этом секрете. В этом случае отображается 1
, потому что у вас сохранен один ключ.
Теперь, когда ваш секрет готов, установите подключаемый модуль блочного хранилища DigitalOcean:
- kubectl apply -f https://raw.githubusercontent.com/digitalocean/csi-digitalocean/master/deploy/kubernetes/releases/csi-digitalocean-v0.3.0.yaml
Вы увидите вывод, подобный следующему:
Outputstorageclass.storage.k8s.io/do-block-storage created
serviceaccount/csi-attacher created
clusterrole.rbac.authorization.k8s.io/external-attacher-runner created
clusterrolebinding.rbac.authorization.k8s.io/csi-attacher-role created
service/csi-attacher-doplug-in created
statefulset.apps/csi-attacher-doplug-in created
serviceaccount/csi-provisioner created
clusterrole.rbac.authorization.k8s.io/external-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/csi-provisioner-role created
service/csi-provisioner-doplug-in created
statefulset.apps/csi-provisioner-doplug-in created
serviceaccount/csi-doplug-in created
clusterrole.rbac.authorization.k8s.io/csi-doplug-in created
clusterrolebinding.rbac.authorization.k8s.io/csi-doplug-in created
daemonset.apps/csi-doplug-in created
Теперь, когда вы установили подключаемый модуль хранилища DigitalOcean, вы можете создать блочное хранилище для хранения кода вашего приложения и файлов конфигурации.
Шаг 3 — Создание постоянного тома
Создав секрет и установив подключаемый модуль блочного хранилища, вы готовы создать свой постоянный том. Постоянный том, или PV, — это блочное хранилище определенного размера, которое существует независимо от жизненного цикла модуля. Использование постоянного тома позволит вам управлять модулями или обновлять их, не беспокоясь о потере кода приложения. Доступ к постоянному тому осуществляется с помощью PersistentVolumeClaim
или PVC, который монтирует PV по требуемому пути.
Откройте файл с именем code_volume.yaml
в редакторе:
- nano code_volume.yaml
Назовите PVC code
, добавив в файл следующие параметры и значения:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: code
spec
для PVC содержит следующие пункты:
Режимы доступа
, которые зависят от варианта использования. Это:ReadWriteOnce
— монтирует том для чтения и записи одним узломReadOnlyMany
— монтирует том как доступный только для чтения многими узламиReadWriteMany
— монтирует том для чтения и записи многими узлами
Блочное хранилище DigitalOcean подключается только к одному узлу, поэтому вы установите для
accessModes
значениеReadWriteOnce
. Это руководство поможет вам добавить небольшой объем кода приложения, поэтому в этом случае 1 ГБ будет достаточно. Если вы планируете хранить на томе больший объем кода или данных, вы можете изменить параметрstorage
в соответствии со своими требованиями. Вы можете увеличить объем хранилища после создания тома, но сжатие диска не поддерживается.... spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
Затем укажите класс хранилища, который Kubernetes будет использовать для предоставления томов. Вы будете использовать класс
do-block-storage
, созданный подключаемым модулем блочного хранилища DigitalOcean.... storageClassName: do-block-storage
Ваш файл
code_volume.yaml
будет выглядеть так:apiVersion: v1 kind: PersistentVolumeClaim metadata: name: code spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: do-block-storage
Сохраните и закройте файл.
Создайте
code
PersistentVolumeClaim, используяkubectl
:- kubectl apply -f code_volume.yaml
Следующий вывод сообщает вам, что объект был успешно создан, и вы готовы смонтировать PVC объемом 1 ГБ в качестве тома.
Outputpersistentvolumeclaim/code createdЧтобы просмотреть доступные постоянные тома (PV):
- kubectl get pv
Вы увидите свой PV в списке:
OutputNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-ca4df10f-ab8c-11e8-b89d-12331aa95b13 1Gi RWO Delete Bound default/code do-block-storage 2mПриведенные выше поля представляют собой обзор вашего файла конфигурации, за исключением полей
Reclaim Policy
иStatus
.Политика возврата
определяет, что делать с PV после удаления PVC, обращающегося к нему.Delete
удаляет PV из Kubernetes, а также из инфраструктуры DigitalOcean. Подробнее оПолитике возврата
иСтатусе
можно узнать из документации Kubernetes PV.Вы успешно создали постоянный том с помощью подключаемого модуля блочного хранилища DigitalOcean. Теперь, когда ваш постоянный том готов, вы создадите свои модули с помощью развертывания.
Шаг 4 — Создание развертывания PHP-FPM
На этом этапе вы узнаете, как использовать развертывание для создания модуля PHP-FPM. Развертывания обеспечивают единый способ создания, обновления и управления модулями с помощью наборов реплик. Если обновление не работает должным образом, развертывание автоматически вернет свои модули к предыдущему образу.
Ключ Deployment
spec.selector
содержит список меток модулей, которыми он будет управлять. Он также будет использовать ключtemplate
для создания необходимых модулей.Этот шаг также познакомит вас с использованием Init Containers. Init Containers запускает одну или несколько команд перед обычными контейнерами, указанными в ключе
template
модуля. В этом руководстве ваш Init Container будет получать образец файлаindex.php
из GitHub Gist с помощьюwget
. Это содержимое файла примера:<?php echo phpinfo();
Чтобы создать развертывание, откройте в редакторе новый файл с именем
php_deployment.yaml
:- nano php_deployment.yaml
Это развертывание будет управлять вашими модулями PHP-FPM, поэтому вы должны назвать объект развертывания
php
. Поды относятся к серверному уровню, поэтому вы сгруппируете развертывание в эту группу, используя меткуtier: backend
:apiVersion: apps/v1 kind: Deployment metadata: name: php labels: tier: backend
Для
spec
развертывания вы укажете, сколько копий этого модуля нужно создать, используя параметрreplicas
. Количествореплик
зависит от ваших потребностей и доступных ресурсов. В этом руководстве вы создадите одну реплику:... spec: replicas: 1
Это развертывание будет управлять модулями, которые соответствуют меткам
app: php
иtier: backend
. Под ключомselector
добавьте:... selector: matchLabels: app: php tier: backend
Далее,
spec
развертывания требуетtemplate
для определения объекта вашего модуля. Этот шаблон будет определять спецификации для создания модуля. Сначала вы добавите метки, указанные для службыphp
selectors
иmatchLabels
развертывания. Добавьтеapp: php
иtier: backend
вtemplate.metadata.labels
:... template: metadata: labels: app: php tier: backend
Модуль может иметь несколько контейнеров и томов, но каждому из них потребуется имя. Вы можете выборочно подключать тома к контейнеру, указав путь подключения для каждого тома.
Сначала укажите тома, к которым будут обращаться ваши контейнеры. Вы создали PVC с именем
code
для хранения кода вашего приложения, поэтому также назовите этот томcode
. В разделеspec.template.spec.volumes
добавьте следующее:... spec: volumes: - name: code persistentVolumeClaim: claimName: code
Затем укажите контейнер, который вы хотите запустить в этом модуле. Вы можете найти различные образы в магазине Docker, но в этом руководстве вы будете использовать образ
php:7-fpm
.В разделе
spec.template.spec.containers
добавьте следующее:... containers: - name: php image: php:7-fpm
Далее вы смонтируете тома, к которым контейнеру требуется доступ. Этот контейнер будет запускать ваш PHP-код, поэтому ему потребуется доступ к тому
code
. Вы также будете использоватьmountPath
, чтобы указать/code
в качестве точки подключения.В разделе
spec.template.spec.containers.volumeMounts
добавьте:... volumeMounts: - name: code mountPath: /code
Теперь, когда вы смонтировали свой том, вам нужно получить код вашего приложения на томе. Возможно, вы ранее использовали FTP/SFTP или клонировали код через соединение SSH, чтобы выполнить это, но этот шаг покажет вам, как скопировать код с помощью Init Container.
В зависимости от сложности вашего процесса установки вы можете использовать один
initContainer
для запуска скрипта, который создает ваше приложение, или вы можете использовать одинinitContainer
для каждой команды. Убедитесь, что тома смонтированы вinitContainer
.В этом руководстве вы будете использовать один Init Container с
busybox
для загрузки кода.busybox
— это небольшое изображение, содержащее утилитуwget
, которую вы будете использовать для этого.В разделе
spec.template.spec
добавьте свойinitContainer
и укажите изображениеbusybox
:... initContainers: - name: install image: busybox
Вашему Init Container потребуется доступ к тому
code
, чтобы он мог загрузить код в это место. В разделеspec.template.spec.initContainers
смонтируйте томcode
по пути/code
:... volumeMounts: - name: code mountPath: /code
Каждый Init Container должен выполнить
команду
. Ваш Init Container будет использоватьwget
для загрузки Github в рабочий каталог/code
. Параметр-O
дает загруженному файлу имя, и вы назовете этот файлindex.php
.Примечание. Обязательно доверяйте коду, который вы загружаете. Прежде чем загружать его на свой сервер, проверьте исходный код, чтобы убедиться, что вас устраивает то, что он делает.
Под контейнером
install
вspec.template.spec.initContainers
добавьте следующие строки:... command: - wget - "-O" - "/code/index.php" - https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php
Готовый файл
php_deployment.yaml
будет выглядеть так:apiVersion: apps/v1 kind: Deployment metadata: name: php labels: tier: backend spec: replicas: 1 selector: matchLabels: app: php tier: backend template: metadata: labels: app: php tier: backend spec: volumes: - name: code persistentVolumeClaim: claimName: code containers: - name: php image: php:7-fpm volumeMounts: - name: code mountPath: /code initContainers: - name: install image: busybox volumeMounts: - name: code mountPath: /code command: - wget - "-O" - "/code/index.php" - https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php
Сохраните файл и выйдите из редактора.
Создайте развертывание PHP-FPM с помощью
kubectl
:- kubectl apply -f php_deployment.yaml
После создания развертывания вы увидите следующий вывод:
Outputdeployment.apps/php createdПодводя итог, это развертывание начнется с загрузки указанных образов. Затем он запросит
PersistentVolume
из вашегоPersistentVolumeClaim
и последовательно запустит вашиinitContainers
. После завершения контейнеры будут запускаться и монтироватьтома
в указанную точку монтирования. После того, как все эти шаги будут выполнены, ваш модуль будет запущен и запущен.Вы можете просмотреть свое развертывание, запустив:
- kubectl get deployments
Вы увидите вывод:
OutputNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE php 1 1 1 0 19sЭти выходные данные могут помочь вам понять текущее состояние развертывания.
Развертывание
— это документация по развертыванию Kubernetes.Вы можете просмотреть модули, запущенные этим развертыванием, с помощью следующей команды:
- kubectl get pods
Вывод этой команды зависит от того, сколько времени прошло с момента создания развертывания. Если вы запустите его вскоре после создания, вывод, скорее всего, будет выглядеть так:
OutputNAME READY STATUS RESTARTS AGE php-86d59fd666-bf8zd 0/1 Init:0/1 0 9sСтолбцы представляют следующую информацию:
Готово
: количествореплик
, на которых запущен этот модуль.Статус
: статус модуля.Init
указывает, что Init Containers запущены. В этих выходных данных завершено выполнение 0 из 1 контейнера инициализации.Перезапуски
: сколько раз этот процесс перезапускался для запуска модуля. Это число увеличится, если какой-либо из ваших Init-контейнеров выйдет из строя. Развертывание будет перезапускать его до тех пор, пока оно не достигнет желаемого состояния.
В зависимости от сложности ваших сценариев запуска может пройти несколько минут, прежде чем статус изменится на
podInitializing
:OutputNAME READY STATUS RESTARTS AGE php-86d59fd666-lkwgn 0/1 podInitializing 0 39sЭто означает, что инициализация контейнеров завершена, и контейнеры инициализируются. Если вы запустите команду, когда все контейнеры запущены, вы увидите, что статус модуля изменится на
Выполняется
.OutputNAME READY STATUS RESTARTS AGE php-86d59fd666-lkwgn 1/1 Running 0 1mТеперь вы видите, что ваш модуль успешно работает. Если ваш модуль не запускается, вы можете выполнить отладку с помощью следующих команд:
- Просмотр подробной информации о пакете:
- kubectl describe pods pod-name
- Просмотр журналов, созданных модулем:
- kubectl logs pod-name
- Просмотр журналов для определенного контейнера в модуле:
- kubectl logs pod-name container-name
Код вашего приложения смонтирован, и теперь служба PHP-FPM готова обрабатывать подключения. Теперь вы можете создать развертывание Nginx.
Шаг 5 — Создание развертывания Nginx
На этом шаге вы будете использовать ConfigMap для настройки Nginx. ConfigMap хранит вашу конфигурацию в формате ключ-значение, на который вы можете ссылаться в других определениях объектов Kubernetes. Этот подход даст вам возможность повторно использовать образ или заменять его другой версией Nginx, если это необходимо. Обновление ConfigMap автоматически реплицирует изменения на любой подключаемый модуль.
Создайте файл
nginx_configMap.yaml
для ConfigMap с помощью редактора:- nano nginx_configMap.yaml
Назовите ConfigMap
nginx-config
и сгруппируйте его в микросервисtier: backend
:apiVersion: v1 kind: ConfigMap metadata: name: nginx-config labels: tier: backend
Далее вы добавите
данные
для ConfigMap. Назовите ключconfig
и добавьте содержимое файла конфигурации Nginx в качестве значения. Вы можете использовать пример конфигурации Nginx из этого руководства.Поскольку Kubernetes может направлять запросы на соответствующий хост для службы, вы можете ввести имя службы PHP-FPM в параметре
fastcgi_pass
вместо ее IP-адреса. Добавьте в файлnginx_configMap.yaml
следующее:... data: config : | server { index index.php index.html; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root ^/code^; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } }
Ваш файл
nginx_configMap.yaml
будет выглядеть так:apiVersion: v1 kind: ConfigMap metadata: name: nginx-config labels: tier: backend data: config : | server { index index.php index.html; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root /code; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } }
Сохраните файл и выйдите из редактора.
Создайте карту конфигурации:
- kubectl apply -f nginx_configMap.yaml
Вы увидите следующий вывод:
Outputconfigmap/nginx-config createdВы закончили создание ConfigMap и теперь можете создать развертывание Nginx.
Начните с открытия нового файла
nginx_deployment.yaml
в редакторе:- nano nginx_deployment.yaml
Назовите развертывание
nginx
и добавьте меткуtier: backend
:apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: tier: backend
Укажите, что вам нужна одна
replicas
вspec
развертывания. Это развертывание будет управлять модулями с меткамиapp: nginx
иtier: backend
. Добавьте следующие параметры и значения:... spec: replicas: 1 selector: matchLabels: app: nginx tier: backend
Затем добавьте модуль
template
. Вам нужно использовать те же метки, которые вы добавили для развертыванияselector.matchLabels
. Добавьте следующее:... template: metadata: labels: app: nginx tier: backend
Предоставьте Nginx доступ к
code
PVC, который вы создали ранее. В разделеspec.template.spec.volumes
добавьте:... spec: volumes: - name: code persistentVolumeClaim: claimName: code
Поды могут монтировать ConfigMap как том. Указание имени файла и ключа создаст файл с его значением в качестве содержимого. Чтобы использовать ConfigMap, задайте для
path
имя файла, в котором будет храниться содержимоеkey
. Вы хотите создать файлsite.conf
из ключаconfig
. В разделеspec.template.spec.volumes
добавьте следующее:... - name: config configMap: name: nginx-config items: - key: config path: site.conf
Предупреждение. Если файл не указан, содержимое
key
заменитmountPath
тома. Это означает, что если путь не указан явно, вы потеряете все содержимое в папке назначения.Далее вы укажете образ, из которого будет создан ваш модуль. В этом руководстве будет использоваться образ
nginx:1.7.9
для стабильности, но вы можете найти другие образы Nginx в магазине Docker. Также сделайте Nginx доступным на порту 80. В разделеspec.template.spec
добавьте:... containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
Nginx и PHP-FPM должны обращаться к файлу по одному и тому же пути, поэтому смонтируйте том
code
в/code
:... volumeMounts: - name: code mountPath: /code
Образ
nginx:1.7.9
автоматически загрузит все файлы конфигурации из каталога/etc/nginx/conf.d
. При монтировании томаconfig
в этот каталог будет создан файл/etc/nginx/conf.d/site.conf
. В разделеvolumeMounts
добавьте следующее:... - name: config mountPath: /etc/nginx/conf.d
Ваш файл
nginx_deployment.yaml
будет выглядеть так:apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: tier: backend spec: replicas: 1 selector: matchLabels: app: nginx tier: backend template: metadata: labels: app: nginx tier: backend spec: volumes: - name: code persistentVolumeClaim: claimName: code - name: config configMap: name: nginx-config items: - key: config path: site.conf containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 volumeMounts: - name: code mountPath: /code - name: config mountPath: /etc/nginx/conf.d
Сохраните файл и выйдите из редактора.
Создайте развертывание Nginx:
- kubectl apply -f nginx_deployment.yaml
Следующий вывод указывает, что ваше развертывание теперь создано:
Outputdeployment.apps/nginx createdПеречислите свои развертывания с помощью этой команды:
- kubectl get deployments
Вы увидите развертывания Nginx и PHP-FPM:
OutputNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx 1 1 1 0 16s php 1 1 1 1 7mПеречислите модули, управляемые обоими развертываниями:
- kubectl get pods
Вы увидите запущенные модули:
OutputNAME READY STATUS RESTARTS AGE nginx-7bf5476b6f-zppml 1/1 Running 0 32s php-86d59fd666-lkwgn 1/1 Running 0 7mТеперь, когда все объекты Kubernetes активны, вы можете посетить службу Nginx в своем браузере.
Список запущенных служб:
- kubectl get services -o wide
Получите внешний IP-адрес для вашего сервиса Nginx:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 39m <none> nginx ClusterIP 10.102.160.47 your_public_ip 80/TCP 27m app=nginx,tier=backend php ClusterIP 10.100.59.238 <none> 9000/TCP 34m app=php,tier=backendВ браузере зайдите на свой сервер, введя
http://your_public_ip
. Вы увидите выводphp_info()
и подтвердите, что ваши службы Kubernetes запущены и работают.Заключение
В этом руководстве вы контейнеризировали сервисы PHP-FPM и Nginx, чтобы вы могли управлять ими независимо. Такой подход не только улучшит масштабируемость вашего проекта по мере его роста, но и позволит вам эффективно использовать ресурсы. Вы также сохранили код своего приложения на томе, чтобы легко обновлять свои службы в будущем.