Tutoriales

Cree pods de Kubernetes con Podman play kube

Cada vez que los desarrolladores de Podman hablan sobre su futuro, siempre mencionan un tema: es más fácil usar Podman para probar cargas de trabajo e implementarlas en Kubernetes.La forma principal para que los usuarios salten entre Podman y Kubernetes es usar Podman’s generate kube y play kube subcomando Como el nombre sugiere, generate kube Cree una descripción YAML de un pod o contenedor Podman para ejecutar en Kubernetes. de lo contrario, play kube Los subcomandos le permiten ejecutar pods de Podman basados ​​en archivos YAML de Kubernetes.

Recientemente, Podman recibió una serie de mejoras para mejorar esta experiencia al agregar las siguientes características:

  • construir imagen play kube
  • quitar las vainas play kube
  • Compatibilidad con contenedores de inicio de estilo Kubernetes

Crea una imagen con Play Kube

Usuario podman play kube Díganos que quieren construir la imagen como parte del proceso del juego. Inicialmente dudamos en implementar la idea porque Kubernetes no tenía un concepto similar.más play kube se usa, más se obtiene en comparación con Docker compose. Ese fue el punto de inflexión. Nuestros usuarios tienen razón.

nuevo podman play kube La función busca un directorio con el mismo nombre que la imagen utilizada en el archivo YAML. Si el directorio existe y existe un Containerfile o Dockerfile en el directorio, Podman crea la imagen del contenedor.

Por ejemplo, un archivo YAML de muestra con Apache y PHP podría verse así:

# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-4.0.0-dev
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2021-09-20T17:40:19Z"
  labels:
	app: php
  name: php
spec:
  containers:
  - args:
	- apache2-foreground
	command:
	- docker-php-entrypoint
	env:
	- name: PATH
  	value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
	- name: TERM
  	value: xterm
	- name: container
  	...
	- name: PHP_EXTRA_BUILD_DEPS
  	value: apache2-dev
	- name: APACHE_ENVVARS
  	value: /etc/apache2/envvars
	image: php-7.2-apache-mysqli:latest
	name: apache
	ports:
	- containerPort: 80
  	hostPort: 8080
  	protocol: TCP
	resources: {}
	securityContext:
  	allowPrivilegeEscalation: true
  	capabilities:
    	drop:
    	- CAP_MKNOD
    	- CAP_NET_RAW
    	- CAP_AUDIT_WRITE
  	privileged: false
  	readOnlyRootFilesystem: false
  	seLinuxOptions: {}
	tty: true
	workingDir: /var/www/html
  dnsConfig: {}
  restartPolicy: Never
status: {}

Tenga en cuenta que en el archivo YAML, la imagen del contenedor se llama php-7.2-apache-mysqli:latestPodman construye la imagen si hay un Containerfile en ese directorio y la imagen no está en el almacén de imágenes.

Ahora mira un ejemplo que quieras usar docker.io/library/php:7.2-apache Pero la extensión PHP para mysqli no está instalada ni habilitada. Crear un Containerfile dentro php-7.2-apache-mysqli contenido. Para dar un poco de perspectiva, aquí está el diseño del directorio:

├── mariadb-conf
│   ├── Containerfile
│   └── my.cnf
├── php-7.2-apache-mysqli
│   ├── Containerfile
│   └── index.php
└── php.yaml

Los contenidos del Containerfile son:

$ cat php-7.2-apache-mysqli/Containerfile  
FROM docker.io/library/php:7.2-apache
RUN docker-php-ext-install mysqli
COPY index.php /var/www/html/index.php

Ahora, ejecuta play kube Comando, haciendo referencia al archivo YAML:

$ podman play kube php.yaml  
-->  /home/baude/myproject/php-7.2-apache-mysqli
STEP 1/3: FROM docker.io/library/php:7.2-apache
STEP 2/3: RUN docker-php-ext-install mysqli
Configuring for:
PHP Api Version:     	20170718
Zend Module Api No:  	20170718
Zend Extension Api No:   320170718
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for a sed that does not truncate output... /bin/sed
checking for cc... cc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...  
checking whether we are cross compiling... no
checking for suffix of object files... o
…
Build complete.
Don't forget to run 'make test'.
 
Installing shared extensions: 	/usr/local/lib/php/extensions/no-debug-non-zts-20170718/
Installing header files:      	/usr/local/include/php/
find . -name \*.gcno -o -name \*.gcda | xargs rm -f
find . -name \*.lo -o -name \*.o | xargs rm -f
find . -name \*.la -o -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
find . -name .libs -a -type d|xargs rm -rf
rm -f libphp.la   	modules/* libs/*
STEP 3/3: COPY index.php /var/www/html/index.php
COMMIT php-7.2-apache-mysqli:latest
--> 096882adf84
Successfully tagged localhost/php-7.2-apache-mysqli:latest
096882adf845274f8c6546cf52a77c7fc78b3fa20c659cfc2b73753972bd5f90
Pod:
d8774760bc3a0bdb1b405c57880f3872b0a71f3434b8d4ab6d8d18c8e6e44ffa
Container:
25162b2da0e2b9078c69404f6d6e1250f6ee4fc032b47564f9bbb971d838cf29

Durante el proceso de construcción se puede ver mysqli Instala, para probarlo, puedes verificar mysql El módulo está instalado. El archivo de índice para este contenedor muestra qué módulos están habilitados:

$ curl http://localhost:8080
Array
(
	[0] => Core
	[1] => date
	[2] => libxml
	...
	[30] => mysqlnd
	[31] => apache2handler
	[32] => mysqli
	[33] => sodium
)

al ejecutar la compilación play kube, el directorio con el nombre de la imagen será el directorio de contexto para la compilación. También agrega un argumento de línea de comando, --build, fuerza una reconstrucción de todas las imágenes utilizadas en el archivo YAML si existen los archivos de directorio y contenedor. Debido a que Kubernetes no crea imágenes, debe insertar la imagen recién creada en el registro del contenedor antes de usar el archivo YAML con Kubernetes.

Eliminar pods con Play Kube

Esta podman play kube Los comandos pueden crear y ejecutar varios pods, que contienen varios contenedores. administrar pods play kube Crear y ejecutar siempre ha sido un proceso manual usando el comando pod de Podman. y, play kube se está convirtiendo rápidamente en una alternativa docker compose, muy orientada al servicio. Por conveniencia y compatibilidad, tiene sentido proporcionar una forma de desmantelar el contenido creado por los archivos de entrada YAML.

[ Learn more about How to use Podman inside of Kubernetes. ]

A partir de Podman v3.4, podman play kube El comando tiene un nuevo --down bandera.Imitar con este nuevo logo docker compose «abajo» porque es más un desmontaje.cuando das --down marca, todos los pods (y sus contenedores) se detienen y posteriormente se eliminan. Si el volumen está en uso, no se eliminará.

Vuelva a visitar el ejemplo de contenedor de PHP anterior, una vez play kube Después de ejecutar el comando, se puede observar que un pod en ejecución tiene dos contenedores, incluido el contenedor de infraestructura del pod:

$ podman pod ps
POD ID    	NAME    	STATUS  	CREATED   	INFRA ID  	# OF CONTAINERS
cc97c8c8a07d  php     	Running 	20 hours ago  bd22e1434d3a  2
$ podman ps -a
CONTAINER ID  IMAGE                               	COMMAND           	CREATED   	STATUS       	PORTS             	NAMES
bd22e1434d3a  k8s.gcr.io/pause:3.5                                      	22 hours ago  Up 22 hours ago  0.0.0.0:8080->80/tcp  cc97c8c8a07d-infra
b97893b79bb9  localhost/php-7.2-apache-mysqli:latest  apache2-foregroun...  22 hours ago  Up 22 hours ago  0.0.0.0:8080->80/tcp  php-greatnapier

Supongamos que desea detener este pod.Puedes añadir --down bandera:

$ podman play kube --down php.yaml  
Pods stopped:
cc97c8c8a07db0f26114022a71ee59771134244a8b465147a513b28f9b7d171b
Pods removed:
cc97c8c8a07db0f26114022a71ee59771134244a8b465147a513b28f9b7d171b
$ podman ps -a
CONTAINER ID  IMAGE   	COMMAND 	CREATED 	STATUS  	PORTS   	NAMES
$ podman pod ps
POD ID      NAME        STATUS      CREATED     INFRA ID    # OF CONTAINERS

La cápsula se detuvo y luego se retiró.Confirme que el contenedor del pod también se eliminó podman ps -a o podman pod ps.

Inicializar soporte de contenedor

Como se mencionó, Podman agrega soporte para contenedores init, que están inspirados y basados ​​en Kubernetes inicializa el contenedorLa idea básica detrás de los contenedores .init es que estos contenedores especiales se ejecuten antes que cualquier otro contenedor normal. en una vainaEl contenedor .Init se considera bloqueante porque no hay otros contenedores de pod ejecutándose hasta que el contenedor init sale. Un pod puede tener varios contenedores de inicio, pero se ejecutarán consecutivamente en el orden en que los agregue al pod porque se están bloqueando.

Una diferencia única entre los contenedores de inicio de Podman y los contenedores de inicio de Kubernetes es que Podman proporciona dos contenedores de inicio: always y onceComo su nombre indica, un always El contenedor init se ejecuta cada vez que se inicia un pod.Una once El contenedor init se ejecuta cuando se inicia el Pod y se elimina cuando el contenedor sale. Esto se debe a que los pods de Podman se pueden reiniciar, a diferencia de los pods de Kubernetes, que simplemente se reemplazan.

Los contenedores de inicio pueden iniciar convenientemente servicios, inicializar bases de datos (en volúmenes) o bloquear ciertas condiciones que se cumplen antes de que se inicien otros contenedores en el pod.Cuando inicie el contenedor con podman play kube Y su capacidad para construir imágenes realmente puede ver la madurez de los contenedores.También puede generar YAML para el contenedor de inicio si podman play kube Ejecutar en el pod que los contiene.

Ejemplo: Apache, MariaDB y PHP

La pila LAMP (Linux, Apache, MySQL y PHP) ha sido durante mucho tiempo un brillante ejemplo de Linux. El siguiente ejemplo implementará una pila LAMP en un pod Podman. Utilizará el contenedor init y el volumen para preparar el contenedor correspondiente y su contenido. Para los volúmenes de base de datos, un contenedor de inicio único prepara la configuración básica y los archivos de la base de datos y luego precarga la base de datos con datos. El contenedor de inicialización de volumen web siempre se ejecuta antes que los contenedores de Apache y PHP y completa el contenido del servidor web con el contenido más reciente del repositorio de Git.

(Brent Calvo, CC BY-SA 4.0)

Primero, realizaré la configuración manualmente, luego seguiré play kube Ejemplo de construcción de una imagen sobre la marcha. A continuación, clone mi proyecto de Git:

$ git clone http://github.com/baude/my-lamp-project

Una vez que se complete la clonación, tendrá la siguiente estructura de directorios:

├── lamp.yaml
├── mariadb-conf
│   ├── Containerfile
│   └── my.cnf
├── mydbstuff
├── mywebstuff
├── php-7.2-apache-mysqli
│   └── Containerfile
├── php-7.2-apache-mysqli-ext
│   ├── Containerfile
│   └── index.php
└── php.yaml

A continuación, debe crear algunas imágenes manualmente. Recuerda que esta versión demuestra el uso manual del contenedor init en Podman:

$ cd mariadb-conf
$ podman build -t mariadb-conf .
STEP 1/2: FROM docker.io/library/mariadb
Trying to pull docker.io/library/mariadb:latest...
Getting image source signatures
Copying blob 7275e59ecb3d done   
...  
Copying config 6b01262bc7 done   
Writing manifest to image destination
Storing signatures
STEP 2/2: COPY my.cnf /etc/mysql/my.cnf
COMMIT mariadb-conf
--> c62d6a4978a
Successfully tagged localhost/mariadb-conf:latest
c62d6a4978a42b649e3468a12d210197dabae29b5daed2d1f0ead778f70a5fc3
$ cd ../php-7.2-apache-mysqli-ext/
$ podman build -t php-7.2-apache-mysqli-ext .
STEP 1/3: FROM docker.io/library/php:7.2-apache
Trying to pull docker.io/library/php:7.2-apache...
Getting image source signatures
Copying blob c2199db96575 done   
... 
Copying config c61d277263 done   
Writing manifest to image destination
Storing signatures
STEP 2/3: RUN docker-php-ext-install mysqli
Configuring for:
PHP Api Version:     	20170718
Zend Module Api No:  	20170718
Zend Extension Api No:   320170718
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for a sed that does not truncate output... /bin/sed
...
 
Build complete.
Don't forget to run 'make test'.
 
Installing shared extensions: 	/usr/local/lib/php/extensions/no-debug-non-zts-20170718/
Installing header files:      	/usr/local/include/php/
find . -name \*.gcno -o -name \*.gcda | xargs rm -f
find . -name \*.lo -o -name \*.o | xargs rm -f
find . -name \*.la -o -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
find . -name .libs -a -type d|xargs rm -rf
rm -f libphp.la   	modules/* libs/*
--> ec9a8979871
STEP 3/3: COPY index.php /var/www/html/index.php
COMMIT php-7.2-apache-mysqli-ext
--> d17ae4015b7
Successfully tagged localhost/php-7.2-apache-mysqli-ext:latest
d17ae4015b7c0af918e9bb5e0d4818e11b394ea3f3f7481d0a558eaa1cfb443

Ahora que tiene la imagen base construida, puede usar el contenedor para crear su pod. El orden en que cree los contenedores no importa a menos que uno o más contenedores de inicio dependan de otro contenedor. En este caso, asegúrese de que el orden de creación sea el correcto.El primer contenedor creado también creará lamp pod y proporcionar mapeo de puertos:

$ podman create -t --pod new:lamp -p 8080:80 --init-ctr=once -v ./mydbstuff:/var/lib/mysql:Z -e MYSQL_ROOT_PASSWORD=mypass mariadb-conf sh -c "mysql_install_db -u root && (mysqld -u root &) && apt-get update && apt-get install -y curl && curl --output - -L  https://github.com/baude/mysql-example/blob/main/world.sql.gz?raw=true  | gunzip -cd | mysql -u root --password='${MYSQL_ROOT_PASSWORD}'"
C14d30bcc6eed259236916c230c0faf64123b9855160c3895c87a77cb49df653

Sucede que el primer contenedor es un contenedor de inicio, que está marcado para ejecutarse una vez. Configura volúmenes de base de datos, incluida la precarga de datos. El siguiente contenedor es un volumen de base de datos normal que se ejecuta dentro de un pod:

$ podman create --pod lamp -t -v ./mydbstuff:/var/lib/mysql:Z mariadb-conf
Aa7a013f0bb1b748df1a0a1f1e691824cd9e6334f65129312514b513a86e8a51

Al igual que el contenedor de inicio, el contenedor de la base de datos también tiene un montaje de enlace mydbstuff El contenedor init lo llena de contenido. El siguiente contenedor también es un contenedor de inicio, pero se ejecuta cada vez que se inicia el pod. En cada inicio, este contenedor clona un sitio web simple para cualquier cambio.El contenido se almacena en mywebstuff volumen:

$ podman create -t --pod lamp --init-ctr=always -v ./mywebstuff:/var/www/html:Z php-7.2-apache-mysqli:latest sh -c "git clone http://github.com/baude/php-example /var/www/html || cd /var/www/html && git pull origin"

El último contenedor son los contenedores de Apache y MySQL.Al igual que su contenedor de inicio, une montajes mywebstuff Sirviendo contenido desde un clon de Git:

$ podman create -t --pod lamp  -v ./mywebstuff:/var/www/html:Z php-7.2-apache-mysqli:latest
Ea5821fdd4cde1d4de197ff3269fb5f89875fd2f78aac4b638e2661acbc7695f

El pod está completamente creado y ahora se puede iniciar:

$ podman pod start lamp
2ba762fc1edcbef4a8c607a598d9d0b3219fc49e765ba5fb795516bc66e73eac
$ podman pod ps
POD ID    	NAME    	STATUS  	CREATED     	INFRA ID  	# OF CONTAINERS
2ba762fc1edc  lamp    	Running 	43 seconds ago  a513f190e1a2  4
$ podman ps -a
CONTAINER ID  IMAGE                               	COMMAND           	CREATED     	STATUS                 	PORTS             	NAMES
a513f190e1a2  k8s.gcr.io/pause:3.5                                      	52 seconds ago  Up 29 seconds ago      	0.0.0.0:8080->80/tcp  2ba762fc1edc-infra
aa7a013f0bb1  localhost/mariadb-conf:latest       	mysqld            	45 seconds ago  Up 17 seconds ago      	0.0.0.0:8080->80/tcp  bold_aryabhata
acd05fc2e9af  localhost/php-7.2-apache-mysqli:latest  sh -c git clone h...  37 seconds ago  Exited (0) 18 seconds ago  0.0.0.0:8080->80/tcp  angry_northcutt
ea5821fdd4cd  localhost/php-7.2-apache-mysqli:latest  apache2-foregroun...  33 seconds ago  Up 17 seconds ago      	0.0.0.0:8080->80/tcp  ecstatic_yalow

El módulo ahora se está ejecutando.

[ Examine 10 considerations for Kubernetes deployments. ]

Tenga en cuenta que el contenedor de inicio de la base de datos no existe porque se ejecuta una sola vez.porque otro contenedor init está configurado para always, todavía existe, pero parece haber salido. Usando su navegador, ahora debería poder ver una consulta simple del sitio web que devuelve información sobre dos ciudades de Minnesota:

$ curl http://localhost:8080
Returned 2 rows.
 
3837 Minneapolis USA Minnesota 382618
3851 Saint Paul USA Minnesota 287151

Tenga en cuenta la vista de árbol del directorio del proyecto LAMP.Todo el contenido de la base de datos está en mydbstuff. También por mywebstuffa excepción del contenido a servir:

$ tree
├── lamp.yaml
├── mariadb-conf
│   ├── Containerfile
│   └── my.cnf
├── mydbstuff
│   ├── aria_log.00000001
│   ├── aria_log_control
│   ├── ddl_recovery-backup.log
│   ├── ddl_recovery.log
│   ├── ib_buffer_pool
│   ├── ibdata1
│   ├── ib_logfile0
│   ├── ibtmp1
│   ├── multi-master.info
│   ├── mysql [error opening dir]
│   ├── performance_schema [error opening dir]
│   ├── sys [error opening dir]
│   ├── test [error opening dir]
│   └── world [error opening dir]
├── mywebstuff
│   ├── index.php
│   └── LICENSE
├── php-7.2-apache-mysqli
│   └── Containerfile
├── php-7.2-apache-mysqli-ext
│   ├── Containerfile
│   └── index.php
└── php.yaml

Reuniéndolo todo: jugar con kube, contenedores de inicio y crear imágenes

Puedes usar un solo play kube para que aparezca una pila LAMP similar.Quité todos los pods e imágenes existentes de este ejemplo para poder demostrar play kubemás poder.

Comience con el contexto del proyecto Git que clonó anteriormente (my-lamp-project). Usando Podman, verifique que no haya imágenes o contenedores en el almacenamiento local:

$ podman images
REPOSITORY  TAG     	IMAGE ID	CREATED 	SIZE
$ podman ps -a
CONTAINER ID  IMAGE   	COMMAND 	CREATED 	STATUS  	PORTS   	NAMES

Ahora reproduzca el archivo YAML en el clon de Git.Si intenta utilizar los archivos YAML proporcionados por el repositorio de Git, deberá cambiar manualmente la ruta de los montajes de enlace, ya que tienen el prefijo /home/baudeAl principio del proceso, Podman crea dos imágenes:

$ podman play kube lamp.yaml  
STEP 1/2: FROM docker.io/library/mariadb
STEP 2/2: COPY my.cnf /etc/mysql/my.cnf
COMMIT localhost/mariadb-conf:latest
--> e4e4e63a5e4
Successfully tagged localhost/mariadb-conf:latest
e4e4e63a5e4fcd3eff0c5c0901d2dbd3bacee99001a60c06046829944592ea0e
STEP 1/2: FROM docker.io/library/php:7.2-apache
STEP 2/2: RUN docker-php-ext-install mysqli && apt-get update && apt-get install -y git
Configuring for:
PHP Api Version:     	20170718
Zend Module Api No:  	20170718
Zend Extension Api No:   320170718
checking for grep that handles long lines and -e... /bin/grep
...
Installing shared extensions: 	/usr/local/lib/php/extensions/no-debug-non-zts-20170718/
Installing header files:      	/usr/local/include/php/
find . -name \*.gcno -o -name \*.gcda | xargs rm -f
find . -name \*.lo -o -name \*.o | xargs rm -f
find . -name \*.la -o -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
find . -name .libs -a -type d|xargs rm -rf
rm -f libphp.la   	modules/* libs/*
Get:1 http://security.debian.org/debian-security buster/updates InRelease [65.4 kB]
Get:2 http://deb.debian.org/debian buster InRelease [122 kB]
Get:3 http://deb.debian.org/debian buster-updates InRelease [51.9 kB]
Get:4 http://security.debian.org/debian-security buster/updates/main amd64 Packages [305 kB]
Get:5 http://deb.debian.org/debian buster/main amd64 Packages [7907 kB]
Get:6 http://deb.debian.org/debian buster-updates/main amd64 Packages [15.2 kB]
Fetched 8466 kB in 2s (4933 kB/s)
Reading package lists...
Reading package lists...
Building dependency tree...
Reading state information...
...
Setting up git (1:2.20.1-2+deb10u3) ...
Setting up xauth (1:1.0.10-1) ...
Processing triggers for libc-bin (2.28-10) ...
Processing triggers for mime-support (3.62) ...
COMMIT localhost/php-7.2-apache-mysqli:latest
--> f0454e4fbfe
Successfully tagged localhost/php-7.2-apache-mysqli:latest
f0454e4fbfe3e59da53255553e019e23380e9006c247a2c218dd4499cb69caf7
Pod:
75aa5664f1e8c2e9b819b8377337dc245911cfbf15e8dc49fb9ee002c8329704
Containers:
c439bffa796f0a7743ad6bcf43e4c88cf485bd7494f5352b237fa9e048dc10c2
2fadb344560a904cb1b0dc2a92fd2cbcfda3c944180c941ffaf4c89793849968

despues de terminar, play kube Muestre la identificación del módulo. Si todo funciona correctamente, debería poder dirigir el cliente web a su puerto asignado HTTP, que a su vez interactúa con la base de datos y devuelve dos resultados a la consulta predeterminada:

$ curl http://localhost:8080
Returned 2 rows.
 
3837 Minneapolis USA Minnesota 382618
3851 Saint Paul USA Minnesota 287151

Ahora, si desea eliminar todos los pods asociados con su archivo YAML, simplemente puede pasar --down marcar como play kube:

$ podman pod ps
POD ID    	NAME    	STATUS  	CREATED    	INFRA ID  	# OF CONTAINERS
75aa5664f1e8  lamp    	Running 	4 minutes ago  ae59b18e6dea  5
$ podman play kube --down lamp.yaml  
Pods stopped:
75aa5664f1e8c2e9b819b8377337dc245911cfbf15e8dc49fb9ee002c8329704
Pods removed:
75aa5664f1e8c2e9b819b8377337dc245911cfbf15e8dc49fb9ee002c8329704
$ podman pod ps
POD ID    	NAME    	STATUS  	CREATED    	INFRA ID  	# OF CONTAINERS

envolver

Podman’s play kube Los comandos siguen ganando nuevas funciones. play kube y generate kube Es un área de crecimiento para el equipo de Podman ascendente y una forma rica en funciones para grabar y reproducir Pods. Nos encantaría escuchar sus pensamientos sobre futuras actualizaciones.

La introducción de la creación dinámica de imágenes y la preparación de pods utilizando contenedores init para aprovisionar y desmantelar pods brinda casos de uso únicos para Podman.

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

Botón volver arriba