Kubernetes, Nomad veya herhangi bir bulutta barındırılan hizmet olarak platform (Paas) gibi platformlar çeşitli güçlü yetenekler sunar. İş yüklerinin ölçeklendirilmesinden gizli dizi yönetimine ve dağıtım stratejilerine kadar bu iş yükü düzenleyicileri, altyapının farklı şekillerde ölçeklendirilmesine yardımcı olmak için optimize edilmiştir.
Ancak operatörlerin her zaman maksimum ölçeklenebilirlik için maliyet ödemesi gerekiyor mu? Bazen karmaşıklığın ve soyutluğun maliyeti, yararlarının önüne geçer. Bunun yerine birçok inşaatçı, yönetim kolaylığı için son derece basit dağıtım mimarilerine güvenmeye başladı. Bir yük dengeleyicinin arkasındaki iki sanal özel sunucu, bir konteyner ana bilgisayar filosu boyunca yayılan bir mikro sunucu kümesiyle karşılaştırıldığında yönetimi çok daha basit bir yığındır. Sorunlar ortaya çıktığında hata ayıklamak veya bakım zamanı geldiğinde yükseltme yapmak için daha az hareketli parça olduğunda bu, temettü ödemeye başlayabilir.
Birçok modern Linux dağıtımının temeli systemd'dir ve genellikle konteyner orkestratörleri veya PaaS sistemleriyle karşılaştırılabilecek güçlü özelliklerle birlikte gelir. Bu makalede, yönetim sorunu yaşamadan diğer büyük sistemlerin yeteneklerini kazanmak için en son systemd özelliklerinden nasıl yararlanabileceğinizi ve herhangi bir sıradan Linux sunucusunu çok yetenekli bir uygulama platformu haline getirecek şekilde nasıl güçlendirebileceğinizi keşfedeceğiz.
Tek bir ana bilgisayarda systemd .service
dosyası yazmak, yönetilen bir işlemi çalıştırmanın ideal bir yoludur. Çoğu zaman uygulamayı değiştirmenize bile gerek kalmaz: systemd çeşitli farklı türdeki hizmetleri destekler ve buna göre uyum sağlayabilir.
Örneğin, basit bir web hizmetinin nasıl çalıştırılacağını tanımlayan bu basit .service
düşünün:
[Unit] Description=a simple web service [Service] ExecStart=/usr/bin/python3 -m http.server 8080
Systemd hizmetleri için varsayılanları unutmayın: ExecStart=
mutlak bir yol olmalı, işlemler arka plana çatallanmamalı ve gerekli ortam değişkenlerini Environment=
seçeneğiyle ayarlamanız gerekebilir.
/etc/systemd/system/webapp.service
gibi bir dosyaya yerleştirildiğinde, systemctl
ile kontrol edebileceğiniz bir hizmet oluşturulur:
systemctl start webapp
işlemi başlatacaktır.systemctl status webapp
hizmetin çalışıp çalışmadığını, çalışma süresini ve stderr
ve stdout
çıktısının yanı sıra işlemin kimliğini ve diğer bilgileri görüntüler.systemctl stop webapp
hizmeti sonlandıracak.
Ek olarak, stderr
ve stdout
yazdırılan tüm çıktılar, Journald tarafından toplanacak ve sistem günlüğü aracılığıyla ( journalctl
ile) erişilebilecek veya özellikle --unit
bayrağı kullanılarak hedeflenecektir:
journalctl --unit webapp
Journald varsayılan olarak depolama alanını dönüşümlü olarak yönettiğinden ve günlükleri günlük aracılığıyla toplamak, günlük depolamasını yönetmek için iyi bir stratejidir.
Bu makalenin geri kalanında bunun gibi bir hizmeti geliştirmeye yönelik seçenekler incelenecektir.
Kubernetes gibi konteyner orkestratörleri, Secrets'ı güvenli bir şekilde ekleme yeteneğini destekler: güvenli veri depolarından alınan ve çalışan iş yüklerine sunulan değerler. API anahtarları veya şifreler gibi hassas veriler, kasıtsız olarak açığa çıkmayı önlemek için ortam değişkenlerinden veya yapılandırma dosyalarından farklı bir işlem gerektirir.
LoadCredential=
systemd seçeneği, diskteki dosyalardan hassas değerlerin yüklenmesini ve bunların güvenli bir şekilde çalışan hizmetlere sunulmasını destekler. Sırları uzaktan yöneten barındırılan platformlar gibi, systemd de Kimlik Bilgilerini, güvende tutulduklarından emin olmak için ortam değişkenleri gibi değerlerden farklı şekilde ele alacaktır.
Bir systemd hizmetine bir sır enjekte etmek için, gizli değeri içeren bir dosyayı dosya sistemindeki bir yola yerleştirerek başlayın. Örneğin, bir API anahtarını bir .service
birimine göstermek için, yeniden başlatmalarda dosyayı kalıcı kılmak için /etc/credstore/api-key
konumunda veya dosyanın kalıcı olarak kalıcı olmasını önlemek için /run/credstore/api-key
konumunda bir dosya oluşturun ( path isteğe bağlı olabilir, ancak systemd bu credstore
yollarını varsayılan olarak değerlendirecektir). Her iki durumda da, dosyanın chmod 400 /etc/credstore/api-key
gibi bir komut kullanılarak sınırlı izinlere sahip olması gerekir.
.service
dosyasının [Service]
bölümü altında, LoadCredential=
seçeneğini tanımlayın ve iki nokta üst üste ( :
) ile ayrılmış iki değeri iletin: kimlik bilgisinin adı ve yolu. Örneğin, /etc/credstore/api-key
dosyamızı "token" olarak adlandırmak için aşağıdaki systemd hizmet seçeneğini tanımlayın:
LoadCredential=token:/etc/credstore/api-key
Systemd hizmetinizi başlattığında, sır ${CREDENTIALS_DIRECTORY}/token
biçiminde bir yol altında çalışan hizmete sunulur; burada ${CREDENTIALS_DIRECTORY}
, systemd tarafından doldurulan bir ortam değişkenidir. Uygulama kodunuz, API belirteçleri veya parolalar gibi güvenli değerler gerektiren kitaplıklarda veya kodlarda kullanılmak üzere bu şekilde tanımlanan her gizli diziyi okumalıdır. Örneğin Python'da bu sırrı aşağıdaki gibi kodla okuyabilirsiniz:
from os import environ from pathlib import Path credentials_dir = Path(environ["CREDENTIALS_DIRECTORY"]) with Path(credentials_dir / "token").open() as f: secret = f.read().strip()
Daha sonra secret
değişkeni, API belirteci veya parola gerektirebilecek tüm kitaplıklar için sırrınızın içeriğiyle birlikte kullanabilirsiniz.
Nomad gibi orkestratörlerin bir başka yeteneği de çöken bir iş yükünü otomatik olarak yeniden başlatabilme yeteneğidir. İşlenmeyen bir uygulama hatasından veya başka bir nedenden dolayı, başarısız uygulamaların yeniden başlatılması, bir uygulamayı dayanıklı olacak şekilde tasarlarken genellikle ilk savunma hattı olan çok kullanışlı bir özelliktir.
Restart=
systemd seçeneği, systemd'nin çalışan bir işlemi otomatik olarak yeniden başlatıp başlatmayacağını kontrol eder. Bu seçeneğin çeşitli potansiyel değerleri vardır, ancak temel hizmetler için on-failure
ayar çoğu kullanım durumunu karşılamak için çok uygundur.
Otomatik yeniden başlatmayı yapılandırırken göz önünde bulundurulması gereken diğer bir ayar da, hizmeti yeniden başlatmadan önce sistemin ne kadar bekleyeceğini belirleyen RestartSec RestartSec=
seçeneğidir . Tipik olarak, bu değerin, başarısız hizmetlerin sıkı bir döngüde yeniden başlatılmasını ve potansiyel olarak süreçleri yeniden başlatmak için harcanan çok fazla CPU zamanını tüketmesini önlemek için özelleştirilmesi gerekir. 5s
gibi çok uzun süre beklemeyen kısa bir değer genellikle yeterlidir.
Süre aralıklarını veya zamana dayalı değerleri kabul eden RestartSec=
gibi seçenekler, ihtiyaçlarınıza bağlı olarak 5min 10s
veya 1hour
gibi çeşitli biçimleri ayrıştırabilir. Ek bilgi için systemd.time kılavuzuna bakın.
Son olarak, diğer iki seçenek, sistemin sonunda pes etmeden önce başarısız üniteleri ne kadar agresif bir şekilde yeniden başlatmaya çalışacağını belirler. StartLimitIntervalSec=
ve StartLimitBurst=
belirli bir süre içinde bir ünitenin ne sıklıkla başlatılmasına izin verildiğini kontrol eder. Örneğin aşağıdaki ayarlar:
StartLimitBurst=5 StartLimitIntervalSec=10
Bir ünitenin 10 saniyelik bir süre içinde yalnızca en fazla 5 kez başlatmayı denemesine izin verir. Yapılandırılmış hizmet 10 saniye içinde altıncı kez başlatmayı denerse, systemd üniteyi yeniden başlatma girişimini durduracak ve bunun yerine failed
olarak işaretleyecektir.
Tüm bu ayarları birleştirerek, .service
biriminize otomatik yeniden başlatmaları yapılandırmak için aşağıdaki seçenekleri dahil edebilirsiniz:
[Unit] StartLimitBurst=5 StartLimitIntervalSec=10 [Service] Restart=on-failure RestartSec=1
Bu yapılandırma, bir hizmeti başarısız olursa (yani sıfırdan farklı bir çıkış koduyla beklenmedik bir şekilde çıkarsa) bir saniye bekledikten sonra yeniden başlatır ve süreç boyunca beş defadan fazla başlatmayı denerse hizmeti yeniden başlatma girişimini durdurur. 10 saniye.
Bir konteyner içinde çalışmanın başlıca faydalarından biri güvenlik korumalı alan oluşturmadır. Bir uygulama sürecini temeldeki işletim sisteminden bölümlere ayırarak, hizmette mevcut olabilecek herhangi bir güvenlik açığının tam gelişmiş bir tehlikeye dönüşmesi çok daha zordur. Docker gibi çalışma zamanları bunu, grupların ve diğer güvenlik temellerinin bir kombinasyonu aracılığıyla başarır.
Temeldeki ana bilgisayarı öngörülemeyen iş yükü davranışına karşı korumaya yardımcı olabilecek benzer kısıtlamaları uygulamak için çeşitli sistemd seçeneklerini etkinleştirebilirsiniz:
ProtectSystem=
/boot
ve /usr
gibi hassas sistem yollarına yazma erişimini kısıtlayabilir. Bu seçeneğe ilişkin belgeler mevcut tüm seçenekleri sıralamaktadır, ancak genel olarak konuşursak, bu seçeneği full
olarak ayarlamak, bu dosya sistemi yollarını korumak için makul bir varsayılandır.ProtectHome=
/home
, /root
ve /run/user
dizinlerini read-only
ayarıyla salt okunur olarak ayarlayabilir veya true
olarak ayarlandığında bunları hizmetin dosya sistemine boş dizinler olarak bağlayabilir. Uygulamanızın bu dizinlere erişmeye özel bir ihtiyacı olmadığı sürece, bunu true
olarak ayarlamak, sistemi bu dizinlere yasadışı erişime karşı güvenli bir şekilde güçlendirebilir.PrivateTmp=
yapılandırılan hizmet için ayrı bir /tmp
ve /var/tmp
dosyası tutar, böylece bu hizmete ve diğer işlemlere ilişkin geçici dosyalar özel kalır. İşlemlerin geçici dosyalar aracılığıyla bilgi paylaşması için zorlayıcı bir neden olmadığı sürece, bu, etkinleştirilmesi yararlı bir seçenektir.NoNewPrivileges=
yürütülen işlemin ayrıcalıklarını yükseltememesini sağlayarak bir hizmeti güçlendirmenin başka bir güvenli ve basit yoludur . Diğer sağlamlaştırma seçeneklerini kullanma yeteneğinden emin değilseniz, bu genellikle etkinleştirilmesi en az sorunlu olanlardan biridir.
systemd.exec kılavuz sayfası, hizmetler gibi yürütülebilir iş yükleri için geçerli olan farklı seçenekleri keşfetmeye yönelik yararlı bir kaynaktır.
Systemd projesinin kılavuz sayfaları kapsamlıdır ve kendi uygulamalarınızı çalıştırmak için mevcut tüm seçenekler hakkında bilgi edinmek için kullanışlıdır. İster bir web sunucusu gibi kalıcı bir hizmet çalıştırıyor olun, ister bir cron işini değiştirmek için periyodik bir .timer
ünitesi çalıştırıyor olun, systemd dokümantasyonu faydalı rehberlik sağlayabilir.