Actualizando K3S con system-upgrade-controller
Introducción
En esta breve actualización, voy a hacer que todos los nodos puedan conectarse y comunicarse entre sí utilizando la librería libcluster con una configuración básica.
Actualizando paquetes
Para que esto funcione, necesitás agregar en mix.exs
:
{:libcluster, "~> 3.3"},
Actualizá tu archivo lib/tr/application.ex
para iniciar libcluster:
topologies = Application.get_env(:libcluster, :topologies, [])
children = [
# Iniciar el supervisor del Cluster para libcluster
{Cluster.Supervisor, [topologies, [name: Tr.ClusterSupervisor]]},
...
Luego necesitás actualizar tu archivo config/prod.exs
para indicarle a libcluster qué buscar en el clúster:
# Configuración de Libcluster
config :libcluster,
topologies: [
erlang_nodes_in_k8s: [
strategy: Elixir.Cluster.Strategy.Kubernetes.DNS,
config: [
service: "tr-cluster-svc",
application_name: "tr",
kubernetes_namespace: "tr",
polling_interval: 10_000
]
]
]
Config para desarrollo config/dev.exs
:
config :libcluster,
topologies: [
example: [
strategy: Cluster.Strategy.Epmd,
config: [hosts: [:"[email protected]", :"[email protected]"]],
connect: {:net_kernel, :connect_node, []},
disconnect: {:erlang, :disconnect_node, []},
list_nodes: {:erlang, :nodes, [:connected]}
]
]
Eso es suficiente para que Elixir intente encontrar los otros pods y conectarse a los nodos. Sin embargo, necesitamos permitir esa comunicación y dejar que los pods lean la información de la API de Kubernetes. A continuación, agregá estos permisos a tu despliegue en 05-role.yaml
:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: tr
name: pod-reader
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: tr
subjects:
- kind: ServiceAccount
name: tr
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Luego en tu archivo 02-deployment.yaml
:
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
Y un servicio para facilitar las cosas 03-service.yaml
(puerto epmd):
apiVersion: v1
kind: Service
metadata:
name: tr-cluster-svc
namespace: tr
spec:
clusterIP: None
selector:
name: tr
Esto es para establecer las variables de entorno correctas para que la aplicación las use y pueda conectarse a los otros nodos
.
Antes de seguir, asegurate de generar los archivos de release:
mix release.init
Ahora actualizá tu archivo rel/env.sh.eex
para que se vea así:
export RELEASE_DISTRIBUTION=name
export RELEASE_NODE=<%= @release.name %>@${POD_IP}
Si todo salió bien, deberías ver algo como esto en los logs:
tr-deployment-6cf5c65b56-ndrgm tr 04:13:13.411 [info] [libcluster:erlang_nodes_in_k8s] connected to :"[email protected]"
tr-deployment-6cf5c65b56-ndrgm tr 04:13:13.416 [info] [libcluster:erlang_nodes_in_k8s] connected to :"[email protected]"
Si querés validarlo localmente, usá este comando desde iex
:
❯ iex --name a@127.0.0.1 --cookie secret -S mix
❯ iex --name b@127.0.0.1 --cookie secret -S mix
iex(b@127.0.0.1)> Node.list()
Algunos enlaces útiles: https://hexdocs.pm/libcluster/readme.html https://hexdocs.pm/libcluster/Cluster.Strategy.Kubernetes.DNS.html https://brain.d.foundation/Engineering/Backend/libcluster+in+elixir
y por último pero no menos importante, ¡buena suerte!
Notas finales
Haceme saber si hay algo que te gustaría ver implementado, probado, explorado o lo que sea en este espacio…
Errata
Si encontrás algún error o tenés alguna sugerencia, mandame un mensaje para que se pueda corregir.
También podés revisar el código fuente y los cambios en los sources aquí
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.