Fortaleça os recursos do Kubernetes: use o CRD para definir a implementação de recursos de várias versões

Canwu Yao, engenheiro de P&D da Rancher China, tem 7 anos de experiência na área de computação em nuvem, é apaixonado por tecnologia de código aberto e tem uma rica experiência prática e de desenvolvimento na área de tecnologias relacionadas à nuvem nativa.

CRD, ou Custom Resource Definition, é um poderoso mecanismo de extensão na API do Kubernetes. Por meio do CRD, os usuários podem definir seus próprios tipos de recursos para estender a API e os tipos de recursos do Kubernetes. As definições CRD podem ser usadas para criar várias versões de recursos, o que é útil para a evolução e atualizações do cluster Kubernetes.

Neste artigo, apresentaremos o conceito de versão e o uso do Kubernetes CRD; discutiremos como definir várias versões de recursos no CRD e discutiremos a implementação do armazenamento e conversão de dados de recursos. Por fim, abordaremos como desenvolver um webhook CRD para compatibilidade de versão CRD no Kubernetes.

CRD multi-versão

O CRD multiversão refere-se à definição de várias versões da API no CRD, e cada versão da API pode ter suas próprias regras, para que a nova versão do aplicativo possa ser atualizada e atualizada sem afetar a versão antiga do aplicativo.

Para criar um CRD de várias versões, precisamos definir um objeto Custom Resource Definition que contenha vários campos de versão. Cada campo de versão possui um esquema, que contém propriedades e regras para recursos personalizados.

Para ilustrar a título de exemplo, o seguinte é um exemplo de CRD de versão única:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: foos.sample.webhook.io
spec:
  conversion:
    strategy: None
  group: sample.webhook.io
  names:
    kind: Foo
    listKind: FooList
    plural: foos
    shortNames:
    - foo
    - foos
    singular: foo
  scope: Namespaced
  versions:
  - name: v1
    schema:
      openAPIV3Schema:
        properties:
          apiVersion:
            type: string
          kind:
            type: string
          metadata:
            type: object
        type: object
    served: true
    storage: true

O arquivo especifica informações de versão, nome do recurso, tipo e outras informações. Por meio do comando kubectl apply, o arquivo CRD pode ser aplicado ao cluster Kubernetes para criar um novo tipo de recurso Foo no cluster, por exemplo:

apiVersion: sample.webhook.io/v1
kind: Foo
metadata:
  name: foo-sample

O recurso personalizado Foo acima tem apenas uma versão v1. Se precisarmos atualizar um campo no recurso personalizado, precisamos atualizar a versão de Foo. Por exemplo, para atualizar para a versão v2, precisamos adicionar a definição da versão v2 no arquivo CRD, por exemplo:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
    name: foos.sample.webhook.io
spec:
    versions:
    - name: v1
      schema:
        openAPIV3Schema:
          properties:
            apiVersion:
              type: string
            kind:
              type: string
            metadata:
              type: object
          type: object
      served: true
      storage: false
    - name: v2
      schema:
        openAPIV3Schema:
          properties:
            alias:
              type: string
            apiVersion:
              type: string
            kind:
              type: string
            metadata:
              type: object
          type: object
      served: true
      storage: true

No arquivo CRD acima, definimos duas versões, v1 e v2. Comparado com v1, v2 adiciona um campo de alias.

armazenamento de dados de recursos

Para garantir que o Kubernetes possa manter corretamente os recursos personalizados no armazenamento e possa ler e restaurar corretamente os recursos personalizados do armazenamento. O campo spec.versions.storage é definido no CRD, que é usado para indicar qual versão do CRD persiste no armazenamento. Em uma definição de CRD, apenas uma versão do campo de armazenamento tem o valor true.

No exemplo acima, definimos duas versões, v1 e v2. O campo de armazenamento da versão v1 é falso e o campo de armazenamento da versão v2 é verdadeiro, o que indica que os dados de recursos da versão v2 são armazenados no Kubernetes etcd.

Então, como armazenar os dados da versão não selecionada? Tomando o  foo-sample exemplo acima, vamos ver como ele é armazenado no etcd. Os resultados são os seguintes:

/registry/sample.webhook.io/foos/default/foo-sample
{"apiVersion":"sample.webhook.io/v2","kind":"Foo","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"sample.webhook.io/v1\",\"kind\":\"Foo\",\"metadata\":{\"annotations\":{},\"name\":\"foo-sample\",\"namespace\":\"default\"}}\n"},"creationTimestamp":"2023-05-22T09:49:03Z","generation":1,"managedFields":[{"apiVersion":"sample.webhook.io/v1","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration":{}}}},"manager":"kubectl-client-side-apply","operation":"Update","time":"2023-05-22T09:49:03Z"}],"name":"foo-sample","namespace":"default","uid":"3360f129-31f7-4a3f-8991-7694524d9a78"}}

A primeira linha é  foo-sample a chave e a segunda linha é  foo-sample o conteúdo expresso no formato json, onde  apiVersion é  sample.webhook.io/v2, que indica que mesmo os recursos da versão v1 são armazenados no formato da versão v2.

conversão de dados

Quando um recurso personalizado oferece suporte a várias versões, porque só pode ser armazenado em um determinado formato de versão, é necessário converter entre a versão armazenada e a versão fornecida para obter compatibilidade com várias versões.

  • Se a transição envolver alterações de esquema e exigir lógica personalizada, ela deverá ser feita usando webhooks. Um exemplo de configuração do webhook no CRD é o seguinte:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
...
spec:  
  conversion:    
      strategy: Webhook    
      webhook:      
          clientConfig:        
            caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJ2akNDQVdPZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQkdNUnd3R2dZRFZRUUtFeE5rZVc1aGJXbGoKYkdsemRHVnVaWEl0YjNKbk1TWXdKQVlEVlFRRERCMWtlVzVoYldsamJHbHpkR1Z1WlhJdFkyRkFNVFk0TkRjegpPRGswTXpBZUZ3MHlNekExTWpJd056QXlNak5hRncwek16QTFNVGt3TnpBeU1qTmFNRVl4SERBYUJnTlZCQW9UCkUyUjVibUZ0YVdOc2FYTjBaVzVsY2kxdmNtY3hKakFrQmdOVkJBTU1IV1I1Ym1GdGFXTnNhWE4wWlc1bGNpMWoKWVVBeE5qZzBOek00T1RRek1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRUZYWDQzaEZRdjRyOApKelR1UkJ0b3lqUmRtWjhIRkExbWZnOXJnTWVlNnVXZ20wMXBNR3lSRnFna3Z1RHF5RUlMTUtCRDduQ2IrVFp3CitBR3loVWhTV0tOQ01FQXdEZ1lEVlIwUEFRSC9CQVFEQWdLa01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWUQKVlIwT0JCWUVGRzg2VnpCcW1wRUcrUWlrS0d1SGNIQlJwS2R3TUFvR0NDcUdTTTQ5QkFNQ0Ewa0FNRVlDSVFDaQp5SFFyeGNXN3dUM0dwRWhyNklQQWpXWDVJOSt4Y0dkUGQzQURKS0hwZ2dJaEFJQmhTc00xd1hxMU80VUlaWWZwCkNWVkxwaCtvUVMvMzI5OHMwS0VqWW9FTAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==        
            service:          
                name: webhook-sample          
                namespace: default          
                path: /v1/webhook/conversion          
                port: 443      
              conversionReviewVersions:      
              - v1
  • Caso não haja alterações no esquema, pode ser utilizada a estratégia de conversão padrão  , onde apenas  os campos são alterados None ao atender diferentes versões  .apiVersion
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
...
spec:
  ...
  conversion:
    strategy: None

Desenvolvimento de webhook CRD

Assim como  o Admission Webhook , o webhook CRD também é um retorno de chamada HTTP e o serviço webhook é um serviço HTTP. A estrutura da interface é a seguinte:

// ConversionReview describes a conversion request/response.
type ConversionReview struct {
    metav1.TypeMeta `json:",inline"`
    // request describes the attributes for the conversion request.
    // +optional
    Request *ConversionRequest `json:"request,omitempty" protobuf:"bytes,1,opt,name=request"`
    // response describes the attributes for the conversion response.
    // +optional
    Response *ConversionResponse `json:"response,omitempty" protobuf:"bytes,2,opt,name=response"`
}

A equipe do projeto Harvester  adicionou suporte de webhook CRD à  estrutura de webhook do harvesterConverter . Os desenvolvedores só precisam implementar  a interface e registrá-la no servidor webhook e, em seguida, iniciar o servidor webhook.

// Converter is a interface to convert object to the desired version
type Converter interface {
    GroupResource() schema.GroupResource
    Convert(Object *unstructured.Unstructured, desiredAPIVersion string) (*unstructured.Unstructured, error)
}

Para obter detalhes de desenvolvimento específicos, consulte o  exemplo de exemplo de webhook .

Resumir

No processo de evolução real do produto, a compatibilidade de várias versões sempre foi uma questão importante. Kubernetes CRD adota uma estratégia de selecionar uma determinada versão para persistência e usar o webhook para realizar a conversão de dados de várias versões para resolver problemas de compatibilidade de várias versões. Também vale a pena aprender com essa estratégia em outros projetos fora do Kubernetes.

referir-se

Versões em definições de recursos personalizados: https://kubernetes.io/zh-cn/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning

Esclarecimento sobre MyBatis-Flex plagiando o navegador MyBatis-Plus Arc lançado oficialmente 1.0, alegando ser um substituto para o Chrome OpenAI lançado oficialmente versão Android ChatGPT VS Code otimizado compactação de ofuscação de nome, JS integrado reduzido em 20%! LK-99: O primeiro supercondutor de temperatura e pressão ambiente? Musk "comprou por zero yuan" e roubou a conta @x no Twitter. O Python Steering Committee planeja aceitar a proposta PEP 703, tornando o bloqueio global do interpretador opcional . O número de visitas ao código aberto do sistema e ao software gratuito de captura de pacotes Stack Overflow caiu significativamente, e Musk disse que foi substituído por LLM
{{o.name}}
{{m.name}}

Acho que você gosta

Origin my.oschina.net/rancher/blog/10092268
Recomendado
Clasificación