Usando variáveis ​​de ambiente nas especificações de implantação do Kubernetes

18

Atualmente, uso uma especificação do Kubernetes Deployment.yamlpara implantar um serviço. A especificação inclui uma referência literal a um endereço IP específico (marcado como <static-ip-address>abaixo):

spec:
  type: LoadBalancer
  loadBalancerIP: <static-ip-address>

Estou preocupado em enviar informações como senhas ou endereços IP para repositórios Git remotos. Posso evitar isso, por exemplo, usando variáveis ​​de ambiente, por exemplo, com uma especificação de implantação e implantação real, aproximadamente da seguinte maneira:

spec:
   type: LoadBalancer
   loadBalancerIP: ${SERVICE_ADDRESS}

e

export SERVICE_ADDRESS=<static-ip-address>
kubectl create -f Deployment.yaml

Obviamente, essa sintaxe específica ainda não funciona. Mas algo assim é possível e, em caso afirmativo, como?

Prefiro não confiar em uma ferramenta de provisionamento separada . Secretas s e ConfigMaps parecem promissores, mas aparentemente eles não podem ser consumidos de uma forma que ternos esta finalidade. Se eu pudesse referenciar diretamente um endereço IP estático que foi definido com gcloud compute addresses create service-addressisso, seria melhor.

Drux
fonte

Respostas:

27

Uma solução muito mais fácil / limpa: envsubst

No deploy.yml:

LoadbalancerIP: $LBIP

Em seguida, basta criar sua var env e executar o kubectl assim:

export LBIP="1.2.3.4"
envsubst < deploy.yml | kubectl apply -f -

Você apenas coloca variáveis ​​regulares do Bash no arquivo que deseja usar, neste caso o manifesto YAML, e depois leu esse arquivo. Ele produzirá o arquivo com os envários substituídos por seus valores. Você também pode usá-lo para criar novos arquivos como este:

envsubst < input.yml > output.yml

envsubstestá disponível no gettextpacote Ubuntu / Debian, por exemplo .

Jan Grewe
fonte
2
+1 para envsubst. até agora não sabia sobre isso
user1129682
1
Não é mais fácil / mais limpo, pois requer uma ferramenta separada, que não é instalada por padrão em todos os sistemas (por exemplo, Mac)
Ivan
@Ivan Sua pergunta era "Mas é possível algo assim e, em caso afirmativo, como?", E essa é a resposta para sua pergunta. A pergunta não era "Como posso fazer isso com as ferramentas disponíveis em todos os sistemas operacionais por padrão?". E sim, é 1) mais fácil E 2) mais limpo do que usar sed. Por sua definição, a solução proposta com sedtambém não seria mais fácil / mais limpa, pois não há sedinstalado nas máquinas Windows por padrão.
Jan Grewe
Não está claro que você estava comparando com a opção "sed".
Ivan
2

Não havia outra solução agradavelmente simples: Eu tenho um Google Compute Endereço my-addressdefinida, e eu, aparentemente, pode usá-lo na especificação de serviço assim: loadBalancerIP: my-address.

Com isso como fonte "externa" para endereços IP e segredos para senhas, não há mais necessidade de uma ferramenta de provisionamento (ou modelos) para meu caso de uso simples (dentro de um ambiente GKE).

OBSOLETE AGORA: Decidi usar uma espécie de ferramenta de provisionamento, a saber, "embutida" sed, afinal.

Meu Deployment.yamlagora contém uma "variável de modelo", por exemplo, em

loadBalancerIP: $$EXTERNAL_IP

e implanto o serviço com, digamos, 1.2.3.4 como endereço IP externo com

cat Deployment.yaml | sed s/\$\$EXTERNAL_IP/1.2.3.4/ | kubectl create -f -
Drux
fonte
1
A abordagem de Jan Grewe é mais genérica e pode ser aplicada a qualquer número de variáveis. Sugiro que aceite a resposta dele em vez de aceitar a sua, que é menos genérica e precisa ser ajustada para cada variável adicional.
TekTimmy
0

Você pode escrever um pré-processador simples para fazer a substituição de variáveis ​​nos arquivos yaml (ou pode usar o jsonnet para realizar a mesma coisa nos arquivos de configuração do json).

Há alguma discussão sobre a adição de modelos diretamente na configuração do Kubernetes, mas ainda não está implementado ou disponível.

Robert Bailey
fonte
Sim, mas o jsonnet é uma ferramenta de provisionamento, conforme mencionado na pergunta.
Drux
1
Se você estiver procurando por algo embutido, seguir o problema ao qual vinculei é sua melhor aposta neste momento.
Robert Bailey
0

Até que os modelos estejam disponíveis, a maneira mais fácil de fazer isso é executar um trabalho que use a API do Kubernetes para atualizar o serviço. Um script de shell curto em uma imagem alpina, juntamente com um segredo (contendo o endereço IP) e um mapa de configuração (contendo o modelo), deve ser bastante simples. A parte difícil está usando corretamente os recursos de autenticação e autorização do apiserver.

/programming/30690186/how-do-i-access-the-kubernetes-api-from-within-a-pod-container fornece um exemplo de acesso à API. Obviamente, você desejará POST para / api / v1 / namespaces / default / services em vez do GET nesse exemplo.

aecolley
fonte
Parece interessante, mas você pode elaborar um pouco mais. Você poderia dar ou apontar para um exemplo de um script de shell adequado.
Drux