O Kubernetes requer um conjunto de máquinas para hospedar o Control Plane e os Worker Nodes nos quais os contêineres são executados. Neste tutorial, você provisionará os recursos de computação necessários para executar um cluster Kubernetes seguro e altamente disponível em uma única Zona de Disponibilidade.
Tenha certeza que vocês definiu uma região padrão como descrito no tutorial Pré-requisitos. Todos os comandos deste tutorial deverão ser executados no seu desktop/laptop.
O modelo de rede do Kubernetes considera uma rede plana (flat network) na qual contêineres e nós (nodes) podem se comunicar. Nos casos em que isso não é desejado, as políticas de rede podem limitar a comunicação entre os grupos de contêineres e, também, com os endpoints de rede externos.
A configuração das políticas de rede está fora do escopo deste tutorial.
Nesta seção, uma rede Virtual Private Cloud (VPC) será configurada para hospedar o cluster Kubernetes na AWS.
Crie a rede customizada VPC chamada kubernetes-modo-dificil, utilizando o(s) comando(s) abaixo:
VPC_ID=$(aws ec2 create-vpc --cidr-block 10.0.0.0/16 --output text --query 'Vpc.VpcId')
aws ec2 create-tags --resources ${VPC_ID} --tags Key=Name,Value=kubernetes-modo-dificil
aws ec2 modify-vpc-attribute --vpc-id ${VPC_ID} --enable-dns-support '{"Value": true}'
aws ec2 modify-vpc-attribute --vpc-id ${VPC_ID} --enable-dns-hostnames '{"Value": true}'
Uma sub-rede/subnet deverá ser criada com um intervalo de endereços IP grande o suficiente para atribuir um endereço IP privado a cada nó do cluster Kubernetes.
Crie a sub-rede (subnet) na rede VPC kubernetes-modo-dificil, utilizando o(s) comando(s) abaixo:
SUBNET_ID=$(aws ec2 create-subnet \
--vpc-id ${VPC_ID} \
--cidr-block 10.0.1.0/24 \
--output text --query 'Subnet.SubnetId')
aws ec2 create-tags --resources ${SUBNET_ID} --tags Key=Name,Value=kubernetes
O range de IPs
10.0.1.0/24poderá ter até 253 instancias computacionais.
Crie um gateway de internet (internet gateway) na rede VPC kubernetes-modo-dificil, utilizando o(s) comando(s) abaixo:
INTERNET_GATEWAY_ID=$(aws ec2 create-internet-gateway --output text --query 'InternetGateway.InternetGatewayId')
aws ec2 create-tags --resources ${INTERNET_GATEWAY_ID} --tags Key=Name,Value=kubernetes
aws ec2 attach-internet-gateway --internet-gateway-id ${INTERNET_GATEWAY_ID} --vpc-id ${VPC_ID}
Crie um route table na rede VPC kubernetes-modo-dificil, utilizando o(s) comando(s) abaixo:
ROUTE_TABLE_ID=$(aws ec2 create-route-table --vpc-id ${VPC_ID} --output text --query 'RouteTable.RouteTableId')
aws ec2 create-tags --resources ${ROUTE_TABLE_ID} --tags Key=Name,Value=kubernetes
aws ec2 associate-route-table --route-table-id ${ROUTE_TABLE_ID} --subnet-id ${SUBNET_ID}
aws ec2 create-route --route-table-id ${ROUTE_TABLE_ID} --destination-cidr-block 0.0.0.0/0 --gateway-id ${INTERNET_GATEWAY_ID}
Crie os security groups na rede VPC kubernetes-modo-dificil, utilizando o(s) comando(s) abaixo:
SECURITY_GROUP_ID=$(aws ec2 create-security-group \
--group-name kubernetes \
--description "Kubernetes security group" \
--vpc-id ${VPC_ID} \
--output text --query 'GroupId')
aws ec2 create-tags --resources ${SECURITY_GROUP_ID} --tags Key=Name,Value=kubernetes
aws ec2 authorize-security-group-ingress --group-id ${SECURITY_GROUP_ID} --protocol all --cidr 10.0.0.0/16
aws ec2 authorize-security-group-ingress --group-id ${SECURITY_GROUP_ID} --protocol all --cidr 10.200.0.0/16
aws ec2 authorize-security-group-ingress --group-id ${SECURITY_GROUP_ID} --protocol tcp --port 22 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id ${SECURITY_GROUP_ID} --protocol tcp --port 6443 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id ${SECURITY_GROUP_ID} --protocol tcp --port 443 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id ${SECURITY_GROUP_ID} --protocol icmp --port -1 --cidr 0.0.0.0/0
Um balanceador de cargas externo será criado para expôr os servidores de API do Kubernetes para os clientes remotos.
Crie o Balanceador de Cargas na rede VPC kubernetes-modo-dificil, utilizando o(s) comando(s) abaixo:
LOAD_BALANCER_ARN=$(aws elbv2 create-load-balancer \
--name kubernetes \
--subnets ${SUBNET_ID} \
--scheme internet-facing \
--type network \
--output text --query 'LoadBalancers[].LoadBalancerArn')
TARGET_GROUP_ARN=$(aws elbv2 create-target-group \
--name kubernetes \
--protocol TCP \
--port 6443 \
--vpc-id ${VPC_ID} \
--target-type ip \
--output text --query 'TargetGroups[].TargetGroupArn')
aws elbv2 register-targets --target-group-arn ${TARGET_GROUP_ARN} --targets Id=10.0.1.1{0,1,2}
aws elbv2 create-listener \
--load-balancer-arn ${LOAD_BALANCER_ARN} \
--protocol TCP \
--port 443 \
--default-actions Type=forward,TargetGroupArn=${TARGET_GROUP_ARN} \
--output text --query 'Listeners[].ListenerArn'
KUBERNETES_PUBLIC_ADDRESS=$(aws elbv2 describe-load-balancers \
--load-balancer-arns ${LOAD_BALANCER_ARN} \
--output text --query 'LoadBalancers[].DNSName')
As instâncias computacionais neste tutorial serão provisionadas usando o Ubuntu Server 18.04 como sistema operacional, que oferece um bom suporte para o ContainerD container runtime. Cada instância computacional será provisionada com um endereço IP, privado e fixo, para simplificar o processo de inicialização do Kubernetes.
Definiremos a imagem das instâncias computacionais através do comando abaixo:
IMAGE_ID=$(aws ec2 describe-images --owners 099720109477 \
--filters \
'Name=root-device-type,Values=ebs' \
'Name=architecture,Values=x86_64' \
'Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*' \
| jq -r '.Images|sort_by(.Name)[-1]|.ImageId')
Um par de chaves será utilizado para o acesso seguro as Instâncias Computacionais. Para criar o SSH Key Pair utilize o(s) comando(s) abaixo:
aws ec2 create-key-pair --key-name kubernetes --output text --query 'KeyMaterial' > kubernetes.id_rsa
chmod 600 kubernetes.id_rsa
Criar 3 instâncias computacionais, do tipo t3.micro, utilizando o(s) comando(s) abaixo. Esses instâncias computacionais farão o papel de Kubernetes Controller Node.
for i in 0 1 2; do
instance_id=$(aws ec2 run-instances \
--associate-public-ip-address \
--image-id ${IMAGE_ID} \
--count 1 \
--key-name kubernetes \
--security-group-ids ${SECURITY_GROUP_ID} \
--instance-type t3.micro \
--private-ip-address 10.0.1.1${i} \
--user-data "name=controller-${i}" \
--subnet-id ${SUBNET_ID} \
--block-device-mappings='{"DeviceName": "/dev/sda1", "Ebs": { "VolumeSize": 50 }, "NoDevice": "" }' \
--output text --query 'Instances[].InstanceId')
aws ec2 modify-instance-attribute --instance-id ${instance_id} --no-source-dest-check
aws ec2 create-tags --resources ${instance_id} --tags "Key=Name,Value=controller-${i}"
echo "controller-${i} created "
done
Cada Worker Node requer uma alocação de sub-rede para os PODs no intervalo CIDR do cluster Kubernetes. A alocação de sub-rede dos PODs será usada para configurar a rede de contêineres em um tutorial posterior. Os metadados da instância pod-cidr serão usados para expor as alocações da sub-rede do pod para as instâncias computacionais em tempo de execução (runtime).
O intervalo CIDR do cluster Kubernetes é definido pelo Flag
--cluster-cidrdo Controller Manager. Neste tutorial, o intervalo CIDR do cluster será definido como10.200.0.0 / 16, que suporta 254 sub-redes.
Crie três instâncias computacionais que hospedarão os worker nodes do Kubernetes, através do(s) comando(s) abaixo:
for i in 0 1 2; do
instance_id=$(aws ec2 run-instances \
--associate-public-ip-address \
--image-id ${IMAGE_ID} \
--count 1 \
--key-name kubernetes \
--security-group-ids ${SECURITY_GROUP_ID} \
--instance-type t3.micro \
--private-ip-address 10.0.1.2${i} \
--user-data "name=worker-${i}|pod-cidr=10.200.${i}.0/24" \
--subnet-id ${SUBNET_ID} \
--block-device-mappings='{"DeviceName": "/dev/sda1", "Ebs": { "VolumeSize": 50 }, "NoDevice": "" }' \
--output text --query 'Instances[].InstanceId')
aws ec2 modify-instance-attribute --instance-id ${instance_id} --no-source-dest-check
aws ec2 create-tags --resources ${instance_id} --tags "Key=Name,Value=worker-${i}"
echo "worker-${i} created"
done