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.
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.
Respostas:
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
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 localdockerreg
segredo do default
namespace para dev
:
kubectl get secret localdockerreg --namespace=default --export -o yaml | kubectl apply --namespace=dev -f -
### UPDATE ### No Kubernetes v1.14, a --export
sinalização está obsoleta . Portanto, o seguinte comando com -oyaml
sinalizador 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 -
--export
sinalizador), recebo um erro dizendo "o namespace da opção fornecida não corresponde". kubectl versão 1.15. Acho que você pode precisar usar sed
ou algo entre esses dois kubectl
comandos para remover o namespace da saída yaml
$ 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
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:
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.
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)
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
--export
está obsoleto
sed
não é a ferramenta apropriada para editar YAML ou JSON.
Aqui está um exemplo que usa jq
para 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 -
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 -
kubectl get secret gitlab-registry --namespace = revsys-com --export -o yaml | \ kubectl apply --namespace = devspectrum-dev -f -
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 -
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.
Outra opção seria usar kubed , conforme recomendado pelo gentil pessoal do Jetstack que nos deu cert-manager. Aqui está o link para o qual eles estão vinculados.