Korumalı alana alma

Sorun bildirin Kaynağı göster

Bu makalede Bazel'de korumalı alana alma, sandboxfs hizmetini yükleme ve korumalı alan ortamınızda hata ayıklama konuları ele alınmaktadır.

Korumalı alana alma, işlemleri birbirinden veya 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, derleme grafiğinde derlemenin yeniden üretilebilirliğini etkileyebilecek gizli bağımlılıkları önlemesini sağlar.

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. Daha sonra Bazel, işlemi execroot/ içinde kısıtlamak için işletim sistemi tarafından sağlanan bir teknik (Linux'ta container'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. 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ış yeniden kullanılması, uzaktan önbelleğe alma sırasında sorunlara yol açar. Paylaşılan bir önbellekteki hatalı bir önbellek girişi, projedeki her geliştiriciyi etkiler ve uzak önbelleğin tamamının silinmesi 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. Uzaktan yürütmenin tüm gerekli dosyaları (yerel araçlar dahil) yüklemesini sağlayarak, her yeni derleyici denemek veya mevcut bir araçta değişiklik yapmak istediğinizde araçları kümedeki her makineye yüklemeniz gerekmesine kıyasla, derleme kümeleri için bakım maliyetlerini önemli ölçüde azaltabilirsiniz.

Hangi korumalı alan stratejisi kullanılmalıdır?

Strateji işaretleriyle, varsa ne tür bir korumalı alan kullanılacağı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 iletirseniz kalıcı çalışanlar genel bir korumalı alanda çalışır.

local (diğer adıyla standalone) stratejisi herhangi bir korumalı alan oluşturmaz. İş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 "ileri düzey" özellik gerektirmeyen bir korumalı alan stratejisidir. Kullanıma hazır tüm POSIX sistemlerinde çalışır. Orijinal kaynak dosyalara işaret eden sembolik bağlantılardan oluşan bir korumalı alan dizini oluşturur, işlemin komut satırını execroot yerine bu dizine ayarlanmış çalışma diziniyle yürütür, ardından bilinen çıkış yapılarını korumalı alandan execroot'a taşır ve korumalı alanı siler. Bu, işlemin bildirilmemiş giriş dosyalarını yanlışlıkla kullanmasını ve execroot'u bilinmeyen çıkış dosyalarıyla dolmasını önler.

linux-sandbox bir adım daha ileri gidiyor ve processwrapper-sandbox temelini oluşturuyor. 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 oluşturulan 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 hemen hemen aynı sonuca ulaşmak için Apple'ın sandbox-exec aracını kullanır.

Hem linux-sandbox hem de darwin-sandbox, işletim sistemlerinin sağladığı mekanizmalardaki kısıtlamalar nedeniyle "iç içe yerleştirilmiş" 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ı alan kullanmanın dezavantajları

  • Korumalı alan oluşturma, ek kurulum ve sökme maliyetine neden olur. 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'ta, korumalı alana alınan derlemeler nadiren yüzde birkaç 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 ö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, temeldeki dosya sisteminin rastgele bir görünümünü zaman cezası olmaksızın sunan bir FUSE dosya sistemidir. Bazel, her işlem için anında execroot/ oluşturmak amacıyla sandboxfs kullanır. Böylece, binlerce sistem çağrısı yapma maliyetinden kurtulmuş olursunuz. execroot/ içindeki diğer G/Ç'lerin, FUSE ek yükü nedeniyle daha yavaş olabileceğini unutmayın.

Sandboxf'leri yükleme

sandboxfs uygulamasını yüklemek ve bununla bir Bazel derlemesi gerçekleştirmek için aşağıdaki adımları uygulayın:

İndir

indirip yükleyin sandboxfs, böylece sandboxfs ikili programı PATH içinde oluşturulur.

Çalıştır sandboxfs

  1. (yalnızca macOS) OSXFUSE'i yükleyin.
  2. (yalnızca macOS) Çalıştırma:

    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.

  3. --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ı 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, kullanıcı ad alanları güvenlik nedeniyle 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ı

Korumalı alan, sistem kurulumu nedeniyle 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 ve 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 özelliklerini kullanarak Bazel'ın derlemeniz başarısız olduğunda çalıştırdığı komutu (korumalı alanı oluşturan bölüm de dahil) tam olarak göstermesini sağlayı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ıklama işlemi gerçekleştirmiyorsanız --sandbox_debug zaman içinde diskinizi doldurduğu için devre dışı bırakmanız gerekir.