*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

com illustration for: Pré-requisitos

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

  • O Docker executando em sua máquina local.

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:

				
					
[label 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:

				
					
[label 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 &lt;^&gt;your_DockerHub_username&lt;^&gt;/hello-world:latest

				
			

Agora, envie-a para o Docker Hub:

				
					
docker push &lt;^&gt;your_DockerHub_username&lt;^&gt;/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<^>:

				
					
[label ~/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: &lt;^&gt;your_DockerHub_username&lt;^&gt;/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 the cloud provider:

				
					
[label 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 the cloud provider.
  • 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:

				
					
[secondary_label 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:

				
					
[secondary_label Output]

NAME          TYPE        CLUSTER-IP         EXTERNAL-IP       PORT(S)    AGE

hello-world   ClusterIP   &lt;^&gt;your_cluster_ip&lt;^&gt;   &lt;^&gt;your_external_ip&lt;^&gt;  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.

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:

				
					
[label 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

				
			
				
					
[secondary_label Output]

 ✓  Development environment activated

 ✓  Files synchronized

    Namespace: default

    Name:      hello-world



Welcome to your development environment. Happy coding!

default:hello-world /app&gt;

				
			

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

				
			
				
					
[secondary_label 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 the cloud provider! <^>:

				
					
[label 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, "&lt;^&gt;Hello world from the cloud provider!&lt;^&gt;")

}

				
			

É 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&gt; go run main.go

				
			
				
					
[secondary_label Output]

Starting hello-world server...

				
			

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

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 the cloud provider.