Necesito elevar el clúster de Kubernetes, pero solo soy un programador de código. Hay una salida



Buen dia Otra nota de mi experiencia. Esta vez es superficial sobre la infraestructura básica, que uso si necesito descargar algo, pero no hay muchachos de desarrollo cerca . Pero el nivel actual de abstracción, en tecnología, permite vivir alrededor de un año con esta infraestructura, criada durante la noche, usando Internet y cosas preparadas.

Palabras clave: AWS + Terraform + kops . Si esto es útil para mí, probablemente será útil para otra persona. Bienvenidos a los comentarios.

-1. Con qué estamos tratando


La situación clásica: el proyecto se escribe en una etapa en la que es necesario descargarlo en algún lugar y comenzar a usarlo. Y el proyecto es más complicado que una simple página html. Me gustaría la posibilidad de escalar horizontalmente, la identidad del entorno en locales, pruebas, stands de productos y un proceso de implementación más o menos normal.
Se trata de una aplicación en Laravel para mostrar todo el proceso de principio a fin. Pero de manera similar, puede implementar una dispersión de servicios en marcha, aplicaciones python, sitios pequeños en WP, páginas html y mucho más. Hasta cierto nivel, esto es suficiente, y luego aparece una persona separada en el equipo, que lo mejorará y complementará.
Recientemente, llegué al hecho de que instalo GoLand, PhpStorm, Docker, Git en máquinas locales y estoy completamente listo para trabajar. Sí, y puede administrar desde una sola máquina en grupos masivos, por lo que describiré todo el proceso sin tener en cuenta el sistema operativo en el que trabaja, empacando todas las cosas en un contenedor acoplable.

0. Preparándose para el trabajo.


Imaginemos que ya hemos registrado una cuenta en AWS , solicitamos a través del soporte técnico aumentar los límites de la cuenta en la cantidad de servidores que se ejecutan simultáneamente, creamos un usuario de IAM y ahora tenemos la clave de acceso + clave secreta . Zona - us-east-1 .

¿Qué necesitamos en la computadora local? AWS CLI , Terraform para la gestión declarativa de AWS , kubectl , kops para configurar el clúster y Helm , para implementar algunos servicios. Recopilamos el Dockerfile (que encontré hace mucho tiempo en algún lugar de la inmensidad del github, pero no puedo encontrar dónde). Escribimos nuestro docker-compose.yml para directorios de montaje y Makefile para alias.

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 : tome la imagen básica de ubuntu e instale todo el software. Makefile : solo por conveniencia, puede usar el mecanismo habitual de alias. Docker-compose.yml : agregamos un contenedor adicional que nos lanzará al navegador K8S Dashboard si necesita ver algo visualmente.

Creamos las carpetas de datos , .ssh , .kube , .aws en la raíz y colocamos nuestra configuración para aws, claves ssh allí y podemos recopilar y ejecutar nuestro contenedor a través de make docker.build y make docker.run .

Bueno, en la carpeta de datos , cree una carpeta en la que coloquemos los archivos yaml k8s , y junto a la segunda, en la que almacenaremos el estado de la terraforma del clúster. Puse el resultado aproximado de esta etapa en el github .

1. Eleve nuestro grupo.


A continuación habrá una traducción gratuita de esta nota. Omitiré muchos puntos teóricos, trataré de describir un breve apretón. De todos modos, el formato de mi nota es tldr.

En nuestra carpeta data / aws-cluster-init-kops-terraform, clonamos lo que hay en este repositorio y vamos a la consola del contenedor a través de make docker.bash . Comienza la dispersión de equipos aburridos.

AWS CLI


Creamos los kops de usuario, agregamos derechos de acceso y reconfiguramos AWS CLI en él para no ejecutar comandos desde el superusuario.

 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


En el archivo data / aws-cluster-init-kops-terraform / variables.tf, cambie el nombre del clúster al deseado. No olvide tomar nuestros servidores dns del archivo update.json y actualizarlos donde compró su dominio.

 #    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


Creamos un clúster a través de kops , exportando la configuración a un archivo .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} 

Se necesita un pequeño comentario aquí. Terraform creará una VPC , y necesitaremos ajustar ligeramente la configuración que nos proporcionará kops . Esto se hace simplemente a través de la imagen auxiliar de ryane / gensubnets: 0.1
 #   terraform output -json > subnets.json 

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

Puede agregar políticas inmediatas 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": ["*"] } ] 

Edición a través de kops edit cluster $ {NAME} .



Ahora podemos elevar el clúster en sí.

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

Todo irá bien, el contexto de kubectl cambiará. En la carpeta data / aws-cluster-init-kops-terraform , almacenaremos el estado del clúster. Simplemente puede poner todo en git y enviarlo a un repositorio privado de paquetes de bits.

 $ 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 nuestra aplicación


Ahora que tenemos algo, podemos implementar nuestros servicios en un clúster. Pondré configuraciones aproximadas en el mismo repositorio . Se pueden poner en un paquete en datos / k8s .

Bromas de servicio


Comencemos con el servicio. Necesitamos helm , route53 , clases de almacenamiento y acceso a nuestro registro privado en hub.docker.com . Bueno, o a cualquier otro, si hay tal deseo.

 # 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


Me quemé tantas veces usando docker no para contenedores sin estado , pero la última configuración hasta ahora ha demostrado ser la más adecuada. Yo uso Stolon para proporcionar escalabilidad. Alrededor de un año, el vuelo es normal.

Implementamos helm-charts y un par de configuraciones 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


El grupo habitual. Nginx y php-fpm . No limpié particularmente las configuraciones, pero todos pueden configurar por sí mismos. Antes de aplicar, debe especificar la imagen de la que tomaremos el código + agregar una línea de certificado desde AWS Certificate Manager . Php en sí mismo: puede tomarlo del dockerhab, pero construí mi privado agregando algunas bibliotecas.

 kubectl apply -f nginx kubectl apply -f php 

En nuestra imagen con el código, lo almacenamos en la carpeta / crm-code . Lo reemplazamos con su imagen y funcionará correctamente. El archivo es nginx / despliegue.yml .



Saca el dominio. El servicio Route53 lo recogerá, cambiará / agregará registros DNS, el certificado se cargará a ELB desde AWS Certificate Manager . El archivo es nginx / service.yml .



Reenvíe las variables env en php para tenerlas dentro y conectarse a PostgreSQL / Redis . El archivo es php / despliegue.yml .



Como resultado, tenemos un clúster K8S , que en un nivel básico podemos escalar, agregar nuevos servicios, nuevos servidores (nodos), cambiar el número de instancias de PostgreSQL, PHP, Nginx y vivir antes de que aparezca una persona separada en el equipo que hará esto .

Como parte de esta breve nota, no tocaré temas de respaldo / monitoreo de todo esto. En la etapa inicial, localhost será suficiente : 8001 / ui del servicio K8S Dashboard . Más tarde, será posible sujetar Prometeo , Grafana , Barman o cualquier otra solución similar.

Usando una terminal o Teamcity , Jenkins actualizando el código hará algo como esto.

 #     -      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 

Me alegraría si fuera interesante para alguien y me alegraría si ayuda a alguien. Gracias por su atencion Una vez más, adjunto un enlace al repositorio uno y dos .

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


All Articles