Bu makalede, Bazel'de korumalı alan, sandboxfs
'ü yükleme ve korumalı alan ortamınızda hata ayıklama ele alınmaktadır.
Korumalı alana alma, işlemleri birbirinden veya bir sistemdeki kaynaklardan izole eden 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ı, işlemleri yalnızca bilinen girişleri içeren bir çalışma dizininde çalıştırır. Böylece, derleyiciler ve diğer araçlar, mutlak yolları bilmedikleri sürece erişmemeleri gereken kaynak dosyaları görmez.
Korumalı alan, ana makine ortamını hiçbir şekilde gizlemez. İşlemler, dosya sistemindeki tüm dosyalara serbestçe erişebilir. Ancak kullanıcı ad alanları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 açık 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 görev yapar. execroot/
, tüm giriş dosyalarını işleme içerir ve oluşturulan tüm çıkışlar için kapsayıcı görevi görü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ı alan kullanmanın nedenleri
İşlem korumalı alanı olmadan Bazel, bir aracın tanımlanmamış giriş dosyalarını (bir işlemin bağımlılıklarında açıkça listelenmeyen dosyalar) kullanıp kullanmadığını bilemez. Beyan edilmemiş giriş dosyalarından biri değiştiğinde Bazel, derlemenin güncel olduğunu düşünmeye devam eder ve işlemi yeniden oluşturmaz. Bu durum, yanlış bir artımlı derlemeye neden olabilir.
Önbellek girişlerinin yanlış şekilde yeniden kullanılması, uzak önbelleğe alma sırasında sorunlara neden olur. 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 stratejisi kullanılmalıdır?
Strateji işaretleri ile, varsa kullanılacak korumalı alan türünü seçebilirsiniz. sandboxed
stratejisini kullanmak, Bazel'in aşağıda listelenen korumalı alan uygulamalarından birini seçmesine neden olarak daha az hermetik korumalı alana kıyasla işletim sistemine özel bir korumalı alanı tercih eder.
--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.
İşlemin komut satırını, çalışma dizini çalışma alanınızın execroot olarak ayarlanmış olacak şekilde 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 dışında tüm dosya sistemini salt okunur hale getirir. Böylece işlem, ana makine dosya sistemindeki herhangi bir öğeyi yanlışlıkla değiştiremez. Bu, hatalı bir testin yanlışlıkla $HOME dizininizi rm
-rf'lemesi gibi durumları önler. İsteğe bağlı olarak, işlemin ağa erişmesini de engelleyebilirsiniz. linux-sandbox
, işlemin diğer süreçleri görmesini önlemek ve sonunda tüm süreçleri (işlem tarafından başlatılan arka plan programları dahil) güvenilir bir şekilde sonlandırmak için PID ad alanlarını kullanır.
darwin-sandbox
benzerdir ancak macOS'te kullanılabilir. Linux korumalı alanıyla yaklaşık olarak aynı sonucu 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
öğesini halihazırda korumalı alana alınmış bir işlemin içinde çalıştıramazsınız. Dolayısıyla, bu durumlarda Bazel 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. Devre dışı bırakmak için --experimental_local_lockfree_output
işaretini iletin. Dinamik yürütme, kalıcı çalışanları sessizce korumalı alana alır.
Korumalı alana almanın dezavantajları
Korumalı alan, ek kurulum ve kaldırma maliyeti gerektirir. Bu maliyetin büyüklüğü, derlemenin şekli ve ana makine işletim sisteminin performansı gibi 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
ayarını yaparak kurulum ve kaldırma maliyetini azaltabilirsiniz.Korumalı alan, aracın sahip olabileceği tüm önbelleği etkili bir şekilde devre dışı bırakır. Daha zayıf korumalı alan garantileri pahasına, kalıcı çalışanlar kullanarak bu durumu azaltabilirsiniz.
Multiplex çalışanları, açık çalışan desteğinin korumalı alana alınmasını gerektirir. Multiplex korumalı alanını desteklemeyen çalışanlar, dinamik yürütme altında tek yönlü çalışanlar olarak çalışır ve bu da ekstra belleğe maliyete neden olabilir.
sandboxf'lar
sandboxfs
, temel dosya sisteminin zaman cezası olmadan keyfi bir görünümünü sunan bir FUSE dosya sistemidir. Bazel, her işlem için execroot/
'ı anında oluşturmak amacıyla sandboxfs
'ü kullanır. Böylece binlerce sistem çağrısı yapma maliyetinden kaçınılır. execroot/
içindeki diğer G/Ç'lerin, FUSE ek yükü nedeniyle daha yavaş olabileceğini unutmayın.
sandboxfs'yi yükleme
sandboxfs
'ü yüklemek ve bu sürümle Bazel derlemesi yapmak için aşağıdaki adımları uygulayın:
İndir
sandboxfs
ikili dosyası PATH
'ınıza eklensin diye sandboxfs
'yi indirip yükleyin.
Çalıştır sandboxfs
- (Yalnızca macOS) OSXFUSE'i yükleyin.
(Yalnızca macOS) Şunu çalıştırın:
sudo sysctl -w vfs.generic.osxfuse.tunables.allow_other=1
Temel macOS sistem hizmetlerinin sandboxf'ler üzerinden çalıştığından emin olmak için bu işlemi yüklemeden ve her yeniden başlatmadan sonra yapmanız gerekir.
--experimental_use_sandboxfs
ile Bazel derlemesi çalıştırın.bazel build target --experimental_use_sandboxfs
Sorun giderme
Yürütülen işlemler için ek açıklama olarak darwin-sandbox
yerine local
veya linux-sandbox
görürseniz bu, korumalı alanın devre dışı bırakıldığı anlamına gelebilir. Etkinleştirmek için --genrule_strategy=sandboxed --spawn_strategy=sandboxed
öğesini iletin.
Hata ayıklama
Korumalı alanla ilgili sorunları gidermek için aşağıdaki stratejileri uygulayın.
Devre dışı bırakılan 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 ve Bazel'in hangi dosyaları oluşturduğunu görebilir ve nasıl davrandığını görmek için komutu tekrar çalıştırabilirsiniz.
--sandbox_debug
kullandığınızda Bazel'in 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.