{"id":30015,"date":"2025-01-15T08:55:34","date_gmt":"2025-01-15T07:55:34","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=30015"},"modified":"2025-01-16T15:42:33","modified_gmt":"2025-01-16T14:42:33","slug":"zaawansowane-opcje-wdrazania-z-kubernetes-i-argo-rollouts","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/zaawansowane-opcje-wdrazania-z-kubernetes-i-argo-rollouts\/","title":{"rendered":"Zaawansowane opcje wdra\u017cania z Kubernetes i Argo Rollouts"},"content":{"rendered":"\n<p>Zwyk\u0142y deployment w Kubernetes zapewnia nam 2 strategie wdra\u017cania, kt\u00f3re mo\u017cemy okre\u015bli\u0107 w polu <strong><em>.spec.strategy.type<\/em><\/strong> \u2013 <strong><em>RollingUpdate<\/em><\/strong> (opcja domy\u015blna) i <strong><em>Recreate<\/em><\/strong>. I jest to zasadniczo wszystko, czego mo\u017cemy u\u017cy\u0107 domy\u015blnie w Kubernetes. Takie opcje mog\u0105 wystarczy\u0107 w niekt\u00f3rych przypadkach, zw\u0142aszcza je\u015bli chcemy postawi\u0107 dzia\u0142aj\u0105c\u0105 aplikacje tak szybko, jak to mo\u017cliwe.<\/p>\n\n\n\n<p>Ale co, je\u015bli potrzebujemy znacznie bardziej wyrafinowanej metody wdra\u017cania? Istnieje niezliczona ilo\u015b\u0107 strategii wdra\u017cania:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Blue-Green,<\/li>\n\n\n\n<li>Canary,<\/li>\n\n\n\n<li>Big Bang,<\/li>\n\n\n\n<li>Feature Toggle itd.<\/li>\n<\/ul>\n\n\n\n<p>Oczywi\u015bcie mo\u017cemy skorzysta\u0107 z hybryd tych metod, co daje nam jeszcze wi\u0119ksze pole do odkrycia, ni\u017c domy\u015blnie zapewniono w K8s. Ale jak mo\u017cemy zaimplementowa\u0107 te strategie wdra\u017cania <strong>bez konieczno\u015bci pisania z\u0142o\u017conych skrypt\u00f3w Bash, bez z\u0142o\u017conej konfiguracji Load Balancera i wielu \u015brodowisk (lub klastr\u00f3w K8s) w naszej chmurze i wreszcie bez potrzeby bardzo skomplikowanej konfiguracji routingu naszego K8s Ingressa?<\/strong><\/p>\n\n\n\n<p>Istnieje znacznie prostsze rozwi\u0105zanie tego problemu, kt\u00f3re jest przyjazne dla Kubernetesa i umo\u017cliwi nam korzystanie z r\u00f3\u017cnych dojrza\u0142ych mechanizm\u00f3w wdra\u017cania przy u\u017cyciu nawet najprostszej, jak\u0105 mo\u017cesz sobie wyobrazi\u0107, konfiguracji K8s+chmura. To narz\u0119dzie nazywa si\u0119 Argo Rollouts!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Najpierw przypomnijmy podstawy<\/strong><\/h2>\n\n\n\n<p>Zanim wyja\u015bnimy sobie, czym jest Argo Rollouts i co mo\u017ce nam da\u0107 dzi\u0119ki wykorzystaniu strategii Canary, najpierw przypomnijmy sobie, jak zachowuje si\u0119 zwyk\u0142y Kubernetes Deployment (z domy\u015bln\u0105 strategi\u0105 <strong><em>RollingUpdate<\/em><\/strong>) podczas aktualizacji.<\/p>\n\n\n\n<p>We\u017amy poni\u017csz\u0105 definicj\u0119 Deploymentu jako przyk\u0142ad:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\napiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: nginx-deployment\n  labels:\n    app: nginx\nspec:\n  replicas: 10\n  selector:\n    matchLabels:\n      app: nginx\n  template:\n    metadata:\n      labels:\n        app: nginx\n    spec:\n      containers:\n      - name: nginx\n        image: my-image:v1\n        ports:\n        - containerPort: 80\n  strategy: # Field added for better clarity\n    type: RollingUpdate\n    rollingUpdate:\n      maxSurge: 10%\n      maxUnavailable: 10%\n<\/pre><\/div>\n\n\n<p>Ten Deployment u\u017cywa wszystkich domy\u015blnych opcji konfiguracji strategii wdra\u017cania, ale dla wi\u0119kszej przejrzysto\u015bci jawnie zdefiniowa\u0142em warto\u015bci w polu <strong><em>.spec.strategy<\/em><\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Proces<\/strong><\/h3>\n\n\n\n<p>Gdy go tworzymy, a nast\u0119pnie aktualizujemy jego Docker obraz do nowej wersji, jednocze\u015bnie rozpoczyna on uruchamianie nowych pod\u00f3w (replik) i usuwanie pod\u00f3w ze starsz\u0105 wersj\u0105 obrazu w r\u00f3wnomiernych sekwencjach, a ca\u0142y proces b\u0119dzie wygl\u0105da\u0142 nast\u0119puj\u0105co:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Pocz\u0105tkowo mamy 10 replik, wszystkie z obrazem w wersji v1.<\/li>\n\n\n\n<li>Aktualizujemy tag obrazu do v2, wi\u0119c Rolling Update wykonuje si\u0119 zgodnie ze zdefiniowanym <strong><em>maxSurge<\/em><\/strong> i <strong><em>maxUnavailable<\/em><\/strong>.<\/li>\n\n\n\n<li>Tworzony jest nowy ReplicaSet, kt\u00f3ry b\u0119dzie uruchamia\u0142 repliki z obrazem w wersji v2.<\/li>\n\n\n\n<li>Jednocze\u015bnie \u2013 nowy ReplicaSet tworzy 2 repliki z obrazem v2, a stary ReplicaSet usuwa swoj\u0105 1 star\u0105 replik\u0119. Nowy ReplicaSet mo\u017ce utworzy\u0107 tylko 2 repliki w tym momencie, poniewa\u017c <strong><em>maxSurge<\/em><\/strong> jest ustawiony na 10% (z liczby <strong><em>.spec.replicas<\/em><\/strong>), wi\u0119c b\u0119dziemy mie\u0107 \u0142\u0105cznie 11 replik (9 starych replik w stanie <strong><em>Running<\/em><\/strong> i 2 nowe repliki w stanie <strong><em>ContainerCreating<\/em><\/strong>). Stary ReplicaSet (na razie) mo\u017ce usun\u0105\u0107 tylko jedn\u0105 replik\u0119, poniewa\u017c <strong><em>maxUnavailable<\/em><\/strong> jest ustawione na 10% (co najmniej 9 replik musi by\u0107 w stanie <strong><em>Running<\/em><\/strong>).<\/li>\n\n\n\n<li>Zaraz po tym, jak repliki z nowego ReplicaSet przejd\u0105 ze stanu <strong><em>ContainerCreating<\/em><\/strong> do <strong><em>Running<\/em><\/strong>, stary ReplicaSet usunie 2 ze swoich replik, a jednocze\u015bnie nowy ReplicaSet utworzy kolejne 2 repliki), wi\u0119c b\u0119dziemy mie\u0107 \u0142\u0105cznie 11 replik (7 starych replik w stanie <strong><em>Running<\/em><\/strong>, 2 nowe repliki w stanie <strong><em>Running<\/em><\/strong> i 2 nowe repliki ze stanem <strong><em>ContainerCreating<\/em><\/strong>).<\/li>\n\n\n\n<li>Nast\u0119pnie wszystkie kolejne operacje s\u0105 podobne do kroku 5, a\u017c osi\u0105gniemy 100% replik w Deploymencie w po\u017c\u0105danej wersji v2 (nowej) i 0% replik z poprzedniej wersji v1 (starej).<\/li>\n\n\n\n<li>Po wykonaniu ostatniej poprawki stary ReplicaSet jest zachowywany lub usuwany w zale\u017cno\u015bci od pola <strong><em>.spec.revisionHistoryLimit<\/em><\/strong> (przy domy\u015blnej konfiguracji pozostanie, chocia\u017c nie b\u0119dzie mia\u0142 \u017cadnych replik).<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Stopniowa aktualizacja<\/strong><\/h3>\n\n\n\n<p>Jest to bardzo przydatna funkcjonalno\u015b\u0107, szczeg\u00f3lnie w por\u00f3wnaniu do przestarza\u0142ych metod wdra\u017cania sprzed ery Kubernetes. <strong>Dzi\u0119ki Rolling Update nie mamy przestoj\u00f3w w dzia\u0142aniu aplikacji, zamiast tego mamy stopniowe aktualizacje,<\/strong> w kt\u00f3rych stale coraz wi\u0119kszy procent naszych replik jest zast\u0119powany nowsz\u0105 wersj\u0105. Mo\u017cemy nawet ustawi\u0107 <strong><em>maxUnavailable<\/em><\/strong> na 0, aby nie straci\u0107 \u017cadnej pojemno\u015bci (podczas wdra\u017cania nowej wersji, zawsze b\u0119dziemy mie\u0107 co najmniej tak\u0105 sam\u0105 liczb\u0119 uruchomionych replik, jak przed rozpocz\u0119ciem procesu aktualizacji).<\/p>\n\n\n\n<p>To \u015bwietnie, ale <strong>co, je\u015bli potrzebujemy znacznie bardziej wyrafinowanej strategii wdra\u017cania<\/strong>, kt\u00f3ra umo\u017cliwi\u0142aby nam znacznie inteligentniejsz\u0105 logik\u0119 w procesie wdra\u017cania?<\/p>\n\n\n\n<p>Teraz mo\u017cemy w ko\u0144cu przej\u015b\u0107 do Argo Rollouts!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Argo Rollouts oraz Canary Deployment<\/strong><\/h2>\n\n\n\n<p>Argo Rollout to narz\u0119dzie open source, kt\u00f3re zapewnia kontroler Kubernetes i zestaw CRD (np. Rollout) dla zaawansowanych strategii wdra\u017cania. Podobnie jak Argo CD, pochodzi z projektu Argo. W tym artykule skupiam si\u0119 tylko na najbardziej standardowym wykorzystaniu strategii Canary, ale mo\u017cesz wykorzysta\u0107 Blue-Green Deployment i wiele innych funkcji Canary Deployment, wi\u0119c polecam zapozna\u0107 si\u0119 z <a href=\"https:\/\/argo-rollouts.readthedocs.io\/en\/stable\/\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >oficjaln\u0105 dokumentacj\u0105<\/a> po\/podczas czytania tego wpisu na blogu.<\/p>\n\n\n\n<p>W przypadku Canary Deployment masz o wiele wi\u0119ksz\u0105 kontrol\u0119 nad procesem wdra\u017cania nowej wersji w por\u00f3wnaniu ze zwyk\u0142ym Rolling Update. W przypadku Rolling Update proces wdra\u017cania jest prosty, ci\u0105g\u0142y oraz r\u00f3wnomiernie stopniowy \u2013 po prostu stopniowo zast\u0119pujemy stare repliki nowymi w tym samym tempie. <strong>W przypadku Canary Deployment tak nie jest<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Canary Deployment i g\u00f3rnicze kanarki<\/strong><\/h3>\n\n\n\n<p>Nazwa \u201eCanary Deployment\u201d pochodzi od g\u00f3rnik\u00f3w, kt\u00f3rzy w przesz\u0142o\u015bci stosowali kanarki jako wczesny system ostrzegania przed szkodliwymi gazami, takimi jak tlenek w\u0119gla (CO) i metan (CH4). Kanarki ostrzega\u0142y g\u00f3rnik\u00f3w o niebezpiecze\u0144stwie, zanim oni je rozpoznali. Podobnie jak g\u00f3rnicy w\u0119gla, in\u017cynierowie oprogramowania chc\u0105 mie\u0107 pewno\u015b\u0107, \u017ce nowy obszar (wersja aplikacji) jest bezpieczny i mo\u017ce by\u0107 u\u017cywany na wi\u0119ksz\u0105 skal\u0119.<\/p>\n\n\n\n<p>Zamiast po prostu wdra\u017ca\u0107 now\u0105 wersj\u0119 bez \u017cadnej kontroli podczas procesu wdra\u017cania, mo\u017cemy wykorzysta\u0107 Canary Deployment, aby pocz\u0105tkowo uruchomi\u0107 tylko kilka kontener\u00f3w w nowej wersji, tak aby tylko niekt\u00f3rzy u\u017cytkownicy korzystali z nowej wersji, a nast\u0119pnie, je\u015bli wszystko przebiegnie pomy\u015blnie (testy nie wykry\u0142y b\u0142\u0119d\u00f3w, a u\u017cytkownicy s\u0105 zadowoleni ze zmiany), mo\u017cemy przeprowadzi\u0107 pe\u0142n\u0105 aktualizacj\u0119 do nowej wersji (i ewentualnie wdro\u017cy\u0107 kilka dodatkowych przydatnych krok\u00f3w podczas procesu aktualizacji).<\/p>\n\n\n\n<p>Mo\u017cesz np. pocz\u0105tkowo zast\u0105pi\u0107 10% swoich replik w nowej wersji i przekierowa\u0107 10% ruchu produkcyjnego do tej nowej wersji. Nast\u0119pnie mo\u017cesz ustawi\u0107 czas oczekiwania lub manualn\u0105 bramk\u0119 (czekanie na r\u0119czne potwierdzenie), a w mi\u0119dzyczasie uruchomi\u0107 zautomatyzowane testy, kt\u00f3re b\u0119d\u0105 szuka\u0107 problemu w nowej wersj\u0105. Nast\u0119pnie, je\u015bli testy zako\u0144cz\u0105 si\u0119 powodzeniem, minie odpowiednia ilo\u015b\u0107 czasu lub zostanie zatwierdzona r\u0119czna bramka, skalujemy np. do 30% replik (i skierowanego ruchu) w nowej wersji i 70% ze starej wersji, nast\u0119pnie odczekaj jaki\u015b czas, a nast\u0119pnie przeskaluj do po\u0142owy replik w nowej wersji, a na koniec przeskaluj do 100% replik w nowej wersji.<\/p>\n\n\n\n<p>To tylko jedna z niesko\u0144czonej liczby mo\u017cliwych konfiguracji, kt\u00f3re mo\u017cesz skonfigurowa\u0107 za pomoc\u0105 Canary Deployment i Argo Rollouts. Argo Rollout oferuje ogromn\u0105 liczb\u0119 funkcji, kt\u00f3re zaspokoj\u0105 potrzeby procesu wdra\u017cania. Mo\u017cesz np. manipulowa\u0107 ilo\u015bci\u0105 ruchu przy u\u017cyciu 2 serwis\u00f3w K8s i kontrolera K8s Ingress dla lepszej izolacji wersji i niezale\u017cno\u015bci od liczby replik oraz kierowanego do nich ruchu (np. 10% replik w nowej wersji, ale tylko 5% ruchu kierowanego do tych replik).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Co wybra\u0107?<\/strong><\/h3>\n\n\n\n<p>Jak wida\u0107, <strong>Canary Deployment jest o wiele bardziej wszechstronn\u0105 strategi\u0105 wdra\u017cania w por\u00f3wnaniu z Rolling Update. Nie m\u00f3wi\u0119, \u017ce jest ona lepsza lub gorsza<\/strong>. Rzadko co\u015b w in\u017cynierii jest po prostu lepsze lub gorsze. Je\u015bli jedna z twoich aplikacji dzia\u0142aj\u0105cych w K8s nie wymaga wdro\u017cenia Canary, poniewa\u017c np. jest stosunkowo prosta, ma bardzo cz\u0119ste i drobne aktualizacje oraz nie wymaga kompleksowej walidacji przy ka\u017cdej aktualizacji do nowej wersji, wdro\u017cenie Canary by\u0142oby bez w\u0105tpienia przerostem formy ponad tre\u015bci\u0105 i powiniene\u015b pozosta\u0107 przy domy\u015blnym Rolling Update.<\/p>\n\n\n\n<p>Jednak je\u015bli Twoja aplikacja mo\u017ce skorzysta\u0107 z podej\u015bcia Canary Deployment, zdecydowanie powiniene\u015b rozwa\u017cy\u0107 jego wdro\u017cenie, szczeg\u00f3lnie przy u\u017cyciu Argo Rollouts.<\/p>\n\n\n\n<p>Je\u015bli jeste\u015b in\u017cynierem DevOps lub kim\u015b powi\u0105zanym z nowoczesnym cloud-native oraz konteneryzacj\u0105, to jest du\u017ce prawdopodobie\u0144stwo, \u017ce ju\u017c s\u0142ysza\u0142e\u015b o Argo CD. Je\u015bli tak, to dobrze, poniewa\u017c pomo\u017ce ci to zrozumie\u0107, czym jest Argo Rollouts. Oba te narz\u0119dzia maj\u0105 zupe\u0142nie inny cel, ale pod wzgl\u0119dem sposobu fundamentalnego dzia\u0142ania s\u0105 bardzo podobne \u2013 oba s\u0105 open-source kodem Golang, kt\u00f3ry mo\u017cemy zainstalowa\u0107 (wraz z dedykowanym narz\u0119dziem CLI), aby wykorzysta\u0107 nowy kontroler Kubernetes i zbi\u00f3r CRDs do cel\u00f3w zwi\u0105zanych z wdra\u017caniem w naszym klastrze K8s.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Najwa\u017cniejszy koncept w Argo Rollouts \u2013 Rollout<\/strong><\/h2>\n\n\n\n<p>Najwa\u017cniejszym konceptem w Argo Rollout jest CRD zwany \u201eRollout\u201d. Ten \u201enowy\u201d obiekt nie jest tak nowy, jak mog\u0142oby si\u0119 wydawa\u0107, poniewa\u017c Rollout to w zasadzie zwyk\u0142y K8s Deployment z wieloma przydatnymi funkcjonalno\u015bciami wdra\u017cania, kt\u00f3re s\u0105 w niego wbudowane.<\/p>\n\n\n\n<p>Zobaczmy przyk\u0142adow\u0105 definicj\u0119 obiektu Rollout:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\napiVersion: argoproj.io\/v1alpha1\nkind: Rollout\nmetadata:\n  name: nginx-rollout\n  labels:\n    app: nginx\nspec:\n  replicas: 10\n  selector:\n    matchLabels:\n      app: nginx\n  template:\n    metadata:\n      labels:\n        app: nginx\n    spec:\n      containers:\n      - name: nginx\n        image: my-image:v1\n        ports:\n        - containerPort: 80\n  strategy:\n    canary: \n      maxSurge: &#039;10%&#039;\n      maxUnavailable: &#039;10%&#039;\n      steps:\n        - setWeight: 30 \n        - pause:\n            duration: 30m \n        - setWeight: 40 \n        - pause:\n            duration: 1h \n        - pause: {} \n        # We don&#039;t need to explicitly specify below line because it&#039;s the default behavior\n        # - setWeight: 100 \n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\"><strong>Rollout a Deployment<\/strong><\/h3>\n\n\n\n<p>Jak wida\u0107, definicja Rolloutu jest prawie taka sama jak definicja Deploymentu, z trzema r\u00f3\u017cnicami:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><em>.apiVersion:<\/em><\/strong> \u2013 musimy u\u017cy\u0107 <strong><em>argoproj.io\/v1alpha1<\/em><\/strong> zamiast <strong><em>apps\/v1<\/em><\/strong><em>,<\/em><\/li>\n\n\n\n<li><strong><em>.kind:<\/em><\/strong> \u2013 musimy u\u017cy\u0107 <strong><em>Rollout<\/em><\/strong> zamiast <strong><em>Deployment<\/em><\/strong><em>,<\/em><\/li>\n\n\n\n<li><strong><em>.spec.strategy:<\/em><\/strong> \u2013 zamiast okre\u015bla\u0107 strategi\u0119 wdro\u017cenia w polu <strong><em>.spec.strategy.type<\/em><\/strong> i ewentualnie skonfigurowanie opcji Rolling Update w polu .<strong><em>spec.strategy.rollingUpdate<\/em><\/strong>, mamy mo\u017cliwo\u015b\u0107 wyboru mi\u0119dzy opcjami <strong><em>canary<\/em><\/strong> i <strong><em>blueGreen<\/em><\/strong> oraz okre\u015blenia opcji konfiguracji w tych nowych polach.<\/li>\n<\/ul>\n\n\n\n<p>Zasadniczo, wszystko jest takie samo jak w Deployment \u2013 z jedyn\u0105 powa\u017cn\u0105 r\u00f3\u017cnic\u0105 w konfiguracji strategii wdro\u017cenia. To \u015bwietna wiadomo\u015b\u0107 dla wszystkich, kt\u00f3rzy nie maj\u0105 czasu na walk\u0119 z pisaniem jakiego\u015b customowego manifestu CRD od zera, zw\u0142aszcza je\u015bli chcesz u\u017cy\u0107 tego niestandardowego zasobu jako zamiennika dla Deploymentu, kt\u00f3ry jest bezsprzecznie jednym z najwa\u017cniejszych obiekt\u00f3w w klastrach K8s.<\/p>\n\n\n\n<p>Dzi\u0119ki Argo Rollouts mo\u017cesz po prostu zainstalowa\u0107 Argo Rollouts (zajmiemy si\u0119 tym za chwil\u0119), zmieni\u0107 <strong><em>.apiVersion<\/em><\/strong>, <strong><em>.kind<\/em><\/strong> i doda\u0107 np. pole <strong><em>.spec.strategy.canary<\/em><\/strong> z <strong><em>{} <\/em><\/strong>jako warto\u015bci\u0105, i to wszystko! Je\u015bli nawet nie musisz niczego okre\u015bla\u0107 w polu <strong><em>.spec.strategy.canary<\/em><\/strong>, poniewa\u017c je\u015bli nic nie okre\u015blisz w tym polu, tw\u00f3j Rollout b\u0119dzie zachowywa\u0107 si\u0119 dok\u0142adnie tak jak zwyk\u0142y Deployment.<\/p>\n\n\n\n<p>Ale oczywi\u015bcie na pewno chcesz wykorzysta\u0107 funkcje, kt\u00f3re zapewnia Rollout, je\u015bli zdecydowa\u0142e\u015b si\u0119 zainstalowa\u0107 Argo Rollouts, <strong>wi\u0119c nie zostawiaj tego pola pustego<\/strong> \ud83d\ude09<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Pole <em>.spec.strategy<\/em><\/strong><\/h3>\n\n\n\n<p>Teraz wyja\u015bnijmy, co dzieje si\u0119 w polu <strong><em>.spec.strategy<\/em><\/strong> w przyk\u0142adzie, kt\u00f3ry tutaj pokaza\u0142em:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n...\n  strategy:\n    canary:\n      maxSurge: &#039;10%&#039;\n      maxUnavailable: &#039;10%&#039;\n      steps:\n        - setWeight: 30\n        - pause:\n            duration: 30m\n        - setWeight: 40\n        - pause:\n            duration: 1h\n        - pause: {}\n<\/pre><\/div>\n\n\n<p>Najpierw okre\u015blamy, \u017ce chcemy u\u017cy\u0107 strategii wdro\u017cenia Canary, a nast\u0119pnie opcjonalnie okre\u015blamy parametry <strong><em>maxSurge<\/em><\/strong> i <strong><em>maxUnavailable<\/em><\/strong>, kt\u00f3re dzia\u0142aj\u0105 dok\u0142adnie tak samo, jak w przypadku zwyk\u0142ego Deploymentu. W tym przypadku <strong><em>maxSurge<\/em><\/strong> zapewnia, \u017ce \u200b\u200bw stanie <strong><em>Running<\/em><\/strong> lub <strong><em>ContainerCreating<\/em><\/strong> nie b\u0119dzie nigdy wi\u0119cej ni\u017c 11 replik (\u0142\u0105cznie), a <strong><em>maxUnavailable<\/em><\/strong> zapewnia, \u017ce \u200b\u200bzawsze b\u0119dzie uruchomionych co najmniej 9 replik.<\/p>\n\n\n\n<p>Nast\u0119pnie okre\u015blamy nasze kroki wdra\u017cania, kt\u00f3re definiuj\u0105 zachowanie Rollout podczas aktualizacji do nowej wersji.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Aktualizacja poda do nowej wersji<\/strong><\/h3>\n\n\n\n<p>Oto wyja\u015bnienie krok po kroku, co si\u0119 stanie, gdy zaktualizujemy poda do nowej wersji:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Pocz\u0105tkowo mamy 10 replik w pojedynczym ReplicaSet z obrazem w wersji v1.<\/li>\n\n\n\n<li>Aktualizujemy wersj\u0119 obrazu do v2<\/li>\n\n\n\n<li><strong><u>Pierwszy krok<\/u><\/strong> jest wykonywany \u2013 1 replika jest usuwana ze starego ReplicaSet (z rewizj\u0105:1) i jednocze\u015bnie tworzony jest nowy ReplicaSet (z rewizj\u0105:2) z 2 replikami w stanie <strong><em>ContainerCreating<\/em><\/strong>, wi\u0119c b\u0119dziemy mie\u0107 9 dzia\u0142aj\u0105cych replik (wszystkie ze starego ReplicaSet) i 11 replik w stanie <strong><em>Running<\/em><\/strong> lub <strong><em>ContainerCreating<\/em><\/strong> (\u0142\u0105cznie). To jest dok\u0142adnie to, czego oczekujemy od naszej konfiguracji p\u00f3l i <strong><em>maxUnavailable<\/em><\/strong> i <strong><em>maxSurge<\/em><\/strong>.<\/li>\n\n\n\n<li>Zaraz po tym, jak jedna z replik z nowego ReplicaSet przejdzie ze stanu <strong><em>ContainerCreating<\/em><\/strong> do <strong><em>Running<\/em><\/strong>, tworzona jest nowa replika w nowym ReplicaSet, a jednocze\u015bnie inna replika ze starego ReplicaSet zostaje usuni\u0119ta, wi\u0119c b\u0119dziemy mie\u0107 9 dzia\u0142aj\u0105cych replik (1 z nowego ReplicaSet i 8 ze starego ReplicaSet) i 11 replik w stanie <strong><em>Running<\/em><\/strong> lub <strong><em>ContainerCreating<\/em><\/strong> (\u0142\u0105cznie).<\/li>\n\n\n\n<li>Zaraz po tym, jak inna replika z nowego ReplicaSet przejdzie ze stanu <strong><em>ContainerCreating<\/em><\/strong> do <strong><em>Running<\/em><\/strong>, inna replika ze starego ReplicaSet zostanie usuni\u0119ta, wi\u0119c b\u0119dziemy mie\u0107 9 dzia\u0142aj\u0105cych replik (2 z nowego ReplicaSet i 7 ze starego ReplicaSet) i 11 replik w stanie <strong><em>Running<\/em><\/strong> lub <strong><em>ContainerCreating<\/em><\/strong> (\u0142\u0105cznie).<\/li>\n\n\n\n<li>Zaraz po tym, jak kolejna replika z nowego ReplicaSet przejdzie ze stanu <strong><em>ContainerCreating<\/em><\/strong> do <strong><em>Running<\/em><\/strong>, kolejna replika ze starego ReplicaSet zostaje zako\u0144czona, wi\u0119c b\u0119dziemy mie\u0107 10 dzia\u0142aj\u0105cych replik (3 z nowego ReplicaSet i 7 ze starego ReplicaSet) i 10 replik w stanie <strong><em>Running<\/em><\/strong>, wi\u0119c pierwszy krok zosta\u0142 zako\u0144czony \u2013 mamy 30% dzia\u0142aj\u0105cych replik z nowego ReplicaSet i 30% ruchu jest kierowane do tych nowych replik.<\/li>\n\n\n\n<li><strong><u>Drugi krok<\/u><\/strong> jest wykonywany \u2013 Rollout czeka 30 minut (brak zmian w liczbie replik).<\/li>\n\n\n\n<li><strong><u>Trzeci krok<\/u><\/strong> jest wykonywany \u2013 1 replika jest usuni\u0119ta ze starego ReplicaSet i w tym samym czasie 1 replika jest tworzona w nowym ReplicaSet (i jest w stanie <strong><em>ContainerCreating<\/em><\/strong>).<\/li>\n\n\n\n<li>Gdy replika z nowego ReplicaSet przechodzi ze stanu <strong><em>ContainerCreating<\/em><\/strong> do <strong><em>Running<\/em><\/strong>, trzeci krok si\u0119 ko\u0144czy, poniewa\u017c mamy 40% dzia\u0142aj\u0105cych replik z nowego ReplicaSet i 40% ruchu jest kierowane do tych nowych replik.<\/li>\n\n\n\n<li><strong><u>Czwarty krok<\/u><\/strong> jest wykonywany \u2013 Rollout czeka 1 godzin\u0119 (brak zmian w liczbie replik).<\/li>\n\n\n\n<li><strong><u>Pi\u0105ty krok<\/u><\/strong> jest wykonywany \u2013 Rollouty czeka na manual\u0105 promocj\u0119. Jest to wa\u017cny krok, kt\u00f3ry implementuje r\u0119czn\u0105 bram\u0119 do naszego procesu wdra\u017cania. Ten krok jest ostatnim zdefiniowanym w tym manife\u015bcie, wi\u0119c jest ostatnim krokiem przed aktualizacj\u0105 naszego Rollout do 100% nowych replik. Teraz powinni\u015bmy przej\u015b\u0107 do interfejsu naszej aplikacji, prawdopodobnie wykona\u0107 kilka test\u00f3w i upewni\u0107 si\u0119, \u017ce naprawd\u0119 chcemy zaktualizowa\u0107 do nowej wersji. Je\u015bli wszystko wygl\u0105da dobrze, mo\u017cemy promowa\u0107 Rollout, np. u\u017cywaj\u0105c polecenia <strong><em>kubectl argo rollouts promote nginx-rollout<\/em><\/strong> (za chwil\u0119 poka\u017c\u0119, jak zainstalowa\u0107 to polecenie).<\/li>\n\n\n\n<li>Na koniec wykonywany jest ostatni krok \u2013 aktualizacja do 100% replik z nowego ReplicaSet i usuni\u0119cie wszystkich replik ze starego ReplicaSet (oczywi\u015bcie w zgodzie z polami <strong><em>maxSurge<\/em><\/strong> i <strong><em>maxUnavailable<\/em><\/strong>). Ten krok zostanie wykonany niezale\u017cnie od tego, czy go okre\u015blimy, czy nie.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Instalacja<\/strong><\/h3>\n\n\n\n<p>To by\u0142 prosty przyk\u0142ad u\u017cycia Rollout. Teraz przejd\u017amy przez proces instalacji, aby\u015b m\u00f3g\u0142 przetestowa\u0107 ten przyk\u0142ad na w\u0142asnym klastrze!<\/p>\n\n\n\n<p>Najpierw uruchom te 2 polecenia, aby zainstalowa\u0107 Argo Rollouts Controller i CRD:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nkubectl create namespace argo-rollouts\nkubectl apply -n argo-rollouts -f https:\/\/github.com\/argoproj\/argo-rollouts\/releases\/latest\/download\/install.yaml\n<\/pre><\/div>\n\n\n<p>Teraz mo\u017cesz ju\u017c wdro\u017cy\u0107 swoj\u0105 pierwsz\u0105 instancj\u0119 Rollout, ale zdecydowanie dobrym pomys\u0142em b\u0119dzie najpierw zainstalowanie kilku dodatkowych rzeczy.<\/p>\n\n\n\n<p>Po pierwsze, polecam \u017ceby\u015b zainstalowa\u0142 <a href=\"https:\/\/argo-rollouts.readthedocs.io\/en\/stable\/installation\/#kubectl-plugin-installation\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >Argo Rollouts plugin for kubectl<\/a>, kt\u00f3ra umo\u017cliwia promowanie wdro\u017ce\u0144, wizualizacj\u0119 procesu aktualizacji wdro\u017ce\u0144, przegl\u0105danie <a href=\"https:\/\/argo-rollouts.readthedocs.io\/en\/stable\/dashboard\/\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >Argo Rollouts Dashboard<\/a>, i og\u00f3lnie pozwala pracowa\u0107 wydajniej z obiektami Rollout. Ponadto, mo\u017cesz chcie\u0107 zainstalowa\u0107 <a href=\"https:\/\/argo-rollouts.readthedocs.io\/en\/stable\/installation\/#shell-auto-completion\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >shell auto-completion for Argo Rollouts<\/a>.<\/p>\n\n\n\n<p>Po zainstalowaniu ca\u0142ego potrzebnego oprogramowania, prawdopodobnie powiniene\u015b sam pobawi\u0107 si\u0119 Argo Rollouts. Mo\u017cesz u\u017cy\u0107 przyk\u0142adu, kt\u00f3ry ju\u017c tutaj pokaza\u0142em, lub przyk\u0142adu, kt\u00f3ry poka\u017c\u0119 za chwil\u0119, albo poszuka\u0107 innych dost\u0119pnych w Internecie (<a href=\"https:\/\/github.com\/argoproj\/argo-rollouts\/tree\/master\/examples\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >oficjalne przyk\u0142ady z GitHub<\/a> mog\u0105 by\u0107 dobrym punktem wyj\u015bcia).<\/p>\n\n\n\n<p>Zalecam otwieranie co najmniej dw\u00f3ch okien terminala jednocze\u015bnie \u2013 jednego, w kt\u00f3rym b\u0119dziesz wykonywa\u0142 polecenia takie jak np. <strong><em>kubectl apply<\/em><\/strong>, i drugiego, w kt\u00f3rym b\u0119dziesz uruchamia\u0142 polecenie <strong><em>kubectl argo rollouts get rollout nginx-rollout &#8211;watch<\/em><\/strong>. Dzi\u0119ki temu b\u0119dziesz na bie\u017c\u0105co ze wszystkim, co dzieje si\u0119 podczas wdra\u017cania (jak przebiega proces).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Zautomatyzowane testy skonfigurowane w procesie wdra\u017cania<\/strong><\/h2>\n\n\n\n<p>Teraz przejd\u017amy do znacznie ciekawszego przyk\u0142adu, kt\u00f3ry poka\u017ce ci jedn\u0105 z najwa\u017cniejszych zalet Argo Rollouts \u2013 <strong>automatyczne testy, kt\u00f3re s\u0105 uruchamiane podczas procesu wdra\u017cania<\/strong>. R\u0119czne bramki, przestoje czasowe i elastyczno\u015b\u0107 ustawiania ilo\u015bci aktualizowanych replik na ka\u017cdym etapie wdro\u017cenia to bardzo przydatne funkcjonalno\u015bci, ale nie tak prze\u0142omowe jak funkcjonalno\u015b\u0107 Argo Rollouts, kt\u00f3r\u0105 om\u00f3wimy teraz.<\/p>\n\n\n\n<p><strong>Argo Rollouts pozwala nam definiowa\u0107 naprawd\u0119 kompleksowe testy<\/strong>, kt\u00f3re b\u0119d\u0105 oparte np. na metrykach z twojego rozwi\u0105zania monitoruj\u0105cego (np. Prometheus), kt\u00f3re przetestuj\u0105 now\u0105 wersj\u0119 (rewizj\u0119) twojego Rollout i na podstawie wynik\u00f3w test\u00f3w zdecyduj\u0105, czy kontynuowa\u0107 proces wdra\u017cania, czy powr\u00f3ci\u0107 do poprzedniej wersji \u2013 <strong>wszystko w pe\u0142ni zautomatyzowany spos\u00f3b!<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Dwa manifesty<\/strong><\/h3>\n\n\n\n<p>Zobaczmy przyk\u0142ad z 2 manifestami. Jeden z Rollout, a drugi z nowym zasobem \u2013 AnalysisTemplate. AnalysisTemplate definiuje spos\u00f3b wykonywania analizy kanarkowej, takiej jak metryki, kt\u00f3re powinna wykona\u0107, jej cz\u0119stotliwo\u015b\u0107 i warto\u015bci, kt\u00f3re s\u0105 uwa\u017cane za udane lub nieudane.<\/p>\n\n\n\n<p>rollout.yml (z polem <strong><em>.spec<\/em><\/strong> uproszczonym dla lepszej czytelno\u015bci):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\napiVersion: argoproj.io\/v1alpha1\nkind: Rollout\nmetadata:\n  name: guestbook\nspec:\n# ...\n  strategy:\n    canary:\n      analysis:\n        templates:\n        - templateName: success-rate\n        startingStep: 2 # Delay starting analysis run until setWeight: 40%\n        args:\n        - name: service-name\n          value: guestbook-svc.default.svc.cluster.local\n      steps:\n      - setWeight: 20\n      - pause: {duration: 10m}\n      - setWeight: 40\n      - pause: {duration: 10m}\n      - setWeight: 60\n      - pause: {duration: 10m}\n      - setWeight: 80\n      - pause: {duration: 10m}\n<\/pre><\/div>\n\n\n<p>analysis-template.yml:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\napiVersion: argoproj.io\/v1alpha1\nkind: AnalysisTemplate\nmetadata:\n  name: success-rate\nspec:\n  args:\n  - name: service-name\n  metrics:\n  - name: success-rate\n    interval: 5m\n    # NOTE: Prometheus queries return results in the form of a vector.\n    # So it is common to access the index 0 of the returned array to obtain the value\n    successCondition: result&#x5B;0] &gt;= 0.95\n    failureLimit: 3\n    provider:\n      prometheus:\n        address: http:\/\/prometheus.example.com:9090\n        query: |\n          sum(irate(\n            istio_requests_total{reporter=&quot;source&quot;,destination_service=~&quot;{{args.service-name}}&quot;,response_code!~&quot;5.*&quot;}&#x5B;5m]\n          )) \/\n          sum(irate(\n            istio_requests_total{reporter=&quot;source&quot;,destination_service=~&quot;{{args.service-name}}&quot;}&#x5B;5m]\n          ))\n<\/pre><\/div>\n\n\n<p>W definicji Rollout mo\u017cemy zobaczy\u0107, \u017ce okre\u015blamy AnalysisTemplate, kt\u00f3ry zostanie u\u017cyty do naszego Rollout. Ponadto wyra\u017anie okre\u015blamy nazw\u0119 us\u0142ugi FQDN i to wszystko, co jest nowe, ale definicja AnalysisTemplate jest czym\u015b zupe\u0142nie nowym. W pliku analysis-template.yml <strong>okre\u015blamy konfiguracj\u0119<\/strong> AnalysisTemplate, tak\u0105 jak:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>interwa\u0142,<\/li>\n\n\n\n<li>warunek powodzenia,<\/li>\n\n\n\n<li>limit niepowodze\u0144,<\/li>\n\n\n\n<li>konfiguracja dostawcy.<\/li>\n<\/ul>\n\n\n\n<p>Nale\u017cy pami\u0119ta\u0107, \u017ce aby u\u017cy\u0107 tego przyk\u0142adu, musisz ju\u017c mie\u0107 dzia\u0142aj\u0105cego Prometheusa.<\/p>\n\n\n\n<p>Nasz AnalysisTemplate rozpocznie testowanie od drugiego kroku i b\u0119dzie wykonywa\u0142 zapytanie Prometheusa (wyra\u017cenie PromQL) co 5 minut, aby sprawdzi\u0107, czy wsp\u00f3\u0142czynnik powodzenia wynosi co najmniej 95%, a je\u015bli warunek nie zostanie spe\u0142niony 3 razy (wyst\u0105pi\u0105 3 lub wi\u0119cej niepowodze\u0144), nowa wersja (ReplicaSet) zostanie wycofana (zeskalowana do 0%), a poprzednia wersja zostanie ponownie zeskalowana do 100%, za\u015b ca\u0142e Rollout pozostanie w stanie <strong><em>Degraded<\/em><\/strong> (do momentu ponownej aktualizacji Rollout).<\/p>\n\n\n\n<p><strong>To \u015bwietna funkcjonalno\u015b\u0107<\/strong> \u2013 absolutnie zero r\u0119cznych operacji, nasze wdro\u017cenie jest wykonywane automatycznie z ci\u0105g\u0142ymi testami, a je\u015bli co\u015b jest nie tak, po prostu wr\u00f3cimy do poprzedniej (i prawie na pewno dzia\u0142aj\u0105cej) wersji! <strong>Wyobra\u017a sobie, ile mo\u017cesz zrobi\u0107 dzi\u0119ki tym testom<\/strong>.<\/p>\n\n\n\n<p>Mo\u017cesz bazowa\u0107 na:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>dowolnych metrykach (op\u00f3\u017anienie, wska\u017anik sukcesu, itp.),<\/li>\n\n\n\n<li>dowolnych logach,<\/li>\n\n\n\n<li>rezultatach z aplikacji.<\/li>\n<\/ul>\n\n\n\n<p><strong>Mo\u017cliwo\u015bci s\u0105 praktycznie nieograniczone<\/strong>.<\/p>\n\n\n\n<p>Same metryki Prometheusa dostarcz\u0105 Ci bardzo przydatnych informacji o potencjalnych problemach z now\u0105 wersj\u0105 twojej aplikacji, ale nie jeste\u015b ograniczony do Prometheusa \u2013 mo\u017cesz u\u017cywa\u0107 Datadog, NewRelic, AWS CloudWatch, a nawet skonfigurowa\u0107 K8s Jobs lub skonfigurowa\u0107 \u017c\u0105danie HTTP, kt\u00f3re b\u0119dzie szuka\u0107 okre\u015blonych pomiar\u00f3w! <\/p>\n\n\n\n<p>AnalysisTemplate to prawdziwa moc Argo Rollouts i <strong>jestem bliski stwierdzenia, \u017ce \u200b\u200bjest to najbardziej przydatna funkcja tego narz\u0119dzia<\/strong>, wi\u0119c je\u015bli ju\u017c zdecydowa\u0142e\u015b, \u017ce chcesz wdro\u017cy\u0107 Argo Rollouts ze wzgl\u0119du na jak\u0105\u015b inn\u0105 jego funkcjonalno\u015b\u0107, to gor\u0105co polecam wg\u0142\u0119bi\u0107 si\u0119 w <a href=\"https:\/\/argo-rollouts.readthedocs.io\/en\/stable\/features\/analysis\/\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >Analysis in Argo Rollouts<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Argo Rollouts wraz z Argo CD<\/strong><\/h2>\n\n\n\n<p>Pozosta\u0142a jedna rzecz, o kt\u00f3rej zdecydowanie warto wspomnie\u0107 \u2013 jak Argo Rollouts i Argo CD wsp\u00f3\u0142pracuj\u0105 ze sob\u0105, gdy s\u0105 u\u017cywane na tych samych K8s workloads?<\/p>\n\n\n\n<p>Oba te narz\u0119dzia pochodz\u0105 z tego samego projektu Argo, wi\u0119c jak mo\u017cna si\u0119 spodziewa\u0107, <strong>maj\u0105 \u015bwietn\u0105 integracj\u0119<\/strong>. Oba mog\u0105 by\u0107 u\u017cywane bez u\u017cywania drugiego (jako samodzielne narz\u0119dzia), ale w wi\u0119kszo\u015bci nowoczesnych konfiguracji K8s b\u0119dziesz chcia\u0142 zaimplementowa\u0107 Argo CD, oraz w zale\u017cno\u015bci od po\u017c\u0105danej strategii wdra\u017cania, mo\u017cesz r\u00f3wnie\u017c zaimplementowa\u0107 Argo Rollout.<\/p>\n\n\n\n<p>Oczywi\u015bcie wszystko wydaje si\u0119 jasne w przypadku pomy\u015blnego wdro\u017cenia \u2013 mamy aktualizacje obrazu w zdalnym repozytorium -&gt; Argo CD to zauwa\u017ca i rozpoczyna synchronizacj\u0119 -&gt; Argo Rollout wykonuje aktualizacj\u0119 (kt\u00f3ra jest pomy\u015blna) -&gt; mamy now\u0105 wersj\u0119 dzia\u0142aj\u0105c\u0105 w klastrze.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Czy grozi nam niesko\u0144czona p\u0119tla?<\/strong><\/h3>\n\n\n\n<p><strong>A co z sytuacj\u0105, gdy AnalysisTemplate zawiedzie, a proces wdra\u017cania zostanie przerwany przez Rollout, poniewa\u017c nowa wersja obrazu ma b\u0142\u0105d?<\/strong> Czy wpadniemy w niesko\u0144czon\u0105 p\u0119tl\u0119, w kt\u00f3rej Argo CD nieustannie pr\u00f3buje zsynchronizowa\u0107 stan ze zdalnego repozytorium, a jednocze\u015bnie Argo Rollout raz po raz zawodzi? Na szcz\u0119\u015bcie tak si\u0119 nie stanie. Argo CD jest \u015bwiadome stanu <strong><em>Degraded<\/em><\/strong> naszego Rollout i nie podejmie \u017cadnych dalszych dzia\u0142a\u0144, je\u015bli ten stan wyst\u0105pi, wi\u0119c zamiast wykona\u0107 nadpisanie, po prostu wy\u015bwietli status <strong><em>Out of Sync<\/em><\/strong>.<\/p>\n\n\n\n<p>To \u015bwietnie, ale co powinni\u015bmy zrobi\u0107 w przypadku takiej sytuacji? Jest co najmniej kilka sposob\u00f3w, aby sobie z tym poradzi\u0107.<\/p>\n\n\n\n<p>Uwa\u017cam, \u017ce je\u015bli ju\u017c u\u017cywasz podej\u015bcia GitOps w swoim SDLC, powiniene\u015b trzyma\u0107 si\u0119 warto\u015bci tej filozofii i u\u017cy\u0107 polecenia <strong><em>git revert<\/em><\/strong>, aby cofn\u0105\u0107 commit, kt\u00f3ry spowodowa\u0142 problem w najnowszej wersji, tak aby po wykonaniu pusha, twoje repozytorium git odzwierciedli\u0142o po\u017c\u0105dany stan. Argo CD zauwa\u017cy t\u0119 szans\u0119 i automatycznie zaktualizuje klaster, wi\u0119c sko\u0144czysz z repozytorium i klastrem K8s, kt\u00f3re s\u0105 ponownie zsynchronizowane, a Rollout jest stabilny i zdrowy (cho\u0107 z poprzedni\u0105 wersj\u0105).<\/p>\n\n\n\n<p>Ostatecznie mo\u017cesz po prostu pushn\u0105\u0107 now\u0105 zmian\u0119 z poprawk\u0105 buga, zamiast u\u017cywa\u0107 <strong><em>git revert<\/em><\/strong>, ale ta akcja oczywi\u015bcie zak\u0142ada, \u017ce \u200b\u200bwiesz, jak naprawi\u0107 problem, ju\u017c go naprawi\u0142e\u015b i masz nowy kontener Docker gotowy do u\u017cycia. Cz\u0119sto, gdy Rollout \u201ewywali si\u0119\u201d podczas procesu wdra\u017cania, najpierw chcesz przywr\u00f3ci\u0107 poprzedni\u0105 wersj\u0119 (u\u017cywaj\u0105c <strong><em>git revert<\/em><\/strong>), aby jak najszybciej zminimalizowa\u0107 zak\u0142\u00f3cenia w aplikacji, a nast\u0119pnie spr\u00f3bowa\u0107 faktycznie naprawi\u0107 problem i spr\u00f3bowa\u0107 wdro\u017cy\u0107 ponownie.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/oferty-pracy\/\"><img decoding=\"async\" width=\"737\" height=\"170\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2025\/01\/praca-k-1.jpg\" alt=\"oferta pracy\" class=\"wp-image-30086\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2025\/01\/praca-k-1.jpg 737w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2025\/01\/praca-k-1-300x69.jpg 300w\" sizes=\"(max-width: 737px) 100vw, 737px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Podsumowanie<\/strong><\/h2>\n\n\n\n<p>Argo Rollouts mo\u017ce by\u0107 \u015bwietnym rozwi\u0105zaniem, je\u015bli potrzebujesz implementacji bardziej zaawansowanej strategii wdra\u017cania (takiej jak Canary), zamiast polega\u0107 na domy\u015blnej aktualizacji Rolling Update w Kubernetes Deployment. Ponadto pami\u0119taj, \u017ce prawdopodobnie najwa\u017cniejszymi zaletami Argo Rollouts s\u0105 automatyczne testy i wycofania aktualizacji (automatyczny powr\u00f3t do poprzedniej wersji), wi\u0119c nie zapomnij o mocy tych funkcjonalno\u015bci.<\/p>\n\n\n\n<p>Zwr\u00f3\u0107 r\u00f3wnie\u017c uwag\u0119, \u017ce wdro\u017cenie tego nowego narz\u0119dzia do twojego klastra nie powinno by\u0107 zbyt skomplikowane, poniewa\u017c dokumentacja jest przejrzysta, zawiera kilka dobrych przyk\u0142ad\u00f3w, a spo\u0142eczno\u015b\u0107 DevOps stworzy\u0142a ju\u017c wiele \u015bwietnych przewodnik\u00f3w na z Argo CD w roli g\u0142\u00f3wnej. Nie powiniene\u015b r\u00f3wnie\u017c mie\u0107 problemu ze znalezieniem odpowiedniego problemu na GitHubie lub pytania na Stack Overflow, je\u015bli napotkasz jaki\u015b problem podczas pracy z Argo Rollouts.<\/p>\n\n\n\n<p>Na koniec, naprawd\u0119 wa\u017cna kwestia \u2013 zawsze pami\u0119taj, aby przeanalizowa\u0107 i upewni\u0107 si\u0119, \u017ce faktycznie potrzebujesz takiego narz\u0119dzia. Nie pr\u00f3buj wdra\u017ca\u0107 czego\u015b, co nie jest ci potrzebne. Nadmierna in\u017cynieria (overengineering) to jedna z najwi\u0119kszych pu\u0142apek dla ka\u017cdego in\u017cyniera (nie tylko in\u017cynier\u00f3w DevOps), wi\u0119c zawsze staraj si\u0119 kwestionowa\u0107 swoje wymagania, zamiast tworzy\u0107 lub akceptowa\u0107 prac\u0119, kt\u00f3ra nie przynosi rzeczywistej warto\u015bci (warto\u015bci biznesowej lub innego rodzaju).<\/p>\n\n\n\n<p>Niemniej, je\u015bli widzisz prawdziwe korzy\u015bci we Canary Deployment w przypadku twojej aplikacji, to Argo Rollouts czeka na Ciebie!<\/p>\n\n\n\n<p>***<\/p>\n\n\n\n<p>Je\u015bli interesuj\u0105 Ci\u0119 narz\u0119dzia stosowane w IT, zajrzyj koniecznie r\u00f3wnie\u017c <a href=\"https:\/\/sii.pl\/blog\/all\/przeglad-narzedzi\/\" target=\"_blank\" rel=\"noopener\" title=\"do innych artyku\u0142\u00f3w naszych ekspert\u00f3w\">do innych artyku\u0142\u00f3w naszych ekspert\u00f3w<\/a> \ud83d\ude42<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;30015&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;5&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 5)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Zaawansowane opcje wdra\u017cania z Kubernetes i Argo Rollouts&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 5)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Zwyk\u0142y deployment w Kubernetes zapewnia nam 2 strategie wdra\u017cania, kt\u00f3re mo\u017cemy okre\u015bli\u0107 w polu .spec.strategy.type \u2013 RollingUpdate (opcja domy\u015blna) i &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/zaawansowane-opcje-wdrazania-z-kubernetes-i-argo-rollouts\/\">Continued<\/a><\/p>\n","protected":false},"author":692,"featured_media":30017,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[2770,1546,1512,224,1084],"class_list":["post-30015","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-argo-rollouts","tag-przeglad-narzedzi","tag-poradnik","tag-kontener","tag-kubernetes"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2025\/01\/Zaawansowane-opcje-wdrazania-z-Kubernetes-i-Argo-Rollouts.jpg","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/30015"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/692"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=30015"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/30015\/revisions"}],"predecessor-version":[{"id":30088,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/30015\/revisions\/30088"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/30017"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=30015"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=30015"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=30015"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}