Etykiety Traefika po kolei, wraz z pułapką dolara

Spis treści
Traefika konfiguruje się, pisząc etykiety na kontenerze – co brzmi jak lista ustawień, a w rzeczywistości jest przestrzenią nazw. Klucze to ścieżki po drzewie, a to, co wygląda na sześć niezależnych wierszy, to trzy twory wiedzące o sobie tylko dlatego, że człon w środku klucza przypadkiem zapisano tak samo.
Ta budowa czyni konfigurację krótką, a jej awarie cichymi. Nic nie sprawdza nazwy względem czegokolwiek, literówka tworzy więc drugi, pusty twór zamiast skargi.

Trzy twory, jedna nazwa
Router rozstrzyga, które żądania należą do tego kontenera, usługa mówi, dokąd je posłać, a middleware zmienia je po drodze. Każde żyje pod własną gałęzią traefik.http i każde oznacza się dowolnie wybraną nazwą – klucz etykiety jest deklaracją.
labels:
- "traefik.enable=true"
- "traefik.http.routers.blog.rule=Host(`blog.example.com`)"
- "traefik.http.routers.blog.entrypoints=websecure"
- "traefik.http.routers.blog.tls.certresolver=le"
- "traefik.http.routers.blog.middlewares=blog-auth@docker"
- "traefik.http.middlewares.blog-auth.basicauth.users=admin:$$2y$$05$$e6zX…"
- "traefik.http.services.blog.loadbalancer.server.port=8080"
Router i usługa są powiązane, bo oba nazywają się blog. Nie ma wiersza, który by to mówił. Kto napisze traefik.http.services.blogg.loadbalancer.server.port, tworzy usługę blogg, na którą nic nie wskazuje, i router blog bez usługi – a Traefik odpowie na żądania do tej nazwy kodem 404, zamiast powiedzieć, czego brakuje.
Gdy kontener wystawia dokładnie jeden port, etykieta usługi odpada w całości, Traefik dopowie ją sobie. Warto o tym wygodnictwie wiedzieć głównie po to, by rozpoznać je w cudzych plikach – z chwilą pojawienia się drugiego portu dopowiadanie się kończy, a trasa pęka dokładnie wtedy, gdy dochodzi zupełnie niezwiązany port.
Przyrostek źródła
Middleware wskazuje się po nazwie, a sama nazwa nie wystarczy. Traefik prowadzi osobną przestrzeń nazw dla każdego źródła – etykiet Dockera, pliku statycznego, zasobu Kubernetesa – a samo blog-auth szuka się w źródle pytającym, z odwrotem zaskakującym na tyle często, by powiedzieć to wprost: odwołanie należy zapisać jako blog-auth@docker.
Pomyłka tutaj jest najcichszą z trzech. Router jest poprawny, usługa jest poprawna, trasa działa – wydaje tylko aplikację bez logowania, które miało przed nią stać. Nic w dzienniku nie wspomina o pominiętym middleware, bo z punktu widzenia Traefika żadnego nie zażądano.
Pułapka dolara
Skrót bcrypt wygląda jak $2y$05$e6zX... i w sporej części składa się ze znaków dolara. Docker Compose podstawia zmienne w każdej odczytanej wartości, z $2y robi się więc pusty napis, z $05 również, a hasło docierające do Traefika jest ułomkiem, który do niczego nie pasuje.
# wygenerowanie
htpasswd -nbB admin "haslo"
admin:$2y$05$e6zXx8Q0m2yYy1H4o1Yb1uJf2Rr7cKq5dW6vT8sN0pL3aG9hC1dS2
# w docker-compose.yml każdy $ zostaje podwojony
admin:$$2y$$05$$e6zXx8Q0m2yYy1H4o1Yb1uJf2Rr7cKq5dW6vT8sN0pL3aG9hC1dS2
# w czystym pliku etykiet albo w wierszu poleceń zostaje pojedynczy
Podwajanie jest regułą Compose’a, a nie Traefika – dlatego ten sam napis trzeba zapisać inaczej zależnie od miejsca pobytu. Skrót we własnym pliku dynamicznej konfiguracji Traefika zachowuje pojedyncze dolary, ten sam skrót w pliku Compose potrzebuje ich podwójnie, a przeniesienie działającej konfiguracji z jednego do drugiego rozkłada ją dokładnie w ten sposób.
Objawem jest okienko logowania odrzucające każde hasło, również właściwe – co prowadzi do sprawdzania hasła, a nie pliku, który je zjadł.
Jak każdy z tych błędów wygląda z zewnątrz
| Błąd | Objaw | Gdzie zajrzeć |
|---|---|---|
| Różna nazwa w routerze i usłudze | 404 dla tej nazwy | panel: router bez usługi |
Middleware bez @docker |
strona otwiera się bez logowania | panel: router nie wymienia middleware |
| Pojedyncze dolary w Compose | 401 przy każdym haśle | docker inspect: etykieta krótsza niż skrót |
| Kontener poza siecią proxy | 502 albo 504 | usługa nie ma osiągalnego serwera |
Brak traefik.enable=true |
404, nie pojawia się nic | panel: kontenera nie ma na liście |
| Dwa kontenery, ta sama nazwa routera | jeden wygrywa, pozornie losowo | panel: jeden router, jeden cel |
Pięć z sześciu rozstrzyga panel przeglądowy, co przemawia za włączeniem go również na małej maszynie, na wewnętrznym wejściu. Pokazuje, co Traefik faktycznie zrozumiał, a każdy z tych błędów jest różnicą między napisanym a zrozumianym.
Dwa nawyki, które zapobiegają większości
Pierwszy polega na wyprowadzeniu każdej nazwy z usługi i użyciu jej bez zmian we wszystkich trzech miejscach – kontener blog, router blog, usługa blog, middleware blog-auth. Nazwy utworzonej mechanicznie nie da się źle zapamiętać, a porównanie etykiet dwóch kontenerów pokazuje wtedy już tylko wiersze naprawdę się różniące.
Drugi polega na odczytywaniu etykiet, a nie pliku. docker inspect pokazuje wartości tak, jak odłożyła je usługa, po zakończeniu podstawiania przez Compose – tam z podwojonego dolara robi się z powrotem pojedynczy i tam po ocalałym skrócie widać, że jest dokładnie tak długi jak wygenerowany.