Sdílet prostřednictvím


Vytvoření první aplikace Service Fabric typu kontejner v Linuxu

Spuštění existující aplikace v kontejneru Linux v clusteru Service Fabric nevyžaduje žádné změny aplikace. Tento článek vás provede vytvořením image Dockeru obsahující webovou aplikaci Python Flask a jejím nasazením do clusteru Service Fabric. Kontejnerizovanou aplikaci budete také sdílet prostřednictvím služby Azure Container Registry. Tento článek předpokládá základní znalost Dockeru. Informace o Dockeru najdete v článku Docker Overview (Přehled Dockeru).

Poznámka:

Tento článek se týká vývojového prostředí linuxu. Modul runtime clusteru Service Fabric a modul runtime Dockeru musí běžet ve stejném operačním systému. V clusteru s Windows nemůžete spouštět kontejnery Linuxu.

Předpoklady

Definice kontejneru Dockeru

Sestavte image založenou na imagi Pythonu, která se nachází na Docker Hubu.

Zadejte kontejner Dockeru v souboru Dockerfile. Soubor Dockerfile obsahuje pokyny k nastavení prostředí uvnitř kontejneru, načtení aplikace, kterou chcete spustit, a mapování portů. Soubor Dockerfile je vstupem příkazu docker build, který vytvoří image.

Vytvořte prázdný adresář a soubor Dockerfile (bez přípony souboru). Do souboru Dockerfile přidejte následující a uložte změny:

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

# 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 outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

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

Další informace najdete v referenčních informacích k souboru Dockerfile.

Vytvoření základní webové aplikace

Vytvořte webovou aplikaci Flask, která naslouchá na portu 80 a vrací „Hello World!“. Ve stejném adresáři vytvořte soubor requirements.txt. Přidejte do něj následující a uložte změny:

Flask

Vytvořte také soubor app.py a přidejte do něj následující fragment kódu:

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)

Přihlaste se k Dockeru a sestavte image.

Dále vytvoříme image, na které běží vaše webová aplikace. Při načítání veřejných imagí z Dockeru (jako python:2.7-slim v našem souboru Dockerfile) je osvědčeným postupem ověření u vašeho účtu Docker Hubu místo vytvoření anonymní žádosti o přijetí změn.

Poznámka:

Při provádění častých anonymních žádostíoch ERROR: toomanyrequests: Too Many Requests.You have reached your pull rate limit. Další informace najdete v tématu Správa veřejného obsahu ve službě Azure Container Registry .

Otevřete okno PowerShellu a přejděte do adresáře, který obsahuje soubor Dockerfile. Potom spusťte následující příkazy:

docker login
docker build -t helloworldapp .

Tento příkaz sestaví novou image podle pokynů ve vašem souboru Dockerfile a pojmenuje ji (označení -t) helloworldapp. Pro sestavení image kontejneru se nejprve z Docker Hubu stáhne základní image, do které se přidá aplikace.

Po dokončení příkazu pro sestavení spusťte příkaz docker images a zobrazte informace o nové imagi:

$ docker images
    
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
helloworldapp                 latest              86838648aab6        2 minutes ago       194 MB

Aplikaci spustíte místně.

Než kontejnerizovanou aplikaci nahrajete do registru kontejneru, ověřte, že se spustí místně.

Spusťte aplikaci s mapováním portu 4000 vašeho počítače na zpřístupněný port 80 kontejneru:

docker run -d -p 4000:80 --name my-web-site helloworldapp

Parametr name udává název spuštěného kontejneru (namísto ID kontejneru).

Připojte se ke spuštěnému kontejneru. Otevřete webový prohlížeč odkazující na IP adresu vrácenou na portu 4000, například ;http://localhost:4000". V prohlížeči by se měl zobrazit nadpis "Hello World!".

Hello World!

Pokud chcete kontejner zastavit, spusťte:

docker stop my-web-site

Odstraňte kontejner z vývojového počítače:

docker rm my-web-site

Nahrání image do registru kontejneru

Po ověření, že se aplikace spustí v Dockeru, nahrajte image do vašeho registru ve službě Azure Container Registry.

Spusťte docker login přihlášení k registru kontejneru pomocí přihlašovacích údajů registru.

Následující příklad předá ID a heslo instančního objektu Microsoft Entra. Instanční objekt jste k registru mohli přiřadit například pro účely scénáře automatizace. Nebo se můžete přihlásit pomocí uživatelského jména a hesla registru.

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

Následující příkaz vytvoří značku, neboli alias, image s plně kvalifikovanou cestou k vašemu registru. Tento příklad umístí image do oboru názvů samples, aby se zabránilo nepořádku v kořenovém adresáři registru.

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

Nahrajte image do registru kontejneru:

docker push myregistry.azurecr.io/samples/helloworldapp

Zabalení image Dockeru pomocí Yeomana

Sada Service Fabric SDK pro Linux zahrnuje generátor Yeoman, který usnadňuje vytvoření aplikace a přidání image kontejneru. Použijme Yeomana k vytvoření aplikace SimpleContainerApp s jediným kontejnerem Dockeru.

Pokud chcete vytvořit aplikaci Service Fabric typu kontejner, otevřete okno terminálu a spusťte příkaz yo azuresfcontainer.

Pojmenujte aplikaci (například mycontainer) a aplikační službu (například myservice).

Jako název image zadejte adresu URL image kontejneru v registru kontejneru (například myregistry.azurecr.io/samples/helloworldapp).

Vzhledem k tomu, že tato image má definovaný vstupní bod úloh, není potřeba explicitně zadat vstupní příkazy (příkazy se spouští uvnitř kontejneru, což zajistí zachování provozu kontejneru po spuštění).

Jako počet instancí zadejte 1.

Zadejte mapování portů v příslušném formátu. V tomto článku je potřeba zadat 80:4000 jako mapování portů. Tímto způsobem jste nakonfigurovali, že všechny příchozí požadavky přicházející na port 4000 na hostitelském počítači se přesměrují na port 80 v kontejneru.

Service Fabric Yeoman generator for containers

Konfigurace ověřování úložiště kontejnerů

Informace o konfiguraci různých typů ověřování pro stahování imagí kontejneru najdete v tématu Ověřováníúložiště kontejnerů.

Konfigurace režimu izolace

V případě verze modulu runtime 6.3 se izolace virtuálního počítače podporuje pro kontejnery Linuxu a podporuje tak dva režimy izolace kontejnerů: proces a Hyper-V. V režimu izolace Technologie Hyper-V jsou jádra izolovaná mezi jednotlivými kontejnery a hostitelem kontejneru. Izolace Hyper-V se implementuje pomocí clear containers. Režim izolace je určen pro clustery s Linuxem ServicePackageContainerPolicy v elementu v souboru manifestu aplikace. Je možné zadat tyto režimy izolace: process, hyperv a default. Výchozí hodnota je režim izolace procesu. Následující fragment kódu ukazuje, jakým způsobem je režim izolace určený v souboru manifestu aplikace.

<ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="MyServicePkg" ServiceManifestVersion="1.0.0"/>
      <Policies>
        <ServicePackageContainerPolicy Hostname="votefront" Isolation="hyperv">
          <PortBinding ContainerPort="80" EndpointRef="myServiceTypeEndpoint"/>
        </ServicePackageContainerPolicy>
    </Policies>
  </ServiceManifestImport>

Konfigurace zásad správného řízení prostředků

Zásady správného řízení prostředků omezují prostředky, které kontejner může použít na hostiteli. Element ResourceGovernancePolicy, který je zadaný v manifestu aplikace, slouží k deklaraci omezení prostředků pro balíček kódu služby. Omezení prostředků je možné nastavit pro tyto prostředky: Memory, MemorySwap, CpuShares (relativní váha CPU), MemoryReservationInMB, BlkioWeight (relativní váha BlockIO). V tomto příkladu balíček služby Guest1Pkg získá jedno jádro na uzlech clusteru, kde je umístěný. Omezení paměti jsou absolutní, takže balíček kódu je omezený na 1024 MB paměti (a má tuto paměť softwarově vyhrazenou). Balíčky kódu (kontejnery a procesy) nejsou schopné přidělit víc paměti, než je toto omezení, a případný pokus o takové přidělení má za následek výjimku z důvodu nedostatku paměti. Aby vynucení omezení prostředků fungovala, musí být omezení paměti zadaná pro všechny balíčky kódu v rámci balíčku služby.

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

Konfigurace dockeru HEALTHCHECK

Počínaje v6.1 Service Fabric automaticky integruje události dockeru HEALTHCHECK do sestavy stavu systému. To znamená, že pokud váš kontejner má HEALTHCHECK povolený, Service Fabric oznámí stav vždy, když se změní stav kontejneru (nahlášený Dockerem). Pokud health_status je healthy, v Service Fabric Exploreru se zobrazí sestava stavu OK. Pokud health_status je unhealthy, zobrazí se UPOZORNĚNÍ.

Od nejnovější verze aktualizace verze 6.4 máte možnost určit, že vyhodnocení docker HEALTHCHECK by se měla hlásit jako chyba. Pokud je tato možnost povolená, zobrazí se zpráva o stavu OK, když je health_statusv pořádku a když health_status není v pořádku, zobrazí se chyba.

Pokyn HEALTHCHECK odkazující na aktuální kontrolu, která se provede pro monitorování stavu kontejneru, musí být uvedený v souboru Dockerfile použitém při generování image kontejneru.

Screenshot shows details of the Deployed Service Package NodeServicePackage.

HealthCheckUnhealthyApp

HealthCheckUnhealthyDsp

Chování HEALTHCHECK pro jednotlivé kontejnery můžete nakonfigurovat zadáním možností HealthConfig jako součásti ContainerHostPolicies v manifestu aplikace.

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

Ve výchozím nastavení IncludeDockerHealthStatusInSystemHealthReport je nastavena na hodnotu true, RestartContainerOnUnhealthStatus Je nastavena na false a TreatContainerUnhealthyStatusAsError je nastavena na false.

Pokud je pro RestartContainerOnUnhealthyDockerHealthStatus nastavená hodnota true, kontejner, který je opakovaně nahlášený ve špatném stavu, se restartuje (potenciálně na jiných uzlech).

Pokud je TreatContainerUnhealthyStatusAsError nastavená na hodnotu true, zobrazí se zprávy o stavu CHYBY, když health_status kontejneru není v pořádku.

Pokud chcete zakázat integraci HEALTHCHECK pro celý cluster Service Fabric, musíte nastavit EnableDockerHealthCheckIntegration na false.

Nasazení aplikace

Jakmile je aplikace sestavená, můžete ji nasadit do místního clusteru pomocí rozhraní příkazového řádku Service Fabric.

Připojte se k místnímu clusteru služby Service Fabric.

sfctl cluster select --endpoint http://localhost:19080

Pomocí instalačního skriptu poskytnutého v šablonách https://github.com/Azure-Samples/service-fabric-containers/ zkopírujte balíček aplikace do úložiště imagí clusteru, zaregistrujte typ aplikace a vytvořte instanci aplikace.

./install.sh

Otevřete prohlížeč a přejdete k Service Fabric Exploreru na adrese http://localhost:19080/Explorer (pokud používáte Vagrant v Mac OS X, místo localhost použijte privátní IP adresu virtuálního počítače). Rozbalte uzel Aplikace a všimněte si, že už obsahuje položku pro váš typ aplikace a další položku pro první instanci tohoto typu.

Připojte se ke spuštěnému kontejneru. Otevřete webový prohlížeč odkazující na IP adresu vrácenou na portu 4000, například ;http://localhost:4000". V prohlížeči by se měl zobrazit nadpis "Hello World!".

Hello World!

Vyčištění

Pomocí odinstalačního skriptu, který je součástí šablony, odstraňte instanci aplikace z místního vývojového clusteru a zrušte registraci typu aplikace.

./uninstall.sh

Po nahrání image do registru kontejneru můžete odstranit místní image z vývojového počítače:

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

Kompletní příklad manifestů služby a aplikace Service Fabric

Tady jsou kompletní manifesty aplikace a služby použité v tomto článku.

ServiceManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="myservicePkg"
                 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="myserviceType" 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 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="VariableName" Value="VariableValue"/>
      -->
    </EnvironmentVariables>
    
  </CodePackage>

  <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="myServiceTypeEndpoint" UriScheme="http" Port="4000" Protocol="http"/>
    </Endpoints>
  </Resources>
</ServiceManifest>

ApplicationManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest ApplicationTypeName="mycontainerType"
                     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">
  <!-- 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="myservicePkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides />
    <Policies>
      <ContainerHostPolicies CodePackageRef="Code">
        <RepositoryCredentials AccountName="myregistry" Password="=P==/==/=8=/=+u4lyOB=+=nWzEeRfF=" PasswordEncrypted="false"/>
        <PortBinding ContainerPort="80" EndpointRef="myServiceTypeEndpoint"/>
      </ContainerHostPolicies>
    </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="myservice">
      <!-- On a local development cluster, set InstanceCount to 1. On a multi-node production 
      cluster, set InstanceCount to -1 for the container service to run on every node in 
      the cluster.
      -->
      <StatelessService ServiceTypeName="myserviceType" InstanceCount="1">
        <SingletonPartition />
      </StatelessService>
    </Service>
  </DefaultServices>
</ApplicationManifest>

Přidání více služeb do stávající aplikace

Pokud chcete přidat další službu kontejneru do aplikace již vytvořené pomocí Yeomana, proveďte následující kroky:

  1. Změňte adresář na kořenovou složku stávající aplikace. Například cd ~/YeomanSamples/MyApplication, pokud MyApplication je aplikace vytvořená pomocí Yeomanu.
  2. Spusťte příkaz yo azuresfcontainer:AddService.

Konfigurace časového intervalu před vynuceným ukončením kontejneru

Můžete nakonfigurovat časový interval, který určuje, jak dlouho modul runtime počká před odebráním kontejneru po zahájení odstraňování služby (nebo jejího přesunu do jiného uzlu). Konfigurací časového intervalu se do kontejneru odešle příkaz docker stop <time in seconds>. Další podrobnosti najdete v dokumentaci k příkazu docker stop. Časový interval pro čekání se zadává v části Hosting. Následující fragment manifestu clusteru ukazuje nastavení intervalu čekání:

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

Výchozí časový interval je nastavený na 10 sekund. Vzhledem k tomu, že je tato konfigurace dynamická, časový limit aktualizuje v clusteru upgrade pouze konfigurace.

Konfigurace modulu runtime pro odebrání nepoužívaných imagí kontejneru

Cluster Service Fabric můžete nakonfigurovat tak, aby z uzlu odebral nepoužívané image kontejneru. Tato konfigurace umožňuje znovu získat místo na disku v případě, že je na uzlu příliš mnoho imagí kontejneru. Pokud chcete tuto funkci povolit, aktualizujte část Hosting v manifestu clusteru, jak je znázorněno v následujícím fragmentu kódu:

{
        "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|..."
          }
          ...
          }
        ]
} 

Image, které se nesmí odstranit, můžete zadat v rámci parametru ContainerImagesToSkip.

Konfigurace doby stahování image kontejneru

Modul runtime Service Fabric pro stažení a extrakci imagí kontejneru přidělí 20 minut. Pro většinu imagí kontejnerů to stačí. U větších imagí nebo při pomalém síťovém připojení může být potřeba prodloužit čas, po který se čeká, než dojde ke zrušení stahování a extrakce imagí. Tento časový limit se nastavuje pomocí atributu ContainerImageDownloadTimeout v části Hosting manifestu clusteru, jak ukazuje následující fragment kódu:

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

Nastavení zásad uchovávání informací kontejneru

Jako pomoc s diagnostikou selhání spuštění kontejneru Service Fabric (verze 6.1 nebo vyšší) podporuje zachování kontejnerů, které se ukončily nebo které se nepovedlo spustit. Tuto zásadu je možné nastavit v souboru ApplicationManifest.xml, jak ukazuje následující fragment kódu:

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

Nastavení ContainersRetentionCount určuje počet kontejnerů, které se při svém selhání zachovají. Pokud je zadaná hodnota záporná, zachovají se všechny kontejnery, které selhaly. Když atribut ContainersRetentionCount není zadaný, nezachovají se žádné kontejnery. Atribut ContainersRetentionCount také podporuje parametry aplikace, takže uživatelé mohou zadat různé hodnoty pro testovací a produkční clustery. Při použití této funkce použijte omezení umístění, aby služba kontejneru cílila na konkrétní uzel. Zabrání se tak přesunu služby kontejneru na jiné uzly. Všechny kontejnery zachované pomocí této funkce je nutné ručně odebrat.

Spuštění démona Dockeru s vlastními argumenty

V modulu runtime Service Fabric verze 6.2 a novější můžete spustit démona Dockeru s vlastními argumenty. Pokud zadáte vlastní argumenty, Service Fabric do modulu Dockeru nepředá žádné další argumenty s výjimkou argumentu --pidfile. Proto by se --pidfile nemělo předávat jako argument. Kromě toho by tento argument měl umožnit, aby démon Dockeru i nadále naslouchal kanálu s výchozím názvem ve Windows (nebo unixovému soketu domény v Linuxu), aby se zajistila komunikace Service Fabric s démonem. Vlastní argumenty se zadávají v manifestu clusteru v části Hosting v rámci části ContainerServiceArguments. Příklad je znázorněný v následujícím fragmentu kódu:

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

Další kroky