Kubernetes - compartilhando segredo entre namespaces

101

Existe uma maneira de compartilhar segredos entre namespaces no Kubernetes?

Meu caso de uso é: tenho o mesmo registro privado para todos os meus namespaces e desejo evitar a criação do mesmo segredo para cada um.

Obrigado pela ajuda.

Matth3o
fonte
isso automatiza o compartilhamento de segredo: github.com/zakkg3/ClusterSecret
NicoKowe

Respostas:

93

Os objetos da API secreta residem em um namespace. Eles só podem ser referenciados por pods no mesmo namespace. Basicamente, você terá que criar o segredo para cada namespace.

https://kubernetes.io/docs/concepts/configuration/secret/#details

Innocent Anigbo
fonte
4
O mesmo para configmaps. kubernetes.io/docs/tasks/configure-pod-container/…
Breedly
1
Essa é a resposta correta, vale a pena mencionar que você pode clonar para outro namespace por kubectl + sed, tudo em uma linha, veja minha resposta abaixo.
NicoKowe
75

Eles só podem ser referenciados por pods no mesmo namespace. Mas você pode simplesmente copiar o segredo de um espaço de nome para outro. Aqui está um exemplo de cópia do localdockerregsegredo do defaultnamespace para dev:

 kubectl get secret localdockerreg --namespace=default --export -o yaml | kubectl apply --namespace=dev -f -

### UPDATE ### No Kubernetes v1.14, a --exportsinalização está obsoleta . Portanto, o seguinte comando com -oyamlsinalizador funcionará sem aviso nas próximas versões.

kubectl get secret localdockerreg --namespace=default -oyaml | kubectl apply --namespace=dev -f -

ou abaixo, se o namespace de origem não for necessariamente padrão

kubectl get secret localdockerreg --namespace=default -oyaml | grep -v '^\s*namespace:\s' | kubectl apply --namespace=dev -f -
Hansika Madushan Weerasena
fonte
1
Isso não funcionará se os segredos dos quais você está exportando não estiverem no namespace padrão
gerasalus
1
Funciona para mim em quaisquer dois namespaces na v1.13
Kshitij Saraogi
4
Hmm, quando eu uso o segundo comando (sem --exportsinalizador), recebo um erro dizendo "o namespace da opção fornecida não corresponde". kubectl versão 1.15. Acho que você pode precisar usar sedou algo entre esses dois kubectlcomandos para remover o namespace da saída yaml
Matt Dodge
6
Para ser mais preciso, você precisa remover o namespace de origem do YAML intermediário: $ kubectl get secret <SECRET> --namespace <NS-SRC> -oyaml | grep -v '^\s*namespace:\s' | kubectl apply --namespace <NS-DST> -f - ps não testado com outros tipos de objeto, mas deve funcionar pps, não se esqueça de excluir a origem se estiver mudando
Costa Shapiro
funciona e muda o contexto com kubectl use contexto se entre clusters
Vincent Gerris
17

A resposta aceita está correta. Aqui está uma dica se você deseja copiar o segredo entre namespaces.

kubectl get secret <secret-name> -n <source-namespace> -o yaml \
| sed s/"namespace: <source-namespace>"/"namespace: <destination-namespace>"/\
| kubectl apply -n <destination-namespace> -f -

/ editar abril de 2020:

Agora existe uma maneira de compartilhar ou sincronizar o segredo entre namespaces usando o operador ClusterSecret:

https://github.com/zakkg3/ClusterSecret

NicoKowe
fonte
7

Os segredos são recursos com namespace, mas você pode usar uma extensão do Kubernetes para replicá-los. Usamos isso para propagar credenciais ou certificados armazenados em segredos para todos os namespaces automaticamente e mantê-los sincronizados (modifique a fonte e todas as cópias serão atualizadas). Consulte Refletor Kubernetes ( https://github.com/EmberStack/kubernetes-reflector ).

A extensão permite que você copie automaticamente e mantenha em sincronia um segredo entre namespaces por meio de anotações:

No segredo de origem, adicione as anotações:

 annotations:
   reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"

Isso criará uma cópia do segredo em todos os namespaces. Você pode limitar os namespaces nos quais uma cópia é criada usando:

reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "namespace-1,namespace-2,namespace-[0-9]*"

A extensão também oferece suporte a certificados ConfigMaps e cert-manager. Disclainer: eu sou o autor da extensão Kubernetes Reflector.

Winromulus
fonte
Bom addon. Usando agora. Obrigado!
CTiPKA
2

Conforme respondido por Innocent Anigbo, você precisa ter o segredo no mesmo namespace. Se você precisar dar suporte a isso dinamicamente ou evitar esquecer a criação de segredo, pode ser possível criar um inicializador para o objeto de namespace https://kubernetes.io/docs/admin/extensible-admission-controllers/ (não fiz isso por conta própria , então não posso dizer com certeza)

Radek 'Goblin' Pieczonka
fonte
1

Melhorando de @NicoKowe

Uma linha para copiar todos os segredos de um namespace para outro

$ for i in `kubectl get secrets | awk '{print $1}'`; do  kubectl get secret $1 -n <source-namespace> -o yaml | sed s/"namespace: <source-namespace>"/"namespace: <target-namespace>"/ | kubectl apply -n <target-namespace> -f -  ; done
Halil Kaskavalci
fonte
1

--export está obsoleto

sed não é a ferramenta apropriada para editar YAML ou JSON.

Aqui está um exemplo que usa jqpara excluir o namespace e outros metadados que não queremos:

kubectl get secret cure-for-covid-19 -n china -o json | jq 'del(.metadata["namespace","creationTimestamp","resourceVersion","selfLink","uid"])' | kubectl apply -n rest-of-world -f -
Evans Tucker
fonte
1

Com base na resposta de @Evans Tucker, mas usa whitelisting em vez de deletar dentro do filtro jq para manter apenas o que queremos.

kubectl get secret cure-for-covid-19 -n china -o json | jq '{apiVersion,data,kind,metadata,type} | .metadata |= {"annotations", "name"}' | kubectl apply -n rest-of-world -f -

Essencialmente a mesma coisa, mas preserva os rótulos.

kubectl get secret cure-for-covid-19 -n china -o json | jq '{apiVersion,data,kind,metadata,type} | .metadata |= {"annotations", "name", "labels"}' | kubectl apply -n rest-of-world -f -

Bruce
fonte
0

kubectl get secret gitlab-registry --namespace = revsys-com --export -o yaml | \ kubectl apply --namespace = devspectrum-dev -f -

user128364
fonte
0

Use RBAC para autorizar o serviço de conta a usar o segredo nos namespaces originais. Mas, isso não é recomendado para ter um segredo compartilhado entre namesapces.

jmselmi
fonte
0

Solução para copiar todos os segredos.

kubectl delete secret --namespace $TARGET_NAMESPACE--all;
kubectl get secret --namespace default --output yaml \
    | sed "s/namespace: $SOURCE_NAMESPACE/namespace: $TARGET_NAMESPACE/" \
    | kubectl apply --namespace $TARGET_NAMESPACE --filename -;
alextes
fonte
0

yqé uma ferramenta de linha de comando útil para editar arquivos YAML. Usei isso em conjunto com as outras respostas para obter isto:

kubectl get secret <SECRET> -n <SOURCE_NAMESPACE> -o yaml | yq write - 'metadata.namespace' <TARGET_NAMESPACE> | kubectl apply -n <TARGET_NAMESPACE> -f -
reiny
fonte
0

Você também pode pensar em usar os segredos externos do Kubernetes do GoDaddy ! onde você armazenará seus segredos no AWS Secret Manager (ASM) e o controlador secreto do GoDaddy criará os segredos automaticamente. Além disso, haveria sincronização entre o cluster ASM e K8S.

Thilee
fonte