O que são as definições de recursos personalizados (CRDs) do Kubernetes?

0
18


Definições de recursos personalizados (CRDs) são extensões da API do Kubernetes que podem definir novos tipos de objetos. Pods, ReplicaSets, ConfigMaps e Ingresses são exemplos de recursos integrados comuns. Os CRDs permitem adicionar tipos totalmente novos a essa lista e gerenciá-los com ferramentas conhecidas do Kubernetes, como o Kubectl.

O mecanismo CRD é intencionalmente abstrato e pode ser usado de inúmeras maneiras para armazenar dados e criar novas funções. Você encontrará recursos personalizados em muitas ferramentas populares da comunidade: Cert-Manager define objetos que representam certificados e emissores SSL, enquanto o Helm renderiza gráficos como seu próprio CRD.

O que um recurso faz?

Os recursos do Kubernetes definem os tipos de dados que você pode armazenar em seu cluster. Eles são acessados ​​por meio da API do Kubernetes, que fornece endpoints para criar, listar e modificar itens em cada tipo de recurso.

Você pode adicionar recursos personalizados para armazenar seus próprios dados arbitrários em seu cluster. Os elementos que você criar serão armazenados pelo componente do plano de controle etcd, juntamente com instâncias de recursos internos. A API exibe recursos personalizados automaticamente, para que você não precise configurar suas próprias ferramentas para instanciar elementos.

Os CRDs atuam como estruturas de dados simples por padrão. Embora os CRDs na natureza geralmente tenham seus próprios comportamentos, o mecanismo de CRD não fornece isso. Os controladores e operadores personalizados do Kubernetes podem ser usados ​​para implementar funções em torno de recursos personalizados. Sem um controlador, os elementos de um CRD sempre existirão como dados estáticos no cluster com os quais você pode interagir por meio de endpoints CRUD fornecidos pela API do Kubernetes.

CRDs são componentes dinâmicos que podem ser criados e excluídos a qualquer momento. Alguns tipos de objetos fornecidos com o Kubernetes também são implementados como CRDs, fornecendo mais modularidade dentro do núcleo do cluster.

Criando um CRF

Os CRDs são eles próprios um tipo de objeto Kubernetes. Você os cria da mesma forma que faria com qualquer outro recurso, escrevendo um arquivo YAML e aplicando-o ao seu cluster:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: custom-apps.crds.example.com
spec:
  group: crds.example.com
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                app-name:
                  type: string
                app-version:
                  type: string
                release-count:
                  type: integer
  scope: Namespaced
  names:
    plural: custom-apps
    singular: custom-app
    kind: CustomApp

Use o Kubectl para adicionar o CustomApp CRD ao seu cluster:

$ kubectl apply -f custom-apps-crd.yaml
customresourcedefinition.apiextensions.k8s.io/custom-apps.crds.example.com created

O arquivo YAML define um CRD que pode ser usado para armazenar dados sobre aplicativos. Os CRDs precisam de um metadata.name S spec.group campo em um formato preciso: o grupo assume a forma de um subdomínio ao qual o CRD pertence. O mesmo subdomínio deve ser incluído nos CRD’s metadata.name . O valor de names.plural é anexado como um novo componente de subdomínio para construir o final metadata.name.

a spec.names O campo define como você fará referência ao CRD ao usar a API do Kubernetes e os comandos do Kubectl. Neste exemplo, você pode executar kubectl get custom-apps S kubectl get custom-app/example-app para interagir com objetos usando o CRD. Ao criar um novo objeto como um arquivo YAML, você precisa definir kind: CustomApp para convertê-lo em uma instância do CRD.

O CRD é configurado como um tipo de objeto em nível de namespace pelo scope campo. Você pode usar Cluster como um valor alternativo para este campo para criar objetos que existem no nível do cluster, fora de qualquer namespace.

Os dados associados aos seus objetos personalizados são definidos no spec.versions.schema.openAPIV3Schema campo. Cada “versão” listada cria uma nova versão da API CRD que você pode referenciar com o apiVersion campo em seus arquivos YAML de recursos. Os dados CRD são configurados usando as propriedades OpenAPI; aqui, todo “aplicativo personalizado” em seu cluster deve ter app-name, app-versionS release-count propriedades definidas em seu YAML spec.

Usando seu CRD

Pode levar alguns minutos para que os endpoints da API de um novo CRD sejam provisionados. Verifique o progresso recuperando os detalhes do CRD com o Kubectl:

$ kubectl describe crd custom-apps.crds.example.com
...
Status:
  Accepted Names:
    Kind:       CustomApp
    List Kind:  CustomAppList
    Plural:     custom-apps
    Singular:   custom-app
  Conditions:
    Last Transition Time:  2022-04-04T13:29:24Z
    Message:               no conflicts found
    Reason:                NoConflicts
    Status:                True
    Type:                  NamesAccepted
    Last Transition Time:  2022-04-04T13:29:24Z
    Message:               the initial names have been accepted
    Reason:                InitialNamesAccepted
    Status:                True
    Type:                  Established
...

O CRD está pronto para uso quando você vê Type: Established perto do final da saída do comando. O Kubernetes aceitará solicitações para o endpoint da API CRD. Nesse caso, a URL base da API será a seguinte:

/apis/custom-apps.crds.example.com/v1/namespaces/*/custom-apps/...

Agora você pode usar o Kubectl para ver os objetos que foram criados com o CRD:

$ kubectl get custom-apps
No resources found in default namespace.

Embora ainda não existam objetos, o Kubernetes agora sabe que tem um tipo de recurso chamado custom-apps.

Para criar um objeto “aplicativo personalizado”, escreva um novo arquivo YAML com kind: CustomApp. a apiVersion deve ser definido para o nome do grupo e a versão da API fornecida pelo CRD. Dentro de spec seção, inclua as propriedades que você definiu no esquema CRD.

apiVersion: crds.example.com/v1
kind: CustomApp
metadata:
  name: demo-app-1
spec:
  app-name: demo-app
  app-version: 1.1.0
  release-count: 5

Use o Kubectl para adicionar o objeto ao seu cluster:

$ kubectl apply -f custom-app.yaml
customapp.crds.example.com/demo-app created

Agora você pode recuperar os detalhes do objeto usando os comandos familiares do Kubectl:

$ kubectl describe custom-app/demo-app-1
Name:         demo-app
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  crds.example.com/v1
Kind:         CustomApp
...
Spec:
  App - Name:       demo-app
  App - Version:    1.1.0
  Release - Count:  5
...
Events:             <none>

Você tem um recurso personalizado em execução que agora armazena alguns dados em seu cluster Kubernetes. Você pode remover o CRD removendo-o no Kubectl; isso limpará automaticamente todos os objetos que o utilizam.

$ kubectl delete crd custom-apps.crds.example.com
customresourcedefinition.apiextensions.k8s.io "custom-apps.crds.example.com" deleted

Construindo APIs declarativas com CRD

Este CRD não adiciona nenhuma funcionalidade ao cluster. Ele armazena dados, fornece uma API para interagir com eles e pode ser referenciado por outros objetos. Os CRDs se tornam mais poderosos quando combinados com um controlador personalizado que pode assumir a responsabilidade de gerenciá-los.

Os controladores rastreiam recursos e agem em resposta a seus eventos. Escrever um manipulador para seus CRDs permite transformá-los em APIs declarativas que causam mudanças reais em seu cluster. Seus objetos podem representar o desejado estado, em vez do estado atual exato.

O Cert-Manager usa esse modelo para adquirir certificados SSL automaticamente quando novos objetos CertificateRequest aparecem em seu cluster. No núcleo do Kubernetes, os nós extraem e executam imagens de contêiner em resposta à aparência dos pods. Os controladores permitem que você anexe comportamentos aos seus próprios CRDs, portanto, adicionar um “aplicativo personalizado” pode fazer com que sua configuração seja extraída de um serviço externo. Você pode começar a criar controladores usando o Go SDK para integrar seu próprio código ao tempo de execução do Kubernetes.

Quando usar CRD?

Os CRDs são melhor usados ​​para lidar com dados internos de sua organização, equipe ou projeto. Eles são projetados para representar esquemas claramente definidos, seja como valores estáticos ou APIs declarativas apoiadas por uma implementação de controlador personalizado.

Recursos avançados permitem que você implemente rotinas de validação para os campos em seu esquema. Você também pode usar finalizadores para lidar com exclusões de objetos e adotar o sistema de controle de versão para lidar com alterações em suas definições de CRD.

Às vezes, os CRDs se sobrepõem aos ConfigMaps do Kubernetes. Esses são objetos integrados para armazenar dados de configuração genéricos associados aos seus aplicativos. Um ConfigMap é apropriado quando você vai consumir os valores em um local específico do seu cluster, como um pod que acessa as configurações do banco de dados como variáveis ​​de ambiente injetadas de um ConfigMap.

Os CRDs devem ser usados ​​quando os dados precisam ser um cidadão de primeira classe em seu cluster. Você pode criar várias instâncias do tipo de recurso CRD, interagir diretamente com elas usando o Kubectl e criar seus próprios esquemas estruturados que orientam os usuários a inserir os valores corretos. Eles podem ser uma escolha melhor quando os dados existem independentemente de qualquer outra coisa em seu cluster.

Resumo

As definições de recursos personalizados (CRDs) do Kubernetes definem novos tipos de objetos que você pode usar com a API do Kubernetes e o Kubectl. Cada CRD obtém sua própria API com versão, possui um esquema estruturado e pode ser usado para implementar novas funcionalidades no cluster quando apoiado por um driver complementar.

Os CRDs às vezes podem parecer complicados e reservados para situações avançadas. Este não tem que ser o caso. CRDs simples para armazenar valores estáticos em seu cluster são fáceis de criar, conforme ilustrado no exemplo de “aplicativo personalizado” acima. Eles podem ser usados ​​para armazenar dados de cluster separados para tratamento de primeira classe no Kubernetes.

Também é importante reconhecer onde os CRDs não são adequados. Objetos integrados como ConfigMaps e Secrets são projetados para acomodar a maioria das formas de configuração que os Pods do seu aplicativo usarão diretamente. Escrever um CRD que defina o esquema do arquivo de configuração do seu aplicativo geralmente é desnecessário e mais difícil de manter ao longo do tempo, pois você não se beneficiará dos recursos do ConfigMap, como atualizações contínuas automáticas e injeção de variável de ambiente.