One place for hosting & domains

      Cómo implementar Laravel 7 y MySQL en Kubernetes con Helm


      El autor seleccionó la organización Diversity in Tech Fund para que reciba una donación como parte del programa Write for DOnations.

      Introducción

      Laravel es actualmente uno de los frameworks de aplicaciones PHP de código abierto más populares. Generalmente, se implementa con una base de datos de MySQL, pero puede configurarse para utilizar una variedad de opciones de almacenamiento de datos backend. Laravel se enorgullece de aprovechar muchas de las características modernas y el vasto ecosistema de paquetes de PHP.

      Kubernetes es una plataforma de orquestación de contenedores que puede alojarse en los clústeres de Kubernetes de DigitalOcean para que se encargue de una gran parte del trabajo administrativo de configuración y ejecución de contenedores en producción. Helm es un administrador de paquetes de Kubernetes que facilita la configuración e instalación de servicios y pods en Kubernetes.

      En esta guía, creará una aplicación PHP de Laravel, compilará la aplicación en una imagen de Docker e implementará esa imagen en un clúster de Kubernetes de DigitalOcean utilizando el chart de Helm de LAMP. A continuación, configurará un controlador Ingress para agregar SSL y un nombre de dominio personalizado a la aplicación. Al finalizar, tendrá una aplicación de Laravel funcional conectada a una base de datos que se ejecuta en un clúster de Kubernetes.

      Requisitos previos

      Paso 1: Crear una nueva aplicación Laravel

      En este paso, utilizará Docker para crear una nueva aplicación Laravel 7, pero debería poder realizar el mismo procedimiento con una aplicación Laravel existente que utilice MySQL como copia de seguridad de la base de datos. La nueva aplicación que compile verificará que Laravel esté conectada a la base de datos y mostrará el nombre de la base de datos.

      Primero, vaya al directorio de inicio y, luego, utilice un contenedor de Docker composer para crear una nueva aplicación Laravel:

      • cd ~
      • docker run --rm -v $(pwd):/app composer create-project --prefer-dist laravel/laravel laravel-kubernetes

      Una vez que esté listo el contenedor y que se hayan instalado todos los paquetes de Composer, debería ver una nueva instalación de Laravel denominada laravel-kubernetes/ en el directorio actual. Diríjase a esa carpeta:

      A partir de aquí, ejecutará el resto de los comandos de este tutorial.

      El objetivo de esta aplicación es probar la conexión de la base de datos y mostrar su nombre en el navegador. Para probar la conexión de la base de datos, abra el archivo ./resources/views/welcome.blade.php en un editor de texto:

      • nano ./resources/views/welcome.blade.php

      Busque la sección <div class="links">...</div> y sustituya el contenido por lo siguiente:

      ./resources/views/welcome.blade.php

      ...
      <div class="links">
         <strong>Database Connected: </strong>
          @php
              try {
                  DB::connection()->getPDO();
                  echo DB::connection()->getDatabaseName();
                  } catch (Exception $e) {
                  echo 'None';
              }
          @endphp
      </div>
      ...
      

      Guarde y cierre el archivo.

      Ese es todo el proceso de personalización que deberá realizar en la aplicación predeterminada Laravel para este tutorial. Una vez que haya terminado, este breve fragmento de PHP probará la conexión de la base de datos y mostrará el nombre de dicha base de datos en la pantalla de presentación de Laravel en el navegador web.

      En el siguiente paso, utilizará Docker para compilar una imagen que contenga esta aplicación de Laravel y Docker Compose para probar que se ejecuta de manera local y que se conecta a una base de datos de MySQL.

      Paso 2: Disponer la aplicación de Laravel en un contenedor

      Ahora que creó una nueva aplicación de Laravel, deberá compilar el código en una imagen de Docker y, luego, evaluar la imagen con Docker Compose. Si bien el objetivo de este tutorial es implementar la aplicación en un clúster de Kubernetes, Docker Compose es una forma práctica de probar la imagen y la configuración de Docker de manera local antes de ejecutarla en la nube. Este proceso de retroalimentación rápido puede ser útil para realizar y probar modificaciones pequeñas.

      Primero, con nano o el editor de texto que prefiera, cree un archivo llamado Dockerfile en la raíz de la aplicación de Laravel:

      Añada el siguiente contenido: Docker utilizará este archivo para compilar el código en una imagen:

      ./Dockerfile

      FROM php:7.4-apache
      
      # Install packages
      RUN apt-get update && apt-get install -y 
          git 
          zip 
          curl 
          sudo 
          unzip 
          libicu-dev 
          libbz2-dev 
          libpng-dev 
          libjpeg-dev 
          libmcrypt-dev 
          libreadline-dev 
          libfreetype6-dev 
          g++
      
      # Apache configuration
      ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
      RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
      RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
      RUN a2enmod rewrite headers
      
      # Common PHP Extensions
      RUN docker-php-ext-install 
          bz2 
          intl 
          iconv 
          bcmath 
          opcache 
          calendar 
          pdo_mysql
      
      # Ensure PHP logs are captured by the container
      ENV LOG_CHANNEL=stderr
      
      # Set a volume mount point for your code
      VOLUME /var/www/html
      
      # Copy code and run composer
      COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
      COPY . /var/www/tmp
      RUN cd /var/www/tmp && composer install --no-dev
      
      # Ensure the entrypoint file can be run
      RUN chmod +x /var/www/tmp/docker-entrypoint.sh
      ENTRYPOINT ["/var/www/tmp/docker-entrypoint.sh"]
      
      # The default apache run command
      CMD ["apache2-foreground"]
      

      Guarde y cierre el archivo.

      Este archivo Dockerfile comienza con una imagen de Docker de Apache PHP 7.4 que se encuentra en Docker Hub y, luego, instala varios paquetes de Linux que generalmente los requieren las aplicaciones de Laravel. A continuación, crea archivos de configuración de Apache y habilita la reescritura de encabezados. El archivo Dockerfile instala varias extensiones comunes de PHP y agrega una variable de entorno para asegurarse de que los registros de Laravel se transmitan al contenedor a través de stderr. Esto le permitirá ver los registros de Laravel mediante el seguimiento de los registros de Docker Compose o Kubernetes.

      Por último, Dockerfile copia todo el código de la aplicación de Laravel a /var/www/tmp e instala las dependencias de Composer. Después, establece un ENTRYPOINT, pero deberá crear ese archivo, que es lo que haremos a continuación.

      En el directorio raíz de su proyecto, cree un nuevo archivo denominado docker-entrypoint.sh. Este archivo se ejecutará cuando el contenedor se ejecute de manera local o en el clúster de Kubernetes, y copiará el código de la aplicación de Laravel del directorio /var/www/tmp a /var/www/html, donde Apache podrá presentarlo.

      • nano ./docker-entrypoint.sh

      Ahora agregue la siguiente secuencia de comandos:

      ./docker-entrypoint.sh

      #!/bin/bash
      
      cp -R /var/www/tmp/. /var/www/html/
      chown -R www-data:www-data /var/www/html
      
      exec "$@"
      

      La última línea, exec "$@", le indica al shell que ejecute cualquier comando que transmitió como argumento de entrada. Esto es importante porque queremos que Docker siga ejecutando el comando Ejecutar de Apache (apache2-foregrund) después de esta secuencia de comandos. Guarde y cierre el archivo.

      A continuación, cree un archivo .dockerignore en el directorio raíz de la aplicación. Este archivo garantizará que cuando compile la imagen de Docker, no se contamine con archivos de entorno o paquetes que no deberían copiarse allí:

      ./.dockerignore

      .env
      /vendor
      

      Guarde y cierre el archivo.

      El archivo docker-compose.yml es el último que debe crear antes de poder ejecutar la aplicación de manera local con Docker Compose. Sin embargo, durante la configuración de este archivo YAML, deberá ingresar la APP_KEY que generó Laravel durante la instalación. Para encontrar esta clave, abra y busque en el archivo . /.env o ejecute los siguientes comandos cat y grep:

      Verá un resultado similar a este:

      Output

      APP_KEY=base64:0EHhVpgg ... UjGE=

      Copie la clave en el portapapeles. Asegúrese de incluir el prefijo base64:. Ahora cree el archivo docker-compose.yml en el directorio raíz de la aplicación:

      • nano ./docker-compose.yml

      Aquí incluiremos la imagen PHP de la aplicación de Laravel y también un contenedor de MySQL para ejecutar la base de datos. Añada el siguiente contenido:

      ./docker-compose.yml

      version: '3.5'
      services:
        php:
          image: your_docker_hub_username/laravel-kubernetes:latest
          restart: always
          ports:
            - 8000:80
          environment:
            - APP_KEY="your_laravel_app_key"
            - APP_ENV=local
            - APP_DEBUG=true
            - DB_PORT=3306
            - DB_HOST=mysql
            - DB_DATABASE
            - DB_USERNAME
            - DB_PASSWORD
        mysql:
          image: mysql:5.7
          restart: always
          environment:
            - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
            - MYSQL_DATABASE=${DB_DATABASE}
            - MYSQL_USER=${DB_USERNAME}
            - MYSQL_PASSWORD=${DB_PASSWORD}
      

      Utilice la variable APP_KEY que copió en el portapapeles para la variable your_laravel_app_key, y el nombre de usuario de Docker Hub para la variable your_docker_hub_username. Guarde y cierre el archivo.

      Creará la primera imagen de manera local con docker.build. La segunda imagen es la imagen de Docker de MySQL oficial que está disponible en Docker Hub. Ambas requieren diversas variables de entorno, las cuales incluirá cuando ejecute los contenedores.

      Para compilar la imagen de Docker que contiene la aplicación de Laravel, ejecute el siguiente comando. Asegúrese de sustituir your_docker_hub_username por su nombre de usuario o el nombre de usuario de su equipo en Docker Hub, donde se almacenará esta imagen:

      • docker build -t your_docker_hub_username/laravel-kubernetes:latest .

      A continuación, puede ejecutar los dos contenedores utilizando Docker Compose con las credenciales necesarias de la base de datos:

      • DB_ROOT_PASSWORD=rootpassword DB_DATABASE=local_db DB_USERNAME=admin DB_PASSWORD=password docker-compose up -d

      Si quiere, puede modificar las cuatro variables de entorno que se utilizan aquí (DB_ROOT_PASSWORD, DB_DATABASE, DB_USERNAME y DB_PASSWORD) pero, dado que solo está probando la aplicación de manera local, aún no es necesario protegerlas.

      El proceso de iniciar la base de datos de MySQL y preparar los contenedores puede tardar hasta 30 segundos. Una vez que lo estén, puede ver la aplicación de Laravel en su equipo en localhost:8000.

      La aplicación Laravel que ejecutándose de manera local con Docker Compose

      Su aplicación PHP se conectará a la base de datos de MySQL. Tras una conexión exitosa, el texto “Database Connected: localdb”(Base de datos conectada: localdb) aparecerá debajo del logotipo de Laravel.

      Ahora que probó la imagen de Docker de manera local con Docker Compose, puede ejecutar docker-compose down para desactivar los contenedores:

      En la siguiente sección, transferirá la imagen de Docker a Docker Hub para que su chart de Helm pueda utilizarla para implementar la aplicación en el clúster de Kubernetes.

      Paso 3: Introducir la imagen de Docker en Docker Hub

      El chart de Helm de LAMP que utilizará para implementar el código en Kubernetes requiere que el código esté disponible en un registro de contenedores. Si bien puede transferir la imagen a un registro privado o con alojamiento propio, a los efectos de este tutorial, utilizará un registro de Docker público y gratuito en Docker Hub.

      En el navegador web, acceda a su cuenta en Docker Hub y, luego, cree un nuevo repositorio llamado laravel-kubernetes.

      Crear un nuevo repositorio en Docker Hub

      A continuación, si no se conectó a Docker Hub desde el equipo local, deberá iniciar sesión en Docker Hub. Puede hacerlo con la siguiente línea de comandos:

      • docker login -u your_docker_hub_username

      Cuando se le solicite, ingrese las credenciales de inicio de sesión. Generalmente, solo debe realizar esta acción una vez en cada equipo, ya que Docker guardará las credenciales en ~/.docker/config.json en el directorio de inicio.

      Por último, transfiera la imagen a Docker Hub:

      • docker push your_docker_hub_username/laravel-kubernetes:latest

      Dependiendo de la velocidad de conexión, puede tomar algunos minutos cargar la aplicación, pero una vez que Docker termine, verá un último resumen de la función hash y el tamaño de la imagen en el terminal. El aspecto será similar a este:

      Output

      latest: digest: sha256:df4bdeda91484c8c26a989b13b8f27ab14d93ab2e676e3c396714cb3811c4086 size: 4918

      Ahora que la aplicación de Laravel está en un contenedor y que introdujo una imagen en Docker Hub, puede utilizar la imagen en la implementación de un chart de Helm o de Kubernetes. En el siguiente paso, configurará valores personalizados en base al chart de Helm de LAMP y lo implementará en el clúster de Kubernetes de DigitalOcean.

      Paso 4: Configurar e implementar la aplicación con el chart de Helm de LAMP

      Helm proporciona varios Charts para ayudarlo a configurar aplicaciones de Kubernetes utilizando combinaciones de herramientas predeterminadas. Si bien podría escribir archivos de servicio de Kubernetes propios para lograr una implementación similar, en esta sección observará que al utilizar un Chart de Helm se requerirá un proceso de configuración mucho menor.

      Primero, necesitará un directorio para almacenar todos los archivos de configuración de Helm. En la raíz de su proyecto Laravel, cree un nuevo directorio llamado helm/:

      Dentro del directorio helm/ crearemos dos nuevos archivos: values.yml y secrets.yml. Primero, cree y abra values.yml:

      El archivo values.yml incluirá opciones de configuración no secretas que anularán los valores predeterminados en el gráfico de Helm de LAMP. Agregue las siguientes opciones de configuración, asegurándose de sustituir your_docker_hub_username por su nombre de usuario:

      ./helm/values.yml

      php:
        repository: "your_docker_hub_username/laravel-kubernetes"
        tag: "latest"
        fpmEnabled: false
        envVars:
          - name: APP_ENV
            value: production
          - name: APP_DEBUG
            value: false
          - name: DB_PORT
            value: 3306
          - name: DB_HOST
            value: localhost
      

      Guarde y cierre el archivo.

      Ahora cree un archivo secrets.yml:

      secrets.yml no se verificará en el control de versiones. Contendrá información de configuración confidencial, como la contraseña de la base de datos y la clave de la aplicación de Laravel. Agregue la siguiente configuración, y adáptela según corresponda para que coincida con sus credenciales:

      ./helm/secrets.yml

      mysql:
        rootPassword: "your_database_root_password"
        user: your_database_user
        password: "your_database_password"
        database: your_database_name
      
      php:
        envVars:
          - name: APP_KEY
            value: "your_laravel_app_key"
          - name: DB_DATABASE
            value: your_database_name
          - name: DB_USERNAME
            value: your_database_user
          - name: DB_PASSWORD
            value: "your_database_password"
      

      Asegúrese de utilizar combinaciones de nombre de usuario y contraseña seguras para su base de datos de producción, y utilice la misma your_laravel_app_key que empleó anteriormente, o ejecute el siguiente comando para abrir una ventana de terminal nueva y generar una nueva clave. Luego, puede copiar el nuevo valor que establezca Laravel en el archivo .env:

      • docker run --rm -v $(pwd):/app php:cli php /app/artisan key:generate

      Guarde y cierre secrets.yml.

      A continuación, para evitar que el archivo secrets.yml se integre en la imagen de Docker o se guarde en el control de versiones, asegúrese de agregar la siguiente línea en los archivos .dockerignore y .gitignore. Abra cada archivo y anexe /helm/secrets.yml a cada uno, o bien ejecute el siguiente comando para agregarlo a ambos:

      • echo '/helm/secrets.yml' >> ./.dockerignore && echo '/helm/secrets.yml' >> ./.gitignore

      Ahora que ha creado los archivos de configuración de Helm para su aplicación y la imagen de Docker, puede instalar este chart de Helm como una nueva versión en el clúster de Kubernetes. Instale el chart desde el directorio raíz de la aplicación:

      • helm install laravel-kubernetes -f helm/values.yml -f helm/secrets.yml stable/lamp

      Verá un resultado similar a este:

      Output

      NAME: laravel-kubernetes LAST DEPLOYED: Mon May 18 13:21:20 2020 NAMESPACE: default STATUS: deployed REVISION: 1

      La aplicación estará disponible en uno o dos minutos, pero puede ejecutar este comando para controlar el servicio de Kubernetes en el clúster:

      Busque el nombre de su aplicación:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) laravel-kubernetes-lamp LoadBalancer your_cluster_ip your_external_ip 80:32175/TCP,3306:32243/TCP

      Cuando el nuevo servicio laravel-kubernetes-lamp muestre una dirección IP en EXTERNAL-IP, puede visitar your_external_ip para ver la aplicación ejecutándose en el clúster de Kubernetes. La aplicación se conectará a la base de datos, y verá el nombre de dicha base de datos debajo del logotipo de Laravel, como sucedió cuando ejecutó la aplicación de manera local en Docker Compose.

      La aplicación de Laravel ejecutándose en Kubernetes con el chart de Helm de LAMP

      Es aceptable ejecutar una aplicación web en una dirección IP no segura cuando se trata de una prueba de concepto, pero sin un certificado SSL y un nombre de dominio personalizado, el sitio web no está listo para producción. Antes de configurar esto en el siguiente paso, desinstale la versión mediante la línea de comandos:

      • helm delete laravel-kubernetes

      En el siguiente paso, ampliará la primera configuración de Helm para agregar un controlador Ingress, un certificado SSL y un dominio personalizado a la aplicación de Laravel.

      Paso 5: Agregar un controlador Ingress y SSL al clúster de Kubernetes

      En Kubernetes, un controlador Ingress es el responsable de exteriorizar los servicios de su aplicación a Internet. En el paso anterior, el chart de Helm de LAMP creó un equilibrador de carga de DigitalOcean y expuso la aplicación de manera directa a través de la dirección IP del equilibrador de carga.

      Podría terminar SSL y el nombre de dominio directamente en el equilibrador de carga, pero, debido a que está trabajando en Kubernetes, podría resultar más práctico administrar todo en el mismo lugar. Para obtener más información sobre los controladores Ingress y detalles sobre los siguientes pasos, consulte Cómo configurar un Ingress de Nginx en Kubernetes de DigitalOcean utilizando Helm.

      El chart de Helm de LAMP incluye una opción de configuración para admitir Ingress. Abra el archivo helm/values.yml:

      Ahora agregue las siguientes líneas:

      ./helm/values.yml

      ...
      # Use Ingress Controller
      service:
        type: ClusterIP
        HTTPPort: 80
      ingress:
        enabled: true
        domain: your_domain
      

      Esto indica que durante la implementación no se instale un equilibrador de carga y que, en su lugar, se exponga la aplicación al puerto 80 del clúster de Kubernetes, donde el controlador Ingress lo exteriorizará a Internet. Guarde y cierre values.yml.

      Ahora ejecute el comando helm install que ejecutó anteriormente para que se volviera a ejecutar la aplicación de Laravel. Asegúrese de ejecutar el comando desde el directorio raíz de la aplicación:

      • helm install laravel-kubernetes -f helm/values.yml -f helm/secrets.yml stable/lamp

      A continuación, instale el controlador nginx-ingress en el clúster de Kubernetes utilizando el controlador Ingress de Nginx que mantiene Kubernetes:

      • helm install nginx-ingress stable/nginx-ingress --set controller.publishService.enabled=true

      Una vez completada la instalación, verá un resultado similar a este:

      Output

      NAME: nginx-ingress LAST DEPLOYED: Mon May 18 13:28:34 2020 NAMESPACE: default STATUS: deployed REVISION: 1

      También necesita un recurso de Ingress para exponer la implementación de la aplicación de Laravel. Cree un nuevo archivo denominado ingress.yml en el directorio raíz de la aplicación:

      Este archivo define el host de la aplicación, el administrador del certificado SSL, el servicio de backend y el nombre del puerto. Agregue las siguientes opciones de configuración, sustituyendo your_domain por el dominio de su elección:

      ./ingress.yml

      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: laravel-kubernetes-ingress
        annotations:
          kubernetes.io/ingress.class: nginx
          cert-manager.io/cluster-issuer: letsencrypt-prod
      spec:
        tls:
          - hosts:
              - your_domain
            secretName: laravel-kubernetes-tls
        rules:
          - host: your_domain
            http:
              paths:
                - backend:
                    serviceName: laravel-kubernetes-lamp
                    servicePort: 80
      

      Guarde y cierre el archivo.

      A continuación, debería instalar Cert-Manager y crear un emisor que le permitirá crear certificados SSL de producción utilizando Let’s Encrypt. Cert-Manager requiere definiciones de recursos personalizados que puede aplicar desde el repositorio de Cert-Manager mediante la línea de comandos:

      • kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.crds.yaml

      Esto creará varios recursos de Kubernetes que se mostrarán en la línea de comandos:

      Output

      customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io create

      Cert-Manager también requiere un espacio de nombres para aislarlo en el clúster de Kubernetes:

      • kubectl create namespace cert-manager

      Obtendrá el siguiente resultado:

      Output

      namespace/cert-manager created

      Debido a que el Cert-Manager de Jetstack no es uno de los charts que mantiene Kubernetes, también deberá agregar el repositorio de Helm para Jetstack. Ejecute el siguiente comando para habilitarlo en Helm:

      • helm repo add jetstack https://charts.jetstack.io

      Si se agrega de manera correcta, se mostrará el siguiente resultado:

      Output

      "jetstack" has been added to your repositories

      Ahora está listo para instalar Cert-Manager en el espacio de nombres de cert-manager del clúster de Kubernetes:

      • helm install cert-manager --version v0.15.0 --namespace cert-manager jetstack/cert-manager

      Cuando finalice, verá un resumen del despliegue similar al siguiente:

      Output

      NAME: cert-manager LAST DEPLOYED: Mon May 18 13:32:08 2020 NAMESPACE: cert-manager STATUS: deployed REVISION: 1

      El archivo de configuración de Kubernetes production_issuer.yml es el último archivo que deberá agregar al directorio raíz de la aplicación de Laravel. Cree el archivo:

      • nano ./production_issuer.yml

      Ahora, agregue lo siguiente:

      apiVersion: cert-manager.io/v1alpha2
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-prod
      spec:
        acme:
          # Email address used for ACME registration
          email: your_email_address
          server: https://acme-v02.api.letsencrypt.org/directory
          privateKeySecretRef:
            # Name of a secret used to store the ACME account private key
            name: letsencrypt-prod-private-key
          # Add a single challenge solver, HTTP01 using nginx
          solvers:
            - http01:
                ingress:
                  class: nginx
      

      Guarde y cierre el archivo.

      Let’s Encrypt enviará a your_email_address cualquier aviso importante y advertencia de vencimiento, así que asegúrese de agregar una dirección que revisará de manera regular. Guarde este archivo y cree un nuevo recurso en el clúster de Kubernetes para el recurso de Ingress y para el emisor de producción:

      • kubectl create -f ingress.yml
      • kubectl create -f production_issuer.yml

      Por último, actualice los registros DNS de su nombre de dominio para que dirija un registro A a la dirección IP del equilibrador de carga. Para encontrar la dirección IP del controlador Ingress escriba:

      • kubectl get service nginx-ingress-controller

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-ingress-controller LoadBalancer your_cluster_ip your_external_ip 80:30187/TCP,443:31468/TCP 6m10s

      Utilice la dirección your_external_ip como la dirección IP para su registro DNS tipo A. El proceso para actualizar los registros DNS varía en función de dónde gestiona los nombres de dominio y el hosting de DNS, pero si utiliza DigitalOcean, puede consultar nuestra guía sobre Cómo administrar registros DNS.

      Una vez que se actualice el registro DNS y se genere el certificado SSL, la aplicación estará disponible en your_domain y se habilitará SSL.

      La aplicación de Laravel con terminación de SSL y un nombre de dominio personalizado

      Si bien la aplicación de PHP y la base de datos ya están conectadas, aún deberá ejecutar migraciones de base de datos. En el último paso, aprenderá a ejecutar los comandos Artisan en el pod de Kubernetes para realizar migraciones de base de datos y otras tareas comunes de mantenimiento.

      Paso 6: Ejecutar comandos remotos

      Mientras se ejecuta la aplicación de Laravel y se mantiene conectada a la base de datos de MySQL en Kubernetes, existen varias operaciones comunes que debería ejecutar en una nueva instalación de Laravel. Una tarea común que debería realizar son las migraciones de base de datos.

      Antes de poder ejecutar un comando Artisan en la aplicación de Laravel, debe conocer el nombre del pod que está ejecutando el container de dicha aplicación. Puede ver todos los pods de su clúster de Kubernetes mediante la siguiente línea de comandos:

      Verá un resultado similar a este:

      Output

      NAME READY STATUS RESTARTS AGE laravel-kubernetes-lamp-77fb989b46-wczgb 2/2 Running 0 16m

      Seleccione el pod para la implementación de laravel-kubernetes-lamp-.... Asegúrese de utilizar el nombre del resultado y no el que aparece arriba. Ahora puede ejecutar kubectl exec en él. Por ejemplo, ejecute una migración de base de datos utilizando el comando artisan migrate. Agregará el indicador --force porque está ejecutando el pod en producción:

      • kubectl exec laravel-kubernetes-lamp-77fb989b46-wczgb -- php artisan migrate --force

      Este comando arrojará un resultado como el siguiente:

      Output

      Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.16 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.05 seconds)

      De esta manera, implementó de manera exitosa Laravel 7 y MySQL en Kubernetes y realizó una tarea de mantenimiento de la base de datos indispensable.

      Conclusión

      En este tutorial, aprendió a disponer una aplicación PHP de Laravel en un container, conectarla con una base de datos de MySQL, introducir una imagen de Docker que contiene su código en Docker Hub y, luego, utilizar un chart de Helm para implementar esa imagen en un clúster de Kubernetes de DigitalOcean. Por último, agregó SSL y un nombre de dominio personalizado, y aprendió a ejecutar herramientas de línea de comandos en los pods en ejecución.

      En comparación del hosting tradicional de la pila LAMP, Kubernetes y Helm ofrecen varias ventajas: escalabilidad, la capacidad de cambiar servicios sin tener que iniciar sesión en el servidor de manera directa, herramientas para realizar actualizaciones progresivas y control sobre el entorno de hosting. Dicho esto, la complejidad de utilizar contenedores y configurar la aplicación al principio eleva la barrera a la hora de comenzar a utilizarlos. Con esta guía como punto de partida, la implementación de Laravel en Kubernetes se vuelve factible. A partir de aquí, quizás quiera aprender más sobre la capacidad de Laravel o agregar herramientas de monitoreo a Kubernetes como Linkerd, que puede instalar de manera manual siguiendo nuestra guía o con un solo clic de DigitalOcean.



      Source link

      Развертывание Laravel 7 и MySQL в Kubernetes с помощью Helm


      Автор выбрал Diversity in Tech Fund для получения пожертвования в рамках программы Write for DOnations.

      Введение

      Laravel — одна из самых популярных в настоящее время инфраструктур приложений PHP с открытым исходным кодом. Обычно она развертывается с СУБД MySQL, но ее можно настроить и для других решений хранения данных. Laravel отличается использованием преимуществ современных возможностей PHP и обширной экосистемой пакетов.

      Kubernetes — платформа оркестровки контейнеров, которую можно размещать на кластерах DigitalOcean Kubernetes для упрощения администрирования, настройки и использования контейнеров в производственной среде. Helm — это диспетчер пакетов Kubernetes, упрощающий настройку и установку служб и подов в Kubernetes.

      В этом обучающем модуле вы создадите приложение Laravel PHP, добавите приложение в образ Docker и развернете этот образ в кластере DigitalOcean Kubernetes, используя чарт LAMP Helm. Затем вы настроите контроллер Ingress для добавления SSL и собственного доменного имени вашего приложения. После прохождения вы получите работающее приложение Laravel, подключенноек базе данных MySQL, запущенной на кластере Kubernetes.

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

      • Система Docker, установленная на компьютере, с которого вы будете подключаться к кластеру. Подробные инструкции по установке Docker для большинства дистрибутивов Linux можно найти здесь или на сайте Docker для других операционных систем.
      • В этом обучающем модуле вы создадите учетную запись Docker Hub для хранения образов Docker.
      • Кластер DigitalOcean Kubernetes с конфигурацией подключения, настроенной с помощью kubectl по умолчанию. Процесс создания кластера Kubernetes в DigitalOcean, описан в документе «Быстрое начало работы с Kubernetes». Процедура подключения к кластеру описана в руководстве «Подключение к кластеру DigitalOcean Kubernetes».
      • Диспетчер пакетов Helm 3, установленный на локальном компьютере. Выполните первый шаг и добавьте репозиторий stable из второго шага обучающего модуля «Установка программного обеспечения в кластерах Kubernetes с помощью диспетчера пакетов Helm 3».
      • Полностью зарегистрированное доменное имя с доступной записью A. В этом обучающем руководстве мы будем использовать your_domain. Вы можете купить доменное имя на Namecheap, получить его бесплатно на Freenom или воспользоваться услугами любого предпочитаемого регистратора доменных имен. Сейчас не нужно думать о привязке записи A вашего домена к IP-адресу. Когда вы дойдете до шага 5 и ваш контроллер Ingress будет установлен, вы подключите your_domain к правильному IP-адресу.

      Шаг 1 — Создание нового приложения Laravel

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

      Перейдите в домашний каталог и создайте новое приложение Laravel с использованием контейнера composer Docker:

      • cd ~
      • docker run --rm -v $(pwd):/app composer create-project --prefer-dist laravel/laravel laravel-kubernetes

      Когда контейнер будет готов и все пакеты Composer будут установлены, вы увидите новую установку Laravel в текущем каталоге laravel-kubernetes/. Перейдите в этот каталог:

      Остальные команды этого обучающего модуля должны выполняться в нем.

      Цель этого приложения — протестировать подключение к базе данных и вывести ее имя в браузере. Чтобы протестировать подключение к базе данных, откройте файл ./resources/views/welcome.blade.php в текстовом редакторе:

      • nano ./resources/views/welcome.blade.php

      Найдите раздел <div class="links">...</div> и замените его содержимое следующим:

      ./resources/views/welcome.blade.php

      ...
      <div class="links">
         <strong>Database Connected: </strong>
          @php
              try {
                  DB::connection()->getPDO();
                  echo DB::connection()->getDatabaseName();
                  } catch (Exception $e) {
                  echo 'None';
              }
          @endphp
      </div>
      ...
      

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

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

      На следующем шаге мы используем Docker для создания образа, содержащего это приложение Laravel, и Docker Compose для тестирования локального запуска и подключения к базе данных MySQL.

      Шаг 2 — Контейнеризация вашего приложения Laravel

      Мы создали новое приложение Laravel, и теперь нам нужно добавить код в образ Docker и протестировать образ с помощью Docker Compose. Хотя целью этого обучающего модуля является развертывание приложения в кластере Kubernetes, Docker Compose открывает удобный способ протестировать образ и конфигурацию Docker локально перед их запуском в облаке. Этот быстрый цикл обратной связи может быть полезен для внесения и тестирования небольших изменений.

      Вначале используйте nano или другой предпочитаемый текстовый редактор для создания в корневом каталоге вашего приложения Laravel файла с именем Dockerfile:

      Добавьте в файл следующее: Docker будет использовать этот файл для встраивания кода в образ:

      ./Dockerfile

      FROM php:7.4-apache
      
      # Install packages
      RUN apt-get update && apt-get install -y 
          git 
          zip 
          curl 
          sudo 
          unzip 
          libicu-dev 
          libbz2-dev 
          libpng-dev 
          libjpeg-dev 
          libmcrypt-dev 
          libreadline-dev 
          libfreetype6-dev 
          g++
      
      # Apache configuration
      ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
      RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
      RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
      RUN a2enmod rewrite headers
      
      # Common PHP Extensions
      RUN docker-php-ext-install 
          bz2 
          intl 
          iconv 
          bcmath 
          opcache 
          calendar 
          pdo_mysql
      
      # Ensure PHP logs are captured by the container
      ENV LOG_CHANNEL=stderr
      
      # Set a volume mount point for your code
      VOLUME /var/www/html
      
      # Copy code and run composer
      COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
      COPY . /var/www/tmp
      RUN cd /var/www/tmp && composer install --no-dev
      
      # Ensure the entrypoint file can be run
      RUN chmod +x /var/www/tmp/docker-entrypoint.sh
      ENTRYPOINT ["/var/www/tmp/docker-entrypoint.sh"]
      
      # The default apache run command
      CMD ["apache2-foreground"]
      

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

      Этот файл Dockerfile начинает с образа PHP 7.4 Apache Docker из Docker Hub, а затем устанавливает несколько пакетов Linux, которые обычно требуются для приложений Laravel. Затем он создает файлы конфигурации Apache и включает перезапись заголовков. Dockerfile устанавливает несколько общих расширений PHP и добавляет переменную среды для обеспечения трансляции журналов Laravel в контейнер через stderr. Это позволяет просматривать журналы Laravel через журналы Docker Compose или Kubernetes.

      В заключение, Dockerfile копирует весь код приложения Laravel в каталог /var/www/tmp и устанавливает зависимости Composer. Затем он устанавливает ENTRYPOINT, но нам еще нужно создать этот файл, что мы сейчас и сделаем.

      Создайте в корневом каталоге проекта новый файл с именем docker-entrypoint.sh. Этот файл будет запускаться при запуске контейнера в локальном режиме или в кластере Kubernetes и будет копировать код приложения Laravel из каталога /var/www/tmp в каталог /var/www/html, где его будет обслуживать Apache.

      • nano ./docker-entrypoint.sh

      Добавьте следующий скрипт:

      ./docker-entrypoint.sh

      #!/bin/bash
      
      cp -R /var/www/tmp/. /var/www/html/
      chown -R www-data:www-data /var/www/html
      
      exec "$@"
      

      Заключительная строка exec "$@" предписывает оболочки запустить любую команду, которая будет передана следующей в качестве входного аргумента. Это важно, потому что нам нужно, чтобы Docker продолжал выполнять команду запуска Apache (apache2-foreground) после выполнения этого скрипта. Сохраните и закройте файл.

      Создайте файл .dockerignore в корневом каталоге вашего приложения. С этим файлом при сборке образа Docker он не будет загрязнен пакетами или файлами среды, которые не следует в него копировать:

      ./.dockerignore

      .env
      /vendor
      

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

      Теперь перед локальным запуском приложения с помощью Docker Compose осталось только создать файл docker-compose.yml. Во время настройки этого файла YAML нужно будет ввести ключ APP_KEY, сгенерированный Laravel во время установки. Чтобы найти его, нужно открыть и запустить поиск файла . /.env или запустить следующие команды cat и grep:

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

      Output

      APP_KEY=base64:0EHhVpgg ... UjGE=

      Скопируйте ключ в буфер обмена. Обязательно добавьте префикс base64:. Теперь создайте файл docker-compose.yml в корневом каталоге вашего приложения:

      • nano ./docker-compose.yml

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

      ./docker-compose.yml

      version: '3.5'
      services:
        php:
          image: your_docker_hub_username/laravel-kubernetes:latest
          restart: always
          ports:
            - 8000:80
          environment:
            - APP_KEY="your_laravel_app_key"
            - APP_ENV=local
            - APP_DEBUG=true
            - DB_PORT=3306
            - DB_HOST=mysql
            - DB_DATABASE
            - DB_USERNAME
            - DB_PASSWORD
        mysql:
          image: mysql:5.7
          restart: always
          environment:
            - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
            - MYSQL_DATABASE=${DB_DATABASE}
            - MYSQL_USER=${DB_USERNAME}
            - MYSQL_PASSWORD=${DB_PASSWORD}
      

      Используйте скопированную вами в буфер обмена переменную APP_KEY для переменной your_laravel_app_key и используйте свое имя пользователя Docker Hub для переменной your_docker_hub_username. Сохраните и закройте файл.

      Первый образ вы создадите локально с помощью docker build. Второй образ — это официальный образ MySQL Docker, доступный в Docker Hub. Для обоих из них требуется несколько переменных среды, которые добавляются при запуске контейнеров.

      Запустите следующую команду для сборки образа Docker, содержащего ваше приложение Laravel. Обязательно замените your_docker_hub_username своим именем пользователя или именем пользователя команды Docker Hub, где будет храниться этот образ:

      • docker build -t your_docker_hub_username/laravel-kubernetes:latest .

      Затем вы можете запустить два контейнера с помощью Docker Compose, используя требуемые учетные данные БД:

      • DB_ROOT_PASSWORD=rootpassword DB_DATABASE=local_db DB_USERNAME=admin DB_PASSWORD=password docker-compose up -d

      Вы можете изменять четыре используемых здесь переменных среды (DB_ROOT_PASSWORD, DB_DATABASE, DB_USERNAME, DB_PASSWORD) , но поскольку вы только тестируете приложение на локальной системе, вам не нужно беспокоиться об их защите.

      Инициализация базы данных MySQL и подготовка контейнеров могут занять до 30 секунд. Когда контейнеры будут готовы, вы можете просмотреть свое приложение Laravel на локальном компьютере по адресу localhost:8000.

      Приложение Laravel, запущенное локально с помощью Docker Compose

      Ваше приложение PHP подключится к вашей базе данных MySQL. После успешного подключения под логотипом Laravel появится текст «Database Connected: local_db».

      Мы протестировали образ Docker на локальной системе с помощью Docker Compose и теперь можем остановить контейнеры с помощью команды docker-compose down:

      В следующем разделе мы отправим образ Docker в Docker Hub, чтобы чарт Helm мог использовать его для развертывания вашего приложения в вашем кластере Kubernetes.

      Шаг 3 — Отправка образа Docker в Docker Hub

      Чарт LAMP Helm, который мы будем использовать для развертывания кода в Kubernetes, требует, чтобы код был доступен в реестре контейнеров. Хотя вы можете отправить свой образ в частный или собственный реестр, в этом обучающем модуле мы будем использовать общедоступный бесплатный реестр Docker в Docker Hub.

      Откройте в браузере свою учетную запись на Docker Hub и создайте новый репозиторий с именем laravel-kubernetes.

      Создание нового репозитория в Docker Hub

      Затем если вы не подключились к Docker Hub с локального компьютера, вам нужно будет войти в Docker Hub. Это можно сделать через командную строку:

      • docker login -u your_docker_hub_username

      Введите в диалоге свои учетные данные. Обычно это нужно делать только один раз на каждом компьютере, поскольку Docker сохраняет ваши учетные данные в каталоге ~/.docker/config.json в вашем домашнем каталоге.

      В заключение отправьте свой образ в Docker Hub:

      • docker push your_docker_hub_username/laravel-kubernetes:latest

      Выгрузка приложения может занять несколько минут в зависимости от скорости подключения, однако после завершения этой операции Docker вы увидите в окне терминала окончательную сводную хэш-сумму и размер вашего образа. Он будет выглядеть примерно так:

      Output

      latest: digest: sha256:df4bdeda91484c8c26a989b13b8f27ab14d93ab2e676e3c396714cb3811c4086 size: 4918

      Мы поместили ваше приложение Laravel в контейнер и отправили образ в Docker Hub, и теперь вы можете использовать этот образ для развертывания чарта Helm или Kubernetes. На следующем шаге мы зададим персонализированные значения на базе чарта LAMP Helm и развернем его в вашем кластере DigitalOcean Kubernetes.

      Шаг 4 — Настройка и развертывание приложения с помощью чарта LAMP Helm

      В Helm имеется ряд чартов, помогающих настраивать приложения Kubernetes с использованием готовых комбинаций инструментов. Хотя вы можете самостоятельно написать служебные файлы Kubernetes для аналогичного развертывания, в этом разделе вы увидите, что использование чарта Helm требует намного меньше настроек.

      Прежде всего, вам потребуется каталог для хранения всех ваших файлов конфигурации Helm. Создайте в корневом каталоге вашего проекта Laravel новый каталог с именем helm/:

      В каталоге helm/ мы создадим два новых файла: values.yml и secrets.yml. Вначале создайте и откройте файл values.yml:

      Файл values.yml будет содержать несекретные параметры конфигурации, которые будут заменять значения по умолчанию в чарте LAMP Helm. Добавьте следующие конфигурации, заменив your_docker_hub_username своим именем пользователя:

      ./helm/values.yml

      php:
        repository: "your_docker_hub_username/laravel-kubernetes"
        tag: "latest"
        fpmEnabled: false
        envVars:
          - name: APP_ENV
            value: production
          - name: APP_DEBUG
            value: false
          - name: DB_PORT
            value: 3306
          - name: DB_HOST
            value: localhost
      

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

      Теперь создайте файл secrets.yml:

      secrets.yml не регистрируется в системе контроля версий. Он будет содержать важные данные конфигурации, в том числе ваш пароль базы данных и ключ приложения Laravel. Добавьте следующие конфигурации с вашими учетными данными:

      ./helm/secrets.yml

      mysql:
        rootPassword: "your_database_root_password"
        user: your_database_user
        password: "your_database_password"
        database: your_database_name
      
      php:
        envVars:
          - name: APP_KEY
            value: "your_laravel_app_key"
          - name: DB_DATABASE
            value: your_database_name
          - name: DB_USERNAME
            value: your_database_user
          - name: DB_PASSWORD
            value: "your_database_password"
      

      Обязательно используйте надежные сочетания имени пользователя и пароля для производственной базы данных и используйте тот же ключ your_laravel_app_key, что и выше, или откройте новое окно терминала и сгенерируйте новый ключ с помощью следующей команды. После этого вы можете скопировать новое значение, задаваемое Laravel в вашем файле .env:

      • docker run --rm -v $(pwd):/app php:cli php /app/artisan key:generate

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

      Чтобы ваш файл secrets.yml не добавлялся в образ Docker и не сохранялся в системе контроля версий, обязательно добавьте следующую строку в ваши файлы .dockerignore и .gitignore. Откройте и добавьте /helm/secrets.yml в каждый файл или запустите следующую команду для добавления в оба файла:

      • echo '/helm/secrets.yml' >> ./.dockerignore && echo '/helm/secrets.yml' >> ./.gitignore

      Вы создали файлы конфигурации Helm для вашего приложения и образа Docker и теперь можете установить этот чарт Helm как новый релиз в вашем кластере Kubernetes. Установите чарт из корневого каталога вашего приложения:

      • helm install laravel-kubernetes -f helm/values.yml -f helm/secrets.yml stable/lamp

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

      Output

      NAME: laravel-kubernetes LAST DEPLOYED: Mon May 18 13:21:20 2020 NAMESPACE: default STATUS: deployed REVISION: 1

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

      Поищите имя вашего приложения:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) laravel-kubernetes-lamp LoadBalancer your_cluster_ip your_external_ip 80:32175/TCP,3306:32243/TCP

      Когда новая служба laravel-kubernetes-lamp отображает IP-адрес под EXTERNAL-IP, вы можете открыть your_external_ip, чтобы увидеть приложение, запущенное в кластере Kubernetes. Ваше приложение подключится к вашей базе данных, и вы увидите имя базы данных под логотипом Laravel, как при локальном запуске приложения с помощью Docker Compose.

      Приложение Laravel, запущенное в Kubernetes с помощью чарта LAMP Helm

      Для концептуальных испытаний веб-приложение можно запустить с незащищенного IP-адреса, но ваш сайт не будет готов для производственной среды без сертификата SSL и персонализированного доменного имени. На следующем шаге мы настроим их, но предварительно нужно удалить релиз через командную строку:

      • helm delete laravel-kubernetes

      На следующем шаге мы расширим первую конфигурацию Helm, добавив контроллер Ingress, сертификат SSL и персонализированный домен в наше приложение Laravel.

      Шаг 5 — Добавление контроллера Ingress и SSL в кластер Kubernetes

      В Kubernetes контроллер Ingress отвечает за предоставление доступа к службам вашего приложения через интернет. На предыдущем шаге чарт LAMP Helm создал балансировщик нагрузки DigitalOcean и открыл прямой доступ к вашему приложению через IP-адрес балансировщика.

      Вы можете вывести SSL и доменное имя напрямую на балансировщик нагрузки, но поскольку мы работаем в Kubernetes, будет удобнее управлять всем в одном месте. Дополнительную информацию о контроллерах Ingress и подробные сведения о следующих шагах можно найти в руководстве «Настройка Nginx Ingress в DigitalOcean Kubernetes с помощью Helm».

      Чарт LAMP Helm включает опцию конфигурации для поддержки Ingress. Откройте ваш файл helm/values.yml:

      Добавьте в него следующие строки:

      ./helm/values.yml

      ...
      # Use Ingress Controller
      service:
        type: ClusterIP
        HTTPPort: 80
      ingress:
        enabled: true
        domain: your_domain
      

      Данная опция указывает, что при развертывании не нужно устанавливать балансировщик нагрузки и что нужно предоставить доступ к приложению через порт 80 кластера Kubernetes, доступ к которому контроллер Ingress откроет через Интернет. Сохраните и закройте файл values.yml.

      Запустите команду helm install, которую вы запускали ранее, чтобы снова запустить приложение Laravel. Команду нужно запускать из корневого каталога вашего приложения:

      • helm install laravel-kubernetes -f helm/values.yml -f helm/secrets.yml stable/lamp

      Затем установите контроллер nginx-ingress в своем кластере Kubernetes, используя обслуживаемый Kubernetes-контроллер Nginx Ingress:

      • helm install nginx-ingress stable/nginx-ingress --set controller.publishService.enabled=true

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

      Output

      NAME: nginx-ingress LAST DEPLOYED: Mon May 18 13:28:34 2020 NAMESPACE: default STATUS: deployed REVISION: 1

      Чтобы открыть доступ к развертыванию вашего приложения Laravel, вам также потребуется ресурс Ingress. Создайте в корневом каталоге вашего приложения новый файл с именем ingress.yml:

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

      ./ingress.yml

      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: laravel-kubernetes-ingress
        annotations:
          kubernetes.io/ingress.class: nginx
          cert-manager.io/cluster-issuer: letsencrypt-prod
      spec:
        tls:
          - hosts:
              - your_domain
            secretName: laravel-kubernetes-tls
        rules:
          - host: your_domain
            http:
              paths:
                - backend:
                    serviceName: laravel-kubernetes-lamp
                    servicePort: 80
      

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

      Затем необходимо установить Cert-Manager и создать центр, который позволит вам создавать производственные сертификаты SSL с помощью Let’s Encrypt. Для Cert-Manager требуются персонализированные определения ресурсов, которые вы можете применить из репозитория Cert-Manager через командную строку:

      • kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.crds.yaml

      При этом будет создан ряд ресурсов Kubernetes, которые будут выведены в командной строке:

      Output

      customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io create

      Cert-Manager также требуется пространство имен для его изоляции в кластере Kubernetes:

      • kubectl create namespace cert-manager

      Вы увидите следующее:

      Output

      namespace/cert-manager created

      Поскольку Jetstack Cert-Manager не входит в число чартов, обслуживаемых Kubernetes, вам нужно будет также добавить репозиторий Jetstack Helm. Запустите следующую команду, чтобы сделать ее доступной в Helm:

      • helm repo add jetstack https://charts.jetstack.io

      При успешном добавлении вывод будет выглядеть так:

      Output

      "jetstack" has been added to your repositories

      Теперь мы готовы установить Cert-Manager в пространство имен cert-manager в кластере Kubernetes:

      • helm install cert-manager --version v0.15.0 --namespace cert-manager jetstack/cert-manager

      После выполнения этой операции вы увидите сводную информацию о развертывании:

      Output

      NAME: cert-manager LAST DEPLOYED: Mon May 18 13:32:08 2020 NAMESPACE: cert-manager STATUS: deployed REVISION: 1

      В заключение нужно добавить в корневой каталог приложения Laravel файл конфигурации Kubernetes с именем production_issuer.yml. Создайте файл:

      • nano ./production_issuer.yml

      Добавьте следующее:

      apiVersion: cert-manager.io/v1alpha2
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-prod
      spec:
        acme:
          # Email address used for ACME registration
          email: your_email_address
          server: https://acme-v02.api.letsencrypt.org/directory
          privateKeySecretRef:
            # Name of a secret used to store the ACME account private key
            name: letsencrypt-prod-private-key
          # Add a single challenge solver, HTTP01 using nginx
          solvers:
            - http01:
                ingress:
                  class: nginx
      

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

      Let’s Encrypt будет отправлять на адрес your_email_address все важные уведомления и предупреждения об окончании срока действия сертификата, так что укажите адрес, который вы будете регулярно проверять. Сохраните этот файл и создайте новый ресурс для вашего ресурса Ingress и производственного центра сертификации в вашем кластере Kubernetes:

      • kubectl create -f ingress.yml
      • kubectl create -f production_issuer.yml

      В заключение обновите записи DNS вашего доменного имени, чтобы запись A указывала на IP-адрес вашего балансировщика нагрузки. Чтобы найти IP-адрес вашего контроллера Ingress, введите следующую команду:

      • kubectl get service nginx-ingress-controller

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-ingress-controller LoadBalancer your_cluster_ip your_external_ip 80:30187/TCP,443:31468/TCP 6m10s

      Используйте адрес your_external_ip в качестве IP-адреса вашей записи DNS A. Процесс обновления записей DNS зависит от того, где вы управляете доменными именами и хостингом DNS, но если вы используете DigitalOcean, вы можете сослаться на наше руководство по управлению записями DNS.

      После обновления ваших записей DNS и генерирования сертификата SSL ваше приложение будет доступно по адресу your_domain с включенным SSL.

      Приложение Laravel с SSL и персонализированным доменным именем

      Хотя ваше приложение PHP и база данных уже связаны, вам все равно необходимо провести миграцию базы данных. На последнем шаге мы увидим, как запускать команды Artisan в поде Kubernetes для миграции базы данных и выполнения других распространенных задач технического обслуживания.

      Шаг 6 — Дистанционный запуск команд

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

      Прежде чем запускать команду Artisan для вашего приложения Laravel, вам нужно знать имя пода, где запущен контейнер вашего приложения Laravel. Для просмотра всех подов в вашем кластере Kubernetes используйте следующую команду:

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

      Output

      NAME READY STATUS RESTARTS AGE laravel-kubernetes-lamp-77fb989b46-wczgb 2/2 Running 0 16m

      Выберите под для развертывания laravel-kubernetes-lamp-... Обязательно используйте выведенное имя, а не указанное выше. Теперь вы можете запустить для него команду kubectl exec. Например, для проведения миграции базы данных используйте команду artisan migrate. Мы добавляем флаг --force, поскольку команда выполняется на поде в производственной среде:

      • kubectl exec laravel-kubernetes-lamp-77fb989b46-wczgb -- php artisan migrate --force

      Эта команда выводит следующее:

      Output

      Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.16 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.05 seconds)

      Мы успешно развернули Laravel 7 и MySQL в Kubernetes и выполнили необходимую задачу по обслуживанию базы данных.

      Заключение

      В этом обучающем модуле мы научились выполнять контейнеризацию приложения Laravel PHP, подключать его к базе данных MySQL, отправлять образ Docker с кодом в Docker Hub, а затем использовать чарт Helm для развертывания этого образа в кластере DigitalOcean Kubernetes. В заключение мы добавили SSL и персонализированное доменное имя и научились запускать инструменты командной строки в работающих подах.

      Kubernetes и Helm дают ряд преимуществ по сравнению с традиционными вариантами хостинга стека LAMP: масштабируемость, возможность замены служб без прямого входа на сервер, инструменты для обновления во время работы и контроль над средой хостинга. При этом сложность начальной контейнеризации и настройки приложения делает начало работы непростой задачей. С этим руководством развертывание Laravel в кластере Kubernetes станет более достижимой задачей. Теперь вы можете изучить дополнительную информацию о возможностях Laravel и добавлении в Kubernetes инструментов мониторинга, таких как Linkerd, которые вы можете установить вручную с помощью нашего руководства или системы DigitalOcean 1-Click.



      Source link

      How To Deploy Laravel 7 and MySQL on Kubernetes using Helm


      The author selected the Diversity in Tech Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      Laravel is one of the most popular open-source PHP application frameworks today. It is commonly deployed with a MySQL database but can be configured to use a variety of backend data storage options. Laravel prides itself on taking advantage of many of PHP’s modern features and extensive package ecosystem.

      Kubernetes is a container orchestration platform that can be hosted on DigitalOcean Kubernetes clusters to take much of the administration work out of setting up and running containers in production. Helm is a Kubernetes package manager that makes configuring and installing services and pods on Kubernetes easier.

      In this guide, you will create a Laravel PHP application, build your app into a Docker image, and deploy that image to a DigitalOcean Kubernetes cluster using the LAMP Helm chart. Next, you’ll set up an Ingress Controller to add SSL and a custom domain name to your app. When completed, you will have a working Laravel application connected to a MySQL database that is running on a Kubernetes cluster.

      Prerequisites

      • Docker installed on the machine that you’ll access your cluster from. You can find detailed instructions on installing Docker for most Linux distributions here or on Docker’s website for other operating systems.
      • An account at Docker Hub for storing Docker images you’ll create during this tutorial.
      • A DigitalOcean Kubernetes 1.17+ cluster with your connection configuration set as the kubectl default. To learn how to create a Kubernetes cluster on DigitalOcean, see Kubernetes Quickstart. To learn how to connect to the cluster, see How to Connect to a DigitalOcean Kubernetes Cluster.
      • The Helm 3 package manager installed on your local machine. Complete the first step and add the stable repo from the second step of the How To Install Software on Kubernetes Clusters with the Helm 3 Package Manager tutorial.
      • A fully registered domain name with an available A record. This tutorial will use your_domain throughout. You can purchase a domain name on Namecheap, get one for free on Freenom, or use the domain registrar of your choice. Don’t worry about associating your domain’s A record with an IP at this time. Once you reach Step 5 and your Ingress controller is in place, you will connect your_domain to the proper IP.

      Step 1 — Creating a New Laravel Application

      In this step, you’ll use Docker to create a new Laravel 7 application, but you should be able to go through the same process with an existing Laravel application that uses MySQL as the backing database. The new application you build will verify that Laravel is connected to the database and display the name of the database.

      First, move to your home directory and then create a new Laravel application using a composer Docker container:

      • cd ~
      • docker run --rm -v $(pwd):/app composer create-project --prefer-dist laravel/laravel laravel-kubernetes

      Once the container is done and all the Composer packages have been installed, you should see a fresh installation of Laravel in your current directory called laravel-kubernetes/. Navigate to that folder:

      You’ll execute the rest of this tutorial’s commands from here.

      The purpose of this application is to test your database connection and display its name in your browser. In order to test the database connection, open up the ./resources/views/welcome.blade.php file in a text editor:

      • nano ./resources/views/welcome.blade.php

      Find the section <div class="links">...</div> and replace its contents with the following:

      ./resources/views/welcome.blade.php

      ...
      <div class="links">
         <strong>Database Connected: </strong>
          @php
              try {
                  DB::connection()->getPDO();
                  echo DB::connection()->getDatabaseName();
                  } catch (Exception $e) {
                  echo 'None';
              }
          @endphp
      </div>
      ...
      

      Save and close the file.

      That’s all the customization you’ll need to make to the default Laravel app for this tutorial. Once completed, this brief snippet of PHP will test your database connection and display the database’s name on the Laravel splash screen in your web browser.

      In the next step, you’ll use Docker to build an image containing this Laravel application and Docker Compose to test that it runs locally and connects to a MySQL database.

      Step 2 — Containerizing Your Laravel Application

      Now that you have created a new Laravel application, you’ll need to build your code into a Docker image and then test the image with Docker Compose. While the goal of this tutorial is to deploy your application to a Kubernetes cluster, Docker Compose is a convenient way to test your Docker image and configuration locally before running it in the cloud. This fast feedback loop can be useful for making and testing small changes.

      First, using nano or your preferred text editor, create a file in the root of your Laravel application called Dockerfile:

      Add the following content. Docker will use this file to build your code into an image:

      ./Dockerfile

      FROM php:7.4-apache
      
      # Install packages
      RUN apt-get update && apt-get install -y 
          git 
          zip 
          curl 
          sudo 
          unzip 
          libicu-dev 
          libbz2-dev 
          libpng-dev 
          libjpeg-dev 
          libmcrypt-dev 
          libreadline-dev 
          libfreetype6-dev 
          g++
      
      # Apache configuration
      ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
      RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
      RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
      RUN a2enmod rewrite headers
      
      # Common PHP Extensions
      RUN docker-php-ext-install 
          bz2 
          intl 
          iconv 
          bcmath 
          opcache 
          calendar 
          pdo_mysql
      
      # Ensure PHP logs are captured by the container
      ENV LOG_CHANNEL=stderr
      
      # Set a volume mount point for your code
      VOLUME /var/www/html
      
      # Copy code and run composer
      COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
      COPY . /var/www/tmp
      RUN cd /var/www/tmp && composer install --no-dev
      
      # Ensure the entrypoint file can be run
      RUN chmod +x /var/www/tmp/docker-entrypoint.sh
      ENTRYPOINT ["/var/www/tmp/docker-entrypoint.sh"]
      
      # The default apache run command
      CMD ["apache2-foreground"]
      

      Save and close the file.

      This Dockerfile starts with the PHP 7.4 Apache Docker Image found on Docker Hub, then installs several Linux packages that are commonly required by Laravel applications. Next, it creates Apache configuration files and enables header rewrites. The Dockerfile installs several common PHP extensions and adds an environment variable to ensure that Laravel’s logs are streamed to the container via stderr. This will allow you to see Laravel logs by tailing your Docker Compose or Kubernetes logs.

      Finally, the Dockerfile copies all the code in your Laravel application to /var/www/tmp and installs the Composer dependencies. It then sets an ENTRYPOINT, but you’ll need to create that file, which we will do next.

      At the root directory of your project, create a new file called docker-entrypoint.sh. This file will run when your container is run locally or in the Kubernetes cluster, and it will copy your Laravel application code from the /var/www/tmp directory to /var/www/html where Apache will be able to serve it.

      • nano ./docker-entrypoint.sh

      Now add the following script:

      ./docker-entrypoint.sh

      #!/bin/bash
      
      cp -R /var/www/tmp/. /var/www/html/
      chown -R www-data:www-data /var/www/html
      
      exec "$@"
      

      The final line, exec "$@" instructs the shell to run whatever command was passed in as an input argument next. This is important because you want Docker to continue running the Apache run command (apache2-foreground) after this script executes. Save and close the file.

      Next, create a .dockerignore file in your app’s root directory. This file will ensure that when you build your Docker image it won’t become polluted with packages or environment files that shouldn’t be copied into it:

      ./.dockerignore

      .env
      /vendor
      

      Save and close the file.

      The last file that you need to create before you can run your app locally using Docker Compose is a docker-compose.yml file. But during the configuration of this YAML file, you will need to enter the APP_KEY that Laravel generated during installation. Find this by opening and searching the ./.env file, or by running the following cat and grep commands:

      You will see an output like this:

      Output

      APP_KEY=base64:0EHhVpgg ... UjGE=

      Copy your key to your clipboard. Be sure to include the base64: prefix. Now create the docker-compose.yml file in your app’s root directory:

      • nano ./docker-compose.yml

      Here we will include your Laravel application’s PHP image as well as a MySQL container to run your database. Add the following content:

      ./docker-compose.yml

      version: '3.5'
      services:
        php:
          image: your_docker_hub_username/laravel-kubernetes:latest
          restart: always
          ports:
            - 8000:80
          environment:
            - APP_KEY="your_laravel_app_key"
            - APP_ENV=local
            - APP_DEBUG=true
            - DB_PORT=3306
            - DB_HOST=mysql
            - DB_DATABASE
            - DB_USERNAME
            - DB_PASSWORD
        mysql:
          image: mysql:5.7
          restart: always
          environment:
            - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
            - MYSQL_DATABASE=${DB_DATABASE}
            - MYSQL_USER=${DB_USERNAME}
            - MYSQL_PASSWORD=${DB_PASSWORD}
      

      Use the APP_KEY variable that you copied to your clipboard for the your_laravel_app_key variable, and use your Docker Hub username for the your_docker_hub_username variable. Save and close the file.

      You’ll create the first image locally using docker build. The second image is the official MySQL Docker image available on Docker Hub. Both require several environment variables, which you’ll include when you run the containers.

      In order to build the Docker image containing your Laravel application, run the following command. Make sure to replace your_docker_hub_username with your username or your team’s username at Docker Hub where this image will be stored:

      • docker build -t your_docker_hub_username/laravel-kubernetes:latest .

      Next, you can run the two containers with Docker Compose with the required database credentials:

      • DB_ROOT_PASSWORD=rootpassword DB_DATABASE=local_db DB_USERNAME=admin DB_PASSWORD=password docker-compose up -d

      The four environment variables used here (DB_ROOT_PASSWORD, DB_DATABASE, DB_USERNAME, DB_PASSWORD) can be modified if you’d like, but since you are only testing your application locally, you don’t have to worry about securing them yet.

      It may take up to 30 seconds for your MySQL database to initialize and your containers to be ready. Once they are, you can view your Laravel application on your machine at localhost:8000.

      The Laravel application running locally using Docker Compose

      Your PHP application will connect to your MySQL database. After a successful connection, the text “Database Connected: local_db” will appear beneath the Laravel logo.

      Now that you’ve tested your Docker image locally using Docker Compose, you can bring the containers down by running docker-compose down:

      In the next section, you’ll push your Docker image to Docker Hub so that your Helm chart can use it to deploy your application to your Kubernetes cluster.

      Step 3 — Pushing Your Docker Image to Docker Hub

      The LAMP Helm Chart that you’ll use to deploy your code to Kubernetes requires that your code be available in a container registry. While you can push your image to a private or self-hosted registry, for the purposes of this tutorial you’ll use a publicly available and free Docker registry on Docker Hub.

      Access your account on Docker Hub using your web browser and then create a new repository called laravel-kubernetes.

      Creating a new repository on Docker Hub

      Next, if you haven’t connected to Docker Hub from your local machine, you’ll need to log into Docker Hub. You can do this through the command line:

      • docker login -u your_docker_hub_username

      Enter your login credentials when prompted. This typically only needs to be done once per machine as Docker will save your credentials to the ~/.docker/config.json in your home directory.

      Finally, push your image to Docker Hub:

      • docker push your_docker_hub_username/laravel-kubernetes:latest

      It may take a few minutes to upload your app depending on your connecti
      on speed, but once Docker is done, you’ll see a final digest hash and the size of your image in the terminal. It will look something like this:

      Output

      latest: digest: sha256:df4bdeda91484c8c26a989b13b8f27ab14d93ab2e676e3c396714cb3811c4086 size: 4918

      Now that your Laravel application is containerized and you’ve pushed an image to Docker Hub, you can use the image in a Helm Chart or Kubernetes deployment. In the next step, you’ll set custom values based on the LAMP Helm Chart and deploy it to your DigitalOcean Kubernetes cluster.

      Step 4 — Configuring and Deploying the Application with the LAMP Helm Chart

      Helm provides a number of Charts to help you set up Kubernetes applications using preset combinations of tools. While you could write your own Kubernetes service files to accomplish a similar deployment, you’ll see in this section that using a Helm Chart will require much less configuration.

      First, you’ll need a directory to store all your Helm configuration files. Create a new directory in the root of your Laravel project called helm/:

      Inside the helm/ directory, you will create two new files: values.yml and secrets.yml. First create and open values.yml:

      The values.yml file will include non-secret configuration options that will override the default values in the LAMP Helm chart. Add the following configurations, making sure to replace your_docker_hub_username with your own username:

      ./helm/values.yml

      php:
        repository: "your_docker_hub_username/laravel-kubernetes"
        tag: "latest"
        fpmEnabled: false
        envVars:
          - name: APP_ENV
            value: production
          - name: APP_DEBUG
            value: false
          - name: DB_PORT
            value: 3306
          - name: DB_HOST
            value: localhost
      

      Save and close the file.

      Now create a secrets.yml file:

      secrets.yml will not be checked into version control. It will contain sensitive configuration information like your database password and Laravel app key. Add the following configurations, adjusting as needed to fit your credentials:

      ./helm/secrets.yml

      mysql:
        rootPassword: "your_database_root_password"
        user: your_database_user
        password: "your_database_password"
        database: your_database_name
      
      php:
        envVars:
          - name: APP_KEY
            value: "your_laravel_app_key"
          - name: DB_DATABASE
            value: your_database_name
          - name: DB_USERNAME
            value: your_database_user
          - name: DB_PASSWORD
            value: "your_database_password"
      

      Be sure to use strong username and password combinations for your production database, and use the same your_laravel_app_key as above, or open a new terminal window and generate a new one by running the following command. You can then copy the new value Laravel sets in your .env file:

      • docker run --rm -v $(pwd):/app php:cli php /app/artisan key:generate

      Save and close secrets.yml.

      Next, in order to prevent your secrets.yml file from being built into the Docker image or saved to version control, make sure to add the following line to both your .dockerignore and .gitignore files. Open and append /helm/secrets.yml to each file, or run the following command to add both:

      • echo '/helm/secrets.yml' >> ./.dockerignore && echo '/helm/secrets.yml' >> ./.gitignore

      Now that you’ve created Helm configuration files for your application and the Docker image, you can install this Helm chart as a new release on your Kubernetes cluster. Install your chart from your application’s root directory:

      • helm install laravel-kubernetes -f helm/values.yml -f helm/secrets.yml stable/lamp

      You will see an output like this:

      Output

      NAME: laravel-kubernetes LAST DEPLOYED: Mon May 18 13:21:20 2020 NAMESPACE: default STATUS: deployed REVISION: 1

      Your application will take a minute or two to become available, but you can run this command to monitor the Kubernetes services in your cluster:

      Look for the name of your application:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) laravel-kubernetes-lamp LoadBalancer your_cluster_ip your_external_ip 80:32175/TCP,3306:32243/TCP

      When your new laravel-kubernetes-lamp service displays an IP address under EXTERNAL-IP, you can visit your_external_ip to see the application running on your Kubernetes cluster. Your app will connect to your database and you will see the name of the database below the Laravel logo, like you did when running your app locally on Docker Compose.

      The Laravel application running on Kubernetes using the LAMP Helm chart

      Running a web application on an unsecured IP address might be okay for a proof of concept, but your website isn’t production-ready without an SSL certificate and a custom domain name. Before you set that up in the next step, uninstall your release via the command line:

      • helm delete laravel-kubernetes

      In the next step you’ll expand on this first Helm configuration to add an Ingress controller, SSL certificate, and custom domain to your Laravel application.

      Step 5 — Adding an Ingress Controller and SSL to Your Kubernetes Cluster

      In Kubernetes, an Ingress Controller is responsible for exposing your application’s services to the internet. In the previous step, the LAMP Helm chart created a DigitalOcean Load Balancer and exposed your application directly via the load balancer’s IP address.

      You could terminate SSL and your domain name directly on the load balancer, but because you’re working in Kubernetes, it might be more convenient to manage it all in the same place. For much more about Ingress Controllers and details about the following steps, read How To Set Up an Nginx Ingress on DigitalOcean Kubernetes Using Helm.

      The LAMP Helm chart includes a configuration option for supporting Ingress. Open up your helm/values.yml file:

      Now add the following lines:

      ./helm/values.yml

      ...
      # Use Ingress Controller
      service:
        type: ClusterIP
        HTTPPort: 80
      ingress:
        enabled: true
        domain: your_domain
      

      This instructs your deployment not to install a load balancer and instead to expose the application to the Kubernetes cluster’s port 80 where the Ingress Controller will expose it to the internet. Save and close values.yml.

      Now run the helm install command you ran previously to get your Laravel application running again. Make sure to run the command from your app’s root directory:

      • helm install laravel-kubernetes -f helm/values.yml -f helm/secrets.yml stable/lamp

      Next, install the nginx-ingress controller on your Kubernetes cluster using the Kubernetes-maintained Nginx Ingress Controller:

      • helm install nginx-ingress stable/nginx-ingress --set controller.publishService.enabled=true

      After installation, you will see an output like this:

      Output

      NAME: nginx-ingress LAST DEPLOYED: Mon May 18 13:28:34 2020 NAMESPACE: default STATUS: deployed REVISION: 1

      You also need an Ingress Resource to expose your Laravel app’s deployment. Create a new file in your app’s root directory called ingress.yml:

      This file defines your application’s host, SSL certificate manager, and backend service and port name. Add the following configurations, replaceing your_domain with the domain of your choice:

      ./ingress.yml

      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: laravel-kubernetes-ingress
        annotations:
          kubernetes.io/ingress.class: nginx
          cert-manager.io/cluster-issuer: letsencrypt-prod
      spec:
        tls:
          - hosts:
              - your_domain
            secretName: laravel-kubernetes-tls
        rules:
          - host: your_domain
            http:
              paths:
                - backend:
                    serviceName: laravel-kubernetes-lamp
                    servicePort: 80
      

      Save and close the file.

      Next, you should install Cert-Manager and create an issuer that will allow you to create production SSL certificates using Let’s Encrypt. Cert-Manager requires Custom Resource Definitions that you can apply from the Cert-Manager repository using the command line:

      • kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.crds.yaml

      This will create a number of Kubernetes resources that will be displayed in the command line:

      Output

      customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io create

      Cert-Manager also requires a namespace to isolate it in your Kubernetes cluster:

      • kubectl create namespace cert-manager

      You will see this output:

      Output

      namespace/cert-manager created

      Because Jetstack’s Cert-Manager is not one of the Kubernetes-maintained charts, you will need to add the Jetstack Helm repository as well. Run the following command to make it available in Helm:

      • helm repo add jetstack https://charts.jetstack.io

      A successful addition will output the following:

      Output

      "jetstack" has been added to your repositories

      Now you’re ready to install Cert-Manager into the cert-manager namespace on your Kubernetes cluster:

      • helm install cert-manager --version v0.15.0 --namespace cert-manager jetstack/cert-manager

      When complete, you’ll see a summary of the deployment like this:

      Output

      NAME: cert-manager LAST DEPLOYED: Mon May 18 13:32:08 2020 NAMESPACE: cert-manager STATUS: deployed REVISION: 1

      The last file you’ll need to add to your Laravel application’s root directory is a production_issuer.yml Kubernetes configuration file. Create the file:

      • nano ./production_issuer.yml

      Now add the following:

      apiVersion: cert-manager.io/v1alpha2
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-prod
      spec:
        acme:
          # Email address used for ACME registration
          email: your_email_address
          server: https://acme-v02.api.letsencrypt.org/directory
          privateKeySecretRef:
            # Name of a secret used to store the ACME account private key
            name: letsencrypt-prod-private-key
          # Add a single challenge solver, HTTP01 using nginx
          solvers:
            - http01:
                ingress:
                  class: nginx
      

      Save and close the file.

      Let’s Encrypt will send your_email_address any important notices and expiration warnings, so be sure to add an address that you’ll check regularly. Save this file and create a new resource for both your Ingress resource and production issuer in your Kubernetes cluster:

      • kubectl create -f ingress.yml
      • kubectl create -f production_issuer.yml

      Finally, update your domain name’s DNS records to point an A record to your load balancer’s IP address. To find the IP address for your Ingress Controller enter:

      • kubectl get service nginx-ingress-controller

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-ingress-controller LoadBalancer your_cluster_ip your_external_ip 80:30187/TCP,443:31468/TCP 6m10s

      Use the your_external_ip address as the IP address for your DNS A Record. The process for updating your DNS records varies depending on where you manage your domain names and DNS hosting, but if you’re using DigitalOcean you can reference our guide on How to Manage DNS Records.

      Once your DNS records update and your SSL certificate is generated, your application will be available at your_domain and SSL will be enabled.

      The Laravel application with SSL termination and a custom domain name

      While your PHP application and database are already connected, you will still need to run database migrations. In the last step, you’ll see how to run Artisan commands on your Kubernetes pod to perform database migrations and other common maintenance tasks.

      Step 6 — Running Remote Commands

      While your Laravel application is running and connected to the MySQL database in Kubernetes, there are several common operations that you should run on a new Laravel installation. One common task that you should perform is database migrations.

      Before you can run an Artisan command on your Laravel application, you need to know the name of the pod that is running your Laravel application container. Using the command line, you can view all the pods in your Kubernetes cluster:

      You will see an output like this:

      Output

      NAME READY STATUS RESTARTS AGE laravel-kubernetes-lamp-77fb989b46-wczgb 2/2 Running 0 16m

      Select the pod for your laravel-kubernetes-lamp-... deployment. Make sure to use the name in your output and not the one listed above. Now you can run kubectl exec on it. For example, run a database migration using the artisan migrate command. You will add the --force flag because you’re running the pod in production:

      • kubectl exec laravel-kubernetes-lamp-77fb989b46-wczgb -- php artisan migrate --force

      This command will produce an output:

      Output

      Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.16 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.05 seconds)

      You have now successfully deployed Laravel 7 and MySQL to Kubernetes and performed an essential database maintenance task.

      Conclusion

      In this tutorial, you learned how to containerize a Laravel PHP application, connect it to a MySQL database, push a Docker image containing your code to Docker Hub, and then use a Helm chart to deploy that image to a DigitalOcean Kubernetes cluster. Finally, you added SSL and a custom domain name and learned how to run command line tools on your running pods.

      Kubernetes and Helm offer you a number of advantages over traditional LAMP stack hosting: scalability, the ability to swap out services without logging into your server directly, tools to perform rolling upgrades, and control over your hosting environment. That said, the complexity of initially containerizing and configuring your application makes the barrier to getting started quite high. With this guide as a starting point, deploying Laravel to Kubernetes becomes more attainable. From here you might consider learning more about the power of Laravel or adding monitoring tools to Kubernetes like Linkerd, which you can install manually with our guide or with a DigitalOcean 1-Click.



      Source link