14 KiB
Кастомная страница ошибки 404 (и других) в Traefik
Страницы ошибок Traefik по умолчанию выглядят скучно. Это даже не страницы, а просто текстовые сообщения. Например,
404 выглядит как 404 page not found
. Это позволяет Traefik быть лёгким и быстрым.
Если хочется сделать страницы статусоы 4xx и 5xx более привлекательными, то кастомизация страниц ошибок — отличная идея! Для каждого HTTP-сервиса внутри можно сделать свои страницы ошибок на уровне приложения (как например, на Gitea, на которой ты сейчас сидишь). И это наиболее правильный способ. Но если http-запрос не привязан ни к какому сервису, и Traefik не знает куда его отправить, то он выдаёт свои страницы ошибок. Например, при обращении по IP.
Traefik позволяет кастомизировать страницы ошибок через middleware типа errors
, который перенаправляет запросы
с определёнными кодами ошибок (например, 404) на кастомный сервис, возвращающий нужную html-страницу. И все это
излишество в k3s
нужно настраивать глобально, с помощью Middleware
и IngressRoute
, и применять ко всем маршрутам.
Чтобы кастомная страница 404 работала для всех запросов в кластере, нужно:
Создать сервис, который возвращает кастомную страницу (например, контейнер с Nginx или простой HTTP-сервер).
Настроить middleware errors
для перехвата ошибок 404.
Применить middleware глобально через IngressRoute
или конфигурацию Traefik.
Самый простой подход — развернуть лёгкий контейнер (например, Nginx) с HTML-файлом для страницы 404 и настроить Traefik для перенаправления ошибок на этот контейнер. Ну или, как альтернатива, использовать внешний сервис (по URL), но это сложнее для глобальной настройки, и создаст зависимость от этого URL.
2. План действий
- Создать кастомную страницу 404 (HTML-файл).
- Развернуть контейнер с Nginx, который будет отдавать эту страницу.
- Настроить Traefik middleware
errors
для перехвата 404. - Применить middleware глобально для всех маршрутов в
k3s
. - Проверить результат.
Настройка кастомной страницы 404
1. Создать кастомную страницу 404
- Создай HTML-файл для страницы 404 на ноде
opi5
:mkdir -p ~/k3s/error-pages cat > ~/k3s/error-pages/404.html <<EOF <!DOCTYPE html> <html> <head> <title>404 Not Found</title> <style> body { font-family: Arial, sans-serif; text-align: center; padding: 50px; } h1 { color: #ff5555; } p { font-size: 18px; } </style> </head> <body> <h1>404 - Page Not Found</h1> <p>Oops! Looks like you're lost in the void.</p> </body> </html>
EOF
#### 2. Развернуть Nginx для отдачи страницы
- Создай манифест для Nginx, который будет отдавать `404.html`:
```bash
cat > ~/k3s/error-pages/error-pages.yaml <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: error-pages
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: error-pages
namespace: error-pages
spec:
replicas: 1
selector:
matchLabels:
app: error-pages
template:
metadata:
labels:
app: error-pages
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: error-pages
mountPath: /usr/share/nginx/html
volumes:
- name: error-pages
configMap:
name: error-pages
---
apiVersion: v1
kind: Service
metadata:
name: error-pages
namespace: error-pages
spec:
selector:
app: error-pages
ports:
- port: 80
targetPort: 80
---
apiVersion: v1
kind: ConfigMap
metadata:
name: error-pages
namespace: error-pages
data:
404.html: |
<!DOCTYPE html>
<html>
<head>
<title>404 Not Found</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; padding: 50px; }
h1 { color: #ff5555; }
p { font-size: 18px; }
</style>
</head>
<body>
<h1>404 - Page Not Found</h1>
<p>Oops! Looks like you're lost in the void.</p>
</body>
</html>
EOF
-
Примени:
kubectl apply -f ~/k3s/error-pages/error-pages.yaml
-
Проверь поды и сервис:
kubectl get pod -n error-pages kubectl get svc -n error-pages
3. Настроить Traefik middleware для ошибок
- Создай манифест для middleware
errors
:cat > ~/k3s/traefik/error-middleware.yaml <<EOF apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: error-pages namespace: kube-system spec: errors: status: - "404" service: name: error-pages namespace: error-pages port: 80 query: /404.html
EOF
- Примени:
```bash
kubectl apply -f ~/k3s/traefik/error-middleware.yaml
- Проверь:
kubectl get middleware -n kube-system
4. Применить middleware глобально
-
В
k3s
дефолтный Traefik обрабатывает маршруты черезIngressRoute
илиIngress
. Чтобы middleware применялся ко всем маршрутам, нужно либо:- Добавить middleware к каждому
IngressRoute
вручную. - Настроить Traefik для глобального применения middleware через
defaultMiddlewares
.
- Добавить middleware к каждому
-
Для простоты создадим глобальный
IngressRoute
для всех доменов:cat > ~/k3s/traefik/global-error-route.yaml <<EOF apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: global-error-route namespace: kube-system spec: entryPoints: - web - websecure routes: - match: HostRegexp(`{host:.+}`) kind: Rule services: - name: noop namespace: kube-system port: 9999 middlewares: - name: error-pages namespace: kube-system
EOF
- Примени:
```bash
kubectl apply -f ~/k3s/traefik/global-error-route.yaml
- Примечание:
- Сервис
noop:9999
— это заглушка, так какIngressRoute
требует сервис, но middlewareerrors
перехватит 404 до обращения к сервису. - Это обеспечивает, что любой запрос с кодом 404 (для любого домена) будет перенаправлен на
error-pages
.
- Сервис
5. Проверить кастомную страницу 404
-
Попробуй открыть несуществующий путь:
curl -v https://git.cube2.ru/nonexistent
-
Ожидаемый ответ:
- Код:
404 Not Found
. - HTML-страница:
<h1>404 - Page Not Found</h1> <p>Oops! Looks like you're lost in the void.</p>
- Код:
-
Проверь для другого домена (например,
Bitwarden
):curl -v https://<bitwarden-domain>/nonexistent
-
Проверь логи Traefik:
kubectl logs -n kube-system -l app.kubernetes.io/name=traefik | tail -n 20
6. (Опционально) Настроить другие ошибки
- Чтобы добавить кастомные страницы для других кодов (например, 403, 500), обнови middleware:
cat > ~/k3s/traefik/error-middleware.yaml <<EOF apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: error-pages namespace: kube-system spec: errors: status: - "403" - "404" - "500-503" service: name: error-pages namespace: error-pages port: 80 query: /{status}.html
EOF
- Создай дополнительные файлы (`403.html`, `500.html`) в `ConfigMap`:
```bash
kubectl edit configmap -n error-pages error-pages
-
Добавь, например:
403.html: | <!DOCTYPE html> <html> <head><title>403 Forbidden</title></head> <body><h1>403 - Forbidden</h1><p>Access denied!</p></body> </html>
-
Примени:
kubectl apply -f ~/k3s/traefik/error-middleware.yaml kubectl delete pod -n error-pages -l app=error-pages
Ответ на твой вопрос
По умолчанию Traefik выдаёт скучные текстовые страницы для 404 и других ошибок. Как сделать кастомные 404 для всего
k3s
без привязки к домену? Где они лежат, и есть ли простой способ их переопределить?
-
Где лежат дефолтные страницы:
- Они встроены в бинарник Traefik и генерируются как текст (не HTML), например:
404 page not found
. - Физически их нет в виде файлов в кластере.
- Они встроены в бинарник Traefik и генерируются как текст (не HTML), например:
-
Почему не HTML:
- Traefik использует текстовые ответы для минимизации ресурсов.
-
Как переопределить:
- Использовать middleware
errors
, который перенаправляет ошибки (например, 404) на кастомный сервис с HTML-страницей. - Развернуть контейнер (например, Nginx) с кастомной страницей.
- Настроить глобальный
IngressRoute
для применения middleware ко всем доменам.
- Использовать middleware
-
Простой способ:
- Создать
ConfigMap
с HTML-файлом (404.html
). - Развернуть Nginx в namespace
error-pages
для отдачи страницы. - Настроить middleware
errors
для перехвата 404. - Применить middleware через глобальный
IngressRoute
.
- Создать
-
Для всего
k3s
:- Глобальный
IngressRoute
сHostRegexp
перехватывает все запросы и применяет middlewareerrors
для ошибок 404.
- Глобальный
Рекомендации
-
Создать и применить страницу 404:
kubectl apply -f ~/k3s/error-pages/error-pages.yaml
-
Настроить middleware:
kubectl apply -f ~/k3s/traefik/error-middleware.yaml
-
Применить глобальный маршрут:
kubectl apply -f ~/k3s/traefik/global-error-route.yaml
-
Проверить:
curl -v https://git.cube2.ru/nonexistent curl -v https://<bitwarden-domain>/nonexistent
-
Проверить логи:
kubectl logs -n kube-system -l app.kubernetes.io/name=traefik | tail -n 20
-
(Опционально) Добавить другие ошибки:
- Обновить
ConfigMap
и middleware для 403, 500 и т.д.
- Обновить
Итог
Дефолтные страницы ошибок Traefik — это встроенные текстовые ответы, которые можно переопределить с помощью middleware errors
и кастомного сервиса (например, Nginx с HTML-страницей). Для глобальной настройки в k3s
мы развернули контейнер с 404.html
, настроили middleware для перехвата ошибок 404, и применили его ко всем доменам через IngressRoute
с HostRegexp
. Это простой и универсальный способ сделать страницы ошибок яркими и весёлыми! 😄 Теперь твои 404 будут выглядеть стильно, и ты можешь добавить такие же для других ошибок.
Действия:
- Применить:
kubectl apply -f ~/k3s/error-pages/error-pages.yaml kubectl apply -f ~/k3s/traefik/error-middleware.yaml kubectl apply -f ~/k3s/traefik/global-error-route.yaml
- Проверить:
curl -v https://git.cube2.ru/nonexistent
Напиши:
- Получилась ли кастомная страница 404? (
curl -v https://git.cube2.ru/nonexistent
) - Работает ли для других доменов? (
curl -v https://<bitwarden-domain>/nonexistent
) - Хочешь настроить страницы для других ошибок (403, 500)?
Теперь можно расслабиться и наслаждаться яркими страницами ошибок! 🚀