- Kubernetes. Servicio motionEye en Kubernetes. Servicio publicado con NodePort.
- Kubernetes. Servicio motionEye en Kubernetes. Servicio publicado con LoadBalancer.
- Kubernetes. Servicio motionEye en Kubernetes. Servicio publicado con Ingress.
El siguiente paso lógico para mejorar la aplicación, y una vez que tenemos el LoadBalancer funcionando, sería crear un recurso INGRESS. Con Ingress se consigue publicar la aplicación web al exterior proporcionando balanceo de carga y terminación SSL. Esta última característica es muy importante en motionEye ya que la aplicación no permite por diseño el protocolo seguro. También voy a describir como gestionar con kubernetes el mantenimiento de los certificados de LetsEncrypt con CERT-MANAGER.
Instalación de INGRESS
Existen diferentes implementaciones de Ingress, yo voy a utilizar nginx que además es mantenida por Kubernetes. Un esquema básico del funcionamiento de Ingress se detalla en la siguiente imagen.
La primera acción es desplegar el Ingress Controller. Además comprobamos que se han desplegado los pods.
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/baremetal/deploy.yaml
$ kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-rdpjk 0/1 Completed 0 15d
ingress-nginx-admission-patch-z29m7 0/1 Completed 2 15d
ingress-nginx-controller-7fc8d55869-zwmvj 1/1 Running 4 (2d2h ago) 15d
$ kubectl -n ingress-nginx get ingressclasses
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 15d
$
Es importante indicarle al Ingress Controller que utilice un LoadBalancer en lugar del NodePort. Para conseguirlo es necesario editar el service en el apartado spec.type cambiando “NodePort” por “LoadBalancer”. Una vez cambiado comprobar que el TYPE aparece como LoadBalancer.
$ kubectl edit service ingress-nginx-controller -n ingress-nginx
$ kubectl get services -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.106.95.250 192.168.2.211 80:31780/TCP,443:30997/TCP 15d
ingress-nginx-controller-admission ClusterIP 10.98.178.209 <none> 443/TCP 15d
$
Instalación de CERT-MANAGER
Con la instalación de Ingress se obtiene un certificado valido a nivel de cifrado. Este certificado, obviamente no es válido para cualquier navegador por lo que es necesario dotar al cluster de una gestión de certificados. Esta utilidad la proporciona cert-manager y la instalación está descrita en Installation.
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml
Una vez instalado es necesario configurar un “cluster issuer”. En mi caso elijo letsencrypt. A continuación detallo el yaml que he creado. El server indicado es el de staging que proporciona letsencrypt para las pruebas. Si utilizas el de producción puedes provocar bloqueos de la cuenta. El de PRO es –> https://acme-v02.api.letsencrypt.org/directory.
$ kubectl apply -f letsencrypt-staging.yaml
clusterissuer.cert-manager.io/letsencrypt-staging configured
$ cat letsencrypt-staging.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
email: tucorreo@correo.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource that will be used to store the account's private key.
name: letsencrypt-issuer-account-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
$
Aplicación motionEye definitiva (Al menos por el momento)
El detalle anterior describe la creación de Deploys necesarios en el Cluster y ahora os dejo los yaml necesarios para la aplicación.
$ cat motioneye-deployment-con-ingress-acme-production.yaml
apiVersion: v1
kind: Namespace
metadata:
name: motioneye
---
apiVersion: v1
kind: Service
metadata:
name: motioneye
namespace: motioneye
labels:
app: motioneye
spec:
ports:
- port: 8765
targetPort: 8765
selector:
app: motioneye
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# Añado el cluster-issuer definido para letsencrypt
cert-manager.io/cluster-issuer: letsencrypt-production
name: motioneye
namespace: motioneye
spec:
rules:
# Aquí tienes que poner el FQDN de tu aplicación
- host: motion.tudominio.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: motioneye
port:
number: 8765
tls:
- hosts:
- motion.tudominio.com
# En este certificate cert-manager guarda el certificado.
# kubectl get certificate -n motioneye
secretName: camaras-cert
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: motioneye
spec:
replicas: 1
selector:
matchLabels:
app: motioneye
template:
metadata:
labels:
app: motioneye
spec:
volumes:
- name: nfs-motioneye-etc
nfs:
server: servidor-nfs
path: /DPVs/motionEye/etc
readOnly: no
- name: nfs-motioneye-var-lib
nfs:
server: servidor-nfs
path: /DPVs/motionEye/var-lib
readOnly: no
- name: localtime
hostPath:
path: "/etc/localtime"
containers:
- name: motioneye-container
image: ccrisan/motioneye:master-amd64
ports:
- containerPort: 8765
protocol: TCP
name: "server"
volumeMounts:
- mountPath: "/etc/motioneye"
name: nfs-motioneye-etc
- mountPath: "/var/lib/motioneye"
name: nfs-motioneye-var-lib
- mountPath: "/etc/localtime"
name: localtime
env:
- name: hostname
value: "CAMARAS"
Sólo te queda el consiguiente apply del fichero anterior y, ya estaría! (0‿~).