Udostępnij za pośrednictwem


Tworzenie pierwszej aplikacji kontenera usługi Service Fabric w systemie Windows

Uruchomienie istniejącej aplikacji w kontenerze systemu Windows w klastrze usługi Service Fabric nie wymaga żadnych zmian w aplikacji. W tym artykule opisano proces tworzenia obrazu platformy Docker zawierającego aplikację internetową platformy Python Flask i wdrażania go w klastrze usługi Azure Service Fabric. Udostępnisz również konteneryzowaną aplikację za pośrednictwem usługi Azure Container Registry. W tym artykule przyjęto założenie, że masz podstawową wiedzę na temat platformy Docker. Aby dowiedzieć się więcej na temat platformy Docker, zapoznaj się z tematem Docker Overview (Omówienie platformy Docker).

Uwaga

Ten artykuł dotyczy środowiska deweloperskiego systemu Windows. Środowisko uruchomieniowe klastra usługi Service Fabric i środowisko uruchomieniowe platformy Docker muszą być uruchomione w tym samym systemie operacyjnym. Nie można uruchamiać kontenerów systemu Windows w klastrze systemu Linux.

Uwaga

Zalecamy korzystanie z modułu Azure Az programu PowerShell do interakcji z platformą Azure. Aby rozpocząć, zobacz Instalowanie programu Azure PowerShell. Aby dowiedzieć się, jak przeprowadzić migrację do modułu Az PowerShell, zobacz Migracja programu Azure PowerShell z modułu AzureRM do modułu Az.

Wymagania wstępne

Uwaga

Wdrażanie kontenerów w klastrze usługi Service Fabric uruchomionym w systemie Windows 10 jest obsługiwane. Zobacz ten artykuł , aby uzyskać informacje na temat konfigurowania systemu Windows 10 do uruchamiania kontenerów systemu Windows.

Uwaga

Usługa Service Fabric w wersji 6.2 lub nowszej obsługuje wdrażanie kontenerów w klastrach działających w systemie Windows Server w wersji 1709.

Definiowanie kontenera platformy Docker

Utwórz obraz na podstawie obrazu języka Python znajdującego się w usłudze Docker Hub.

Określ kontener platformy Docker w pliku Dockerfile. Plik Dockerfile składa się z instrukcji dotyczących konfigurowania środowiska wewnątrz kontenera, ładowania aplikacji, którą chcesz uruchomić, i mapowania portów. Plik Dockerfile jest wejściem do polecenia docker build, które tworzy obraz.

Utwórz pusty katalog i utwórz plik Dockerfile (bez rozszerzenia pliku). Dodaj następujące elementy do pliku Dockerfile i zapisz zmiany:

# Use an official Python runtime as a base image
FROM python:2.7-windowsservercore

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app

# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

Aby uzyskać więcej informacji, przeczytaj dokumentację pliku Dockerfile .

Tworzenie podstawowej aplikacji internetowej

Utwórz aplikację webową Flask nasłuchującą na porcie 80, która zwraca wartość Hello World!. W tym samym katalogu utwórz plik requirements.txt. Dodaj następujące elementy i zapisz zmiany:

Flask

Utwórz również plik app.py i dodaj następujący fragment kodu:

from flask import Flask

app = Flask(__name__)


@app.route("/")
def hello():

    return 'Hello World!'


if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

Zaloguj się do platformy Docker i skompiluj obraz

Następnie utworzymy obraz, który uruchamia aplikację internetową. Podczas ściągania obrazów publicznych z platformy Docker (na przykład python:2.7-windowsservercore w naszym pliku Dockerfile) najlepszym rozwiązaniem jest uwierzytelnianie przy użyciu konta usługi Docker Hub zamiast tworzenia anonimowego żądania ściągnięcia.

Uwaga

Podczas wykonywania częstych anonimowych żądań ściągnięcia mogą wystąpić błędy platformy Docker podobne do ERROR: toomanyrequests: Too Many Requests. lub You have reached your pull rate limit.. Zaloguj się do Docker Hub, aby zapobiec tym błędom. Aby uzyskać więcej informacji, zobacz Zarządzanie zawartością publiczną za pomocą usługi Azure Container Registry .

Otwórz okno programu PowerShell i przejdź do katalogu zawierającego plik Dockerfile. Następnie uruchom następujące polecenia:

docker login
docker build -t helloworldapp .

To polecenie kompiluje nowy obraz przy użyciu instrukcji w pliku Dockerfile, nazywając (-t tagowanie) obraz helloworldapp. Aby utworzyć obraz kontenera, obraz podstawowy jest najpierw pobierany z usługi Docker Hub, do której jest dodawana aplikacja.

Po zakończeniu polecenia kompilacji uruchom docker images polecenie , aby wyświetlić informacje o nowym obrazie:

$ docker images

REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
helloworldapp                 latest              8ce25f5d6a79        2 minutes ago       10.4 GB

Uruchamianie aplikacji lokalnie

Sprawdź lokalnie obraz przed przesłaniem go do rejestru kontenerów.

Uruchom aplikację:

docker run -d --name my-web-site helloworldapp

nazwa nadaje nazwę uruchomionego kontenera (zamiast identyfikatora kontenera).

Po uruchomieniu kontenera znajdź jego adres IP, aby można było nawiązać połączenie z uruchomionym kontenerem w przeglądarce:

docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" my-web-site

Jeśli to polecenie nie zwróci niczego, uruchom następujące polecenie i sprawdź element NetworkSettings-Networks> dla adresu IP:

docker inspect my-web-site

Połącz się z uruchomionym kontenerem. Otwórz przeglądarkę internetową wskazującą zwrócony adres IP, na przykład "http://172.31.194.61"". W przeglądarce powinien zostać wyświetlony nagłówek "Hello World!".

Aby zatrzymać kontener, uruchom polecenie:

docker stop my-web-site

Usuń kontener z komputera deweloperskiego:

docker rm my-web-site

Wypychanie obrazu do rejestru kontenerów

Po sprawdzeniu, czy kontener działa na maszynie dewelopera, wypchnij obraz do rejestru w usłudze Azure Container Registry.

Uruchom docker login, aby zalogować się do rejestru kontenerów za pomocą poświadczeń rejestru.

Poniższy przykład przekazuje identyfikator i hasło Service Principal Microsoft Entra. Na przykład, możesz przypisać główną jednostkę usługi do swojego rejestru na potrzeby scenariusza automatyzacji. Możesz też zalogować się przy użyciu nazwy użytkownika i hasła rejestru.

docker login myregistry.azurecr.io -u xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -p myPassword

Następujące polecenie tworzy tag lub alias obrazu z pełną ścieżką dostępu do rejestru. W tym przykładzie obraz jest umieszczany w przestrzeni nazw samples , aby uniknąć zanieczyszczenia w głównym katalogu rejestru.

docker tag helloworldapp myregistry.azurecr.io/samples/helloworldapp

Wypchnij obraz do rejestru kontenerów:

docker push myregistry.azurecr.io/samples/helloworldapp

Tworzenie konteneryzowanej usługi w programie Visual Studio

Zestaw SDK i narzędzia usługi Service Fabric udostępniają szablon usługi, który ułatwia tworzenie konteneryzowanej aplikacji.

  1. Uruchom program Visual Studio. Wybierz Plik>Nowy>Projekt.
  2. Wybierz Aplikację Service Fabric, nadaj jej nazwę "MyFirstContainer", a następnie kliknij OK.
  3. Wybierz pozycję Kontener z listy szablonów usług.
  4. W polu Nazwa obrazu wpisz "myregistry.azurecr.io/samples/helloworldapp", obraz, który przesłałeś do repozytorium kontenerów.
  5. Nadaj usłudze nazwę, a następnie kliknij przycisk OK.

Konfigurowanie komunikacji

Konteneryzowana usługa wymaga punktu końcowego do komunikacji. Dodaj element z protokołem, portem i typem Endpoint do pliku ServiceManifest.xml. W tym przykładzie jest używany stały port 8081. Jeśli port nie zostanie określony, zostanie wybrany losowy port z zakresu portów aplikacji.

<Resources>
  <Endpoints>
    <Endpoint Name="Guest1TypeEndpoint" UriScheme="http" Port="8081" Protocol="http"/>
  </Endpoints>
</Resources>

Uwaga

Dodatkowe punkty końcowe dla usługi można dodać, deklarując dodatkowe elementy programu EndPoint z odpowiednimi wartościami właściwości. Każdy port może zadeklarować tylko jedną wartość protokołu.

Definiując punkt końcowy, usługa Service Fabric publikuje punkt końcowy w usłudze Nazewnictwa. Inne usługi uruchomione w klastrze mogą rozpoznać ten kontener. Komunikację między kontenerami można również przeprowadzić, używając serwera proxy w trybie zwrotnym. Komunikacja odbywa się poprzez podanie portu nasłuchiwania HTTP odwrotnego serwera proxy oraz nazwy usług, z którymi chcesz się komunikować, jako zmiennych środowiskowych.

Usługa jest skonfigurowana do nasłuchiwania na określonym porcie (w tym przypadku 8081). Gdy aplikacja zostanie wdrożona w klastrze na platformie Azure, zarówno klaster, jak i aplikacja działają za modułem równoważenia obciążenia platformy Azure. Port aplikacji musi być otwarty w module równoważenia obciążenia platformy Azure, aby ruch przychodzący mógł przechodzić do usługi. Ten port można otworzyć w module równoważenia obciążenia platformy Azure przy użyciu skryptu programu PowerShell lub w witrynie Azure Portal.

Konfigurowanie i ustawianie zmiennych środowiskowych

Zmienne środowiskowe można określić dla każdego pakietu kodu w manifeście usługi. Ta funkcja jest dostępna dla wszystkich usług niezależnie od tego, czy są one wdrażane jako kontenery, procesy lub pliki wykonywalne gościa. Wartości zmiennych środowiskowych można zastąpić w manifeście aplikacji lub określić podczas wdrażania jako parametry aplikacji.

Poniższy fragment kodu XML manifestu usługi przedstawia przykład sposobu określania zmiennych środowiskowych dla pakietu kodu:

<CodePackage Name="Code" Version="1.0.0">
  ...
  <EnvironmentVariables>
    <EnvironmentVariable Name="HttpGatewayPort" Value=""/>    
  </EnvironmentVariables>
</CodePackage>

Te zmienne środowiskowe można zastąpić w manifeście aplikacji:

<ServiceManifestImport>
  <ServiceManifestRef ServiceManifestName="Guest1Pkg" ServiceManifestVersion="1.0.0" />
  <EnvironmentOverrides CodePackageRef="FrontendService.Code">
    <EnvironmentVariable Name="HttpGatewayPort" Value="19080"/>
  </EnvironmentOverrides>
  ...
</ServiceManifestImport>

Konfigurowanie mapowania z portu kontenera na port hosta i odnajdywania kontener-kontener

Skonfiguruj port hosta używany do komunikowania się z kontenerem. Powiązanie portów mapuje port, na którym usługa nasłuchuje w obrębie kontenera, na port na hoście. Dodaj element PortBinding w elemencie ContainerHostPolicies pliku ApplicationManifest.xml. W tym artykule ContainerPort wynosi 80 (kontener udostępnia port 80, jak określono w pliku Dockerfile) i EndpointRef jest "Guest1TypeEndpoint" (punkt końcowy zdefiniowany wcześniej w manifeście usługi). Przychodzące żądania do usługi na porcie 8081 są mapowane na port 80 w kontenerze.

<ServiceManifestImport>
    ...
    <Policies>
        <ContainerHostPolicies CodePackageRef="Code">
            <PortBinding ContainerPort="80" EndpointRef="Guest1TypeEndpoint"/>
        </ContainerHostPolicies>
    </Policies>
    ...
</ServiceManifestImport>

Uwaga

Dodatkowe powiązania portów dla usługi można dodać, deklarując dodatkowe elementy PortBinding z odpowiednimi wartościami ich właściwości.

Konfigurowanie uwierzytelniania repozytorium kontenerów

Zobacz Uwierzytelnianie repozytorium kontenerów, aby dowiedzieć się, jak skonfigurować różne typy uwierzytelniania na potrzeby pobierania obrazu kontenera.

Konfigurowanie trybu izolacji

System Windows obsługuje dwa tryby izolacji dla kontenerów: proces i funkcję Hyper-V. W trybie izolacji procesu wszystkie kontenery uruchomione na tej samej maszynie hosta współużytkują jądro wspólnie z hostem. W trybie izolacji Hyper-V jądra są izolowane między każdym kontenerem Hyper-V a hostem kontenera. Tryb izolacji jest określony w elemecie ContainerHostPolicies w pliku manifestu aplikacji. Tryby izolacji, które można określić, to process, hypervi default. Wartość domyślna to tryb izolacji procesów na hostach systemu Windows Server. Na hostach z systemem Windows 10 obsługiwany jest tylko tryb izolacji Hyper-V, więc kontener działa w trybie izolacji Hyper-V niezależnie od ustawienia trybu izolacji. Poniższy fragment kodu pokazuje, jak tryb izolacji jest określony w pliku manifestu aplikacji.

<ContainerHostPolicies CodePackageRef="Code" Isolation="hyperv">

Uwaga

Tryb izolacji hyperv jest dostępny w SKU Azure Ev3 i Dv3, które obsługują wirtualizację zagnieżdżoną.

Konfiguracja zarządzania zasobami

Nadzór nad zasobami ogranicza zasoby, których kontener może używać na hoście. Element ResourceGovernancePolicy określony w manifeście aplikacji służy do deklarowania limitów zasobów dla pakietu kodu usługi. Limity zasobów można ustawić dla następujących zasobów: Pamięć, PamięćSwap, CpuShares (względna waga procesora), MemoryReservationInMB, BlkioWeight (Waga względna BlockIO). W tym przykładzie pakiet usługi Guest1Pkg otrzymuje jeden rdzeń na węzłach klastra, na których został umieszczony. Limity pamięci są bezwzględne, więc pakiet kodu jest ograniczony do 1024 MB pamięci (i rezerwacji z miękką gwarancją tego samego). Pakiety kodu (kontenery lub procesy) nie mogą przydzielić większej ilości pamięci niż ten limit i próby wykonania tej czynności powodują wyjątek braku pamięci. Aby wymuszanie limitu zasobów działało, wszystkie pakiety kodu w pakiecie usługi powinny mieć określone limity pamięci.

<ServiceManifestImport>
  <ServiceManifestRef ServiceManifestName="Guest1Pkg" ServiceManifestVersion="1.0.0" />
  <Policies>
    <ServicePackageResourceGovernancePolicy CpuCores="1"/>
    <ResourceGovernancePolicy CodePackageRef="Code" MemoryInMB="1024"  />
  </Policies>
</ServiceManifestImport>

Konfigurowanie narzędzia docker HEALTHCHECK

Począwszy od wersji 6.1, usługa Service Fabric automatycznie integruje zdarzenia docker HEALTHCHECK z raportem kondycji systemu. Oznacza to, że jeśli kontener ma włączoną funkcję HEALTHCHECK , usługa Service Fabric będzie zgłaszać kondycję za każdym razem, gdy stan kondycji kontenera ulegnie zmianie zgodnie z raportem platformy Docker. Raport zdrowia OK zostanie wyświetlony w Service Fabric Explorer, gdy health_status jest zdrowy, a WARNING będzie wyświetlane, gdy health_status jest niezdrowy.

Od najnowszego wydania odświeżającego w wersji 6.4, możesz określić, że oceny docker HEALTHCHECK powinny być zgłaszane jako błąd. Jeśli ta opcja jest włączona, zostanie wyświetlony raport kondycji OK, gdy health_status jest w dobrej kondycji, a błąd pojawi się, gdy health_status jest w złej kondycji.

Instrukcja HEALTHCHECK wskazująca rzeczywistą kontrolę wykonywaną na potrzeby monitorowania kondycji kontenera musi znajdować się w pliku Dockerfile używanym podczas generowania obrazu kontenera.

Zrzut ekranu przedstawiający szczegóły wdrożonego pakietu usługi NodeServicePackage.

HealthCheckUnhealthyApp

HealthCheckUnhealthyDsp

Zachowanie HEALTHCHECK dla każdego kontenera można skonfigurować, określając opcje HealthConfig w ramach elementu ContainerHostPolicies w programie ApplicationManifest.

<ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="ContainerServicePkg" ServiceManifestVersion="2.0.0" />
    <Policies>
      <ContainerHostPolicies CodePackageRef="Code">
        <HealthConfig IncludeDockerHealthStatusInSystemHealthReport="true"
		      RestartContainerOnUnhealthyDockerHealthStatus="false" 
		      TreatContainerUnhealthyStatusAsError="false" />
      </ContainerHostPolicies>
    </Policies>
</ServiceManifestImport>

Domyślnie właściwość IncludeDockerHealthStatusInSystemHealthReport jest ustawiona na wartość true, właściwość RestartContainerOnUnhealthyDockerHealthStatus ma wartość false, a właściwość TreatContainerUnhealthyStatusAsError ma wartość false.

Jeśli parametr RestartContainerOnUnhealthyDockerHealthStatus ma wartość true, kontener, który wielokrotnie zgłasza niezdrowy status, zostanie ponownie uruchomiony, ewentualnie na innych węzłach.

Jeśli właściwość TreatContainerUnhealthyStatusAsError ma wartość true, raporty o kondycji BŁĘDÓW będą wyświetlane, gdy health_status kontenera jest w złej kondycji.

Jeśli chcesz wyłączyć integrację HEALTHCHECK dla całego klastra usługi Service Fabric, musisz ustawić wartość EnableDockerHealthCheckIntegration na false.

Wdrażanie aplikacji kontenera

Zapisz wszystkie zmiany i skompiluj aplikację. Aby opublikować aplikację, kliknij prawym przyciskiem myszy pozycję MyFirstContainer w Eksploratorze rozwiązań i wybierz pozycję Publikuj.

W polu Punkt końcowy połączenia wprowadź punkt końcowy zarządzania klastrem. Na przykład containercluster.westus2.cloudapp.azure.com:19000. Punkt końcowy połączenia klienta można znaleźć na karcie Przegląd klastra w witrynie Azure Portal.

Kliknij przycisk Publikuj.

Service Fabric Explorer to internetowe narzędzie do sprawdzania aplikacji i węzłów oraz zarządzania nimi w klastrze usługi Service Fabric. Otwórz przeglądarkę i przejdź pod adres http://containercluster.westus2.cloudapp.azure.com:19080/Explorer/ i postępuj zgodnie z instrukcjami wdrażania aplikacji. Aplikacja jest wdrażana, ale jest w stanie błędu do momentu pobrania obrazu w węzłach klastra (co może zająć trochę czasu, w zależności od rozmiaru obrazu): Błąd

Aplikacja jest gotowa, gdy jest w Ready stanie: Gotowe

Otwórz przeglądarkę i przejdź pod adres http://containercluster.westus2.cloudapp.azure.com:8081. W przeglądarce powinien zostać wyświetlony nagłówek "Hello World!".

Czyszczenie

Nadal są naliczane opłaty podczas działania klastra, rozważ usunięcie klastra.

Po wypchnięciu obrazu do rejestru kontenerów można usunąć obraz lokalny z komputera deweloperskiego:

docker rmi helloworldapp
docker rmi myregistry.azurecr.io/samples/helloworldapp

Zgodność systemu operacyjnego kontenera i hosta z Windows Server

Kontenery systemu Windows Server nie są zgodne ze wszystkimi wersjami systemu operacyjnego hosta. Na przykład:

  • Kontenery systemu Windows Server utworzone przy użyciu systemu Windows Server w wersji 1709 nie działają na hoście z systemem Windows Server w wersji 2016.
  • Kontenery systemu Windows Server utworzone przy użyciu systemu Windows Server 2016 działają w trybie izolacji Hyper-V tylko na hoście z systemem Windows Server w wersji 1709.
  • W przypadku kontenerów systemu Windows Server utworzonych przy użyciu systemu Windows Server 2016 może być konieczne upewnienie się, że wersja systemu operacyjnego kontenera i systemu operacyjnego hosta są takie same podczas uruchamiania w trybie izolacji procesów na hoście z systemem Windows Server 2016.

Aby dowiedzieć się więcej, zobacz Zgodność wersji kontenera systemu Windows.

Podczas kompilowania i wdrażania kontenerów w klastrze usługi Service Fabric należy wziąć pod uwagę zgodność systemu operacyjnego hosta i systemu operacyjnego kontenera. Na przykład:

  • Upewnij się, że kontenery są wdrażane przy użyciu systemu operacyjnego zgodnego z systemem operacyjnym w węzłach klastra.
  • Upewnij się, że tryb izolacji określony dla aplikacji kontenera jest zgodny z obsługą systemu operacyjnego kontenera w węźle, w którym jest wdrażana.
  • Rozważ, jak uaktualnienia systemu operacyjnego do węzłów klastra lub kontenerów mogą mieć wpływ na ich zgodność.

Zalecamy następujące rozwiązania, aby upewnić się, że kontenery są prawidłowo wdrażane w klastrze usługi Service Fabric:

  • Użyj jednoznacznego tagowania swoich obrazów Docker, aby określić wersję systemu operacyjnego Windows Server, na której oparty jest kontener.
  • Użyj tagowania systemu operacyjnego w pliku manifestu aplikacji, aby upewnić się, że aplikacja jest zgodna z różnymi wersjami i uaktualnieniami systemu Windows Server.

Uwaga

Za pomocą usługi Service Fabric w wersji 6.2 lub nowszej można wdrażać kontenery oparte na systemie Windows Server 2016 lokalnie na hoście systemu Windows 10. W systemie Windows 10 kontenery działają w trybie izolacji Hyper-V, niezależnie od trybu izolacji ustawionego w manifeście aplikacji. Aby dowiedzieć się więcej, zobacz Konfigurowanie trybu izolacji.

Określanie obrazów kontenerów specyficznych dla kompilacji systemu operacyjnego

Kontenery systemu Windows Server mogą nie być zgodne w różnych wersjach systemu operacyjnego. Na przykład kontenery systemu Windows Server utworzone przy użyciu systemu Windows Server 2016 nie działają w systemie Windows Server w wersji 1709 w trybie izolacji procesów. W związku z tym, jeśli węzły klastra są aktualizowane do najnowszej wersji, usługi kontenerów utworzone przy użyciu wcześniejszych wersji systemu operacyjnego mogą zakończyć się niepowodzeniem. Aby obejść ten błąd w wersji 6.1 środowiska uruchomieniowego i nowszej, usługa Service Fabric obsługuje określanie wielu obrazów systemu operacyjnego na kontener i tagowanie ich przy użyciu wersji kompilacji systemu operacyjnego w manifeście aplikacji. Wersję kompilacji systemu operacyjnego można uzyskać, uruchamiając polecenie winver w wierszu polecenia systemu Windows. Zaktualizuj manifesty aplikacji i określ nadpisania obrazów dla wersji systemu operacyjnego przed aktualizacją systemu operacyjnego na węzłach. Poniższy fragment kodu pokazuje, jak określić wiele obrazów kontenerów w manifeście aplikacji, ApplicationManifest.xml:

      <ContainerHostPolicies> 
         <ImageOverrides> 
	       <Image Name="myregistry.azurecr.io/samples/helloworldappDefault" /> 
               <Image Name="myregistry.azurecr.io/samples/helloworldapp1701" Os="14393" /> 
               <Image Name="myregistry.azurecr.io/samples/helloworldapp1709" Os="16299" /> 
         </ImageOverrides> 
      </ContainerHostPolicies> 

Wersja kompilacji dla systemu Windows Server 2016 to 14393, a wersja kompilacji dla systemu Windows Server w wersji 1709 to 16299. Manifest usługi nadal określa tylko jeden obraz dla usługi kontenera, jak pokazano poniżej:

<ContainerHost>
    <ImageName>myregistry.azurecr.io/samples/helloworldapp</ImageName> 
</ContainerHost>

Uwaga

Funkcja tagowania wersji kompilacji systemu operacyjnego jest dostępna tylko dla usługi Service Fabric w systemie Windows

Jeśli podstawowy system operacyjny na maszynie wirtualnej jest kompilacją 16299 (wersja 1709), usługa Service Fabric wybiera obraz kontenera odpowiadający tej wersji systemu Windows Server. Jeśli w manifeście aplikacji jest również udostępniany nieotagowany obraz kontenera obok otagowanych obrazów kontenera, usługa Service Fabric traktuje nieotagowany obraz jako taki, który działa w różnych wersjach. Oznacz obrazy kontenerów jawnie, aby uniknąć problemów podczas uaktualniania.

Nieoznakowany obraz kontenera będzie działał jako nadpisanie tego podanego w pliku ServiceManifest. Dlatego obraz "myregistry.azurecr.io/samples/helloworldappDefault" zastąpi wartość ImageName "myregistry.azurecr.io/samples/helloworldapp" w pliku ServiceManifest.

Kompletne przykładowe manifesty aplikacji i usługi Service Fabric

Poniżej przedstawiono kompletne manifesty usługi i aplikacji używane w tym artykule.

ServiceManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="Guest1Pkg"
                 Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="https://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <ServiceTypes>
    <!-- This is the name of your ServiceType.
         The UseImplicitHost attribute indicates this is a guest service. -->
    <StatelessServiceType ServiceTypeName="Guest1Type" UseImplicitHost="true" />
  </ServiceTypes>

  <!-- Code package is your service executable. -->
  <CodePackage Name="Code" Version="1.0.0">
    <EntryPoint>
      <!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers -->
      <ContainerHost>
        <ImageName>myregistry.azurecr.io/samples/helloworldapp</ImageName>
        <!-- Pass comma delimited commands to your container: dotnet, myproc.dll, 5" -->
        <!--Commands> dotnet, myproc.dll, 5 </Commands-->
        <Commands></Commands>
      </ContainerHost>
    </EntryPoint>
    <!-- Pass environment variables to your container: -->    
    <EnvironmentVariables>
      <EnvironmentVariable Name="HttpGatewayPort" Value=""/>
      <EnvironmentVariable Name="BackendServiceName" Value=""/>
    </EnvironmentVariables>

  </CodePackage>

  <!-- Config package is the contents of the Config directory under PackageRoot that contains an
       independently-updateable and versioned set of custom configuration settings for your service. -->
  <ConfigPackage Name="Config" Version="1.0.0" />

  <Resources>
    <Endpoints>
      <!-- This endpoint is used by the communication listener to obtain the port on which to
           listen. Please note that if your service is partitioned, this port is shared with
           replicas of different partitions that are placed in your code. -->
      <Endpoint Name="Guest1TypeEndpoint" UriScheme="http" Port="8081" Protocol="http"/>
    </Endpoints>
  </Resources>
</ServiceManifest>

ApplicationManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest ApplicationTypeName="MyFirstContainerType"
                     ApplicationTypeVersion="1.0.0"
                     xmlns="http://schemas.microsoft.com/2011/01/fabric"
                     xmlns:xsd="https://www.w3.org/2001/XMLSchema"
                     xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <Parameters>
    <Parameter Name="Guest1_InstanceCount" DefaultValue="-1" />
  </Parameters>
  <!-- Import the ServiceManifest from the ServicePackage. The ServiceManifestName and ServiceManifestVersion
       should match the Name and Version attributes of the ServiceManifest element defined in the
       ServiceManifest.xml file. -->
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="Guest1Pkg" ServiceManifestVersion="1.0.0" />
    <EnvironmentOverrides CodePackageRef="FrontendService.Code">
      <EnvironmentVariable Name="HttpGatewayPort" Value="19080"/>
    </EnvironmentOverrides>
    <ConfigOverrides />
    <Policies>
      <ContainerHostPolicies CodePackageRef="Code">
        <RepositoryCredentials AccountName="myregistry" Password="MIIB6QYJKoZIhvcNAQcDoIIB2jCCAdYCAQAxggFRMIIBTQIBADA1MCExHzAdBgNVBAMMFnJ5YW53aWRhdGFlbmNpcGhlcm1lbnQCEFfyjOX/17S6RIoSjA6UZ1QwDQYJKoZIhvcNAQEHMAAEg
gEAS7oqxvoz8i6+8zULhDzFpBpOTLU+c2mhBdqXpkLwVfcmWUNA82rEWG57Vl1jZXe7J9BkW9ly4xhU8BbARkZHLEuKqg0saTrTHsMBQ6KMQDotSdU8m8Y2BR5Y100wRjvVx3y5+iNYuy/JmM
gSrNyyMQ/45HfMuVb5B4rwnuP8PAkXNT9VLbPeqAfxsMkYg+vGCDEtd8m+bX/7Xgp/kfwxymOuUCrq/YmSwe9QTG3pBri7Hq1K3zEpX4FH/7W2Zb4o3fBAQ+FuxH4nFjFNoYG29inL0bKEcTX
yNZNKrvhdM3n1Uk/8W2Hr62FQ33HgeFR1yxQjLsUu800PrYcR5tLfyTB8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBybgM5NUV8BeetUbMR8mJhgFBrVSUsnp9B8RyebmtgU36dZiSObDsI
NtTvlzhk11LIlae/5kjPv95r3lw6DHmV4kXLwiCNlcWPYIWBGIuspwyG+28EWSrHmN7Dt2WqEWqeNQ==" PasswordEncrypted="true"/>
        <PortBinding ContainerPort="80" EndpointRef="Guest1TypeEndpoint"/>
      </ContainerHostPolicies>
      <ServicePackageResourceGovernancePolicy CpuCores="1"/>
      <ResourceGovernancePolicy CodePackageRef="Code" MemoryInMB="1024"  />
    </Policies>
  </ServiceManifestImport>
  <DefaultServices>
    <!-- The section below creates instances of service types, when an instance of this
         application type is created. You can also create one or more instances of service type using the
         ServiceFabric PowerShell module.

         The attribute ServiceTypeName below must match the name defined in the imported ServiceManifest.xml file. -->
    <Service Name="Guest1">
      <StatelessService ServiceTypeName="Guest1Type" InstanceCount="[Guest1_InstanceCount]">
        <SingletonPartition />
      </StatelessService>
    </Service>
  </DefaultServices>
</ApplicationManifest>

Konfigurowanie interwału czasu przed wymuszeniem zakończenia działania kontenera

Możesz skonfigurować czas oczekiwania na czas działania przed usunięciem kontenera po rozpoczęciu usuwania usługi (lub przejścia do innego węzła). Konfigurowanie interwału czasu powoduje wysłanie polecenia docker stop <time in seconds> do kontenera. Aby uzyskać więcej informacji, zobacz docker stop. Interwał czasu oczekiwania jest określony w Hosting sekcji . Sekcję Hosting można dodać podczas tworzenia klastra lub nowszej w ramach uaktualniania konfiguracji. Poniższy fragment kodu manifestu klastra pokazuje, jak ustawić interwał oczekiwania:

"fabricSettings": [
	...,
	{
        "name": "Hosting",
        "parameters": [
          {
                "name": "ContainerDeactivationTimeout",
                "value" : "10"
          },
	      ...
        ]
	}
]

Domyślny interwał czasu jest ustawiony na 10 sekund. Ponieważ ta konfiguracja jest dynamiczna, aktualizacja konfiguracji tylko dla klastra aktualizuje limit czasu.

Konfigurowanie środowiska uruchomieniowego w celu usunięcia nieużywanych obrazów kontenerów

Klaster usługi Service Fabric można skonfigurować tak, aby usuwał nieużywane obrazy kontenerów z węzła. Ta konfiguracja umożliwia odzyskanie miejsca na dysku, jeśli na węźle znajduje się zbyt wiele obrazów kontenerów. Aby włączyć tę funkcję, zaktualizuj sekcję Hosting w manifeście klastra, jak pokazano w poniższym fragmencie kodu:

"fabricSettings": [
	...,
	{
        "name": "Hosting",
        "parameters": [
          {
                "name": "PruneContainerImages",
                "value": "True"
          },
          {
                "name": "ContainerImagesToSkip",
                "value": "mcr.microsoft.com/windows/servercore|mcr.microsoft.com/windows/nanoserver|mcr.microsoft.com/dotnet/framework/aspnet|..."
          }
          ...
        ]
	} 
]

W przypadku obrazów, których nie należy usuwać, można określić je w ramach parametru ContainerImagesToSkip .

Konfigurowanie czasu pobierania obrazu kontenera

Środowisko uruchomieniowe Service Fabric przydziela 20 minut na pobieranie i wyodrębnianie obrazów kontenerów, co jest odpowiednie dla większości obrazów kontenerów. W przypadku dużych obrazów lub gdy połączenie sieciowe działa wolno, może być konieczne zwiększenie czasu oczekiwania przed przerwaniem pobierania i wyodrębniania obrazu. Ten limit czasu jest ustawiany przy użyciu atrybutu ContainerImageDownloadTimeout w sekcji Hosting manifestu klastra, jak pokazano w poniższym fragmencie kodu:

"fabricSettings": [
	...,
	{
        "name": "Hosting",
        "parameters": [
          {
              "name": "ContainerImageDownloadTimeout",
              "value": "1200"
          }
          ...
        ]
	}
]

Ustawianie zasad przechowywania kontenerów

Aby ułatwić diagnozowanie błędów uruchamiania kontenera, usługa Service Fabric (wersja 6.1 lub nowsza) obsługuje przechowywanie kontenerów, które zakończyły działanie lub nie powiodło się. Te zasady można ustawić w pliku ApplicationManifest.xml, jak pokazano w poniższym fragmencie kodu:

 <ContainerHostPolicies CodePackageRef="NodeService.Code" Isolation="process" ContainersRetentionCount="2"  RunInteractive="true"> 

Ustawienie ContainersRetentionCount określa liczbę kontenerów do przechowywania w przypadku wystąpienia w nich błędu. Jeśli zostanie określona wartość ujemna, wszystkie kontenery z niepowodzeniami zostaną zatrzymane. Gdy atrybut ContainersRetentionCount nie zostanie określony, żadne kontenery nie zostaną zachowane. Atrybut ContainersRetentionCount obsługuje też parametry aplikacji, dzięki czemu użytkownicy mogą określać różne wartości dla klastrów testowych i produkcyjnych. W przypadku używania tej funkcji można zastosować ograniczenia rozmieszczania, tak aby obiektem docelowym usługi kontenera był określony węzeł, co zapobiega przenoszeniu usługi kontenera do innych węzłów. Wszelkie kontenery przechowywane przy użyciu tej funkcji należy usunąć ręcznie.

Uruchamianie demona platformy Docker przy użyciu argumentów niestandardowych

W wersji 6.2 i nowszych środowiska uruchomieniowego Service Fabric można uruchomić demona Dockera z argumentami niestandardowymi. Gdy określone są argumenty niestandardowe, Service Fabric nie przekazuje żadnych innych argumentów do silnika Docker, poza argumentem --pidfile. --pidfile W związku z tym nie należy przekazywać go jako argumentu. Ponadto argument powinien nadal ustawiać daemona Docker na nasłuch w domyślnym potoku nazw w systemie Windows (lub gnieździe domeny Unix w systemie Linux) w celu umożliwienia usłudze Service Fabric komunikowania się z demonem. Argumenty niestandardowe są przekazywane w manifeście klastra w sekcji Hosting w obszarze ContainerServiceArguments , jak pokazano w poniższym fragmencie kodu:

"fabricSettings": [
	...,
	{ 
        "name": "Hosting", 
        "parameters": [ 
          { 
            "name": "ContainerServiceArguments", 
            "value": "-H localhost:1234 -H unix:///var/run/docker.sock" 
          }
          ...
        ] 
	} 
]

Nadpisanie punktu wejścia

W wersji 8.2 ServiceFabric Runtime można zastąpić punkt wejścia dla pakietu kodu kontenera i hosta exe. Może to być używane w sytuacjach, gdzie wszystkie elementy manifestu pozostają niezmienione, ale konieczna jest zmiana obrazu kontenera. W takim wypadku aprowizacja innej wersji typu aplikacji nie jest już konieczna. Ponadto, w zależności od tego, czy scenariusz dotyczy testów czy środowiska produkcyjnego, mogą być przekazywane różne argumenty, podczas gdy punkt wejścia pozostaje ten sam.

Poniżej przedstawiono przykład sposobu zastępowania punktu wejścia kontenera:

ApplicationManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest ApplicationTypeName="MyFirstContainerType"
                     ApplicationTypeVersion="1.0.0"
                     xmlns="http://schemas.microsoft.com/2011/01/fabric"
                     xmlns:xsd="https://www.w3.org/2001/XMLSchema"
                     xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <Parameters>
    <Parameter Name="ImageName" DefaultValue="myregistry.azurecr.io/samples/helloworldapp" />
    <Parameter Name="Commands" DefaultValue="commandsOverride" />
    <Parameter Name="FromSource" DefaultValue="sourceOverride" />
    <Parameter Name="EntryPoint" DefaultValue="entryPointOverride" />
  </Parameters>
  <!-- Import the ServiceManifest from the ServicePackage. The ServiceManifestName and ServiceManifestVersion
       should match the Name and Version attributes of the ServiceManifest element defined in the
       ServiceManifest.xml file. -->
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="Guest1Pkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides />
    <Policies>
      <CodePackagePolicy CodePackageRef="Code">
        <EntryPointOverride>
         <ContainerHostOverride>
            <ImageOverrides>
              <Image Name="[ImageName]" />
            </ImageOverrides>
            <Commands>[Commands]</Commands>
            <FromSource>[Source]</FromSource>
            <EntryPoint>[EntryPoint]</EntryPoint>
          </ContainerHostOverride>
        </EntryPointOverride>
      </CodePackagePolicy>
    </Policies>
  </ServiceManifestImport>
</ApplicationManifest>

ServiceManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="Guest1Pkg"
                 Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="https://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <ServiceTypes>
    <!-- This is the name of your ServiceType.
         The UseImplicitHost attribute indicates this is a guest service. -->
    <StatelessServiceType ServiceTypeName="Guest1Type" UseImplicitHost="true" />
  </ServiceTypes>

  <!-- Code package is your service executable. -->
  <CodePackage Name="Code" Version="1.0.0">
    <EntryPoint>
      <!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers -->
      <ContainerHost>
        <ImageName>default imagename</ImageName>
        <Commands>default cmd</Commands>
        <EntryPoint>default entrypoint</EntryPoint>
        <FromSource>default source</FromSource>
      </ContainerHost>
    </EntryPoint>
  </CodePackage>

  <ConfigPackage Name="Config" Version="1.0.0" />
</ServiceManifest>

Po określeniu przesłonięć w manifeście aplikacji, kontener z obrazem o nazwie myregistry.azurecr.io/samples/helloworldapp, poleceniem commandsOverride, żródłem sourceOverride i punktem wejścia entryPointOverride zostanie uruchomiony.

Podobnie poniżej przedstawiono przykład sposobu zastępowania elementu ExeHost:

<?xml version="1.0" encoding="utf-8"?>
<Policies>
  <CodePackagePolicy CodePackageRef="Code">
    <EntryPointOverride>
      <ExeHostOverride>
        <Program>[Program]</Program>
        <Arguments>[Entry]</Arguments>
      </ExeHostOverride>
    </EntryPointOverride>
  </CodePackagePolicy>
</Policies>

Uwaga

Przesłanianie punktu wejścia nie jest obsługiwane dla SetupEntryPoint.

Następne kroki