Kubernetes daje nam możliwość pracy zarówno imperatywnej (my mówimy co ma się teraz stać) lub deklaratywnie (opisujemy stan oczekiwany). Imperatywne działania są OK jeżeli nie trzeba się cofać i mamy trochę czasu by każdą komendę wprowadzić na przykład:
- stwórz pod z obrazem X;
- zaktualizuj obraz konternera na Y;
- dodaj nowy kontener do poda.
Niby wszystko prosto a jednak – jak wykonamy czynności cofnięcia się do poprzedniego kroku? Jaka jest ta wartość Y? Kto ma ją zapisaną? Przy bardziej skomplikowanych skryptach zaczyna to być coraz trudniejsze do ogarnięcia.
Dlatego też przy pracy z Kubernetes zaleca się pracę deklaratywną – opisujemy stan, który nas interesuje, a jak do niego Kubernetes doprowadzi to nas trochę mało interesuje. Takim opisem stanu jest plik yaml w którym opisujemy nasz pod i określamy kontenery w nim dostępne. Całość wygląda bardzo podobnie jak w przypadku imperatywnego działania z tą różnicą, iż każda zmiana to zmodyfikowany plik a zmodyfikowany plik to przeważnie commit do repozytorium. A więc coś co możemy łatwo w razie potrzeby przywrócić do stany poprzedniego. Z tego niby prostego zdania wynika jedna ważna rzecz❗pliki yaml (deklaratywny opis stanu) są częścią naszego kodu źródłowego i powinny być przechowywane w repozytorium.
I tutaj pojawia się pewien problem, to co sam robiłem i to co widzę, że zespoły robią, to przy opisie poda by sobie ułatwić pracę bardzo często do obrazu dodają tag latest. Co oznacza, że Kubernetes pobierze nam najnowszy obraz kontenera i następnie go uruchomi. Za. Każdym. Razem. Jak. Będziemy. Wdrażać. Aplikację. Specjalnie to zdanie zaznaczyłem. Mianowicie zastosowanie tego tagu spowoduje, że nie uda nam się cofnąć do poprzedniej wdrożonej wersji aplikacji, gdyż Kubernetes za każdym razem będzie pobierał najnowszy obraz kontenera.
Ba, ciężko nawet powiedzieć jaka wersja jest u nas wdrożona, jeżeli wykorzystany jest tag latest. Nie wspominając o “lenistwie” naszym, w którym zupełnie przypadkowo, te same pliku co są wykorzystywane w środowisku programistycznym, są także wykorzystywane w środowisku… produkcyjnym. Dlatego nawet w środowisku developerskim nie powinniśmy używać tagu latest. To oczywiście powoduje pewne dodatkowe kroki przy budowaniu naszego rozwiązania w celu podmienienia tagu na konkretną wersję – przeważnie załatwiane przez narzędzia CI/CD.
Jeżeli za pomocą CI/CD będziemy modyfikować nasze yamle by wstrzyknąć wersję obrazu zbudowanego w trakcie budowania naszego rozwiązania to powinniśmy pamiętać o tym, iż wynikowy plik yaml powinien być artefaktem naszego builda. Tylko dlatego byśmy mogli go wielokrotnie wdrażać bez efektów ubocznych. Budowanie pliku yaml nie powinno być odpowiedzialnością narzędzia wdrażającego nasze rozwiązanie – dlaczego? Pomyślcie, że potem byście musieli sami wdrożyć takie rozwiązanie bez CD, jakie parametry byście podali?
Jest to przykład, na to, iż w K8s bardzo ważne jest myślenie w przyszłość i stosowanie nawet mniej wydajnych form na początku, tylko po to by potem przypadkiem taki yaml z latest nie trafił na produkcję ;) Bo to już naprawdę…
.. zaboli ;)