Como usar o kubernetes-client para executar “kubectl apply”

Dec 16 2020

Eu tenho um script Python que basicamente executa os três comandos a seguir :

kubectl apply -f class.yaml
kubectl apply -f rbac.yaml
kubectl apply -f deployment-arm.yaml

Quero usar o cliente kubernetes escrito em Python para substituí-lo. Meu código atual carrega os arquivos yaml (usando pyyaml), edita-os um pouco, insere em um arquivo e usa a linha de comando kubectl para executar esses três comandos. Parte do código:

# load files, edit them and dump into new files, part ...
result = run(['kubectl', 'apply', '-f', class_file_path])
# status check part ...
result = run(['kubectl', 'apply', '-f', rbac_file_path])
# status check part ...
result = run(['kubectl', 'apply', '-f', deployment_file_path])
# status check part ...

O que eu quero fazer: substituir esses três comandos pelo python kubernetes-client. Lendo a documentação e vendo o tópico , me deparei com o create_namespaced_deploymentmétodo que acho que devo usar para o deployment_file_patharquivo. Mas não consigo descobrir o que preciso fazer com os outros dois arquivos.

Supondo que eu já carregado os três arquivos YAML (usando PyYAML) e editado-los (sem despejar em novos arquivos) e agora você tem dicts yaml livres deployment_dict, class_dicte rbac_dict, Como posso usar o cliente para executar os três acima métodos?

EDIT : BTW, se não for possível passar os três dicts, eu poderia simplesmente despejá-los em arquivos novamente, mas quero usar o cliente Python em vez do kubectl. Como fazer isso?

Respostas

1 anemyte Dec 23 2020 at 16:35

Existe uma função separada para cada objeto e ação:

from kubernetes import client, config
import yaml

body = yaml.safe_load("my_deployment.yml")
config.load_kube_config()
apps_api = client.AppsV1Api()
apps_api.create_namespaced_deployment(body=body, namespace="default")
apps_api.replace_namespaced_deployment(body=body, namespace="default")
apps_api.patch_namespaced_deployment(body=body, namespace="default")
apps_api.delete_namespaced_deployment(body=body, namespace="default")

body = yaml.safe_load("my_cluster_role.yml")
rbac_api = client.RbacAuthorizationV1Api()
rbac_api.create_cluster_role(body=body)
rbac_api.patch_cluster_role(body=body)
rbac_api.replace_cluster_role(body=body)
rbac_api.delete_cluster_role(body=body)

# And so on

Quando você usa kubectl applyvocê não se importa se o objeto já existe, qual API usar, qual método aplicar, mas com o cliente você terá que fazer. Como você pode ver no exemplo, você precisa:

  1. Carregar kube-config.
  2. Selecione a API certa para usar (crie um objeto somente depois de carregar a configuração).
  3. Selecione o método que deseja usar. Observe que create_somethingnão funcionará se o somethingjá existir.

Graças ao padrão de nomenclatura estrito, é fácil obter a função necessária do cliente usando

getattr(some_k8s_api, f"{verb}_{namespaced_or_not}_{kind.lower()}")

Recomendo que você passe pelos exemplos que a biblioteca fornece, eles realmente são ótimos para aprender a coisa.

JanosVinceller Dec 29 2020 at 05:07

Não tenho ideia, mas em algum lugar eu vi isso:

cat <<EOF | kubectl apply -f -
<<here the content of the yaml>>
EOF

E se isso funciona, isso funciona?

cat class.yaml rbac.yaml deployment-arm.yaml | kubectl apply -f -