Kapsayıcı uygulamalarını Azure Batch
Azure Batch, Azure'da çok sayıda toplu işlem işi çalıştırma ve ölçeklendirmenizi sağlar. Batch görevleri doğrudan bir Batch havuzu içinde sanal makinelerde (düğümler) çalışmasına neden olabilir, ancak düğümler üzerinde Docker ile uyumlu kapsayıcılarda görevleri çalıştırmak için bir Batch havuzu da kurabilirsiniz. Bu makalede, kapsayıcı görevlerini çalıştırmayı destekleyen bir işlem düğümü havuzu oluşturma ve ardından havuzda kapsayıcı görevleri çalıştırma hakkında bilgi edinebilirsiniz.
Buradaki kod örnekleri Batch .NET ve Python SDK'larını kullanır. Kapsayıcı özellikli Batch havuzları oluşturmak ve kapsayıcı görevlerini çalıştırmak için Azure portal dahil olmak üzere diğer Batch SDK'larını ve araçlarını da kullanabilirsiniz.
Kapsayıcılar neden kullanılır?
Kapsayıcıları kullanmak, uygulamaları çalıştırmak için bir ortamı ve bağımlılıkları yönetmek zorunda kalmadan Batch görevlerini çalıştırmanın kolay bir yolunu sağlar. Kapsayıcılar, uygulamaları birkaç farklı ortamda çalıştırabilir basit, taşınabilir ve kendi kendine yeterli birimler olarak dağıtır. Örneğin, bir kapsayıcıyı yerel olarak derleme ve test edin, ardından kapsayıcı görüntüsünü Azure'da veya başka bir yerde yer alan bir kayıt defterine yükleyin. Kapsayıcı dağıtım modeli, uygulamayı nerede barındırırsanız barındırın, uygulamanın çalışma zamanı ortamının her zaman doğru şekilde yüklenmiş ve yapılandırılmış olması sağlanır. Batch'te kapsayıcı tabanlı görevler, uygulama paketleri ve kaynak dosyaları ile çıkış dosyalarının yönetimi de dahil olmak üzere kapsayıcı dışı görevlerin özelliklerinden de faydalanır.
Önkoşullar
Kapsayıcı kavramlarını ve Batch havuzu ve işi oluşturma hakkında bilgi sahibi olmak gerekir.
SDK sürümleri: Batch SDK'ları, aşağıdaki sürümlerden sonra kapsayıcı görüntülerini destekler:
- Batch REST API 2017-09-01.6.0 sürümü
- Batch .NET SDK sürüm 8.0.0
- Batch Python SDK sürüm 4.0
- Batch Java SDK sürüm 3.0
- Batch Node.js SDK sürüm 3.0
Hesaplar: Azure aboneliğinde bir Batch hesabı ve isteğe bağlı olarak bir Azure Depolama oluşturmanız gerekir.
Desteklenen bir VM görüntüsü: Kapsayıcılar, desteklenen bir görüntüden (sonraki bölümde listelenmiştir) yalnızca Sanal Makine Yapılandırması ile oluşturulan havuzlarda de kullanılabilir. Özel bir görüntü sağlarsanız, aşağıdaki bölümdeki noktalara ve Sanal makine havuzu oluşturmak için yönetilen özel görüntü kullanma bölümündeki gereksinimlere bakın.
Aşağıdaki sınırlamaları unutmayın:
- Batch yalnızca Linux havuzlarında çalışan kapsayıcılar için RDMA desteği sağlar.
- Kapsayıcı Windows için, havuzunuz için çok çekirdekli bir VM boyutu seçmenizi öneririz.
Desteklenen sanal makine görüntüleri
Kapsayıcı iş yükleri için VM işlem Windows havuzu oluşturmak için aşağıdaki desteklenen sanal makine veya Linux görüntülerinden birini kullanın. Batch ile uyumlu Market görüntüleri hakkında daha fazla bilgi için bkz. Sanal makine görüntülerinin listesi.
Windows desteği
Batch, Windows atamaları olan sunucu görüntülerini destekler. Genellikle bu görüntü sku'su adlarının son eki veya -with-containers -with-containers-smalldisk olur. Ek olarak, Batch'te desteklenen tüm görüntülerin listelene API'si, görüntünün Docker kapsayıcılarını desteklemesi DockerCompatible durumda bir özellik gösterir.
Ayrıca docker çalıştıran VM'lerden özel görüntüler oluşturabilirsiniz Windows.
Linux desteği
Linux kapsayıcı iş yükleri için Batch şu anda özel görüntüye gerek kalmadan Microsoft Azure Batch tarafından Azure Market Linux görüntülerini desteklemektedir.
RDMA olmadan VM boyutları
- Publisher:
microsoft-azure-batch- Teklif:
centos-container - Teklif:
ubuntu-server-container
- Teklif:
RDMA ile VM boyutları
- Publisher:
microsoft-azure-batch- Teklif:
centos-container-rdma - Teklif:
ubuntu-server-container-rdma
- Teklif:
Bu görüntüler yalnızca havuzlarda kullanım için Azure Batch ve Docker kapsayıcı yürütmesi için hazır. Bu özellik:
- Önceden yüklenmiş Docker uyumlu Moby kapsayıcı çalışma zamanı
- Azure N serisi VM'lerde dağıtımı basit hale getirmek için önceden yüklenmiş NVIDIA GPU sürücüleri ve NVIDIA kapsayıcı çalışma zamanı
- '-rdma' son ekini olan VM görüntüleri, InfiniBand RDMA VM boyutları desteğiyle önceden yapılandırılmıştır. Bu VM görüntüleri, InfiniBand desteğine sahip vm boyutlarıyla kullanılmamalı.
Batch ile uyumlu Linux dağıtımlarından biri üzerinde Docker çalıştıran VM'lerden özel görüntüler de oluşturabilirsiniz. Kendi özel Linux görüntülerinizi sağlamayı seçerseniz, Sanal makine havuzu oluşturmak için yönetilen özel görüntü kullanma yönergelerine bakın.
Özel görüntüde Docker desteği için Docker Community Edition (CE) veya Docker Enterprise Sürümü (EE) yükleyin.
Özel Linux görüntüsü kullanırken dikkat edilmesi gereken ek noktalar:
- Özel görüntü kullanırken Azure N serisi boyutların GPU performansından yararlanmak için NVIDIA sürücülerini önceden yükleyin. Ayrıca, NVIDIA GPU'ları için Docker Altyapısı Yardımcı Programı'nı , NVIDIA Docker'ı yüklemeniz gerekir.
- Azure RDMA ağına erişmek için RDMA özellikli bir VM boyutu kullanın. Batch tarafından desteklenen CentOS HPC ve Ubuntu görüntülerine gerekli RDMA sürücüleri yüklenir. MPI iş yüklerini çalıştırmak için ek yapılandırma gerekli olabilir. Bkz. Batch havuzunda RDMA özellikli veya GPU özellikli örnekleri kullanma.
Batch havuzu için kapsayıcı yapılandırması
Batch havuzunun kapsayıcı iş yüklerini çalıştırması için, havuzun VirtualMachineConfiguration nesnesinde ContainerConfiguration ayarlarını belirtmeniz gerekir. (Bu makale Batch .NET API başvurusuna bağlantılar sağlar. İlgili ayarlar Batch Python API'sindedir.)
Aşağıdaki örneklerde gösterildiği gibi önceden hazır kapsayıcı görüntüleri ile veya olmadan kapsayıcı özellikli bir havuz oluşturabilirsiniz. Çekme (veya önceden yükleme) işlemi, kapsayıcı görüntülerini İnternet'Docker Hub veya başka bir kapsayıcı kayıt defterinden önceden yüklemenizi sağlar. En iyi performans için Batch hesabıyla aynı bölgede bir Azure kapsayıcı kayıt defteri kullanın.
Kapsayıcı görüntülerini önceden yüklemenin avantajı, görevlerin ilk kez çalışmaya başlamasının kapsayıcı görüntüsünün indir indirebilirsiniz. Kapsayıcı yapılandırması, havuz oluşturulduğunda kapsayıcı görüntülerini VM'lere çeker. Havuzda çalıştıran görevler daha sonra kapsayıcı görüntülerinin listesine ve kapsayıcı çalıştırma seçeneklerine başvurur.
Önceden hazır kapsayıcı görüntüleri olmadan havuz
Kapsayıcı özellikli bir havuzu önceden hazır kapsayıcı görüntüleri olmadan yapılandırmak için, aşağıdaki örneklerde ContainerConfiguration VirtualMachineConfiguration gösterildiği gibi ve nesnelerini tanımlayın. Bu örnekler Market'te bulunan Azure Batch havuzları görüntüsü için Ubuntu Server kullanır.
image_ref_to_use = batch.models.ImageReference(
publisher='microsoft-azure-batch',
offer='ubuntu-server-container',
sku='16-04-lts',
version='latest')
"""
Specify container configuration. This is required even though there are no prefetched images.
"""
container_conf = batch.models.ContainerConfiguration()
new_pool = batch.models.PoolAddParameter(
id=pool_id,
virtual_machine_configuration=batch.models.VirtualMachineConfiguration(
image_reference=image_ref_to_use,
container_configuration=container_conf,
node_agent_sku_id='batch.node.ubuntu 16.04'),
vm_size='STANDARD_D1_V2',
target_dedicated_nodes=1)
...
ImageReference imageReference = new ImageReference(
publisher: "microsoft-azure-batch",
offer: "ubuntu-server-container",
sku: "16-04-lts",
version: "latest");
// Specify container configuration. This is required even though there are no prefetched images.
ContainerConfiguration containerConfig = new ContainerConfiguration();
// VM configuration
VirtualMachineConfiguration virtualMachineConfiguration = new VirtualMachineConfiguration(
imageReference: imageReference,
nodeAgentSkuId: "batch.node.ubuntu 16.04");
virtualMachineConfiguration.ContainerConfiguration = containerConfig;
// Create pool
CloudPool pool = batchClient.PoolOperations.CreatePool(
poolId: poolId,
targetDedicatedComputeNodes: 1,
virtualMachineSize: "STANDARD_D1_V2",
virtualMachineConfiguration: virtualMachineConfiguration);
Kapsayıcı yapılandırması için görüntüleri önceden sipariş edin
Havuza kapsayıcı görüntülerini önceden eklemek için kapsayıcı görüntülerinin listesini ( container_image_names , Python'da) üzerine ContainerConfiguration ekleyin.
Aşağıdaki temel Python örneğinde, 'den standart bir Ubuntu kapsayıcı görüntüsünün nasıl öncedenDocker Hub.
image_ref_to_use = batch.models.ImageReference(
publisher='microsoft-azure-batch',
offer='ubuntu-server-container',
sku='16-04-lts',
version='latest')
"""
Specify container configuration, fetching the official Ubuntu container image from Docker Hub.
"""
container_conf = batch.models.ContainerConfiguration(
container_image_names=['ubuntu'])
new_pool = batch.models.PoolAddParameter(
id=pool_id,
virtual_machine_configuration=batch.models.VirtualMachineConfiguration(
image_reference=image_ref_to_use,
container_configuration=container_conf,
node_agent_sku_id='batch.node.ubuntu 16.04'),
vm_size='STANDARD_D1_V2',
target_dedicated_nodes=1)
...
Aşağıdaki C# örneğinde, bir TensorFlow görüntüsünü Docker Hub. Bu örnek, havuz düğümleri üzerinde VM ana bilgisayar üzerinde çalışan bir başlangıç görevi içerir. Kapsayıcılardan erişilebilen bir dosya sunucusunu bağlama gibi bir başlangıç görevini konakta çalıştırabilirsiniz.
ImageReference imageReference = new ImageReference(
publisher: "microsoft-azure-batch",
offer: "ubuntu-server-container",
sku: "16-04-lts",
version: "latest");
ContainerRegistry containerRegistry = new ContainerRegistry(
registryServer: "https://hub.docker.com",
userName: "UserName",
password: "YourPassword"
);
// Specify container configuration, prefetching Docker images
ContainerConfiguration containerConfig = new ContainerConfiguration();
containerConfig.ContainerImageNames = new List<string> { "tensorflow/tensorflow:latest-gpu" };
containerConfig.ContainerRegistries = new List<ContainerRegistry> { containerRegistry };
// VM configuration
VirtualMachineConfiguration virtualMachineConfiguration = new VirtualMachineConfiguration(
imageReference: imageReference,
nodeAgentSkuId: "batch.node.ubuntu 16.04");
virtualMachineConfiguration.ContainerConfiguration = containerConfig;
// Set a native host command line start task
StartTask startTaskContainer = new StartTask( commandLine: "<native-host-command-line>" );
// Create pool
CloudPool pool = batchClient.PoolOperations.CreatePool(
poolId: poolId,
virtualMachineSize: "Standard_NC6",
virtualMachineConfiguration: virtualMachineConfiguration);
// Start the task in the pool
pool.StartTask = startTaskContainer;
...
Özel kapsayıcı kayıt defterinden görüntüleri önceden yükleme
Ayrıca, özel bir kapsayıcı kayıt defteri sunucusunda kimlik doğrulararak kapsayıcı görüntülerini önceden de hazırlarsınız. Aşağıdaki örneklerde, ve nesneleri özel bir Azure kapsayıcı kayıt defterinden ContainerConfiguration VirtualMachineConfiguration özel tensorFlow görüntüsünü önceden alır. Görüntü başvurusu önceki örnektekiyle aynıdır.
image_ref_to_use = batch.models.ImageReference(
publisher='microsoft-azure-batch',
offer='ubuntu-server-container',
sku='16-04-lts',
version='latest')
# Specify a container registry
container_registry = batch.models.ContainerRegistry(
registry_server="myRegistry.azurecr.io",
user_name="myUsername",
password="myPassword")
# Create container configuration, prefetching Docker images from the container registry
container_conf = batch.models.ContainerConfiguration(
container_image_names = ["myRegistry.azurecr.io/samples/myImage"],
container_registries =[container_registry])
new_pool = batch.models.PoolAddParameter(
id="myPool",
virtual_machine_configuration=batch.models.VirtualMachineConfiguration(
image_reference=image_ref_to_use,
container_configuration=container_conf,
node_agent_sku_id='batch.node.ubuntu 16.04'),
vm_size='STANDARD_D1_V2',
target_dedicated_nodes=1)
// Specify a container registry
ContainerRegistry containerRegistry = new ContainerRegistry(
registryServer: "myContainerRegistry.azurecr.io",
userName: "myUserName",
password: "myPassword");
// Create container configuration, prefetching Docker images from the container registry
ContainerConfiguration containerConfig = new ContainerConfiguration();
containerConfig.ContainerImageNames = new List<string> {
"myContainerRegistry.azurecr.io/tensorflow/tensorflow:latest-gpu" };
containerConfig.ContainerRegistries = new List<ContainerRegistry> { containerRegistry } );
// VM configuration
VirtualMachineConfiguration virtualMachineConfiguration = new VirtualMachineConfiguration(
imageReference: imageReference,
nodeAgentSkuId: "batch.node.ubuntu 16.04");
virtualMachineConfiguration.ContainerConfiguration = containerConfig;
// Create pool
CloudPool pool = batchClient.PoolOperations.CreatePool(
poolId: poolId,
targetDedicatedComputeNodes: 4,
virtualMachineSize: "Standard_NC6",
virtualMachineConfiguration: virtualMachineConfiguration);
...
ACR için yönetilen kimlik desteği
içinde depolanan kapsayıcılara Azure Container Registry,hizmette kimlik doğrulaması yapmak için kullanıcı adı/parola veya yönetilen kimlik kullanılabilir. Yönetilen kimlik kullanmak için öncelikle kimliğin havuza atan olduğundan ve kimliğin erişmek istediğiniz kapsayıcı kayıt defterine atanmış bir role AcrPull sahip olduğundan emin olun. Ardından, Batch'e ACR ile kimlik doğrularken hangi kimliğin kullanıcazı söylemeniz gerekir.
ContainerRegistry containerRegistry = new ContainerRegistry(
registryServer: "myContainerRegistry.azurecr.io",
identityReference: new ComputeNodeIdentityReference() { ResourceId = "/subscriptions/SUB/resourceGroups/RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/identity-name" }
);
// Create container configuration, prefetching Docker images from the container registry
ContainerConfiguration containerConfig = new ContainerConfiguration();
containerConfig.ContainerImageNames = new List<string> {
"myContainerRegistry.azurecr.io/tensorflow/tensorflow:latest-gpu" };
containerConfig.ContainerRegistries = new List<ContainerRegistry> { containerRegistry } );
// VM configuration
VirtualMachineConfiguration virtualMachineConfiguration = new VirtualMachineConfiguration(
imageReference: imageReference,
nodeAgentSkuId: "batch.node.ubuntu 16.04");
virtualMachineConfiguration.ContainerConfiguration = containerConfig;
// Create pool
CloudPool pool = batchClient.PoolOperations.CreatePool(
poolId: poolId,
targetDedicatedComputeNodes: 4,
virtualMachineSize: "Standard_NC6",
virtualMachineConfiguration: virtualMachineConfiguration);
...
Görev için kapsayıcı ayarları
Kapsayıcı etkin bir havuzda kapsayıcı görevi çalıştırmak için kapsayıcıya özgü ayarları belirtin. Ayarlar, kayıt defteri ve kapsayıcı çalıştırma seçeneklerini içeren görüntü.
Kapsayıcıya
ContainerSettingsözgü ayarları yapılandırmak için görev sınıflarının özelliğini kullanın. Bu ayarlar TaskContainerSettings sınıfı tarafından tanımlanır. Batch tarafından--rmele alındıklarında kapsayıcı--runtimeseçeneğinin ek bir seçenek gerektirmeyebilirsiniz.Kapsayıcı görüntülerde görevler çalıştırdısanız, bulut görevi ve iş yöneticisi görevi kapsayıcı ayarlarını gerektirir. Ancak, başlangıç görevi, işhazırlama görevi ve iş bırakma görevi kapsayıcı ayarlarını gerektirmez (başka bir şekilde, kapsayıcı bağlamında veya doğrudan düğümde çalıştırabilirsiniz).
Daha Windows, görevlerin ElevationLevel olarak ayarlanmış şekilde çalışması
admingerekir.Linux için Batch kullanıcı/grup iznini kapsayıcıyla eşler. Kapsayıcı içindeki herhangi bir klasöre erişim için yönetici izni gerekiyorsa, görevi yönetici yükseltme düzeyiyle havuz kapsamı olarak çalıştırmanız gerekebilir. Bu, toplu Işlemin görevi kapsayıcı bağlamında kök olarak çalıştırmasını sağlayacaktır. Aksi takdirde, yönetici olmayan bir kullanıcının bu klasörlere erişimi olmayabilir.
GPU özellikli donanımla kapsayıcı havuzları için toplu Işlem, kapsayıcı görevleri için GPU 'YU otomatik olarak etkinleştirecek, bu nedenle
–gpusbağımsız değişkenini içermemelidir.
Kapsayıcı görevi komut satırı
Bir kapsayıcı görevi çalıştırdığınızda, toplu Işlem, görevde belirtilen görüntüyü kullanarak bir kapsayıcı oluşturmak için Docker Create komutunu otomatik olarak kullanır. Batch daha sonra kapsayıcıda görev yürütmeyi denetler.
Kapsayıcı olmayan Batch görevlerinde olduğu gibi, bir kapsayıcı görevi için bir komut satırı ayarlarsınız. Batch kapsayıcıyı otomatik olarak oluşturduğundan, komut satırı yalnızca kapsayıcıda çalıştırılacak komutu veya komutları belirtir.
Bir Batch görevinin kapsayıcı görüntüsü bir ENTRYPOINT betiği ile yapılandırıldıysa, Komut satırlarınızı varsayılan giriş noktasını kullanacak şekilde veya geçersiz kılmak üzere ayarlayabilirsiniz:
Kapsayıcı görüntüsünün varsayılan GIRIŞ noktasını kullanmak için, görev komut satırını boş dizeye ayarlayın
"".Varsayılan GIRIŞ noktasını geçersiz kılmak için ya da görüntüde bir ENTRYPOINT yoksa, örneğin veya gibi bir komut satırını uygun olarak ayarlayın
/app/myapp/bin/sh -c python myscript.py.
İsteğe bağlı Containerrunoptions , docker create kapsayıcıyı oluşturmak ve çalıştırmak için Batch 'in kullandığı komuta sağladığınız ek bağımsız değişkenlerdir. Örneğin, kapsayıcı için çalışma dizini ayarlamak için --workdir <directory> seçeneğini ayarlayın. Ek seçenekler için Docker oluşturma başvurusuna bakın.
Kapsayıcı görevi çalışma dizini
Bir Batch kapsayıcı görevi, kapsayıcıda düzenli (kapsayıcı olmayan) bir görevde Dizin toplu Iş kümelerine çok benzeyen bir çalışma dizininde yürütülür. bu çalışma dizininin görüntüde yapılandırıldıysa iş dizininden farklı olduğunu veya varsayılan kapsayıcı çalışma dizinini ( C:\ Windows kapsayıcısında veya / bir Linux kapsayıcısında) farklı olduğunu unutmayın.
Batch kapsayıcı görevi için:
AZ_BATCH_NODE_ROOT_DIRKonak düğümündeki (Azure Batch dizinlerin kökü) her yinelemeli olarak tüm dizinler kapsayıcı ile eşleştirilir- Tüm görev ortam değişkenleri, kapsayıcınıza eşlenir
- Düğümdeki görev çalışma dizini,
AZ_BATCH_TASK_WORKING_DIRdüzenli bir görevle aynı şekilde ayarlanır ve kapsayıcıya eşlenir.
Bu eşlemeler kapsayıcı görevlerle, kapsayıcı olmayan görevlerle aynı şekilde çalışmanıza olanak sağlar. örneğin, uygulama paketleri kullanarak uygulamalar yükleyip Azure Depolama kaynak dosyalarına erişin, görev ortamı ayarlarını kullanın ve kapsayıcı başlatıldıktan sonra görev çıkış dosyalarını kalıcı hale getirin.
Kapsayıcı görevlerinin sorunlarını giderme
Kapsayıcı göreviniz beklenen şekilde çalışmazsa, kapsayıcı görüntüsünün WORKDIR veya ENTRYPOINT yapılandırması hakkında bilgi almanız gerekebilir. Yapılandırmayı görmek için Docker Image İnceleme komutunu çalıştırın.
Gerekirse, görüntüye göre kapsayıcı görevinin ayarlarını ayarlayın:
- Görev komut satırında mutlak bir yol belirtin. Görev komut satırı için görüntünün varsayılan GIRIŞ noktası kullanılırsa, mutlak bir yolun ayarlandığından emin olun.
- Görevin kapsayıcı çalıştırma seçenekleri ' nde, çalışma dizinini görüntüdeki WORKDIR ile eşleşecek şekilde değiştirin. Örneğin, ayarlayın
--workdir /app.
Kapsayıcı görevi örnekleri
Aşağıdaki Python kod parçacığında, Docker Hub 'dan çekilen kurgusal bir görüntüden oluşturulan kapsayıcıda çalışan temel bir komut satırı gösterilmektedir. Burada --rm kapsayıcı seçeneği, görev bittikten sonra kapsayıcıyı kaldırır ve --workdir seçeneği bir çalışma dizini ayarlar. Komut satırı, küçük bir dosyayı konaktaki görev çalışma dizinine yazan basit bir kabuk komutuyla kapsayıcı GIRIŞ noktasını geçersiz kılar.
task_id = 'sampletask'
task_container_settings = batch.models.TaskContainerSettings(
image_name='myimage',
container_run_options='--rm --workdir /')
task = batch.models.TaskAddParameter(
id=task_id,
command_line='/bin/sh -c \"echo \'hello world\' > $AZ_BATCH_TASK_WORKING_DIR/output.txt\"',
container_settings=task_container_settings
)
Aşağıdaki C# örneği bir bulut görevi için temel kapsayıcı ayarlarını göstermektedir:
// Simple container task command
string cmdLine = "c:\\app\\myApp.exe";
TaskContainerSettings cmdContainerSettings = new TaskContainerSettings (
imageName: "myimage",
containerRunOptions: "--rm --workdir c:\\app"
);
CloudTask containerTask = new CloudTask (
id: "Task1",
commandline: cmdLine);
containerTask.ContainerSettings = cmdContainerSettings;
Sonraki adımlar
- Shipbahçe tariflerinegöre Azure Batch kapsayıcı iş yüklerinin kolay dağıtımı için bkz. Batch shipbahçe araç seti.
- Linux üzerinde Docker CE 'yi yükleme ve kullanma hakkında bilgi için bkz. Docker belgeleri.
- Yönetilen özel görüntünün bir sanal makine havuzu oluşturmak için nasıl kullanılacağınıöğrenin.
- Kapsayıcı tabanlı sistemler oluşturmaya yönelik bir çerçeve olan Moby projesihakkında daha fazla bilgi edinin.