Table of Contents
*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:
- Um cluster Kubernetes 1.12+. Neste tutorial, a configuração utilizará um cluster Kubernetes da the cloud provider com três nodes, mas você está livre para criar um cluster usando outro método.
- O
kubectle odoctlinstalados e configurados para se comunicar com seu cluster.
- Uma conta no Docker Hub.
- 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 usarpackage <^>main<^>.
- A seção
importindica de quais pacotes o código depende. Neste caso, ele utiliza ofmtpara manipulação de string enet/httppara o servidor HTTP.
- A função
mainé o entry point do seu binário. O métodohttp.HandleFuncé usado para configurar o servidor para chamar a funçãohelloServerquando uma requisição para o caminho/for recebida.http.ListenAndServeinicia um servidor HTTP que escuta em todas as interfaces de rede na porta8080.
- A função
helloServercontém a lógica do seu tratamento de requisições. Neste caso, ele irá escreverHello 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
builderconté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<^>:
[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: <^>your_DockerHub_username<^>/hello-world:latest
ports:
- containerPort: 8080
O manifesto para fazer a implantação tem três seções principais:
metadatadefine o nome da sua implantação.
replicasdefine quantas cópias dela você deseja em execução.
templateinforma ao Kubernetes o que implantar e quais rótulos adicionar. Neste caso, um único contêiner, com a imagemokteto/hello-world:latest, escutando na porta8080, e com o rótuloapp: hello-world. Observe que este rótulo é o mesmo usado na seçãoselector.
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:
metadatainforma ao Kubernetes como nomear seu serviço.
typeinforma 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
portsinforma ao Kubernetes quais portas você deseja expor, e como mapeá-las para a sua implantação. Neste caso, você irá expor a porta80externamente e direcioná-la para a porta8080em sua implantação.
selectorinforma ao Kubernetes como direcionar tráfego. Neste caso, qualquer pod com o rótuloapp: hello-worldreceberá 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 <^>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.
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
-ssuprime qualquer saída.
- A flag
-Smostra erros.
- A flag
-ffaz com que a requisição falhe em erros de HTTP.
- A flag
-Lfaz com que a requisição siga redirecionamentos.
- O operador
|direciona esta saída para o comandosh, que irá baixar e instalar o binário mais recente dooktetoem 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>
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
[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, "<^>Hello world from the cloud provider!<^>")
}
É 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
[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.