Kubernetes – montándonos un entorno de pruebas – homeLAB!

Hace ya unas semanas estuve en vBrownBagLATAM mostrando lo fácil que es montarnos un LAB de Kubernetes, si buscamos en Internet podremos ver muchos posts de clusters usando Raspberry Pi. En mi caso intente usar LXD como base para las maquinas (contenedores) que tendrán Kubernetes, tanto el master como los nodos. Resulta que el host con Ubuntu/LXD usado para este proyecto no tiene bastante capacidad de CPU para correr varios contenedores y dentro de estos tener Kubernetes.

Así que termine con un cluster de tres Raspberry Pi y otro sin terminar basado en LXD.

En esta entrada se detalla como iniciar con tres Raspberry Pi + Hypriot + Kubernetes.

Ingredientes!

Hypriot tiene una guía en su propio portal donde describen la inicialización y configuración de un cluster de Kubernetes, es recomendable leer esa guía.

https://blog.hypriot.com/post/setup-kubernetes-raspberry-pi-cluster/

 

 

  1. Luego de introducir la imagen de Hypriot en el SD Card que usaremos en cada RPi, podremos hacer un:
  • Por defecto el RPi solicitara IP median DHCP, es recomendable cambiarlo a estático. Ha diferencia de una imagen Raspbian, la dirección IP puede ser configurada en /etc/network.

 

sudo apt update
sudo apt upgrade -y

 

  1. Lo interesante de Hypriot es que viene con Docker preinstalado, esto nos ahorra algunos minutos ya que no tenemos que hacer cambios como deshabilitar SWAP y editar la opción de cgroups. El siguiente paso es instalar Kubernetes:

 

sudo su -

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" > /etc/apt/sources.list.d/kubernetes.list

apt update

apt install -y kubeadm kubelet

 

  1. Ahora toca inicializar el master node:

 

kubeadm init --pod-network-cidr 10.244.0.0/16 --service-cidr 10.96.0.0/12 --service-dns-domain "k8s.do" --apiserver-advertise-address 44.164.67.227 --ignore-preflight-errors=all
  • Recibiremos un mensaje de confirmación relacionado a la creación del cluster, un dato importante es el $TOKEN que más adelante usaremos para asociar los nodos.
  • No es recomendable iniciar el cluster con –ignore-preflight-errors=all, esta opción se usaría como última alternativa si tenemos errores que no podemos evitar, tal como Swap en LXD.

 

  1. Usando el Usuario pirate prepararemos el ambiente para usar kubectl sin especificar config o credenciales ya que estas serán cargadas desde el ambiente de usuario.

 

mkdir -p $HOME/.kube

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

sudo chown $(id -u):$(id -g) $HOME/.kube/config

echo "export KUBECONFIG=${HOME}/.kube/config" >> ~/.bashrcsource ~/.bashrc

 

  1. Veo que muchos usan flannel como su CNI, en este cluster instalare wave, en el basado en LXD probare nuevamente con flannel. De esta manera tendría ambos CNI para comparar funcionalidades, luego se podría preparar una lista con las diferencias.

 

$ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

 

  1. Para este momento ya contamos con un master, tenemos listo el CNI, podemos proceder a agregar nodos a nuestro cluster.
  • Validamos que el CNI fue desplegado haciendo un kubectl get nodes, si nuestro nodo master tiene el estado de Ready esto quiere decir que estamos listos para el próximo paso.

 

sudo kubeadm join --token=$TOKEN

 

  • $TOKEN es el valor que recibimos cuando iniciamos nuestro master.
  • Recibiremos un mensaje indicándonos que todo aconteció correctamente y que revisemos nuestro cluster.

 

  1. Verificamos que nuestro cluster cuenta con los nodos en los cuales ejecutamos kubeadm join.
kubectl get nodes
kubectl get pods –all-namespaces

 

 

  1. Validaremos que nuestro cluster puede ejecutar “Pods”.
  • En este ejemplo, utilizare la imagen oficial de nginx y será configurada para escuchar en el puerto 80 de todos los nodos.

 

$ kubectl run nginx --image=nginx --replicas=3 --port=80

deployment "nginx" created

 

  • exponemos los Pods de nginx.

 

$ kubectl expose deployment nginx --port 80service "nginx" exposed

 

  • validamos que el puerto 80 está escuchando en los IP de nuestros nodos.

 

$ kubectl get endpoints

NAME         ENDPOINTS                                   AGE

kubernetes   192.168.7.220:6443                          37

mnginx        10.244.4.2:80,10.244.4.3:80,10.244.3.2:80   23s

 

  1. Rápidamente usando la herramienta curl, podemos validar que nginx está respondiendo en el puerto especificado.
$ curl 10.244.4.2 | head -n 5

 

  • deberíamos recibir una respuesta como la siguiente:
<DOCTYPE html>

<html>

<head>

<title>Welcome to nginx!</title>

<style>

 

  • esto confirma que nuestro Pod está siendo ejecutado correctamente en el cluster de Kubernetes, aun faltarían muchos puntos por cubrir. Acceso desde fuera del cluster es importante ya que esta es la forma que nuestros usuarios/clientes consumirán servicios como nginx.

 

Hasta el momento solo hemos realizado configuraciones básicas en un entorno de Kubernetes y posiblemente algunos lleguen a la conclusión de que es mucho trabajo para simplemente tener un nginx o alguna otra aplicación la cual se puede levantar con Docker on LXC. Lo interesante de Kubernetes es la poca diferencia en administrar un cluster con 3 nodos a uno con 40 nodos.

En las próximas entradas escribiere como instalar y utilizar Helm, así también como instalar Istio para controlar el consumo de los servicios instalados en Kubernetes.

Kubernetes – el orquestrador!

Pido disculpas por el título, fue el primero que me llego a la cabeza.

 

Kubernetes.

Desde hace unos años esta plataforma ha estado disponible para ser usada de manera gratuita, por lo menos el nombre ha estado apareciendo en búsquedas relacionadas a Containers. La instalación de la misma, por lo que he podido investigar era algo complicada, luego aparecieron herramientas para facilitar esto y proveer un método fácil de seguir para montar esta plataforma y poder crear ambientes de prueba para luego poder desplegar en producción.

 

Minukbe:

https://github.com/kubernetes/minikube

Minikube is a tool that makes it easy to run Kubernetes locally. Minikube runs a single-node Kubernetes cluster inside a VM on your laptop for users looking to try out Kubernetes or develop with it day-to-day.”

Kubeadm:

https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/

kubeadm is a toolkit that helps you bootstrap a best-practice Kubernetes cluster in an easy, reasonably secure and extensible way. It also supports managing Bootstrap Tokens for you and upgrading/downgrading clusters.”

 

Kubernetes on Ubuntu: Conjure-UP

https://kubernetes.io/docs/getting-started-guides/ubuntu/

https://docs.conjure-up.io/2.4.0/en/walkthrough

There are multiple ways to run a Kubernetes cluster with Ubuntu. These pages explain how to deploy Kubernetes on Ubuntu on multiple public and private clouds, as well as bare metal.”

conjure-up provides the quickest way to deploy Kubernetes on Ubuntu for multiple clouds and bare metal. It provides a user-friendly UI that prompts you for cloud credentials and configuration options

 

 

He iniciado mis pruebas usando kubeadm, debido a que la mayoría de los “blog posts y how to” son para crear un cluster de k8s usando Raspberry Pi. En mi caso he iniciado usando LXD para correr el master y los worker estarían siendo ejecutados en RPi con Raspbian.

Luego de mirar un poco y leer sobre el concepto de k8s decidí probar con Conjure-up, con esta solución terminamos con un Cluster de Kubernetes listo para recibir despliegues de software ya que el “conjuro” usado crea todos los componentes necesarios. El siguiente en mi lista es Minukube.

Mi objetivo final es tener una infraestructura de k8s la cual pueda usar no solo para aprender de que trata todo esto, si no también, ejecutar tareas las cuales serán partes de mi homelab.

Más adelante publicare un post donde explico paso a paso como montarnos un cluster de Kubernetes usando Ubuntu + LXD, de esta manera podremos tener todo ejecutando en una misma máquina, este es el mismo objetivo que se consigue con Conjure-up pero con la ventaja que se hace todo paso a paso y así entendemos mejor el proceso de inicialización de un cluster.

Ubuntu LXD, Alternativa ligera?

Ubuntu LXD, Alternativa ligera?

Containers!

LXD

Si se hace una búsqueda en Internet relacionada a Docker, contenedores y demás, podremos notar que se ha convertido en algo muy aceptado. Desde hace un tiempo estoy sacando provecho de Docker en mi NAS. unRAID es actualmente mi sistema de preferencia para servicios de filesharing y un beneficio adicional es la facilidad con la que se pueden lanzar contenedores con Docker y tener servicios funcionales y fáciles de mantener.

Pero en este post me gustaría hablar de LXD, esto es un desarrollo realizado por Canonical, los creadores de Ubuntu. Durante un tiempo, no era atraído por esta distribución de Linux, pero eso está cambiando gracias a las utilidades que han creado y liberado para la comunidad. Todo comenzó con LXC, lo usé para solucionar un impase en una implementación relacionada al manejo de datos .xml que necesitaban ser recibidos de manera segura, el proveedor solicitaba SFTP en un entorno aislado, en ese momento probé LXC y se crearon varios contenedores para cada proveedor. Todo funciono de maravilla y decidí seguir investigando.

De manera casi inmediata encontré un caso de uso para tenerlo en mi casa y este fue, tener pequeños Ubuntus corriendo servicios claves (DNS, MySQL, PHP, AD Blocking…), todo fue de maravilla. Hace unos días pude terminar de completar una “nueva máquina” con un board Mini-ITX + 6GB de RAM y varios SSD de tamaños entre 120GB y 60GB. Teniendo un consumo de apenas 20Watts, esta pequeña maquina es ideal para estar encendida 24/7.

Investigando la mejor manera de tener LXC, veo que Ubuntu ahora hace referencia a LXD como el siguiente paso de LXC, tomar en cuenta que LXD no es un reemplazo y es más que un complemento.

Info: https://linuxcontainers.org/lxd/introduction/#relationship-with-lxc

“ LXD isn't a rewrite of LXC, in fact it's building on top of LXC to provide a new, better user experience. Under the hood, LXD uses LXC through liblxc and its Go binding to create and manage the containers.

It's basically an alternative to LXC's tools and distribution template system with the added features that come from being controllable over the network. “

 

Instalando LXD.

Los siguientes pasos son basados en el documento oficial de LinuxContainers en la sección de LXD:

Nota: LXD puede ser instalado en las siguientes distribuciones:

  • ArchLinux
  • Fedora
  • Gentoo
  • Ubuntu
  • Debian

 

En este caso he seleccionado Ubuntu por que debería ser la distribución mejor soportada, ¿cierto?

apt install lxd lxd-client
sudo lxd init

 

Una serie de preguntas deben ser contestadas luego de ejecutar el lxd init. Siendo las más importantes la relacionada a redes, aquí se podría seleccionar crear un Bridge o utilizar uno ya existente, en mi caso opte por utilizar uno que ya había creado. La segunda opción con relevancia es el Storage, inicialmente seleccione dir como Storage backend, luego adicione un segundo disco usando ZFS.

 

Validando la instalación de LXD.

Luego de realizar la instalación podemos verificar que nuestro manejador de contenedores está operando de manera correcta con los siguientes comandos:

lxc info
lxc image list - en un entorno recién instalado este comando no presenta información.
lxc storage list
lxc network list
lxc list – en un entorno recién instalado este comando no presenta información.

 

Iniciando un contenedor.

Un nuevo contenedor puede ser creado desde una imagen, un contenedor existente o un snapshot. Por defecto LXD viene con tres repositorios de imágenes que podemos usar para crear contenedores.

  • ubuntu
  • ubuntu-daily
  • images

podemos investigar cuales imágenes están disponibles de la siguiente manera:

lxc image list ubuntu:

en pantalla nos mostrara la lista de imágenes disponibles para ser usadas, en este repositorio tenemos las versiones de Ubuntu.

Si cambiamos “ubuntu:” por “ubuntu-daily: podemos ver los snapshots generados diariamente. Si en lugar de Ubuntu usamos “images:”, tendremos una lista de todas las distribuciones que han generado imágenes y enviado al repositorio de Linux Containers, incluyendo a Ubuntu.

El resultado de este comando puede ser abrumador ya que contiene bastante información, en cambio si queremos ver la lista de una versión de Ubuntu o una distribución específica, podemos hacer:

lxc image list ubuntu:xenial

De esta manera solo tendremos las imágenes de Xenial.

Por otro lado, si queremos buscar imágenes de Debian:

lxc image list images:debian

lxc image list images:debian/9/

–  tendremos solo las versiones de Stretch.

La lista de imágenes está disponible vía web en: https://uk.images.linuxcontainers.org/

 

Ya sabemos el nombre de la imagen que queremos usar como base de nuestro contenedor. Usando los siguientes comandos podemos crear contenedores.

lxc init ubuntu:xenial cont1

– un nuevo contenedor será creado usando Xenial como base.

lxc launch ubuntu:xenial cont2

– a diferencia del anterior, de este modo podemos crear e inmediatamente iniciar el nuevo contenedor.

 

Interactuando con los contenedores.

Bien, ya tenemos nuestros contenedores. Necesitamos actualizarlo, instalar aplicaciones, usarlo tal cual usaríamos un servidor en físico o una máquina virtual que ya conocemos y queremos.

lxc exec cont1 – bash

– inmediatamente ejecutado este comando estaremos en el contenedor llamado cont1, el acceso es otorgado directamente con permisos de root. En lo adelante todo es exactamente igual que cualquier instalación de Ubuntu. Para salir del contenedor escribimos exit.

 

Aquí termina esta pequeña introducción a LXD, la capacidad de esta herramienta es bastante amplia, tengo varios planes y pruebas para realizar. Entre ella están tales como correr Kubernetes en LXD o crear un Docker Swarm usando contenedores en LXD y Raspberry Pi3.

Más información puede ser encontrada en:

 

IPv6 en la casa, al estilo Homelab!

Hablar de IPv6 es como tirarle piedras a la Luna. Estuve cerca??

nota: esto no es un tutorial, es solo una descripción del enredo al cual llamo “Conexión IPv6”.

Ahora en serio, no voy a decir que en .DO no se está haciendo nada, a nivel residencial y a nivel empresarial creo que menos. Pero en el ámbito educativo podemos ver a PUCMM como el número uno en .DO con relación a conectividad IPv6, creo que al menos el 70% de sus servicios son accesibles vía IPv6, y esto lo digo por el simple hecho de que he intentado usar esos servicios y responden.

Vamos al tema, ya que los proveedores no se han decidido a llevar IPv6 a las casas, tuve que salir a buscar IPv6 por mi cuenta. Ya desde hace años estaba jugando con el “nuevo” direccionamiento gracias a un túnel, TunnelBroker de Hurricane Electric para ser exacto. Y el problema con este era que mi dirección IPv4 en la casa no es fija y sé que tienen un método para poder establecer el túnel con direcciones dinámicas pero ya era un poco complicado simplemente mantener el túnel, además de esto se sumó que servicios como Netflix comenzaron a bloquear esas direcciones IPv6 de HE cuando detectaban que eran parte de TunnelBroker.

Después de un tiempo sin tener conectividad de IPv6 de juguete en la casa me topé con que podía hacerme de un numero autónomo (ASN) y de un IPv6 PA.

Let’s the game begins!!

 

Según HE, soy mi propio ISP.

 

Lo primero fue registrar una organización en RIPE:

Luego realizar el proceso necesario para la asignación de ASN, para esto tenemos que enviar copias de documentos personales al LIR.

 

En este punto ya tenemos el numero autónomo (ASN) que es el pilar de todo el proceso que realizaremos más adelante. Nos toca conseguir un /48 de IPv6 para poder anunciarlo, cualquier asignación más grande de 48 será filtrada por los proveedores de upstream, puede ser que tu peer directo la deje pasar pero es posible que sea filtrada más adelante y no llegue al DFZ de IPv6.

Yo adquirí un /44 con SnapServ del cual solo estoy anunciando un /48 por el momento.

https://www.snapserv.ch/pricing.html

 

Pasemos inventario:

Tenemos número autónomo.

Tenemos direcciones IPv6 para anunciar.

 

Ahora necesitamos routers donde realizar las configuraciones de lugar y que todo este enredo funcione!

En mi caso fue bastante fácil ya que tenía equipos haciendo BGP con otros routers desde hace tiempo gracias a DN42.net, inicialmente lo que hice fue detener el proceso Quagga(BGPd), editar el archivo de configuración y cambiar 64635 -> 207036, reiniciar el proceso y listo!

En caso de ser desde cero, lo primero sería instalar un motor de enrutamiento dinámico (en el caso que sea Linux el router) o habilitar/configurar esta funcionalidad en el router o router que planeemos usar.

Linux – he decidido usar Quagga por la similitud que tienen con el CLI de Cisco.

Mikrotik RouterOS – en la casa tengo varios de estos equipos que soportan BGP.

 

Como se conectan estos equipos y pueden establecer una sesión BGP?

VPN!

En mi caso particular al estar usando el mismo ASN en todos los nodos, estos deben tener la habilidad de alcanzarse mutuamente, quiere decir que deben estar en Mesh. La primera vez que intente esto lo hice usando OpenVPN, que desastre, tenía que establecer alrededor de 6 túneles en cada máquina con Debian. Buscando alternativas me encontré con Tinc, muy buen software con el que dure bastante tiempo en uso hasta que me topé con Zerotier.

https://www.zerotier.com/

Usando zerotier puedo tener una VPN tipo mesh. En otras palabras, mi VPN funciona como un Switch Layer 2. Todas las maquinas tienen un IP de la misma subred y así puedo hacer sesiones BGP entre ellas sin tener que conectarlas directamente.

 

Y así termine con direcciones IPv6 accesibles globalmente en los equipos de mi casa. Pensé que este artículo terminaría como un paso a paso pero me di cuenta de que este enredo es más complicado de lo que pensé. En los próximos días dividiré cada sección y si podre crear un paso a paso.

 

Default Rule NDP – VMware NSX.

Siguiendo con las pruebas de IPv6 en NSX, he notado que una vez tenemos el Manager corriendo y al menos un Controller, si vamos a Firewall -> General, tenemos tres reglas creadas por defecto. En mi caso me ha llamado la atención una llamada Default Rule NDP la cual tiene un Action = Allow.

 

 

Primero, que es NDP?

Es un protocolo usado en IPv6, este opera en el Network Layer (Capa 3 del modelo OSI). Una de las tareas importantes es que este protocolo es el encargado de encontrar (descubrir) otros nodos en el mismo segmento (link).

A mi entender esta es la razón del porque esta regla está en la parte de General cuando entramos a Firewall, la primera prueba que hice fue cambiar el Allow por Block y automáticamente la VM en el cluster que está preparado para NSX y al cual esta política le aplica dejo de alcanzar TODOS los demás host en el mismo link layer. Por ejemplo, si quisiera hacer lo mismo en IPv4 dentro de NSX tendría que crear una regla en la parte de Ethernet tal vez usando la MAC de la VM que no quiero que genere tráfico a ningún otro hosts.

Personalmente pienso que esto no debería ser una política creada por defecto y más bien una opción habilitada en el mismo servicio de Firewall, se puede dar el caso que por equivocación se coloque una regla que interfiera con la comunicación NDP más arriba de esta por defecto y automáticamente tendremos un mal día.