Versión imprimible multipagina. Haga click aquí para imprimir.
Almacenamiento
- 1: Volumes
- 2: Snapshots de Volúmenes
- 3: Volúmenes Persistentes
- 4: Volúmenes proyectados
- 5: Clonación de volumen CSI
- 6: Volume Snapshot Classes
- 7: Volúmenes efímeros
- 8: Aprovisionamiento Dinámico de volumen
- 9: StorageClass (Clases de Almacenamiento)
- 10: Capacidad de Almacenamiento
- 11: Almacenamiento en Windows
- 12: Límites de Volumen específicos del Nodo
- 13: Supervisión del Estado del Volumen
1 - Volumes
Los archivos localizados dentro de un contenedor son efímeros, lo cual presenta problemas
para aplicaciones no triviales cuando se ejecutan en contenedores. Un problema es la
pérdida de archivos cuando el contenedor termina. Kubelet reinicia el contenedor con un estado limpio.
Un segundo problema ocurre cuando compartimos ficheros entre contenedores corriendo juntos dentro de un Pod
. La abstracción volume de Kubernetes resuelve ambos problemas.
Se sugiere familiaridad con Pods
Trasfondo
Docker tiene el concepto de volúmenes, aunque es algo más flojo y menos controlado. Un volumen de Docker es un directorio en disco o en otro contenedor. Docker provee controladores de volúmenes, pero la funcionalidad es algo limitada.
Kubernetes soporta muchos tipos de volúmenes. Un Pod puede utilizar cualquier número de tipos de volúmenes simultáneamente. Los tipos de volúmenes efímeros tienen el mismo tiempo de vida que un Pod, pero los volúmenes persistentes existen más allá del tiempo de vida de un Pod. Cuando un Pod deja de existir, Kubernetes destruye los volúmenes efímeros; sin embargo, Kubernetes no destruye los volúmenes persistentes. Para cualquier tipo de volumen en un Pod dado, los datos son preservados a lo largo de los reinicios del contenedor.
En su núcleo, un volumen es un directorio, posiblemente con algunos datos en este, que puede ser accesible para los contenedores en un Pod. Cómo ese directorio llega a crearse, el medio que lo respalda, y el contenido de este se determinan por el tipo de volumen usado.
Para usar un volumen, especifica los volúmenes a proveer al por en .spec.volumes
y declara
dónde montar estos volúmenes dentro de los contenedores en .spec.containers[*].volumeMounts
.
Un proceso en el contenedor observa una vista del sistema de archivos compuesta por la imagen Docker y volúmenes.
La imagen Docker está en la raíz de la jerarquía del sistema de archivos.
Los volúmenes se montan en las rutas especificadas dentro de la imagen. Los volúmenes no se pueden montar en otros volúmenes o tener enlaces duros a otros volúmenes. Cada contenedor en la configuración del Pod debe especificar de forma independiente donde montar cada volumen.
Tipos de volúmenes
Kubernetes soporta varios tipos de volúmenes
awsElasticBlockStore
Un volumen awsElasticBlockStore
monta un
volumen EBS de Amazon Web Services (AWS) en tu Pod. A diferencia de
emptyDir
, que se borra cuando se quita un Pod, el contenido de un volumen EBS es persistido cuando se desmonta el volumen.
Esto significa que un volumen EBS puede ser pre-poblado con datos, y que los datos puedes ser compartidos entre pods.
aws ec2 create-volume
o la API de AWS antes de poder usarlo.
Existen algunas restricciones cuando usas un volumen awsElasticBlockStore
:
- Los nodos en los que corren los pods deben ser instances AWS EC2.
- Estas instancias deben estar en la misma región y zona de disponibilidad que el volumen EBS
- EBS solo soporta una única instancia EC2 montando un volumen
Creando un volumen AWS EBS
Antes poder usar un volumen EBS en un Pod, necesitas crearlo.
aws ec2 create-volume --availability-zone=eu-west-1a --size=10 --volume-type=gp2
Asegúrate de que la zona coincide con la zona en que has creado el clúster. Revisa que el tamaño y el tipo de volumen EBS son compatibles para tu uso.
Ejemplo de configuración AWS EBS
apiVersion: v1
kind: Pod
metadata:
name: test-ebs
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-ebs
name: test-volume
volumes:
- name: test-volume
# Este volumen EBS debe existir anteriormente.
awsElasticBlockStore:
volumeID: "<volume id>"
fsType: ext4
Si el volumen EBS está particionado, puedes suministrar el campo opcional partition: "<partition number>"
para especificar cuál partición montar.
Migración CSI AWS EBS CSI
Kubernetes v1.17 [beta]
La función CSIMigration
para awsElasticBlockStore
, cuando se habilita, redirige todas las operaciones
de complemento desde el complemento existente dentro del árbol existente al controlador de Interfaz de Almacenamiento del Contenedor (CSI) de ebs.csi.aws.com
. Para utilizar esta función, el controlador AWS EBS CSI debe ser instalado en el clúster y las características beta
CSIMigration
y CSIMigrationAWS
deben estar habilitadas.
Migración CSI AWS EBS CSI completa
Kubernetes v1.17 [alpha]
Para desactivar el complemento de almacenamiento awsElasticBlockStore
de ser cargado por el administrador de controladores y el kubelet, establece el atributo CSIMigrationAWSComplete
a true
. Esta función requiere tener instalado el controlador de interfaz de almacenamiento del contenedor (CSI) en todos los nodos en obreros.
azureDisk
El tipo de volumen azureDisk
monta un Data Disk de Microsoft Azure en el Pod.
Para más detalles, mira el azureDisk
volume plugin.
Migración CSI azureDisk
Kubernetes v1.19 [beta]
La función CSIMigration
para azureDisk
, cuando se habilita, redirige todas las operaciones
de complemento desde el complemento existente dentro del árbol existente al controlador de Interfaz de Almacenamiento del Contenedor (CSI) de disk.csi.azure.com
. Para utilizar esta función, el controlador Azure Disk CSI debe ser instalado en el clúster y las características beta
CSIMigration
y CSIMigrationAzureDisk
deben estar habilitadas.
azureFile
El tipo de volumen azureFile
monta un volumen de ficheros de Microsoft Azure (SMB 2.1 and 3.0) en un Pod.
Para más detalles, mira el azureFile
volume plugin.
Migración CSI azureFile CSI
Kubernetes v1.21 [beta]
La función CSIMigration
para azureFile
, cuando se habilita, redirige todas las operaciones
de complemento desde el complemento existente dentro del árbol existente al controlador de Interfaz de Almacenamiento del Contenedor (CSI) de file.csi.azure.com
. Para utilizar esta función, el controlador Azure File CSI
Driver
debe ser instalado en el clúster y las feature gates CSIMigration
y CSIMigrationAzureFile
deben estar habilitadas.
El controlador Azure File CSI no soporta usar el mismo volumen con fsgroups diferentes, si está habilitadla migración CSI Azurefile, usar el mismo volumen con fsgorups diferentes no será compatible en absoluto.
cephfs
Un volumen cephfs
permite montar un volumen CephFS existente en tu Pod.
A diferencia de emptydir
, que es borrado cuando se remueve el Pod, el contenido de un volumen cephfs
es preservado y el volumen es meramente desmontado. Esto significa que un volumen cephfs
puede ser pre-poblado por múltiples escritores simultáneamente.
Mira el CephFS example para más detalles.
cinder
El tipo de volumen cinder
se usa para montar un volumen Cinder de OpenStack en tu Pod.
Cinder volume configuration example
apiVersion: v1
kind: Pod
metadata:
name: test-cinder
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-cinder-container
volumeMounts:
- mountPath: /test-cinder
name: test-volume
volumes:
- name: test-volume
# Este volumen de OpenStack debe existir anteriormente.
cinder:
volumeID: "<volume id>"
fsType: ext4
Migración CSI OpenStack
Kubernetes v1.21 [beta]
La función CSIMigration
para Cinder está habilitada por defecto en Kubernetes 1.21.
Esta redirige todas las operaciones de complemento desde el complemento existente dentro del árbol existente al controlador de Interfaz de Almacenamiento del Contenedor (CSI) de cinder.csi.openstack.org
.
El controlador OpenStack Cinder CSI Driver debe estar instalado en el clúster.
Puedes deshabilitar la migración CSI para tu clúster estableciendo el feature gate CSIMigrationOpenStack
a false
.
Si deshabilitas la función CSIMigrationOpenStack
, el complemento del volumen Cinder dentro del árbol toma la responsabilidad para todos los aspectos de la administración del almacenamiento del volumen Cinder.
configMap
Un ConfigMap
provee una manera de inyectar datos de configuración a los pods.
Los datos almacenados en un ConfigMap se pueden referenciar en un volumen de tipo configMap
y luego ser consumidos por aplicaciones contenerizadas corriendo en un Pod.
Cuando haces referencia a un ConfigMap, provees el nombre del ConfigMap en el volumen.
Puedes personalizar la ruta para una entrada específica en el ConfigMap.
La siguiente configuración muestra cómo montar un ConfigMap log-config
en un Pod llamado configmap-pod
:
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: test
image: busybox:1.28
command: ['sh', '-c', 'echo "The app is running!" && tail -f /dev/null']
volumeMounts:
- name: config-vol
mountPath: /etc/config
volumes:
- name: config-vol
configMap:
name: log-config
items:
- key: log_level
path: log_level
El ConfigMap log-config
es montado como un volumen, y todo el contenido almacenado en su entrada log_level
es
montado en el Pod en la ruta /etc/config/log_level
. Ten en cuenta que esta ruta se deriva del mountPath
del volumen y el path
cuya clave es log_level
.
downwardAPI
Un volumen de downwardAPI
hace que los datos API descendentes estén disponibles para las aplicaciones.
Monta un directorio y escribe los datos solicitados en archivos de texto sin formato.
subPath
no recibirá actualizaciones API descendientes.
Mira el downward API example para mayores detalles.
emptyDir
Un volumen emptyDir
es creado primero cuando se asigna un Pod a un nodo, y existe mientras el Pod está corriendo en el nodo.
Como su nombre lo indica un volumen emptydir
está inicialmente vacío. Todos los contenedores en el Pod pueden leer y escribir
los archivos en el volumen emptyDir
, aunque ese volumen se puede montar en la misma o diferente ruta en cada contenedor. Cuando un Pod es removido del nodo por alguna razón, los datos en emptydir
se borran permanentemente.
emptyDir
están seguros en caso de
colapso del contenedor.
Algunos usos para un emptyDir
son:
- Espacio temporal, como para una clasificación de combinación basada en disco
- Marcar un largo cálculo para la recuperación de fallos
- Contener archivos que un contenedor de administrador de contenido recupera mientras un contenedor de servidor web sirve los datos
Dependiendo de tu entorno, los volúmenes emptydir
se almacenan en cualquier medio que respalde el nodo tales como disco SSD, o almacenamiento de red. Sin embargo, si se establece el campo emptydir.medium
a Memory
, Kubernetes monta en su lugar un tmpfs (sistema de ficheros respaldado por la RAM). Mientras que tmpfs es muy rápido, ten en cuenta que a diferencia de los discos, tmpfs se limpia cuando el nodo reinicia y cualquier archivo que escribas cuenta con el límite de memoria del contenedor.
SizeMemoryBackedVolumes
está habilitado,
puedes especificar un tamaño para los volúmenes respaldados en memoria. Si no se especifica ningún tamaño, los volúmenes respaldados en memoria tienen un tamaño del 50% de la memoria en un host Linux.
Ejemplo de configuración de emptyDir
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
fc (canal de fibra)
Un tipo de volumen fc
permite que un volumen de almacenamiento de bloque de canal de fibra existente se monte en un Pod.
Puede especificar nombres mundiales de destino únicos o múltiples (WWN) utilizando el parámetro targetWWNs
en su configuración de volumen.
Si se especifican varios WWN, targettWWNs esperan que esos WWN sean de conexiones de múltiples rutas.
Revisa el ejemplo de canal de fibra para más detalles.
flocker (deprecado)
Flocker es un administrador open-source de volúmenes de contenedor agrupado por clúster. Flocker proporciona administración y orquestación de volúmenes de datos respaldados por una variedad de backends de almacenamiento.
Un volumen flocker
permite montar un conjunto de datos Flocker en un Pod. Si el conjunto de datos no existe en Flocker, necesita ser creado primero con el CLI de Flocker o usando la API de Flocker. Si el conjunto de datos existe será adjuntado
de nuevo por Flocker al nodo donde el Pod está programado. Esto significa que los datos pueden ser compartidos entre pods como sea necesario.
Mira el ejemplo de Flocker para más detalles.
gcePersistentDisk
Un volumen gcePersistentDisk
monta un volumen de Google Compute Engine (GCE)
de disco persistente (DP) en tu Pod.
A diferencia de emptyDir
, que se borra cuando el Pod es removido, el contenido de un disco persistente es preservado
y el volumen solamente se desmonta. Esto significa que un disco persistente puede ser pre-poblado con datos,
y que esos datos se pueden compartir entre pods.
gcloud
, la API de GCE o la UI antes de poder usarlo.
Existen algunas restricciones cuando usas gcePersistentDisk
:
- Los nodos en los que se ejecutan los pods deben ser máquinas virtuales GCE.
- Esas máquinas virtuales deben estar en el mismo proyecto GCE y zona que el disco persistente se encuentra.
Una de las características del disco persistente CGE es acceso concurrente de solo lectura al disco persistente.
Un volumen gcePersistentDisk
permite montar simultáneamente un disco de solo lectura a múltiples consumidores.
Esto significa que puedes pre-poblar un DP con tu conjunto de datos y luego servirlo en paralelo desde tantos pods como necesites. Desafortunadamente, los DPs solo se pueden montar por un único consumidor en modo lectura-escritura.
No están permitidos escritores simultáneos.
Usar un disco persistente GCE con un Pod controlado por un ReplicaSet fallará a manos que el DP sea de solo lectura o el número de réplicas sea 0 o 1.
Creando un disco persistente GCE
Antes de poder usar un disco persistente GCE en un Pod, necesitas crearlo.
gcloud compute disks create --size=500GB --zone=us-central1-a my-data-disk
Ejemplo de configuración de un disco persistente GCE
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
# Este PD GCE debe existir con anterioridad.
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
Discos regionales persistentes
La función de discos regionales persistentes permite la creación de discos persistentes que están disponibles en dos zonas dentro de la misma región. Para usar esta función, el volumen debe ser provisto como un PersistentVolumen; referenciar el volumen directamente desde un Pod no está soportado.
Aprovisionamiento manual de un PD PersistentVolume Regional
El aprovisionamiento dinámico es posible usando un StorageClass para el DP GCE. Antes de crear un PersistentVolume, debes crear el disco persistente:
gcloud compute disks create --size=500GB my-data-disk
--region us-central1
--replica-zones us-central1-a,us-central1-b
Ejemplo de configuración de un disco persistente regional
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-volume
spec:
capacity:
storage: 400Gi
accessModes:
- ReadWriteOnce
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: failure-domain.beta.kubernetes.io/zone
operator: In
values:
- us-central1-a
- us-central1-b
Migración CSI GCE
Kubernetes v1.17 [beta]
La función CSIMigration
para el DP GCE, cuando se habilita, redirige todas las operaciones
de complemento desde el complemento existente dentro del árbol existente al controlador de Interfaz de Almacenamiento del Contenedor (CSI) de pd.csi.storage.gke.io
. Para poder usar esta función, el controlador PD GCE debe ser instalado en el clúster y habilitar las funciones beta
CSIMigration
y CSIMigrationGCE
.
gitRepo (deprecado)
gitRepo
está deprecado. Para aprovisionar un contenedor con un repositorio git, monta un EmptyDir en un InitContainer que clona un repositorio usando git, luego monta el EmptyDir en el contenedor del Pod.
Un volumen gitRepo
es un ejemplo de un complemento de volumen. Este complemento monta un directorio vacío y clona un repositorio git en este directorio para que tu Pod pueda usarlo.
Aquí un ejemplo de un volumen gitrepo
:
apiVersion: v1
kind: Pod
metadata:
name: server
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /mypath
name: git-volume
volumes:
- name: git-volume
gitRepo:
repository: "git@somewhere:me/my-git-repository.git"
revision: "22f1d8406d464b0c0874075539c1f2e96c253775"
glusterfs
Un volumen glusterfs
permite montar un volumen Glusterfs en tu Pod.
A diferencia de emptyDir
, que se borra cuando se remueve un Pod, el contenido de un volumen glusterfs
es preservado
y el volumen solamente se desmonta. Esto significa que un volumen glusterfs puede ser pre-poblado con datos,
y que los datos pueden ser compartidos entre pods. GlusterFS puede ser montado por múltiples escritores simultáneamente.
Mira el ejemplo de GlusterFS para más detalles.
hostPath
Un volumen hostPath
monta un archivo o un directorio del sistema de archivos del nodo host a tu Pod.
Esto no es algo de muchos Pods necesiten, pero ofrece una trampa de escape poderosa para algunas aplicaciones.
Por ejemplo, algunos usos de un hostPath
son:
- ejecutar un contenedor que necesita acceso a los directorios internos de Docker, usa un
hostPath
de/var/lib/docker
- ejecutar un cAdvisor en un contenedor; usa un
hostPath
de/sys
- permitir a un Pod especificar si un
hostPath
dado debería existir ante de correr el Pod, si debe crearse, cómo debe existir
Además de la propiedad requerida path
, puedes especificar opcionalmente un tipo
para un volumen hostPath
.
Los valores soportados para el campo tipo
son:
Valor | Comportamiento |
---|---|
Una cadena vacía (por defecto) es para compatibilidad con versiones anteriores, lo que significa que no se harán revisiones antes de montar el volumen hostPath. | |
DirectoryOrCreate |
Si no hay nada en la ruta dada, se creará un directorio vacío como es requerido con los permisos a 0755, teniendo el mismo grupo y propiedad que el Kubelet. |
Directory |
Un directorio debe existir en la ruta dada |
FileOrCreate |
Si no hay nada en la ruta dada, se creará un archivo vacío como es requerido con los permisos a 0644, teniendo el mismo grupo y propiedad que el Kubelet. |
File |
Un archivo debe existir en la ruta dada |
Socket |
Un socket de UNIX debe existir en la ruta dada |
CharDevice |
Un dispositivo de caracteres debe existir en la ruta data |
BlockDevice |
Un dispositivo de bloques dbe existir en la ruta dada |
Ten cuidado cuando uses este tipo de volumen, porque:
- Los Pods con configuración idéntica (tales como los creados por un PodTemplate) pueden comportarse de forma distinta en nodos distintos debido a diferentes ficheros en los nodos.
- Los ficheros o directorios creados en los hosts subyacentes son modificables solo por root. Debes ejecutar tu proceso como root en un Contenedor privilegiado o modificar los permisos de archivo en el host para escribir a un volumen
hostPath
Ejemplo de configuración hostPath
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# localización del directorio en el host
path: /data
# este campo es opcional
type: Directory
FileOrCreate
no crea el directorio padre del archivo. Si el directorio padre del archivo montado no existe,
el Pod falla en iniciar. Para asegurar que este modo funciona, puedes intentar montar directorios y ficheros de forma separada,
tal como se muestra en la confugiración FileOrCreate
ejemplo de configuración hostPath FileOrCreate
apiVersion: v1
kind: Pod
metadata:
name: test-webserver
spec:
containers:
- name: test-webserver
image: registry.k8s.io/test-webserver:latest
volumeMounts:
- mountPath: /var/local/aaa
name: mydir
- mountPath: /var/local/aaa/1.txt
name: myfile
volumes:
- name: mydir
hostPath:
# Asegúrate que el directorio del archivo es creado.
path: /var/local/aaa
type: DirectoryOrCreate
- name: myfile
hostPath:
path: /var/local/aaa/1.txt
type: FileOrCreate
iscsi
Un volumen iscsi
permite que se monte un volumen ISCSI (SCSI sobre IP) existente
en tu Pod. A diferencia de emptydir
, que es removido cuando se remueve un Pod,
el contenido de un volumen iscsi
es preservado y el volumen solamente se desmonta.
Esto significa que un volumen iscsi puede ser pre-poblado con datos, y que estos datos se pueden compartir entre pods.
Una función de SCSI es que puede ser montado como de solo lectura por múltiples consumidores simultáneamente. Esto significa que puedes pre-poblar un volumen con tu conjunto de datos y servirlo en paralelo para tantos Pods como necesites. Desafortunadamente, los volúmenes ISCSI solo se pueden montar por un único consumidor en modo lectura-escritura. Escritores simultáneos no está permitido.
Mira el ejemplo iSCSI para más detalles.
local
Un volumen local
representa un dispositivo de almacenamiento local como un disco, una partición o un directorio.
Los volúmenes locales solo se pueden usar como un PersistenVolume creado estáticamente. El aprovisionamiento dinámico no está soportado.
Comparados con volúmenes hostPath
, los volúmenes local
se usan de manera duradera y portátil sin programar pods manualmente
a los nodos. El sistema está consciente de las limitaciones del nodo del volumen al mirar la afinidad del nodo en el PersistenVolumen.
Sin embargo, los volúmenes local
están sujetos a la disponibilidad del nodo subyacente y no son compatibles para todas las aplicaciones.
Si un nodo deja de estar sano, entonces el volumen local
se vuelve inaccesible al Pod.
El Pod que utiliza este volumen no se puede ejecutar.
Las aplicaciones que usan volúmenes local
deben ser capaces de tolerar esta disponibilidad reducida,
así como la pérdida potencial de datos, dependiendo de las características de durabilidad del disco subyacente.
El siguiente ejemplo muestra un PersistentVolume usando un volumen local
y nodeAffinity
:
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- example-node
Debes establecer un valor de nodeAffinity
del PersistenVolume cuando uses volúmenes local
.
El Scheduler de Kubernetes usa nodeaffinity
del PersistenVolume para programar estos Pods al nodo correcto.
El volumeMode
del PersistentVolume se puede establecer en "Block" (en lugar del valor por defecto, "Filesystem")
para exponer el volumen local como un dispositivo de bloque sin formato.
Cuando usas volúmenes locales, se recomienda crear un StorageClass con volumeBindingMode
en WaitForFirstConsumer
.
Para más detalles, mira el ejemplo de StorageClass. Retrasar el enlace con el volumen asegura que la decisión del PersistenVolumeClaim sea evaluada con otras limitaciones que el Pod pueda tener,
tales como requisitos de recursos del nodo, selectores de nodo, afinidad del Pod, y anti-afinidad del Pod.
Se puede ejecutar un aprovisionador estático externo para un manejo mejorado del ciclo de vida del volumen local. Ten en cuenta que este aprovisionador no soporta aprovisionamiento dinámico todavía. Para un ejemplo de un aprovisionador local externo, mira la guía de usuario de aprovisionador de volumen local
nfs
Un volumen nfs
permite montar un NFS (Sistema de Ficheros de Red) compartido en tu Pod.
A diferencia de emptyDir
que se borra cuando el Pod es removido, el contenido de un volumen nfs
solamente se desmonta.
Esto significa que un volumen NFS puede ser pre-poblado con datos, y que estos datos puedes ser compartidos entre pods.
NFS puede ser montado por múltiples escritores simultáneamente.
Mira el ejemplo NFS para más información.
persistentVolumeClaim
Un volumen persistenceVolumeClain
se utiliza para montar un PersistentVolume en tu Pod. PersistentVolumeClaims son una forma en que el usuario "reclama" almacenamiento duradero (como un PersistentDisk GCE o un volumen ISCSI) sin conocer los detalles del entorno de la nube en particular.
Mira la información spbre PersistentVolumes para más detalles.
portworxVolume
Un portworxVolume
es un almacenamiento de bloque elástico que corre hiperconvergido con Kubernetes.
Almacenamiento de huellas de Portworx en un servidor, niveles basados en capacidades y capacidad agregada en múltiples servidores.
Portworx se ejecuta como invitado en máquinas virtuales o en nodos Linux nativos.
Un portworxVolume
puede ser creado dinámicamente a través de Kubernetes o puede ser pre-aprovisionado y referido dentro de un Pod. Aquí un Pod de ejemplo refiriendo a un volumen Portworx pre-aprovisionado:
apiVersion: v1
kind: Pod
metadata:
name: test-portworx-volume-pod
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /mnt
name: pxvol
volumes:
- name: pxvol
# Este volumen portworx debe sxistir con anterioridad.
portworxVolume:
volumeID: "pxvol"
fsType: "<fs-type>"
pxvol
antes de usarlo en el Pod.
Para más detalles, mira los ejemplos de volumen Portworx.
projected
Un volumen projected
mapea distintas fuentes de volúmenes existentes en un mismo directorio.
Actualmente, se pueden los siguientes tipos de volúmenes:
secret
downwardAPI
configMap
serviceAccountToken
Se requiere que todas las fuentes estén en el mismo namespace que el Pod. Para más detalles mira el all-in-one volume design document.
Configuración de ejemplo con un secret, un downwardAPI, y un configMap
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: busybox
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "cpu_limit"
resourceFieldRef:
containerName: container-test
resource: limits.cpu
- configMap:
name: myconfigmap
items:
- key: config
path: my-group/my-config
Configuración de ejemplo: secrets con un modo de permisos no predeterminados
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: busybox
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- secret:
name: mysecret2
items:
- key: password
path: my-group/my-password
mode: 511
Cada volumen proyectado está listado en spec bajo sources
. Los parámetros son casi los mismos salvo dos excepciones:
- Para los secrets, el campo
secretName
ha sido cambiado aname
para ser consistente con el nombre del configMap. - El
defaultMode
solo se puede especificar en el nivel proyectado y no para cada fuente de volumen. Sin, como se muestra arriba, puedes establecer explícitamente elmode
para cada proyección individual.
Cuando la función TokenRequestProjection
está habilitada, puedes inyectar el token para el service account actual en un Pod en la ruta especificada.
Por ejemplo:
apiVersion: v1
kind: Pod
metadata:
name: sa-token-test
spec:
containers:
- name: container-test
image: busybox
volumeMounts:
- name: token-vol
mountPath: "/service-account"
readOnly: true
volumes:
- name: token-vol
projected:
sources:
- serviceAccountToken:
audience: api
expirationSeconds: 3600
path: token
El Pod de ejemplo tiene un volumen proyectado que contiene el token del serviceAccount inyectado.
Este token se puede usar por el contenedor de un Pod para acceder a la API del servidor de Kubernetes.
El audience
contiene la audiencia dirigida del token. Un recipiente del token debe identificarse a sí mismo con
un identificador especificado en la audiencia del token, de lo contrario debería rechazar el token. Este campo es opcional y por defecto tiene el valor del identificador del servidor API.
EL campo expirationSeconds
es la duración esperada de la validez del token del serviceAccount.
Su valor por defecto es 1 hora y debe ser al menos 10 minutos (600 segundos). Un administrador puede limitar
su valor máximo al especificar la opción --service-account-max-token-expiration
para el servidor API. El campo path
especifica una ruta relativa al punto de montaje del volumen proyectado.
subPath
no recibirá actualizaciones de estas fuentes de volumen.
quobyte
Un volumen quobyte
permite montar un volumen Quobyte en tu Pod.
Quobyte soporta el Container Storage Interface. CSI es el complemento recomendado para usar Quobyte dentro de Kubernetes. El proyecto Github de Quobyte tiene instrucciones para desplegar usando CSI, junto con ejemplos.
rbd
Un volumen rbd
permite montar un volumen Rados Block Device (RBD) en tu Pod.
A diferencia de emptyDir
, que se borra cuando el Pod es removido, el contenido de un volumen rbd
es preservado y el volumen se desmonta. Esto significa que un volumen RBD puede ser pre-poblado con datos, y que estos datos pueden ser compartidos entre pods.
Una función de RBD es que solo se puede montar como de solo lectura por múltiples consumidores simultáneamente. Esto significa que puedes pre-poblar un volumen con tu conjunto de datos y luego servirlo en paralelo desde tantos pods como necesites. Desafortunadamente, los volúmenes RBD solo se pueden montar por un único consumidor en modo lectura-escritura. No se permiten escritores simultáneos.
Mira el ejemplo RBD para más detalles.
scaleIO (deprecado)
ScaleIO es una plataforma de almacenamiento basada en software que usa el hardware existente para crear clústeres de almacenamiento en red de bloques compartidos escalables. El complemento de volumen scaleIO
permite a los pods desplegados acceder a volúmenes existentes ScaleIO. Para información acerca de aprovisionamiento dinámico de nuevos persistence volumen claims, mira ScaleIO persistent volumes
El siguiente ejemplo es una configuración de un Pod con ScaleIO:
apiVersion: v1
kind: Pod
metadata:
name: pod-0
spec:
containers:
- image: registry.k8s.io/test-webserver
name: pod-0
volumeMounts:
- mountPath: /test-pd
name: vol-0
volumes:
- name: vol-0
scaleIO:
gateway: https://localhost:443/api
system: scaleio
protectionDomain: sd0
storagePool: sp1
volumeName: vol-0
secretRef:
name: sio-secret
fsType: xfs
Para más detalles, mira los ejemplos de ScaleIO
secret
Un volumen seret
se utiliza para pasar información sensible, como contraseñas, a los Pods.
Puedes guardar secrets en la API de Kubernetes y montarlos como ficheros para usarlos con los pods sin acoplarlos con Kubernetes directamente. Los volúmenes secret
son respaldados por tmpfs (un sistema de ficheros respaldado por la RAM) así que nunca se escriben en un almacenamiento no volátil.
subPath
no recibirá las actualizaciones del Secret.
Para más detalles, mira Configurando Secrets.
storageOS
Un volumen storageos
permite montar un volumen existente StorageOS en tu Pod.
StorageOS corre como un contenedor dentro de tu contenedor Kubernetes, haciendo accesible el almacenamiento local o adjunto desde cualquier node dentro del cluster de Kubernetes. Los datos pueden ser replicados para protegerlos contra fallos del nodo. Este aprovisionamiento y compresión pueden mejorar el uso y reducir costes.
El contenedor StorageOs requiere Linux de 64 bits y no tiene dependencias adicionales. Una licencia gratuita para desarrolladores está disponible.
El siguiente ejemplo es una configuración de un Pod con Storage OS:
apiVersion: v1
kind: Pod
metadata:
labels:
name: redis
role: master
name: test-storageos-redis
spec:
containers:
- name: master
image: kubernetes/redis:v1
env:
- name: MASTER
value: "true"
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /redis-master-data
name: redis-data
volumes:
- name: redis-data
storageos:
# El volumen `redis-vol01` debe existir dentro de StorageOS en el namespace `default`.
volumeName: redis-vol01
fsType: ext4
Para más información sobre StorageOS, aprovisionamiento dinámico, y PersistentVolumeClaims, mira los ejemplos de StorageOS examples.
vsphereVolume
Un volumen vsphereVolume
se usa para montar un volumen VMDK vSphere en tu Pod. El contenido de un volumen es preservado cuando se desmonta. Tiene soporte para almacén de datos VMFS y VSAN.
Creando un volumen VMDK
Elige uno de los siguientes métodos para crear un VMDK.
Primero entra mediante ssh en ESX, luego usa uno de los siguientes comandos para crear un VMDK:
vmkfstools -c 2G /vmfs/volumes/DatastoreName/volumes/myDisk.vmdk
Usa el siguiente comando para crear un VMDK:
vmware-vdiskmanager -c -t 0 -s 40GB -a lsilogic myDisk.vmdk
Ejemplo de configuración vSphere VMDK
apiVersion: v1
kind: Pod
metadata:
name: test-vmdk
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-vmdk
name: test-volume
volumes:
- name: test-volume
# Este volumen VMDK ya debe existir.
vsphereVolume:
volumePath: "[DatastoreName] volumes/myDisk"
fsType: ext4
Para mayor información, mira el ejemplo de vSphere volume.
Migración CSI vSphere
Kubernetes v1.19 [beta]
CSIMigration
está habilitada, redirige todas las operaciones de complemento desde el complemento existente en el árbol al controlador CSI csi.vsphere.vmware.com
. Para
usar esta función, el controlador vSphere CSI debe estar instalado en el clúster y las feature gates CSIMigration
y CSIMigrationvSphere
deben estar habilitadas.
Esto también requiere que la versión de vSphere vCenter/ESXi sea la 7.0u1 y la versión mínima de HW version sea VM versión 15.
Los siguientes parámetros de Storageclass desde el complemento incorporado vsphereVolume
no están soportados por el controlador vSphere CSI:
diskformat
hostfailurestotolerate
forceprovisioning
cachereservation
diskstripes
objectspacereservation
iopslimit
Los volúmenes existentes creados usando estos parámetros serán migrados al controlador vSphere CSI, pero los volúmenes nuevos creados por el controlador vSphere CSI no respetarán estos parámetros
migración completa de vSphere CSI
Kubernetes v1.19 [beta]
vsphereVolume
y no cargarlo por el administrador del controlador y el kubelet, necesitas establecer eta función a true
. Debes instalar un controlador de tipo csi.vsphere.vmware.com
en todos los nodos worker.
Uso de subPath
Algunas veces es útil compartir un volumen para múltiples usos en un único Pod.
La propiedad volumeMounts[*].subPath
especifica una sub-ruta dentro del volumen referenciado en lugar de su raíz.
El siguiente ejemplo muestra cómo configurar un Pod con la pila LAMP (Linux Apache MySQL PHP) usando un único volumen compartido. Esta configuración de ejemplo usando subPath
no se recomienda para su uso en producción.
El código de la aplicación PHP y los recursos apuntan al directorio html
del volumen y la base de datos MySQL se almacena en el directorio mysql
. Por ejemplo:
The PHP application's code and assets map to the volume's html
folder and
the MySQL database is stored in the volume's mysql
folder. For example:
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site
spec:
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpasswd"
volumeMounts:
- mountPath: /var/lib/mysql
name: site-data
subPath: mysql
- name: php
image: php:7.0-apache
volumeMounts:
- mountPath: /var/www/html
name: site-data
subPath: html
volumes:
- name: site-data
persistentVolumeClaim:
claimName: my-lamp-site-data
Uso de subPath con variables de entorno expandidas
Kubernetes v1.17 [stable]
subPathExpr
para construir un nombre de directorio subPath
desde variables de entorno de la API.
Las propiedades subPath
y subPathExpr
son mutuamente exclusivas.
En este ejemplo, un Pod
usa subPathExpr
para crear un directorio pod1
dentro del volumen hostPath
var/logs/pods
.
El volumen hostPath
toma el nombre del Pod
desde la downwardAPI
.
El directorio anfitrión var/log/pods/pod1
se monta en /logs
en el contenedor.
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: container1
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
image: busybox
command:
[
"sh",
"-c",
"while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt",
]
volumeMounts:
- name: workdir1
mountPath: /logs
subPathExpr: $(POD_NAME)
restartPolicy: Never
volumes:
- name: workdir1
hostPath:
path: /var/log/pods
Recursos
El medio de almacenamiento (como un disco o un SSD) de un volumen emptyDir
se determina por el medio del sistema de archivos que contiene el directorio raíz
del kubelet (típicamente /var/lib/kubelet
).
No hay límite de cuánto espacio puede consumir un volumen emptydir
o hostPath
,
y no hay aislamiento entre contenedores o entre pods.
Para aprender más sobre requerir espacio usando una espacificación de recurso, mira cómo administrar recursos.
Complementos de volúmenes fuera del árbol
Los complementos de volumen fuera del árbol incluyen Container Storage Interface (CSI) y FlexVolume. Estos complementos permiten a los proveedores de almacenamiento crear complementos de almacenamiento personalizados sin añadir su código fuente al repositorio de Kubernetes.
Anteriormente, todos los complementos de volumen estaban "en el árbol". Los complementos "en el árbol" se construían, enlazaban, compilaban y enviaban con los binarios del núcleo de Kubernetes. Esto significaba que agregar un nuevo sistema de almacenamiento a Kubernetes (un complemento de volumen) requería verificar el código en el repositorio de código del núcleo de Kubernetes.
Tanto CSI como FlexVolume permiten que se desarrollen complementos de volúmenes independientemente del código base de Kubernetes, y se desplieguen (instalen) en los clústeres de Kubernetes como extensiones.
Para los proveedores de almacenamiento que buscan crear un complemento de volumen fuera del árbol, por favor refiéranse a Preguntas frecuentees de complementos de volumen.
csi
La interfaz de almacenamiento del contenedor (CSI) define una interfaz estándar para sistemas de orquestación del contenedor (como Kubernetes) para exponer sistemas de almacenamiento arbitrario a sus cargas de trabajo del contenedor.
Por favor, lee la propuesta de diseño CSI para más información.
Una vez que se despliega un controlador de volumen CSI compatible, los usuarios pueden usar el tipo de volumen csi
para adjuntar o montar los volúmenes expuestos por el controlador CSI.
Un volumen csi
puede ser usado en un Pod en tres maneras distintas:
- a través de una referencia a PersistentVolumeClaim
- con un volumen general efímero (característica alpha)
- con un volumen efímero CSI si el controlador permite esta (característica beta)
Los siguientes campos están disponibles para que los administradores de almacenamiento configuren el volumen persistente CSI
driver
: Un valor de cadena de caracteres que especifica el nombre del controlador de volumen a usar. Este valor debe corresponder al valor de respuesta en elGetPluginInfoResponse
por el controlador CSI tal como se define en la especificación CSI. Es usado por Kubernetes para identificar cuál controlador llamar, y por los componentes del controlador CSI para identificar cuáles objetos PV pertenecen al controlador CSI.volumenHandle
: Un valor de cadena de caracteres que identifica el volumen unívocamente. Este valor debe corresponder al valor en el campovolumen.id
delCreateVolumeResponse
por el controlador CSI como se define en la especificación CSI spec. El valor es pasado comovolume.id
en todas las llamadas al controlador de volumen CSI cuando referencias el volumen.readOnly
: Un valor booleano opcional que indica si el volumen es para ser "ControllerPublished" (adjuntado) como solo lectura. Por defecto es falso. Este valor es pasado el controlador CSI en el camporeadOnly
en elControllerPublishVolumeRequest
.fsType
: Si elVolumeMode
del PV esFilesystem
entonces este campo se puede usar para especificar el sistema de archivos que debería usarse para montar el volumen. Si el volumen no ha sido formateado y soportado, este valor se utilizará para formatear el volumen. Este valor se para al controlador CSI con el campoVolumeCapability
deControllerPublishVolumeRequest
,NodeStageVolumeRequest
, yNodePublishVolumeRequest
.volumeAttributes
: Un mapa de cadena de caracteres que especifica las propiedades estáticas de un volumen. Este mapa debe corresponder al map devuelto por el campovolume.attributes
delCreateVolumeResponse
por el controlador CSI tal como se define en la especificación CSI spec. El mapa es pasado al controlador CSI con el campovolume.context
en elControllerPublishVolumeRequest
,NodeStageVolumeRequest
, yNodePublishVolumeRequest
.controllerPublishSecretRef
: Una referencia al objeto secret que contiene información sensible para pasar al controlador CSI para completar las llamadas CSIControllerPublishVolume
yControllerUnpublishVolume
. Este campo es opcional, y puede estar vacío si no se requiere un secret. Si el Secret contiene más de un secret, se pasan todos los secrets.nodeStageSecretRef
: Una referencia al objeto secret que contiene información sensible a pasar al controlador CSI para completar la llamada CSINodeStageVolume
. Este ampo es opcional, y puede estar vacío si no se requiere un secret. Si el Secret contiene más de un secret, todos los secrets son pasados.nodePublishSecretRef
: Una referencia al objeto que contiene información sensible a pasar al controlador CSI para completar la llamada CSINodePublishVolume
. Este ampo es opcional, y puede estar vacío si no se requiere un secret. Si el Secret contiene más de un secret, todos los secrets son pasados.
Soporte de volumen CSI de fila de bloques
Kubernetes v1.18 [stable]
Los proveedores con controladores CSI externos pueden implementar soporte de volumen de bloques sin procesar en cargas de trabajo de Kubernetes.
Puedes configurar tu You can set up your PersistentVolume/PersistentVolumeClaim with raw block volume support como de costumbre, sin ningún cambio específico CSI.
Volúmenes efímeros CSI
Kubernetes v1.16 [beta]
Puedes configurar directamente volúmenes CSI dentro de la especificación del Pod. Los volúmenes especificados de esta manera son efímeros y no se persisten entre reinicios del Pod. Mira Volúmenes efímeros para más información.
Para más información de cómo desarrollador un controlador CSI, mira la documentación kubernetes-csi
Migrando a controladores CSI desde complementos en el árbol.
Kubernetes v1.17 [beta]
CSIMigration
, cuando está habilitada, dirige todas las operaciones hacia complementos existentes en el árbol a complementos CSI correspondientes (que se espera que estén instalados y configurados). Como resultado, los operadores no tienen que hacer ningún cambio de configuración a las clases de almacenamiento, PersistentVolumes o PersistentVolumeClaims (refiriéndose a complementos en el árbol) cuando haces la transición a un controlador CSI que un reemplaza complemento en el árbol.
Las operaciones y funciones que están soportadas incluye: aprovisionamiento/borrado, adjuntar/separar, montar/desmontar y redimensionar volúmenes.
In-tree plugins that support CSIMigration
and have a corresponding CSI driver implemented
are listed in Types of Volumes.
flexVolume
FlexVolume is an out-of-tree plugin interface that has existed in Kubernetes since version 1.2 (before CSI). It uses an exec-based model to interface with drivers. The FlexVolume driver binaries must be installed in a pre-defined volume plugin path on each node and in some cases the control plane nodes as well.
Pods interact with FlexVolume drivers through the flexvolume
in-tree volume plugin.
For more details, see the FlexVolume examples.
Propagación del montaje
La propagación del montaje permite compartir volúmenes montados por un contenedor para otros contenedores en el mismo Pod, o aun para otros pods en el mismo nodo.
La propagación del montaje de un volumen es controlada por el campo mountPropagation
en containers[*].volumeMounts
. Sus valores son:
-
None
- Este montaje de volumen no recibirá ningún montaje posterior que el host haya montado en este volumen o en cualquiera de sus subdirectorios. De manera similar, los montajes creados por el contenedor no serán visibles en el host. Este es el modo por defecto.Este modo es igual la propagación del montaje
private
tal como se describe en la documentación Linux kernel documentation -
HostToContainer
- Este montaje de volumen recibirá todos los montajes subsecuentes que son montados a este volumen o cualquiera de sus subdirectorios.En otras palabras, si el host monta algo dentro del montaje del volumen, el contenedor lo verá montado allí.
De manera similar, si cualquier Pod con propagación de montaje
Bidirectional
al mismo volumen monta algo allí, el contenedor con propagación de montajeHostToContainer
lo verá.Este modo es igual a la propagación de montaje
rslave
tal como se describe en la documentación del kernel de Linux -
Bidirectional
- Este montaje de volumen se comporta de la misma manera de el montajeHostToContainer
. Adicionalmente, todos los montajes de volúmenes creados por el contenedor serán propagados de vuelta al host y a todos los contenedores de todos los pods que usan el mismo volumen.Un uso típico para este modo es un Pod con un FlexVolumen o un controlador CSI o un Pod que necesita montar al en el host usando un volumen
hostPath
.Este modo es igual a la propagación de montaje
rshared
tal como se describe en la documentación del kernel de Linux documentaciónAdvertencia: La propagación por montajeBidirectional
puede ser peligrosa. Puede dañar el sistema operativo host y, por lo tanto, solo se permite en contenedores privilegiados. Se recomienda encarecidamente estar familiarizado con el comportamiento del kernel de Linux. Además, cualquier montaje de volumen creado por contenedores en pods debe destruirse (desmontado) por los contenedores en el momento de la terminación.
Configuration
Before mount propagation can work properly on some deployments (CoreOS, RedHat/Centos, Ubuntu) mount share must be configured correctly in Docker as shown below.
Edit your Docker's systemd
service file. Set MountFlags
as follows:
MountFlags=shared
Or, remove MountFlags=slave
if present. Then restart the Docker daemon:
sudo systemctl daemon-reload
sudo systemctl restart docker
Siguientes pasos
Sigue un ejemplo de desplegar WordPrss y MySQL con volúmenes persistentes.
2 - Snapshots de Volúmenes
En Kubernetes, un VolumeSnapshot representa un Snapshot de un volumen en un sistema de almacenamiento. Este documento asume que está familiarizado con volúmenes persistentes de Kubernetes.
Introducción
Al igual que los recursos de API PersistentVolume
y PersistentVolumeClaim
se utilizan para aprovisionar volúmenes para usuarios y administradores, VolumeSnapshotContent
y VolumeSnapshot
se proporcionan para crear Snapshots de volumen para usuarios y administradores.
Un VolumeSnapshotContent
es un Snapshot tomado de un volumen en el clúster que ha sido aprovisionado por un administrador. Es un recurso en el clúster al igual que un PersistentVolume es un recurso de clúster.
Un VolumeSnapshot
es una solicitud de Snapshot de un volumen por parte del usuario. Es similar a un PersistentVolumeClaim.
VolumeSnapshotClass
permite especificar diferentes atributos que pertenecen a un VolumeSnapshot
. Estos atributos pueden diferir entre Snapshots tomados del mismo volumen en el sistema de almacenamiento y, por lo tanto, no se pueden expresar mediante el mismo StorageClass
de un PersistentVolumeClaim
.
Los Snapshots de volumen brindan a los usuarios de Kubernetes una forma estandarizada de copiar el contenido de un volumen en un momento determinado, sin crear uno completamente nuevo. Esta funcionalidad permite, por ejemplo, a los administradores de bases de datos realizar copias de seguridad de las bases de datos antes de realizar una edición o eliminar modificaciones.
Cuando utilicen esta función los usuarios deben tener en cuenta lo siguiente:
- Los objetos de API
VolumeSnapshot
,VolumeSnapshotContent
, yVolumeSnapshotClass
son CRDs, y no forman parte de la API principal. - La compatibilidad con
VolumeSnapshot
solo está disponible para controladores CSI. - Como parte del proceso de implementación de
VolumeSnapshot
, el equipo de Kubernetes proporciona un controlador de Snapshot para implementar en el plano de control y un sidecar auxiliar llamado csi-snapshotter para implementar junto con el controlador CSI. El controlador de Snapshot observa los objetosVolumeSnapshot
yVolumeSnapshotContent
y es responsable de la creación y eliminación del objetoVolumeSnapshotContent
. El sidecar csi-snapshotter observa los objetosVolumeSnapshotContent
y activa las operacionesCreateSnapshot
yDeleteSnapshot
en un punto final CSI. - También hay un servidor webhook de validación que proporciona una validación más estricta en los objetos Snapshot. Esto debe ser instalado por las distribuciones de Kubernetes junto con el controlador de Snapshots y los CRDs, no los controladores CSI. Debe instalarse en todos los clústeres de Kubernetes que tengan habilitada la función de Snapshot.
- Los controladores CSI pueden haber implementado o no la funcionalidad de Snapshot de volumen. Los controladores CSI que han proporcionado soporte para Snapshot de volumen probablemente usarán csi-snapshotter. Consulte CSI Driver documentation para obtener más detalles.
- Los CRDs y las instalaciones del controlador de Snapshot son responsabilidad de la distribución de Kubernetes.
Ciclo de vida de un Snapshot de volumen y el contenido de un Snapshot de volumen.
VolumeSnapshotContents
son recursos en el clúster. VolumeSnapshots
son solicitudes de esos recursos. La interacción entre VolumeSnapshotContents
y VolumeSnapshots
sigue este ciclo de vida:
Snapshot del volumen de aprovisionamiento
Hay dos formas de aprovisionar los Snapshots: aprovisionadas previamente o aprovisionadas dinámicamente.
Pre-aprovisionado
Un administrador de clúster crea una serie de VolumeSnapshotContents
. Llevan los detalles del Snapshot del volumen real en el sistema de almacenamiento que está disponible para que lo utilicen los usuarios del clúster. Existen en la API de Kubernetes y están disponibles para su consumo.
Dinámica
En lugar de utilizar un Snapshot preexistente, puede solicitar que se tome una Snapshot dinámicamente de un PersistentVolumeClaim. El VolumeSnapshotClass especifica los parámetros específicos del proveedor de almacenamiento para usar al tomar una Snapshot.
Vinculante
El controlador de Snapshots maneja el enlace de un objeto VolumeSnapshot
con un objeto VolumeSnapshotContent
apropiado, tanto en escenarios de aprovisionamiento previo como de aprovisionamiento dinámico. El enlace es un mapeo uno a uno.
En el caso de un enlace aprovisionado previamente, el VolumeSnapshot permanecerá sin enlazar hasta que se cree el objeto VolumeSnapshotContent solicitado.
Persistent Volume Claim como Snapshot Source Protection
El propósito de esta protección es garantizar que los objetos de la API PersistentVolumeClaim en uso, no se eliminen del sistema mientras se toma un Snapshot (ya que esto puede resultar en la pérdida de datos).
Mientras se toma un Snapshot de un PersistentVolumeClaim, ese PersistentVolumeClaim está en uso. Si elimina un objeto de la API PersistentVolumeClaim en uso activo como fuente de Snapshot, el objeto PersistentVolumeClaim no se elimina de inmediato. En cambio, la eliminación del objeto PersistentVolumeClaim se pospone hasta que el Snapshot esté readyToUse o se cancele.
Borrar
La eliminación se activa al eliminar el objeto VolumeSnapshot
, y se seguirá la DeletionPolicy
. Sí DeletionPolicy
es Delete
, entonces el Snapshot de almacenamiento subyacente se eliminará junto con el objeto VolumeSnapshotContent
. Sí DeletionPolicy
es Retain
, tanto el Snapshot subyacente como el VolumeSnapshotContent
permanecen.
VolumeSnapshots
Cada VolumeSnapshot contiene una especificación y un estado.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: new-snapshot-test
spec:
volumeSnapshotClassName: csi-hostpath-snapclass
source:
persistentVolumeClaimName: pvc-test
persistentVolumeClaimName
es el nombre de la fuente de datos PersistentVolumeClaim para el Snapshot. Este campo es obligatorio para aprovisionar dinámicamente un Snapshot.
Un Snapshot de volumen puede solicitar una clase particular especificando el nombre de un VolumeSnapshotClass
utilizando el atributo volumeSnapshotClassName
. Si no se establece nada, se usa la clase predeterminada si está disponible.
Para los Snapshots aprovisionadas previamente, debe especificar un volumeSnapshotContentName
como el origen del Snapshot, como se muestra en el siguiente ejemplo. El campo de origen volumeSnapshotContentName
es obligatorio para los Snapshots aprovisionados previamente.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: test-snapshot
spec:
source:
volumeSnapshotContentName: test-content
Contenido del Snapshot de volumen
Cada VolumeSnapshotContent contiene una especificación y un estado. En el aprovisionamiento dinámico, el controlador común de Snapshots crea objetos VolumeSnapshotContent
. Aquí hay un ejemplo:
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
name: snapcontent-72d9a349-aacd-42d2-a240-d775650d2455
spec:
deletionPolicy: Delete
driver: hostpath.csi.k8s.io
source:
volumeHandle: ee0cfb94-f8d4-11e9-b2d8-0242ac110002
volumeSnapshotClassName: csi-hostpath-snapclass
volumeSnapshotRef:
name: new-snapshot-test
namespace: default
uid: 72d9a349-aacd-42d2-a240-d775650d2455
volumeHandle
es el identificador único del volumen creado en el backend de almacenamiento y devuelto por el controlador CSI durante la creación del volumen. Este campo es obligatorio para aprovisionar dinámicamente un Snapshot. Especifica el origen del volumen del Snapshot.
Para los Snapshots aprovisionados previamente, usted (como administrador del clúster) es responsable de crear el objeto VolumeSnapshotContent
de la siguiente manera.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
name: new-snapshot-content-test
spec:
deletionPolicy: Delete
driver: hostpath.csi.k8s.io
source:
snapshotHandle: 7bdd0de3-aaeb-11e8-9aae-0242ac110002
volumeSnapshotRef:
name: new-snapshot-test
namespace: default
snapshotHandle
es el identificador único del Snapshot de volumen creado en el backend de almacenamiento. Este campo es obligatorio para las Snapshots aprovisionadas previamente. Especifica el ID del Snapshot CSI en el sistema de almacenamiento que representa el VolumeSnapshotContent
.
Aprovisionamiento de Volúmenes a partir de Snapshots
Puede aprovisionar un nuevo volumen, rellenado previamente con datos de una Snapshot, mediante el campo dataSource en el objeto PersistentVolumeClaim
.
Para obtener más detalles, consulte Volume Snapshot and Restore Volume from Snapshot.
3 - Volúmenes Persistentes
Este documento describe volúmenes persistentes en Kubernetes. Se sugiere familiarizarse con volumes, StorageClasses y VolumeAttributesClasses.
Introducción
La gestión del almacenamiento es un problema distinto al de la gestión de instancias de cómputo. El subsistema PersistentVolume proporciona una API para usuarios y administradores que abstrae los detalles de cómo se proporciona el almacenamiento de cómo se consume. Para hacer esto, introducimos dos nuevos recursos de API: PersistentVolume y PersistentVolumeClaim.
Un PersistentVolume (PV) es una pieza de almacenamiento en el clúster que ha sido provisionada por un administrador o provisionada dinámicamente usando Storage Classes. Es un recurso en el clúster al igual que un nodo es un recurso del clúster. Los PVs son plugins de volumen como Volúmenes, que tienen un ciclo de vida independiente de cualquier Pod individual que use el PV. Este objeto API captura los detalles de la implementación del almacenamiento, sea NFS, iSCSI o un sistema de almacenamiento específico de un proveedor de nube.
Un PersistentVolumeClaim (PVC) es una solicitud de almacenamiento por parte de un usuario. Es similar a un Pod. Los Pods consumen recursos de nodos y los PVCs consumen recursos de PVs. Los Pods pueden solicitar niveles específicos de recursos (CPU y Memoria). Las solicitudes pueden pedir tamaños específicos y modos de acceso (por ejemplo, pueden montarse como ReadWriteOnce, ReadOnlyMany, ReadWriteMany o ReadWriteOncePod, ver Modos de Acceso).
Aunque los PersistentVolumeClaims permiten a un usuario consumir recursos de almacenamiento abstractos, es común que los usuarios necesiten PersistentVolumes con propiedades variadas, tales como rendimiento, para diferentes problemas. Los administradores del clúster necesitan poder ofrecer una variedad de PersistentVolumes que difieran en más aspectos que el tamaño y los modos de acceso, sin exponer a los usuarios a los detalles de cómo se implementan esos volúmenes. Para estas necesidades, existe el recurso StorageClass.
Vea el tutorial detallado con ejemplos prácticos.
Ciclo de vida de un volumen y una solicitud
Los PVs son recursos en el clúster. Los PVCs son solicitudes para esos recursos y también actúan como comprobantes de reclamo al recurso. La interacción entre PVs y PVCs sigue este ciclo de vida:
Aprovisionamiento
Hay dos formas en que los PVs pueden ser aprovisionados: estáticamente o dinámicamente.
Estático
Un administrador del clúster crea un número de PVs. Llevan los detalles del almacenamiento real, que está disponible para uso de los usuarios del clúster. Existen en la API de Kubernetes y están disponibles para su consumo.
Dinámico
Cuando ninguno de los PVs estáticos creados por el administrador coincide con un PersistentVolumeClaim de un usuario,
el clúster puede intentar aprovisionar dinámicamente un volumen especialmente para el PVC.
Este aprovisionamiento se basa en StorageClasses: el PVC debe solicitar una
clase de almacenamiento y
el administrador debe haber creado y configurado esa clase para que ocurra el aprovisionamiento
dinámico. Las solicitudes que piden la clase ""
efectivamente desactivan
el aprovisionamiento dinámico para sí mismas.
Para habilitar el aprovisionamiento dinámico de almacenamiento basado en clases de almacenamiento, el administrador del clúster
necesita habilitar el controlador de admisión DefaultStorageClass
admission controller
en el servidor API. Esto se puede hacer, por ejemplo, asegurándose de que DefaultStorageClass
esté
entre la lista de valores delimitados por comas y ordenados para la bandera --enable-admission-plugins
del
componente del servidor API. Para más información sobre las opciones de línea de comandos del servidor API,
consulta la documentación de kube-apiserver.
Binding
Un usuario crea, o en el caso de aprovisionamiento dinámico, ya ha creado, un PersistentVolumeClaim con una cantidad específica de almacenamiento solicitado y con ciertos modos de acceso. Un bucle de control en el plano de control observa los nuevos PVCs, encuentra un PV coincidente (si es posible) y los une. Si un PV fue aprovisionado dinámicamente para un nuevo PVC, el bucle siempre unirá ese PV al PVC. De lo contrario, el usuario siempre obtendrá al menos lo que pidió, pero el volumen puede ser superior a lo solicitado. Una vez unidos, los enlaces PersistentVolumeClaim son exclusivos, independientemente de cómo se hayan unido. Una unión PVC a PV es un mapeo uno a uno, utilizando un ClaimRef que es una unión bidireccional entre el PersistentVolume y el PersistentVolumeClaim.
Las solicitudes permanecerán sin unir indefinidamente si no existe un volumen coincidente. Las solicitudes se unirán a medida que los volúmenes coincidentes estén disponibles. Por ejemplo, un clúster aprovisionado con muchos PVs de 50Gi no coincidirá con un PVC que solicite 100Gi. El PVC puede unirse cuando se agregue un PV de 100Gi al clúster.
Uso
Los Pods usan las solicitudes como volúmenes. El clúster inspecciona la solicitud para encontrar el volumen unido y monta ese volumen para un Pod. Para los volúmenes que admiten múltiples modos de acceso, el usuario especifica qué modo desea cuando utiliza su solicitud como volumen en un Pod.
Una vez que un usuario tiene una solicitud y esa solicitud está unida, el PV unido pertenece al
usuario mientras lo necesiten. Los usuarios programan Pods y acceden a sus PVs reclamados incluyendo una sección de persistentVolumeClaim
en el bloque volumes
de un Pod.
Consulta Solicitudes como Volúmenes para más detalles sobre esto.
Protección de Objeto de Almacenamiento en Uso
El propósito de la función de Protección de Objeto de Almacenamiento en Uso es asegurar que las PersistentVolumeClaims (PVCs) en uso activo por un Pod y los PersistentVolumes (PVs) que están unidos a PVCs no sean eliminados del sistema, ya que esto podría resultar en pérdida de datos.
Si un usuario elimina un PVC en uso activo por un Pod, el PVC no se elimina inmediatamente. La eliminación del PVC se pospone hasta que el PVC ya no esté en uso activo por ningún Pod. Además, si un administrador elimina un PV que está unido a un PVC, el PV no se elimina inmediatamente. La eliminación del PV se pospone hasta que el PV ya no esté unido a ningún PVC.
Puedes ver que un PVC está protegido cuando el estado del PVC es Terminating
y la lista de Finalizers
incluye kubernetes.io/pvc-protection
:
kubectl describe pvc hostpath
Name: hostpath
Namespace: default
StorageClass: example-hostpath
Status: Terminating
Volume:
Labels: <none>
Annotations: volume.beta.kubernetes.io/storage-class=example-hostpath
volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers: [kubernetes.io/pvc-protection]
...
Puedes ver que un PV está protegido cuando el estado del PV es Terminating
y la lista de Finalizers
incluye también kubernetes.io/pv-protection
:
kubectl describe pv task-pv-volume
Name: task-pv-volume
Labels: type=local
Annotations: <none>
Finalizers: [kubernetes.io/pv-protection]
StorageClass: standard
Status: Terminating
Claim:
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1Gi
Message:
Source:
Type: HostPath (bare host directory volume)
Path: /tmp/data
HostPathType:
Events: <none>
Reclamación
Cuando un usuario ha concluido con el uso de su volumen, puede eliminar los objetos PVC de la API que permite la recuperación del recurso. La política de reclamación para un PersistentVolume le dice al clúster que hacer con el volumen después de que ha sido liberado de su solicitud. Actualmente, los volúmenes pueden ser Retenidos, Reciclados o Eliminados.
Retener
La política de reclamación Retain
permite la recuperación manual del recurso.
Cuando se elimina el PersistentVolumeClaim, el PersistentVolume todavía existe
y el volumen se considera "liberado". Pero aún no está disponible para
otra solicitud porque los datos del reclamante anterior permanecen en el volumen.
Un administrador puede reclamar manualmente el volumen con los siguientes pasos.
- Eliminar el PersistentVolume. El recurso de almacenamiento asociado en la infraestructura externa todavía existe después de que se haya eliminado el PV.
- Limpiar manualmente los datos en el recurso de almacenamiento asociado en consecuencia.
- Eliminar manualmente el recurso de almacenamiento asociado.
Si deseas reutilizar el mismo recurso de almacenamiento, crea un nuevo PersistentVolume con la misma definición de recurso de almacenamiento.
Eliminar
Para los plugins de volumen que soportan la política de reclamación Delete
, la eliminación remueve
tanto el objeto PersistentVolume de Kubernetes, como el recurso de almacenamiento asociado
en la infraestructura externa. Los volúmenes que fueron aprovisionados dinámicamente
heredan la política de reclamación de su StorageClass, que
por defecto es Delete
. El administrador debe configurar la StorageClass
de acuerdo con las expectativas de los usuarios; de lo contrario, el PV debe ser editado o
modificado después de que se haya creado. Consulta
Cambiar la Política de Reclamación de un PersistentVolume.
Reciclar
Recycle
está obsoleta. En su lugar, el enfoque recomendado
es utilizar el aprovisionamiento dinámico.
Si es compatible con el plugin de volumen subyacente, la política de reclamación Recycle
realiza
un borrado básico (rm -rf /elvolumen/*
) en el volumen y lo hace disponible nuevamente para una nueva solicitud.
Sin embargo, un administrador puede configurar una plantilla de Pod reciclador personalizada usando
los argumentos de línea de comandos del administrador del controlador de Kubernetes como se describe en la
referencia.
La plantilla de Pod reciclador personalizada debe contener una especificación de volumes
, como
se muestra en el ejemplo a continuación:
apiVersion: v1
kind: Pod
metadata:
name: pv-recycler
namespace: default
spec:
restartPolicy: Never
volumes:
- name: vol
hostPath:
path: /any/path/it/will/be/replaced
containers:
- name: pv-recycler
image: "registry.k8s.io/busybox"
command:
[
"/bin/sh",
"-c",
'test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z "$(ls -A /scrub)" || exit 1',
]
volumeMounts:
- name: vol
mountPath: /scrub
Sin embargo, la ruta particular especificada en la plantilla de Pod reciclador personalizado en la parte de volumes
se reemplaza con la ruta particular del volumen que está siendo reciclado.
Finalizador de protección de eliminación de PersistentVolume
Kubernetes v1.23 [alpha]
Los finalizadores pueden agregarse en un PersistentVolume para asegurar que los PersistentVolumes
con política de reclamación Delete
solo se eliminen después de que se eliminen los almacenamientos subyacentes.
Los finalizadores recién introducidos kubernetes.io/pv-controller
y
external-provisioner.volume.kubernetes.io/finalizer
solo se agregan a los volúmenes provisionados dinámicamente.
El finalizador kubernetes.io/pv-controller
se agrega a los volúmenes de plugins integrados.
El siguiente es un ejemplo.
kubectl describe pv pvc-74a498d6-3929-47e8-8c02-078c1ece4d78
Name: pvc-74a498d6-3929-47e8-8c02-078c1ece4d78
Labels: <none>
Annotations: kubernetes.io/createdby: vsphere-volume-dynamic-provisioner
pv.kubernetes.io/bound-by-controller: yes
pv.kubernetes.io/provisioned-by: kubernetes.io/vsphere-volume
Finalizers: [kubernetes.io/pv-protection kubernetes.io/pv-controller]
StorageClass: vcp-sc
Status: Bound
Claim: default/vcp-pvc-1
Reclaim Policy: Delete
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 1Gi
Node Affinity: <none>
Message:
Source:
Type: vSphereVolume (a Persistent Disk resource in vSphere)
VolumePath: [vsanDatastore] d49c4a62-166f-ce12-c464-020077ba5d46/kubernetes-dynamic-pvc-74a498d6-3929-47e8-8c02-078c1ece4d78.vmdk
FSType: ext4
StoragePolicyName: vSAN Default Storage Policy
Events: <none>
El finalizador external-provisioner.volume.kubernetes.io/finalizer
se agrega para los volúmenes CSI.
El siguiente es un ejemplo:
Name: pvc-2f0bab97-85a8-4552-8044-eb8be45cf48d
Labels: <none>
Annotations: pv.kubernetes.io/provisioned-by: csi.vsphere.vmware.com
Finalizers: [kubernetes.io/pv-protection external-provisioner.volume.kubernetes.io/finalizer]
StorageClass: fast
Status: Bound
Claim: demo-app/nginx-logs
Reclaim Policy: Delete
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 200Mi
Node Affinity: <none>
Message:
Source:
Type: CSI (a Container Storage Interface (CSI) volume source)
Driver: csi.vsphere.vmware.com
FSType: ext4
VolumeHandle: 44830fa8-79b4-406b-8b58-621ba25353fd
ReadOnly: false
VolumeAttributes: storage.kubernetes.io/csiProvisionerIdentity=1648442357185-8081-csi.vsphere.vmware.com
type=vSphere CNS Block Volume
Events: <none>
Cuando la bandera de funcionalidad CSIMigration{provider}
está habilitada para un plugin de volumen integrado específico,
el finalizador kubernetes.io/pv-controller
se reemplaza por el finalizador
external-provisioner.volume.kubernetes.io/finalizer
.
Reservando un PersistentVolume
El plano de control puede unir PersistentVolumeClaims a PersistentVolumes correspondientes en el clúster. Sin embargo, si quieres que un PVC se una a un PV específico, necesitas pre-unirlos.
Al especificar un PersistentVolume en un PersistentVolumeClaim, declaras una unión
entre ese PV y PVC específicos. Si el PersistentVolume existe y no ha reservado
PersistentVolumeClaims a través de su campo claimRef
, entonces el PersistentVolume y
el PersistentVolumeClaim se unirán.
La unión ocurre independientemente de algunos criterios de coincidencia de volumen, incluida la afinidad de nodo. El plano de control aún verifica que la clase de almacenamiento, los modos de acceso y el tamaño de almacenamiento solicitado sean válidos.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foo-pvc
namespace: foo
spec:
storageClassName: "" # La cadena vacía debe establecerse explícitamente; de lo contrario, se establecerá la StorageClass predeterminada
volumeName: foo-pv
...
Este método no garantiza ningún privilegio de unión al PersistentVolume.
Si otros PersistentVolumeClaims pudieran usar el PV que especificas, primero
necesitas reservar ese volumen de almacenamiento. Especifica el PersistentVolumeClaim relevante
en el campo claimRef
del PV para que otros PVCs no puedan unirse a él.
apiVersion: v1
kind: PersistentVolume
metadata:
name: foo-pv
spec:
storageClassName: ""
claimRef:
name: foo-pvc
namespace: foo
...
Esto es útil si deseas consumir PersistentVolumes que tienen su claimPolicy
establecido
en Retain
, incluyendo casos donde estás reutilizando un PV existente.
Expandiendo Persistent Volume Claims
Kubernetes v1.24 [stable]
El soporte para expandir PersistentVolumeClaims (PVCs) está habilitado por defecto. Puedes expandir los siguientes tipos de volúmenes:
- azureFile (obsoleto)
- csi
- flexVolume (obsoleto)
- rbd (obsoleto)
- portworxVolume (obsoleto)
Solo puedes expandir un PVC si el campo allowVolumeExpansion
de su clase de almacenamiento está establecido en verdadero.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: example-vol-default
provisioner: vendor-name.example/magicstorage
parameters:
resturl: "http://192.168.10.100:8080"
restuser: ""
secretNamespace: ""
secretName: ""
allowVolumeExpansion: true
Para solicitar un volumen más grande para un PVC, edita el objeto PVC y especifica un tamaño mayor. Esto desencadena la expansión del volumen que respalda el PersistentVolume subyacente. Nunca se crea un nuevo PersistentVolume para satisfacer la solicitud. En cambio, se redimensiona un volumen existente.
.spec
de un PersistentVolumeClaim coincidente para hacer que el tamaño del PersistentVolumeClaim coincida con el PersistentVolume,
entonces no ocurre ningún redimensionamiento de almacenamiento.
El plano de control de Kubernetes verá que el estado deseado de ambos recursos coincide,
concluirá que el tamaño del volumen de respaldo se ha aumentado manualmente
y que no es necesario ningún redimensionamiento.
Expansión de volúmenes CSI
Kubernetes v1.24 [stable]
El soporte para la expansión de volúmenes CSI está habilitado por defecto, pero también requiere que un controlador CSI específico soporte la expansión de volumen. Consulta la documentación del controlador CSI específico para obtener más información.
Redimensionando un volumen que contiene un sistema de archivos
Solo puedes redimensionar volúmenes que contienen un sistema de archivos si el sistema de archivos es XFS, Ext3 o Ext4.
Cuando un volumen contiene un sistema de archivos, el sistema de archivos solo se redimensiona cuando un nuevo Pod está utilizando
el PersistentVolumeClaim en modo ReadWrite
. La expansión del sistema de archivos se realiza cuando un Pod se está iniciando
o cuando un Pod está en ejecución y el sistema de archivos subyacente soporta la expansión en línea.
Los FlexVolumes (obsoletos desde Kubernetes v1.23) permiten redimensionar si el controlador está configurado con la
capacidad RequiresFSResize
en true
. El FlexVolume se puede redimensionar al reiniciar el Pod.
Redimensionando un PersistentVolumeClaim en uso
Kubernetes v1.24 [stable]
En este caso, no necesitas eliminar y recrear un Pod o despliegue que esté utilizando un PVC existente. Cualquier PVC en uso se vuelve automáticamente disponible para su Pod tan pronto como su sistema de archivos haya sido expandido. Esta característica no tiene efecto en PVCs que no están en uso por un Pod o despliegue. Debes crear un Pod que utilice el PVC antes de que la expansión pueda completarse.
Similar a otros tipos de volúmenes - los volúmenes FlexVolume también pueden ser expandidos cuando están en uso por un Pod.
Recuperación de fallos al expandir volúmenes
Si un usuario especifica un nuevo tamaño que es demasiado grande para ser satisfecho por el sistema de almacenamiento subyacente, la expansión del PVC será reintentada continuamente hasta que el usuario o el administrador del clúster tomen alguna acción. Esto puede ser indeseable y por lo tanto Kubernetes proporciona los siguientes métodos de recuperación de tales fallos.
Si la expansión del almacenamiento subyacente falla, el administrador del clúster puede recuperar manualmente el estado del Persistent Volume Claim (PVC) y cancelar las solicitudes de redimensionamiento. De lo contrario, las solicitudes de redimensionamiento son reintentadas continuamente por el controlador sin intervención del administrador.
- Marca el PersistentVolume (PV) que está vinculado al PersistentVolumeClaim (PVC) con una política de reclamación
Retain
. - Elimina el PVC. Dado que el PV tiene una política de reclamación
Retain
, no perderemos ningún dato al recrear el PVC. - Elimina la entrada
claimRef
de las especificaciones del PV, para que un nuevo PVC pueda vincularse a él. Esto debería hacer que el PV estéAvailable
(Disponible). - Vuelve a crear el PVC con un tamaño menor que el PV y establece el campo
volumeName
del PVC con el nombre del PV. Esto debería vincular el nuevo PVC al PV existente. - No olvides restaurar la política de reclamación del PV.
Kubernetes v1.23 [alpha]
RecoverVolumeExpansionFailure
debe estar habilitada para que esta característica funcione. Consulta la documentación de interruptores de funcionalidades para más información.
Si el interruptor de funcionalidad de RecoverVolumeExpansionFailure
está habilitado en tu clúster, y la expansión ha fallado para un PVC, puedes intentar nuevamente la expansión con un tamaño menor al valor previamente solicitado. Para solicitar un nuevo intento de expansión con un tamaño propuesto menor, edita .spec.resources
para ese PVC y elige un valor que sea menor al valor que intentaste previamente.
Esto es útil si la expansión a un valor más alto no tuvo éxito debido a una restricción de capacidad.
Si eso ha ocurrido, o sospechas que podría haber ocurrido, puedes intentar nuevamente la expansión especificando un tamaño que esté dentro de los límites de capacidad del proveedor de almacenamiento subyacente. Puedes monitorear el estado de la operación de redimensionamiento observando .status.allocatedResourceStatuses
y los eventos en el PVC.
Ten en cuenta que, aunque puedes especificar una cantidad menor de almacenamiento que la solicitada anteriormente, el nuevo valor aún debe ser mayor que .status.capacity
.
Kubernetes no admite reducir un PVC a menos de su tamaño actual.
Tipos de Persistent Volumes
Los tipos de PersistentVolume se implementan como plugins. Actualmente, Kubernetes admite los siguientes plugins:
csi
- Interfaz de Almacenamiento de Contenedores (CSI)fc
- Almacenamiento de Canal de Fibra (FC)hostPath
- Volumen HostPath (solo para pruebas en un único nodo; NO FUNCIONARÁ en un clúster multinodo; considera usar el volumenlocal
en su lugar)iscsi
- iSCSI (SCSI sobre IP) almacenamientolocal
- dispositivos de almacenamiento locales montados en los nodos.nfs
- Almacenamiento del Sistema de Archivos de Red (NFS)
Los siguientes tipos de PersistentVolume están obsoletos. Esto significa que el soporte aún está disponible, pero se eliminará en una futura versión de Kubernetes.
azureFile
- Azure File (obsoleto en v1.21)flexVolume
- FlexVolume (obsoleto en v1.23)portworxVolume
- Volumen Portworx (obsoleto en v1.25)vsphereVolume
- Volumen VMDK de vSphere (obsoleto en v1.19)cephfs
- Volumen CephFS (obsoleto en v1.28)rbd
- Dispositivo de Bloque Rados (RBD) (obsoleto en v1.28)
Versiones anteriores de Kubernetes también soportaban los siguientes tipos de PersistentVolume integrados:
awsElasticBlockStore
- AWS Elastic Block Store (EBS) (no disponible en v1.27)azureDisk
- Disco Azure (no disponible en v1.27)cinder
- Cinder (almacenamiento en bloque de OpenStack) (no disponible en v1.26)photonPersistentDisk
- Disco persistente del controlador Photon. (no disponible a partir de v1.15)scaleIO
- Volumen ScaleIO. (no disponible a partir de v1.21)flocker
- Almacenamiento Flocker. (no disponible a partir de v1.25)quobyte
- Volumen Quobyte. (no disponible a partir de v1.25)storageos
- Volumen StorageOS. (no disponible a partir de v1.25)
Volúmenes Persistentes
Cada PV contiene una especificación y un estado, que corresponden a la especificación y el estado del volumen. El nombre de un objeto PersistentVolume debe ser un válido nombre de subdominio DNS.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
Capacidad
Por lo general, un PV tendrá una capacidad de almacenamiento específica. Esto se establece utilizando el atributo capacity
del PV. Lea el término del glosario Cantidad para comprender las unidades esperadas por capacity
.
Actualmente, el tamaño de almacenamiento es el único recurso que se puede establecer o solicitar. En el futuro, los atributos adicionales pueden incluir IOPS, throughput, etc.
Modo de Volumen
Kubernetes v1.18 [stable]
Kubernetes admite dos volumeModes
(modos de volumen) para PersistentVolumes: Filesystem
y Block
(Sistema de archivos y Bloque).
volumeMode
es un parámetro opcional de la API.
Filesystem
es el modo predeterminado que se utiliza cuando se omite el parámetro volumeMode
.
Un volumen con volumeMode: Filesystem
se monta en Pods en un directorio. Si el volumen está respaldado por un dispositivo de bloque y el dispositivo está vacío, Kubernetes crea un sistema de archivos en el dispositivo antes de montarlo por primera vez.
Puedes establecer el valor de volumeMode
en Block
para utilizar un volumen como un dispositivo de bloque sin formato. Este tipo de volumen se presenta en un Pod como un dispositivo de bloque, sin ningún sistema de archivos en él.
Este modo es útil para proporcionar al Pod la forma más rápida posible de acceder a un volumen, sin ninguna capa de sistema de archivos entre el Pod y el volumen.
Por otro lado, la aplicación que se ejecuta en el Pod debe saber cómo manejar un dispositivo de bloque sin formato.
Consulta Soporte para Volúmenes en Bloque sin Procesar para ver un ejemplo de cómo usar un volumen con volumeMode: Block
en un Pod.
Modos de Acceso
Un PersistentVolume puede montarse en un host de cualquier manera compatible con el proveedor de recursos. Como se muestra en la tabla a continuación, los proveedores tendrán diferentes capacidades y los modos de acceso de cada PV se establecerán en los modos específicos admitidos por ese volumen en particular. Por ejemplo, NFS puede admitir múltiples clientes de lectura/escritura, pero un PV de NFS específico podría exportarse en el servidor como de solo lectura. Cada PV tiene su propio conjunto de modos de acceso que describen las capacidades específicas de ese PV en particular.
Los modos de acceso son:
ReadWriteOnce
- el volumen puede montarse como lectura-escritura por un solo nodo. El modo de acceso ReadWriteOnce aún puede permitir que varios Pods accedan al volumen cuando los Pods se ejecutan en el mismo nodo. Para el acceso de un solo Pod, consulta ReadWriteOncePod.
ReadOnlyMany
- el volumen puede montarse como solo lectura por muchos nodos.
ReadWriteMany
- el volumen puede montarse como lectura-escritura por muchos nodos.
ReadWriteOncePod
-
FEATURE STATE:el volumen puede montarse como lectura-escritura por un solo Pod. Utiliza el modo de acceso ReadWriteOncePod si deseas garantizar que solo un Pod en todo el clúster pueda leer ese PVC o escribir en él.
Kubernetes v1.29 [stable]
El modo de acceso ReadWriteOncePod
solo es compatible con los volúmenes CSI y Kubernetes versión 1.22+. Para utilizar esta función, deberás actualizar los siguientes CSI sidecars a estas versiones o superiores:
En la línea de comandos (CLI), los modos de acceso se abrevian de la siguiente manera:
- RWO - ReadWriteOnce (Lectura/Escritura para Uno)
- ROX - ReadOnlyMany (Solo Lectura para Muchos)
- RWX - ReadWriteMany (Lectura/Escritura para Muchos)
- RWOP - ReadWriteOncePod (Lectura/Escritura para Uno por Pod)
¡Importante! Un volumen solo puede montarse utilizando un modo de acceso a la vez, incluso si admite varios modos.
Volume Plugin | ReadWriteOnce | ReadOnlyMany | ReadWriteMany | ReadWriteOncePod | |
---|---|---|---|---|---|
AzureFile | ✓ | ✓ | ✓ | - | |
CephFS | ✓ | ✓ | ✓ | - | |
CSI | depends on the driver | depends on the driver | depends on the driver | depends on the driver | |
FC | ✓ | ✓ | - | - | |
FlexVolume | ✓ | ✓ | depends on the driver | - | |
HostPath | ✓ | - | - | - | |
iSCSI | ✓ | ✓ | - | - | |
NFS | ✓ | ✓ | ✓ | - | |
RBD | ✓ | ✓ | - | - | |
VsphereVolume | ✓ | - | - (works when Pods are collocated) | - | |
PortworxVolume | ✓ | - | ✓ | - | - |
Clase
Un PV puede tener una clase, que se especifica configurando el atributo storageClassName
con el nombre de una StorageClass. Un PV de una clase particular solo puede vincularse a PVC que soliciten esa clase. Un PV sin storageClassName
no tiene clase y solo puede vincularse a PVC que no soliciten una clase en particular.
En el pasado, en lugar del atributo storageClassName
, se utilizaba la anotación volume.beta.kubernetes.io/storage-class
. Esta anotación todavía funciona; sin embargo, quedará completamente en desuso en una versión futura de Kubernetes.
Política de Reclamación
Las políticas de reclamación actuales son:
- Retain (Retener) -- reclamación manual
- Recycle (Reciclar) -- limpieza básica (
rm -rf /elvolumen/*
) - Delete (Eliminar) -- eliminar el volumen
Para Kubernetes 1.29, solo los tipos de volumen nfs
y hostPath
admiten el reciclaje.
Opciones de Montaje
Un administrador de Kubernetes puede especificar opciones de montaje adicionales cuando se monta un Persistent Volume en un nodo.
Los siguientes tipos de volumen admiten opciones de montaje:
azureFile
cephfs
(desaconsejado en v1.28)cinder
(desaconsejado en v1.18)iscsi
nfs
rbd
(desaconsejado en v1.28)vsphereVolume
Las opciones de montaje no se validan. Si una opción de montaje es inválida, el montaje falla.
En el pasado, en lugar del atributo mountOptions
, se utilizaba la anotación volume.beta.kubernetes.io/mount-options
. Esta anotación todavía funciona; sin embargo, quedará completamente en desuso en una versión futura de Kubernetes. Se recomienda utilizar el atributo mountOptions
para especificar las opciones de montaje en lugar de la anotación.
Afinidad de Nodos
Un PV puede especificar la afinidad de nodos para definir restricciones que limiten desde qué nodos se puede acceder a este volumen. Los Pods que utilizan un PV solo se programarán en nodos seleccionados por la afinidad de nodos. Para especificar la afinidad de nodos, configura nodeAffinity
en .spec
de un PV. La referencia de API de PersistentVolume tiene más detalles sobre este campo.
Fase
Un PersistentVolume estará en una de las siguientes fases:
Available
(Disponible)- un recurso gratuito que aún no está vinculado a una solicitud
Bound
(Vinculado)- el volumen está vinculado a una solicitud
Released
(Liberado)- la solicitud ha sido eliminada, pero el recurso de almacenamiento asociado aún no ha sido reclamado por el clúster
Failed
(Fallido)- el volumen ha fallado en su proceso de reclamación (automatizada)
Puedes ver el nombre de la PVC vinculada al PV utilizando kubectl describe persistentvolume <nombre>
.
Marca de tiempo de transición de fase
Kubernetes v1.29 [beta]
El campo .status
de un PersistentVolume puede incluir un campo lastPhaseTransitionTime
en versión alfa. Este campo registra la marca de tiempo de la última transición de fase del volumen. Para volúmenes recién creados, la fase se establece en Pending
(Pendiente) y lastPhaseTransitionTime
se establece en el tiempo actual.
PersistentVolumeLastPhaseTransitionTime
para poder usar o ver el campo lastPhaseTransitionTime
.
PersistentVolumeClaims
Cada PVC contiene un spec (especificación) y un status (estado), que es la especificación y el estado de la solicitud. El nombre de un objeto PersistentVolumeClaim debe ser un nombre de subdominio DNS válido.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- { key: environment, operator: In, values: [dev] }
Modos de Acceso
Las solicitudes utilizan las mismas convenciones que los volúmenes al solicitar almacenamiento con modos de acceso específicos.
Modos de Volumen
Las solicitudes utilizan la misma convención que los volúmenes para indicar el consumo del volumen como un sistema de archivos o un dispositivo de bloque.
Recursos
Las solicitudes, al igual que los Pods, pueden solicitar cantidades específicas de un recurso. En este caso, la solicitud es para almacenamiento. El mismo modelo de recurso se aplica tanto a los volúmenes como a las solicitudes.
Selector
Las solicitudes pueden especificar un selector de etiqueta para filtrar aún más el conjunto de volúmenes. Solo los volúmenes cuyas etiquetas coincidan con el selector pueden vincularse a la solicitud. El selector puede constar de dos campos:
matchLabels
(coincidencia de etiquetas) - el volumen debe tener una etiqueta con este valor.matchExpressions
(expresiones de coincidencia) - una lista de requisitos especificados por clave, lista de valores y operador que relaciona la clave y los valores. Los operadores válidos incluyen In, NotIn, Exists y DoesNotExist.
Todos los requisitos, tanto de matchLabels
como de matchExpressions
, se combinan mediante un operador AND: todos deben cumplirse para que haya coincidencia.
Clase
Una solicitud puede solicitar una clase en particular especificando el nombre de una StorageClass utilizando el atributo storageClassName
. Solo los PV de la clase solicitada, es decir, aquellos con el mismo storageClassName
que el PVC, pueden vincularse al PVC.
Las PVC no necesariamente tienen que solicitar una clase. Una PVC con su storageClassName
configurado igual a ""
siempre se interpreta como una solicitud de un PV sin clase, por lo que solo puede vincularse a PV sin clase (sin anotación o con ""
configurado). Una PVC sin storageClassName
no es exactamente lo mismo y se trata de manera diferente por parte del clúster, dependiendo de si el plugin de admisión DefaultStorageClass
está activado.
- Si el plugin de admisión está activado, el administrador puede especificar una StorageClass predeterminada. Todas las PVC que no tengan
storageClassName
solo podrán vincularse a los PV de esa clase predeterminada. La especificación de una StorageClass predeterminada se realiza configurando la anotaciónstorageclass.kubernetes.io/is-default-class
igual atrue
en un objeto StorageClass. Si el administrador no especifica una predeterminada, el clúster responderá a la creación de PVC como si el plugin de admisión estuviera desactivado. Si se especifican más de una StorageClass predeterminada, la más nueva se utilizará cuando se provisione dinámicamente la PVC. - Si el plugin de admisión está desactivado, no existe una noción de una StorageClass predeterminada. Todas las PVC que tengan
storageClassName
configurado como""
solo podrán vincularse a los PV que también tenganstorageClassName
configurado como""
. Sin embargo, las PVC sinstorageClassName
pueden actualizarse más adelante una vez que esté disponible la StorageClass predeterminada. Si la PVC se actualiza, ya no se vinculará a los PV que tenganstorageClassName
configurado como""
.
Consulta asignación retroactiva de StorageClass predeterminada para obtener más detalles.
Según el método de instalación, el administrador puede implementar una StorageClass predeterminada en un clúster de Kubernetes mediante el administrador de complementos durante la instalación.
Cuando una PVC especifica un selector
además de solicitar una StorageClass, los requisitos se combinan mediante una operación AND: solo se puede vincular un PV de la clase solicitada y con las etiquetas solicitadas a la PVC.
selector
no vacío no puede tener un PV provisionado dinámicamente para ella.
En el pasado, en lugar del atributo storageClassName
, se utilizaba la anotación volume.beta.kubernetes.io/storage-class
. Esta anotación todavía funciona; sin embargo, no será compatible en futuras versiones de Kubernetes. Se recomienda utilizar el atributo storageClassName
en su lugar.
Asignación retroactiva de StorageClass predeterminada
Kubernetes v1.28 [stable]
Puedes crear una PersistentVolumeClaim sin especificar un storageClassName
para la nueva PVC, incluso cuando no exista una StorageClass predeterminada en tu clúster. En este caso, la nueva PVC se crea tal como la definiste, y el storageClassName
de esa PVC permanece sin configurar hasta que esté disponible la predeterminada.
Cuando está disponible una StorageClass predeterminada, el plano de control identifica cualquier PVC existente sin storageClassName
. Para las PVC que tienen un valor vacío para storageClassName
o que no tienen esta clave, el plano de control actualiza esas PVC para establecer storageClassName
de acuerdo con la nueva StorageClass predeterminada. Si tienes una PVC existente donde storageClassName
es ""
, y configuras una StorageClass predeterminada, entonces esta PVC no se actualizará.
Para seguir vinculando a PV con storageClassName
configurado como ""
(mientras existe una StorageClass predeterminada), debes establecer el storageClassName
de la PVC asociada en ""
.
Este comportamiento ayuda a los administradores a cambiar la StorageClass predeterminada eliminando primero la antigua y luego creando o configurando otra. Este breve período en el que no hay una predeterminada hace que las PVC creadas en ese momento sin storageClassName
no tengan ninguna predeterminada, pero debido a la asignación retroactiva de la StorageClass predeterminada, esta forma de cambiar las predeterminadas es segura.
Solicitudes como Volúmenes
Los Pods acceden al almacenamiento utilizando la solicitud como un volumen. Las solicitudes deben existir en el mismo Namespace que el Pod que utiliza la solicitud. El clúster encuentra la solicitud en el Namespace del Pod y la utiliza para obtener el PersistentVolume que respalda la solicitud. Luego, el volumen se monta en el host y dentro del Pod.
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
Una Nota sobre Espacios de Nombres
Las vinculaciones de PersistentVolumes son exclusivas y, dado que las PersistentVolumeClaims son objetos con espacio de nombres, montar solicitudes con modos "Many" (ROX
, RWX
) solo es posible dentro de un mismo espacio de nombres (namespace).
Los PersistentVolumes de tipo hostPath
Los PersistentVolumes de tipo hostPath
utilizan un archivo o directorio en el nodo para emular almacenamiento conectado a la red. Consulta un ejemplo de un volumen de tipo hostPath
.
Soporte para Volúmenes en Bloque sin Procesar
Kubernetes v1.18 [stable]
Los siguientes complementos de volumen admiten volúmenes en bloque sin procesar, incluida la provisión dinámica cuando corresponda:
- CSI
- FC (Fibre Channel)
- iSCSI
- Volumen local
- OpenStack Cinder
- RBD (desaconsejado)
- RBD (Ceph Block Device; desaconsejado)
- VsphereVolume
PersistentVolume que Utiliza un Volumen en Bloque sin Procesar
apiVersion: v1
kind: PersistentVolume
metadata:
name: block-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
volumeMode: Block
persistentVolumeReclaimPolicy: Retain
fc:
targetWWNs: ["50060e801049cfd1"]
lun: 0
readOnly: false
PersistentVolumeClaim Solicitando un Volumen en Bloque sin Procesar
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: block-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Block
resources:
requests:
storage: 10Gi
Especificación de Pod Agregando la Ruta del Dispositivo en Bloque sin Procesar en el Contenedor
apiVersion: v1
kind: Pod
metadata:
name: pod-with-block-volume
spec:
containers:
- name: fc-container
image: fedora:26
command: ["/bin/sh", "-c"]
args: ["tail -f /dev/null"]
volumeDevices:
- name: data
devicePath: /dev/xvda
volumes:
- name: data
persistentVolumeClaim:
claimName: block-pvc
Vinculación de Volúmenes en Bloque
Si un usuario solicita un volumen en bloque sin procesar indicándolo mediante el campo volumeMode
en la especificación de PersistentVolumeClaim, las reglas de vinculación difieren ligeramente de versiones anteriores que no consideraban este modo como parte de la especificación. A continuación, se muestra una tabla de las posibles combinaciones que el usuario y el administrador pueden especificar para solicitar un dispositivo en bloque sin procesar. La tabla indica si el volumen se vinculará o no dadas las combinaciones: Matriz de vinculación de volumen para volúmenes provisionados estáticamente:
PV volumeMode | PVC volumeMode | Resultado |
---|---|---|
unspecified | unspecified | BIND |
unspecified | Block | NO BIND |
unspecified | Filesystem | BIND |
Block | unspecified | NO BIND |
Block | Block | BIND |
Block | Filesystem | NO BIND |
Filesystem | Filesystem | BIND |
Filesystem | Block | NO BIND |
Filesystem | unspecified | BIND |
Soporte para Instantáneas de Volúmenes y Restauración de Volúmenes desde Instantáneas
Kubernetes v1.20 [stable]
Las instantáneas de volúmenes solo admiten los plugins de volumen CSI fuera del árbol. Para obtener más detalles, consulta Instantáneas de Volúmenes. Los plugins de volumen dentro del árbol están obsoletos. Puedes obtener información sobre los plugins de volumen obsoletos en el FAQ de Plugins de Volumen.
Crear una PersistentVolumeClaim desde una Instantánea de Volumen
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restore-pvc
spec:
storageClassName: csi-hostpath-sc
dataSource:
name: new-snapshot-test
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Clonación de Volúmenes
Clonación de Volúmenes solo está disponible para plugins de volumen CSI.
Crear una PersistentVolumeClaim desde una PVC existente
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cloned-pvc
spec:
storageClassName: my-csi-plugin
dataSource:
name: existing-src-pvc-name
kind: PersistentVolumeClaim
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Pobladores de Volúmenes y Fuentes de Datos
Kubernetes v1.24 [beta]
Kubernetes admite pobladores de volúmenes personalizados.
Para utilizar pobladores de volúmenes personalizados, debes habilitar la característica AnyVolumeDataSource
feature gate para el kube-apiserver y kube-controller-manager.
Los pobladores de volúmenes aprovechan un campo de especificación de PVC llamado dataSourceRef
. A diferencia del campo dataSource
, que solo puede contener una referencia a otra PersistentVolumeClaim o a un VolumeSnapshot, el campo dataSourceRef
puede contener una referencia a cualquier objeto en el mismo Namespace, excepto los objetos principales que no sean PVC. Para los clústeres que tienen habilitada la característica, se prefiere el uso de dataSourceRef
en lugar de dataSource
.
Fuentes de Datos entre Espacios de Nombres
Kubernetes v1.26 [alpha]
Kubernetes admite fuentes de datos de volúmenes entre espacios de nombres.
Para utilizar fuentes de datos de volúmenes entre espacios de nombres, debes habilitar las características AnyVolumeDataSource
y CrossNamespaceVolumeDataSource
Interruptores de funcionalidades (feature gates) para el kube-apiserver y kube-controller-manager.
Además, debes habilitar la característica CrossNamespaceVolumeDataSource
para el csi-provisioner.
Al habilitar la característica CrossNamespaceVolumeDataSource
, puedes especificar un Namespace en el campo dataSourceRef.
gateway.networking.k8s.io
. Consulta ReferenceGrant en la documentación de la API de Gateway para obtener detalles. Esto significa que debes extender tu clúster de Kubernetes con al menos ReferenceGrant de la API de Gateway antes de poder utilizar este mecanismo.
Las referencias a fuentes de datos
El campo dataSourceRef
se comporta de manera casi idéntica al campo dataSource
. Si se especifica uno mientras que el otro no, el servidor de la API asignará el mismo valor a ambos campos. Ninguno de los campos puede cambiarse después de su creación, y cualquier intento de especificar valores diferentes para los dos campos resultará en un error de validación. Por lo tanto, los dos campos siempre tendrán el mismo contenido.
Hay dos diferencias importantes entre el campo dataSourceRef
y el campo dataSource
que los usuarios deben tener en cuenta:
-
El campo
dataSource
ignora los valores no válidos (como si el campo estuviera en blanco), mientras que el campodataSourceRef
nunca ignora los valores y generará un error si se utiliza un valor no válido. Los valores no válidos son cualquier objeto central (objetos sin apiGroup) excepto PVCs. -
El campo
dataSourceRef
puede contener diferentes tipos de objetos, mientras que el campodataSource
solo permite PVCs y VolumeSnapshots.
Cuando se habilita la característica CrossNamespaceVolumeDataSource
, existen diferencias adicionales:
- El campo
dataSource
solo permite objetos locales, mientras que el campodataSourceRef
permite objetos en cualquier Namespaces. - Cuando se especifica un Namespace,
dataSource
ydataSourceRef
no están sincronizados.
Los usuarios siempre deben utilizar dataSourceRef
en clústeres que tengan habilitada la puerta de enlace de características y recurrir a dataSource
en clústeres que no la tengan habilitada. No es necesario mirar ambos campos bajo ninguna circunstancia. Los valores duplicados con semántica ligeramente diferente existen solo por compatibilidad con versiones anteriores. En particular, una mezcla de controladores más antiguos y más nuevos pueden interoperar porque los campos son iguales.
Uso de pobladores de volúmenes
Los pobladores de volúmenes son controladores que pueden crear volúmenes no vacíos, donde el contenido del volumen es determinado por un Recurso Personalizado. Los usuarios crean un volumen poblado haciendo referencia a un Recurso Personalizado utilizando el campo dataSourceRef
:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: populated-pvc
spec:
dataSourceRef:
name: example-name
kind: ExampleDataSource
apiGroup: example.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Dado que los pobladores de volúmenes son componentes externos, los intentos de crear una PVC que los utilice pueden fallar si no se han instalado todos los componentes correctos. Los controladores externos deben generar eventos en la PVC para proporcionar retroalimentación sobre el estado de la creación, incluyendo advertencias si la PVC no puede ser creada debido a la falta de algún componente necesario. Esto ayuda a los usuarios a comprender por qué la creación de la PVC ha fallado y qué componentes faltan para que funcione correctamente.
Puedes instalar el controlador volume data source validator en tu clúster. Este controlador genera eventos de advertencia en una PVC en caso de que no haya ningún poblador registrado para manejar ese tipo de fuente de datos. Cuando se instala un poblador adecuado para una PVC, es responsabilidad de ese controlador de poblador informar sobre eventos relacionados con la creación del volumen y problemas durante el proceso. Esto proporciona información útil para los usuarios y administradores del clúster sobre el estado y los problemas relacionados con las PVC que utilizan pobladores de volúmenes.
Uso de una fuente de datos de volumen entre Namespaces
Kubernetes v1.26 [alpha]
Crea un ReferenceGrant para permitir que el propietario del Namespace acepte la referencia.
Define un volumen poblado especificando una fuente de datos de volumen entre Namespaces utilizando el campo dataSourceRef
. Debes tener un ReferenceGrant válido en el Namespace de origen previamente:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-ns1-pvc
namespace: default
spec:
from:
- group: ""
kind: PersistentVolumeClaim
namespace: ns1
to:
- group: snapshot.storage.k8s.io
kind: VolumeSnapshot
name: new-snapshot-demo
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foo-pvc
namespace: ns1
spec:
storageClassName: example
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
dataSourceRef:
apiGroup: snapshot.storage.k8s.io
kind: VolumeSnapshot
name: new-snapshot-demo
namespace: default
volumeMode: Filesystem
Escribiendo configuraciones portátiles
Si estás escribiendo plantillas de configuración o ejemplos que se ejecutarán en una amplia gama de clústeres y necesitas almacenamiento persistente, se recomienda que utilices el siguiente patrón:
- Incluye objetos PersistentVolumeClaim en tu conjunto de configuración (junto con Despliegues, ConfigMaps, etc.).
- No incluyas objetos PersistentVolume en la configuración, ya que el usuario que instala la configuración puede no tener permisos para crear PersistentVolumes.
- Ofrece al usuario la opción de proporcionar un nombre de clase de almacenamiento al instanciar la plantilla.
- Si el usuario proporciona un nombre de clase de almacenamiento, coloca ese valor en el campo
persistentVolumeClaim.storageClassName
. Esto hará que la PVC coincida con la clase de almacenamiento correcta si el administrador del clúster ha habilitado las StorageClasses. - Si el usuario no proporciona un nombre de clase de almacenamiento, deja el campo
persistentVolumeClaim.storageClassName
como nulo. Esto hará que se provisione automáticamente un PV para el usuario con la StorageClass predeterminada en el clúster. Muchos entornos de clúster tienen una StorageClass predeterminada instalada, o los administradores pueden crear su propia StorageClass predeterminada.
- Si el usuario proporciona un nombre de clase de almacenamiento, coloca ese valor en el campo
- En tus herramientas, observa las PVC que no se están enlazando después de algún tiempo y comunica esto al usuario, ya que esto puede indicar que el clúster no tiene soporte de almacenamiento dinámico (en cuyo caso el usuario debe crear un PV correspondiente) o que el clúster no tiene un sistema de almacenamiento (en cuyo caso el usuario no puede implementar configuraciones que requieran PVCs).
Siguientes pasos
- Aprende más sobre Cómo crear un PersistentVolume.
- Aprende más sobre Cómo crear un PersistentVolumeClaim.
- Lee el documento de diseño de almacenamiento persistente.
Referencias de API
Puedes encontrar información detallada sobre las APIs PersistentVolume
y PersistentVolumeClaim
en la documentación oficial de Kubernetes. Estos enlaces te llevarán a las páginas de referencia que describen las especificaciones y los campos de estas API, junto con ejemplos y ejercicios de uso.
4 - Volúmenes proyectados
Este documento describe los volúmenes proyectados en Kubernetes. Necesita estar familiarizado con volúmenes.
Introducción
Un volumen proyectado
asigna varias fuentes de volúmenes existentes al mismo directorio.
Actualmente se pueden proyectar los siguientes tipos de fuentes de volumen:
Se requiere que todas las fuentes estén en el mismo espacio de nombres que el Pod. Para más detalles, vea el documento de diseño all-in-one volume.
Configuración de ejemplo con un secreto, una downwardAPI y una configMap
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: busybox:1.28
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "cpu_limit"
resourceFieldRef:
containerName: container-test
resource: limits.cpu
- configMap:
name: myconfigmap
items:
- key: config
path: my-group/my-config
Configuración de ejemplo: secretos con un modo de permiso no predeterminado establecido
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: busybox:1.28
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- secret:
name: mysecret2
items:
- key: password
path: my-group/my-password
mode: 511
Cada fuente de volumen proyectada aparece en la especificación bajo sources
. Los parámetros son casi los mismos con dos excepciones:
- Para los secretos, el campo
secretName
se ha cambiado aname
para que sea coherente con el nombre de ConfigMap. - El
defaultMode
solo se puede especificar en el nivel proyectado y no para cada fuente de volumen. Sin embargo, como se ilustra arriba, puede configurar explícitamente elmode
para cada proyección individual.
Volúmenes proyectados de serviceAccountToken
Puede inyectar el token para la service account actual en un Pod en una ruta especificada. Por ejemplo:
apiVersion: v1
kind: Pod
metadata:
name: sa-token-test
spec:
containers:
- name: container-test
image: busybox:1.28
volumeMounts:
- name: token-vol
mountPath: "/service-account"
readOnly: true
serviceAccountName: default
volumes:
- name: token-vol
projected:
sources:
- serviceAccountToken:
audience: api
expirationSeconds: 3600
path: token
El Pod de ejemplo tiene un volumen proyectado que contiene el token de cuenta de servicio inyectado. Los contenedores en este Pod pueden usar ese token para acceder al servidor API de Kubernetes, autenticándose con la identidad de the pod's ServiceAccount.
El campo audience
contiene la audiencia prevista del
token. Un destinatario del token debe identificarse con un identificador especificado en la audiencia del token y, de lo contrario, debe rechazar el token. Este campo es opcional y de forma predeterminada es el identificador del servidor API.
The expirationSeconds
es la duración esperada de validez del token de la cuenta de servicio. El valor predeterminado es 1 hora y debe durar al menos 10 minutos (600 segundos).
Un administrador
también puede limitar su valor máximo especificando la opción --service-account-max-token-expiration
para el servidor API. El campo path
especifica una ruta relativa al punto de montaje del volumen proyectado.
subPath
no recibirá actualizaciones para esas fuentes de volumen.
Interacciones SecurityContext
La propuesta para el manejo de permisos de archivos en la mejora del volumen de cuentas de servicio proyectadas introdujo los archivos proyectados que tienen los permisos de propietario correctos establecidos.
Linux
En los pods de Linux que tienen un volumen proyectado y RunAsUser
configurado en el Pod
SecurityContext
,
los archivos proyectados tienen la conjunto de propiedad correcto, incluida la propiedad del usuario del contenedor.
Cuando todos los contenedores en un pod tienen el mismo runAsUser
configurado en su
PodSecurityContext
o el contenedor
SecurityContext
,
entonces el kubelet garantiza que el contenido del volumen serviceAccountToken
sea propiedad de ese usuario y que el archivo token tenga su modo de permiso establecido en 0600
.
Ephemeral containers agregado a un pod después de su creación no cambia los permisos de volumen que se establecieron cuando se creó el pod.
Si los permisos de volumen serviceAccountToken
de un Pod se establecieron en 0600
porque todos los demás contenedores en el Pod tienen el mismo runAsUser
, los contenedores efímeros deben usar el mismo runAsUser
para poder leer el token.
Windows
En los pods de Windows que tienen un volumen proyectado y RunAsUsername
configurado en el pod SecurityContext
, la propiedad no se aplica debido a la forma en que se administran las cuentas de usuario en Windows.
Windows almacena y administra cuentas de grupos y usuarios locales en un archivo de base de datos llamado Administrador de cuentas de seguridad (SAM).
Cada contenedor mantiene su propia instancia de la base de datos SAM, de la cual el host no tiene visibilidad mientras el contenedor se está ejecutando.
Los contenedores de Windows están diseñados para ejecutar la parte del modo de usuario del sistema operativo de forma aislada del host, de ahí el mantenimiento de una base de datos SAM virtual.
Como resultado, el kubelet que se ejecuta en el host no tiene la capacidad de configurar dinámicamente la propiedad de los archivos del host para cuentas de contenedores virtualizados. Se recomienda que, si los archivos de la máquina host se van a compartir con el contenedor, se coloquen en su propio montaje de volumen fuera de C:\
.
De forma predeterminada, los archivos proyectados tendrán la siguiente propiedad, como se muestra en un archivo de volumen proyectado de ejemplo:
PS C:\> Get-Acl C:\var\run\secrets\kubernetes.io\serviceaccount\..2021_08_31_22_22_18.318230061\ca.crt | Format-List
Path : Microsoft.PowerShell.Core\FileSystem::C:\var\run\secrets\kubernetes.io\serviceaccount\..2021_08_31_22_22_18.318230061\ca.crt
Owner : BUILTIN\Administrators
Group : NT AUTHORITY\SYSTEM
Access : NT AUTHORITY\SYSTEM Allow FullControl
BUILTIN\Administrators Allow FullControl
BUILTIN\Users Allow ReadAndExecute, Synchronize
Audit :
Sddl : O:BAG:SYD:AI(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU)
Esto implica que todos los usuarios administradores como ContainerAdministrator
tendrán acceso de lectura, escritura y ejecución, mientras que los usuarios que no sean administradores tendrán acceso de lectura y ejecución.
En general, se desaconseja otorgar acceso al contenedor al host, ya que puede abrir la puerta a posibles vulnerabilidades de seguridad.
Crear un Pod de Windows con RunAsUser
en su SecurityContext
dará como resultado que el Pod quede atascado en ContainerCreating
para siempre. Por lo tanto, se recomienda no utilizar la opción RunAsUser
exclusiva de Linux con Windows Pods.
5 - Clonación de volumen CSI
Este documento describe el concepto para clonar volúmenes CSI existentes en Kubernetes. Se sugiere estar familiarizado con Volúmenes.
Introducción
La función de clonación de volumen CSI agrega soporte para especificar PVCs existentes en el campo dataSource
para indicar que un usuario desea clonar un Volume.
Un Clon se define como un duplicado de un volumen de Kubernetes existente que se puede consumir como lo sería cualquier volumen estándar. La única diferencia es que al aprovisionar, en lugar de crear un "nuevo" Volumen vacío, el dispositivo de backend crea un duplicado exacto del Volumen especificado.
La implementación de la clonación, desde la perspectiva de la API de Kubernetes, agrega la capacidad de especificar un PVC existente como dataSource durante la creación de un nuevo PVC. El PVC de origen debe estar vinculado y disponible (no en uso).
Los usuarios deben tener en cuenta lo siguiente cuando utilicen esta función:
- El soporte de clonación (
VolumePVCDataSource
) sólo está disponible para controladores CSI. - El soporte de clonación sólo está disponible para aprovisionadores dinámicos.
- Los controladores CSI pueden haber implementado o no la funcionalidad de clonación de volúmenes.
- Sólo puede clonar un PVC cuando existe en el mismo Namespace que el PVC de destino (el origen y el destino deben estar en el mismo Namespace).
- La clonación sólo se admite dentro de la misma Clase de Almacenamiento.
- El volumen de destino debe ser de la misma clase de almacenamiento que el origen
- Se puede utilizar la clase de almacenamiento predeterminada y se puede omitir storageClassName en la especificación
- La clonación sólo se puede realizar entre dos volúmenes que usan la misma configuración de VolumeMode (si solicita un volumen en modo de bloqueo, la fuente DEBE también ser en modo de bloqueo)
Aprovisionamiento
Los clones se aprovisionan como cualquier otro PVC con la excepción de agregar un origen de datos que hace referencia a un PVC existente en el mismo Namespace.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: clone-of-pvc-1
namespace: myns
spec:
accessModes:
- ReadWriteOnce
storageClassName: cloning
resources:
requests:
storage: 5Gi
dataSource:
kind: PersistentVolumeClaim
name: pvc-1
spec.resources.requests.storage
y el valor que especifique debe ser igual o mayor que la capacidad del volumen de origen.
El resultado es un nuevo PVC con el nombre clone-of-pvc-1
que tiene exactamente el mismo contenido que la fuente especificada pvc-1
.
Uso
Una vez disponible el nuevo PVC, el PVC clonado se consume igual que el resto de PVC. También se espera en este punto que el PVC recién creado sea un objeto independiente. Se puede consumir, clonar, tomar snapshots, o eliminar de forma independiente y sin tener en cuenta sus datos originales. Esto también implica que la fuente no está vinculada de ninguna manera al clon recién creado, también puede modificarse o eliminarse sin afectar al clon recién creado.
6 - Volume Snapshot Classes
Este documento describe el concepto de VolumeSnapshotClass en Kubernetes. Se sugiere estar familiarizado con Volume Snapshots y Storage Classes.
Introducción
Al igual que StorageClass proporciona a los administradores una forma de describir las “clases” de almacenamiento que ofrecen al aprovisionar un volumen, VolumeSnapshotClass proporciona una forma de describir las “clases” de almacenamiento al aprovisionar un Snapshot de volumen.
El Recurso VolumeSnapshotClass
Cada VolumeSnapshotClass contiene los campos driver
, deletionPolicy
, y parameters
,
que se utilizan cuando un VolumeSnapshot que pertenece a la clase, necesita aprovisionarse dinámicamente.
El nombre de un objeto VolumeSnapshotClass es significativo y es la forma en que los usuarios pueden solicitar una clase en particular. Los administradores establecen el nombre y parámetros de una clase cuando crean por primera vez objetos VolumeSnapshotClass; una vez creados los objetos no pueden ser actualizados.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-hostpath-snapclass
driver: hostpath.csi.k8s.io
deletionPolicy: Delete
parameters:
Los administradores pueden especificar un VolumeSnapshotClass predeterminado para VolumeSnapshots que no solicitan ninguna clase en particular. Para definir la clase predeterminada agregue la anotación: snapshot.storage.kubernetes.io/is-default-class: "true"
.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-hostpath-snapclass
annotations:
snapshot.storage.kubernetes.io/is-default-class: "true"
driver: hostpath.csi.k8s.io
deletionPolicy: Delete
parameters:
Driver
Las clases de Snapshot de volumen tienen un controlador que determina que complemento de volumen CSI se utiliza para aprovisionar VolumeSnapshots. Este campo debe especificarse.
DeletionPolicy
Las clases de Snapshot de volumen tienen un deletionPolicy. Permite configurar lo que sucede con un VolumeSnapshotContent cuando se va a eliminar el objeto VolumeSnapshot al que está vinculado. La deletionPolicy de una clase de Snapshot de volumen puede Retain
o Delete
. Este campo debe ser especificado.
Si la deletionPolicy es Delete
, el Snapshot de almacenamiento subyacente se eliminará junto con el objeto VolumeSnapshotContent. Si deletionPolicy es Retain
, tanto el Snapshot subyacente como VolumeSnapshotContent permanecerán.
Parameters
Las clases de Snapshot de volumen tienen parámetros que describen los Snapshots de volumen que pertenecen a la clase de Snapshot de volumen. Se pueden aceptar diferentes parámetros dependiendo del driver
.
7 - Volúmenes efímeros
Este documento describe volúmenes efímeros en Kubernetes. Se sugiere tener conocimiento previo sobre volúmenes, en particular PersistentVolumeClaim y PersistentVolume.
Algunas aplicaciones requieren almacenamiento adicional, pero no les preocupa si esos datos se almacenan de manera persistente entre reinicios. Por ejemplo, los servicios de caché a menudo tienen limitaciones de tamaño de memoria y pueden trasladar datos poco utilizados a un almacenamiento más lento que la memoria, con un impacto mínimo en el rendimiento general.
Otras aplicaciones esperan que algunos datos de entrada de solo lectura estén presentes en archivos, como datos de configuración o claves secretas.
Los volúmenes efímeros están diseñados para estos casos de uso. Debido a que los volúmenes siguen el ciclo de vida del Pod y se crean y eliminan junto con el Pod, los Pods pueden detenerse y reiniciarse sin estar limitados a la disponibilidad de algún volumen persistente.
Los volúmenes efímeros se especifican en línea en la especificación del Pod, lo que simplifica la implementación y gestión de aplicaciones.
Tipos de volúmenes efímeros
Kubernetes admite varios tipos diferentes de volúmenes efímeros para diversos propósitos:
-
emptyDir: vacíos al inicio del Pod, con el almacenamiento proveniente localmente del directorio base de kubelet (generalmente el disco raíz) o la RAM.
-
configMap, downwardAPI, secret: inyectar diferentes tipos de datos de Kubernetes en un Pod.
-
CSI volúmenes efímeros: Similar a los tipos de volumen anteriores, pero proporcionados por controladores especiales CSI que soportan específicamente esta característica
-
volúmenes efímeros genéricos, que pueden proporcionar todos los controladores de almacenamiento que también admiten volúmenes persistentes
emptyDir
, configMap
, downwardAPI
, secret
se proporcionan como almacenamiento efímero local.
Ellos son administrados por kubelet en cada nodo.
Los volúmenes efímeros CSI deben ser proporcionados por controladores de almacenamiento CSI de terceros.
Los volúmenes efímeros genéricos pueden ser proporcionados por controladores de almacenamiento CSI de terceros, pero también por cualquier otro controlador de almacenamiento que admita la provisión dinámica. Algunos controladores CSI están escritos específicamente para volúmenes efímeros CSI y no admiten la provisión dinámica; por lo tanto, no se pueden utilizar para volúmenes efímeros genéricos.
La ventaja de utilizar controladores de terceros es que pueden ofrecer funcionalidades que Kubernetes en sí mismo no admite, como el almacenamiento con características de rendimiento diferentes al disco gestionado por kubelet o la inyección de datos diversos.
Volúmenes efímeros de CSI
Kubernetes v1.25 [stable]
configMap
,
downwardAPI
y secret
: el almacenamiento se gestiona localmente en cada nodo y se crea junto con otros recursos locales después de que un Pod ha sido programado en un nodo. Kubernetes ya no tiene ningún concepto de reprogramación de Pods en esta etapa. La creación de volúmenes debe ser poco propensa a fallos,
de lo contrario, el inicio del Pod queda atascado. En particular, la programación de Pods con conciencia de la capacidad de almacenamiento no está admitida para estos volúmenes. Actualmente, tampoco están cubiertos por los límites de uso de recursos de almacenamiento de un Pod, porque eso es algo que kubelet solo puede aplicar para el almacenamiento que administra él mismo.
Aquí tienes un ejemplo de manifiesto para un Pod que utiliza almacenamiento efímero CSI:
kind: Pod
apiVersion: v1
metadata:
name: my-csi-app
spec:
containers:
- name: my-frontend
image: busybox:1.28
volumeMounts:
- mountPath: "/data"
name: my-csi-inline-vol
command: ["sleep", "1000000"]
volumes:
- name: my-csi-inline-vol
csi:
driver: inline.storage.kubernetes.io
volumeAttributes:
foo: bar
Los volumeAttributes
determinan qué volumen es preparado por el controlador. Estos atributos son específicos de cada controlador y no están estandarizados. Consulta la documentación de cada controlador CSI para obtener instrucciones adicionales.
Restricciones del conductor CSI
Los volúmenes efímeros CSI permiten a los usuarios proporcionar volumeAttributes
directamente al controlador CSI como parte de la especificación del Pod. Un controlador CSI que permite volumeAttributes
que normalmente están restringidos a administradores NO es adecuado para su uso en un volumen efímero en línea. Por ejemplo, los parámetros que normalmente se definen en la clase de almacenamiento no deben estar expuestos a los usuarios a través del uso de volúmenes efímeros en línea.
Los administradores del clúster que necesiten restringir los controladores CSI que se pueden utilizar como volúmenes en línea dentro de una especificación de Pod pueden hacerlo mediante:
-
Eliminar
Ephemeral
devolumeLifecycleModes
en la especificación de CSIDriver, lo que evita que los controladores CSI admitan volúmenes efímeros en línea. -
Usando un webhook de admisión para restringir el uso de este controlador.
Volúmenes efímeros genéricos
Kubernetes v1.23 [stable]
Los volúmenes efímeros genéricos son similares a los volúmenes emptyDir
en el sentido de que proporcionan un directorio por Pod para datos temporales que generalmente está vacío después de la provisión. Pero también pueden tener características adicionales:
- El almacenamiento puede ser local o conectado a la red.
- Los volúmenes pueden tener un tamaño fijo que los Pods no pueden exceder.
- Los volúmenes pueden tener algunos datos iniciales, dependiendo del controlador y los parámetros.
- Se admiten operaciones típicas en los volúmenes, siempre que el controlador las soporte, incluyendo instantáneas, clonación, cambiar el tamaño, y seguimiento de la capacidad de almacenamiento.
Ejemplo:
kind: Pod
apiVersion: v1
metadata:
name: my-app
spec:
containers:
- name: my-frontend
image: busybox:1.28
volumeMounts:
- mountPath: "/scratch"
name: scratch-volume
command: ["sleep", "1000000"]
volumes:
- name: scratch-volume
ephemeral:
volumeClaimTemplate:
metadata:
labels:
type: my-frontend-volume
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "scratch-storage-class"
resources:
requests:
storage: 1Gi
Ciclo de vida y reclamo de volumen persistente
La idea clave de diseño es que los parámetros para una solicitud de volumen se permiten dentro de una fuente de volumen del Pod. Se admiten etiquetas, anotaciones y todo el conjunto de campos para una PersistentVolumeClaim. Cuando se crea un Pod de este tipo, el controlador de volúmenes efímeros crea entonces un objeto PersistentVolumeClaim real en el mismo espacio de nombres que el Pod y asegura que la PersistentVolumeClaim se elimine cuando se elimina el Pod.
Eso desencadena la vinculación y/o aprovisionamiento de volúmenes, ya sea de inmediato si el StorageClass utiliza la vinculación inmediata de volúmenes o cuando el Pod está programado provisionalmente en un nodo (modo de vinculación de volumen WaitForFirstConsumer
). Este último se recomienda para volúmenes efímeros genéricos, ya que permite al planificador elegir libremente un nodo adecuado para el Pod. Con la vinculación inmediata, el planificador está obligado a seleccionar un nodo que tenga acceso al volumen una vez que esté disponible.
En términos de propiedad de recursos,
un Pod que tiene almacenamiento efímero genérico es el propietario de la PersistentVolumeClaim(s) que proporciona ese almacenamiento efímero. Cuando se elimina el Pod, el recolector de basura de Kubernetes elimina la PVC, lo que suele desencadenar la eliminación del volumen, ya que la política de recuperación predeterminada de las clases de almacenamiento es eliminar los volúmenes.
Puedes crear almacenamiento local cuasi-efímero utilizando una StorageClass con una política de recuperación de retain
: el almacenamiento sobrevive al Pod y, en este caso, debes asegurarte de que la limpieza del volumen se realice por separado.
Mientras estas PVC existen, pueden usarse como cualquier otra PVC. En particular, pueden ser referenciadas como fuente de datos en la clonación o creación de instantáneas de volúmenes. El objeto PVC también contiene el estado actual del volumen.
Nomenclatura de PersistentVolumeClaim.
La nomenclatura de las PVC creadas automáticamente es determinista: el nombre es una combinación del nombre del Pod y el nombre del volumen, con un guion medio (-
) en el medio. En el ejemplo anterior, el nombre de la PVC será my-app-scratch-volume
. Esta nomenclatura determinista facilita la interacción con la PVC, ya que no es necesario buscarla una vez que se conocen el nombre del Pod y el nombre del volumen.
La nomenclatura determinista también introduce un posible conflicto entre diferentes Pods (un Pod "pod-a" con el volumen "scratch" y otro Pod con nombre "pod" y volumen "a-scratch" terminan teniendo el mismo nombre de PVC "pod-a-scratch") y entre Pods y PVCs creadas manualmente.
Estos conflictos se detectan: una PVC solo se utiliza para un volumen efímero si se creó para el Pod. Esta comprobación se basa en la relación de propiedad. Una PVC existente no se sobrescribe ni se modifica. Pero esto no resuelve el conflicto, ya que sin la PVC adecuada, el Pod no puede iniciarse.
Seguridad
El uso de volúmenes efímeros genéricos permite a los usuarios crear PVC de forma indirecta si pueden crear Pods, incluso si no tienen permiso para crear PVC directamente. Los administradores del clúster deben ser conscientes de esto. Si esto no encaja en su modelo de seguridad, deberían utilizar un webhook de admisión que rechace objetos como Pods que tienen un volumen efímero genérico.
La cuota normal del espacio de nombres para PVC sigue aplicándose, por lo que incluso si a los usuarios se les permite utilizar este nuevo mecanismo, no pueden utilizarlo para eludir otras políticas.
Siguientes pasos
Volúmenes efímeros gestionados por kubelet
Ver almacenamiento efímero local.
Volúmenes efímeros de CSI
- Para obtener más información sobre el diseño, consulta el KEP de Volúmenes efímeros en línea de CSI.
- Para obtener más información sobre el desarrollo futuro de esta función, consulte el problema de seguimiento de mejoras #596.
Volúmenes efímeros genéricos
- Para obtener más información sobre el diseño, consulta el KEP de Volúmenes efímeros genéricos en línea.
8 - Aprovisionamiento Dinámico de volumen
El aprovisionamiento dinámico de volúmenes permite crear volúmenes de almacenamiento bajo demanda. Sin el aprovisionamiento dinámico, los administradores de clústeres tienen que realizar llamadas manualmente a su proveedor de almacenamiento o nube para crear nuevos volúmenes de almacenamiento y luego crear objetos de PersistentVolume
para representarlos en Kubernetes. La función de aprovisionamiento dinámico elimina la necesidad de que los administradores del clúster aprovisionen previamente el almacenamiento. En cambio, el aprovisionamiento ocurre automáticamente cuando los usuarios lo solicitan.
Antecedentes
La implementación del aprovisionamiento dinámico de volúmenes se basa en el objeto API StorageClass
del grupo API storage.k8s.io
. Un administrador de clúster puede definir tantos objetos
StorageClass
como sea necesario, cada uno especificando un volume plugin (aka
provisioner) que aprovisiona un volumen y el conjunto de parámetros para pasar a ese aprovisionador. Un administrador de clúster puede definir y exponer varios tipos de almacenamiento (del mismo o de diferentes sistemas de almacenamiento) dentro de un clúster, cada uno con un conjunto personalizado de parámetros. Este diseño también garantiza que los usuarios finales no tengan que preocuparse por la complejidad y los matices de cómo se aprovisiona el almacenamiento, pero que aún tengan la capacidad de seleccionar entre múltiples opciones de almacenamiento.
Puede encontrar más información sobre las clases de almacenamiento aqui.
Habilitación del aprovisionamiento dinámico
Para habilitar el aprovisionamiento dinámico, un administrador de clúster debe crear previamente uno o más objetos StorageClass para los usuarios. Los objetos StorageClass definen qué aprovisionador se debe usar y qué parámetros se deben pasar a ese aprovisionador cuando se invoca el aprovisionamiento dinámico. El nombre de un objeto StorageClass debe ser un nombre de subdominio de DNS válido.
El siguiente manifiesto crea una clase de almacenamiento llamada "slow" que aprovisiona discos persistentes estándar similares a discos.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
El siguiente manifiesto crea una clase de almacenamiento llamada "fast" que aprovisiona discos persistentes similares a SSD.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
Usar Aprovisionamiento Dinámico
Los usuarios solicitan almacenamiento aprovisionado dinámicamente al incluir una clase de almacenamiento en su PersistentVolumeClaim
. Antes de Kubernetes v1.6, esto se hacía a través del la anotación
volume.beta.kubernetes.io/storage-class
. Sin embargo, esta anotación está obsoleta desde v1.9. Los usuarios ahora pueden y deben usar el campo
storageClassName
del objeto PersistentVolumeClaim
. El valor de este campo debe coincidir con el nombre de un StorageClass
configurada por el administrador
(ver documentación).
Para seleccionar la clase de almacenamiento llamada "fast", por ejemplo, un usuario crearía el siguiente PersistentVolumeClaim:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: claim1
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast
resources:
requests:
storage: 30Gi
Esta afirmación da como resultado que se aprovisione automáticamente un disco persistente similar a SSD. Cuando se elimina la petición, se destruye el volumen.
Comportamiento Predeterminado
El aprovisionamiento dinámico se puede habilitar en un clúster de modo que todas las peticiones se aprovisionen dinámicamente si no se especifica una clase de almacenamiento. Un administrador de clúster puede habilitar este comportamiento al:
- Marcar un objeto
StorageClass
como default; - Asegúrese de que el controlador de admisión
DefaultStorageClass
esté habilitado en el servidor de API.
Un administrador puede marcar un StorageClass
específico como predeterminada agregando la anotación
storageclass.kubernetes.io/is-default-class
.
Cuando existe un StorageClass
predeterminado en un clúster y un usuario crea un
PersistentVolumeClaim
con storageClassName
sin especificar, el controlador de admisión
DefaultStorageClass
agrega automáticamente el campo
storageClassName
que apunta a la clase de almacenamiento predeterminada.
Tenga en cuenta que puede haber como máximo una clase de almacenamiento default, o un PersistentVolumeClaim
sin storageClassName
especificado explícitamente.
Conocimiento de la Topología
En los clústeres Multi-Zone, los Pods se pueden distribuir en zonas de una región. Los backends de almacenamiento de zona única deben aprovisionarse en las zonas donde se programan los Pods. Esto se puede lograr configurando el Volume Binding Mode.
9 - StorageClass (Clases de Almacenamiento)
Este documento describe el concepto de una StorageClass (Clases de Almacenamiento) en Kubernetes. Necesita estar familiarizado con volumes y persistent volumes.
Introducción
Una StorageClass proporciona una forma para que los administradores describan las "clases" de almacenamiento que ofrecen. Diferentes clases pueden corresponder a niveles de calidad de servicio, o a políticas de copia de seguridad, o a políticas arbitrarias determinadas por los administradores del clúster de Kubernetes. Kubernetes en sí no tiene opiniones sobre lo que representan las clases. Este concepto a veces se denomina "profiles" en otros sistemas de almacenamiento.
El recurso StorageClass
Cada StorageClass contiene los campos provisioner
, parameters
y
reclaimPolicy
, que se utilizan cuando un PersistentVolume que pertenece a
la clase debe aprovisionarse dinámicamente.
El nombre de un objeto StorageClass es significativo y es la forma en que los usuarios pueden solicitar una clase en particular. Los administradores establecen el nombre y otros parámetros de una clase al crear objetos StorageClass por primera vez, y los objetos no pueden actualizarse una vez creados.
Los administradores pueden especificar una StorageClass predeterminada solo para los PVC que no solicite cualquier clase en particular a la que vincularse: vea la sección PersistentVolumeClaim para detalles.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
mountOptions:
- debug
volumeBindingMode: Immediate
Proveedor
Cada StorageClass tiene un aprovisionador que determina qué complemento de volumen se usa para el aprovisionamiento de PV. Este campo debe ser especificado.
Complemento de volumen | Aprovisionador interno | Ejemplo de configuración |
---|---|---|
AWSElasticBlockStore | ✓ | AWS EBS |
AzureFile | ✓ | Azure File |
AzureDisk | ✓ | Azure Disk |
CephFS | - | - |
Cinder | ✓ | OpenStack Cinder |
FC | - | - |
FlexVolume | - | - |
GCEPersistentDisk | ✓ | GCE PD |
iSCSI | - | - |
NFS | - | NFS |
RBD | ✓ | Ceph RBD |
VsphereVolume | ✓ | vSphere |
PortworxVolume | ✓ | Portworx Volume |
Local | - | Local |
No está restringido especificar los aprovisionadores "internos" enumerados aquí (cuyos nombres tienen el prefijo "kubernetes.io" y se envían junto con Kubernetes). También puede ejecutar y especificar aprovisionadores externos, que son programas independientes que siguen una especificación definida por Kubernetes. Los autores de proveedores externos tienen total discreción sobre dónde vive su código, cómo se envía el aprovisionador, cómo debe ser ejecutada, qué complemento de volumen usa (incluido Flex), etc. El repositorio kubernetes-sigs/sig-storage-lib-external-provisioner alberga una biblioteca para escribir aprovisionadores externos que implementa la mayor parte de la especificación. Algunos proveedores externos se enumeran en el repositorio kubernetes-sigs/sig-storage-lib-external-provisioner.
Por ejemplo, NFS no proporciona un aprovisionador interno, pero se puede usar un aprovisionador externo. También hay casos en los que los proveedores de almacenamiento de terceros proporcionan su propio aprovisionador externo.
Política de reclamación
Los PersistentVolumes creados dinámicamente por StorageClass tendrán la política de recuperación especificada en el campo reclaimPolicy
de la clase, que puede ser Delete
o Retain
. Si no se especifica reclaimPolicy
cuando se crea un objeto StorageClass, el valor predeterminado será Delete
.
Los PersistentVolumes que se crean manualmente y se administran a través de StorageClass tendrán la política de recuperación que se les asignó en el momento de la creación.
Permitir expansión de volumen
Kubernetes v1.11 [beta]
PersistentVolumes se puede configurar para que sea ampliable. Esta función, cuando se establece en true
, permite a los usuarios cambiar el tamaño del volumen editando el objeto de PVC correspondiente.
Los siguientes tipos de volúmenes admiten la expansión de volumen, cuando el StorageClass subyacente tiene el campo allowVolumeExpansion
establecido en verdadero.
Tipo de volumen | Versión requerida de Kubernetes |
---|---|
gcePersistentDisk | 1.11 |
awsElasticBlockStore | 1.11 |
Cinder | 1.11 |
rbd | 1.11 |
Azure File | 1.11 |
Azure Disk | 1.11 |
Portworx | 1.11 |
FlexVolume | 1.13 |
CSI | 1.14 (alpha), 1.16 (beta) |
Opciones de montaje
Los PersistentVolumes creados dinámicamente por StorageClass tendrán las opciones de montaje especificadas en el campo mountOptions
de la clase.
Si el complemento de volumen no admite opciones de montaje pero se especifican opciones de montaje, el aprovisionamiento fallará. Las opciones de montura no se validan ni en la clase ni en el PV. Si una opción de montaje no es válida, el montaje PV falla.
Modo de enlace de volumen
El campo volumeBindingMode
controla cuándo debe ocurrir enlace de volumen y aprovisionamiento dinámico. Cuando no está configurado, el modo "Inmediato" se usa de manera predeterminada.
El modo Inmediato
indica que el enlace de volumen y la dinámica
el aprovisionamiento ocurre una vez que se crea PersistentVolumeClaim. Para los backends de almacenamiento que están restringidos por topología y no son accesibles globalmente desde todos los nodos del clúster, los volúmenes persistentes se vincularán o aprovisionarán sin conocimiento de los requisitos de programación del pod. Esto puede resultar en Pods no programables.
Un administrador de clústeres puede abordar este problema especificando el modo WaitForFirstConsumer
que retrasará el enlace y el aprovisionamiento de un PersistentVolume hasta que se cree un Pod que use PersistentVolumeClaim.
PersistentVolumes se seleccionarán o aprovisionarán de acuerdo con la topología especificada por las restricciones de programación del pod. Estos incluyen, pero no se limitan a requerimientos de recursos,
node selectors,
pod affinity and anti-affinity,
y taints and tolerations.
Los siguientes complementos admiten WaitForFirstConsumer
con aprovisionamiento dinámico:
Los siguientes complementos admiten WaitForFirstConsumer
con enlace PersistentVolume creado previamente:
- Todo lo anterior
- Local
Kubernetes v1.17 [stable]
Si elige usar WaitForFirstConsumer
, no use nodeName
en la especificación del pod para especificar la afinidad del nodo. Si se utiliza nodeName
en este caso, el planificador se omitirá y el PVC permanecerá en estado pendiente
.
En su lugar, puede usar el selector de nodos para el nombre de host en este caso, como se muestra a continuación.
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
nodeSelector:
kubernetes.io/hostname: kube-01
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
Topologías permitidas
Cuando un operador de clúster especifica el modo de enlace de volumen WaitForFirstConsumer
, ya no es necesario restringir el aprovisionamiento a topologías específicas en la mayoría de las situaciones. Sin embargo, si todavía es necesario, se puede especificar allowedTopologies
.
Este ejemplo demuestra cómo restringir la topología de los volúmenes aprovisionados a determinadas
zonas y debe usarse como reemplazo de los parámetros zone
y zones
para el
complementos compatibles.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:
- key: failure-domain.beta.kubernetes.io/zone
values:
- us-central-1a
- us-central-1b
Parámetros
Las clases de almacenamiento tienen parámetros que describen los volúmenes que pertenecen a la clase de almacenamiento. Se pueden aceptar diferentes parámetros dependiendo del provisioner
. Por ejemplo, el valor io1
, para el parámetro type
y el parámetro iopsPerGB
son específicos de EBS. Cuando se omite un parámetro, se utiliza algún valor predeterminado.
Puede haber como máximo 512 parámetros definidos para StorageClass. La longitud total del objeto de parámetros, incluidas sus claves y valores, no puede superar los 256 KiB.
AWS EBS
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
type: io1
iopsPerGB: "10"
fsType: ext4
-
type
:io1
,gp2
,sc1
,st1
. Ver AWS docs para detalles. Por defecto:gp2
. -
zone
(Obsoleto): AWS zona. Si no se especificazone
nizones
, los volúmenes generalmente se distribuyen por turnos en todas las zonas activas donde el clúster de Kubernetes tiene un nodo. Los parámetroszone
yzones
no deben usarse al mismo tiempo. -
zones
(Obsoleto): una lista separada por comas de las zonas de AWS. Si no se especificazone
nizones
, los volúmenes generalmente se distribuyen por turnos en todas las zonas activas donde el clúster de Kubernetes tiene un nodo. Los parámetroszone
yzones
no deben usarse al mismo tiempo. -
iopsPerGB
: solo para volúmenesio1
. Operaciones de E/S por segundo por GiB. El complemento de volumen de AWS multiplica esto por el tamaño del volumen solicitado para calcular las IOPS del volumen y lo limita a 20 000 IOPS (máximo admitido por AWS, consulte Documentos de AWS). Aquí se espera una cadena, es decir,"10"
, no10
. -
fsType
: fsType que es compatible con kubernetes. Predeterminado:"ext4"
. -
encrypted
: indica si el volumen de EBS debe cifrarse o no. Los valores válidos son"true"
o"false"
. Aquí se espera una cadena, es decir,"true"
, notrue
. -
kmsKeyId
: opcional. El nombre de recurso de Amazon completo de la clave que se utilizará al cifrar el volumen. Si no se proporciona ninguno peroencrypted
es verdadero, AWS genera una clave. Consulte los documentos de AWS para obtener un valor de ARN válido.
GCE PD
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
fstype: ext4
replication-type: none
-
type
:pd-standard
opd-ssd
. Por defecto:pd-standard
-
zone
(Obsoleto): zona GCE. Si no se especificazone
nizones
, los volúmenes generalmente se distribuyen por turnos en todas las zonas activas donde el clúster de Kubernetes tiene un nodo. Los parámetroszone
yzones
no deben usarse al mismo tiempo. -
zones
(Obsoleto): Una lista separada por comas de zona(s) GCE. Si no se especificazone
nizones
, los volúmenes generalmente se distribuyen por turnos en todas las zonas activas donde el clúster de Kubernetes tiene un nodo. Los parámetroszone
yzones
no deben usarse al mismo tiempo. -
fstype
:ext4
oxfs
. Por defecto:ext4
. El tipo de sistema de archivos definido debe ser compatible con el sistema operativo host. -
replication-type
:none
orregional-pd
. Por defecto:none
.
Si replication-type
se establece en none
, se aprovisionará un PD regular (zonal).
Si replication-type
se establece enregional-pd
, a
Regional Persistent Disk
será aprovisionado. Es muy recomendable tener
volumeBindingMode: WaitForFirstConsumer
establecido, en cuyo caso cuando crea un Pod que consume un PersistentVolumeClaim que usa esta clase de almacenamiento, un disco persistente regional se aprovisiona con dos zonas. Una zona es la misma que la zona en la que está programado el Pod. La otra zona se selecciona aleatoriamente de las zonas disponibles para el clúster. Las zonas de disco se pueden restringir aún más usando allowedTopologies
.
NFS
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: example-nfs
provisioner: example.com/external-nfs
parameters:
server: nfs-server.example.com
path: /share
readOnly: "false"
server
: Servidor es el nombre de host o la dirección IP del servidor NFS.path
: Ruta que exporta el servidor NFS.readOnly
: Una bandera que indica si el almacenamiento se montará como solo lectura (falso por defecto)
Kubernetes no incluye un proveedor de NFS interno. Debe usar un aprovisionador externo para crear una StorageClass para NFS. Aquí hay unos ejemplos:
OpenStack Cinder
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gold
provisioner: kubernetes.io/cinder
parameters:
availability: nova
availability
: Zona de disponibilidad. Si no se especifica, los volúmenes generalmente se distribuyen por turnos en todas las zonas activas donde el clúster de Kubernetes tiene un nodo.
Kubernetes v1.11 [deprecated]
Este proveedor interno de OpenStack está obsoleto. Por favor use el proveedor de nube externo para OpenStack.
vSphere
Hay dos tipos de aprovisionadores para las clases de almacenamiento de vSphere:
- CSI provisioner:
csi.vsphere.vmware.com
- vCP provisioner:
kubernetes.io/vsphere-volume
Los proveedores In-tree estan obsoletos. Para obtener más información sobre el aprovisionador de CSI, consulte Kubernetes vSphere CSI Driver y vSphereVolume CSI migration.
Aprovisionador de CSI
El aprovisionador vSphere CSI StorageClass funciona con clústeres de Tanzu Kubernetes. Para ver un ejemplo, consulte el vSphere CSI repository.
Aprovisionador de vCP
Los siguientes ejemplos utilizan el aprovisionador StorageClass de VMware Cloud Provider (vCP).
-
Cree una StorageClass con un formato de disco especificado por el usuario.
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast provisioner: kubernetes.io/vsphere-volume parameters: diskformat: zeroedthick
diskformat
:thin
,zeroedthick
yeagerzeroedthick
. Por defecto:"thin"
. -
Cree una StorageClass con un formato de disco en un almacén de datos especificado por el usuario.
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast provisioner: kubernetes.io/vsphere-volume parameters: diskformat: zeroedthick datastore: VSANDatastore
datastore
: el usuario también puede especificar el almacén de datos en StorageClass. El volumen se creará en el almacén de datos especificado en StorageClass, que en este caso esVSANDatastore
. Este campo es opcional. Si no se especifica el almacén de datos, el volumen se creará en el almacén de datos especificado en el archivo de configuración de vSphere utilizado para inicializar vSphere Cloud Provider. -
Gestión de políticas de almacenamiento dentro de Kubernetes
-
Uso de la política de vCenter SPBM existente
Una de las características más importantes de vSphere for Storage Management es la administración basada en políticas. La gestión basada en políticas de almacenamiento (SPBM) es un marco de políticas de almacenamiento que proporciona un único plano de control unificado en una amplia gama de servicios de datos y soluciones de almacenamiento. SPBM permite a los administradores de vSphere superar los desafíos iniciales de aprovisionamiento de almacenamiento, como la planificación de la capacidad, los niveles de servicio diferenciados y la gestión del margen de capacidad.
Las políticas de SPBM se pueden especificar en StorageClass mediante el parámetro
storagePolicyName
. -
Soporte de políticas Virtual SAN dentro de Kubernetes
Los administradores de Vsphere Infrastructure (VI) tendrán la capacidad de especificar capacidades de almacenamiento Virtual SAN personalizadas durante el aprovisionamiento dinámico de volúmenes. Ahora puede definir los requisitos de almacenamiento, como el rendimiento y la disponibilidad, en forma de capacidades de almacenamiento durante el aprovisionamiento dinámico de volúmenes. Los requisitos de capacidad de almacenamiento se convierten en una política de Virtual SAN que luego se transfiere a la capa de Virtual SAN cuando se crea un volumen persistente (disco virtual). El disco virtual se distribuye en el almacén de datos de Virtual SAN para cumplir con los requisitos.
Puedes ver la Administración basada en políticas de almacenamiento para el aprovisionamiento dinámico de volúmenes para obtener más detalles sobre cómo utilizar las políticas de almacenamiento para la gestión de volúmenes persistentes.
-
Hay pocos ejemplos de vSphere que prueba para la administración persistente de volúmenes dentro de Kubernetes para vSphere.
Ceph RBD
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/rbd
parameters:
monitors: 10.16.153.105:6789
adminId: kube
adminSecretName: ceph-secret
adminSecretNamespace: kube-system
pool: kube
userId: kube
userSecretName: ceph-secret-user
userSecretNamespace: default
fsType: ext4
imageFormat: "2"
imageFeatures: "layering"
-
monitors
: Monitores Ceph, delimitados por comas. Este parámetro es obligatorio. -
adminId
: ID de cliente de Ceph que es capaz de crear imágenes en el grupo. El valor predeterminado es "admin". -
adminSecretName
: Nombre secreto paraadminId
. Este parámetro es obligatorio. El secreto proporcionado debe tener el tipo "kubernetes.io/rbd". -
adminSecretNamespace
: El espacio de nombres paraadminSecretName
. El valor predeterminado es "predeterminado". -
pool
: Grupo Ceph RBD. El valor predeterminado es "rbd". -
userId
: ID de cliente de Ceph que se utiliza para asignar la imagen RBD. El valor predeterminado es el mismo queadminId
. -
userSecretName
: El nombre de Ceph Secret parauserId
para mapear la imagen RBD. Él debe existir en el mismo espacio de nombres que los PVC. Este parámetro es obligatorio. El secreto proporcionado debe tener el tipo "kubernetes.io/rbd", por ejemplo creado de esta manera:kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \ --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \ --namespace=kube-system
-
userSecretNamespace
: El espacio de nombres parauserSecretName
. -
fsType
: fsType que es compatible con Kubernetes. Por defecto:"ext4"
. -
imageFormat
: Ceph RBD formato de imagen, "1" o "2". El valor predeterminado es "2". -
imageFeatures
: Este parámetro es opcional y solo debe usarse si estableceimageFormat
a "2". Las características admitidas actualmente sonlayering
solamente. El valor predeterminado es "" y no hay funciones activadas.
Azure Disk
Clase de almacenamiento Azure Unmanaged Disk
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/azure-disk
parameters:
skuName: Standard_LRS
location: eastus
storageAccount: azure_storage_account_name
skuName
: Nivel de SKU de la cuenta de almacenamiento de Azure. El valor predeterminado está vacío.location
: Ubicación de la cuenta de almacenamiento de Azure. El valor predeterminado está vacío.storageAccount
: Nombre de la cuenta de almacenamiento de Azure. Si se proporciona una cuenta de almacenamiento, debe residir en el mismo grupo de recursos que el clúster y se ignora lalocation
. Si no se proporciona una cuenta de almacenamiento, se creará una nueva cuenta de almacenamiento en el mismo grupo de recursos que el clúster.
Clase de almacenamiento Azure Disk (empezando desde v1.7.2)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/azure-disk
parameters:
storageaccounttype: Standard_LRS
kind: managed
storageaccounttype
: Nivel de SKU de la cuenta de almacenamiento de Azure. El valor predeterminado está vacío.kind
: Los valores posiblesshared
,dedicated
, ymanaged
(por defecto). Cuandokind
esshared
, todos los discos no administrados se crean en algunas cuentas de almacenamiento compartido en el mismo grupo de recursos que el clúster. Cuandokind
esdedicated
, se creará una nueva cuenta de almacenamiento dedicada para el nuevo disco no administrado en el mismo grupo de recursos que el clúster. Cuandokind
esmanaged
, todos los discos administrados se crean en el mismo grupo de recursos que el clúster.resourceGroup
: Especifique el grupo de recursos en el que se creará el disco de Azure. Debe ser un nombre de grupo de recursos existente. Si no se especifica, el disco se colocará en el mismo grupo de recursos que el clúster de Kubernetes actual.
- Premium VM puede conectar discos Standard_LRS y Premium_LRS, mientras que Standard VM solo puede conectar discos Standard_LRS.
- La VM administrada solo puede adjuntar discos administrados y la VM no administrada solo puede adjuntar discos no administrados.
Azure File
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azurefile
provisioner: kubernetes.io/azure-file
parameters:
skuName: Standard_LRS
location: eastus
storageAccount: azure_storage_account_name
skuName
: Nivel de SKU de la cuenta de almacenamiento de Azure. El valor predeterminado está vacío.location
: Ubicación de la cuenta de almacenamiento de Azure. El valor predeterminado está vacío.storageAccount
: Nombre de la cuenta de almacenamiento de Azure. El valor predeterminado está vacío. Si un almacenamiento no se proporciona la cuenta, se buscan todas las cuentas de almacenamiento asociadas con el grupo de recursos para encontrar una que coincida conskuName
ylocation
. Si se proporciona una cuenta de almacenamiento, debe residir en el mismo grupo de recursos que el clúster y se ignoranskuName
ylocation
.secretNamespace
: el espacio de nombres del secreto que contiene el nombre y la clave de la cuenta de Azure Storage. El valor predeterminado es el mismo que el Pod.secretName
: el nombre del secreto que contiene el nombre y la clave de la cuenta de Azure Storage. El valor predeterminado esazure-storage-account-<accountName>-secret
readOnly
: una bandera que indica si el almacenamiento se montará como de solo lectura. El valor predeterminado es falso, lo que significa un montaje de lectura/escritura. Esta configuración también afectará la configuraciónReadOnly
en VolumeMounts.
Durante el aprovisionamiento de almacenamiento, se crea un secreto denominado secretName
para las credenciales de montaje. Si el clúster ha habilitado ambos RBAC y Controller Roles, agregue el permiso de create
de recurso secret
para clusterrole
system:controller:persistent-volume-binder
.
En un contexto de tenencia múltiple, se recomienda enfáticamente establecer el valor para secretNamespace
explícitamente; de lo contrario, las credenciales de la cuenta de almacenamiento pueden ser leído por otros usuarios.
Volumen Portworx
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: portworx-io-priority-high
provisioner: kubernetes.io/portworx-volume
parameters:
repl: "1"
snap_interval: "70"
priority_io: "high"
-
fs
: sistema de archivos a distribuir:none/xfs/ext4
(predeterminado:ext4
). -
block_size
: tamaño de bloque en Kbytes (predeterminado:32
). -
repl
: número de réplicas síncronas que se proporcionarán en forma de factor de replicación1..3
(predeterminado:1
) Aquí se espera una cadena, es decir"1"
y no1
. -
priority_io
: determina si el volumen se creará a partir de un almacenamiento de mayor rendimiento o de menor prioridadhigh/medium/low
(predeterminado:low
). -
snap_interval
: reloj/intervalo de tiempo en minutos para determinar cuándo activar las instantáneas. Las instantáneas son incrementales según la diferencia con la instantánea anterior, 0 desactiva las instantáneas (predeterminado:0
). Aquí se espera una cadena, es decir"70"
y no70
. -
aggregation_level
: especifica el número de fragmentos en los que se distribuiría el volumen, 0 indica un volumen no agregado (predeterminado:0
). Aquí se espera una cadena, es decir,"0"
y no0
-
ephemeral
: especifica si el volumen debe limpiarse después de desmontarlo o si debe ser persistente. El caso de usoemptyDir
puede establecer este valor en verdadero y el caso de uso depersistent volumes
, como para bases de datos como Cassandra, debe establecerse en falso,true/false
(predeterminadofalse
). Aquí se espera una cadena, es decir,"true"
y notrue
.
Local
Kubernetes v1.14 [stable]
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
Actualmente, los volúmenes locales no admiten el aprovisionamiento dinámico; sin embargo, aún se debe crear una StorageClass para retrasar el enlace del volumen hasta la programación del Pod. Esto se especifica mediante el modo de enlace de volumen WaitForFirstConsumer
.
Retrasar el enlace de volumen permite que el programador considere todos los datos de un Pod. restricciones de programación al elegir un PersistentVolume apropiado para un PersistentVolumeClaim.
10 - Capacidad de Almacenamiento
La capacidad de almacenamiento es limitada y puede variar según el nodo en el que un Pod se ejecuta: es posible que no todos los nodos puedan acceder al almacenamiento conectado a la red o que, para empezar, el almacenamiento sea local en un nodo.
Kubernetes v1.21 [beta]
Esta página describe cómo Kubernetes realiza un seguimiento de la capacidad de almacenamiento y cómo el planificador usa esa información para programar Pods en nodos que tienen acceso a suficiente capacidad de almacenamiento para los volúmenes restantes que faltan. Sin el seguimiento de la capacidad de almacenamiento, el planificador puede elegir un nodo que no tenga suficiente capacidad para aprovisionar un volumen y se necesitarán varios reintentos de planificación.
El seguimiento de la capacidad de almacenamiento es compatible con los controladores de la Interfaz de Almacenamiento de Contenedores (CSI) y necesita estar habilitado al instalar un controlador CSI.
API
Hay dos extensiones de API para esta función:
- Los objetos CSIStorageCapacity: son producidos por un controlador CSI en el Namespace donde está instalado el controlador. Cada objeto contiene información de capacidad para una clase de almacenamiento y define qué nodos tienen acceso a ese almacenamiento.
- El campo
CSIDriverSpec.StorageCapacity
: cuando se establece entrue
, el Planificador de Kubernetes considerará la capacidad de almacenamiento para los volúmenes que usan el controlador CSI.
Planificación
El planificador de Kubernetes utiliza la información sobre la capacidad de almacenamiento si:
- la Feature gate de
CSIStorageCapacity
estrue
, - un Pod usa un volumen que aún no se ha creado,
- ese volumen usa un StorageClass que hace referencia a un controlador CSI y usa el [modo de enlace de volumen] (/docs/concepts/storage/storage-classes/#volume-binding-mode)
WaitForFirstConsumer
, y - el objeto
CSIDriver
para el controlador tieneStorageCapacity
establecido entrue
.
En ese caso, el planificador sólo considera los nodos para el Pod que tienen suficiente almacenamiento disponible. Esta verificación es muy simplista y solo compara el tamaño del volumen con la capacidad indicada en los objetos CSIStorageCapacity
con una topología que incluye el nodo.
Para los volúmenes con el modo de enlace de volumen Immediate
, el controlador de almacenamiento decide dónde crear el volumen, independientemente de los pods que usarán el volumen.
Luego, el planificador programa los pods en los nodos donde el volumen está disponible después de que se haya creado.
Para los volúmenes efímeros de CSI, la planificación siempre ocurre sin considerar la capacidad de almacenamiento. Esto se basa en la suposición de que este tipo de volumen solo lo utilizan controladores CSI especiales que son locales a un nodo y no necesitan allí recursos importantes.
Replanificación
Cuando se selecciona un nodo para un Pod con volúmenes WaitForFirstConsumer
, esa decisión sigue siendo tentativa. El siguiente paso es que se le pide al controlador de almacenamiento CSI que cree el volumen con una pista de que el volumen está disponible en el nodo seleccionado.
Debido a que Kubernetes pudo haber elegido un nodo basándose en información de capacidad desactualizada, es posible que el volumen no se pueda crear realmente. Luego, la selección de nodo se restablece y el planificador de Kubernetes intenta nuevamente encontrar un nodo para el Pod.
Limitaciones
El seguimiento de la capacidad de almacenamiento aumenta las posibilidades de que la planificación funcione en el primer intento, pero no puede garantizarlo porque el planificador tiene que decidir basándose en información potencialmente desactualizada. Por lo general, el mismo mecanismo de reintento que para la planificación sin información de capacidad de almacenamiento es manejado por los errores de planificación.
Una situación en la que la planificación puede fallar de forma permanente es cuando un pod usa varios volúmenes: es posible que un volumen ya se haya creado en un segmento de topología que luego no tenga suficiente capacidad para otro volumen. La intervención manual es necesaria para recuperarse de esto, por ejemplo, aumentando la capacidad o eliminando el volumen que ya se creó. Trabajo adicional para manejar esto automáticamente.
Habilitación del seguimiento de la capacidad de almacenamiento
El seguimiento de la capacidad de almacenamiento es una función beta y está habilitada de forma predeterminada en un clúster de Kubernetes desde Kubernetes 1.21. Además de tener la función habilitada en el clúster, un controlador CSI también tiene que admitirlo. Consulte la documentación del controlador para obtener más detalles.
Siguientes pasos
- Para obtener más información sobre el diseño, consulte las Restricciones de Capacidad de Almacenamiento para la Planificación de Pods KEP.
- Para obtener más información sobre un mayor desarrollo de esta función, consulte problema de seguimiento de mejoras #1472.
- Aprender sobre Planificador de Kubernetes
11 - Almacenamiento en Windows
Esta página proporciona una descripción general del almacenamiento específico para el sistema operativo Windows.
Almacenamiento persistente
Windows tiene un controlador de sistema de archivos en capas para montar las capas del contenedor y crear un sistema de archivos de copia basado en NTFS. Todas las rutas de archivos en el contenedor se resuelven únicamente dentro del contexto de ese contenedor.
-
Con Docker, los montajes de volumen solo pueden apuntar a un directorio en el contenedor y no a un archivo individual. Esta limitación no se aplica a containerd.
-
Los montajes de volumen no pueden proyectar archivos o directorios de vuelta al sistema de archivos del host.
-
No se admiten sistemas de archivos de solo lectura debido a que siempre se requiere acceso de escritura para el registro de Windows y la base de datos SAM. Sin embargo, se admiten volúmenes de solo lectura.
-
Las máscaras y permisos de usuario en los volúmenes no están disponibles. Debido a que la base de datos SAM no se comparte entre el host y el contenedor, no hay un mapeo entre ellos. Todos los permisos se resuelven dentro del contexto del contenedor.
Como resultado, las siguientes funcionalidades de almacenamiento no son compatibles en nodos de Windows:
- Montajes de subruta de volumen: solo es posible montar el volumen completo en un contenedor de Windows
- Montaje de subruta de volumen para secretos
- Proyección de montaje en el host
- Sistema de archivos raíz de solo lectura (los volúmenes mapeados todavía admiten
readOnly
) - Mapeo de dispositivos de bloque
- Memoria como medio de almacenamiento (por ejemplo,
emptyDir.medium
configurado comoMemory
) - Características del sistema de archivos como uid/gid; permisos de sistema de archivos de Linux por usuario
- Configuración de permisos de secretos con DefaultMode (debido a la dependencia de UID/GID)
- Soporte de almacenamiento/volumen basado en NFS
- Ampliación del volumen montado (resizefs)
Los volúmenes de Kubernetes habilitan la implementación de aplicaciones complejas, con requisitos de persistencia de datos y uso compartido de volúmenes de Pod, en Kubernetes. La gestión de volúmenes persistentes asociados a un backend o protocolo de almacenamiento específico incluye acciones como la provisión/desprovisión/redimensión de volúmenes, la conexión/desconexión de un volumen de/para un nodo de Kubernetes, y el montaje/desmontaje de un volumen de/para contenedores individuales en un Pod que necesita persistir datos.
Los componentes de gestión de volúmenes se envían como plugin de volumen de Kubernetes. Las siguiente variedad de clases de plugins de volumen de Kubernetes son compatibles en Windows:
-
- Ten en cuenta que los FlexVolumes han sido descontinuados a partir de la versión 1.23.
Plugins de volumen incorporados
Los siguientes plugins incorporados admiten almacenamiento persistente en nodos de Windows:
12 - Límites de Volumen específicos del Nodo
Esta página describe la cantidad máxima de Volúmenes que se pueden adjuntar a un Nodo para varios proveedores de nube.
Los proveedores de la nube como Google, Amazon y Microsoft suelen tener un límite en la cantidad de Volúmenes que se pueden adjuntar a un Nodo. Es importante que Kubernetes respete esos límites. De lo contrario, los Pods planificados en un Nodo podrían quedarse atascados esperando que los Volúmenes se conecten.
Límites predeterminados de Kubernetes
El Planificador de Kubernetes tiene límites predeterminados en la cantidad de Volúmenes que se pueden adjuntar a un Nodo:
Servicio de almacenamiento en la nube | Volúmenes máximos por Nodo |
---|---|
Amazon Elastic Block Store (EBS) | 39 |
Google Persistent Disk | 16 |
Microsoft Azure Disk Storage | 16 |
Límites personalizados
Puede cambiar estos límites configurando el valor de la variable de entorno KUBE_MAX_PD_VOLS y luego iniciando el Planificador. Los controladores CSI pueden tener un procedimiento diferente, consulte su documentación sobre cómo personalizar sus límites.
Tenga cuidado si establece un límite superior al límite predeterminado. Consulte la documentación del proveedor de la nube para asegurarse de que los Nodos realmente puedan admitir el límite que establezca.
El límite se aplica a todo el clúster, por lo que afecta a todos los Nodos.
Límites de Volumen dinámico
Kubernetes v1.17 [stable]
Los límites de Volumen dinámico son compatibles con los siguientes tipos de Volumen.
- Amazon EBS
- Google Persistent Disk
- Azure Disk
- CSI
Para los Volúmenes administrados por in-tree plugins de Volumen, Kubernetes determina automáticamente el tipo de Nodo y aplica la cantidad máxima adecuada de Volúmenes para el Nodo. Por ejemplo:
-
En Google Compute Engine, se pueden adjuntar hasta 127 Volúmenes a un Nodo, según el tipo de Nodo.
-
Para los discos de Amazon EBS en los tipos de instancias M5,C5,R5,T3 y Z1D, Kubernetes permite que solo se adjunten 25 Volúmenes a un Nodo. Para otros tipos de instancias en Amazon Elastic Compute Cloud (EC2), Kubernetes permite adjuntar 39 Volúmenes a un Nodo.
-
En Azure, se pueden conectar hasta 64 discos a un Nodo, según el tipo de Nodo. Para obtener más detalles, consulte Sizes for virtual machines in Azure.
-
Si un controlador de almacenamiento CSI anuncia una cantidad máxima de Volúmenes para un Nodo (usando
NodeGetInfo
), el kube-scheduler respeta ese límite. Consulte las especificaciones de CSI para obtener más información. -
Para los Volúmenes administrados por in-tree plugins que han sido migrados a un controlador CSI, la cantidad máxima de Volúmenes será la que informe el controlador CSI.
13 - Supervisión del Estado del Volumen
Kubernetes v1.21 [alpha]
La supervisión del estado del volumen de CSI permite que los controladores de CSI detecten condiciones de volumen anómalas de los sistemas de almacenamiento subyacentes y las notifiquen como eventos en PVCs o Pods.
Supervisión del Estado del Volumen
El monitoreo del estado del volumen de Kubernetes es parte de cómo Kubernetes implementa la Interfaz de Almacenamiento de Contenedores (CSI). La función de supervisión del estado del volumen se implementa en dos componentes: un controlador de supervisión del estado externo y Kubelet.
Si un controlador CSI admite la función supervisión del estado del volumen desde el lado del controlador, se informará un evento en el PersistentVolumeClaim (PVC) relacionado cuando se detecte una condición de volumen anormal en un volumen CSI.
El controlador de estado externo también observa los eventos de falla del nodo. Se puede habilitar la supervisión de fallas de nodos configurando el indicador enable-node-watcher
en verdadero. Cuando el monitor de estado externo detecta un evento de falla de nodo, el controlador reporta que se informará un evento en el PVC para indicar que los Pods que usan este PVC están en un nodo fallido.
Si un controlador CSI es compatible con la función monitoreo del estado del volumen desde el lado del nodo, se informará un evento en cada Pod que use el PVC cuando se detecte una condición de volumen anormal en un volumen CSI.
CSIVolumeHealth
feature gate para usar esta función desde el lado del nodo.
Siguientes pasos
Ver la documentación del controlador CSI para averiguar qué controladores CSI han implementado esta característica.