O Kubernetes CSI é uma implementação específica do Kubernetes da Container Storage Interface (CSI). A especificação CSI fornece um padrão que permite a conectividade entre sistemas de storage e plataformas de orquestração de contêineres (CO). É a base do gerenciamento de storage do Kubernetes.
O padrão CSI determina como blocos arbitrários e sistemas de storage de arquivos são expostos a workloads em sistemas de conteinerização como Kubernetes. Fornecedores de storage de terceiros podem usar o CSI para criar plug-ins e implantá-los para permitir que Kubernetes funcione com novos sistemas de storage, sem precisar editar o código principal do Kubernetes.
Neste artigo:
Antes da Container Storage Interface, o Kubernetes só dava suporte ao uso de plug-ins de volume k8s na árvore, que precisavam ser escritos e implantados usando binários principais do Kubernetes. Isso significava que os provedores de storage tinham que verificar a base de código principal de seus plug-ins k8s para habilitar o suporte a novos sistemas de storage.
O Flex-volume, uma solução baseada em plug-ins, tentou resolver esse problema expondo a API baseada em executável a plug-ins de terceiro. Embora essa solução operasse de acordo com um princípio semelhante ao do CSI em termos de desprendimento dos binários k8s, havia vários problemas com essa abordagem. Primeiro, exigia acesso à raiz ao sistema de arquivos mestre e host para permitir a implantação de arquivos de driver. Segundo, vinha com uma carga significativa de dependências e pré-requisitos do sistema operacional que se supunha estarem disponíveis no host.
A CSI aborda esses problemas usando a conteinerização e aproveitando as primitivas de armazenamento do k8s. A CSI se tornou a solução onipresente para permitir o uso de plug-ins de armazenamento fora da árvore. Ela permite que os provedores de armazenamento implantem plug-ins por meio de primitivos padrão do k8s, como classes de armazenamento, PersistentVolumes (PVs) e PersistentVolumeClaims (PVCs).
O principal objetivo do CSI é padronizar o mecanismo para expor todos os tipos de sistemas de storage em cada orquestrador de contêineres.
Conteúdo relacionado: Leia nosso guia sobre Kubernetes Persistent Volumes
Um volume CSI pode ser usado para provisionar recursos PersistentVolume, que podem ser consumidos por cargas de trabalho do Kubernetes. Você pode provisionar PersistentVolumes dinamicamente (quando eles são solicitados por uma carga de trabalho) ou manualmente.
Você pode criar um StorageClass que faz referência a um plug-in de armazenamento CSI. Isso permite que as cargas de trabalho do Kubernetes criem PersistentVolumes dinamicamente. Os dados salvos nesses PersistentVolumes são mantidos no equipamento de armazenamento definido no plug-in CSI.
Por exemplo, o seguinte StorageClass permite o provisionamento de volumes de storage do tipo "fast-storage", usando um plug-in CSI chamado "csi-driver.example.com". (Este e os outros exemplos abaixo foram compartilhados na postagem oficial do blog do Kubernetes CSI )
Quando uma entidade do Kubernetes cria um objeto PersistentVolumeClaim que solicita este StorageClass, um PersistentVolume pertencente ao StorageClass é provisionado dinamicamente. A imagem abaixo contém um exemplo de um PVC que faz referência ao fast-storage StorageClass.
Observe que na definição de StorageClass acima há três parâmetros: type e dois segredos chamados mysecret e mynamespace. Quando o PVC é declarado, veja o que acontece nos bastidores:
Leia nosso post no blog: Provisionamento dinâmico de volumes persistentes do Kubernetes com NetApp Trident e Cloud Volumes ONTAP
Você pode provisionar manualmente um volume no Kubernetes e disponibilizá-lo para cargas de trabalho sem usar o mecanismo PVC. A imagem abaixo fornece um exemplo de um objeto PV que permite que cargas de trabalho usem um volume de armazenamento chamado “existingVolumeName”. Como acima, o volume CSI faz referência ao plugin de armazenamento csi-driver.example.com.
A imagem abaixo fornece um exemplo que mostra como um modelo de pod do Kubernetes pode fazer referência a um PVC para acessar um volume CSI.
Quando a PersistenVolumeClaim aparece no modelo de pod, sempre que o pod é programado, o Kubernetes aciona várias operações no plug-in CSI, incluindo ControllerPublishVolume, NodeStageVolume e NodePublishVolume. Isso cria um volume de armazenamento, monta-o e o torna disponível para uso por contêineres em execução no pod.
Os drivers CSI no Kubernetes normalmente são implantados com componentes de controlador e por nó.
Componente do controlador
O plug-in do controlador é implantado como uma Deployment ou um StatefulSet e pode ser montado em qualquer nó dentro do cluster. Ele compreende um driver CSI que implementa um serviço CSI Controller, bem como um contêiner sidecar (ou múltiplos contêineres). Um contêiner sidecar do controlador geralmente interage com objetos do Kubernetes e também faz chamadas para o serviço CSI Controller.
O controlador não requer acesso direto a um host - ele pode realizar todas as operações por meio de serviços externos do plano de controle e da API do Kubernetes. É possível implantar várias cópias de um componente do controlador para alta disponibilidade (HA), mas você deve implementar a eleição de líder para garantir que apenas um controlador esteja ativo em um determinado momento.
Entre os sidecars do controlador estão um external-provisioner, um external-attacher, um external-snapshotter e um external-resizer. A inclusão de determinados sidecars em uma implantação pode ser opcional, dependendo das especificações detalhadas na página do sidecar.
O controlador se comunica com contêineres sidecar que têm a tarefa de gerenciar eventos do Kubernetes. O controlador então envia chamadas relevantes para o driver CSI. Um soquete de domínio UNIX é compartilhado por meio de um emptyDir volume, permitindo as chamadas entre sidecars e o driver.
Os sidecars do controlador usam regras de controle de acesso baseado em funções (RBAC) para governar sua interação com objetos do Kubernetes. Os repositórios de sidecar fornecem exemplos de configurações de RBAC que você pode incorporar às suas políticas de RBAC.
Componente por nó
O plug-in de nó deve ser implantado em todos os nós de um cluster, por meio de um DaemonSet. Ele compreende o driver CSI que implementa o serviço CSI Node e o contêiner sidecar que serve como registrador de driver de nó.
O componente de nó se comunica com o kubelet, que é executado em todos os nós e lida com chamadas para o serviço CSI Node. As chamadas podem montar ou desmontar volumes de armazenamento de um sistema de storage e disponibilizá-los para o pod consumir. O kubelet usa um soquete de domínio UNIX, que é compartilhado por meio de um volume HostPath no host, para fazer chamadas para o driver CSI. Um soquete de domínio UNIX adicional é usado pelo node-driver-registrar para registrar o driver no kubelet.
O plug-in de nó requer acesso direto a um host para montar volumes de driver. Para disponibilizar montagens de sistema de arquivos e dispositivos de bloco para o kubelet, o driver CSI precisa usar um ponto de montagem bidirecional que permita que o kubelet veja as montagens criadas pelo contêiner do driver.
O Kubernetes não determina o empacotamento de um driver de volume CSI, mas fornece recomendações para simplificar a implantação de drivers CSI em contêineres no Kubernetes.
Os fornecedores de armazenamento são aconselhados a seguir as seguintes etapas ao implantar um driver de volume CSI em contêiner:
Outra opção para uma possível implantação mais simples é ter todos os componentes em um único DaemonSet, incluindo o external-provisioner e o external-attacher. No entanto, essa estratégia consome mais recursos e requer o uso de um protocolo de eleição de líder (como https://git.k8s.io/contrib/election) para os componentes external-attacher e external-provisioner.
O cluster do Kubernetes deve habilitar pods privilegiados para permitir o uso de drivers CSI. Por exemplo, você precisa definir a sinalização --allow-privileged como true para o kubelet e o servidor de API—em determinados ambientes, como kubeadm, GCE e GKE, esse é o padrão.
O servidor de API deve ser iniciado com os seguintes sinalizadores privilegiados:
$ ./kube-apiserver ... --allow-privileged=true ... $ ./kubelet ... --allow-privileged=true ...
A Interface de Storage de Contêiner requer um recurso de propagação de montagem que permite que volumes montados sejam compartilhados entre contêineres dentro do mesmo nó ou pod. O daemon do Docker para um cluster precisa permitir o compartilhamento de montagem para habilitar a propagação de montagem.
NetApp Cloud Volumes ONTAP, a solução de gerenciamento de storage de nível empresarial líder do setor, oferece serviços de gerenciamento de storage seguros e comprovados na AWS, Azure e Google Cloud. A capacidade do Cloud Volumes ONTAP pode ser dimensionada para petabytes e oferece suporte a vários casos de uso, como serviços de arquivos, bancos de dados, DevOps ou qualquer outro workload empresarial, com um forte conjunto de recursos, incluindo alta disponibilidade, proteção de dados, eficiências de storage, integração com Kubernetes e muito mais.
Em particular, o Cloud Volumes ONTAP é compatível com provisionamento e gerenciamento de volumes persistentes do Kubernetes para workloads em contêineres.
Saiba mais sobre Kubernetes NFS Provisioning File Services com Cloud Volumes ONTAP e Trident.
Saiba mais sobre como o Cloud Volumes ONTAP ajuda a enfrentar os desafios das aplicações em contêineres nestes Kubernetes Workloads com Cloud Volumes ONTAP Case Studies.