En un articulo anterior vimos los conceptos básicos de kubernetes y algo de su arquitectura, hoy vamos a ver cómo se instala y configura kubernetes en AWS (Amazon Web Services). Este tutorial lo vamos a hacer con la versión estable de kops (1.7.1) lo cual nos permite instalar kubernetes 1.7.*.
Instalando Kubernetes en AWS con kops
Herramientas necesarias
- kops (Kubernetes Operations) => https://github.com/kubernetes/kops
- aws-cli (Amazon Command Line Interface) => https://aws.amazon.com/cli/
- kubectl (Kubernets Command Line Interface) => https://kubernetes.io/docs/user-guide/kubectl-overview/
- jq (Command Line Json Processor) => https://stedolan.github.io/jq/download/
Preparación
Primero que todo tenemos que configurar aws-cli para poder manipular la infraestructura en AWS
aws cli
Este proceso solicitará las keys de AWS y la región por defecto a usar, por ejemplo us-west-2
Es necesario crear un lugar donde almacenar el estado del cluster de kubernetes, usamos para nuestro caso un bucket en AWS, lo creamos incluyendo versionado.
aws s3api create-bucket --bucket <bucket name> --region <region> --create-bucket-configuration LocationConstraint=<region>
aws s3api put-bucket-versioning --bucket <bucket name> --versioning-configuration Status=Enabled
Ej.
aws s3api create-bucket --bucket my-cluster --region us-west-2 --create-bucket-configuration LocationConstraint=us-west-2
aws s3api put-bucket-versioning --bucket my-cluster --versioning-configuration Status=Enabled
Para facilitar el uso de kops se puede incluir una variable de entorno con el nombre del bucket
export KOPS_STATE_STORE=s3://my-cluster
Creando una zona en Route53
Se procede ahora a crear la zona en Route53 para que el cluster se pueda comunicar con la infraestructura definida en AWS usando el siguiente comando
ID=$(uuidgen) && \
aws route53 create-hosted-zone \
--name <subdominio>.<dominio> \
--vpc VPCRegion="<region>",VPCId="<vpc id>" \
--caller-reference $ID \
--hosted-zone-config Comment="Kube cluster DNS",PrivateZone=true \
| jq .DelegationSet.NameServers
Ej.
ID=$(uuidgen) && \
aws route53 create-hosted-zone \
--name kube.midominio.com \
--vpc VPCRegion="us-west-2",VPCId="vpc-4654651" \
--caller-reference $ID \
--hosted-zone-config Comment="Kube cluster DNS",PrivateZone=true \
| jq .DelegationSet.NameServers
El valor de la vpc es la existente en la infraestructura para permitir conectarse sin problema entre todas las instancias.
Esta zona esta configurada como zona privada.
Creando Cluster de Kubernetes
Una vez tenemos la zona en Route53, copiamos su id para usarlo cuando se cree el cluster.
Con el siguiente comando vamos a crear el cluster con las siguientes características:
- nombre => kube.midominio.com
- zona => us-west-2
- Master => t2.micro
- Volume Master => 8 Gb
- Nodos => t2.micro
- Volume Nodo => 8 Gb
- Cantidad de Nodos => 2
- Zona DNS => El id de la zona creada en Route53
- Tipo de DNS => privado
- CIDR de la red => se usa el de la vpc
- Topología => privada
- Llave ssh => kube_rsa.pub
- vpc => id de la vpc que exista en aws.
kops create cluster \
--name=kube.midominio.com \
--zones=us-west-2b \
--state=s3://my-cluster \
--master-size="t2.micro" \
--master-volume-size=8 \
--node-size="t2.micro" \
--node-volume-size=8 \
--node-count=2 \
--dns-zone=**********\
--dns=private \
--networking flannel \
--network-cidr=***.***.0.0/16 \
--topology private \
--ssh-public-key="~/.ssh/kube_rsa.pub" \
--vpc=vpc-4654651 \
--yes
Con el comando anterior creamos las especificaciones del cluster y validamos que no existen conflictos en las subnets asignadas a otras instancias, si llega a dar error al crear estas subnets es necesario hacerlo a mano.
Resolviendo conflictos de subnets
Primero descargamos la configuración del cluster en formato yaml
kops get clusters my-cluster -o yaml > cluster-config.yam
Editamos el el archivo en la parte de configuración de subnets
Los valores de name y zone pueden ser por ejemplo us-west-2a
subnets:
- cidr: ***.***.***.0/19
name: <name>
type: Private
zone: <zone>
- cidr: ***.***.***.0/22
name: utility-<name>
type: Utility
zone: <zone>
Una vez editada guardamos el archivo y reemplazamos la configuración
kops replace -f cluster-config.yaml
Y aplicamos la nueva configuración
kops update cluster --name my-cluster --yes
Validando la instalación de Kubernetes
Una vez instalado el cluster revisamos en la zona que creamos en route53 y se deben haber creado 4 registros nuevos, tomamos el alias del registro de api.kube.midominio.com
y hacemos ping para obtener la ip, ya que esta es una zona privada hay que crear el registro en el archivo hosts del sistema (/etc/hosts en sistemas *nix, /Windows/system32/Drivers/etc/hosts en windows)
51.25.254.25 api.kube.midominio.com
Ahora vamos a validar que el cluster esté corriendo los nodos que definimos
kops validate clusters
Instalando el dashboard de Kubernetes
Una vez hemos realizado esto solo falta instalar el dashboard que nos permite desde el navegador administrar el cluster de Kubernetes.
kubectl create -f https://git.io/kube-dashboard
Configurando el cluster de Kubernetes
Vamos a configurar ahora el cluster para correr nuestros contenedores de docker.
Creando el Namespace
Vamos a crear el namespace, esto se hace una sola vez y sirve para tener todos los microservicios dentro de un espacio común.
kubectl create --namespace=production
Creando el Service
Los microservicios necesitan un service el cual crea un load balancer para conectar a ese microservicio y sus diferentes pods
Aquí está el código de ejemplo que debe ser guardado con el nombre que quieran pero la extensión tiene que ser yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: production
annotations:
service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
spec:
ports:
- port: 80
targetPort: 8000
protocol: TCP
selector:
app: my-service
type: LoadBalancer
Lo guardan por ejemplo con el nombre my-first-service.yaml
kubectl apply -f my-first-service.yaml
Creando el Secret
Esta es una característica muy importante que tiene Kubernetes y es el poder crear secrets con datos que se pasan como variables de entorno a los contenedores, estos secrets pueden ser datos de conexión a la base de datos, la url del load balancer que se crea por Kubernetes cuando creamos nuestro servicio en el paso anterior/
Estos secrets no deben ser subidos por ninguna razón a tu repositorio en github.
Los valores de los secrets se pasan a base64 para evitar problemas de manejo de caracteres raros y se hace con el siguiente comando
echo -n "my-secret" | base64
Nos da como salida
bXktc2VjcmV0
La estructura del archivo secrets es la siguiente
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: bXktc2VjcmV0
Esto lo guardan en un archivo llamado por ejemplo my-secrets.yaml
y lo envían a kubernets usando
kubectl apply -f my-secrets.yaml
Creando el Deployment
Hasta aquí hemos creado nuestro servicio y nuestros secrets pero aún no tenemos nuestros contenedores corriendo, así que manos a la obra
El deployment es la última parte que creamos, esto es configurar el número de pods (instancias) que se van a ejecutar de nuestro ms.
El siguiente es un ejemplo del código de un deployment
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-service
namespace: production
spec:
replicas: 2
template:
metadata:
labels:
app: my-service
tier: backend
track: stable
spec:
containers:
- name: my-service
image: mi-image
ports:
- containerPort: <port>
imagePullPolicy: Always
imagePullSecrets:
- name: docker-io
Tenemos algunos datos importantes en este archivo como son:
replicas => número de pods (instancias) de nuestro contenedor
image => es el nombre de nuestra imagen de docker, debe estar pública en algún lado, por ejemplo usando el servicio de ECS de amazon o en hub.docker.com
El anterior código lo guardamos como my-service-deployment.yaml
y lo subimos a Kubernetes para tener nuestros pods funcionando.
kubectl apply -f my-service-deployment.yaml
Con esto tenemos nuestro primer servicio corriendo en kubernetes, si necesitan correr más servicios dentro de su cluster de kubernetes solo tienen que repetir los pasos desde la creación del service.
Espero sus comentarios y dudas sobre este apasionante tema y si les gustaría aprender algo en especial.
Curso de Kubernetes (2019)