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.
Eğer kubectl patch
karşı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 PUT
и PATCH
. Bu durumda, update
и replace
Kullanılmış PUT
Ve patch
ne 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, kubectl
Go 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 apply
yani olmayan kaynakların oluşturulması ve mevcut olanların güncellenmesi tamamen kod tarafında çalışır kubectl
. Çabalar gösteriliyor 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 patch
Kaynağı 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. 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 apply
Yani, 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 apply
olarak kullanılabilir edit
Ve 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. patch
kaynaktan 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: 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: replace
kı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. kubectl
API 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
iradeapplication/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.
Kaynak: habr.com