Kubernetes Uygulama, Değiştirme ve Yama İşlemlerinin Doğru Karşılaştırması

Kubernetes'in kaynakları güncellemek için çeşitli seçenekleri vardır: uygulama, düzenleme, yama ve değiştirme. Her birinin ne yapacağı ve ne zaman kullanılacağı konusunda kafa karışıklığı var. Hadi çözelim.

Kubernetes Uygulama, Değiştirme ve Yama İşlemlerinin Doğru Karşılaştırması

Eğer Google'da ara "kubernetes uygula vs değiştir" ifadesi bulunur StackOverflow'a yanıt verbu doğru değil. arama yaparken "kubernetes application vs patch" ilk bağlantı aşağıdaki belgelerdir: kubectl patchkarşılaştırma içermeyen apply и patch. Bu makale farklı seçeneklere ve her birinin doğru kullanımına bakacaktır.

Bir Kubernetes kaynağının yaşam döngüsü sırasında (hizmet, dağıtım, giriş vb.) bazen bu kaynağın bazı özelliklerini değiştirmeniz, eklemeniz veya kaldırmanız gerekir. Örneğin bir not ekleyin, kopya sayısını artırın veya azaltın.

Kubernetes CLI'sı

Zaten CLI aracılığıyla Kubernetes kümeleriyle çalışıyorsanız, bunları zaten biliyorsunuzdur. apply и edit. Takım apply kaynak spesifikasyonunu dosyadan okur ve Kubernetes kümesine bir "upsert" yapar; Kaynak yoksa oluşturur, varsa günceller. Takım edit API aracılığıyla bir kaynağı okur, ardından kaynak spesifikasyonunu yerel bir dosyaya yazar ve bu dosya daha sonra bir metin düzenleyicide açılır. Dosyayı düzenleyip kaydettikten sonra, kubectl yapılan değişiklikleri API aracılığıyla geri gönderecek ve API bu değişiklikleri dikkatli bir şekilde kaynağa uygulayacaktır.

Herkes komutları bilmiyor patch и replace. Takım patch komut satırında yalnızca değiştirilen kısmı sağlayarak kaynak spesifikasyonunun bir kısmını değiştirmenize olanak tanır. Takım replace aynı şekilde çalışır edit, ancak her şeyin manuel olarak yapılması gerekiyor: kaynak spesifikasyonunun güncel sürümünü örneğin kullanarak indirmeniz gerekiyor. kubectl get -o yaml, düzenleyin ve ardından kullanın replace Bir kaynağı değişen spesifikasyona göre güncellemek için. Takım replace Kaynağın okunması ve değiştirilmesi arasında herhangi bir değişiklik meydana gelirse çalışmaz.

Kubernetes API'sı

Muhtemelen yöntemleri biliyorsunuzdur CoreV1().Pods().Update(), replaceNamespacedService veya patch_namespaced_deployment, eğer kümelerle çalışıyorsanız Kubernetes API'si için istemci kitaplığı bazı programlama dilleri kullanarak. Kütüphane bu yöntemleri, yöntemleri kullanarak HTTP istekleri aracılığıyla işler. PUT и PATCH. Bu durumda, update и replace Kullanılmış PUTVe patchne kadar önemsiz olursa olsun, kullanır PATCH.

Bu unutulmamalıdır ki kubectl ayrıca API aracılığıyla kümelerle de çalışır. Başka bir deyişle, kubectlGo dili için istemci kitaplığının üstünde yer alan ve standart API yeteneklerine ek olarak alt komutları daha kompakt ve okunabilir bir biçimde sağlama yeteneğini büyük ölçüde sağlayan bir sarmalayıcıdır. Örneğin, daha önce fark etmiş olabileceğiniz gibi, yöntem apply Yukarıdaki paragrafta belirtilmemişti. Şu anda (Mayıs 2020, yakl. çevirmen) tüm mantık kubectl applyyani olmayan kaynakların oluşturulması ve mevcut olanların güncellenmesi tamamen kod tarafında çalışır kubectl. Çabalar gösteriliyor mantıksal aktarım hakkında apply API tarafına, ancak hala beta aşamasında. Aşağıda daha detaylı yazacağım.

Varsayılan olarak yama

En iyi kullanılan patchKaynağı güncellemek istiyorsanız . Her iki istemci kitaplığı da Kubernetes API'sinin üzerinde bu şekilde çalışır ve kubectl (istemci kitaplığı için bir sarmalayıcı olduğundan şaşırtıcı değil, yakl. çevirmen).

Stratejik olarak çalışın

Tüm takımlar kubectl apply, edit и patch yöntemi kullan PATCH Mevcut bir kaynağı güncellemek için HTTP isteklerinde. Komutların uygulanmasını daha ayrıntılı olarak incelerseniz, hepsi bu yaklaşımı kullanır. stratejik birleştirme yaması kaynakları güncellemek için komut olmasına rağmen patch başka yaklaşımlar kullanabilir (bununla ilgili daha fazlası aşağıdadır). Stratejik birleştirme yama yaklaşımı, sağlanan spesifikasyonu mevcut spesifikasyonla birleştirerek "doğruyu yapmaya" çalışır. Daha spesifik olarak, hem nesneleri hem de dizileri birleştirmeye çalışır; bu da değişikliklerin eklemeli olma eğiliminde olduğu anlamına gelir. Örneğin, komutu çalıştırmak patch Pod kapsayıcısı belirtiminde yeni bir ortam değişkeninin yer alması, bu ortam değişkeninin mevcut ortam değişkenlerinin üzerine yazmak yerine onlara eklenmesine neden olur. Bu yaklaşımı kullanarak kaldırmak için, parametre değerini sağlanan spesifikasyonda null değerine zorlamanız gerekir. Takımlardan hangisi kubectl Güncelleme için kullanmak en iyisi midir?

Kaynaklarınızı kullanarak oluşturur ve yönetirseniz kubectl apply, güncelleme yaparken her zaman kullanmak daha iyidir kubectl applyöyle ki kubectl Yapılandırmayı yönetebilir ve uygulamadan uygulamaya istenen değişiklikleri doğru şekilde izleyebilir. Avantaj her zaman kullanın apply daha önce uygulanmış bir spesifikasyonu takip ederek spesifikasyon özelliklerinin ve dizi öğelerinin ne zaman açıkça kaldırıldığını bilmesine olanak sağlamasıdır. Bu, kullanmanıza olanak tanır apply özellikleri ve dizi öğelerini kaldırmak için normal bir stratejik birleştirme işe yaramaz. Takımlar edit и patch notları güncellemeyin kubectl apply Değişiklikleri izlemek için kullanır; dolayısıyla Kubernetes API aracılığıyla izlenen ve yapılan ancak komutlar aracılığıyla yapılan tüm değişiklikler edit и patch, sonraki komutlara görünmez applyYani, apply giriş spesifikasyonunda görünmeseler bile bunları kaldırmaz apply (Belgeler şunu söylüyor edit и patch kullanılan notlarda güncellemeler yap apply, ancak pratikte - hayır).

Eğer komutu kullanmazsanız applyolarak kullanılabilir editVe patch, yapılan değişikliğe en uygun komutu seçerek. Malzeme Listesi özelliklerini eklerken ve değiştirirken her iki yaklaşım da kabaca aynıdır. Belirtim özelliklerini veya dizi öğelerini silerken edit tek seferlik bir başlatma gibi davranıyor apply, belirtimin düzenlenmeden önce ve sonra nasıl olduğunu takip etmek de dahil, böylece özellikleri ve dizi öğelerini bir kaynaktan açıkça kaldırabilirsiniz. Spesifikasyonda özellik değerini açıkça null olarak ayarlamanız gerekir. patchkaynaktan kaldırmak için. Stratejik birleştirme yamasını kullanarak bir dizi öğesinin kaldırılması, birleştirme yönergelerinin kullanılmasını gerektirdiğinden daha karmaşıktır. Daha geçerli alternatifler için aşağıdaki diğer yükseltme yaklaşımlarına bakın.

İstemci kitaplığında yukarıdaki komutlara benzer şekilde davranan güncelleme yöntemlerini uygulamak için kubectl, isteklerde ayarlanmalıdır content-type в application/strategic-merge-patch+json. Bir spesifikasyondaki özellikleri kaldırmak istiyorsanız, benzer şekilde değerlerini açıkça null olarak ayarlamanız gerekir. kubectl patch. Dizi öğelerini kaldırmanız gerekiyorsa, güncelleştirme spesifikasyonuna birleştirme yönergelerini dahil etmeli veya güncelleştirmeler için farklı bir yaklaşım kullanmalısınız.

Güncellemelere yönelik diğer yaklaşımlar

Kubernetes diğer iki güncelleme yaklaşımını da destekler: JSON birleştirme yaması и JSON yaması. JSON birleştirme yaması yaklaşımı, girdi olarak kısmi bir Kubernetes spesifikasyonunu alır ve stratejik birleştirme yaması yaklaşımına benzer şekilde birleştirme nesnelerini destekler. İkisi arasındaki fark, bölme spesifikasyonundaki kap dizisi de dahil olmak üzere yalnızca dizi değiştirmeyi desteklemesidir. Bu, JSON birleştirme yamasını kullanırken herhangi bir kapsayıcının herhangi bir özelliğinin değişmesi durumunda tüm kapsayıcılar için eksiksiz spesifikasyonlar sağlamanız gerektiği anlamına gelir. Dolayısıyla bu yaklaşım, bir Malzeme Listesindeki bir diziden öğeleri kaldırmak için kullanışlıdır. Komut satırında şunu kullanarak JSON birleştirme yamasını seçebilirsiniz: kubectl patch --type=merge. Kubernetes API ile çalışırken request yöntemini kullanmalısınız PATCH ve kurulum content-type в application/merge-patch+json.

JSON yaması yaklaşımı, bir kaynağın kısmi spesifikasyonunu sağlamak yerine, kaynakta yapmak istediğiniz değişiklikleri bir dizi olarak sağlamayı kullanır; burada dizinin her bir öğesi, kaynakta yapılan değişikliğin bir açıklamasını temsil eder. Bu yaklaşım, yapılan değişiklikleri ifade etmenin daha esnek ve güçlü bir yoludur, ancak kısmi bir kaynak spesifikasyonu göndermek yerine, yapılan değişikliklerin ayrı, Kubernetes olmayan bir biçimde listelenmesi pahasına olur. İÇİNDE kubectl kullanarak JSON yamasını seçebilirsiniz. kubectl patch --type=json. Kubernetes API'yi kullanırken bu yaklaşım istek yöntemini kullanarak çalışır PATCH ve kurulum content-type в application/json-patch+json.

Güvene ihtiyacımız var - değiştirmeyi kullanın

Bazı durumlarda kaynağın okunduğu andan güncellendiği zamana kadar kaynakta herhangi bir değişiklik yapılmadığından emin olmanız gerekir. Başka bir deyişle, tüm değişikliklerin gerçekleşeceğinden emin olmalısınız. atomik. Bu durumda, kullanmanız gereken kaynakları güncellemek için replace. Örneğin, birden fazla kaynak tarafından güncellenen bir sayacın bulunduğu bir ConfigMap'iniz varsa, iki kaynağın sayacı aynı anda güncellemediğinden, güncellemenin kaybolmasına neden olmadığından emin olmalısınız. Göstermek için yaklaşımı kullanarak bir dizi olayı hayal edin. patch:

  • A ve B, kaynağın mevcut durumunu API'den alır
  • Her biri, sayacı birer birer artırarak ve ayrıca "güncelleyen" notuna sırasıyla "A" veya "B" ekleyerek spesifikasyonu yerel olarak günceller.
  • Ve kaynağı biraz daha hızlı günceller
  • B kaynağı günceller

Sonuç olarak A güncellemesi kaybolur. Son işlem patch kazanırsa, sayaç iki yerine bir artar ve "güncelleyen" notunun değeri "B" ile biter ve "A" içermez. Yukarıdakileri, yaklaşım kullanılarak güncellemeler yapıldığında ne olacağıyla karşılaştıralım. replace:

  • A ve B, kaynağın mevcut durumunu API'den alır
  • Her biri, sayacı birer birer artırarak ve ayrıca "güncelleyen" notuna sırasıyla "A" veya "B" ekleyerek spesifikasyonu yerel olarak günceller.
  • Ve kaynağı biraz daha hızlı günceller
  • B kaynağı güncellemeye çalışıyor ancak kaynak sürümü spesifikasyonda olduğundan güncelleme API tarafından reddediliyor replace kaynağın sürümü A'nın değiştirme işlemiyle artırıldığı için kaynağın Kubernetes'teki geçerli sürümüyle eşleşmiyor.

Yukarıdaki durumda B'nin kaynağı yeniden getirmesi, yeni durumda değişiklik yapması ve tekrar denemesi gerekecektir. replace. Bu, sayacın iki kat artmasına ve "güncellenen" notunun sonuna "AB" eklenmesine neden olacaktır.

Yukarıdaki örnek, yürütülürken şunu ima eder: replace Kaynağın tamamı tamamen değiştirildi. Şunun için kullanılan spesifikasyon: replacekısmi veya parça parça olmamalıdır. apply, ancak ekleme dahil eksiksiz resourceVersion spesifikasyon meta verilerine ekleyin. Etkinleştirmediyseniz resourceVersion veya sağladığınız sürüm güncel değilse değiştirme işlemi reddedilecektir. Yani kullanılacak en iyi yaklaşım replace – kaynağı okuyun, güncelleyin ve hemen değiştirin. Kullanma kubectlşöyle görünebilir:

$ kubectl get deployment my-deployment -o json 
    | jq '.spec.template.spec.containers[0].env[1].value = "new value"' 
    | kubectl replace -f -

Sırayla yürütülen aşağıdaki iki komutun başarılı bir şekilde yürütüleceğini belirtmekte fayda var, çünkü deployment.yaml mülkiyet içermez .metadata.resourceVersion

$ kubectl create -f deployment.yaml
$ kubectl replace -f deployment.yaml

Bu yukarıda söylenenlerle çelişiyor gibi görünüyor; "ekleme resourceVersion spesifikasyon meta verilerine ekleyin." Bunu söylemek yanlış mı? Hayır, değil, çünkü eğer kubectl belirtmediğinizi fark eder resourceVersion, bunu kaynaktan okuyacak ve belirttiğiniz spesifikasyona ekleyecek ve ancak bundan sonra çalıştıracaktır. replace. Atomikliğe güvenirseniz bu potansiyel olarak tehlikeli olduğundan, sihir tamamen yan tarafta çalışır. kubectlAPI ile çalışan istemci kitaplıklarını kullanırken buna güvenmemelisiniz. Bu durumda mevcut kaynak spesifikasyonunu okumanız, güncellemeniz ve ardından çalıştırmanız gerekecektir. PUT rica etmek.

Siz yama yapamazsınız, biz değiştiririz

Bazen API'nin gerçekleştiremeyeceği bazı değişiklikler yapmanız gerekebilir. Bu durumlarda, kaynağı silip yeniden oluşturarak değiştirilmesini zorunlu kılabilirsiniz. Bu kullanılarak yapılır kubectl replace --force. Komutun çalıştırılması, kaynakları hemen kaldırır ve ardından bunları sağlanan spesifikasyondan yeniden oluşturur. API'de "zorla değiştirme" işleyicisi yoktur ve bunu API aracılığıyla yapabilmek için iki işlem gerçekleştirmeniz gerekir. Öncelikle kaynağı ayarlayarak silmeniz gerekir. gracePeriodSeconds sıfıra (0) ve propagationPolicy "Arka Plan"da seçin ve ardından bu kaynağı istenen spesifikasyonla yeniden oluşturun.

Uyarı: Bu yaklaşım potansiyel olarak tehlikelidir ve tanımlanamayan bir duruma yol açabilir.

Sunucu tarafında uygula

Yukarıda belirtildiği gibi Kubernetes geliştiricileri mantığı uygulamaya çalışıyor apply arasında kubectl Kubernetes API'sinde. Mantık apply Kubernetes 1.18'de şu adresten kullanılabilir: kubectl apply --server-side veya yöntemi kullanarak API aracılığıyla PATCH с content-type application/apply-patch+YAML.

Not: JSON aynı zamanda YAML'de de geçerlidir, dolayısıyla spesifikasyonu JSON olarak gönderebilirsiniz. content-type irade application/apply-patch+yaml.

Bu mantığın yanında kubectl API aracılığıyla herkesin kullanımına sunulur, apply sunucu tarafında, spesifikasyondaki alanlardan kimin sorumlu olduğunu takip eder, böylece çatışmasız düzenleme için güvenli çoklu erişime izin verir. Başka bir deyişle, eğer apply sunucu tarafında daha yaygın hale gelecek, kubectl, Pulumi veya Terraform, GitOps gibi farklı istemciler için evrensel bir güvenli kaynak yönetimi arayüzünün yanı sıra istemci kitaplıklarını kullanarak kendi kendine yazılan komut dosyaları görünecektir.

sonuçlar

Kümelerdeki kaynakları güncellemenin farklı yollarına ilişkin bu kısa genel bakışın size yardımcı olacağını umuyorum. Bunun yalnızca uygulama ve değiştirme olmadığını bilmek güzel; bir kaynağı uygula, düzenle, yama veya değiştir kullanarak güncellemek mümkündür. Sonuçta prensip olarak her yaklaşımın kendi uygulama alanı vardır. Atomik değişiklikler için değiştirme tercih edilir; aksi takdirde, uygulama aracılığıyla stratejik birleştirme yamasını kullanmalısınız. En azından "kubernetes uygula vs değiştir" araması yaparken Google'a veya StackOerflow'a güvenemeyeceğinizi anlamanızı bekliyorum. En azından bu makale mevcut cevabın yerini alana kadar.

Kubernetes Uygulama, Değiştirme ve Yama İşlemlerinin Doğru Karşılaştırması

Kaynak: habr.com

Yorum ekle