One place for hosting & domains

      Развертывание приложения PHP с Kubernetes на Ubuntu 16.04


      Автор выбрал фонд Open Internet/Free Speech Fund для получения пожертвования в рамках программы Write for DOnations.

      Введение

      Kubernetes — это система с открытым исходным кодом, предназначенная для оркестрации контейнеров. Она позволяет вам создавать, обновлять и масштабировать контейнеры, не беспокоясь о вынужденном простое.

      Для запуска PHP-приложения Nginx выступает в роли прокси-сервера для PHP-FPM. Контейнеризация этой системы в одном контейнере может быть обременительной задачей, но Kubernetes поможет организовать управление обоими службами, расположенными в отдельных контейнерах. Использование Kubernetes позволяет вам организовать многократное использование ваших контейнеров и переключение между ними, и вам не придется каждый раз повторно собирать образ контейнера при выходе новой версии Nginx или PHP.

      В этом руководстве вы развернете приложение PHP 7 в кластере Kubernetes с помощью Nginx и PHP-FPM, работающих в отдельных контейнерах. Также вы узнаете, как хранить ваши файлы конфигурации и код приложения за пределами образа контейнера, используя блочную систему хранения DigitalOcean. Такой подход позволит вам повторно использовать образ Nginx для любого приложения, которое нуждается в веб-сервере или прокси-сервере, передавая только том конфигурации без необходимости повторной сборки образа.

      Предварительные требования

      • Базовое понимание объектов 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.
      • metadata: здесь содержится name объекта наряду с labels, который вы можете захотеть применить к объекту.
      • spec: этот элемент содержит конкретную конфигурацию в зависимости от вида создаваемого объекта, например, образ контейнера или порты, через которые контейнер будет доступен.

      Сначала мы создадим директорию для хранения определений объекта Kubernetes.

      Подключитесь по SSH к своему главному узлу и создайте директорию definitions, где будут храниться определения объекта Kubernetes.

      Перейдите в недавно созданную директорию definitions:

      Создайте службу PHP-FPM с помощью создания файла php_service.yaml:

      Задайте значение Service для параметра kind для указания того, что этот объект представляет собой службу:

      php_service.yaml

      ...
      apiVersion: v1
      kind: Service
      

      Назовите службу php, поскольку она будет предоставлять доступ к PHP-FPM:

      php_service.yaml

      ...
      metadata:
        name: php
      

      Вы будете логически группировать различные объекты с помощью меток. В этом руководстве вы будете использовать метки для группирования объектов в уровни, например, фронтэнд или бекэнд. PHP-поды будут работать в фоне службы, поэтому вы можете пометить это следующим образом: tier: backend.

      php_service.yaml

      ...
        labels:
          tier: backend
      

      Служба определяет, какие поды следует подключить, с помощью меток selector. Под, соответствующий этим меткам, будет обслуживаться независимо от того, был ли под создан до или после службы. Ниже в этом руководстве вы узнайте, как добавлять метки для ваших подов.

      Используйте метку tier: backend для привязки пода к уровню бекэнда. Затем вы должны добавить метку app: php, чтобы указать, что этот под запускает PHP. Добавьте две эти метки после раздела metadata.

      php_service.yaml

      ...
      spec:
        selector:
          app: php
          tier: backend
      

      Затем укажите порт, используемый для доступа к этой службе. В этом руководстве вы будете использовать порт 9000. Добавьте его в файл php_service.yaml под разделом spec:

      php_service.yaml

      ...
        ports:
          - protocol: TCP
            port: 9000
      

      Ваш готовый файл php_service.yaml будет выглядеть следующим образом:

      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

      Данный вывод подтверждает создание службы:

      Output

      service/php created

      Убедитесь, что служба запущена:

      Вы увидите, что служба PHP-FPM работает:

      Output

      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

      Существуют различные типы служб, поддерживаемые Kubernetes. Ваша служба php использует тип службы по умолчанию, ClusterIP. Данный тип службы назначает внутренний IP-адрес и делает службу доступной только внутри кластера.

      Теперь, когда служба PHP-FPM готова, мы перейдем к созданию службы Nginx. Создайте и откройте новый файл nginx_service.yaml с помощью редактора:

      Данная служба будет затрагивать поды Nginx, поэтому вы должны будете назвать ее nginx. Затем вы должны будете добавить метку tier: backend, потому что она принадлежит к уровню бекэнда.

      nginx_service.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: nginx
        labels:
          tier: backend
      

      Как и в случае со службой php, настройте работу с подами с помощью меток selector — app: nginx и tier: backend. Cделайте эту службу доступной для порта 80, порта HTTP по умолчанию.

      nginx_service.yaml

      ...
      spec:
        selector:
          app: nginx
          tier: backend
        ports:
        - protocol: TCP
          port: 80
      

      Служба Nginx будет доступна из Интернета при использовании вашего открытого IP-адреса Droplet. <^>your_public_ip^> можно найти в вашей облачной панели DigitalOcean. В разделе spec.externalIPs добавьте:

      nginx_service.yaml

      ...
      spec:
        externalIPs:
        - your_public_ip
      

      Ваш файл nginx_service.yaml будет выглядеть следующим образом:

      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

      После запуска службы вы увидите следующий вывод:

      Output

      service/nginx created

      Для просмотра всех запущенных служб можно выполнить следующее:

      Вы увидите службы PHP-FPM и Nginx, представленные в результате выполнения команды:

      Output

      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

      Обратите внимание, что для удаления службы вы можете использовать следующую команду:

      • kubectl delete svc/service_name

      Теперь, когда вы создали службы PHP-FPM и Nginx, вам нужно указать, где вы будете хранить ваш код приложения и файлы конфигурации.

      Шаг 2 — Установка плагина хранилища DigitalOcean

      Kubernetes предоставляет различные плагины для хранения, которые позволяют создавать пространство для хранения вашей среды. На этом шаге вы будете устанавливать плагин хранилища DigitalOcean для создания блочного хранилища в DigitalOcean. После завершения установки будет добавлен класс хранения под названием do-block-storage, который вы будете использовать для создания блочного хранилища.

      Сначала вам нужно будет настроить для Kubernetes объект типа Secret для хранения маркера API DigitalOcean. Объекты Secret используются для обмена чувствительной информацией, например, ключами и паролями SSH, с другими объектами Kubernetes в одном пространстве имен. Пространства имен предоставляют способ логического разделения ваших объектов Kubernetes.

      Откройте файл secret.yaml в редакторе:

      Назовите ваш объект типа Secret digitalocean и добавьте его в пространство имен kube-system. Пространство имен kube-system — это используемое по умолчанию пространство имен для внутренних служб Kubernetes, которое также используется в плагине хранилища DigitalOcean для запуска различных компонентов.

      secret.yaml

      apiVersion: v1
      kind: Secret
      metadata:
        name: digitalocean
        namespace: kube-system
      

      Вместо ключа spec объект Secret использует ключ data или stringData для хранения необходимой информации. Параметр data хранит закодированные с помощью стандарта base64 данные, которые автоматически расшифровываются при получении. Параметр stringData хранит незашифрованные данные, автоматически закодированные во время создания или обновления, и не выводит данные при получении объектов типа Secret. Для удобства вы будете использовать stringData в рамках этого руководства.

      Добавьте access-token в качестве stringData:

      secret.yaml

      ...
      stringData:
        access-token: your-api-token
      

      Сохраните и закройте файл.

      Ваш файл secret.yaml будет выглядеть следующим образом:

      secret.yaml

      apiVersion: v1
      kind: Secret
      metadata:
        name: digitalocean
        namespace: kube-system
      stringData:
        access-token: your-api-token
      

      Создайте объект типа Secret:

      • kubectl apply -f secret.yaml

      Вы увидите следующий результат при создании объекта Secret:

      Output

      secret/digitalocean created

      Вы можете просмотреть объект Secret с помощью следующей команды:

      • kubectl -n kube-system get secret digitalocean

      Результат будет выглядеть примерно следующим образом:

      Output

      NAME TYPE DATA AGE digitalocean Opaque 1 41s

      Тип Opaque означает, что этот объект типа Secret предназначен только для чтения, что соответствует стандарту для объектов Secret stringData. Вы можете ознакомиться с дополнительной информацией о данных объектах в Спецификации для объектов типа Secret. Поле DATA отображает количество предметов, сохраненных в данном объекте Secret. В этом случае он отображает 1, потому что вы сохранили один ключ.

      Теперь, когда ваш объект Secret был создан, установите плагин хранилища DigitalOcean:

      • kubectl apply -f https://raw.githubusercontent.com/digitalocean/csi-digitalocean/master/deploy/kubernetes/releases/csi-digitalocean-v0.3.0.yaml

      Вы увидите примерно следующий результат:

      Output

      storageclass.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 — Создание постоянного тома

      После создания объекта типа Secret и установки плагина блочного хранилища вы можете создать собственный постоянный том. Постоянный том (Persistent Volume, PV) — это блочное хранилище заданного размера, которое существует независимо от жизненного цикла пода. Использование постоянного тома позволит вам управлять или обновлять поды, не беспокоясь о потере кода приложения. Доступ к постоянному тому можно получить с помощью PersistentVolumeClaim, или PVC, который монтирует постоянный том по требуемому пути.

      Откройте файл code_volume.yaml в редакторе:

      Присвойте PVC имя code, добавив в файл следующие параметры и значения:

      code_volume.yaml

      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: code
      

      spec для PVC содержит следующие элементы:

      • accessModes, значение которого может меняться в зависимости от варианта использования. Ниже представлены возможные варианты:
        • ReadWriteOnce — монтирует том для чтения и записи с помощью одного узла
        • ReadOnlyMany — монтирует том только для чтения с помощью многих узлов
        • ReadWriteMany — монтирует том для чтения и записи с помощью многих узлов
      • resources — пространство для хранилища, которое вам требуется

      Блочное хранилище DigitalOcean устанавливается только на один узел, поэтому для accessModes нужно установить значение ReadWriteOnce. В этом обучающем руководстве вы будете добавлять небольшое количество кода приложения, поэтому в нашем случае будет достаточно 1 ГБ. Если вы планируете хранить большее количество кода или данных в томе, вы можете изменять параметр storage согласно вашим потребностям. Вы можете увеличить объем хранилища после создания тома, но сокращение диска не поддерживается.

      code_volume.yaml

      ...
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
      

      Далее укажите класс хранилища, который Kubernetes будет использовать для предоставления томов. Вы будете использовать класс do-block-storage, созданный плагином блочного хранилища DigitalOcean.

      code_volume.yaml

      ...
        storageClassName: do-block-storage
      

      Ваш файл code_volume.yaml будет выглядеть следующим образом:

      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 ГБ в качестве тома.

      Output

      persistentvolumeclaim/code created

      Для просмотра доступных постоянных томов (PV):

      Вы увидите в списке постоянные тома:

      Output

      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, а также из инфраструктуры DigitalOcean. Вы можете получить дополнительные данные о параметрах Reclaim Policy (Политика восстановления) и Status (Статус) в документации Kubernetes PV.

      Вы успешно создали постоянный том с помощью плагина блочного хранилища DigitalOcean. Теперь, когда ваш постоянный том готов, вы можете создать ваши поды с помощью развертывания.

      Шаг 4 — Создание Deployment (Развертывания) PHP-FPM

      На этом шаге вы научитесь использовать Deployment (Развертывание) для создания вашего пода PHP-FPM. Развертывания предоставляют единообразный способ создания, обновления подов и управления ими с помощью ReplicaSets. Если обновление не работает ожидаемым образом, Deployment будет автоматически возвращать свои поды к предыдущему образу.

      Ключ для развертывания spec.selector будет содержать список меток подов, которыми будет управлять. Также мы будем использовать ключ template для создания требуемых подов.

      Кроме того, на этом шаге мы познакомимся с использованием Init-контейнеров. Init-контейнеры запускают одну или несколько команд, прежде чем будут запущены обычные контейнеры, указанные в ключе template пода. В этом обучающем руководстве ваш Init-контейнер будет получать пример файла index.php из GitHub Gist с помощью wget. Вот как выглядит содержимое примера файла:

      index.php

      <?php
      echo phpinfo();
      

      Для создания развертывания откройте новый файл с именем php_deployment.yaml в вашем редакторе:

      Это развертывание будет управлять вашими подами PHP-FPM, поэтому вы должны использовать для объекта Deployment имя php. Поды принадлежат к уровню бекэнда, поэтому вы должны объединить развертывание в эту группу с помощью метки tier: backend:

      php_deployment.yaml

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: php
        labels:
          tier: backend
      

      Для элемента spec развертывания вы должны будете указать, сколько экземпляров этого пода нужно создать, используя параметр replicas. Значение параметра replicas будет варьироваться в зависимости от ваших потребностей и доступных ресурсов. В этом обучающем руководстве мы создадим одну реплику:

      php_deployment.yaml

      ...
      spec:
        replicas: 1
      

      Это развертывание будет управлять подами с метками app: php и tier: backend. Рядом с ключом selector добавьте:

      php_deployment.yaml

      ...
        selector:
          matchLabels:
            app: php
            tier: backend
      

      Далее для элемента spec необходимо задать значение template для определения объекта вашего пода. Этот шаблон определяет спецификации, на основании которых создается под. Во-первых, вам нужно добавить метки, которые были указаны для selectors службы php и matchLabels развертывания. Добавьте app: php и tier: backend в template.metadata.labels:

      php_deployment.yaml

      ...
        template:
          metadata:
            labels:
              app: php
              tier: backend
      

      Под может иметь несколько контейнеров и томов, но для каждого из них потребуется имя. Вы можете избирательно монтировать тома в контейнер, указав путь для каждого тома.

      Во-первых, укажите тома, к которым будут подключены ваши контейнеры. Вы создали PVC с именем code для хранения кода приложения, поэтому вы должны присвоить этому тому аналогичное имя code. В разделе spec.template.spec.volumes добавьте следующее:

      php_deployment.yaml

      ...
          spec:
            volumes:
            - name: code
              persistentVolumeClaim:
                claimName: code
      

      Затем укажите контейнер, который вы хотите запустить в этом поде. Вы можете найти различные образы в магазине Docker, но в этом руководстве мы будем использовать образ php:7-fpm.

      В разделе spec.template.spec.containers добавьте следующее:

      php_deployment.yaml

      ...
            containers:
            - name: php
              image: php:7-fpm
      

      Теперь нужно смонтировать тома, к которым контейнеру требуется доступ. Этот контейнер будет запускать ваш код PHP, поэтому ему потребуется доступ к тому code. Также вы будете использовать mountPath, чтобы задать /code в качестве точки для монтирования.

      В spec.template.spec.containers.volumeMounts добавьте:

      php_deployment.yaml

      ...
              volumeMounts:
              - name: code
                mountPath: /code
      

      Теперь, когда вы смонтировали ваш том, вам нужно поместить код приложения в том. Возможно, вы ранее использовали FTP/SFTP или клонировали код через соединение SSH, чтобы добиться этого, но на данном этапе мы покажем, как скопировать код с помощью Init-контейнера.

      В зависимости от сложности процесса настройки вы можете использовать либо один initContainer для запуска скрипта, который собирает ваше приложение, либо один initContainer для каждой команды. Убедитесь, что тома монтируются в initContainer.

      В этом руководстве вы будете использовать один Init-контейнер с busybox для загрузки кода. busybox — это небольшой образ, содержащий утилиту wget, которую вы будете использовать для этой цели.

      В spec.template.spec добавьте ваш initContainer и укажите образ busybox:

      php_deployment.yaml

      ...
            initContainers:
            - name: install
              image: busybox
      

      Вашему Init-контейнеру потребуется доступ к тому code, чтобы выполнить загрузку кода в это место. В spec.template.spec.initContainers смонтируйте том code на путь /code:

      php_deployment.yaml

      ...
              volumeMounts:
              - name: code
                mountPath: /code
      

      Для каждого Init-контейнера необходимо запустить command. Ваш Init-контейнер будет использовать wget для загрузки кода с Github в рабочую директорию /code. Параметр -O предоставляет загруженному файлу имя, и вы должны будете назвать этот файл index.php.

      Примечание: обязательно проверьте код, который вы загружаете. Проверьте исходный код, прежде чем загружать его на сервер, чтобы убедиться, что код не делает ничего, что может вам не понравиться.

      Для контейнера install в spec.template.spec.initContainers добавьте следующие строки:

      php_deployment.yaml

      ...
              command:
              - wget
              - "-O"
              - "/code/index.php"
              - https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php
      

      Ваш готовый файл php_deployment.yaml будет выглядеть следующим образом:

      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

      Вы увидите следующий результат создания развертывания:

      Output

      deployment.apps/php created

      В конце концов данное развертывание начнет загружать заданные образы. Затем оно запросит PersistentVolume у PersistentVolumeClaim и последовательно запустит ваши initContainers. После завершения контейнеры будут запускаться и монтировать тома в заданную точку монтирования. После завершения всех этих шагов ваш под будет готов к работе и запущен.

      Вы можете просмотреть ваше развертывание с помощью следующей команды:

      Результат будет выглядеть следующим образом:

      Output

      NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE php 1 1 1 0 19s

      Данный вывод поможет вам понять текущее состояние развертывания. Развертывание — один из контроллеров, поддерживающих желаемое состояние. Созданный вами шаблон указывает, что состояние DESIRED будет иметь 1 реплику пода с именем php. Поле CURRENT указывает, сколько реплик запущено, поэтому эти данные должны соответствовать данным состояния DESIRED. Вы можете ознакомиться с дополнительными данными в документации по развертыванию в Kubernetes.

      С помощью следующей команды можно просмотреть поды, запущенные данным развертыванием:

      Вывод этой команды варьируется в зависимости от того, сколько времени прошло с момента создания развертывания. Если вы запустили его сразу после создания, результат будет выглядеть следующим образом:

      Output

      NAME READY STATUS RESTARTS AGE php-86d59fd666-bf8zd 0/1 Init:0/1 0 9s

      Столбцы представляют следующую информацию:

      • Ready: количество реплик, запускающих под.
      • Status: состояние пода. Init указывает, что Init-контейнеры запущены. В этом выводе 0 из 1 Init-контейнера прекратили работу.
      • Restarts: сколько раз этот процесс был перезапущен для запуска пода. Это число будет увеличиваться, если какой-либо из ваших Init-контейнеров прекратит работу. Развертывание будет перезапущено, пока не будет достигнуто желаемое состояние.

      В зависимости от сложности ваших скриптов запуска может потребоваться несколько минут, чтобы состояние поменялось на podInitializing:

      Output

      NAME READY STATUS RESTARTS AGE php-86d59fd666-lkwgn 0/1 podInitializing 0 39s

      Это означает, что Init-контейнер завершил работу, и контейнеры инициализируются. Если вы запустите команду, когда все контейнеры запущены, вы увидите, что статус пода изменился на Running.

      Output

      NAME READY STATUS RESTARTS AGE php-86d59fd666-lkwgn 1/1 Running 0 1m

      Теперь вы увидите, что ваш под успешно запущен. Если ваш под не был запущен, вы можете выполнить отладку с помощью следующих команд:

      • Просмотр подробной информации о поде:
      • kubectl describe pods 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​​​:

      nginx_configMap.yaml

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: nginx-config
        labels:
          tier: backend
      

      Затем вы должны будете добавить данные для ConfigMap. Присвойте ключу имя config и добавьте содержимое файла конфигурации Nginx в качестве значения. Вы можете воспользоваться примером конфигурации Nginx из этого руководства.

      Поскольку Kubernetes может перенаправлять запросы на соответствующий хост для службы, вы можете ввести имя службы PHP-FPM для параметра fastcgi_pass вместо его IP-адреса. Добавьте следующее в файл nginx_configMap.yaml:

      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 будет выглядеть следующим образом:

      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;
              }
          }
      

      Сохраните файл и выйдите из редактора.

      Создайте ConfigMap:

      • kubectl apply -f nginx_configMap.yaml

      Результат будет выглядеть следующим образом:

      Output

      configmap/nginx-config created

      Вы завершили создание ConfigMap и теперь можете выполнить сборку вашего развертывания Nginx.

      Для начала откройте новый файл nginx_deployment.yaml в редакторе:

      • nano nginx_deployment.yaml

      Назовите развертывание nginx и добавьте метку tier: backend:

      nginx_deployment.yaml

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx
        labels:
          tier: backend
      

      Укажите, что вам нужна одна реплика в spec развертывания. Это развертывание будет управлять подами с метками app:nginx и tier:backend. Добавьте следующие параметры и значения:

      nginx_deployment.yaml

      ...
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: nginx
            tier: backend
      

      Затем добавьте шаблон пода. Вам нужно использовать те же метки, которые вы добавили для развертывания selector.matchLabels. Добавьте следующее:

      nginx_deployment.yaml

      ...
        template:
          metadata:
            labels:
              app: nginx
              tier: backend
      

      Предоставьте Nginx доступ к code PVC, который вы создали ранее. В spec.template.spec.volumes добавьте:

      nginx_deployment.yaml

      ...
          spec:
            volumes:
            - name: code
              persistentVolumeClaim:
                claimName: code
      

      Поды могут монтировать ConfigMap в качестве тома. При указании имени файла и ключа будет создан файл с содержимым в виде его значения. Для использования ConfigMap настройте в качестве path имя файла, где будет храниться содержимое key. Вам нужно создать файл site.conf из ключа config. В разделе spec.template.spec.volumes добавьте следующее:

      nginx_deployment.yaml

      ...
            - 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 добавьте:

      nginx_deployment.yaml

      ...
            containers:
            - name: nginx
              image: nginx:1.7.9
              ports:
              - containerPort: 80
      

      Nginx и PHP-FPM требуется доступ к файлу с одним путем, поэтому вы должны смонтировать том code в /code:

      nginx_deployment.yaml

      ...
              volumeMounts:
              - name: code
                mountPath: /code
      

      Образ nginx:1.7.9 будет автоматически загружать любые файлы конфигурации в директорию /etc/nginx/conf.d. При монтировании тома config в этой директории будет создан файл /etc/nginx/conf.d/site.conf. В volumeMounts добавьте следующее:

      nginx_deployment.yaml

      ...
              - name: config
                mountPath: /etc/nginx/conf.d
      

      Ваш файл nginx_deployment.yaml будет выглядеть следующим образом:

      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

      Следующий вывод означает, что ваше развертывание было успешно создано:

      Output

      deployment.apps/nginx created

      Сформируйте список ваших развертываний с помощью этой команды:

      Вы увидите развертывания Nginx и PHP-FPM:

      Output

      NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx 1 1 1 0 16s php 1 1 1 1 7m

      Сформируйте список подов, которые управляются обоими развертываниями:

      Вы увидите запущенные поды:

      Output

      NAME 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:

      Output

      NAME 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, чтобы вы могли управлять ими независимо. Такой подход не только повышает масштабируемость вашего проекта в процессе роста, но также позволит эффективно использовать ресурсы. Также вы сохранили код приложения в томе, чтобы вы могли легко обновить ваши службы в будущем.



      Source link

      Cómo instalar la pila Linux, Apache, MariaDB, PHP (LAMP) en Debian 9


      Introducción

      Una pila “LAMP” es un grupo de aplicaciones de software de código abierto que se instalan normalmente juntas para permitir que un servidor aloje aplicaciones web y sitios web dinámicos. Este término es en realidad un acrónimo que representa al sistema operativo Linux y al servidor web Apache. Los datos del sitio se almacenan en una base de datos MariaDB y el contenido dinámico se procesa mediante PHP.

      En esta guía, instalaremos una pila LAMP en un servidor Debian 9.

      Requisitos previos

      Para completar este tutorial, deberá disponer de un servidor de Debian 9 con una cuenta de usuario sudo no root y un firewall básico. Esto se puede configurar usando nuestra guía de configuración inicial de servidores para Debian 9.

      Paso 1: Instalar Apache y actualizar el firewall

      El servidor web Apache está entre los más populares del mundo. Cuenta con una completa documentación y se ha usado extensamente durante gran parte de la historia de la Web, lo que lo convierte en una gran opción para alojar un sitio web.

      Instale Apache usando apt, el administrador de paquetes de Debian:

      • sudo apt update
      • sudo apt install apache2

      Ya que este es un comando sudo, estas operaciones se ejecutan con privilegios root. Le pedirá su contraseña de usuario normal para verificar sus intenciones.

      Una vez que introduzca su contraseña, apt le indicará los paquetes que planea instalar y el espacio adicional que ocuparán en el disco duro. Pulse Y y luego ENTER para continuar. Con esto, la instalación continuará.

      A continuación, suponiendo que seguió las instrucciones de configuración inicial del servidor instalando y habilitando el firewall UFW, asegúrese de que su firewall permita el tráfico HTTP y HTTPS.

      Cuando se instala en Debian 9, UFW se carga con perfiles de app que puede usar para ajustar la configuración de su firewall. Vea la lista completa de perfiles de aplicaciones ejecutando lo siguiente:

      Los perfiles WWW se utilizan para administrar los puertos usados por servidores web:

      Output

      Available applications: . . . WWW WWW Cache WWW Full WWW Secure . . .

      Si inspecciona el perfil WWW Full, este muestra que permite el tráfico a los puertos 80 y 443.

      • sudo ufw app info "WWW Full"

      Output

      Profile: WWW Full Title: Web Server (HTTP,HTTPS) Description: Web Server (HTTP,HTTPS) Ports: 80,443/tcp

      Permita el tráfico HTTP y HTTPS para este perfil:

      • sudo ufw allow in “WWW Full”

      Puede realizar una comprobación de inmediato para verificar que todo está en orden visitando la dirección IP pública de su servidor en su navegador web.

      http://your_server_ip
      

      Verá la página web predeterminada de Apache de Debian 9, que se encuentra allí para fines informativos y de prueba. Debería tener un aspecto similar a este:

      Página predeterminada de Apache de Debian 9

      Si ve esta página, su servidor web estará correctamente instalado y el acceso a él será posible a través de su firewall.

      Si no conoce la dirección IP pública de su servidor, hay varias formas de encontrarla. Por lo general, es la dirección que utiliza para establecer conexión con su servidor a través de SSH.

      Existen varias formas de hacerlo desde la línea de comandos. Primero, podría usar las herramientas de iproute2 para obtener su dirección IP escribiendo esto:

      • ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's//.*$//'

      Esto nos brindará dos o tres líneas. Todas estas direcciones son correctas, pero su computadora puede usar una de ellas. Por ello, no dude en probarlas todas.

      Un método alternativo consiste en usar la utilidad curl para contactar a una parte externa a fin de que le indique su evaluación del servidor. Esto se hace solicitando a un servidor específico su dirección IP:

      • sudo apt install curl
      • curl http://icanhazip.com

      Independientemente del método que utilice para obtener su dirección IP, escríbala en la barra de direcciones de su navegador web para ver la página predeterminada de Apache.

      Paso 2: Instalar MariaDB

      Ahora que su servidor web está listo, es el momento de instalar MariaDB. MariaDB es un sistema de administración de bases de datos. Básicamente, organizará y brindará acceso a bases de datos en las que su sitio puede almacenar información.

      MariaDB es una ramificación de MySQL creada por la comunidad. En Debian 9, el servidor de MySQL predeterminado es MariaDB 10.1, y mysql-server, que normalmente se utiliza para instalar MySQL, es un paquete de transición que instalará MariaDB. Sin embargo, se recomienda instalar MariaDB usando el paquete real del programa: mariadb-server.

      Una vez más, utilice apt para adquirir e instalar este software:

      • sudo apt install mariadb-server

      Nota: En este caso, no es necesario que ejecute sudo apt update antes del comando. Esto se debe a que recientemente lo ejecutó en los comandos anteriores para instalar Apache y el índice de paquetes de su computadora debería estar actualizado.

      Este comando, además, le mostrará una lista de los paquetes que se instalarán y el espacio que ocuparán en el disco. Ingrese Y para continuar.

      Cuando se complete la instalación, ejecute una secuencia de comandos de seguridad sencilla que viene con MariaDB previamente instalada. Con esto, se eliminarán algunos ajustes predeterminados y se bloqueará el acceso a su sistema de bases de datos. Inicie la secuencia de comandos interactiva ejecutando lo siguiente:

      • sudo mysql_secure_installation

      Con esto, verá una serie de solicitudes mediante las cuales podrá realizar cambios en las opciones de seguridad de su instalación de MariaDB. En la primera solicitud se pedirá que introduzca la contraseña root de la base de datos actual. Esta es una cuenta administrativa de MariaDB que tiene mayores privilegios. Considérela como algo similar a la cuenta root para el propio servidor (aunque la que está configurando ahora sea una cuenta específica de MariaDB). Debido a que acaba de instalar MariaDB y aún no realizó aún cambios en la configuración, el espacio de esta contraseña estará en blanco. Por ello, pulse ENTER en la solicitud.

      En la siguiente solicitud se pregunta si desea configurar una contraseña root de la base de datos. Escriba N y pulse ENTER. En Debian, la cuenta root para MariaDB está estrechamente vinculada al mantenimiento del sistema automatizado, por tanto no deberíamos cambiar los métodos de autenticación configurados para esa cuenta. Hacer esto permitiría que una actualización de paquetes dañara el sistema de bases de datos eliminando el acceso a la cuenta administrativa. Más tarde, se explicará la manera configurar de forma opcional una cuenta administrativa adicional para el acceso con contraseña si la autenticación del socket no es apropiada para su caso de uso.

      Desde allí, puede pulsar Y y luego ENTER para aceptar los valores predeterminados para todas las preguntas siguientes. Con esto, se eliminarán algunos usuarios anónimos y la base de datos de prueba, se deshabilitarán las credenciales de inicio de sesión remoto de root y se cargarán estas nuevas reglas para que MariaDB aplique de inmediato los cambios que realizó.

      En las nuevas instalaciones en sistemas Debian, el usuario root de MariaDB está configurado para autenticarse usando el complemento unix_socket de forma predeterminada en lugar de una contraseña. Esto proporciona una mayor seguridad y utilidad en muchos casos, pero también puede generar complicaciones cuando necesita otorgar derechos administrativos a un programa externo (por ejemplo, phpMyAdmin).

      Debido a que el servidor utiliza la cuenta root para tareas como la rotación de registros y el inicio y la deteneción del servidor, es mejor no cambiar los detalles de autenticación root de la cuenta. La modificación de las credenciales de la cuenta en /etc/mysql/debian.cnf puede funcionar al principio, pero las actualizaciones de paquetes pueden sobrescribir esos cambios. En vez de modificar la cuenta root, los encargados del mantenimiento de paquetes recomiendan crear una cuenta administrativa independiente si necesita configurar un acceso basado en contraseña.

      Para hacerlo, crearemos una nueva cuenta llamada admin con las mismas capacidades que la cuenta root, pero configurada para la autenticación de contraseñas. Para hacer esto, abra la instrucción de MariaDB desde su terminal:

      Ahora, podremos crear un nuevo usuario con privilegios root y acceso basado en contraseña. Cambie el nombre de usuario y la contraseña según sus preferencias:

      • GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;

      Vacíe los privilegios para garantizar que se guarden y estén disponibles en la sesión actual:

      Después de esto, cierre el shell de MariaDB:

      Ahora, en cualquier momento que desee acceder a su base de datos como su nuevo usuario administrativo, deberá autenticarse como ese usuario con la contraseña que acaba de configurar usando el siguiente comando:

      En este momento, el sistema de base de datos está configurado y puede proceder a instalar PHP, el componente final de la pila LAMP.

      Paso 3: Instalar PHP

      PHP es el componente de su configuración que procesará código para mostrar contenido dinámico. Puede ejecutar secuencias de comandos, establecer conexión con sus bases de datos de MariaDB para obtener información y entregar el contenido procesado a su servidor web para su visualización.

      Una vez más, utilice el sistema apt para instalar PHP. Además, incluye algunos paquetes de helper esta vez para que el código de PHP pueda ejecutarse con el servidor Apache y comunicarse con su base de datos de MariaDB:

      • sudo apt install php libapache2-mod-php php-mysql

      Con esto, PHP debería instalarse sin problemas. Lo probaremos en un momento.

      En la mayoría de los casos, le convendrá modificar la forma en que Apache presenta los archivos cuando se solicita un directorio. Actualmente, si un usuario solicita un directorio del servidor, Apache buscará primero un archivo llamado index.html. Queremos indicar al servidor web que priorice los archivos PHP respecto de otros. Por ello, haga que Apache busque primero un archivo index.php.

      Para hacer esto, escriba este comando a fin de abrir el archivo dir.conf en un editor de texto con privilegios root:

      • sudo nano /etc/apache2/mods-enabled/dir.conf

      Tendrá un aspecto similar a este:

      /etc/apache2/mods-enabled/dir.conf

      <IfModule mod_dir.c>
          DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm
      </IfModule>
      

      Mueva el archivo de índice PHP (resaltado arriba) a la primera posición después de la especificación DirectoryIndex, como se muestra a continuación:

      /etc/apache2/mods-enabled/dir.conf

      <IfModule mod_dir.c>
          DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm
      </IfModule>
      

      Cuando termine, guarde y cierre el archivo pulsando CTRL+X. Confirme que desea guardar los cambios escribiendo Y y luego pulse ENTER para verificar la ubicación en la que se guardará el archivo.

      Después de esto, reinicie el servidor web Apache para que se reconozcan sus cambios. Hágalo escribiendo lo siguiente:

      • sudo systemctl restart apache2

      También puede verificar el estado del servicio apache2 usando systemctl:

      • sudo systemctl status apache2

      Sample Output

      ● apache2.service - The Apache HTTP Server Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2018-09-04 18:23:03 UTC; 9s ago Process: 22209 ExecStop=/usr/sbin/apachectl stop (code=exited, status=0/SUCCESS) Process: 22216 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS) Main PID: 22221 (apache2) Tasks: 6 (limit: 4915) CGroup: /system.slice/apache2.service ├─22221 /usr/sbin/apache2 -k start ├─22222 /usr/sbin/apache2 -k start ├─22223 /usr/sbin/apache2 -k start ├─22224 /usr/sbin/apache2 -k start ├─22225 /usr/sbin/apache2 -k start └─22226 /usr/sbin/apache2 -k start

      Para mejorar la funcionalidad de PHP, tendrá la opción de instalar algunos módulos adicionales. Para ver las opciones disponibles para módulos y bibliotecas PHP, canalice los resultados de apt search en less, un localizador que le permite desplazarse por el resultado de otros comandos:

      Utilice las teclas de flecha para desplazarse arriba y abajo, y pulse Q para salir.

      Como resultado, obtendrá todos los componentes opcionales que puede instalar. Verá una breve descripción de cada uno:

      Output

      Sorting... Full Text Search... bandwidthd-pgsql/stable 2.0.1+cvs20090917-10 amd64 Tracks usage of TCP/IP and builds html files with graphs bluefish/stable 2.2.9-1+b1 amd64 advanced Gtk+ text editor for web and software development cacti/stable 0.8.8h+ds1-10 all web interface for graphing of monitoring systems cakephp-scripts/stable 2.8.5-1 all rapid application development framework for PHP (scripts) ganglia-webfrontend/stable 3.6.1-3 all cluster monitoring toolkit - web front-end haserl/stable 0.9.35-2+b1 amd64 CGI scripting program for embedded environments kdevelop-php-docs/stable 5.0.3-1 all transitional package for kdevelop-php kdevelop-php-docs-l10n/stable 5.0.3-1 all transitional package for kdevelop-php-l10n … :

      En Internet podrá obtener más información sobre lo que hace cada módulo. También puede consultar la descripción extensa del paquete escribiendo lo siguiente:

      Verá muchos resultados; habrá un campo llamado Description, que tendrá una explicación más larga de la funcionalidad que proporciona el módulo.

      Por ejemplo, para saber qué hace el módulo php-cli, puede escribir lo siguiente:

      Junto con una gran cantidad de información, encontrará algo similar a esto:

      Output

      … Description: command-line interpreter for the PHP scripting language (default) This package provides the /usr/bin/php command interpreter, useful for testing PHP scripts from a shell or performing general shell scripting tasks. . PHP (recursive acronym for PHP: Hypertext Preprocessor) is a widely-used open source general-purpose scripting language that is especially suited for web development and can be embedded into HTML. . This package is a dependency package, which depends on Debian's default PHP version (currently 7.0). …

      Si después de investigar decide que desea instalar un paquete, puede hacerlo usando el comando apt install como lo ha hecho con el otro software.

      Si determina que necesita php-cli, puede escribir lo siguiente:

      Si desea instalar más de un módulo, puede hacerlo enumerando cada uno de ellos, separados por un espacio, con el comando apt install, como se muestra a continuación:

      • sudo apt install package1 package2 ...

      En este punto, su pila LAMP estará instalada y confgurada. Antes de realizar más cambios o implementar una aplicación, sería útil probar de forma proactiva su configuración PHP en caso de que haya problemas que deban abordarse.

      Paso 4: Probar el procesamiento de PHP en su servidor web

      A fin de verificar que su sistema esté configurado de forma adecuada para PHP, cree una secuencia de comandos PHP muy básica llamada info.php. Para que Apache encuentre este archivo y lo presente correctamente, debe guardarse en un directorio muy específico llamado web root.

      En Debian 9, este directorio se encuentra en /var/www/html/. Cree el archivo en esa ubicación ejecutando lo siguiente:

      • sudo nano /var/www/html/info.php

      Con esto se abrirá un archivo vacío. Añada el siguiente texto, que es el código PHP válido, dentro del archivo:

      /var/www/html/info.php

      <?php
      phpinfo();
      ?>
      

      Cuando termine, guarde y cierre el archivo.

      Ahora puede probar si su servidor web puede mostrar correctamente el contenido generado por esta secuencia de comandos PHP. Para probar esto, visite esta página en su navegador web. Necesitará de nuevo la dirección IP pública de su servidor.

      La dirección que le convendrá visitar es la siguiente:

      http://your_server_ip/info.php
      

      La página a la que llegue debería tener un aspecto similar a este:

      Información de PHP predeterminada de Debian 9

      En esta página se proporciona información básica sobre su servidor desde la perspectiva de PHP. Es útil para la depuración y para asegurarse de que sus ajustes se apliquen correctamente.

      Si puede ver esta página en su navegador, su PHP funcionará como se espera.

      Probablemente desee eliminar este archivo tras esta prueba, ya que podría proporcionar información sobre su servidor a usuarios no autorizados. Para hacer esto, ejecute el siguiente comando:

      • sudo rm /var/www/html/info.php

      Siempre puede recrear esta página si necesita acceder a la información posteriormente.

      Conclusión

      Ahora que dispone de una pila LAMP instalada, tiene muchas opciones respecto de lo que puede hacer a continuación. Básicamente, instaló una plataforma que le permitirá instalar la mayoría de los tipos de sitios y recursos de software web en su servidor.



      Source link

      Cómo implementar una aplicación PHP con Kubernetes en Ubuntu 16.04


      El autor seleccionó Open Internet/Free Speech para recibir una donación como parte del programa Write for DOnations.

      Introducción

      Kubernetes es un sistema de orquestación de contenedores de código abierto. Le permite crear, actualizar y escalar contenedores sin preocuparse por el tiempo de inactividad.

      Para ejecutar una aplicación PHP, Nginx funciona como proxy para PHP-FPM. Disponer esta configuración en un solo contenedor puede ser un proceso engorroso, pero Kubernetes permitirá administrar ambos servicios en contenedores separados. Utilizar Kubernetes le permitirá lograr que sus contenedores sean reutilizables e intercambiables, y no tendrá que reconstruir la imagen de sus contenedores cada vez que haya una nueva versión de Nginx o PHP.

      En este tutorial, implementará una aplicación PHP 7 en un clúster de Kubernetes con Nginx y PHP-FPM ejecutándose en contenedores separados. También aprenderá a mantener los archivos de configuración y el código de aplicación fuera de la imagen de contenedor que utilice el sistema de almacenamiento en bloque de DigitalOcean. Este enfoque le permitirá reutilizar la imagen de Nginx para cualquier aplicación que necesite un servidor web o proxy pasando un volumen de configuración en lugar de reconstruir la imagen.

      Requisitos previos

      Paso 1: Crear los servicios de PHP-FPM y Nginx

      En este paso, creará los servicios de PHP-FPM y Nginx. Un servicio permite acceder a un conjunto de pods desde el interior del clúster. Los servicios dentro de un clúster pueden comunicarse de forma directa a través de sus nombres, sin necesidad de direcciones IP. El servicio de PHP-FPM permitirá el acceso a los pods de PHP-FPM, mientras que el servicio Nginx permitirá el acceso a los pods de Nginx.

      Debido a que los pods de Nginx representarán los pods de PHP-FPM, tendrá que indicar al servicio la forma de encontrarlos. En lugar de utilizar direcciones IP, aprovechará la detección automática de servicios de Kubernetes para utilizar nombres legibles para humanos para dirigir solicitudes al servicio apropiado.

      Para crear el servicio, creará un archivo de definición de objeto. Cada definición de objeto de Kubernetes es un archivo YAML que contiene por lo menos los siguientes elementos:

      • apiVersion: versión de la API de Kubernetes a la que pertenece la definición.
      • kind: objeto de Kubernetes que este archivo representa. Por ejemplo,un pod o service.
      • metadata: contiene el name del objeto junto con cualquier labels que desee aplicarle.
      • spec: contiene una configuración específica según el tipo de objeto que cree, como la imagen del contenedor o los puertos en los cuales se podrá acceder a este.

      Primero, creará un directorio para contener sus definiciones de objetos de Kubernetes.

      Aplique SSH a su *nodo maestro *y cree el directorio definitions que contendrá sus definiciones de objetos de Kubernetes.

      Acceda al directorio definitions recién creado:

      Realice su servicio de PHP-FPM creando un archivo php_service.yaml:

      Establezca kind como Service para especificar que este objeto es un servicio:

      php_service.yaml

      ...
      apiVersion: v1
      kind: Service
      

      Nombre el servicio como php, ya que proporcionará acceso a PHP-FPM:

      php_service.yaml

      ...
      metadata:
        name: php
      

      Agrupará de manera lógica diferentes objetos con etiquetas. En este tutorial, utilizará etiquetas para agrupar los objetos en “niveles”, como frontend o backend. Los pods de PHP se ejecutarán detrás de este servicio, por lo que le asignará la etiqueta tier: backend.

      php_service.yaml

      ...
        labels:
          tier: backend
      

      Un servicio determina los pods a los que se debe acceder utilizando las etiquetas selector. Se servirá un pod que coincida con estas etiquetas, independiente de que este se cree antes o después del servicio. Agregará etiquetas para sus pods posteriormente en el tutorial.

      Utilice la etiqueta tier: backend para asignar el pod al nivel de backend. También agregará la etiqueta app: php para especificar que este pod ejecuta PHP. Agregue estas dos etiquetas después de la sección de metadata.

      php_service.yaml

      ...
      spec:
        selector:
          app: php
          tier: backend
      

      A continuación, especifique el puerto utilizado para acceder a este servicio. En este tutorial, utilizará el puerto 9000. Añádalo al archivo php_service.yaml en spec:

      php_service.yaml

      ...
        ports:
          - protocol: TCP
            port: 9000
      

      Su archivo php_service.yaml completo tendrá el siguiente aspecto:

      php_service.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: php
        labels:
          tier: backend
      spec:
        selector:
          app: php
          tier: backend
        ports:
        - protocol: TCP
          port: 9000
      

      Presione CTRL + o para guardar el archivo y luego CTRL + x para cerrar nano.

      Ahora que ha creado la definición de objeto para su servicio, para ejecutar el servicio utilizará el comando kubectl apply junto con el argumento -f y especificará su archivo php_service.yaml.

      Cree su servicio:

      • kubectl apply -f php_service.yaml

      Este resultado confirma la creación del servicio:

      Output

      service/php created

      Verifique que su servicio esté en ejecución:

      Observará su servicio de PHP-FPM en ejecución:

      Output

      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

      Kubernetes admite varios tipos de servicios. Su servicio php utiliza el tipo de servicio predeterminado, clusterIP. Este tipo de servicio asigna una IP interna y permite acceder al servicio sólo desde el interior del clúster.

      Ahora que el servicio de PHP-FPM está listo, creará el servicio de Nginx. Cree y abra un nuevo archivo llamado nginx_service.yaml con el editor:

      Este servicio se orientará a los pods de Nginx, por lo que lo llamará nginx. También agregará una etiqueta tier: backend, ya que pertenece al nivel de backend:

      nginx_service.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: nginx
        labels:
          tier: backend
      

      De modo similar al servicio php, dirija los pods con las etiquetas de selección app: nginx y tier: backend. Permita que sea posible acceder a este servicio en el puerto 80, el puerto HTTP predeterminado.

      nginx_service.yaml

      ...
      spec:
        selector:
          app: nginx
          tier: backend
        ports:
        - protocol: TCP
          port: 80
      

      Será posible acceder al servicio de Nginx de forma pública en Internet desde la dirección IP pública de su Droplet. Puede encontrar your_public_ip desde su panel en la nube de DigitalOcean. En spec.externalIPs, agregue lo siguiente:

      nginx_service.yaml

      ...
      spec:
        externalIPs:
        - your_public_ip
      

      Su archivo nginx_service.yaml tendrá este aspecto:

      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    
      

      Guarde y cierre el archivo. Cree el servicio de Nginx:

      • kubectl apply -f nginx_service.yaml

      Observará el siguiente resultado cuando el servicio esté en ejecución:

      Output

      service/nginx created

      Puede ver todos los servicios en funcionamiento ejecutando lo siguiente:

      Observará los servicios de PHP-FPM y Nginx enumerados en el resultado:

      Output

      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

      Tenga en cuenta que si desea eliminar un servicio puede ejecutar lo siguiente:

      • kubectl delete svc/service_name

      Ahora que creó sus servicios de PHP-FPM y Nginx, deberá especificar el lugar de almacenamiento para el código de su aplicación y sus archivos de configuración.

      Paso 2: Instalar el complemento de almacenamiento de DigitalOcean

      Kubernetes proporciona diversos complementos de almacenamiento que pueden crear el espacio de almacenamiento para su entorno. En este paso, instalará el complemento de almacenamiento de DigitalOcean para crear un almacén en bloques en DigitalOcean. Una vez completada la instalación, agregará una clase de almacenamiento llamada do-block-storage que utilizará para crear su almacenamiento en bloques.

      Primero configurará un objeto secreto de Kubernetes para almacenar su token de API de DigitalOcean. Los objetos secretos se utilizan para compartir información confidencial, como claves y contraseñas SSH, con otros objetos de Kubernetes dentro del mismo espacio de nombres. Los espacios de nombres ofrecen una alternativa lógica para separar sus objetos de Kubernetes.

      Abra un archivo llamado secret.yaml con el editor:

      Nombre su objeto secreto digitalocean y agréguelo al namespace kube-system. kube-system es el espacio de nombres predeterminado para los servicios internos de Kubernetes y el complemento de almacenamiento de DigitalOcean también lo utiliza para iniciar varios componentes.

      secret.yaml

      apiVersion: v1
      kind: Secret
      metadata:
        name: digitalocean
        namespace: kube-system
      

      En lugar de una clave spec, un secreto utiliza una clave data o stringData para contener la información necesaria. El parámetro data contiene datos codificados en base64 que se decodifican de manera automática cuando se recuperan. El parámetro stringData contiene datos no codificados que se codifican de manera automática durante la creación o actualización, y no muestra los datos al recuperar secretos. En este tutorial, utilizará stringData para una mayor practicidad.

      Agregue el access-token como stringData:

      secret.yaml

      ...
      stringData:
        access-token: your-api-token
      

      Guarde y cierre el archivo.

      Su archivo secret.yaml tendrá el siguiente aspecto:

      secret.yaml

      apiVersion: v1
      kind: Secret
      metadata:
        name: digitalocean
        namespace: kube-system
      stringData:
        access-token: your-api-token
      

      Cree el secreto:

      • kubectl apply -f secret.yaml

      Verá este resultado al crear secretos:

      Output

      secret/digitalocean created

      Puede visualizar el secreto con el siguiente comando:

      • kubectl -n kube-system get secret digitalocean

      El resultado tendrá un aspecto similar a este:

      Output

      NAME TYPE DATA AGE digitalocean Opaque 1 41s

      El tipo Opaque implica que este secreto es de sólo lectura, parámetro estándar para los secretos de stringData. Puede obtener más información más acerca de ello en las especificaciones de diseño de secretos. El campo DATA muestra el número de elementos almacenados en este secreto. En este caso, muestra 1 porque tiene una sola clave almacenada.

      Ahora que su secreto está implementado, instale el complemento de almacenamiento en bloques de DigitalOcean:

      • kubectl apply -f https://raw.githubusercontent.com/digitalocean/csi-digitalocean/master/deploy/kubernetes/releases/csi-digitalocean-v0.3.0.yaml

      Verá resultados similares al siguiente:

      Output

      storageclass.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

      Ahora que instaló el complemento de almacenamiento de DigitalOcean, puede crear almacenamiento en bloques para contener el código de su aplicación y sus archivos de configuración.

      Paso 3: Crear el volumen persistente

      Con su secreto implementado y el complemento de almacenamiento en bloques instalado, estará listo para crear su volumen persistente. Un volumen persistente, o VP, es un almacenamiento en bloques de un tamaño especifico que es independiente del ciclo de vida de un pod. Utilizar un volumen persistente le permitirá administrar o actualizar sus pods sin preocuparse por la posibilidad de perder el código de su aplicación. El acceso a un volumen persistente es posible utilizando un PersistentVolumeClaim, o PVC, que monta el VP en la ruta requerida.

      Abra un archivo llamado code_volume.yaml con su editor:

      Dé el nombre code al PVC agregando los siguientes parámetros y valores a su archivo:

      code_volume.yaml

      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: code
      

      La spec para un PVC contiene los siguientes elementos:

      • accessModes que varían según el caso de uso. Son los siguientes:
        • ReadWriteOnce: monta el volumen con atributos de lectura y escritura para un solo nodo.
        • ReadOnlyMany: monta el volumen con atributos de sólo lectura para muchos nodos.
        • ReadWriteMany: monta el volumen con atributos de lectura y escritura para muchos nodos.
      • resources: espacio de almacenamiento que usted requiere.

      El almacenamiento en bloques de DigitalOcean solo se monta en un único nodo, por lo que usted fijará accessModes en ReadWriteOnce. Este tutorial le servirá de guía para agregar una pequeña cantidad de código de aplicación. Por lo tanto 1 gigabyte será suficiente en este caso de uso. Si planea almacenar una mayor cantidad de código o datos en el volumen, puede modificar el parámetro storage para que se adapte a sus necesidades. Puede aumentar la cantidad de almacenamiento después de crear el volumen, pero no es posible reducir el disco.

      code_volume.yaml

      ...
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
      

      A continuación, especifique la clase de almacenamiento que Kubernetes utilizará para proporcionar los volúmenes. Utilizará la clase do-block-storage creada por el complemento de almacenamiento en bloques de DigitalOcean.

      code_volume.yaml

      ...
        storageClassName: do-block-storage
      

      Su archivo code_volume.yaml tendrá el siguiente aspecto:

      code_volume.yaml

      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: code
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
        storageClassName: do-block-storage
      

      Guarde y cierre el archivo.

      Cree el elemento code PersistentVolumeClaim utilizando kubectl:

      • kubectl apply -f code_volume.yaml

      El siguiente resultado le indica que el objeto se creó de forma correcta y está listo para montar su PVC de 1 GB como un volumen.

      Output

      persistentvolumeclaim/code created

      Para visualizar volúmenes persistentes (VP) disponibles:

      Verá su VP enumerado:

      Output

      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

      A excepción de Reclaim Policy y Status, en los campos anteriores se muestra un resumen de su archivo de configuración. Reclaim Policy define lo que se hace con el VP después de que el PVC que lo accede es eliminado. Delete elimina el VP de Kubernetes y la infraestructura de DigitalOcean. Puede obtener más información sobre Reclaim Policy y Status en la documentación de VP de Kubernetes.

      De esta manera, habrá creado correctamente un volumen persistente utilizando el complemento de almacenamiento en bloques de DigitalOcean. Ahora que su volumen persistente está listo, creará sus pods con una implementación.

      Paso 4: Crear una implementación de PHP-FPM

      En este paso, aprenderá a utilizar una implementación para crear su pod de PHP-FPM. Las implementaciones proporcionan una manera uniforme de crear, actualizar y administrar pods utilizando ReplicaSets. Si una actualización no funciona como se espera, una implementación restaurará de manera automática sus pods a una imagen anterior.

      La clave de despliegue spec.selector enumerará las etiquetas de los pods que administrará. También utilizará la clave template para crear los pods necesarios.

      En este paso también se introducirá el uso de contenedores Init. Los contenedores Init ejecutan uno o más comandos antes que los contenedores regulares especificados en la clave template del pod. En este tutorial, su contenedor Init obtendrá un archivo de muestra de index.php de GitHub Gist utilizando wget. El archivo de muestra contiene lo siguiente:

      index.php

      <?php
      echo phpinfo();
      

      Para crear su implementación, abra un nuevo archivo llamado php_deployment.yaml con su editor:

      Esta implementación administrará sus pods de PHP-FPM, por lo que dará al objeto de implementación el nombre php. Los pods pertenecen al nivel de backend, por lo que agrupará la implementación en este grupo utilizando la etiqueta tier: backend:

      php_deployment.yaml

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: php
        labels:
          tier: backend
      

      Para la implementación spec, especificará la cantidad de copias de este pod que se crearán utilizando el parámetro replicas. El número de replicas variará según sus necesidades y los recursos disponibles. En este tutorial, creará una réplica:

      php_deployment.yaml

      ...
      spec:
        replicas: 1
      

      La implementación administrará pods que coincidan con app: php y las etiquetas de tier: backend. En la clave de selector agregue:

      php_deployment.yaml

      ...
        selector:
          matchLabels:
            app: php
            tier: backend
      

      A continuación, la implementación spec requiere el elemento template para la definición de objeto de su pod. Esta plantilla definirá las especificaciones a partir de las cuales se creará el pod. Primero, agregará las etiquetas que se especificaron para el servicio php selectors y las matchLabels de la implementación. Agregue app: php y tier: backend en template.metadata.labels:

      php_deployment.yaml

      ...
        template:
          metadata:
            labels:
              app: php
              tier: backend
      

      Un pod puede tener varios contenedores y volúmenes, pero cada uno requerirá un nombre. Puede montar de manera selectiva volúmenes en un contenedor especificando una ruta de montaje para cada volumen.

      Primero, especifique los volúmenes a los que accederá su contenedor. Creó un PVC llamado code para contener el código de su aplicación. Por lo tanto dé el nombre code a este volumen también. En spec.template.spec.volumes, agregue lo siguiente:

      php_deployment.yaml

      ...
          spec:
            volumes:
            - name: code
              persistentVolumeClaim:
                claimName: code
      

      A continuación, especifique el contenedor que desee ejecutar en este pod. Puede encontrar varias imágenes en la tienda de Docker, pero en este tutorial empleará la imagen php:7-fpm.

      En spec.template.spec.containers, agregue lo siguiente:

      php_deployment.yaml

      ...
            containers:
            - name: php
              image: php:7-fpm
      

      A continuación, montará los volúmenes a los que el contenedor solicita acceso. Este contenedor ejecutará su código PHP, de modo que deberá acceder al volumen code. También utilizará mountPath para especificar /code como punto de montaje.

      En spec.template.spec.containers.volumeMounts, agregue lo siguiente:

      php_deployment.yaml

      ...
              volumeMounts:
              - name: code
                mountPath: /code
      

      Ahora que montó su volumen, debe introducir el código de su aplicación en el volumen. Es posible que para hacerlo haya utilizado previamente FTP/SFTP o clonado el código a través de una conexión SSH, pero en este paso verá la forma de copiar el código utilizando un contenedor Init.

      Según la complejidad de su proceso de configuración, puede utilizar un solo initContainer para ejecutar una secuencia de comandos que construya su aplicación, o puede utilizar un initContainer por comando. Asegúrese de que los volúmenes se monten en el initContainer.

      En este tutorial, utilizará un contenedor Init único con busybox para descargar el código. busybox es una pequeña imagen que contiene la utilidad wget que utilizará para hacerlo.

      En spec.template.spec, agregue su initContainer y especifique la imagen busybox:

      php_deployment.yaml

      ...
            initContainers:
            - name: install
              image: busybox
      

      Su contenedor Init necesitará acceso al volumen code para que pueda descargar el código en esa ubicación. En spec.template.spec.initContainers, monte el volumen code en la ruta /code:

      php_deployment.yaml

      ...
              volumeMounts:
              - name: code
                mountPath: /code
      

      Cada contenedor Init debe ejecutar un command. Su contenedor Init utilizará wget para descargar el código de Github en el directorio de trabajo /code. La opción -O asigna un nombre al archivo descargado, y usted dará a este archivo el nombre index.php.

      Nota: Asegúrese de el código que extraerá sea confiable. Antes de introducir el código fuente en su servidor, inspecciónelo para asegurarse de que las funciones que realiza le parezcan adecuadas.

      En el contenedor install en spec.template.spec.initContainers, agregue estas líneas:

      php_deployment.yaml

      ...
              command:
              - wget
              - "-O"
              - "/code/index.php"
              - https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php
      

      Su archivo php_deployment.yaml completo tendrá este aspecto:

      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
      

      Guarde el archivo y salga del editor.

      Cree la implementación de PHP-FPM con kubectl:

      • kubectl apply -f php_deployment.yaml

      Visualizará el siguiente resultado al crear la implementación:

      Output

      deployment.apps/php created

      A modo de resumen, esta implementación se iniciará descargando las imágenes especificadas. Luego, solicitará el PersistentVolume de su PersistentVolumeClaim y ejecutará en serie sus initContainers. Una vez completado el proceso, los contenedores ejecutarán y montarán los volumes en punto de montaje especificado. Una vez que todos estos pasos se hayan completado, su pod estará listo y en ejecución.

      Puede ver su implementación ejecutando lo siguiente:

      Verá el siguiente resultado:

      Output

      NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE php 1 1 1 0 19s

      Este resultado puede ayudarle a comprender el estado actual de la implementación. Deployment es uno de los controladores que conservan un estado deseado. El elemento template que creó especifica que un elemento replicas del pod del estado DESIRED se llamará php. El campo CURRENT indica cuántas réplicas se encuentran en ejecución, por lo que debe coincidir con el estado DESIRED. Puede leer información sobre los campos restantes en la documentación de implementación de Kubernetes.

      Puede ver los pods iniciados por esta implementación con el siguiente comando:

      El resultado de este comando varía según el tiempo transcurrido desde la creación de la implementación. Si la ejecuta poco después de su creación, el resultado probablemente tendrá este aspecto:

      Output

      NAME READY STATUS RESTARTS AGE php-86d59fd666-bf8zd 0/1 Init:0/1 0 9s

      Las columnas representan la siguiente información:

      • Ready: número de replicas que ejecutan este pod.
      • Status: estado del pod. Init indica que los contenedores Init están en ejecución. En este resultado, del total de 1 contenedor Init, ninguno terminó de ejecutarse.
      • Restarts: cantidad de veces que este proceso se reinició para iniciar el pod. Este número aumentará si alguno de sus contenedores Init falla. La implementación se reiniciará hasta que alcance un estado deseado.

      Según de la complejidad de sus secuencias de comandos de inicio, pueden pasar algunos minutos hasta que el estado cambie a podInitializing:

      Output

      NAME READY STATUS RESTARTS AGE php-86d59fd666-lkwgn 0/1 podInitializing 0 39s

      Esto significa que los contenedores Init han finalizado y que se están iniciando los contenedores. Si ejecuta el comando cuando todos los contenedores estén en ejecución, verá que el estado de pod cambiará a Running.

      Output

      NAME READY STATUS RESTARTS AGE php-86d59fd666-lkwgn 1/1 Running 0 1m

      Ahora verá que su pod se ejecuta de forma correcta. Si su pod no se inicia, puede realizar una depuración con los siguientes comandos:

      • Ver información detallada de un pod:
      • kubectl describe pods pod-name
      • Ver registros generados por un pod:
      • Ver registros para un contenedor específico en un pod:
      • kubectl logs pod-name container-name

      Su código de aplicación está montado y el servicio de PHP-FPM ya está listo para manejar conexiones. Ahora podrá crear su implementación de Nginx.

      Paso 5: Crear la implementación de Nginx

      En este paso, utilizará un ConfigMap para configurar Nginx. Un ConfigMap contiene su configuración en un formato de clave-valor al que puede hacer referencia en otras definiciones de objetos de Kubernetes. Este enfoque le brindará la flexibilidad necesaria para reutilizar o cambiar la imagen con una versión de Nginx distinta si es necesario. Actualizar ConfigMap replicará los cambios de manera automática en cualquier pod montado en él.

      Con su editor, cree un archivo nginx_configMap.yaml para su ConfigMap:

      • nano nginx_configMap.yaml

      Dé el nombre nginx-config a ConfigMap y agrúpelo en el microservicio de tier: backend:

      nginx_configMap.yaml

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: nginx-config
        labels:
          tier: backend
      

      A continuación, agregará data para ConfigMap. Dé a la clave el nombre config y añada el contenido de su archivo de configuración de Nginx como valor. Puede utilizar el ejemplo de configuración de Nginx de este tutorial.

      Debido a que Kubernetes puede dirigir solicitudes al host adecuado para un servicio, puede ingresar el nombre de su servicio de PHP-FPM en el parámetro fastcgi_pass en lugar de su dirección IP. Agregue lo siguiente a su archivo nginx_configMap.yaml:

      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;
              }
          }
      

      Su archivo nginx_configMap.yaml tendrá el siguiente aspecto:

      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;
              }
          }
      

      Guarde el archivo y salga del editor.

      Cree el ConfigMap:

      • kubectl apply -f nginx_configMap.yaml

      Verá lo siguiente:

      Output

      configmap/nginx-config created

      Con esto, habrá terminado de crear su ConfigMap y ya podrá crear su implementación de Nginx.

      Comience abriendo un nuevo archivo nginx_deployment.yaml en el editor:

      • nano nginx_deployment.yaml

      Dé el nombre nginx a la implementación y añada la etiqueta tier: backend:

      nginx_deployment.yaml

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx
        labels:
          tier: backend
      

      Especifique que desea un elemento replicas en la implementación spec. Esta implementación administra pods con etiquetas app: nginx y tier: backend. Agregue los siguientes parámetros y valores:

      nginx_deployment.yaml

      ...
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: nginx
            tier: backend
      

      A continuación, agregue el elemento template del pod. Debe utilizar las mismas etiquetas que agregó para selector.matchLabels de la implementación. Agregue lo siguiente:

      nginx_deployment.yaml

      ...
        template:
          metadata:
            labels:
              app: nginx
              tier: backend
      

      Habilite el acceso de Nginx al PVC code que creó previamente. En spec.template.spec.volumes, agregue lo siguiente:

      nginx_deployment.yaml

      ...
          spec:
            volumes:
            - name: code
              persistentVolumeClaim:
                claimName: code
      

      Los pods pueden montar un ConfigMap como un volumen. Especificar un nombre de archivo y una clave creará un archivo con su valor como el contenido. Para usar ConfigMap, fije path en el nombre del archivo que tendrá el contenido de key. EL objetivo es crear un archivo site.conf a partir de la clave config. En spec.template.spec.volumes, agregue lo siguiente:

      nginx_deployment.yaml

      ...
            - name: config
              configMap:
                name: nginx-config
                items:
                - key: config
                  path: site.conf
      

      Advertencia: Si no se especifica un archivo, el contenido de key sustituirá el elemento mountPath del volumen. Esto quiere decir que si una ruta no está especificada de manera explícita, perderá todo el contenido de la carpeta de destino.

      A continuación, especificará la imagen a partir de la cual se creará su pod. En este tutorial se utilizará la imagen nginx:1.7.9 por cuestiones de estabilidad, pero puede encontrar otras imágenes de Nginx en la tienda de Docker. Además, debe hacer que Nginx esté disponible en el puerto 80. En spec.template.spec, agregue lo siguiente:

      nginx_deployment.yaml

      ...
            containers:
            - name: nginx
              image: nginx:1.7.9
              ports:
              - containerPort: 80
      

      Nginx y PHP-FPM deben acceder al archivo en la misma ruta. Por ello, monte el volumen de code en /code:

      nginx_deployment.yaml

      ...
              volumeMounts:
              - name: code
                mountPath: /code
      

      La imagen nginx:1.7.9 cargará de manera automática cualquier archivo de configuración en el directorio /etc/nginx/conf.d. Si se monta el volumen de config en este directorio, se creará el archivo /etc/nginx/conf.d/site.conf. En volumeMounts, agregue lo siguiente:

      nginx_deployment.yaml

      ...
              - name: config
                mountPath: /etc/nginx/conf.d
      

      Su archivo nginx_deployment.yaml tendrá el siguiente aspecto:

      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
      

      Guarde el archivo y salga del editor.

      Cree la implementación de Nginx:

      • kubectl apply -f nginx_deployment.yaml

      El siguiente resultado indica que se creó su implementación:

      Output

      deployment.apps/nginx created

      Enumere sus implementaciones con el siguiente comando:

      Visualizará las implementaciones de Nginx y PHP-FPM:

      Output

      NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx 1 1 1 0 16s php 1 1 1 1 7m

      Enumere los pods administrados por ambas implementaciones:

      Visualizará los pods que estén en ejecución:

      Output

      NAME READY STATUS RESTARTS AGE nginx-7bf5476b6f-zppml 1/1 Running 0 32s php-86d59fd666-lkwgn 1/1 Running 0 7m

      Ahora que todos los objetos de Kubernetes están activos, podrá visitar el servicio de Nginx en su navegador.

      Enumere los servicios en ejecución:

      • kubectl get services -o wide

      Obtenga la IP externa para su servicio de Nginx:

      Output

      NAME 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

      En su navegador, visite su servidor escribiendo http://your_public_ip. Verá el resultado de php_info() y habrá confirmado que sus servicios de Kubernetes están configurados y activos.

      Conclusión

      A través de esta guía , cargó en contenedores los servicios de PHP-FPM y Nginx para poder administrarlos de manera independiente. Este enfoque no solo mejorará la escalabilidad de su proyecto a medida que amplíe sus capacidades, sino también le permitirá utilizar los recursos de manera eficaz. También almacenó el código de su aplicación en un volumen para poder actualizar sus servicios de manera sencilla en el futuro.



      Source link