اجرای کانتینرها در WSL با استفاده از #C: بررسی عمیق ابزار wslc و SDK نیتیو مایکروسافت
نویسنده: وحید نصیری
تاریخ: ۱۴۰۵/۰۴/۱۵ ۰۹:۴۵
آدرس: www.dntips.ir
wslc، مجموعهای از SDKها را برای زبانهای C++ ،C و بهویژه #C ارائه داده است. در این مقاله، ابتدا به بررسی این ابزار خط فرمان پرداخته و سپس نحوه مدیریت کانتینرها را از درون کدهای داتنت بررسی میکنیم.wsl --update --pre-release
wsl --version
WSL version: 2.9.3.0 Kernel version: 6.18.35.2-1
wslc.exe (که به صورت پیشفرض با نام مستعار container.exe نیز در دسترس است) به محیط شما اضافه میشود. ساختار دستورات این CLI شباهت بسیاری به داکر دارد و کار با آن بسیار سرراست است.# دریافت یک ایمیج از داکر هاب wslc pull alpine:latest # اجرای یک دستور درون کانتینر و دریافت خروجی wslc run alpine:latest cat /etc/alpine-release # مشاهده لیست ایمیجهای دانلود شده wslc images # مشاهده کانتینرهای فعال wslc list
نکته: شما حتی میتوانید سناریوهای پیچیدهتر، مانند اجرای یک دسکتاپ کامل لینوکس یا اجرای پردازشهای سنگین یادگیری ماشین متصل به GPU را با wslc انجام دهید:wslc run --rm --gpus all pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime python -c "import torch; print(torch.cuda.is_available())"
virtiofs: این فایلسیستم جدید سرعت دسترسی و تبادل فایل بین ویندوز و کانتینر را تا ۲ برابر افزایش میدهد.consomme): این حالت شبکه تجربی، ترافیک لینوکس را مستقیماً از لایههای ویندوز عبور میدهد. این کار مشکل همیشگی توسعهدهندگان با کانتینرها در محیطهای سازمانی (مانند قطع شدن ارتباط به دلیل تغییرات VPN یا سیستمهای پروکسی) را کاملاً برطرف میکند..csproj)net11.0 خطا ایجاد خواهد کرد.<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net11.0-windows10.0.19041.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.WSL.Containers" Version="2.9.3" />
</ItemGroup>
</Project>using Microsoft.WSL.Containers;
const string imageName = "alpine:latest";
var storagePath = Path.Combine(AppContext.BaseDirectory, "WslcStorage");
// ۱. ایجاد و شروع یک Session (یک ماشین مجازی سبک و ایزوله اختصاصی)
Console.WriteLine("[wslc] Starting session...");
using var session = new Session(new SessionSettings("DotNetUpSession", storagePath));
session.Start();
// ۲. دانلود ایمیج درون خطی به داخل این Session
Console.WriteLine("[wslc] Pulling image...");
session.PullImage(new PullImageOptions(imageName));
// ۳. پیکربندی و ساخت کانتینر
using Container container = session.CreateContainer(new ContainerSettings(imageName)
{
InitProcess = new ProcessSettings { CommandLine = ["/bin/sleep", "infinity"] },
EnableAutoRemove = true,
});
// ۴. استارت کانتینر
container.Start();
// ۵. اجرای یک دستور و خواندن خروجی از Standard Output به صورت رویدادمحور
using var waitHandle = new ManualResetEventSlim();
using Stream stdout = Console.OpenStandardOutput();
using Process process = container.CreateProcess(new ProcessSettings
{
CommandLine = [
"/bin/sh",
"-c",
"echo \"Hello from a WSL container running Alpine $(cat /etc/alpine-release)\""
],
OutputMode = ProcessOutputMode.Event,
});
process.OutputReceived += data => stdout.Write(data, 0, data.Length);
process.Exited += _ => waitHandle.Set();
process.Start();
waitHandle.Wait(); // منتظر ماندن تا پایان اجرای دستور درون کانتینر
// ۶. پایان دادن به کار Session و آزادسازی منابع
Console.WriteLine("\n[wslc] Terminating session...");
session.Terminate();
Console.WriteLine("[wslc] Done.");Session ایجاد میکنید، کاملاً جدا و مستقل از کانتینرهایی است که به صورت عمومی در wslc CLI سیستم مشاهده میکنید.wslc --session DotNetUpSession images wslc --session DotNetUpSession container list
0.462.0-pre-release افزونه Dev Containers در VS Code، شما میتوانید با تغییر تنظیمات Docker Path به wslc، محیطهای توسعه ایزوله خود را مستقیماً روی کانتینرهای نیتیو ویندوز بالا بیاورید.wslc و SDK بومی داتنت، یک گزینه فوقالعاده سبک، سریع و ادغامشده با سیستمعامل را در اختیار ما قرار میدهد. این ابزار کارایی بالایی در سناریوهایی نظیر خودکارسازی تستهای نرمافزاری (Integration Tests)، اجرای خطوط لوله CI/CD محلی، یا توسعه ابزارهایی دارد که نیاز دارند به صورت برنامهنویسیشده فرآیندهای لینوکسی را در محیطی امن و ایزوله روی ویندوز اجرا کنند.consomme و سیستم مدیریت حافظه جدید، این کانتینرها سربار بسیار کمتری نسبت به یک ماشین مجازی کامل Hyper-V دارند.wslc سازگار نیستند. برای کارهای بزرگ سازمانی، کوبرنتیز روی سرورهای لینوکس خام (Bare-metal) همچنان استاندارد اول دنیاست.Microsoft.WSL.Containers وابستگی شدیدی به سیستمعامل میزبان (ویندوز و سشنهای WSL آن) دارد که پورتپذیری (Portability) برنامه شما را محدود میکند.wslc) اجرا میکنید، معماری زیرساختی سیستم به شکل زیر کار میکند:consomme در WSL جدید، ترافیک شبکه کانتینر مستقیماً از سوکتهای ویندوز عبور میکند. این کار تاخیر شبکه (Latency) را که در حالت عادی به دلیل لایههای مجازیسازی ایجاد میشد، به شدت کاهش میدهد.fork() استفاده میکند. اگر حجم نوشتن داده در ردیس بسیار زیاد باشد، شبیهسازی لینوکس در ویندوز ممکن است تحت فشارهای فوقسنگین دچار افت فریم و کندی عملکرد دیسک شود.IMemoryCache به جای Redis با WSL Containers توصیه نمیشود؟IMemoryCache (کش درونپروسهای یا In-Process) نهتنها توصیه میشود، بلکه در بسیاری از سناریوها گزینه بسیار بهتری نسبت به راهاندازی ردیس در کانتینر WSL است. IMemoryCache به شدت توصیه میشود:IMemoryCache دادهها را مستقیماً داخل حافظه RAM اختصاصیِ خود پروسه داتنت (In-Process) ذخیره میکند. در این حالت، خواندن دادهها نیازی به هیچ ارتباط شبکهای، فرآیند سریالسازی (Serialization) به JSON یا بایت، و لایههای مجازیسازی ندارد. سرعت آن عملاً در حد نانوثانیه است، در حالی که ردیس (حتی در سریعترین حالت روی لوکال) به دلیل استفاده از سوکتهای شبکه، تاخیری در حد میلیثانیه دارد.builder.Services.AddMemoryCache() فعال میشود. IMemoryCache درون پروسه برنامه قرار دارند، با هر بار آپدیت اپلیکیشن، ریاستارت شدن IIS یا کرش کردن برنامه، کل دادههای کششده پاک میشوند و با اولین درخواستها، فشار سنگینی به دیتابیس وارد میشود تا کش دوباره ساخته شود (مسئله Cache Stampede). اما ردیس خارج از پروسه برنامه شماست و با ریاستارت شدن اپلیکیشن، دادههای آن حفظ میشوند.HybridCache معرفی کرده است که بهترینِ هر دو جهان را به شما میدهد.IMemoryCache) جستجو میشوند تا در کسری از میلیثانیه پاسخ داده شوند. HybridCache به صورت پیشفرض جلوی مشکل همزمانی شدید درخواستها برای یک دادهی کشنشده (Stampede Protection) را میگیرد. IMemoryCache را انتخاب کنید و خود را درگیر کانتینر و ردیس نکنید.HybridCache داتنت استفاده کنید که تلفیقی هوشمندانه از هر دو لایه است.