Bu makalede, Bazel'de korumalı alan ve korumalı alan ortamınızda hata ayıklama ele alınmaktadır.
Korumalı alan, işlemleri birbirinden veya sistemdeki kaynaklardan ayıran bir izin kısıtlama stratejisidir. Bazel için bunun anlamı dosya sistemi erişimini kısıtlamaktır.
Bazel'in dosya sistemi korumalı alanı, yalnızca bilinen girişleri içeren bir çalışma dizininde işlemleri yürütür. Böylece derleyiciler ve diğer araçlar, mutlak yollarını bilmedikleri sürece erişmeleri gerekmeyen kaynak dosyalarını görmez.
Korumalı alan, ana makine ortamını hiçbir şekilde gizlemez. İşlemler, dosya sistemindeki tüm dosyalara özgürce erişebilir. Ancak kullanıcı ad alanını destekleyen platformlarda işlemler, çalışma dizinlerinin dışındaki dosyaları değiştiremez. Bu sayede, derleme grafiğinde derlemenin yeniden üretilebilirliğini etkileyebilecek gizli bağımlılıklar bulunmaz.
Daha ayrıntılı olarak belirtmek gerekirse Bazel, her işlem için bir execroot/
dizini oluşturur. Bu dizin, yürütme sırasında işlemin çalışma dizini olarak işlev görür. execroot/
işlemin tüm giriş dosyalarını içerir ve oluşturulan tüm çıkışların kapsayıcısı olarak kullanılır. Ardından Bazel, işlemi execroot/
içinde sınırlamak için işletim sistemi tarafından sağlanan bir tekniği (Linux'da kapsayıcılar ve macOS'te sandbox-exec
) kullanır.
Korumalı alana alma nedenleri
İşlem korumalı alan olmadan, Bazel bir aracın bildirilmemiş giriş dosyaları (bir işlemin bağımlılıklarında açıkça listelenmeyen dosyalar) kullanıp kullanmadığını bilmez. Tanımlanmamış giriş dosyalarından biri değiştiğinde Bazel, derlemenin güncel olduğunu düşünür ve işlemi yeniden oluşturmaz. Bu durum, yanlış bir artımlı derlemeyle sonuçlanabilir.
Önbellek girişlerinin yanlış yeniden kullanılması, uzaktan önbelleğe alma sırasında sorunlara yol açar. Ortak bir önbelleğe eklenen bozuk bir önbelleğe girişi projedeki her geliştiriciyi etkiler ve uzak önbelleğin tamamını silmek uygun bir çözüm değildir.
Korumalı alan, uzaktan yürütme davranışını taklit eder. Bir derleme korumalı alan ile iyi çalışıyorsa büyük olasılıkla uzaktan yürütmede de çalışır. Uzak yürütme işleminin gerekli tüm dosyaları (yerel araçlar dahil) yüklemesini sağlayarak, yeni bir derleyiciyi denemek veya mevcut bir araçta değişiklik yapmak istediğinizde araçları kümedeki her makineye yüklemek zorunda kalmak yerine derleme kümelerinin bakım maliyetlerini önemli ölçüde azaltabilirsiniz.
Hangi korumalı alan stratejisini kullanacağınız
Strateji işaretleri ile, varsa kullanılacak korumalı alan türünü seçebilirsiniz. sandboxed
stratejisi kullanıldığında Bazel, aşağıda listelenen korumalı alan uygulamalarından birini seçer. Bu seçimde, daha az hermetik olan genel korumalı alana kıyasla işletim sistemine özel bir korumalı alan tercih edilir.
--worker_sandboxing
işaretini gönderirseniz kalıcı çalışanlar genel bir korumalı alanda çalışır.
local
(diğer adıyla standalone
) stratejisi herhangi bir tür korumalı alan kullanmaz.
Bu işlev, çalışma dizini çalışma alanınızın execroot olarak ayarlanmış şekilde işlemin komut satırını yürütür.
processwrapper-sandbox
, herhangi bir "gelişmiş" özellik gerektirmeyen bir korumalı alan stratejisidir. Hazır olarak herhangi bir POSIX sisteminde çalışmalıdır. Orijinal kaynak dosyalara işaret eden sembolik bağlantılardan oluşan bir korumalı alan dizini oluşturur, çalışma dizini execroot yerine bu dizin olarak ayarlanarak işlemin komut satırını yürütür, ardından bilinen çıkış yapılarını korumalı alandan execroot'a taşır ve korumalı alanı siler. Bu, işlemin yanlışlıkla tanımlanmamış giriş dosyalarını kullanmasını ve execroot'u bilinmeyen çıkış dosyalarıyla doldurmasını önler.
linux-sandbox
, processwrapper-sandbox
'ten bir adım daha ileri giderek bu temeli geliştirir. Docker'ın arka planına benzer şekilde, işlemi ana makineden izole etmek için Linux Ad Alanlarını (Kullanıcı, Bağlantı, PID, Ağ ve IPC ad alanları) kullanır. Yani, korumalı alan dizini hariç dosya sisteminin tamamını salt okunur hale getirir. Böylece, işlem ana makine dosya sisteminde yanlışlıkla hiçbir şeyi değiştiremez. Bu, hatalı bir testin yanlışlıkla $HOME dizininizi rm-rf komutuyla silmesini önler. Dilerseniz işlemin ağa erişmesini de engelleyebilirsiniz. linux-sandbox
, işlemin başka işlemleri görmesini önlemek ve sonunda tüm işlemleri (işlem tarafından oluşturulan daemon'lar dahil) güvenilir bir şekilde sonlandırmak için PID ad alanını kullanır.
darwin-sandbox
benzerdir ancak macOS'te kullanılabilir. Linux korumalı alanıyla hemen hemen aynı sonuçları elde etmek için Apple'ın sandbox-exec
aracını kullanır.
Hem linux-sandbox
hem de darwin-sandbox
, işletim sistemleri tarafından sağlanan mekanizmalardaki kısıtlamalar nedeniyle "iç içe yerleştirilmiş" bir senaryoda çalışmaz. Docker, aynı zamanda container büyüsü için Linux ad alanlarını da kullandığından docker run --privileged
kullanmadığınız sürece linux-sandbox
işlemini Docker container'ında kolayca çalıştıramazsınız. macOS'te, sandbox-exec
'ü zaten korumalı alanda olan bir işlem içinde çalıştıramazsınız. Bu nedenle, Bazel bu durumlarda otomatik olarak processwrapper-sandbox
kullanmaya geri döner.
Derleme hatası almayı (örneğin, yanlışlıkla daha düşük katı bir yürütme stratejisiyle derlememeyi) tercih ederseniz Bazel'in kullanmaya çalıştığı yürütme stratejileri listesini (örneğin, bazel build
--spawn_strategy=worker,linux-sandbox
) açıkça değiştirin.
Dinamik yürütme, genellikle yerel yürütme için korumalı alan gerektirir. Kapsam dışında kalmak için --experimental_local_lockfree_output
işaretini iletin. Dinamik yürütme, kalıcı çalışanları sessizce korumalı alana yerleştirir.
Korumalı alan kullanmanın dezavantajları
Korumalı alan, ek kurulum ve kaldırma maliyeti gerektirir. Bu maliyetin ne kadar büyük olacağı, derlemenin şekli ve ana makine işletim sisteminin performansı da dahil olmak üzere birçok faktöre bağlıdır. Linux için korumalı alan derlemeleri nadiren birkaç yüzdeden daha yavaştır.
--reuse_sandbox_directories
politikasının ayarlanması, kurulum ve söküm maliyetini azaltabilir.Korumalı alan, aracın sahip olabileceği tüm önbellekleri etkili bir şekilde devre dışı bırakır. Bu sorunu, kalıcı çalışanlar kullanarak azaltabilirsiniz. Bununla birlikte, korumalı alan garantileri daha zayıf olur.
Çoklu çalışanlar, korumalı alana yerleştirilmek için açık çalışan desteği gerektirir. Çoklu korumalı alan desteği sunmayan çalışanlar, dinamik yürütme altında tekil çalışan olarak çalışır. Bu da ek bellek kullanımına neden olabilir.
Hata ayıklama
Korumalı alan kullanımıyla ilgili sorunları ayıklamak için aşağıdaki stratejileri uygulayın.
Devre dışı ad alanları
Google Kubernetes Engine küme düğümleri veya Debian gibi bazı platformlarda, güvenlik endişeleri nedeniyle kullanıcı ad alanları varsayılan olarak devre dışı bırakılır. /proc/sys/kernel/unprivileged_userns_clone
dosyası varsa ve 0 değerini içeriyorsa kullanıcı ad alanlarını aşağıdaki komutu çalıştırarak etkinleştirebilirsiniz:
sudo sysctl kernel.unprivileged_userns_clone=1
Kural yürütme hataları
Sistem kurulumu nedeniyle korumalı alan kuralları yürütemeyebilir. namespace-sandbox.c:633: execvp(argv[0], argv): No such file or
directory
gibi bir mesaj görürseniz genel kurallar için --strategy=Genrule=local
, diğer kurallar için --spawn_strategy=local
ile korumalı alanı devre dışı bırakmayı deneyin.
Derleme hataları için ayrıntılı hata ayıklama
Derlemeniz başarısız olduysa --verbose_failures
ve --sandbox_debug
kullanarak Bazel'ın derlemeniz başarısız olduğunda çalıştırdığı komutu (korumalı alanı oluşturan bölüm dahil) tam olarak göstermesi için kullanın.
Örnek hata mesajı:
ERROR: path/to/your/project/BUILD:1:1: compilation of rule
'//path/to/your/project:all' failed:
Sandboxed execution failed, which may be legitimate (such as a compiler error),
or due to missing dependencies. To enter the sandbox environment for easier
debugging, run the following command in parentheses. On command failure, a bash
shell running inside the sandbox will then automatically be spawned
namespace-sandbox failed: error executing command
(cd /some/path && \
exec env - \
LANG=en_US \
PATH=/some/path/bin:/bin:/usr/bin \
PYTHONPATH=/usr/local/some/path \
/some/path/namespace-sandbox @/sandbox/root/path/this-sandbox-name.params --
/some/path/to/your/some-compiler --some-params some-target)
Artık oluşturulan korumalı alan dizinini inceleyebilir, Bazel'in hangi dosyaları oluşturduğunu görebilir ve nasıl davrandığını görmek için komutu tekrar çalıştırabilirsiniz.
Bazel, --sandbox_debug
kullanıldığında korumalı alan dizinini silmediğini unutmayın. Etkin bir şekilde hata ayıklamadığınız sürece --sandbox_debug
'ü devre dışı bırakmanız gerekir. Aksi takdirde, diskiniz zaman içinde dolar.