Uygulama yapılandırmalarını depolamak için tercih edilen yol nedir?


38

Çoğu zaman, geliştirme uygulaması config'i projenin kök dizininde saklıyorum, şöyle:

app
|-- config.json

Ancak bu en iyi yaklaşım gibi görünmüyor çünkü bu yapılandırma sürüm kontrol sisteminde depolanıyor - muhtemelen kullanıcı adlarına, şifrelere ve diğer hassas özelliklere neden oluyor.

12 Factor App kılavuzu, config dosyalarını tamamen bırakmanızı ve konfigürasyon ayarları için ortam değişkenlerini kullanmanızı önerir:

... config ortam değişkenlerinde saklanır. Env değişkenleri, kod değiştirmeden dağıtımcılar arasında kolayca değiştirilebiliyor; config dosyalarının aksine, yanlışlıkla kod deposuna girme olasılıkları çok azdır; ve özel yapılandırma dosyalarından veya Java Sistem Özellikleri gibi diğer yapılandırma mekanizmalarından farklı olarak, bunlar dil ve işletim sistemi ile ilgili bir standarttır.

Bu bana kulağa çok hoş geliyor ama biri kaynak ortamını kontrol etmeden, belirtilen ortam değişkenlerini nerede saklıyor? Ve bu değişkenleri uygulamaya aktarmak için hangi araçları kullanabilirim? Düzinelerce yapılandırma seçeneği olabilir ve uygulamayı her başlatışınızda elle yazmanız hoş değildir - bu nedenle bir yerde bir tür dosyada depolanmaları gerekir. Böylece söz konusu dosya kaynak kontrolü ile sonuçlanacak ve başladığımız yere geri döneceğiz.

Yerel konfigürasyonun kaynak kontrolünde saklanma riski olmayan evrensel olarak kabul edilmiş bir yapılandırma seçeneği var mı?


1
Eh, en azından .gitignoresürüm kontrolünde kontrol edilmemesi gereken dosya veya klasörleri tanımlayabileceğim bir şey var . Söylediğiniz gibi, Env vars'ının gerçekten nerede yardım edeceğini görmüyorum, onları ayarlamak için bir komut dosyanız var ve proje ile birlikte saklanmalı ya da sisteminizde (bir ana dizinde veya hatta makinelerin başlangıcında 'bir yere' sahip olmalısınız) senaryolar) kendi başına çok fazla problem yaratıyor gibi görünüyor, özellikle de çok fazla konfigürasyon gerekliyse. Her durumda, config bilgisini bölerek gizli bilgilerin farklı dosyalara girmesini sağlayacağım.
thorsten müller

@ thorstenmüller - .gitignore ile sadece temel / şablon konfigürasyonunun hala saklanması gereken problemi vardır, bu, uygulamanın iki konfigürasyonu okuması gerektiği anlamına gelir - temel olan, varsayılan seçeneklerle (scm'de saklanır) ve yerel olan, tabanı geçersiz kılan (ve scm olarak kaydedilmez). Env vars ile toplu dağıtımın daha kolaylaştığını hayal ediyorum - yeni sanal makine kurulumu için ortam değişkenlerini belirlemek, standart olmayan bir dosyaya bir şeyler yazmaktan daha kolaydır.
Rogach

Güzel soru, Bunun için normal kullanıcıya özel uygulama veri deposunu kullanmaya başladıktan sonra hayat daha kolaylaştı ;-)
Wolf

1
Redis denediniz mi redis.io . Özel olarak sadece anahtar-değer yapı depolaması içindir.
Karan

2
@jporcenaluk - Anahtar-değer depolarını severim, fakat sadece config yönetimini idare etmek için uygulamaya tam kapsamlı bir redis ekledim, biraz overkill gibi hissettiriyor. Öte yandan, belki de yeterince büyük projeler üzerinde hiç çalışmadım.
Rogach

Yanıtlar:


16

Muhtemelen buna iyi bir cevap yok. Bir gün olağanüstü durum kurtarma amacıyla gerekli olacağı için bu verileri güvenli bir yerde saklamanız gerekiyor gibi görünüyor. Bu, ortam değişkenlerini ayarlayan özellik dosyalarına ve komut dosyalarına eşit olarak uygulanır.

  • Kaynak kodla (SVN / GIT'de vb.) Bu veri üretim veritabanı şifrelerini ve benzerlerini içereceğinden gerçekten kötü bir fikirdir.
  • Kurumsal gecelik yedeklemeniz yeterli olabilir, ancak kolayca erişilebilen bir değişiklik geçmişi tutmak olası değildir.
  • Verilerin, tüketen yazılıma ayrı olarak sürümlenmesi gerekir. Mevcut sistemimizde, konfigürasyon değişikliği yeni bir uygulama kurulumuna yol açıyor ve bu sadece yanlış.

Şu anda bu sorunun çözümlerine bakıyoruz ve kısıtlı erişime sahip bir kod deposuna yaslanıyoruz. Bu depo yalnızca yapılandırma verilerini içerir. Başkalarının paylaşacak deneyimleri var mı?


2
Bir proje için iki ayrı havuza sahip olmak iyi bir fikir gibi görünmüyor - temiz geri dönüşler yapamaz veya şubelerle çalışamazsınız, çünkü o zaman iki havuzu aynı anda manipüle etmeniz gerekecektir (örneğin, başka şubeler bazı yeni yapılandırma seçenekleri gerektirir) ve ne zaman config havuzuna geçmeden o yeni şubeye geç, işler garip şekillerde bozulur).
Rogach

2
@Rogach Ben senin fikrini alıyorum. Bazı konfigürasyonları kodda tutmanın geçerli nedenleri vardır, ancak sorunuzda söylediğiniz gibi, hassas malzemelerin başka bir yere gitmesi gerekir. Böylece iki depo kaçınılmaz görünüyor. Ayrıca, uygulama sunucularının sık sık burada yardımcı olduğunu da söylemedim. Veri kaynakları ve JNDI değişkenleri yönetici tarafından ayarlanabilir ve genel olmayacaktır.
kiwiron

İkinci bir mağaza mantıklı. Konfigürasyon ile birlikte saklanabilecek başka gizli bilgiler de olabilir (örneğin, müşterilerin sorunlarını gidermek için analiz edilen üretim verileri).
Kurt

1
@Rogach Çok fazla nefret çekiyor gibi gözüküyorlar, ama git alt modülleri bunun üstesinden gelebilirdi, sanırım - eğer bir tanesi doğru ayarlandıysa ve sınırlı erişim deposu içinde yaşayabilirdi.
Nadiren Needy

9

Sorunları ve olası çözümleri incelerken, Jeff Atwood tarafından popüler hale getirilmiş bir yöntemi kullanmamda bana yardımcı olur : Tanrı, hassas yapılandırma bilgilerini saklamak için bir yol yaratsaydı, bunu nasıl yapardı?

Peki, kimin yapılandırma bilgisine ihtiyaç duyduğunu bilir ve yalnızca bu insanlara verir ve bilgiye asla başkaları tarafından erişilemez.

İlk bölüm zaten dikkate alınmalıdır: kaynak kontrol sisteminiz kullanıcıların kimliğini doğrulamalıdır. Ve bu yaklaşım aynı zamanda Troy Hunt'ın 10 Kaynak Kontrolü Komutanlığı'nda "bağımlılıkların kaynak kontrolünde olması gerekir" # 10'a göre geçerliliği verilmiştir .

Ancak sızdırılmışsa nasıl güvenli tutulur? Orada düz metin olarak saklanması gerekmiyor! Şifreleme kullanın. .NET'te, yapılandırma dosyalarınızdaki bağlantı dizesi verilerini şifrelemek için atabileceğiniz adımlar vardır . Özel seçim teknolojinizle bunu yapmak için eşdeğer yöntemleri bulmanız gerekecektir.


3
Sadece açıklığa kavuşturmak istedim - şifreleme yapılandırması nasıl yardımcı olacak? Anladığım kadarıyla, tüm geliştiriciler arasında aynı şifre çözme şifresini paylaşmanız gerekecek ve bu sorunların aranması gibi görünüyor.
Rogach

Şirketinizin dışındaki bir kişi deponuza erişirse, şifreleriniz gizlenir. Birisi dosyaları projeden bir USB sürücüye kopyalar ve bir yere bırakırsa, aynı şey. Elbette sürdürülmesi gereken daha fazla iş olacak. Daha fazla güvenlik genellikle kolaylık pahasına gelir. Bu çözüm biraz hantal, size bunu vereceğim. OP'nin sorusunu çözmek için daha iyi bir yola açığım!
jporcenaluk

5

Birçok kişi yapılandırmayı kaynak kodunuzla birlikte düzenli dosyalarda saklamayı eleştirir, ancak benim deneyimime göre, bu aslında oldukça iyi bir çözüm:

  • Herhangi bir dilde uygulamak kolaydır. Birçok kutuda karmaşık konfigürasyon dosyaları için destek alıyorsunuz. Örneğin, Spring Boot özellikli Java söz konusu olduğunda, ağaç benzeri herhangi bir yapıyı ifade edebilen YAML desteği alırsınız ve farklı ortamlar için ayrı konfigürasyon dosyalarının yanı sıra çevreye özgü dosyaların devralabildiği temel bir yapılandırmaya sahip olmak kolaydır.
  • Yazılımınızı çalıştırmak için konfigürasyon gereklidir ve kod değişiklikleri genellikle konfigürasyon ayarlarının eklenmesini / değiştirilmesini gerektirir, bu nedenle konfigürasyonu ve kodu bir arada tutmak doğaldır.
  • Yapılandırmayı kaynakla birlikte saklamak, düzenli bir kod incelemesi sırasında hangi ayarın ve ne zaman veya hangi ayarları yapılandırabileceğinizi bilmek gibi, kaynak kontrolünün tüm avantajlarını sağlar.
  • CIA için çalışmadığınız sürece, güvenlik argümanı bana aşırı düşmüş görünüyor. Böylece veritabanı şifreniz, uygulamanızın çalıştığı makinedeki bir dosyada saklanır. Birisi uygulamanızla makineye erişebilirse, muhtemelen çok büyük bir sorun yaşarsınız - örneğin, uygulamanızı indirip aynı bağlantı noktasındaki yerine kendi uygulamalarını başlatabilirler. Böyle bir senaryoda, DB şifresine erişebilmek bu kadar büyük bir sorun olmayabilir. Tüm bağlantılarınız tam olarak şifrelenmediği sürece, makinenize erişebiliyorsa, ilgi çekici verilerin çoğunu yine de ağ arayüzlerinden alabilir.
  • Metinsel bir yapılandırma dosyasına sahip olmak, ancak içinde şifreleri veya diğer hassas verileri saklamamak için Hiera gibi bir araç kullanabilirsiniz .

Bu nedenle, çoğu durumda, kaynak denetiminde kodla birlikte depolanan metinsel yapılandırma iyi bir başlangıçtır.

Dağıtılmış sistemlerde iseniz veya uygulamalarınızı yeniden dağıtmadan konfigürasyonunuzu çalışırken değiştirebilirsiniz, daha iyi bir konfigürasyon sunucusuna dayalı bir çözüm bulabilirsiniz. Spring Cloud bu tür mekanizmaları destekliyor ve arka uç hizmet yapılandırmaları git deposu veya Eureka olabilir . Zookeeper'ı kullanarak da kendi başınıza dönebilirsiniz . Bu yaklaşımlardan herhangi biri, yazılımınızı yeniden kurmak ve yeniden dağıtmak zorunda kalmadan yapılandırmaları güncellemek için birçok sunucudaki tutarlı yapılandırmaların yönetilmesini kolaylaştıracaktır. Bu, config sunucusunu ve onu uygulamalarınızdan nasıl kullanacağınızı ve konuşlandırmak ve sürdürmek için başka bir sistemden nasıl faydalanacağını elbette gerektirir.


Ancak kod, config dosyasındaki sırlara sahip olmayan birinin ellerini değiştirir, gerçek bir karışıklık olacaktır.
Tim Ludwinski

@TimLudwinski Anahtarlar / sırlar, bireysel geliştiricilere değil, şirkete aittir, bu nedenle herhangi bir tek bir kişi ayrılırsa kaybolmayacak şekilde muhafaza edilmelidir. Örneğin merkezi bir kayıt defteri olması için yöneticiler / güvenlik ekibi tarafından bunlar sorun olabilir ve korunabilir.
Michał Kosmulski

5

Çalıştığım yerde de aynı problemle mücadele ediyoruz. Şu anda tüm konfigürasyonlarımız dosya tabanlı ve bunları kullanan bireysel uygulamalarla kaynak kontrollü. Bu, çoğaltmaya ve sadece geliştirme yerine üretim / qa parolalarına erişime sahip geliştiricilere yol açar.

Bu, ileriye doğru giden iyi bir çözüm bulduğumuzu söyledi. Config dosyalarımızı ayrı bir git repo'ya taşıyoruz (config repo etiketli). Daha sonra, kendisine iletilen profilleri temel alarak yalnızca config repo'daki dosyaları sunan bir bahar-cloud-config (java) sunucusu kurduk. Bu, istemciyi kullanıp başlangıçta indirebilecek Java uygulamaları için mükemmeldir. PHP / java dışı uygulamalarımız için dosyayı doğrudan indireceğiz. (Uygun değil). Gelecekte, PHP uygulamasının yapılandırmaları kendi başına indirmesine ve bir yerden önbelleğe almasına izin veren bir şey yazabiliriz, ancak ilk çalıştırma için yüksek öncelikli değildir. Bu çözümü, 12 faktör uygulamaları önerilerini açıkça ihlal etmeyen bir hizmet olarak yapılandırma olarak düşünüyorum.

Zookeeper'ın aynı şey için kullanılabileceğine inanıyorum (kubernetes + zookeeper ile bir kurulum gördüm) bu yüzden neden bu cevabın neden -1 olduğunu bilmiyorum.

Bağlantılar:

https://spring.io/guides/gs/centralized-configuration/

https://cloud.spring.io/spring-cloud-config/


3

Tüm yapılandırmayı tek bir dosyada saklamak yerine, birkaç dosyada saklayın.

  • Bir yapılandırma dizini var . Buradaki tüm dosyalar, belki hariç, yapılandırma dosyaları olarak yorumlanır README*.
  • Tüm dosya adları alfabetik olarak sıralanır ve dosyalar bu sıraya göre yüklenir. Bu gibi durumlarda dosyaları genellikle bir rakam veya iki ile başlar nedeni budur: 01-logging.json. 02-database.json, vb.
  • Tüm dosyalardan gelen veriler, uygulama için mevcut olan aynı yapılandırma yapısına yüklenir . Bu, birkaç dosyanın birbirlerinin ayarlarını nasıl tamamlayabildiğini ve hatta tahmin edilebilir bir şekilde onları geçersiz kılabileceği yoludur.
  • VCS'de yalnızca görülebilen güvenli değerlere sahip yapılandırma dosyalarını veya varsayılan değerleri saklayın. Yapılandırma sırasında yapılandırma dosyalarını sırlarla ekleyin veya kimliği doğrulanmış bir sır saklama hizmeti kullanın.

En yakın Linux kutunuzda, /etc/sudoers.dveya 'ya bakın /etc/nginx/conf.d. Aynı modeli gösterir.

Sır yönetimi farklı bir canavardır. Bunları küçükken manuel bir adım olarak yönetebilirsiniz. Zookeeper gibi şeyler kullanabilirsiniz. Sırları şifreli biçimde bir VCS'ye kontrol edebilir ve bir dağıtım adımı olarak şifresini çözebilirsiniz. Bir dizi başka seçenek var.

(Ayrıca, bir fikir parçası: JSON iyi bir yapılandırma dosyası formatı değildir, çünkü yorumlara izin vermez; yorumlar çok önemlidir. TOML, YAML ve hatta INI formatları pratik kullanımda daha iyidir.)


2

Seçenekleriniz biraz dağıttığınız işletim sistemi tarafından tanımlanmış.

Ben öneririm, evet, değerleri kaynak kontrolüne koy. AMA sadece 'dev' sürümleri. Kaynak kodunuzun derlenmesini ve çalışmasını istiyorsunuz! Ekstra gizli adımlar içermemelidir

Oluşturma ve dağıtma işleminiz, dağıtım sırasında bu değerleri ortam başına değiştirmelidir. (ahtapot bu tür bir modele sahiptir)


0

Apache zookeeper, dağıtılmış sistemler için uygulama yapılandırmalarını saklamak için harika seçenekler sunar. Hayvan bekçisinde yapılan değişiklikler, başvuru sonunda bir küratör veya hayvan bekçisi tarafından yakalanıp işlenebilir.


6
Seçenekler nedir? o nasıl çalışır? Onları nerede saklıyor? Biri diğerine mi tercih edilir? Her seçeneğin çeşitli avantajları ve dezavantajları nelerdir? Bu farklı işletim sistemlerinde nasıl etkileşime giriyor?

3
@Gangz - Daha ayrıntılı bir cevap ile ilgilenirim, lütfen aşağı yöndeki önerilerden vazgeçmeyin ve cevabınızı yardım edebilmek için geliştirin.
Jay Elston
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.