Solución:
Muy bien, algunas partes de estas respuestas fueron útiles en la búsqueda de la solución completa, especialmente la de @Matt. Sin embargo, me tomó bastante tiempo hacer que esto funcionara, así que decidí escribir mi propia respuesta con todos los necesario detalles con los que otros también podrían tener problemas.
Lo primero sería crear un servidor de imágenes Docker capaz de responder a cualquier solicitud con contenido 404, excepto /healthz
y /metrics
. Como mencionó @Matt, esta podría ser una instancia de Nginx (que he usado). Para resumir:
-
/healthz
debería volver200
-
/metrics
es opcional, pero debería devolver datos que Prometheus pueda leer en caso de que lo esté utilizando para métricas de k8s. Nginx puede proporcionar algunos datos básicos que Prometheus puede leer. Considere este enlace si desea obtener la integración completa de Prometheus con Nginx. -
/
devuelve un 404 con su contenido HTML personalizado.
Por lo tanto, la Dockerfile
Se ve como esto:
FROM nginx:alpine
# Remove default NGINX Config
# Take care of Nginx logging
RUN rm /etc/nginx/conf.d/default.conf &&
ln -sf /dev/stdout /var/log/nginx/access.log &&
ln -sf /dev/stderr /var/log/nginx/error.log
# NGINX Config
COPY ./default.conf /etc/nginx/conf.d/default.conf
# Resources
COPY content/ /var/www/html/
CMD ["nginx", "-g", "daemon off;"]
En la misma carpeta donde se encuentra Dockerfile, cree este default.conf
Archivo de configuración de Nginx:
server {
root /var/www/html;
index 404.html;
location / {
}
location /healthz {
access_log off;
return 200 "healthyn";
}
location /metrics {
# This creates a readable and somewhat useful response for Prometheus
stub_status on;
}
error_page 404 /404.html;
location = /404.html {
internal;
}
}
Por fin, proporcione un content/404.html
archivo con HTML / CSS a su gusto.
Ahora cree la imagen de Docker con:
docker build --no-cache -t custom-default-backend .
Etiquete esta imagen para que esté lista para ser insertada en DockerHub (o en su propio registro de Docker privado):
docker tag custom-default-backend:latest <your_dockerhub_username>/custom-default-backend
Envía la imagen a un repositorio de DockerHub:
docker push <your_dockerhub_username>/custom-default-backend
Ahora viene la parte de la integración de esta imagen de backend predeterminada personalizada en la instalación de Helm. Para hacer esto, primero necesitamos crear este archivo de recursos k8s (custom_default_backend.yaml
):
---
apiVersion: v1
kind: Service
metadata:
name: custom-default-backend
namespace: ingress-nginx
labels:
app.kubernetes.io/name: custom-default-backend
app.kubernetes.io/part-of: ingress-nginx
spec:
selector:
app.kubernetes.io/name: custom-default-backend
app.kubernetes.io/part-of: ingress-nginx
ports:
- port: 80
targetPort: 80
name: http
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: custom-default-backend
namespace: ingress-nginx
labels:
app.kubernetes.io/name: custom-default-backend
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: custom-default-backend
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: custom-default-backend
app.kubernetes.io/part-of: ingress-nginx
spec:
containers:
- name: custom-default-backend
# Don't forget to edit the line below
image: <your_dockerhub_username>/custom-default-backend:latest
imagePullPolicy: Always
ports:
- containerPort: 80
Suponiendo que tenemos un espacio de nombres k8s ingress-nginx
ya creado podemos crear estos dos recursos.
kubectl apply -f custom_default_backend.yaml
Ahora, para vincular el controlador de entrada de Nginx con nuestro nuevo servicio, probablemente podríamos editar la implementación del controlador de entrada. Pero he decidido eliminarlo por completo a través de Helm:
helm delete nginx-ingress -n ingress-nginx
E instálelo de nuevo con este comando (asegúrese de tener el --set
bandera con los argumentos adecuados incluidos):
helm install nginx-ingress --namespace ingress-nginx stable/nginx-ingress --set defaultBackend.enabled=false,controller.defaultBackendService=ingress-nginx/custom-default-backend
Con estos pasos, debería terminar con una implementación de backend predeterminada personalizada que funcione. Aquí hay un repositorio de GitHub con los archivos que he usado en esta respuesta.
El proyecto proporciona la aplicación de error personalizada Go que se puede integrar en una imagen de contenedor para reemplazar default-backend
. los errorHandler
la función hace la magia.
Al final es un servidor web que responde a cualquier solicitud con contenido 404, excepto /healthz
y /metrics
. Puede hacerlo con una instancia de nginx y páginas de error html si lo desea.
Probablemente no desee utilizar el manejo de errores personalizado completo, esto es ligeramente diferente donde el controlador de entrada buscará ciertos códigos de estado HTTP de un backend de aplicación normal y los pasará al backend predeterminado para su manejo. Esto causa problemas para la mayoría de las aplicaciones, a menos que estén diseñadas para usarlo desde el principio.