Korumalı alana alma

Sorun bildir Kaynağı görüntüleyin Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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 bu, dosya sistemine erişimi kısıtlamak anlamına gelir.

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ı 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. 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ış ş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ütmenin davranışını taklit eder. Bir derleme korumalı alanda iyi çalışıyorsa uzaktan yürütmede de büyük olasılıkla ç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 ayarlandığı şekilde işlemin komut satırını yürütür.

processwrapper-sandbox, "gelişmiş" özellikler gerektirmeyen bir korumalı alan stratejisidir. Herhangi bir POSIX sisteminde kutudan çıkar çıkmaz ç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 platformun üzerine inşa edilmiştir. Docker'ın arka planda yaptığına benzer şekilde, işlemi ana makineden yalıtmak için Linux ad alanlarını (kullanıcı, bağlama, 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 herhangi bir değişiklik yapamaz. Bu sayede, hatalı bir testin yanlışlıkla $HOME dizininizi rm-rf komutuyla silmesini önleyebilirsiniz. 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, macOS için benzer bir uygulamadır. 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, kapsayıcı sihirbazı için Linux ad alanını da kullandığından docker run --privileged kullanmadığınız sürece linux-sandbox'ü Docker kapsayıcısı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.

Bir derleme hatası almak istiyorsanız (örneğin, yanlışlıkla daha az katı bir yürütme stratejisiyle derleme yapmamak için) Bazel'in kullanmaya çalıştığı yürütme stratejilerinin listesini açıkça değiştirin (örneğin, bazel build --spawn_strategy=worker,linux-sandbox).

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 alır.

Korumalı alana alma işleminin 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 ö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 tek kanallı çalışanlar olarak çalışır. Bu durum ek bellek kullanımına neden olabilir.

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 içeriyorsa aşağıdaki komutu çalıştırarak kullanıcı ad alanını 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 Bazel'in, derlemeniz başarısız olduğunda çalıştırılan tam komutu (korumalı alanı ayarlayan bölüm dahil) göstermesi için --verbose_failures ve --sandbox_debug simgesini 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.