Kubernetes (также известная как k8s) — это система оркестрации с открытым исходным кодом. Она позволяет пользователям развертывать, масштабировать и управлять контейнеризированными приложениями с минимальным временем простоя. В этом руководстве вы узнаете, как развернуть PHP приложение в кластере Kubernetes.
Nginx работает как прокси для PHP-FPM при запуске PHP-приложения. Управление этими двумя службами в одном контейнере — сложный процесс. Kubernetes помогает нам управлять ними в двух разных контейнерах и избавляет от лишних хлопот. Он также позволяет пользователям повторно использовать контейнеры и не беспокоиться о сборке образа контейнера для каждой новой версии PHP/Nginx.
Вы запустите свое приложение и службу прокси в двух отдельных контейнерах. В руководстве также будет рассказано, как использовать локальное хранилище для создания Persistent Volume (PV) и Persistent Volume Claim (PVC). Затем вы будете использовать этот PVC для хранения файлов конфигурации и кода вне образов контейнеров. После завершения этого руководства вы сможете повторно использовать свой образ Nginx для других приложений, которым требуется прокси-сервер. Вы можете добиться этого, передав конфигурацию вместо повторной сборки образа для нее.
Предварительные требования
- Базовое понимание Kubernetes (k8s) и его объектов. Обратитесь к этому руководству для подробного обзора экосистемы Kubernetes.
- Кластер Kubernetes, запущенный и работающий на Ubuntu 18.04. Следуйте этому руководству, чтобы создать свой кластер Kubernetes с помощью kubeadm.
- Кроме того, вам необходимо разместить код вашего приложения по общедоступному URL-адресу, например, на GitHub.
Шаг 1. Создание служб PHP-FPM и Nginx
Этот шаг поможет вам создать службы PHP-FPM и Nginx. Любая служба предоставляет доступ к набору подов внутри кластера. Все службы, присутствующие в кластере, могут взаимодействовать друг с другом по своим именам, без IP-адресов. Служба PHP-FPM и служба Nginx предоставят доступ к подам PHP-FPM и Nginx соответственно.
Вам нужно будет указать службе PHP-FPM, как находить поды Nginx, так как она будет выступать в качестве прокси для подов PHP-FPM. Для этого вы воспользуетесь автоматическим обнаружением служб Kubernetes’ и будете использовать понятные человеку имена для маршрутизации запроса к соответствующей службе.
Чтобы создать любую службу, вам нужно будет создать файл YAML, содержащий определение объекта. Этот YAML-файл содержит как минимум следующие теги:
apiVersion: версия API Kubernetes, к которой относится определение.kind: тип объекта Kubernetes, который создает этот YAML-файл. Например:service,jobилиpod.metadata: имя объекта и различныеlabels, которые пользователь может захотеть применить к этому объекту, определяются под этим тегом.spec: этот тег содержит спецификацию вашего объекта, такую как переменные окружения (ENV), используемый образ контейнера, порты, по которым будет доступна служба контейнера.
Создание службы PHP-FPM
Для начала вам следует создать каталог для хранения определения вашего объекта Kubernetes. Войдите на свой мастер-узел и создайте каталог с именем “definitions:”
|
1 |
mkdir definitions |
Перейдите в каталог definitions:
|
1 |
cd definitions |
Затем создайте файл службы PHP-FPM как файл php_service.yaml:
|
1 |
nano php_fpm_service.yaml |
После этого установите apiVersion и kind в файле php_fpm_service.yaml:
|
1 2 |
apiVersion: v1 kind: Service |
Назовите свою службу php или php-fpm, так как она будет предоставлять доступ к вашему приложению PHP-FPM:
|
1 2 3 |
… Metadata: name: php |
Пометьте свою службу php как tier: backend, так как PHP-приложение будет работать за этой службой:
|
1 2 3 |
… labels: tier: backend |
Служба использует метки selector, чтобы определить, к каким подам обращаться. Любой под, соответствующий этим меткам, независимо от того, когда он был создан, обслуживается. Вы узнаете, как добавлять метки к своим подам, позже в этом руководстве.
Включите tier: backend метку, которая назначает ваш pod на уровень backend, вместе с app: php-fpm меткой, указывающей, что в pod запущено приложение PHP-FPM. Вы должны добавить эти метки после раздела metadata раздела:
|
1 2 3 4 5 |
… spec: selector: app: php-fpm tier: backend |
Затем вам нужно объявить порт для доступа к этой службе php-fpm в разделе spec. Вы можете добавить любой порт по вашему выбору, но в этом руководстве мы будем использовать порт 9000 в этом руководстве:
|
1 2 3 4 |
... ports: - protocol: TCP port: 9000 |
После выполнения описанных выше шагов ваш файл php_fpm_service.yaml будет выглядеть следующим образом:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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 для создания службы PHP
После того как определение объекта для вашей службы создано, запустите команду kubectl apply с аргументом -f, указав ваш файл php_fpm_service.yaml:
|
1 |
kubectl apply -f php_fpm_service.yaml |
Вывод вышеуказанной команды должен быть следующим:
|
1 |
service/php created |
Запустите команду ниже, чтобы убедиться, что служба php-fpm запущена:
|
1 |
$ kubectl get svc |
Вы сможете увидеть, что служба php-fpm запущена и работает:
|
1 2 3 |
NAME 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 |
Создание службы Nginx
Поскольку ваша служба PHP-FPM готова, пришло время создать и службу Nginx. Создайте и откройте новый YAML-файл для этой службы под названием nginx_service.yaml в редакторе:
|
1 |
$ nano nginx_service.yaml |
Назовите эту службу nginx, так как она будет нацелена на pods Nginx. Эта служба также относится к backend, поэтому вам следует добавить к ней метку tier: backend:
|
1 2 3 4 5 6 |
apiVersion: v1 kind: Service metadata: name: nginx labels: tier: backend |
Как и в случае со службой php-fpm, добавьте селекторные метки app: nginx и tier: backend для выбора целевых pods. Добавьте HTTP-порт по умолчанию 80 для доступа к этой службе:
|
1 2 3 4 5 6 7 8 |
... spec: selector: app: nginx tier: backend ports: - protocol: TCP port: 80 |
Служба Nginx может быть общедоступна в Интернете по публичному IP-адресу. Вы можете добавить IP-адрес вашего рабочего узла в качестве your_public_ip. Добавьте строки ниже в раздел spec.externalIPs:
|
1 2 3 4 5 |
... spec: externalIPs: - your_public_ip |
Ваш файл nginx_service.yaml должен выглядеть следующим образом после выполнения всех описанных выше шагов:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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 |
Сохраните и закройте файл после добавления всех необходимых параметров выше.
Применение команды kubectl для создания службы Nginx
|
1 |
kubectl apply -f nginx_service.yaml |
|
1 |
service/nginx created |
|
1 |
$ kubectl get svc |
|
1 2 3 4 |
NAME 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 |
|
1 |
$ kubectl delete svc/service_name |
Шаг 2. Создание локального хранилища и постоянного тома (Persistent Volume)
Kubernetes предоставляет различные плагины хранения, которые помогают создавать пространство хранения для вашей среды. Этот шаг покажет вам, как создать локальный StorageClass и как этот класс хранения можно использовать в дальнейшем для создания постоянного тома (Persistent Volume).
Создание локального хранилища
Создайте файл, например storageClass.yaml, в вашем редакторе:
|
1 |
$nano storageClass.yaml |
Добавьте kind как "storageClass" и apiVersion как "storage.k8s.io/v1" следующим образом:
|
1 2 |
kind: StorageClass apiVersion: storage.k8s.io/v1 |
Назовите этот StorageClass как "my-local-storage" и добавьте provisioner и volumeBindingMode следующим образом:
|
1 2 3 4 5 |
… metadata: name: my-local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: Immediate |
Сохраните и закройте файл. Ваш итоговый файл storageClass.yaml должен выглядеть следующим образом:
|
1 2 3 4 5 6 |
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: my-local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer |
Теперь создайте StorageClass, выполнив команду kubectl create, как показано ниже:
|
1 |
$ kubectl create -f storageClass.yaml |
После выполнения вышеуказанной команды вы должны получить следующий вывод:
|
1 |
storageclass.storage.k8s.io/my-local-storage created |
Создание локального постоянного тома (Persistent Volume)
После создания локального хранилища вы можете создать локальный постоянный том (Persistent Volume). Постоянный том, также известный как PV, представляет собой блочное хранилище определенного размера, независимое от жизненного цикла пода. Локальный постоянный том — это не что иное, как локальный диск или каталог, доступный на узле кластера Kubernetes. Этот локальный постоянный том позволяет пользователям получать доступ к локальному хранилищу с помощью локального запроса на постоянный том (Persistent Volume Claim) очень простым и переносимым способом. Вы можете создать этот локальный постоянный том, используя класс хранения, который мы только что создали. Откройте файл, например persistentVolume.yaml, в вашем редакторе:
|
1 |
$ nano persistentVolume.yaml |
Дайте этому постоянному тому имя, например "my-local-pv":
|
1 2 3 4 |
apiVersion: v1 kind: PersistentVolume metadata: name: my-local-pv |
При создании локального постоянного тома вы можете добавить емкость хранилища в соответствии с вашими потребностями. В этом руководстве мы будем использовать 5 Gi для хранилища:
|
1 2 3 4 |
… spec: capacity: storage: 5Gi |
Добавьте accessModes, persistentVolumeReclaimPolicy и укажите то же имя storageClassName, которое использовалось в storageClass.yaml:
|
1 2 3 4 5 |
… accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: my-local-storage |
Добавьте local.path для вашего Persistent Volume, как показано ниже:
|
1 2 3 |
… local: path: /mnt/disk/vol |
После добавления всех обязательных полей ваш persistentVolume.yaml файл должен выглядеть следующим образом:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
apiVersion: v1 kind: PersistentVolume metadata: name: my-local-pv spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: my-local-storage local: path: /mnt/disk/vol nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - worker |
Подготовка локального тома (Local Volume)
Теперь нам нужно подготовить локальный том на узле “worker”, как мы указали в persistentVolume.yaml файле. Выполните приведенные ниже команды на узле, который вы настроили в persistentVolume. В данном случае это узел “worker”:
|
1 2 3 |
$ DIRNAME="vol" $ mkdir -p /mnt/disk/$DIRNAME $ chmod 777 /mnt/disk/$DIRNAME |
Выполните приведенную ниже команду на главном узле, где находится ваш persistentVolume.yaml файл:
|
1 |
kubectl create -f persistentVolume.yaml |
Вы должны получить следующий вывод:
|
1 |
persistentvolume/my-local-pv created |
После успешного создания локального хранилища и Persistent Volume вы можете перейти к созданию Persistent Volume Claim для хранения кода вашего приложения и конфигурационных файлов.
Step 3: Create the Persistent Volume
Код вашего приложения должен быть в безопасности во время управления подами или их обновления. Для этого вы будете использовать Persistent Volume, созданный на предыдущем шаге, доступ к которому осуществляется с помощью PersistentVolumeClaim, или PVC. Этот PVC монтирует PV по требуемому пути.
Откройте файл, например code_volume.yaml, в вашем редакторе:
|
1 |
$ nano code_volume.yaml |
Назовите ваш PVC как code, добавив в файл следующие параметры и значения:
|
1 2 3 4 |
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: code |
Раздел spec в PVC содержит следующие элементы:
- accessModes: Возможны следующие значения для этого поля:
- ReadWriteOnce – монтирует том для одного узла с правами как на чтение, так и на запись.
- ReadOnlyMany – монтирует том для множества узлов только с правами на чтение.
- ReadWriteMany – монтирует том для множества узлов с правами как на чтение, так и на запись.
- resources: определяет необходимый объем хранилища.
Поскольку локальное хранилище монтируется только к одному узлу, вам потребуется установить accessMode в значение ReadWriteOnce. В этом руководстве вы добавите лишь небольшой фрагмент кода приложения, поэтому здесь будет достаточно 1 ГБ хранилища. Однако, если вы хотите хранить больший объем данных или кода, вы можете изменить параметр storage в соответствии со своими требованиями. Обратите внимание, что после создания тома вы сможете увеличить размер хранилища. Однако уменьшение размера не поддерживается:
|
1 2 3 4 5 6 7 |
... spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi |
Теперь объявите класс хранилища, который кластер Kubernetes будет использовать для выделения томов. Используйте созданный на предыдущем шаге класс хранилища my-local-storage в качестве значения для storageClassName:
|
1 2 |
... storageClassName: my-local-storage |
После выполнения описанных выше шагов ваш файл code_volume.yaml должен выглядеть следующим образом:
|
1 2 3 4 5 6 7 8 9 10 11 |
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: code spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: my-local-storage |
Теперь сохраните файл и выйдите из него.
Создание PVC
Создайте PVC code, выполнив команду kubectl apply:
|
1 |
$ kubectl apply -f code_volume.yaml |
Вы должны получить следующий вывод, указывающий на то, что объект был успешно создан и готов к монтированию вашего PVC объемом 1 ГБ в качестве тома:
|
1 |
persistentvolumeclaim/code created |
Вы можете выполнить следующую команду, чтобы проверить доступные Persistent Volume (PV):
|
1 |
$ kubectl get pv |
Вывод вышеуказанной команды должен быть следующим:
|
1 2 |
NAME 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, представляют собой обзор вашего конфигурационного файла. Reclaim Policy определяет, что происходит с PV после удаления обращающегося к нему PVC. Значение Delete удаляет PV как из кластера Kubernetes, так и из инфраструктуры хранения. Вы можете обратиться к документации по Kubernetes PV, чтобы получить четкое представление о Reclaim Policy и Status.
Теперь вы можете создать свои поды с помощью Deployment, так как вы успешно создали Persistent Volume с использованием локального хранилища.
Шаг 4. Создание Deployment для вашего приложения PHP-FPM
Этот шаг поможет вам создать под PHP-FPM с помощью Deployment. Deployment использует ReplicaSets для обеспечения стабильного способа создания, обновления и управления вашими подами. Deployment автоматически откатывает свои поды к предыдущему образу.
Ключ spec.selector в Deployment перечисляет все метки управляемых им подов. Он также использует ключ template для создания необходимых подов.
На этом шаге мы также рассмотрим применение Init-контейнеров (Init Containers). Init-контейнеры выполняют несколько команд перед запуском обычных контейнеров, указанных в шаблоне пода. В данном случае Init-контейнер будет использовать GitHub Gist (https://gist.github.com/) для получения примера файла index.php. Содержимое этого файла-примера:
|
1 2 |
<?php echo phpinfo(); |
Создание PHP Deployment
Откройте новый файл с именем php_deployment.yaml в вашем редакторе, чтобы создать Deployment:
|
1 |
$ nano php_deployment.yaml |
Теперь назовите объект Deployment как PHP, так как этот Deployment будет управлять вашими подами PHP-FPM. Добавьте метку tier: backend, потому что под будет принадлежать к уровню backend:
|
1 2 3 4 5 6 |
apiVersion: apps/v1 kind: Deployment metadata: name: php labels: tier: backend |
Используя параметр replica, укажите количество копий этого пода, которое должно быть создано. Количество реплик может варьироваться в зависимости от ваших требований и доступных ресурсов. В этом руководстве вы создадите только одну реплику вашего пода:
|
1 2 3 4 |
... spec: replicas: 1 |
Добавьте app: php и tier:backend метки под ключом selector, который указывает, что этот Deployment будет управлять подами, соответствующими этим двум меткам:
|
1 2 3 4 5 |
... selector: matchLabels: app: php tier: backend |
Теперь определению объекта вашего пода требуется шаблон (template) в спецификации Deployment. Этот шаблон определяет спецификацию, необходимую для создания вашего пода. Для начала добавьте метки, которые были указаны для селектора службы php и matchLabels в Deployment. Затем добавьте app:php и tier:backend под template.metadata.labels:
|
1 2 3 4 5 6 7 |
... template: metadata: labels: app: php tier: backend |
Сначала вам нужно указать все тома, к которым ваши контейнеры будут иметь доступ. Назовите этот том code, так как вы ранее создали PVC с именем code для хранения кода вашего приложения:
|
1 2 3 4 5 6 |
... spec: volumes: - name: code persistentVolumeClaim: claimName: code |
Затем укажите имя контейнера вместе с образом, который вы хотите запустить внутри вашего пода. В магазине Docker (https://hub.docker.com/explore/) доступно множество различных образов, но в этом руководстве мы будем использовать образ php:7-fpm:
|
1 2 3 4 |
... containers: - name: php image: php:7-fpm |
Теперь смонтируйте тома, к которым контейнеру требуется доступ. Поскольку этот контейнер будет запускать ваш PHP-код, ему понадобится доступ к тому code, созданному на предыдущем шаге. На этом шаге вы также узнаете, как скопировать код вашего приложения с помощью Init-контейнера.
Для загрузки кода в этом руководстве будет показано, как использовать один Init-контейнер с busybox. Busybox — это небольшой контейнер с утилитой wget, которую вы будете использовать для этой цели.
Сначала добавьте ваш initContainer под spec.template.spec и укажите образ busybox:
|
1 2 3 4 |
... initContainers: - name: install image: busybox |
Затем, чтобы загрузить код в том code, вашему Init-контейнеру потребуется доступ к нему. Смонтируйте том code по пути /code под spec.template.spec.initContainers:
|
1 2 3 4 |
... volumeMounts: - name: code mountPath: /code |
Каждому Init-контейнеру требуется запуск команды. Этот Init-контейнер будет использовать wget для загрузки code из Github в директорию /code. Вы можете передать параметр -O, чтобы дать этому загруженному файлу имя, и вы можете назвать этот файл index.php.
Кроме того, добавьте следующие строки под контейнером install в spec.template.spec.initContainers:
|
1 2 3 4 5 6 |
... command: - wget - "-O" - "/code/index.php" - https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php |
После выполнения всех этих шагов ваш php_deployment.yaml файл должен выглядеть следующим образом:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
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 Deployment с помощью kubectl apply команды:
|
1 |
$ kubectl apply -f php_deployment.yaml |
Успешное создание Deployment должно вывести следующий результат:
|
1 |
deployment.apps/php created |
Этот Deployment начинается с загрузки указанных образов, затем он запросит PersistentVolume у вашего PersistentVolumeClaim, а затем запустит ваши initContainers. Как только этот шаг будет выполнен, контейнеры запустятся и примонтируют тома к указанной точке монтирования. После выполнения всех этих шагов ваш под будет запущен и готов к работе.
Вы можете запустить следующую команду для просмотра вашего Deployment:
|
1 |
$ kubectl get deployments |
После запуска вышеуказанной команды вы должны получить следующий вывод:
|
1 2 |
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE php 1 1 1 0 19s |
С помощью этого вывода вы можете понять текущее состояние Deployment. Deployment — это контроллер, который поддерживает желаемое состояние. Поле DESIRED указывает, что у него есть 1 реплика пода с именем php. Поле CURRENT указывает, сколько реплик DESIRED состояния запущены в данный момент. Для исправного пода это значение должно совпадать с DESIRED состоянием. Вы можете узнать больше об остальных полях в документации по Kubernetes Deployments.
После этого, чтобы проверить статус запущенного пода, вы можете выполнить следующую команду:
|
1 |
$ kubectl get pods |
Вывод этой команды может отличаться в зависимости от времени, прошедшего с момента создания Deployment. Если запустить её вскоре после создания Deployment, вывод будет похож на:
|
1 2 |
NAME READY STATUS RESTARTS AGE php-5d8f6bbf7f-56df2 0/1 Init:0/1 0 9s |
Объяснение:
Эти столбцы представляют следующую информацию:
- Ready: количество текущих/желаемых реплик, в которых запущен этот под.
- Status: Статус вашего пода. Init:0/1 указывает на то, что Init-контейнеры запущены и 0 из 1 Init-контейнеров завершили работу.
- Restarts: Это указывает количество перезапусков данного процесса для запуска пода.
Изменение статуса вашего пода на podInitializing может занять несколько минут в зависимости от сложности ваших скриптов запуска:
|
1 2 |
NAME READY STATUS RESTARTS AGE php-5d8f6bbf7f-56df2 0/1 podInitializing 0 39s |
Это указывает на то, что Init-контейнеры успешно запустились, и теперь инициализируются основные контейнеры:
|
1 2 |
NAME READY STATUS RESTARTS AGE php-5d8f6bbf7f-56df2 1/1 Running 0 4m10s |
Как видите, теперь ваш под запущен и работает. Однако, если ваш под не запускается, вы можете выполнить следующие команды для отладки:
1. Для просмотра подробной информации о поде:
|
1 |
$ kubectl describe pods pod-name |
2. Для просмотра логов пода:
|
1 |
$ kubectl logs pod-name |
3. Для просмотра логов конкретного контейнера в поде:
|
1 |
$ kubectl logs pod-name container-name |
Поздравляем! Вы успешно смонтировали код приложения, и служба PHP-FPM готова обрабатывать подключения. Аналогичным образом вы можете создать развертывание Nginx.
Шаг 5. Создание развертывания Nginx
Этот шаг покажет вам, как настроить Nginx с помощью ConfigMap. ConfigMap хранит все необходимые конфигурации в формате «ключ-значение», который будет использоваться в определениях других объектов Kubernetes. Такой подход дает вам гибкость для повторного использования или замены образа Nginx на другую версию по мере необходимости. Вы можете обновить ConfigMap, и эти изменения будут автоматически применены ко всем подам, монтирующим этот ConfigMap.
Для начала откройте файл nginx_configmap.yaml в вашем редакторе:
|
1 |
$ nano nginx_configMap.yaml |
Теперь назовите этот ConfigMap nginx-config и добавьте его в микросервис tier: backend:
|
1 2 3 4 5 6 |
apiVersion: v1 kind: ConfigMap metadata: name: nginx-config labels: tier: backend |
Кроме того, вы можете добавить данные в ConfigMap. Добавьте ключ с именем config и укажите все содержимое конфигурационного файла Nginx в качестве значения.
Поскольку Kubernetes может маршрутизировать запросы к соответствующим хостам для службы, вы можете указать имя вашей службы PHP-FPM в параметре fastcgi_pass вместо ее IP-адреса. Добавьте следующие строки кода в ваш файл nginx_configMap.yaml:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
... 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 файл будет выглядеть следующим образом:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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 — команду для создания ConfigMap:
|
1 |
$ kubectl apply -f nginx_configMap.yaml |
После этого вы должны увидеть на экране следующий вывод:
|
1 |
configmap/nginx-config created |
Вы успешно создали Nginx Configmap. Теперь вы можете создать Nginx Deployment.
Создание Nginx Deployment
Для начала вы можете создать новый файл с именем nginx_deployment.yaml в редакторе:
|
1 |
$ nano nginx_deployment.yaml |
Назовите этот Deployment nginx и добавьте к нему метку tier: backend:
|
1 2 3 4 5 6 7 |
apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: tier: backend |
После этого укажите количество реплик, добавив поле replica в спецификацию Deployment, и добавьте к нему метки app: nginx и tier: backend:
|
1 2 3 4 5 6 7 |
... spec: replicas: 1 selector: matchLabels: app: nginx tier: backend |
Аналогично добавьте шаблон пода. Убедитесь, что вы добавили те же метки, которые были добавлены в selector.matchLabels Deployment. Вы можете добавить следующее:
|
1 2 3 4 5 6 |
... template: metadata: labels: app: nginx tier: backend |
Предоставьте Nginx доступ к созданному ранее PVC code, добавив следующие параметры в раздел spec.template.spec.volumes:
|
1 2 3 4 5 6 |
... spec: volumes: - name: code persistentVolumeClaim: claimName: code |
|
1 2 3 4 5 6 7 |
... - name: config configMap: name: nginx-config items: - key: config path: site.conf |
Предупреждение: Содержимое ключа заменит mountPath тома, если файл не указан. Другими словами, вы потеряете все содержимое в целевой папке, если путь не указан явно.
Теперь укажите имя, образ и порт, которые вы хотите использовать в своем поде. Здесь мы будем использовать образ nginx:1.7.9 и порт 80. Добавьте их в раздел spec.template.spec раздел:
|
1 2 3 4 5 6 |
... containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 |
Также смонтируйте том code в /code, так как и Nginx, и PHP-FPM должны будут иметь доступ к файлу по одному и тому же пути:
|
1 2 3 4 |
... volumeMounts: - name: code mountPath: /code |
Образ nginx-1.7.9 автоматически загружает любой конфигурационный файл из папки /etc/nginx/conf.d. Теперь, если мы смонтируем том config в эту директорию, он создаст /etc/nginx/conf.d/site.conf. Добавьте следующее в раздел volumeMount:
|
1 2 3 |
... - name: config mountPath: /etc/nginx/conf.d |
После выполнения всех вышеперечисленных шагов ваш файл nginx_deployment.yaml должен выглядеть следующим образом:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
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 |
Теперь вы можете сохранить и закрыть файл и создать Deployment Nginx, выполнив следующую команду:
|
1 |
$ kubectl apply -f nginx_deployment.yaml |
При успешном выполнении команды вы должны увидеть следующий вывод:
|
1 |
deployment.apps/nginx created |
Вы можете вывести список всех ваших Deployments, выполнив следующие команды:
|
1 |
$ kubectl get deployments |
Теперь вы должны увидеть Deployments как для Nginx, так и для PHP-FPM:
Кроме того, вы можете выполнить следующую команду, чтобы вывести список подов, управляемых обоими перечисленными выше Deployments:
|
1 |
$ kubectl get pods |
Вы увидите, что оба ваших пода запущены и работают следующим образом:
Поскольку на данный момент все ваши объекты Kubernetes активны, теперь вы можете получить доступ к сервису Nginx в своем браузере.
Выполните следующую команду, чтобы вывести список сервисов:
|
1 |
$ kubectl get services -o wide |
Запишите External IP вашего сервиса Nginx:
Теперь, используя этот External IP сервиса Nginx, вы можете перейти на свой сервер, введя http://your_public_ip в своем браузере. Вы должны увидеть вывод php_info(), который подтверждает, что ваши сервисы Kubernetes запущены и работают.
Заключение
В этом руководстве, чтобы независимо управлять сервисами PHP-FPM и Nginx, вы контейнеризировали оба этих сервиса. Благодаря этому вы не только повысите масштабируемость своего проекта, но и будете эффективно использовать ресурсы. Вы также узнали, как создать локальное хранилище и Persistent Volume для хранения кода приложения на томе и иметь возможность легко обновлять свои сервисы в будущем. Таким образом вы повысили удобство использования и поддержки вашего кода.
Кроме того, ознакомьтесь с другими нашими руководствами по Docker и Kubernetes, которые вы можете найти в нашем блоге:
- Знакомство с Kubernetes
- Как создать кластер Kubernetes с помощью Kubeadm на Ubuntu 18.04
- Очистка ресурсов Docker — образов, контейнеров и томов
- Развертывание Laravel, Nginx и MySQL с помощью Docker Compose
- Как установить & управлять Docker на Ubuntu в публичном облаке
Приятной работы!


Комментарии
Комментариев пока нет. Будьте первым.