Kubernetes (también conocido como k8s) es un sistema de orquestación de código abierto. Permite a los usuarios implementar, escalar y administrar aplicaciones en contenedores con un tiempo de inactividad mínimo. En este tutorial, aprenderá a implementar una aplicación PHP en un clúster de Kubernetes.
Nginx se comporta como un proxy para PHP-FPM mientras se ejecuta una aplicación PHP. Administrar estos dos servicios en un solo contenedor es un proceso difícil. Kubernetes nos ayuda a administrarlos en dos contenedores diferentes y reduce las complicaciones. También permite a los usuarios reutilizar los contenedores y no preocuparse por compilar su imagen de contenedor para cada nueva versión de PHP/Nginx.
Ejecutará su aplicación y el servicio de proxy en dos contenedores separados. El tutorial también proporcionará información sobre cómo utilizar el almacenamiento local para crear un Volumen Persistente (PV) y una Solicitud de Volumen Persistente (PVC). Luego, utilizará esta PVC para mantener sus archivos de configuración y código fuera de las imágenes de contenedor. Después de completar este tutorial, podrá reutilizar su imagen de Nginx para otras aplicaciones que requieran un servidor proxy. Puede lograr esto pasando una configuración, en lugar de reconstruir la imagen para ello.
Requisitos previos
- Una comprensión básica de Kubernetes (k8s) y sus objetos. Consulte esta guía para obtener una visión detallada del ecosistema de Kubernetes.
- Un clúster de Kubernetes que esté activo y en funcionamiento en Ubuntu 18.04. Siga este tutorial para crear su clúster de Kubernetes usando kubeadm.
- Además, debe alojar el código de su aplicación en una URL pública, por ejemplo, GitHub.
Paso 1: Crear los servicios PHP-FPM y Nginx
Este paso le ayudará a crear los servicios PHP-FPM y Nginx. Cualquier servicio proporciona acceso a un conjunto de pods dentro de un clúster. Todos los servicios presentes en un clúster pueden comunicarse entre sí con sus nombres, sin direcciones IP. El servicio PHP-FPM y el servicio Nginx proporcionarán acceso a los pods de PHP-FPM y Nginx, respectivamente.
Deberá indicarle al servicio PHP-FPM cómo encontrar los pods de Nginx, ya que actuará como un proxy para los pods de PHP-FPM. Para esto, aprovechará el descubrimiento automático de servicios de Kubernetes’ y utilizará nombres legibles por humanos para enrutar la solicitud al servicio respectivo.
Para crear cualquier servicio, deberá crear un archivo YAML que contenga la definición del objeto. Este archivo YAML tiene al menos las siguientes etiquetas:
apiVersion: La versión de la API de Kubernetes a la que pertenece la definición.kind: El tipo de objeto de Kubernetes que crea este archivo YAML. Por ejemplo: unservice, unjob, o unpod.metadata: El nombre del objeto y las diferenteslabelsque el usuario podría querer aplicar a este objeto se definen bajo esta etiqueta.spec: Esta etiqueta contiene la especificación del objeto, como las variables de entorno (ENV), la imagen de contenedor que se utilizará y los puertos en los que el servicio del contenedor estará accesible.
Creación del servicio PHP-FPM
Para empezar, debe crear un directorio para guardar la definición de su objeto de Kubernetes. Inicie sesión en su nodo maestro y cree un directorio llamado “definitions:”
|
1 |
mkdir definitions |
Cambie al directorio definitions:
|
1 |
cd definitions |
A continuación, cree su archivo de servicio PHP-FPM como el archivo php_service.yaml:
|
1 |
nano php_fpm_service.yaml |
Después de eso, establezca apiVersion y kind en el archivo php_fpm_service.yaml:
|
1 2 |
apiVersion: v1 kind: Service |
Nombre su servicio como php o php-fpm ya que proporcionará acceso a su aplicación PHP-FPM:
|
1 2 3 |
… Metadata: name: php |
Etiquete su servicio php como tier: backend ya que la aplicación PHP se ejecutará detrás de este servicio:
|
1 2 3 |
… labels: tier: backend |
Un servicio utiliza las etiquetas de selector para determinar a qué pods acceder. Cualquier pod que coincida con estas etiquetas, independientemente de cuándo se haya creado, recibirá servicio. Aprenderá cómo agregar etiquetas a sus pods más adelante en este tutorial.
Incluye la etiqueta tier: backend que asigna tu pod a la capa backend, junto con la etiqueta app: php-fpm para indicar que el pod ejecuta una aplicación PHP-FPM. Debes añadir estas etiquetas después de la sección metadata:
|
1 2 3 4 5 |
… spec: selector: app: php-fpm tier: backend |
A continuación, debes declarar el puerto para acceder a este servicio php-fpm bajo spec. Puedes añadir cualquier puerto de tu elección, pero usaremos el puerto 9000 en este tutorial:
|
1 2 3 4 |
... ports: - protocol: TCP port: 9000 |
Una vez completados los pasos anteriores, tu archivo php_fpm_service.yaml se verá así:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
apiVersion: v1 kind: Service metadata: name: php labels: tier: backend spec: selector: app: php tier: backend ports: - protocol: TCP port: 9000 |
Presiona Ctrl + O para guardar el archivo, luego presiona Ctrl + X para salir de nano.
Aplicar el comando kubectl para crear el servicio PHP
Una vez creada la definición del objeto para tu servicio, ejecuta el comando kubectl apply con el argumento -f especificando tu archivo php_fpm_service.yaml:
|
1 |
kubectl apply -f php_fpm_service.yaml |
La salida del comando anterior debería ser:
|
1 |
service/php creado |
Ejecuta el siguiente comando para verificar que tu servicio php-fpm se está ejecutando:
|
1 |
$ kubectl get svc |
Podrás ver el servicio php-fpm activo y en ejecución:
|
1 2 3 |
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10m php ClusterIP 10.100.59.238 <none> 9000/TCP 5m |
Creación del servicio Nginx
Dado que tu servicio PHP-FPM ya está listo, es hora de que también crees tu servicio Nginx. Crea y abre un nuevo archivo YAML para este servicio, llamado nginx_service.yaml en el editor:
|
1 |
$ nano nginx_service.yaml |
Nombra este servicio como nginx ya que se dirigirá a los pods de Nginx. Este servicio también pertenece al backend, por lo que debes añadirle una etiqueta tier: backend:
|
1 2 3 4 5 6 |
apiVersion: v1 kind: Service metadata: name: nginx labels: tier: backend |
Al igual que hicimos en el servicio php-fpm, añade las etiquetas de selector app: nginx y tier: backend para dirigirte a los pods. Añade el puerto HTTP predeterminado 80 para acceder a este servicio:
|
1 2 3 4 5 6 7 8 |
... spec: selector: app: nginx tier: backend ports: - protocol: TCP port: 80 |
Se puede acceder públicamente al servicio Nginx en Internet desde la dirección IP pública. Puedes añadir la IP de tu nodo de trabajo como your_public_ip. Añade las siguientes líneas bajo spec.externalIPs:
|
1 2 3 4 5 |
... spec: externalIPs: - your_public_ip |
Tu archivo nginx_service.yaml debería verse como el siguiente una vez que completes todos los pasos anteriores:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
apiVersion: v1 kind: Service metadata: name: nginx labels: tier: backend spec: selector: app: nginx tier: backend ports: - protocol: TCP port: 80 externalIPs: - your_public_ip |
Guarda y cierra el archivo después de añadir todos los parámetros requeridos anteriormente.
Aplicar el comando kubectl para crear el servicio Nginx
|
1 |
kubectl apply -f nginx_service.yaml |
|
1 |
service/nginx creado |
|
1 |
$ kubectl get svc |
|
1 2 3 4 |
NOMBRE TIPO CLUSTER-IP EXTERNA-IP PUERTO(S) EDAD kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13m nginx ClusterIP 10.102.160.47 su_ip_publica 80/TCP 50s php ClusterIP 10.100.59.238 <none> 9000/TCP 8m |
|
1 |
$ kubectl delete svc/nombre_servicio |
Paso 2: Crear almacenamiento local y volumen persistente
Kubernetes proporciona varios complementos de almacenamiento que le ayudan a crear espacio de almacenamiento para su entorno. Este paso le guiará sobre cómo crear una StorageClass local y cómo se puede utilizar esta clase de almacenamiento para crear un volumen persistente.
Crear un almacenamiento local
Cree un archivo, por ejemplo, storageClass.yaml, en su editor:
|
1 |
$nano storageClass.yaml |
Añada kind como "storageClass" y apiVersion como "storage.k8s.io/v1" de la siguiente manera:
|
1 2 |
kind: StorageClass apiVersion: storage.k8s.io/v1 |
Nombre esta StorageClass como "my-local-storage" y añada provisioner y volumeBindingMode de la siguiente manera:
|
1 2 3 4 5 |
… metadata: name: my-local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: Immediate |
Guarde y salga del archivo y su archivo final storageClass.yaml debería verse así:
|
1 2 3 4 5 6 |
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: my-local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer |
Ahora, cree la StorageClass ejecutando el comando kubectl create, como se muestra a continuación:
|
1 |
$ kubectl create -f storageClass.yaml |
Después de ejecutar el comando anterior, debería obtener la siguiente salida:
|
1 |
storageclass.storage.k8s.io/my-local-storage creado |
Crear un volumen persistente local
Después de crear el almacenamiento local, puede crear su volumen persistente local. Un volumen persistente, también conocido como PV, es el almacenamiento de bloques de tamaño especificado que es independiente del ciclo de vida de un pod. Un volumen persistente local no es más que un disco local o un directorio que está disponible en un nodo del clúster de Kubernetes. Este volumen persistente local permite a sus usuarios acceder al almacenamiento local mediante una reclamación de volumen persistente local de una manera muy sencilla pero portátil. Puede crear este volumen persistente local utilizando esta clase de almacenamiento que acabamos de crear. Abra un archivo, por ejemplo, persistentVolume.yaml, en su editor:
|
1 |
$ nano persistentVolume.yaml |
Asigne un nombre a este volumen persistente, por ejemplo, "my-local-pv":
|
1 2 3 4 |
apiVersion: v1 kind: PersistentVolume metadata: name: my-local-pv |
Puede añadir capacidad de almacenamiento según su uso al crear un volumen persistente local. En este tutorial, utilizaremos 5 Gi para el almacenamiento:
|
1 2 3 4 |
… spec: capacity: storage: 5Gi |
Añada accessModes, persistentVolumeReclaimPolicy y proporcione el mismo storageClassName que se utilizó en storageClass.yaml:
|
1 2 3 4 5 |
… accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: my-local-storage |
Agregue el local.path para su volumen persistente (Persistent Volume) como se muestra a continuación:
|
1 2 3 |
… local: path: /mnt/disk/vol |
Después de agregar todos los campos requeridos, su archivo persistentVolume.yaml debería verse así:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
apiVersion: v1 kind: PersistentVolume metadata: name: my-local-pv spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: my-local-storage local: path: /mnt/disk/vol nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - worker |
Preparación del volumen local
Ahora, necesitamos preparar un volumen local en el nodo “worker” tal como lo hemos agregado en el archivo persistentVolume.yaml . Ejecute los siguientes comandos en el nodo que ha configurado en persistentVolume. En este caso, es el nodo “worker”:
|
1 2 3 |
$ DIRNAME="vol" $ mkdir -p /mnt/disk/$DIRNAME $ chmod 777 /mnt/disk/$DIRNAME |
Ejecute el siguiente comando en el nodo maestro donde su archivo persistentVolume.yaml está presente:
|
1 |
kubectl create -f persistentVolume.yaml |
Debería obtener la siguiente salida:
|
1 |
persistentvolume/my-local-pv created |
Dado que ha creado con éxito su almacenamiento local y su volumen persistente (Persistent Volume), ahora puede proceder a crear una reclamación de volumen persistente (Persistent Volume Claim) para contener el código de su aplicación y los archivos de configuración.
Paso 3: Crear el volumen persistente
El código de su aplicación debe mantenerse seguro mientras administra o actualiza sus pods. Para ello, utilizará el volumen persistente (Persistent Volume) creado en el paso anterior, al cual se accede mediante una reclamación de volumen persistente (Persistent Volume Claim) o PVC. Esta PVC monta el PV en la ruta requerida.
Abra un archivo, por ejemplo, code_volume.yaml, en su editor:
|
1 |
$ nano code_volume.yaml |
Nombre su PVC como code agregando los siguientes parámetros y valores a su archivo:
|
1 2 3 4 |
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: code |
La sección spec de una PVC tiene los siguientes elementos:
- accessModes: Existen varios valores posibles para este campo, los cuales se detallan a continuación:
- ReadWriteOnce – Monta el volumen para un solo nodo con permisos tanto de lectura como de escritura.
- ReadOnlyMany – Monta el volumen para muchos nodos con permiso de solo lectura.
- ReadWriteMany – Monta el volumen para muchos nodos con permisos tanto de lectura como de escritura.
- resources: Define el espacio de almacenamiento requerido.
Dado que el almacenamiento local está montado en un solo nodo, deberá establecer el accessMode en ReadWriteOnce. En este tutorial agregará solo una pequeña parte de código de aplicación, por lo que 1 GB de almacenamiento será suficiente aquí. Sin embargo, si desea almacenar una mayor cantidad de datos o código, puede modificar el parámetro de almacenamiento de acuerdo con sus requisitos. Tenga en cuenta que una vez creado el volumen, podrá aumentar el tamaño del almacenamiento. Sin embargo, no se admite la reducción del mismo:
|
1 2 3 4 5 6 7 |
... spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi |
Ahora, declare la clase de almacenamiento que el clúster de Kubernetes utilizará para asignar a los volúmenes. Utilice la clase de almacenamiento my-local-storage, creada en el paso anterior, aquí para su storageClassName:
|
1 2 |
... storageClassName: my-local-storage |
Después de completar los pasos anteriores, su archivo code_volume.yaml debería verse así:
|
1 2 3 4 5 6 7 8 9 10 11 |
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: code spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: my-local-storage |
Ahora guarde y salga del archivo.
Creación de PVC
Cree el PVC de código ejecutando el comando kubectl apply:
|
1 |
$ kubectl apply -f code_volume.yaml |
Debería obtener la siguiente salida que indica que el objeto se creó correctamente y está listo para poder montar su PVC de 1 GB como volumen:
|
1 |
persistentvolumeclaim/code created |
Puede ejecutar el siguiente comando para verificar el volumen persistente (PV) disponible:
|
1 |
$ kubectl get pv |
La salida del comando anterior debería ser la siguiente:
|
1 2 |
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-ca4df10f-ab8c-11e8-b89d-12331aa95b13 1Gi RWO Delete Bound default/code do-block-storage 2m |
Todos los campos anteriores, excepto Reclaim Policy y Status, son una descripción general de su archivo de configuración. Reclaim Policy define qué sucede con el PV una vez que se elimina el PVC que accede a él. El valor Delete elimina el PV tanto del clúster de Kubernetes como de la infraestructura de almacenamiento. Puede consultar la documentación de PV de Kubernetes para tener una comprensión clara de Reclaim Policy y Status.
Ahora puede crear sus pods utilizando un Deployment, ya que ha creado correctamente su volumen persistente utilizando el almacenamiento local.
Paso 4: Crear un Deployment para su aplicación PHP-FPM
Este paso le ayudará a crear su pod PHP-FPM utilizando Deployment. Deployment utiliza ReplicaSets para proporcionar una forma estable de crear, actualizar y administrar sus pods. Un Deployment revierte automáticamente sus pods a una imagen anterior.
La clave spec.selector en el Deployment enumera todas las etiquetas de los pods que administra. También utiliza la clave template para crear los pods que se requieren.
En este paso, también introduciremos la aplicación de Init Containers. Los Init Containers ejecutan algunos comandos antes de los contenedores regulares que se especifican bajo la plantilla del pod’s. Aquí, el Init Container utilizará GitHub Gist (https://gist.github.com/) para obtener un index.php de muestra. El contenido del archivo de muestra es:
|
1 2 |
<?php echo phpinfo(); |
Creación del Deployment de PHP
Abra un nuevo archivo llamado php_deployment.yaml en su editor para crear su Deployment:
|
1 |
$ nano php_deployment.yaml |
Ahora, nombre al objeto Deployment PHP, ya que este Deployment administrará sus pods PHP-FPM. Agregue la etiqueta tier: backend porque el pod pertenecerá a la capa backend:
|
1 2 3 4 5 6 |
apiVersion: apps/v1 kind: Deployment metadata: name: php labels: tier: backend |
Usando el parámetro replica, especifique el número de copias de este pod que se deben crear. El número de réplicas puede variar según sus requisitos y los recursos disponibles. En este tutorial, creará solo una réplica de su pod:
|
1 2 3 4 |
... spec: replicas: 1 |
Agregue app: php y tier:backend etiquetas bajo la clave selector que denota que este Deployment administrará los pods que coincidan con estas dos etiquetas:
|
1 2 3 4 5 |
... selector: matchLabels: app: php tier: backend |
Ahora, la definición de objeto de su pod necesita una plantilla bajo la especificación de su Deployment. Esta plantilla define la especificación que se necesita para crear su pod. Para empezar, agregue las etiquetas que se especificaron para el selector de servicio php y el matchLabels del Deployment. Luego agregue app:php y tier:backend bajo template.metadata.labels:
|
1 2 3 4 5 6 7 |
... template: metadata: labels: app: php tier: backend |
First, you need to specify all the volumes that your containers will access. Name this volume code as you had created a PVC named code to hold your application code:
|
1 2 3 4 5 6 |
... spec: volumes: - name: code persistentVolumeClaim: claimName: code |
A continuación, especifique el nombre del contenedor junto con la imagen que desea ejecutar dentro de su pod. Hay varias imágenes disponibles en la tienda de Docker (https://hub.docker.com/explore/), pero en este tutorial, utilizaremos la imagen php:7-fpm:
|
1 2 3 4 |
... containers: - name: php image: php:7-fpm |
Ahora, monte los volúmenes a los que el contenedor requiere acceso. Dado que este contenedor ejecutará su código php, necesitará acceso al volumen code creado en el paso anterior. En este paso, también aprenderá cómo copiar el código de su aplicación utilizando un Init Container.
To download the code, this tutorial will guide you on how to use a single Init Container with busybox. Busybox is a small container with wget utility that you will use to achieve this.
First, add your initContainer under spec.template.spec y especifique la imagen de busybox:
|
1 2 3 4 |
... initContainers: - name: install image: busybox |
Luego, para descargar el código en el volumen code, su Init Container necesitará acceso a él. Monte el volumen code en la ruta /code bajo spec.template.spec.initContainers:
|
1 2 3 4 |
... volumeMounts: - name: code mountPath: /code |
Cada Init Container requiere ejecutar un comando. Este Init Container utilizará wget para descargar el code desde Github en el directorio /code. Puede pasar una opción -O para darle un nombre a este archivo descargado, y puede nombrar este archivo index.php.
Además, agregue las siguientes líneas debajo de install container en spec.template.spec.initContainers:
|
1 2 3 4 5 6 |
... command: - wget - "-O" - "/code/index.php" - https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php |
Después de completar todos estos pasos, su php_deployment.yaml archivo debería verse así:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
apiVersion: apps/v1 kind: Deployment metadata: name: php labels: tier: backend spec: replicas: 1 selector: matchLabels: app: php tier: backend template: metadata: labels: app: php tier: backend spec: volumes: - name: code persistentVolumeClaim: claimName: code containers: - name: php image: php:7-fpm volumeMounts: - name: code mountPath: /code initContainers: - name: install image: busybox volumeMounts: - name: code mountPath: /code command: - wget - "-O" - "/code/index.php" - https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php |
Ahora puede guardar el archivo y salir. A continuación, cree su Deployment de PHP-FPM utilizando el kubectl apply comando:
|
1 |
$ kubectl apply -f php_deployment.yaml |
La creación exitosa del Deployment debería darle la siguiente salida:
|
1 |
deployment.apps/php creado |
Este Deployment comienza descargando las imágenes especificadas, luego solicitará el PersistentVolume de su PersistentVolumeClaim, y luego ejecutará sus initContainers. Una vez hecho este paso, los contenedores se ejecutarán y montarán los volúmenes en el punto de montaje especificado. Después de completar todos estos pasos, su pod estará en funcionamiento.
Puede ejecutar el siguiente comando para ver su Deployment:
|
1 |
$ kubectl get deployments |
Después de ejecutar el comando anterior, debería obtener la siguiente salida:
|
1 2 |
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE php 1 1 1 0 19s |
Puede comprender el estado actual del Deployment con la ayuda de esta salida. Un Deployment es un controlador que mantiene el estado deseado. El DESIRED campo especifica que tiene 1 réplica del pod llamado php. El CURRENT campo indica cuántas réplicas del DESIRED estado se están ejecutando actualmente. Para un pod saludable, esto debería coincidir con el DESIRED estado. Puede obtener más información sobre los campos restantes en la documentación.
Después de eso, para verificar el estado de su pod en ejecución, puede ejecutar el siguiente comando:
|
1 |
$ kubectl get pods |
La salida de este comando puede variar según el tiempo transcurrido desde que creó su Deployment. Si se ejecuta poco después de crear el Deployment, la salida será similar a:
|
1 2 |
NAME READY STATUS RESTARTS AGE php-5d8f6bbf7f-56df2 0/1 Init:0/1 0 9s |
Explicación:
Estas columnas representan la información de la siguiente manera:
- Ready: El número de réplicas actuales/deseadas que ejecutan este pod.
- Estado: El estado de su pod. Init:0/1 indica que los Init Containers se están ejecutando y 0 de 1 Init Containers han terminado de ejecutarse.
- Reinicios: Esto indica la cantidad de veces que este proceso se ha reiniciado para iniciar el pod.
Su pod puede tardar unos minutos en cambiar el estado a podInitializing dependiendo de la complejidad de sus scripts de inicio:
|
1 2 |
NOMBRE LISTO ESTADO REINICIOS EDAD php-5d8f6bbf7f-56df2 0/1 podInitializing 0 39s |
Esto indica que los Init Containers se han ejecutado correctamente y ahora los contenedores se están inicializando:
|
1 2 |
NOMBRE LISTO ESTADO REINICIOS EDAD php-5d8f6bbf7f-56df2 1/1 Running 0 4m10s |
Como puede ver ahora, su pod está activo y en funcionamiento. Sin embargo, en caso de que su pod no se inicie, puede ejecutar los siguientes comandos para fines de depuración:
1. Para ver información detallada del pod:
|
1 |
$ kubectl describe pods pod-nombre |
2. Para ver los logs del pod:
|
1 |
$ kubectl logs pod-nombre |
3. Para ver los logs de un contenedor específico en el pod:
|
1 |
$ kubectl logs pod-nombre contenedor-nombre |
¡Felicitaciones! Ha montado con éxito el código de la aplicación y el servicio PHP-FPM está listo para manejar conexiones. De manera similar, puede crear su Deployment de Nginx.
Paso 5: Crear su Deployment de Nginx
Este paso le guiará sobre cómo configurar Nginx utilizando un ConfigMap. Un ConfigMap guarda todas las configuraciones requeridas en un formato de clave-valor que se utilizará en otras definiciones de objetos de Kubernetes. Con este enfoque, tendrá la flexibilidad de reutilizar o cambiar la imagen de Nginx por una versión diferente, cuando sea necesario. Puede actualizar el ConfigMap y este replicará automáticamente esos cambios en cualquier pod que esté montando este ConfigMap.
Para empezar, abra un archivo nginx_configmap.yaml en su editor:
|
1 |
$ nano nginx_configMap.yaml |
Ahora, nombre este ConfigMap como nginx-config y agréguelo al microservicio tier: backend:
|
1 2 3 4 5 6 |
apiVersion: v1 kind: ConfigMap metadata: name: nginx-config labels: tier: backend |
Además, puede agregar los datos al ConfigMap. Agregue una clave llamada config y agregue todo el contenido del archivo de configuración de Nginx como valor.
Dado que es posible que Kubernetes dirija las solicitudes a los hosts respectivos para un servicio, puede ingresar el nombre de su servicio PHP-FPM bajo el parámetro fastcgi_pass en lugar de su dirección IP. Agregue las siguientes líneas de código a su archivo nginx_configMap.yaml:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
... data: config : | server { index index.php index.html; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root /code; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } } |
Once completed, your nginx_configMap.yaml file will look like this:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
apiVersion: v1 kind: ConfigMap metadata: name: nginx-config labels: tier: backend data: config : | server { index index.php index.html; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root /code; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } } |
Ahora puede guardar y salir del editor. Ahora ejecute el kubectl apply comando para crear el ConfigMap:
|
1 |
$ kubectl apply -f nginx_configMap.yaml |
Después de eso, debería ver la siguiente salida en su pantalla:
|
1 |
configmap/nginx-config created |
Ha creado con éxito su Configmap de Nginx. Ahora puede crear su Deployment de Nginx.
Creación del Deployment de Nginx
Para empezar, puede crear un nuevo archivo llamado nginx_deployment.yaml en el editor:
|
1 |
$ nano nginx_deployment.yaml |
Nombre a este Deployment nginx y añada la etiqueta tier: backend a este:
|
1 2 3 4 5 6 7 |
apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: tier: backend |
Después de eso, especifique el número de réplicas añadiendo el campo replica en la especificación (spec) del Deployment y añada las etiquetas app: nginx y tier: backend a este:
|
1 2 3 4 5 6 7 |
... spec: replicas: 1 selector: matchLabels: app: nginx tier: backend |
De manera similar, añada la plantilla del pod. Asegúrese de añadir las mismas etiquetas que había añadido en el selector.matchLabels del Deployment. Puede añadir lo siguiente:
|
1 2 3 4 5 6 |
... template: metadata: labels: app: nginx tier: backend |
Dé a Nginx acceso al PVC de código que se creó anteriormente añadiendo los siguientes parámetros bajo spec.template.spec.volumes:
|
1 2 3 4 5 6 |
... spec: volumes: - name: code persistentVolumeClaim: claimName: code |
|
1 2 3 4 5 6 7 |
... - name: config configMap: name: nginx-config items: - key: config path: site.conf |
Advertencia: El contenido de la clave reemplazará el mountPath del volumen si no se especifica un archivo. En otras palabras, perderá todo el contenido de la carpeta de destino si no se especifica explícitamente una ruta.
Ahora, especifique el nombre, la imagen y el puerto que desea usar en su pod. Aquí, usaremos la imagen nginx:1.7.9 y el puerto 80. Añádalos bajo spec.template.spec sección:
|
1 2 3 4 5 6 |
... containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 |
Además, monta el volumen de código en /code ya que tanto Nginx como PHP-FPM necesitarán acceder al archivo en la misma ruta:
|
1 2 3 4 |
... volumeMounts: - name: code mountPath: /code |
La nginx-1.7.9 carga automáticamente cualquier archivo de configuración bajo la carpeta /etc/nginx/conf.d. Ahora, si montamos el volumen de configuración en este directorio, creará /etc/nginx/conf.d/site.conf. Agrega lo siguiente bajo la sección volumeMount sección:
|
1 2 3 |
... - name: config mountPath: /etc/nginx/conf.d |
Después de completar todos los pasos anteriores, tu archivo nginx_deployment.yaml debería verse así:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: tier: backend spec: replicas: 1 selector: matchLabels: app: nginx tier: backend template: metadata: labels: app: nginx tier: backend spec: volumes: - name: code persistentVolumeClaim: claimName: code - name: config configMap: name: nginx-config items: - key: config path: site.conf containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 volumeMounts: - name: code mountPath: /code - name: config mountPath: /etc/nginx/conf.d |
Ahora puedes guardar y salir del archivo y crear el Deployment de Nginx ejecutando el siguiente comando:
|
1 |
$ kubectl apply -f nginx_deployment.yaml |
Tras la ejecución exitosa del comando, deberías ver la siguiente salida:
|
1 |
deployment.apps/nginx created |
Puedes listar todos tus Deployments ejecutando los siguientes comandos:
|
1 |
$ kubectl get deployments |
Ahora deberías ver tanto el Deployment de Nginx como el de PHP-FPM:
Además, puede ejecutar el siguiente comando para listar los pods que están gestionados por ambos Deployments listados anteriormente:
|
1 |
$ kubectl get pods |
Verá que ambos pods están activos y en funcionamiento como se muestra a continuación:
Dado que todos sus objetos de Kubernetes están activos en este momento, ahora puede acceder al servicio Nginx en su navegador.
Ejecute el siguiente comando para listar los servicios:
|
1 |
$ kubectl get services -o wide |
Tome nota de la IP externa de su servicio Nginx:
Ahora, utilizando esta IP externa del servicio Nginx, puede visitar su servidor escribiendo http://your_public_ip en su navegador. Debería poder ver la salida de php_info() que confirma que sus servicios de Kubernetes están activos y en funcionamiento.
Conclusión
En este tutorial, para gestionar sus servicios PHP-FPM y Nginx de forma independiente, ha contenedorizado los dos servicios. Al hacerlo, no solo mejorará la escalabilidad de su proyecto, sino que también utilizará sus recursos de manera eficiente. También ha aprendido cómo crear almacenamiento local y un volumen persistente (Persistent Volume) para almacenar el código de su aplicación en un volumen y poder actualizar fácilmente sus servicios en el futuro. Al hacerlo, ha mejorado la usabilidad y el mantenimiento de su código.
Además, eche un vistazo a nuestros otros tutoriales centrados en Docker y Kubernetes que puede encontrar en nuestro blog:
- Conociendo Kubernetes
- Cómo crear un clúster de Kubernetes usando Kubeadm en Ubuntu 18.04
- Limpieza de recursos de Docker: imágenes, contenedores y volúmenes
- Despliegue de Laravel, Nginx y MySQL con Docker Compose
- Cómo instalar & operar Docker en Ubuntu en la nube pública
¡Feliz computación!


Comentarios
Aún no hay comentarios. Sea el primero.