Preciso aumentar o cluster Kubernetes, mas sou apenas um programador de código. Existe uma saída



Bom dia Outra nota da minha experiência. Desta vez, é superficial sobre a infraestrutura básica, que eu uso se precisar descarregar algo, mas não há caras de devOps por perto . Mas o atual nível de abstração, em tecnologia, permite que cerca de um ano convide com essa infraestrutura, criada durante a noite, usando a Internet e coisas prontas.

Palavras-chave - AWS + Terraform + kops . Se isso for útil para mim, provavelmente será útil para outra pessoa. Bem-vindo aos comentários.

-1. Com o que estamos lidando


A situação clássica - o projeto é gravado em um estágio em que é necessário descarregá-lo em algum lugar e começar a usá-lo. E o projeto é mais complicado do que uma simples página html. Gostaria da possibilidade de escala horizontal, a identidade do ambiente no local, teste, bancas de produtos e um processo de implantação mais ou menos normal.
Trata-se de uma aplicação no Laravel para mostrar todo o processo do começo ao fim. Mas, de maneira semelhante, você pode implantar uma dispersão de serviços em movimento, aplicativos python, pequenos sites no WP, páginas html e muito mais. Até um certo nível, isso é suficiente e, em seguida, uma pessoa separada aparece na equipe, que a aprimora e complementa.
Recentemente, cheguei ao fato de instalar o GoLand, PhpStorm, Docker, Git em máquinas locais e estou completamente pronto para trabalhar. Sim, e você pode gerenciar a partir de uma única máquina em clusters em massa, portanto descreverei todo o processo sem levar em conta o sistema operacional em que você trabalha, embalando tudo em um contêiner de docker.

0. Preparando-se para o trabalho.


Vamos imaginar que já registramos uma conta na AWS , solicitada pelo suporte técnico para aumentar os limites da conta pelo número de servidores em execução simultânea, criamos um usuário do IAM e agora temos a Chave de acesso + Chave secreta . Zona - us-leste-1 .

O que precisamos no computador local? AWS CLI , Terraform para gerenciamento declarativo da AWS , kubectl , kops para configurar o cluster e Helm , para implantar alguns serviços. Coletamos o Dockerfile (que encontrei há muito tempo em algum lugar na vastidão do github, mas não consigo encontrar onde). Nós escrevemos nosso docker-compose.yml para diretórios de montagem e Makefile para aliases.

Dockerfile
FROM ubuntu:16.04 ARG AWSCLI_VERSION=1.12.1 ARG HELM_VERSION=2.8.2 ARG ISTIO_VERSION=0.6.0 ARG KOPS_VERSION=1.9.0 ARG KUBECTL_VERSION=1.10.1 ARG TERRAFORM_VERSION=0.11.0 # Install generally useful things RUN apt-get update \ && apt-get -y --force-yes install --no-install-recommends \ curl \ dnsutils \ git \ jq \ net-tools \ ssh \ telnet \ unzip \ vim \ wget \ && apt-get clean \ && apt-get autoclean \ && apt-get autoremove \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # Install AWS CLI RUN apt-get update \ && apt-get -y --force-yes install \ python-pip \ && pip install awscli==${AWSCLI_VERSION} \ && apt-get clean \ && apt-get autoclean \ && apt-get autoremove \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # Install Terraform RUN wget -O terraform.zip https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip \ && unzip terraform.zip \ && mv terraform /usr/local/bin/terraform \ && chmod +x /usr/local/bin/terraform \ && rm terraform.zip # Install kubectl ADD https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl /usr/local/bin/kubectl RUN chmod +x /usr/local/bin/kubectl # Install Kops ADD https://github.com/kubernetes/kops/releases/download/${KOPS_VERSION}/kops-linux-amd64 /usr/local/bin/kops RUN chmod +x /usr/local/bin/kops # Install Helm RUN wget -O helm.tar.gz https://storage.googleapis.com/kubernetes-helm/helm-v${HELM_VERSION}-linux-amd64.tar.gz \ && tar xfz helm.tar.gz \ && mv linux-amd64/helm /usr/local/bin/helm \ && chmod +x /usr/local/bin/helm \ && rm -Rf linux-amd64 \ && rm helm.tar.gz # Create default user "kops" RUN useradd -ms /bin/bash kops WORKDIR /home/kops USER kops # Ensure the prompt doesn't break if we don't mount the ~/.kube directory RUN mkdir /home/kops/.kube \ && touch /home/kops/.kube/config 

docker-compose.yml
 version: '2.1' services: cluster-main: container_name: cluster.com image: cluster.com user: root stdin_open: true volumes: - ./data:/data - ./.ssh:/root/.ssh - ./.kube:/root/.kube - ./.aws:/root/.aws cluster-proxy: container_name: cluster.com-kubectl-proxy image: cluster.com user: root entrypoint: kubectl proxy --address='0.0.0.0' --port=8001 --accept-hosts='.*' ports: - "8001:8001" stdin_open: true volumes: - ./data:/data - ./.ssh:/root/.ssh - ./.kube:/root/.kube - ./.aws:/root/.aws 

Makefile
 docker.build: docker build -t cluster.com . docker.run: docker-compose up -d docker.bash: docker exec -it cluster.com bash 


Dockerfile - pegue a imagem básica do ubuntu e instale todo o software. Makefile - apenas por conveniência, você pode usar o mecanismo usual de aliases. Docker-compose.yml - adicionamos um contêiner adicional que nos lançará no navegador K8S Dashboard se você precisar ver algo visualmente.

Criamos as pastas de dados , .ssh , .kube , .aws na raiz e colocamos nossa configuração para as chaves aws, ssh e podemos coletar e executar nosso contêiner por meio de make docker.build e make docker.run .

Bem, na pasta de dados , crie uma pasta na qual colocamos os arquivos yaml k8s e ao lado do segundo, na qual armazenaremos o estado da terraform do cluster. Eu coloquei o resultado aproximado dessa etapa no github .

1. Aumente nosso cluster.


Em seguida, haverá uma tradução gratuita desta nota. Omitirei muitos pontos teóricos, tentarei descrever um breve aperto. Mesmo assim, o formato da minha anotação é tldr.

Na pasta data / aws-cluster-init-kops-terraform, clonamos o que há neste repositório e vamos para o console do contêiner através do make docker.bash . A dispersão de equipes chatas começa.

CLI da AWS


Criamos o número de usuários, adicionamos direitos de acesso e reconfiguramos o AWS CLI nele para não executar comandos do superusuário.

 aws iam create-group --group-name kops #   aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess --group-name kops aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonRoute53FullAccess --group-name kops aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess --group-name kops aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/IAMFullAccess --group-name kops aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AWSCertificateManagerFullAccess --group-name kops aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonVPCFullAccess --group-name kops aws iam create-user --user-name kops aws iam add-user-to-group --user-name kops --group-name kops aws iam create-access-key --user-name kops 

 aws configure 

Inicializar Terraform


No arquivo data / aws-cluster-init-kops-terraform / variables.tf, altere o nome do cluster para o desejado. Não esqueça de pegar nossos servidores DNS do arquivo update.json e atualizá-los onde você comprou seu domínio.

 #    cd /data/aws-cluster-init-kops-terraform #    AWS CLI export AWS_ACCESS_KEY_ID=$(aws configure get aws_access_key_id) export AWS_SECRET_ACCESS_KEY=$(aws configure get aws_secret_access_key) #  terraform terraform init terraform get terraform apply #  NS  cat update-zone.json \ | jq ".Changes[].ResourceRecordSet.Name=\"$(terraform output name).\"" \ | jq ".Changes[].ResourceRecordSet.ResourceRecords=$(terraform output -json name_servers | jq '.value|[{"Value": .[]}]')" \ > update-zone.json 

Kops


Criamos um cluster através do kops , exportando a configuração para um arquivo .tf .

 export NAME=$(terraform output cluster_name) export KOPS_STATE_STORE=$(terraform output state_store) export ZONES=$(terraform output -json availability_zones | jq -r '.value|join(",")') kops create cluster \ --master-zones $ZONES \ --zones $ZONES \ --topology private \ --dns-zone $(terraform output public_zone_id) \ --networking calico \ --vpc $(terraform output vpc_id) \ --target=terraform \ --out=. \ ${NAME} 

Uma pequena observação é necessária aqui. O Terraform criará uma VPC , e precisaremos ajustar um pouco a configuração que o kops nos fornecerá. Isso é feito simplesmente através da imagem auxiliar ryane / gensubnets: 0.1
 #   terraform output -json > subnets.json 

 #     echo subnets.json | docker run --rm -i ryane/gensubnets:0.1 

Você pode adicionar políticas imediatas para route53.

 additionalPolicies: master: | [ { "Effect": "Allow", "Action": ["route53:ListHostedZonesByName"], "Resource": ["*"] }, { "Effect": "Allow", "Action": ["elasticloadbalancing:DescribeLoadBalancers"], "Resource": ["*"] }, { "Effect": "Allow", "Action": ["route53:ChangeResourceRecordSets"], "Resource": ["*"] } ] node: | [ { "Effect": "Allow", "Action": ["route53:ListHostedZonesByName"], "Resource": ["*"] }, { "Effect": "Allow", "Action": ["elasticloadbalancing:DescribeLoadBalancers"], "Resource": ["*"] }, { "Effect": "Allow", "Action": ["route53:ChangeResourceRecordSets"], "Resource": ["*"] } ] 

A edição através do kops edita o cluster $ {NAME} .



Agora podemos aumentar o próprio cluster.

 kops update cluster \ --out=. \ --target=terraform \ ${NAME} terraform apply 

Tudo vai correr bem, o contexto do kubectl mudará. Na pasta data / aws-cluster-init-kops-terraform , armazenaremos o estado do cluster. Você pode simplesmente colocar tudo no git e enviá-lo para um repositório de bitpack privado.

 $ kubectl get nodes NAME STATUS AGE ip-10-20-101-252.ec2.internal Ready,master 7m ip-10-20-103-232.ec2.internal Ready,master 7m ip-10-20-103-75.ec2.internal Ready 5m ip-10-20-104-127.ec2.internal Ready,master 6m ip-10-20-104-6.ec2.internal Ready 5m 

2. Levante nossa aplicação


Agora que temos algo, podemos implantar nossos serviços em um cluster. Vou colocar configurações aproximadas no mesmo repositório . Eles podem ser colocados em um pacote em data / k8s .

Piadas de serviço


Vamos começar com o serviço. Precisamos de leme , rota53 , classes de armazenamento e acesso ao nosso registro privado em hub.docker.com . Bem, ou para qualquer outro, se houver esse desejo.

 # Init helm kubectl create serviceaccount --namespace kube-system tiller kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}' helm init 

 kubectl apply -f default-namespace.yaml kubectl apply -f storage-classes.yaml kubectl apply -f route53.yaml kubectl apply -f docker-hub-secret.yml kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml 

PostgreSQL + Redis


Eu queimei tantas vezes usando o docker não para contêineres sem estado , mas a última configuração até agora se mostrou a mais adequada. Eu uso o Stolon para fornecer escalabilidade. Cerca de um ano, o voo é normal.

Implementamos helm-charts e algumas configurações rápidas de Redis .

 #  etcd  stolon cd etcd-chart helm install --name global-etcd . #   stolon cd stolon-chart helm dep build helm install --name global-postgres . #  redis kubectl apply -f redis 

Nginx + php


O grupo de sempre. Nginx e php-fpm . Não limpei particularmente as configurações, mas todos podem configurar por si mesmos. Antes de aplicar, você deve especificar a imagem a partir da qual obteremos o código + adicionar uma linha de certificado do AWS Certificate Manager . Php propriamente dito - você pode acessá-lo no dockerhab, mas eu construí o meu particular adicionando algumas bibliotecas.

 kubectl apply -f nginx kubectl apply -f php 

Em nossa imagem com o código, nós o armazenamos na pasta / crm-code . Nós a substituímos por sua imagem e ela funcionará corretamente. O arquivo é nginx / deployment.yml .



Traga para fora o domínio. O serviço Route53 irá buscá-lo, alterar / adicionar registros DNS, o certificado será carregado no ELB a partir do AWS Certificate Manager . O arquivo é nginx / service.yml .



Encaminhe as variáveis ​​env no php para tê-las dentro e se conecte ao PostgreSQL / Redis . O arquivo é php / deployment.yml .



Como resultado, temos um cluster K8S , que em um nível básico podemos dimensionar, adicionar novos serviços, novos servidores (nós), alterar o número de instâncias do PostgreSQL, PHP, Nginx e viver antes que uma pessoa separada apareça na equipe que fará isso .

Como parte desta breve nota, não abordarei os problemas de backup / monitoramento de todas essas coisas. No estágio inicial, o host local será suficiente : 8001 / ui do serviço K8S Dashboard . Posteriormente, será possível fixar Prometheus , Grafana , Barman ou qualquer outra solução semelhante.

Usando um terminal ou Teamcity , Jenkins atualizando o código fará algo assim.

 #     -      Teamcity docker build -t GROUP/crm-code:latest . docker push GROUP/crm-code:latest #   (  ) kubectl set image deployment/php-fpm php-fpm=GROUP/php-fpm kubectl rollout status deployment/php-fpm kubectl set image deployment/php-fpm php-fpm=GROUP/php-fpm:latest kubectl set image deployment/nginx nginx=danday74/nginx-lua kubectl rollout status deployment/nginx kubectl set image deployment/nginx nginx=danday74/nginx-lua:latest kubectl rollout status deployment/php-fpm kubectl rollout status deployment/nginx 

Eu ficaria feliz se isso seria interessante para alguém e duplamente feliz se isso ajudasse alguém. Obrigado pela atenção. Mais uma vez, anexo um link ao repositório um e dois .

Source: https://habr.com/ru/post/pt423481/


All Articles