Blog Post

Desenvolvedores BR
9 MIN READ

AKS com Windows

wdossantos's avatar
wdossantos
Icon for Microsoft rankMicrosoft
Jan 17, 2023

Hoje em dia é muito comum ouvirmos falar de kubernetes, essa tecnologia é uma resposta para a grande adoção de aplicações baseadas em containers com arquiteturas como micro serviço ou Service Oriented Architectures (SOA), no entanto a criação de um cluster de kubernetes não gerenciado dentro da nossa infraestrutura (on-premises) é uma tarefa bem complexa e demanda uma equipe experiente para manter tudo rodando. Assim o AKS (Serviço de Kubernetes do Azure) se torna uma excelente opção para implantação de um cluster de Kubernetes de forma gerenciada na nuvem Azure. Podemos usar o AKS para simplificar a implantação e o gerenciamento de aplicativos nativos de nuvem, arquiteturas de micro serviços ou mesmo aquelas aplicações mais antigas, o AKS simplifica o dimensionamento horizontal, a auto recuperação e o balanceamento de carga.

Nesse artigo vou focar nas aplicações que precisam de windows para rodar, como por exemplo as aplicações desenvolvidas no .NET Full Framework, mas antes de partir para a prática vamos pontuar alguns conceitos básicos do AKS.

 

Container

 

Podemos entender o container como um pacote, com todas as dependências necessárias para o software rodar (código, DLLs, configurações de ambientes etc.). Ele é um processo isolado, e não possui um sistema operacional completo, pois ele utiliza o compartilhamento do kernel do Sistema Operacional onde está sendo executado, tornando um container ainda mais leve.

Virtual Machines X Containers

 

Mas e o Docker?

 

Docker é um conjunto de produtos que usam virtualização para entregar software em pacotes chamados contêineres. Com o Docker podemos fazer testes em nosso ambiente de desenvolvimento de forma muito simples, pois não precisamos instalar nada diretamente na máquina de desenvolvimento, tudo fica isolado em um container, uma vez configurados, ambientes complexos podem ficar disponíveis em minutos.

 

Azure kuberntes service(AKS)

 

O Kubernetes é um sistema de orquestração de contêineres open-source que automatiza a implantação, o dimensionamento e a gestão de aplicações em contêineres. Ele foi originalmente projetado pelo Google e agora é mantido pela Cloud Native Computing Foundation. Porém, configurar e operar um cluster de kubernetes não é uma tarefa fácil, e por isso, temos o Azure Kubernetes Service, que é uma implementação do Kubernetes como um serviço gerenciado, onde você não precisa se preocupar em manter o seu cluster.

 

Vantagens AKS

 

  1. Orquestração de Containers
  2. Escalabilidade
  3. Deploy Ágil CI/CD
  4. Segurança
  5. Integração com Azure Devops e Visual Studio
  6. Pague apenas pelos Nodes e Armazenamento

 

Arquitetura básica

 

Elementos da arquitetura
  1. Cluster : Conjunto de máquinas
  2. Node: VM
  3. Pod: menor unidade que o AKS gerencia. Os containers rodam dentro dos pods.

 

Node pools

 

Os nodes são as máquinas do cluster, ou seja, onde os pods serão executados. Os Node pools, por sua vez, são um agrupamento de máquinas com uma mesma configuração, representados por um VM Scale Set. Pools de diferentes tipos podem ser adicionados ao cluster para lidar com uma variedade de cargas de trabalho. Os pools existentes podem ser dimensionados e atualizados ou os pools que não são mais necessários podem ser excluídos.

Learn more about node pools

novo node poll

 

Network

 

Existem dois plugins disponíveis para definir o comportamento da rede do AKS, o Kubenet e o Azure CNI.

 

Kubernetes networking (Basic)

 

Os recursos de rede normalmente são criados e configurados conforme o cluster AKS é implantado. Neste modelo, os nodes recebem um endereço de IP da sua subnet, enquanto os pods recebem um IP virtual, que não faz parte da subnet, utilizando NAT (Network address translation) para que os pods consigam se comunicar entre si e atingir outros recursos da Azure.

 

Azure Container Networking Interface (CNI)

 

No caso do Azure CNI, os pods adotam IPs reais da subnet. Isso implica que o cluster AKS está conectado a recursos e configurações de rede virtual existentes, eliminando a necessidade do NAT. Esta opção é obrigatória para utilizar Node Pools Windows.

Azure Container Networking Interface (CNI)

 

CLI

 

Vou usar vários comandos de CLI, começando com a CLI do AKS que precisa ser instalada. Também será preciso logar na conta do Azure usando a CLI do Azure e para isso use os comandos abaixo.

instalar o Azure CLI

# Fazer login na conta do Azure  
az login  
az account set --subscription <id>  
# Baixar a CLI do AKS  
az aks install-cli  

 

Criando cluster via CLI

 

Para criar containers Windows, precisamos usar o plugin Azure CNI, com o parâmetro –network-plugin azure, mas existem outros detalhes como a necessidade de atrelar a uma subnet, e em um service principal. O node pool inicial vai ser criado em Linux mas poderemos adicionar um segundo node pool com windows sem problemas siga os comandos abaixo para criar subir uma aplicação .NET Full Framework 4.8 chamada POC_KUBE_KEYVAULT, você pode usar qualquer aplicação semelhante no lugar dela.

 

Primeiro passo vamos criar a VNET

 

$vnet = az network vnet create `
--name AKS_BLOG_MS_VNET `
--resource-group AKS_BLOG_MS `
--subnet-name default

 

Depois criar o service principal

 

$sp=$(az identity create --name aks03sp --resource-group AKS_BLOG_MS | ConvertFrom-Json)

az role assignment create `
--assignee $sp.clientId `
--resource-group AKS_BLOG_MS `
--role "Network Contributor"

 

Listar a subnet

 

Vamos obter o ID do recurso de sub-rede para a rede virtual existente na qual o cluster AKS será associado

$subnetId = az network vnet subnet list `
--resource-group AKS_BLOG_MS `
--vnet-name AKS_BLOG_MS_VNET `
--query "[0].id" --output tsv

 

Por fim criar o cluster com node pool principal

 

Aqui vamos criar a instancia do AKS com um node pool Linux, ele é obrigatório e só depois de criado a instancia é que vamos adicionar um node pool com windows, observe que já na criação da instancia definimos o plugin de rede Azure CNI.

az aks create `
    --resource-group AKS_BLOG_MS `
    --name aks03blog `
    --network-plugin azure `
    --vnet-subnet-id $subnetId `
    --docker-bridge-address 172.17.0.1/16 `
    --dns-service-ip 10.2.0.10 `
    --service-cidr 10.2.0.0/24 `
    --generate-ssh-keys `
    --enable-managed-identity `
    --assign-identity $sp.id `
    --node-count 1

 

Finalmente criamos o node pool windows

 

az aks nodepool add `
    --resource-group AKS_BLOG_MS `
    --cluster-name aks03blog `
    --os-type Windows `
    --name npwin `
    --node-count 1

Para saber mais clique aqui

É possível usar o Cloud Shell direto no portal do Azure Assim não precisamos instalar as CLI no nosso ambiente, mas eu prefiro usar local.

 

Vamos conectar no cluster

 

# Obter credenciais de acesso para um cluster Kubernetes gerenciado  
az aks get-credentials --resource-group AKS_BLOG_MS --name aks03blog    

 

Listar e limpar os contextos

 

# Lista quais contextos ja foram configurados  
kubectl config get-contexts
# reseta todos os contextos  
kubectl config unset contexts  

 

Agora já podemos usar alguns comandos do "kubectl" como listar um determinado tipo de recurso, podemos utilizar o comando "kubectl" get e o tipo do recurso

 

kubectl get pods    
kubectl get nodes    
kubectl get deployments    
kubectl get services    
kubectl logs <nomedopod>  
kubectl top nodes

O comando "kubectl" logs exibe os logs de um container que está dentro do pod selecionado. O "kubectl" top nodes, por sua vez, lista os nodes do cluster de acordo com o uso de CPU e Memória.

 

Docker File imagem Windows

 

Agora vamos empacotar nossa aplicação em uma imagem utilizando do docker, esse arquivo apenas pega uma imagem windows desse repositório mcr.microsoft.com e copia os arquivos já compilados para dentro da pasta inetpub/wwwroot

FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019  
WORKDIR /inetpub/wwwroot  
COPY /POC_KUBE_KEYVAULT/bin/publish .   
RUN DIR  
EXPOSE 80:80

Eu não adicionei o passo para compilar a aplicação com o msbuild, por isso é preciso que você faça isso na mão e aponte para a pasta dos arquivos compilados.

 

Compilação do arquivo DockerFile

 

docker build -t poc_kube_keyvault:dev01 .  
docker images
docker images  
REPOSITORY                                  TAG                              IMAGE ID       CREATED          SIZE  
poc_kube_keyvault                           dev01                            71489f0f1f38   12 minutes ago   8.79GB  
mcr.microsoft.com/dotnet/framework/aspnet   4.8-windowsservercore-ltsc2019   828e8fa2b4fd   2 weeks ago      8.75GB

 

Azure Container Registry

 

O ACR é um Registry Privado para hospedar imagens de containers. Usando o ACR, é possível armazenar as suas imagens de forma segura, como se fosse um repositório de código, mas no lugar de código temos as imagens.

 

Criar instância do ACR

 

az acr create --resource-group AKS_BLOG_MS --name acr03blog  --sku Basic
Criando uma instância do ACR

 

Login ACR

 

az acr login -n acr03blog.azurecr.io  

 

Criar TAG

 

docker tag poc_kube_keyvault:dev01 acr03blog.azurecr.io/pockubekeyvault:latest

 

Subindo a Imagem no acr

 

docker push acr03blog.azurecr.io/pockubekeyvault:latest

 

Criar manifesto YAML para Deploy

 

Para criar a aplicação, vamos criar um deploy. O deploy é como uma abastração do pod. Com ele, é possível configurar o número de réplicas do pod e utilizar estratégias de deploy. Uma dica para criar os arquivos YAML facilmente, é utilizar a linha de comando, com o "kubectl" create deploy, com o parametro o –dry-run=client -o yaml para gerar o yaml base.

 

kubectl create deploy pocaks --image=acr03blog.azurecr.io/pockubekeyvault:latest --dry-run=client -o yaml > deployblog01.yaml

 

Manifesto gerado

 

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: pocaks
  name: pocaks
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pocaks
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: pocaks
    spec:
      containers:
      - image: acr03blog.azurecr.io/pockubekeyvault:latest
        name: pockubekeyvault
        resources: {}
status: {}

 

Adicionar um node selector para o label do sistema operacional

 

kubectl get nodes

NAME                                STATUS   ROLES   AGE     VERSION
aks-nodepool1-14817848-vmss000000   Ready    agent   5h56m   v1.24.6
aksnpwin000000                      Ready    agent   35m     v1.24.6

kubectl describe node aksnpwin000000

Vamos usar o label kubernetes.io/os:windows

nodeSelector:
    kubernetes.io/os: windows

 

Final

 

apiVersion: apps/v1  
kind: Deployment  
metadata:  
  creationTimestamp: null  
  labels:  
    app: pocaks  
  name: pocaks  
spec:  
  replicas: 1  
  selector:  
    matchLabels:  
      app: pocaks  
  strategy: {}  
  template:  
    metadata:  
      creationTimestamp: null  
      labels:  
        app: pocaks  
    spec:  
      containers:  
      - image: acr03blog.azurecr.io/pockubekeyvault:latest
        name: pockubekeyvault  
        resources: {}  
      nodeSelector:
        kubernetes.io/os: windows
status: {}

 

Deploy no AKS

 

kubectl create -f deployblog01.yaml

 

Criar arquivo YAML para Serviço

 

Após criar o deployment, é necessário expor os nossos pods para que seja possível acessá-los publicamente. Para isso, vamos utilizar um load balancer com um ip público o Kubernet usa uma abstração chamada de Service para configurá-lo:

kubectl expose -f deployblog01.yaml --name=pocsvc --type=LoadBalancer --port=80 --target-port=80 --dry-run=client -o yaml > svcblog01.yaml

 

Manifesto do serviço gerado

 

apiVersion: v1  
kind: Service  
metadata:  
  creationTimestamp: null  
  labels:  
    app: pocaks  
  name: pocsvc  
spec:  
  ports:  
  - port: 80  
    protocol: TCP  
    targetPort: 80  
  selector:  
    app: pocaks  
  type: LoadBalancer  
status:  
  loadBalancer: {}

 

Deploy do serviço no AKS

 

kubectl create -f svcblog01.yaml

O segredo do AKS são os arquivos de yaml, eles vão ser a principal interface de configuração do AKS, nesse momento perceba que existe uma relação entre o arquivo da Aplicação e o Arquivo de Serviço, o primeiro yaml criar uma deploy de uma imagem especifica e chama isso de pocaks o segundo arquivo cria uma forma de acessar essa aplicação e aponta para ela usando o mesmo label pocaks.

 

Vamos ver qual o IP público

 

kubectl get services
kubectl get services  
NAME         TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)        AGE  
kubernetes   ClusterIP      10.0.0.1      <none>           443/TCP        18h  
pocsvc       LoadBalancer   10.0.198.13   20.237.239.202   80:31401/TCP   17h

Tentei acessar usando o ip externo acima do serviço pocsvc, mas a aplicação ainda não estava respondendo, então comecei a dar uma olhada no cluster usando os comandos de CLI.

kubectl get pods  
NAME                      READY   STATUS             RESTARTS   AGE  
pocaks-859797885f-lnmsp   0/1     ImagePullBackOff   0          3m47s

 

Vamos ver os logs

 

kubectl get event --sort-by='.metadata.creationTimestamp' -A  
kubectl describe pod pocaksapi-59c9b558ff-gf4zl  
kubectl describe deployment pocaks

Encontrei essa entrada no log de eventos do AKS, e pelo que parece o que está faltando e atachar o ACR no AKS de forma que ele possa acessá-lo.

default 3m39s Warning Failed pod/pocaks-859797885f-j4tgb Failed to pull image “keyvaultaks.azurecr.io/pockubekeyvault:latest”: rpc error: code = Unknown desc = failed to pull and unpack image “keyvaultaks.azurecr.io/pockubekeyvault:latest”: failed to resolve reference “keyvaultaks.azurecr.io/pockubekeyvault:latest”: failed to authorize: failed to fetch anonymous token: unexpected status: 401 Unauthorized

az aks update -n aks03blog -g AKS_BLOG_MS --attach-acr acr03blog

Integrate Azure Container Registry with Azure Kubernetes Service - Azure Kubernetes Service

kubectl get pods  
NAME                     READY   STATUS    RESTARTS   AGE  
pocaks-b87d78d46-wdts5   1/1     Running   0          30m

Demorou um pouco, mas deu certo!

az aks check-acr --name aks03blog --resource-group AKS_BLOG_MS --acr acr03blog.azurecr.io
http://20.237.239.202/

Referências

  1. Multiplos node pools
  2. Configure Azure CNI
Updated Jan 17, 2023
Version 2.0
No CommentsBe the first to comment