Tutorial

Como desenvolver aplicações no Kubernetes com o Okteto

DevelopmentOpen SourceKubernetesDigitalOcean Managed Kubernetes

O autor selecionou Girls Who Code para receber uma doação como parte do programa Write for DOnations.

Introdução

O Okto CLI é um projeto de código aberto que fornece uma experiência de desenvolvimento local para aplicações em execução no Kubernetes. Com ele, você pode escrever seu código em seu IDE local e assim que você salvar um arquivo, as alterações podem ser enviadas para seu cluster Kubernetes e seu app irá atualizar imediatamente. Todo este processo acontece sem a necessidade de compilar imagens Docker ou aplicar os manifestos do Kubernetes, o que pode levar muito tempo.

Neste tutorial, você usará o Okteto para melhorar sua produtividade ao desenvolver uma aplicação nativa para o Kubernetes. Primeiro, você criará um cluster Kubernetes e o utilizará para executar uma aplicação “Hello World” padrão. Em seguida, você usará o Okteto para desenvolver e atualizar automaticamente sua aplicação sem ter nada localmente.

Pré-requisitos

Antes de iniciar este tutorial, você vai precisar do seguinte:

Passo 1 — Criando a aplicação Hello World

O programa “Hello World” é uma antiga tradição no desenvolvimento Web. Neste caso, ele é um Web service simples que responde “Hello World” a cada requisição. Agora que você criou seu cluster Kubernetes, vamos criar um app “Hello World” no Golang e os manifestos que você usará para fazer a implantação do app no Kubernetes.

Primeiro, vá para seu diretório home:

  • cd ~

Agora, crie um novo diretório chamado hello_world e entre nele:

  • mkdir hello_world
  • cd hello_world

Crie e abra um novo arquivo sob o nome main.go com seu IDE ou editor de texto favorito:

  • nano main.go

O main.go será um servidor Web Golang que retorna a mensagem Hello world! Então, vamos usar o seguinte código:

main.go
package main

import (
    "fmt"
    "net/http"
)

func main() {
    fmt.Println("Starting hello-world server...")
    http.HandleFunc("/", helloServer)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

func helloServer(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello world!")
}

O código no main.go faz o seguinte:

  • A primeira instrução em um arquivo de código-fonte em Go deve ser o nome do pacote (package). Comandos executáveis devem sempre usar package main.
  • A seção import indica de quais pacotes o código depende. Neste caso, ele utiliza o fmt para manipulação de string e net/http para o servidor HTTP.
  • A função main é o entry point do seu binário. O método http.HandleFunc é usado para configurar o servidor para chamar a função helloServer quando uma requisição para o caminho / for recebida. http.ListenAndServe inicia um servidor HTTP que escuta em todas as interfaces de rede na porta 8080.
  • A função helloServer contém a lógica do seu tratamento de requisições. Neste caso, ele irá escrever Hello world! como a resposta à requisição.

Você precisa criar uma imagem Docker e enviá-la para seu registro Docker para que o Kubernetes possa baixá-la e, em seguida, executar a aplicação.

Abra um novo arquivo com o nome Dockerfile com seu IDE ou editor de texto favorito:

  • nano Dockerfile

O Dockerfile conterá os comandos necessários para compilar o contêiner Docker da sua aplicação. Vamos usar o seguinte código:

Dockerfile
FROM golang:alpine as builder
RUN apk --update --no-cache add bash
WORKDIR /app
ADD . .
RUN go build -o app

FROM alpine as prod
WORKDIR /app
COPY --from=builder /app/app /app/app
EXPOSE 8080
CMD ["./app"]

O Dockerfile contém dois estágios, builder e prod:

  • O estágio builder contém as ferramentas Go build. Ele é responsável por copiar os arquivos e compilar o binário Go.
  • O estágio prod é a imagem final. Ela conterá apenas um SO simplificado e o binário da aplicação.

Esta é uma boa prática a seguir. Ela torna seus contêineres de produção menores e mais seguros, pois eles contêm apenas sua aplicação e exatamente o que é necessário para executá-la.

Compile a imagem de contêiner (substitua your_DockerHub_username com seu nome de usuário no Docker Hub):

  • docker build -t your_DockerHub_username/hello-world:latest

Agora, envie-a para o Docker Hub:

  • docker push your_DockerHub_username/hello-world:latest

Em seguida, crie uma nova pasta para os manifestos do Kubernetes:

  • mkdir k8s

Quando você usa um manifesto do Kubernetes, você informa a ele como quer que a aplicação seja executada. Desta vez, você criará um objeto de implantação. Então, crie um novo arquivo deployment.yaml com seu IDE ou editor de texto favorito:

  • nano k8s/deployment.yaml

O conteúdo a seguir descreve um objeto de implantação do Kubernetes que executa a imagem Docker okteto/hello-world:latest. Adicione este conteúdo ao seu novo arquivo, mas no seu caso substitua okteto listado após o rótulo image por your_DockerHub_username:

~/hello_world/k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  selector:
    matchLabels:
      app: hello-world
  replicas: 1
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: hello-world
        image: your_DockerHub_username/hello-world:latest
        ports:
        - containerPort: 8080

O manifesto para fazer a implantação tem três seções principais:

  • metadata define o nome da sua implantação.
  • replicas define quantas cópias dela você deseja em execução.
  • template informa ao Kubernetes o que implantar e quais rótulos adicionar. Neste caso, um único contêiner, com a imagem okteto/hello-world:latest, escutando na porta 8080, e com o rótulo app: hello-world. Observe que este rótulo é o mesmo usado na seção selector.

Agora, você precisará de uma maneira de acessar sua aplicação. Você pode expor uma aplicação no Kubernetes criando um objeto de serviço. Vamos continuar usando os manifestos para fazer isso. Crie um novo arquivo chamado service.yaml com seu IDE ou editor de texto favorito:

  • nano k8s/service.yaml

O conteúdo a seguir descreve um serviço que expõe o objeto de implantação hello-world, que por trás , usará um balanceador de carga da DigitalOcean:

k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: hello-world
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
      name: http
  selector:
    app: hello-world

O manifesto de serviço tem quatro seções principais:

  • metadata informa ao Kubernetes como nomear seu serviço.
  • type informa ao Kubernetes como você deseja expor seu serviço. Neste caso, ele irá expô-lo externamente através de um balanceador de carga da DigitalOcean.
  • O rótulo ports informa ao Kubernetes quais portas você deseja expor, e como mapeá-las para a sua implantação. Neste caso, você irá expor a porta 80 externamente e direcioná-la para a porta 8080 em sua implantação.
  • selector informa ao Kubernetes como direcionar tráfego. Neste caso, qualquer pod com o rótulo app: hello-world receberá tráfego.

Agora, você tem tudo pronto para fazer a implantação da sua aplicação “Hello World” no Kubernetes. Vamos fazer isso a seguir.

Passo 2 — Fazendo a implantação da sua aplicação Hello World

Neste passo, você irá fazer a implantação da sua aplicação “Hello World” no Kubernetes, e, em seguida, você validará se ela está funcionando corretamente.

Comece fazendo a implantação de sua aplicação no Kubernetes:

  • kubectl apply -f k8s

Você verá o seguinte resultado:

Output
deployment.apps "hello-world" created service "hello-world" created

Após cerca de um minuto ou mais, você será capaz de recuperar o IP da sua aplicação. Use este comando kubectl para verificar seu serviço:

  • kubectl get service hello-world

Você verá uma saída como esta listando seus objetos de serviço do Kubernetes. Observe o IP da sua aplicação na coluna EXTERNAL-IP:

Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-world ClusterIP your_cluster_ip your_external_ip 8080/TCP 37s

Abra seu navegador e vá para your_external_ip listado para sua aplicação “Hello World”. Confirme que sua aplicação está funcionando antes de continuar com o próximo passo.

Hello World Okteto

Até este momento, você seguiu uma rota bastante tradicional para o desenvolvimento de aplicações com o Kubernetes. Avançando, sempre que você desejar alterar o código em sua aplicação, você terá que compilar e enviar uma nova imagem Docker, e, em seguida, baixar esta imagem do Kubernetes. Esse processo pode levar algum tempo. O Okteto foi projetado para simplificar este loop interno de desenvolvimento. Vamos dar uma olhada no Okteto CLI e ver como ele pode ajudar.

Passo 3 — Instalando o Okteto CLI

Agora, você irá melhorar sua produtividade de desenvolvimento no Kubernetes instalando o Okteto CLI. A interface de linha de comando do Okteto é um projeto de código aberto que lhe permite sincronizar alterações de código da aplicação com uma aplicação executando no Kubernetes. Você pode continuar usando seu IDE, debuggers, ou compiladores favoritos sem ter que fazer commit, compilação, envio ou reimplantação de contêineres para testar sua aplicação – como você fez nos passos anteriores.

Para instalar o Okteto CLI em uma máquina macOS ou Linux, execute o seguinte comando:

  • curl https://get.okteto.com -sSfL | sh

Vamos dar uma olhada mais de perto neste comando:

  • O comando curl é usado para transferir dados de e para um servidor.
  • A flag -s suprime qualquer saída.
  • A flag -S mostra erros.
  • A flag -f faz com que a requisição falhe em erros de HTTP.
  • A flag -L faz com que a requisição siga redirecionamentos.
  • O operador | direciona esta saída para o comando sh, que irá baixar e instalar o binário mais recente do okteto em sua máquina local.

Se você estiver executando o Windows, você pode baixar alternadamente o arquivo através do seu navegador Web e adicioná-lo manualmente.ao seu $PATH.

Assim que o Okteto CLI estiver instalado, você está pronto para colocar sua aplicação “Hello World” em modo de desenvolvimento.

Passo 4 — Colocando sua aplicação Hello World no modo de desenvolvimento

O Okteto CLI foi projetado para alternar a aplicação em execução em um cluster Kubernetes com o código que você tem em sua máquina. Para fazer isso, o Okteto utiliza as informações fornecidas a partir de um arquivo de manifesto do Okteto. Este arquivo declara o objeto de implantação do Kubernetes que irá alternar com seu código local.

Crie um novo arquivo chamado okteto.yaml com seu IDE ou editor de texto favorito:

  • nano okteto.yaml

Vamos escrever um manifesto básico onde você define o nome do objeto de implantação, a imagem base do Docker a usar e um shell. Voltaremos a essas informações mais tarde. Use o seguinte arquivo de conteúdo de amostra:

okteto.yaml
name: hello-world
image: okteto/golang:1
workdir: /app
command: ["bash"]

Prepare-se para colocar sua aplicação em modo de desenvolvimento executando o seguinte comando:

  • okteto up
Output
✓ Development environment activated ✓ Files synchronized Namespace: default Name: hello-world Welcome to your development environment. Happy coding! default:hello-world /app>

O comando okteto up alterna a aplicação “Hello World” em um ambiente de desenvolvimento, o que significa:

  • O contêiner da aplicação Hello World é atualizado com a imagem docker okteto/golang:1. Esta imagem contém as ferramentas de desenvolvimento necessárias para compilar, testar, debugar e executar a aplicação “Hello World”.

  • Um serviço de sincronização de arquivos é criado para manter suas alterações atualizadas entre seu sistema de arquivos local e seus pods da aplicação.

  • Um shell remoto inicia em seu ambiente de desenvolvimento. Agora, você pode compilar, testar, e executar sua aplicação como se você estivesse em sua máquina local.

  • Qualquer processo que você executar no shell remoto receberá o mesmo tráfego de entrada, as mesmas variáveis de ambiente, volumes, ou segredos que os pods da aplicação original “Hello World”. Isso, por sua vez, lhe dá um ambiente de desenvolvimento altamente realista, como em produção.

No mesmo console, agora execute a aplicação como você faria normalmente (sem compilar e enviar uma imagem Docker), desta forma:

  • go run main.go
Output
Starting hello-world server...

A primeira vez que você executar a aplicação, o Go baixará suas dependências e compilará sua aplicação. Espere este processo terminar e teste sua aplicação, abrindo seu navegador e atualizando a página da sua aplicação, assim como você fez anteriormente.

Agora, tudo está pronto para começar a desenvolver diretamente no Kubernetes.

Passo 5 — Desenvolvendo diretamente no Kubernetes

Vamos começar a fazer alterações na aplicação “Hello World” e, em seguida, ver como essas alterações se refletem no Kubernetes.

Abra o arquivo main.go com seu IDE ou editor de texto favorito. Por exemplo, abra um console separado e execute o seguinte comando:

  • nano main.go

Em seguida, altere sua mensagem de resposta para Hello world from DigitalOcean! :

main.go
package main

import (
    "fmt"
    "net/http"
)

func main() {
    fmt.Println("Starting hello-world server...")
    http.HandleFunc("/", helloServer)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

func helloServer(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello world from DigitalOcean!")
}

É aqui que seu fluxo de trabalho muda. Em vez de compilar e refazer a implantação de contêineres para atualizar a aplicação “Hello World”, o Okteto sincronizará suas alterações com o seu ambiente de desenvolvimento no Kubernetes.

A partir do console onde você executou o comando okteto up, cancele a execução do go run main.go pressionando CTRL + C. Agora, execute novamente a aplicação:

  • default:hello-world /app> go run main.go
Output
Starting hello-world server...

Volte ao navegador e recarregue a página para sua aplicação “Hello World”.

Hello world DigitalOcean"

Suas alterações de código foram aplicadas instantaneamente ao Kubernetes, e tudo sem exigir quaisquer commits, compilações, ou envios.

Conclusão

O Okteto transforma seu cluster Kubernetes em uma plataforma de desenvolvimento completa ao clique de um botão. Neste tutorial, você instalou e configurou o Okteto CLI para iterar suas alterações de código diretamente no Kubernetes, tão rápido quanto você pode digitar código. Agora, você pode ir ao repositório de amostras do Okteto para ver como usá-lo com diferentes linguagens de programação e debuggers

Além disso, se você compartilhar um cluster Kubernetes com sua equipe, considere dar acesso a cada membro a um namespace seguro, configurado para estar isolado de outros desenvolvedores trabalhando no mesmo cluster. Esta ótima funcionalidade também é fornecida pelo Okteto App no Marketplace de Kubernetes da DigitalOcean.

Creative Commons License