Bot eco hecho en Go
Bot de eco
Esta publicación iba a ser sobre el uso avanzado de ksonnet, pero terminó siendo más sobre el bot de eco en sí, así que decidí renombrarla.
Para ser honesto, no hay otra forma de obtener los beneficios de tener ksonnet si no vas a aprovechar las facilidades de despliegues como código que trae gracias a Jsonnet.
Esta vez veremos cómo usar plantillas adecuadas; parece que las plantillas generadas con ks
están desactualizadas. Al momento de escribir esto, la versión de ksonnet es 0.13.1, sin sorpresa aquí porque no es una herramienta realmente madura. Requiere mucho esfuerzo en aprender, hackear y leer para que las cosas funcionen, pero espero que pronto sea más fácil; por supuesto, esta es mi opinión personal y aún no lo he usado para un proyecto real, pero espero que crezca y se vuelva más usable antes de intentar hacer algo para el mundo real con él.
En los ejemplos estaré usando minikube o puedes revisar este repositorio que tiene una buena visión general de minikube. Una vez instalado y iniciado (minikube start
), ese comando descargará y configurará el entorno local; si has estado siguiendo las publicaciones anteriores, ya tienes minikube instalado y funcionando:
Empecemos
Esta vez no voy a desplegar otra instancia de WordPress sino un simple bot de eco de Slack hecho con Go:
package main
import (
"fmt"
"os"
"strings"
slack "github.com/nlopes/slack"
)
func main() {
api := slack.New(
os.Getenv("SLACK_API_TOKEN"),
)
rtm := api.NewRTM()
go rtm.ManageConnection()
for msg := range rtm.IncomingEvents {
fmt.Print("Event Received: ")
switch ev := msg.Data.(type) {
case *slack.HelloEvent:
// Ignore hello
case *slack.ConnectedEvent:
fmt.Println("Infos:", ev.Info)
fmt.Println("Connection counter:", ev.ConnectionCount)
case *slack.MessageEvent:
// Only echo what it said to me
fmt.Printf("Message: %v\n", ev)
info := rtm.GetInfo()
prefix := fmt.Sprintf("<@%s> ", info.User.ID)
if ev.User != info.User.ID && strings.HasPrefix(ev.Text, prefix) {
rtm.SendMessage(rtm.NewOutgoingMessage(ev.Text, ev.Channel))
}
case *slack.PresenceChangeEvent:
fmt.Printf("Presence Change: %v\n", ev)
case *slack.LatencyReport:
fmt.Printf("Current latency: %v\n", ev.Value)
case *slack.RTMError:
fmt.Printf("Error: %s\n", ev.Error())
case *slack.InvalidAuthEvent:
fmt.Printf("Invalid credentials")
return
default:
// Ignore other events..
// fmt.Printf("Unexpected: %v\n", msg.Data)
}
}
}
Como puedes ver, es el ejemplo más simple del archivo readme del proyecto Go Slack API. Solo se conecta a Slack y cuando lee un mensaje, si está dirigido al bot, entonces devuelve el mensaje. Crear un bot y todo lo demás está fuera del alcance de este artículo, pero es realmente simple. Solo necesitas crear una aplicación en el espacio de trabajo de Slack, configurarla como un bot y obtener el token (hay mucho más que puedes personalizar, pero ese es el procedimiento más básico para comenzar con un bot), luego lo invitas a cualquier canal que quieras y comienzas a interactuar con él.
Aquí puedes ver el Dockerfile
; por seguridad, creamos un usuario de aplicación para la compilación y para ejecutarlo, y para ahorrar espacio y ancho de banda, solo enviamos lo que necesitamos usando una compilación de múltiples etapas:
# Build
FROM golang:1.11.2-alpine as builder
WORKDIR /app
RUN adduser -D -g 'app' app && \
chown -R app:app /app && \
apk add git && apk add gcc musl-dev
ADD . /app/
RUN go get -d -v ./... && go build -o main . && chown -R app:app /app /home/app
# Run
FROM golang:1.11.2-alpine
WORKDIR /app
RUN adduser -D -g 'app' app && \
chown -R app:app /app
COPY --from=builder --chown=app /app/health_check.sh /app/health_check.sh
COPY --from=builder --chown=app /app/main /app/main
USER app
CMD ["/app/main"]
Hay algunos archivos más allí; puedes ver las fuentes completas aquí, por ejemplo health_check.sh
, como nuestra aplicación no escucha en ningún puerto, necesitamos una forma de decirle a Kubernetes cómo verificar si nuestra aplicación está viva.
Bien, suficiente código repetitivo, vamos al grano, así que creemos una nueva aplicación ksonnet:
$ ks init echobot
INFO Using context "minikube" from kubeconfig file "~/.kube/config"
INFO Creating environment "default" with namespace "default", pointing to "version:v1.8.0" cluster at address "https://192.168.99.100:8443"
INFO Generating ksonnet-lib data at path '~/Webs/echobot/echobot/lib/ksonnet-lib/v1.8.0'
Y ahora tomemos una plantilla y modifiquémosla adecuadamente para poder crear el despliegue para el bot components/echobot.jsonnet
:
// Import KSonnet library
local params = std.extVar('__ksonnet/params').components.demo;
local k = import 'k.libsonnet';
// Specify the import objects that we need
local container = k.extensions.v1beta1.deployment.mixin.spec.template.spec.containersType;
local depl = k.extensions.v1beta1.deployment;
// Environment variables, instead of hardcoding it here we could use a param or a secret
// But I will leave that as an exercise for you :)
local envs = [
{
name: 'SLACK_API_TOKEN',
value: 'really-long-token',
},
];
local livenessProbe = {
exec: {
command: [
'/bin/sh',
'-c',
'/app/health_check.sh',
],
},
};
// Define containers
local containers = [
container.new('echobot', 'kainlite/echobot:0.0.2') {
env: (envs),
livenessProbe: livenessProbe,
},
];
// Define deployment with 3 replicas
local deployment =
depl.new('echobot', 1, containers, { app: 'echobot' });
local resources = [deployment];
// Return list of resources.
k.core.v1.list.new(resources)
Ten en cuenta que he subido esa imagen a Docker Hub, así que puedes usarla para seguir el ejemplo si quieres; después de eso, simplemente reemplaza really-long-token
con tu token, y luego haz:
$ ks apply default
INFO Applying deployments echobot
INFO Creating non-existent deployments echobot
Y ahora, si verificamos nuestro despliegue y pod, deberíamos ver algo como esto:
Y en los logs:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
echobot-7456f7d7dd-twg4r 1/1 Running 0 53s
$ kubectl logs -f echobot-7456f7d7dd-twg4r
Event Received: Event Received: Infos: &{wss://cerberus-xxxx.lb.slack-msgs.com/websocket/1gvXP_yQCFE-Y= 0xc000468000 0xc0004482a0 [] [] [] [] []}
Connection counter: 0
Event Received: Event Received: Current latency: 1.256397423s
Event Received: Current latency: 1.25679313s
Event Received: Current latency: 1.256788737s
Event Received: Message: &{{message CEDGU6EA0 UEDJT5DDH <@UED48HD33> echo! 1546124966.002300 false [] [] <nil> false 0 false 1546124966.002300 <nil> [] 0 [] [] false <nil> 0 TEDJT5CTD [] false false} <nil>}
Y eso es todo por ahora; espero que hayas disfrutado este pequeño recorrido por ksonnet. El código fuente del bot se puede encontrar aquí. En una publicación futura, podría explorar ksonnet y charts de helm.
Temas próximos
Como prometí, haré una publicación sobre Gitkube y Skaffold; hay muchas herramientas de despliegue para Kubernetes, pero esas son las más prometedoras para mí. Además, después de eso, comenzaré a cubrir más temas sobre Docker, ContainerD, KubeADM, y Kubernetes en general.
Erratas
Si encuentras algún error o tienes alguna sugerencia, por favor envíame un mensaje para que pueda corregirlo.
No tienes cuenta? Regístrate aqui
Ya registrado? Iniciar sesión a tu cuenta ahora.
-
Comentarios
Online: 0
Por favor inicie sesión para poder escribir comentarios.