Jak parametryzować dockerfile

2

Hejka :)
Czuję się amatorem w tematach devopsowych i chciałam podpytać o dobre praktyki.

Mój problem:
Mam działająca aplikację, w dockerfile mam zdefiniowane żeby uruchamiać javaagenta. Chcę uruchamiać tego javaagenta tylko dla wybranych środowisk w zależności od parametru.

Moje pierwsze podejście do tematu, to było, żeby w entrypoint dodać skrypt bashowy i w tym skrypcie mieć zdefiniowany warunek.
Plusy rozwiązania: buduję jeden image i mogę go deployowac sukcesywnie na różnych środowiskach.
Problem: Okazuje się, ze używamy w projekcie distroless jdk - co implikuje, że nie ma shella :D

Zwątpiłam w siebie, stwierdziłam, że celowo używają jdk bez shella ze względów bezpieczeństwa czy tam dobrych praktyk i postanowiłam przejśc na podejście, żeby dodać drugi dockerfile i w zależności od parametru wybierać odpowiedni dockerfile i w ten sposób chcę to rozwiązać. To oczywiście sprawia, że już w momencie budowania a nie deployu muszę znać ten parametr ale jeżeli nie mam użyć shella to wydaje się jedynym sensownym rozwiązaniem.

Moje pytanie, czy faktycznie podejście inny dockerfile jest lepsze i czy faktycznie unikać skryptów w dockerfile?

3

Chyba standardowym podejściem jest, że konfigurujesz kontener za pomocą zmiennych środowiskowych.
Ja bym poszedł w stronę entrypoint ze skryptem.

1

Powłoka w kontenerze nie dziedziczy potoku po powłoce hosta. To znaczy, że trzeba wpisać na sztywno. Ewentualnie znaleźć wtyczkę Dockera, która to umożliwi, ale pod spodem i tak będzie to zwykłe przepisywania zmiennych.
Można spróbować też podejścia z ~/.bashrc i wywołaniem w stylu CMD ["/bin/bash -l -c 'skrypt.sh'"]. W takim przypadku skrypt będzie dziedziczyć potok po ~/.bashrc.

2

Zdecydowałam się pozostawić jdk distroless i nie dodawać dodatkowych zależności, zakładając, że zostało zastosowane jdk distroless ze względów zmniejszenia wielkości image'u i bezpieczeństwa (nie udostępnianie konsoli). Zastanawiam się na ile to jest hype (is a best practice employed by Google) a na ile faktycznie jest to niebezpieczne, ale skoro trendy zmierzają do wykluczania shella, to raczej trzeba być konsekwentnym i nie dodawać shella i skryptu w ENTRYPOINT. Aczkolwiek wolałabym mieć ten skrypt tak szczerze mówiąc :(

1

To z pozoru głupie, ale ma sens. Kontenery nie działają w przestrzeni użytkownika. To daje możliwość mieszania w środowiskach bez wpływu na inne. Gdyby jednak uruchomić te same procesy w przestrzeni użytkownika, kontener byłby tym samym, co zwykła aplikacja i byłby bezużyteczny. No bo co za różnica, że odpalę bazę danych jako demon czy jako kontener? A tak jak jest teraz, jest średnio, ale działa.
Trochę łatwiej to załapać jeśli miało się kontakt z Uniksami. Dziedziczenie środowiska (environment inheritance) - genialne w swojej prostocie, ale przykłady jednak się przydają.

4
szarotka napisał(a):

Zastanawiam się na ile to jest hype (is a best practice employed by Google) a na ile faktycznie jest to niebezpieczne

Już stare, ale wkleję po raz kolejny :P https://www.infoq.com/news/2020/12/dockerhub-image-vulnerabilities/

Generalnie najprościej byłoby zrezygnować z ifologii i po prostu podawać gotowy zestaw flag / opcji z zewnątrz - ifologię możesz wyciągnąć wyżej, gdzie shell jest tak czy owak albo nawet nie mieć żadnej, odpowiednio składając CI/CD i cały tooling wokół deployowania (mam tu na myśli docker-compose, konfiguracje k8s itd)

Potem ten gotowy zestaw możesz już wstrzyknąć sobie na parę sposobów:

  • na etapie budowania obrazu, przez ARG lub ENV - nadal jest to słabe, bo budujesz osobne obrazy żeby tylko mieć różne zestawy flag :( ale jest proste jak budowa cepa
  • na etapie uruchamiania kontenera - tutaj zależy jak i czym uruchamiasz aplikację Javową, czy odpalasz kontenery z ręki czy jakimś kubernetesem itd, ale generalnie sprowadza się do podmontowania tego agenta przez docker volume i wstrzyknięcia pożądanych flag przez zmienną środowiskową, np. JAVA_OPTS, JAVA_TOOL_OPTIONS albo i jeszcze co innego.

1 użytkowników online, w tym zalogowanych: 0, gości: 1