In Docker gehostete MicroservicesMicroservices hosted in Docker

EinführungIntroduction

In diesem Tutorial werden die erforderlichen Aufgaben zum Erstellen und Bereitstellen eines ASP.NET Core-Microservice in einem Docker-Container erläutert.This tutorial details the tasks necessary to build and deploy an ASP.NET Core microservice in a Docker container. Im Verlauf dieses Tutorials lernen Sie Folgendes:During the course of this tutorial, you'll learn:

  • Generieren einer ASP.NET Core-Anwendung mit YeomanHow to generate an ASP.NET Core application using Yeoman
  • Erstellen einer Docker-EntwicklungsumgebungHow to create a development Docker environment
  • Erstellen eines Docker-Images basierend auf einem vorhandenen ImageHow to build a Docker image based on an existing image.
  • Bereitstellen Ihres Diensts in einem Docker-ContainerHow to deploy your service into a Docker container.

Dabei lernen Sie auch einige C#-Sprachfunktionen kennen:Along the way, you'll also see some C# language features:

  • Konvertieren von C#-Objekten in JSON-NutzlastenHow to convert C# objects into JSON payloads.
  • Erstellen unveränderlicher DatenübertragungsobjekteHow to build immutable Data Transfer Objects
  • Verarbeiten eingehender HTTP-Anforderungen und Generieren der HTTP-AntwortHow to process incoming HTTP Requests and generate the HTTP Response
  • Arbeiten mit Nullable-WerttypenHow to work with nullable value types

Sie können die Beispiel-App für dieses Thema anzeigen oder herunterladen.You can view or download the sample app for this topic. Anweisungen zum Herunterladen finden Sie unter Beispiele und Lernprogramme.For download instructions, see Samples and Tutorials.

Warum Docker?Why Docker?

Docker erleichtert das Erstellen von standardmäßigen Computerimages zum Hosten Ihrer Dienste in einem Rechenzentrum oder der öffentlichen Cloud.Docker makes it easy to create standard machine images to host your services in a data center, or the public cloud. Mit Docker können Sie das Image konfigurieren und nach Bedarf replizieren, um die Installation der Anwendung zu skalieren.Docker enables you to configure the image, and replicate it as needed to scale the installation of your application.

Der gesamte Code in diesem Tutorial ist in einer beliebigen .NET Core-Umgebung einsetzbar.All the code in this tutorial will work in any .NET Core environment. Die zusätzlichen Aufgaben für eine Docker-Installation funktionieren in Verbindung mit einer ASP.NET Core-Anwendung.The additional tasks for a Docker installation will work for an ASP.NET Core application.

Erforderliche KomponentenPrerequisites

Sie müssen Ihren Computer zur Ausführung von .NET Core einrichten.You’ll need to setup your machine to run .NET core. Die Installationsanweisungen finden Sie auf der Seite .NET Core.You can find the installation instructions on the .NET Core page. Sie können diese Anwendung unter Windows, Ubuntu Linux, macOS oder in einem Docker-Container ausführen.You can run this application on Windows, Ubuntu Linux, macOS or in a Docker container. Sie müssen Ihren bevorzugten Code-Editor installieren.You’ll need to install your favorite code editor. In den folgenden Beschreibungen wird Visual Studio Code verwendet. Hierbei handelt es sich um einen plattformübergreifenden Open Source-Editor.The descriptions below use Visual Studio Code which is an open source, cross platform editor. Sie können jedoch auch ein beliebiges anderes Tool verwenden, mit dem Sie vertraut sind.However, you can use whatever tools you are comfortable with.

Sie müssen auch das Docker-Modul installieren.You'll also need to install the Docker engine. Anweisungen für Ihre Plattform finden Sie auf der Docker-Installationsseite.See the Docker Installation page for instructions for your platform. Docker kann in vielen Linux-Distributionen, unter macOS oder Windows installiert werden.Docker can be installed in many Linux distributions, macOS, or Windows. Die oben erwähnte Seite enthält Abschnitte zu jeder verfügbaren Installation.The page referenced above contains sections to each of the available installations.

Die meisten zu installierenden Komponenten sind einem Paket-Manager zugeordnet.Most components to be installed are done by a package manager. Wenn Sie den Node.js-Paket-Manager npm installiert haben, können Sie diesen Schritt überspringen.If you have node.js's package manager npm installed you can skip this step. Installieren Sie andernfalls das aktuelle NodeJS von nodejs.org, sodass der npm-Paket-Manager installiert wird.Otherwise install the latest NodeJs from nodejs.org which will install the npm package manager.

An diesem Punkt müssen Sie eine Reihe von Befehlszeilentools installieren, die die ASP.NET Core-Entwicklung unterstützen.At this point you will need to install a number of command line tools that support ASP.NET core development. Die Befehlszeilenvorlagen verwenden Yeoman, Bower, Grunt und Gulp.The command line templates use Yeoman, Bower, Grunt, and Gulp. Sie haben sie bereits installiert? Hervorragend – geben Sie andernfalls Folgendes in Ihre bevorzugte Shell ein:If you have them installed that is good, otherwise type the following into your favorite shell:

npm install -g yo bower grunt-cli gulp

Die -g-Option gibt an, dass dies eine globale Installation ist, und diese Tools im gesamten System verfügbar sind.The -g option indicates that it is a global install, and those tools are available system wide. (Eine lokale Installation beschränkt das Paket auf ein einzelnes Projekt).(A local install scopes the package to a single project). Nachdem Sie diese wesentlichen Tools installiert haben, müssen Sie die Yeoman-ASP.NET-Vorlagengeneratoren installieren:Once you've installed those core tools, you need to install the yeoman asp.net template generators:

npm install -g generator-aspnet

Erstellen der AnwendungCreate the Application

Jetzt haben Sie alle Tools installiert und können eine neue ASP.NET Core-Anwendung erstellen.Now that you've installed all the tools, create a new asp.net core application. Um den Befehlszeilengenerator zu verwenden, führen Sie den folgenden Yeoman-Befehl in Ihrer bevorzugten Shell aus:To use the command line generator, execute the following yeoman command in your favorite shell:

yo aspnet

Dieser Befehl fordert Sie auf, auszuwählen, welchen Anwendungstyp Sie erstellen möchten.This command prompts you to select what Type of application you want to create. Für diesen Microservice sollten Sie die unkomplizierteste Webanwendung wählen, also wählen Sie „Leere Web-Anwendung“ aus.For this microservice, you want the simplest, most lightweight web application possible, so select 'Empty Web Application'. Die Vorlage fordert Sie zur Eingabe eines Namens auf.The template will prompt you for a name. Wählen Sie „WeatherMicroservice“.Select 'WeatherMicroservice'.

Die Vorlage erstellt acht Dateien für Sie:The template creates eight files for you:

  • Eine für ASP.NET Core-Anwendungen angepasste .gitignore-Datei.A .gitignore, customized for asp.net core applications.
  • Eine Startup.cs-Datei.A Startup.cs file. Diese enthält die Grundlage für die Anwendung.This contains the basis of the application.
  • Eine Program.cs-Datei.A Program.cs file. Diese enthält den Einstiegspunkt für die Anwendung.This contains the entry point of the application.
  • Eine WeatherMicroservice.csproj-Datei.A WeatherMicroservice.csproj file. Dies ist die Build-Datei für die Anwendung.This is the build file for the application.
  • Die Docker-Datei.A Dockerfile. Dieses Skript erstellt ein Docker-Image für die Anwendung.This script creates a Docker image for the application.
  • Eine README.md-Datei.A README.md. Diese enthält Links zu anderen ASP.NET Core-Ressourcen.This contains links to other asp.net core resources.
  • Eine web.config-Datei.A web.config file. Diese enthält grundlegende Konfigurationsinformationen.This contains basic configuration information.
  • Eine runtimeconfig.template.json-Datei.A runtimeconfig.template.json file. Diese enthält von IDEs verwendete Debugeinstellungen.This contains debugging settings used by IDEs.

Jetzt können Sie die von der Vorlage generierte Anwendung ausführen.Now you can run the template generated application. Dies geschieht mithilfe einer Reihe von Tools von der Befehlszeile aus.That's done using a series of tools from the command line. Der dotnet-Befehl führt die erforderlichen Tools für die .NET-Entwicklung aus.The dotnet command runs the tools necessary for .NET development. Jedes Verb führt einen anderen Befehl aus.Each verb executes a different command

Der erste Schritt besteht im Wiederherstellen aller Abhängigkeiten:The first step is to restore all the dependencies:

dotnet restore

Die Dotnet-Wiederherstellung verwendet den NuGet-Paket-Manager, um alle erforderlichen Pakete im Verzeichnis der Anwendung zu installieren.Dotnet restore uses the NuGet package manager to install all the necessary packages into the application directory. Sie generiert außerdem eine project.json.lock-Datei.It also generates a project.json.lock file. Diese Datei enthält Informationen zu jedem Paket, auf das verwiesen wird.This file contains information about each package that is referenced. Nach der Wiederherstellung alle Abhängigkeiten erstellen Sie die Anwendung:After restoring all the dependencies, you build the application:

dotnet build

Hinweis

Starting with .NET Core 2.0, you don't have to run dotnet restore because it's run implicitly by all commands, such as dotnet build and dotnet run, that require a restore to occur. It's still a valid command in certain scenarios where doing an explicit restore makes sense, such as continuous integration builds in Visual Studio Team Services or in build systems that need to explicitly control the time at which the restore occurs.

Sobald Sie die Anwendung erstellen, führen Sie sie über die Befehlszeile aus:And once you build the application, you run it from the command line:

dotnet run

Die Standardkonfiguration lauscht auf http://localhost:5000.The default configuration listens to http://localhost:5000. Wenn Sie den Browser öffnen und zu dieser Seite navigieren, sehen Sie ein „Hello World!“.You can open a browser and navigate to that page and see a "Hello World!" Vorgang nicht gefunden werden konnte.message.

Anatomie einer ASP.NET Core-AnwendungAnatomy of an ASP.NET Core application

Da Sie jetzt die Anwendung erstellt haben, können wir nun die Implementierung dieser Funktionalität betrachten.Now that you've built the application, let's look at how this functionality is implemented. Zwei der generierten Dateien sind hier besonders interessant: „project.json“ und „Startup.cs“.There are two of the generated files that are particularly interesting at this point: project.json and Startup.cs.

„project.json“ enthält Informationen zum Projekt.Project.json contains information about the project. Sie werden häufig mit den beiden Knoten „Abhängigkeiten“ und „Frameworks“ arbeiten.The two nodes you'll often work with are 'dependencies' and 'frameworks'. Der Abhängigkeiten-Knoten listet alle Pakete auf, die für diese Anwendung erforderlich sind.The dependencies node lists all the packages that are needed for this application. Im Moment ist dies ein kleiner Knoten, der nur die Pakete benötigt, die den Webserver ausführen.At the moment, this is a small node, needing only the packages that run the web server.

Der frameworks-Knoten gibt die Versionen und Konfigurationen des .NET Framework an, das diese Anwendung ausführen wird.The 'frameworks' node specifies the versions and configurations of the .NET framework that will run this application.

Die Anwendung wird in „Startup.cs“ implementiert.The application is implemented in Startup.cs. Diese Datei enthält die Startklasse.This file contains the startup class.

Die beiden Methoden werden von der ASP.NET Core-Infrastruktur zum Konfigurieren und Ausführen der Anwendung aufgerufen.The two methods are called by the asp.net core infrastructure to configure and run the application. Die ConfigureServices-Methode beschreibt die Dienste, die für diese Anwendung erforderlich sind.The ConfigureServices method describes the services that are necessary for this application. Sie erstellen einen einfachen Microservice, sodass keine Abhängigkeiten konfiguriert werden müssen.You're building a lean microservice, so it doesn't need to configure any dependencies. Die Configure-Methode konfiguriert die Handler für eingehende HTTP-Anforderungen.The Configure method configures the handlers for incoming HTTP Requests. Die Vorlage erstellt einen einfachen Handler, der auf jede Anforderung mit dem Text „Hello World!“ reagiert.The template generates a simple handler that responds to any request with the text 'Hello World!'.

Erstellen eines MicroserviceBuild a microservice

Sie werden einen Dienst erstellen, der Wetterberichte aus aller Welt bereitstellt.The service you're going to build will deliver weather reports from anywhere around the globe. In einer Produktionsanwendung würden Sie einen Dienst aufrufen, um Wetterdaten abzurufen.In a production application, you'd call some service to retrieve weather data. In diesem Beispiel generieren wir einen zufälligen Wetterbericht.For our sample, we'll generate a random weather forecast.

Sie müssen eine Reihe von Aufgaben ausführen, um unseren zufälligen Wetterdienst zu implementieren:There are a number of tasks you'll need to perform in order to implement our random weather service:

  • Analysieren der eingehenden Anforderung, um den Breiten- und Längengrad zu lesen.Parse the incoming request to read the latitude and longitude.
  • Generieren einiger zufälliger Vorhersagedaten.Generate some random forecast data.
  • Konvertieren dieser zufälligen Vorhersagedaten von C#-Objekten in JSON-Pakete.Convert that random forecast data from C# objects into JSON packets.
  • Festlegen des Antwortheaders, um anzugeben, dass Ihr Dienst JSON-Daten zurücksendet.Set the response header to indicate that your service sends back JSON.
  • Schreiben der Antwort.Write the response.

In den nächsten Abschnitten werden diese Schritte erläutert.The next sections walk you through each of these steps.

Analyse der Abfragezeichenfolge.Parsing the Query String.

Sie beginnen mit der Analyse der Abfragezeichenfolge.You'll begin by parsing the query string. Der Dienst nimmt die Argumente „lat“ und „long“ in der Abfragezeichenfolge in diesem Formular entgegen:The service will accept 'lat' and 'long' arguments on the query string in this form:

http://localhost:5000/?lat=-35.55&long=-12.35

Alle Änderungen, die Sie vornehmen müssen, sind in dem Lambdaausdruck enthalten, der in Ihrer Startklasse als Argument für app.Run definiert ist.All the changes you need to make are in the lambda expression defined as the argument to app.Run in your startup class.

Das Argument des Lambdaausdrucks ist der HttpContext für die Anforderung.The argument on the lambda expression is the HttpContext for the request. Eine seiner Eigenschaften ist das Request-Objekt.One of its properties is the Request object. Das Request-Objekt verfügt über eine Query-Eigenschaft, die ein Wörterbuch aller Werte in der Abfragezeichenfolge für die Anforderung enthält.The Request object has a Query property that contains a dictionary of all the values on the query string for the request. Die erste Addition besteht darin, die Werte für Breiten- und Längengrad zu finden:The first addition is to find the latitude and longitude values:

var latString = context.Request.Query["lat"].FirstOrDefault();
var longString = context.Request.Query["long"].FirstOrDefault();

Die Abfrage-Wörterbuchwerte sind vom Typ StringValue.The Query dictionary values are StringValue type. Dieser Typ kann eine Auflistung von Zeichenfolgen enthalten.That type can contain a collection of strings. Für Ihren Wetterdienst ist jeder Wert eine einzelne Zeichenfolge.For your weather service, each value is a single string. Daher erfolgt der Aufruf von FirstOrDefault() im obigen Code.That's why there's the call to FirstOrDefault() in the code above.

Als Nächstes müssen Sie die Zeichenfolgen in Double-Werte konvertieren.Next, you need to convert the strings to doubles. Die Methode, mit der Sie die Zeichenfolge in einen Double-Wert konvertieren, ist double.TryParse():The method you'll use to convert the string to a double is double.TryParse():

bool TryParse(string s, out double result);

Diese Methode nutzt C#-out-Parameter, um anzugeben, ob die Eingabezeichenfolge in einen Double-Wert konvertiert werden kann.This method leverages C# out parameters to indicate if the input string can be converted to a double. Wenn die Zeichenfolge einen gültigen Double-Wert darstellt, gibt die Methode „true“ zurück, und das result-Argument enthält den Wert.If the string does represent a valid representation for a double, the method returns true, and the result argument contains the value. Wenn die Zeichenfolge keinen gültigen Double-Wert darstellt, gibt die Methode „false“ zurück.If the string does not represent a valid double, the method returns false.

Sie können diese API mithilfe einer Erweiterungsmethode anpassen, die einen Nullable-Double-Wert zurückgibt.You can adapt that API with the use of an extension method that returns a nullable double. Ein Nullable-Werttyp ist ein Typ, der einen Werttyp darstellt und auch einen fehlenden, d.h. NULL-Wert enthalten kann.A nullable value type is a type that represents some value type, and can also hold a missing, or null value. Ein Nullable-Typ wird durch Anhängen des ?-Zeichens an die Typdeklaration dargestellt.A nullable type is represented by appending the ? character to the type declaration.

Erweiterungsmethoden sind als statische Methoden definierte Methoden, können aber durch Hinzufügen des this-Modifizierers zum ersten Parameter so aufgerufen werden, als ob sie Member dieser Klasse sind.Extension methods are methods that are defined as static methods, but by adding the this modifier on the first parameter, can be called as though they are members of that class. Erweiterungsmethoden können nur in statischen Klassen definiert werden.Extension methods may only be defined in static classes. Hier ist die Definition der Klasse, die die Erweiterungsmethode für die Analyse enthält:Here's the definition of the class containing the extension method for parse:

public static class Extensions
{
    public static double? TryParse(this string input)
    {
        double result;
        if (double.TryParse(input, out result))
        {
            return result;
        }
        else
        {
            return default(double?);
        }
    }
}

Der default(double?)-Ausdruck gibt den Standardwert für den double?-Typ zurück.The default(double?) expression returns the default value for the double? type. Dieser Standardwert ist der NULL-Wert (oder nicht vorhandener Wert).That default value is the null (or missing) value.

Sie können diese Erweiterungsmethode verwenden, um die Abfragezeichenfolgen-Argumente in den Double-Typ zu konvertieren:You can use this extension method to convert the query string arguments into the double type:

var latitude = latString.TryParse();
var longitude = longString.TryParse();

Um den Analysecode mühelos zu testen, aktualisieren Sie die Antwort so, dass sie die Werte der Argumente enthält:To easily test the parsing code, update the response to include the values of the arguments:

await context.Response.WriteAsync($"Retrieving Weather for lat: {latitude}, long: {longitude}");                

An diesem Punkt können Sie die Webanwendung ausführen und prüfen, ob Ihr Analysecode funktioniert.At this point, you can run the web application and see if your parsing code is working. Fügen Sie der Webanforderung in einem Browser Werte hinzu, und Sie sollten die aktualisierten Ergebnisse sehen.Add values to the web request in a browser, and you should see the updated results.

Erstellen einer zufälligen WettervorhersageBuild a random weather forecast

Ihre nächste Aufgabe ist das Erstellen einer zufälligen Wettervorhersage.Your next task is to build a random weather forecast. Wir beginnen mit einem Datencontainer, der die Werte enthält, die Sie für einen Wetterbericht wünschen:Let's start with a data container that holds the values you'd want for a weather forecast:

public class WeatherReport
{
    private static readonly string[] PossibleConditions = new string[]
    {
        "Sunny",
        "Mostly Sunny",
        "Partly Sunny",
        "Partly Cloudy",
        "Mostly Cloudy",
        "Rain"
    };

    public int HiTemperature { get; }
    public int LoTemperature { get; }
    public int AverageWindSpeed { get; }
    public string Conditions { get; }
}

Als Nächstes erstellen Sie einen Konstruktor, der diese Werte nach dem Zufallsprinzip festlegt.Next, build a constructor that randomly sets those values. Dieser Konstruktor verwendet die Werte für den Breiten- und Längengrad, um den Zufallszahlengenerator zu starten.This constructor uses the values for the latitude and longitude to seed the Random number generator. Das bedeutet, dass die Vorhersage für den gleichen Ort identisch ist.That means the forecast for the same location is the same. Wenn Sie die Argumente für den Breiten- und Längengrad ändern, erhalten Sie eine andere Vorhersage (weil Sie mit einem anderen Startwert beginnen.)If you change the arguments for the latitude and longitude, you'll get a different forecast (because you start with a different seed.)

public WeatherReport(double latitude, double longitude, int daysInFuture)
{
    var generator = new Random((int)(latitude + longitude) + daysInFuture);

    HiTemperature = generator.Next(40, 100);
    LoTemperature = generator.Next(0, HiTemperature);
    AverageWindSpeed = generator.Next(0, 45);
    Conditions = PossibleConditions[generator.Next(0, PossibleConditions.Length - 1)];
}

Sie können jetzt die 5-Tage-Wettervorhersage in Ihrer Antwortmethode generieren:You can now generate the 5-day forecast in your response method:

if (latitude.HasValue && longitude.HasValue)
{
    var forecast = new List<WeatherReport>();
    for (var days = 1; days < 6; days++)
    {
        forecast.Add(new WeatherReport(latitude.Value, longitude.Value, days));
    }
    var json = JsonConvert.SerializeObject(forecast, Formatting.Indented);
    context.Response.ContentType = "application/json; charset=utf-8";
    await context.Response.WriteAsync(json);
}

Erstellen Sie die JSON-Antwort.Build the JSON response.

Die letzte Codierungsaufgabe auf dem Server ist, das WeatherReport-Array in ein JSON-Paket zu konvertieren und dieses an den Client zurückzusenden.The final code task on the server is to convert the WeatherReport array into a JSON packet, and send that back to the client. Wir erstellen zunächst das JSON-Paket.Let's start by creating the JSON packet. Sie fügen das NewtonSoft JSON-Serialisierungsprogramm der Liste der Abhängigkeiten hinzu.You'll add the NewtonSoft JSON Serializer to the list of dependencies. Verwenden Sie hierzu die dotnet-CLI:You can do that using the dotnet CLI:

dotnet add package Newtonsoft.Json

Anschließend können Sie das Objekt mithilfe der JsonConvert-Klasse in eine Zeichenfolge schreiben:Then, you can use the JsonConvert class to write the object to a string:

var json = JsonConvert.SerializeObject(forecast, Formatting.Indented);
context.Response.ContentType = "application/json; charset=utf-8";
await context.Response.WriteAsync(json);

Der obige Code konvertiert das Vorhersageobjekt (eine Liste der WeatherForecast-Objekte) in ein JSON-Paket.The code above converts the forecast object (a list of WeatherForecast objects) into a JSON packet. Nachdem Sie das Antwortpaket erstellt haben, legen Sie den Inhaltstyp auf application/json fest, und schreiben Sie die Zeichenfolge.After you've constructed the response packet, you set the content type to application/json, and write the string.

Die Anwendung wird jetzt ausgeführt und gibt zufällige Vorhersagen zurück.The application now runs and returns random forecasts.

Erstellen eines Docker-ImagesBuild a Docker image

Unsere letzte Aufgabe ist das Ausführen der Anwendung in Docker.Our final task is to run the application in Docker. Wir erstellen einen Docker-Container, der ein Docker-Image ausführt, das die Anwendung darstellt.We'll create a Docker container that runs a Docker image that represents our application.

Ein Docker-Image ist eine Datei, die die Umgebung für die Ausführung der Anwendung definiert.A Docker Image is a file that defines the environment for running the application.

Ein Docker-Container stellt eine ausgeführte Instanz eines Docker-Images dar.A Docker Container represents a running instance of a Docker image.

Entsprechend können Sie sich das Docker-Image als eine Klasse und den Docker-Container als ein Objekt oder eine Instanz dieser Klasse vorstellen.By analogy, you can think of the Docker Image as a class, and the Docker Container as an object, or an instance of that class.

Die von der ASP.NET-Vorlage erstellte Docker-Datei ist für unsere Zwecke geeignet.The Dockerfile created by the asp.net template will serve for our purposes. Betrachten wir ihren Inhalt.Let's go over its contents.

Die erste Zeile gibt das Quellimage an:The first line specifies the source image:

FROM microsoft/dotnet:1.1-sdk-msbuild

Mit Docker können Sie ein Computerimage auf Basis einer Quellvorlage konfigurieren.Docker allows you to configure a machine image based on a source template. Das bedeutet, Sie müssen beim Start nicht alle Computerparameter, sondern nur Änderungen angeben.That means you don't have to supply all the machine parameters when you start, you only need to supply any changes. Hier dienen die Änderungen dazu, unsere Anwendung einzubeziehen.The changes here will be to include our application.

In diesem ersten Beispiel verwenden wir die 1.1-sdk-msbuild-Version des Dotnet-Images.In this first sample, we'll use the 1.1-sdk-msbuild version of the dotnet image. Dies ist die einfachste Möglichkeit zum Erstellen einer funktionierenden Docker-Umgebung.This is the easiest way to create a working Docker environment. Dieses Image enthält die Dotnet Core-Laufzeit und das Dotnet SDK.This image include the dotnet core runtime, and the dotnet SDK. Dies vereinfacht den Einstieg und das Erstellen, erstellt aber kein größeres Image.That makes it easier to get started and build, but does create a larger image.

Die nächsten fünf Zeilen richten die Anwendung ein und erstellen sie:The next five lines setup and build your application:

WORKDIR /app

# copy csproj and restore as distinct layers

COPY WeatherMicroservice.csproj .
RUN dotnet restore 

# copy and build everything else

COPY . .

# RUN dotnet restore
RUN dotnet publish -c Release -o out

Hinweis

Starting with .NET Core 2.0, you don't have to run dotnet restore because it's run implicitly by all commands, such as dotnet build and dotnet run, that require a restore to occur. It's still a valid command in certain scenarios where doing an explicit restore makes sense, such as continuous integration builds in Visual Studio Team Services or in build systems that need to explicitly control the time at which the restore occurs.

Hiermit wird die Projektdatei aus dem aktuellen Verzeichnis in die Docker-VM kopiert und werden alle Pakete wiederhergestellt.This will copy the project file from the current directory to the docker VM, and restore all the packages. Die Verwendung der Dotnet-CLI bedeutet, dass das Docker-Image das .NET Core-SDK einbeziehen muss.Using the dotnet CLI means that the Docker image must include the .NET Core SDK. Danach wird der Rest der Anwendung kopiert, und der Dotnet-publish-Befehl erstellt Ihre Anwendung und macht daraus ein Paket.After that, the rest of your application gets copied, and the dotnet publish command builds and packages your application.

Die letzte Zeile der Datei führt die Anwendung aus:The final line of the file runs the application:

ENTRYPOINT ["dotnet", "out/WeatherMicroservice.dll", "--server.urls", "http://0.0.0.0:5000"]

Auf diesen konfigurierten Port wird im --server.urls-Argument für dotnet in der letzten Zeile der Docker-Datei verwiesen.This configured port is referenced in the --server.urls argument to dotnet on the last line of the Dockerfile. Die ENTRYPOINT-Befehl teilt Docker mit, welcher Befehl und welche Befehlszeilenoptionen den Dienst starten.The ENTRYPOINT command informs Docker what command and command line options start the service.

Erstellen und Ausführen des Images in einem ContainerBuilding and running the image in a container.

Wir erstellen ein Image und führen den Dienst in einem Docker-Container aus.Let's build an image and run the service inside a Docker container. Nicht alle Dateien in Ihrem lokalen Verzeichnis sollen in das Image kopiert werden.You don't want all the files from your local directory copied into the image. Stattdessen erstellen Sie die Anwendung im Container.Instead, you'll build the application in the container. Sie erstellen eine .dockerignore-Datei, um die Verzeichnisse festzulegen, die nicht in das Image kopiert werden.You'll create a .dockerignore file to specify the directories that are not copied into the image. Kein Buildobjekt soll kopiert werden.You don't want any of the build assets copied. Geben Sie die Verzeichnisse für Build und Veröffentlichung in der .dockerignore-Datei an:Specify the build and publish directories in the .dockerignore file:

bin/*
obj/*
out/*

Sie erstellen das Image mithilfe des Docker-build-Befehls.You build the image using the docker build command. Führen Sie den folgenden Befehl in dem Verzeichnis aus, das Ihren Code enthält.Run the following command from the directory containing your code.

docker build -t weather-microservice .

Dieser Befehl erstellt das Containerimage basierend auf allen Informationen in Ihrer Docker-Datei.This command builds the container image based on all the information in your Dockerfile. Das -t-Argument liefert ein Tag, d.h. einen Namen, für dieses Containerimage.The -t argument provides a tag, or name, for this container image. In der Befehlszeile oben wird das Tag weather-microservice für den Docker-Container verwendet.In the command line above, the tag used for the Docker container is weather-microservice. Nach Abschluss dieses Befehls verfügen Sie über einen Container, in dem Sie den neuen Dienst ausführen können.When this command completes, you have a container ready to run your new service.

Führen Sie den folgenden Befehl zum Starten des Containers aus, und starten Sie Ihren Dienst:Run the following command to start the container and launch your service:

docker run -d -p 80:5000 --name hello-docker weather-microservice

Die -d-Option bedeutet, den Container unabhängig vom aktuellen Terminal auszuführen.The -d option means to run the container detached from the current terminal. Dies bedeutet, dass die Ausgabe des Befehls nicht auf Ihrem Terminal angezeigt wird.That means you won't see the command output in your terminal. Die -p-Option gibt die Portzuordnung zwischen dem Dienst und dem Host an.The -p option indicates the port mapping between the service and the host. Hier gibt sie an, dass jede an Port 80 eingehende Anforderung an Port 5000 im Container weitergeleitet werden soll.Here it says that any incoming request on port 80 should be forwarded to port 5000 on the container. 5000 entspricht dem Port, auf den der Dienst über die Befehlszeilenargumente lauscht, die in der oben genannten Docker-Datei angegeben sind.Using 5000 matches the port your service is listening on from the command line arguments specified in the Dockerfile above. Das --name-Argument benennt den ausgeführten Container.The --name argument names your running container. Es ist ein praktischer Name, den Sie zum Arbeiten mit dem betreffenden Container verwenden können.It's a convenient name you can use to work with that container.

Sie können sehen, ob das Image ausgeführt wird, indem Sie den Befehl überprüfen:You can see if the image is running by checking the command:

docker ps

Wenn der Container ausgeführt wird, sehen Sie eine Zeile, in der er als ausgeführter Prozess aufgelistet wird.If your container is running, you'll see a line that lists it in the running processes. (Vielleicht ist er der einzige).(It may be the only one).

Sie können Ihren Dienst testen, indem Sie einen Browser öffnen, zu „localhost“ navigieren und einen Breiten- und Längengrad angeben:You can test your service by opening a browser and navigating to localhost, and specifying a latitude and longitude:

http://localhost/?lat=35.5&long=40.75

Anfügen an einen ausgeführten ContainerAttaching to a running container

Bei der Ausführung Ihres Diensts in einem Befehlsfenster konnten Sie sehen, dass für jede Anforderung Diagnoseinformationen ausgegeben wurden.When you ran your sevice in a command window, you could see diagnostic information printed for each request. Diese Informationen werden nicht angezeigt, wenn der Container im getrennten Modus ausgeführt wird.You don't see that information when your container is running in detached mode. Der Docker-attach-Befehl ermöglicht Ihnen das Anfügen an einen ausgeführten Container, sodass Sie die Protokollinformationen sehen können.The Docker attach command enables you to attach to a running container so that you can see the log information. Führen Sie diesen Befehl in einem Befehlsfenster aus:Run this command from a command window:

docker attach --sig-proxy=false hello-docker

Das --sig-proxy=false-Argument bedeutet, dass Ctrl-C-Befehle nicht an den Containerprozess gesendet werden, aber stattdessen den docker attach-Befehl beenden.The --sig-proxy=false argument means that Ctrl-C commands do not get sent to the container process, but rather stop the docker attach command. Das letzte Argument ist der Name, den der Container im docker run-Befehl erhält.The final argument is the name given to the container in the docker run command.

Hinweis

Sie können auch die Docker zugewiesene Container-ID verwenden, um auf einen Container zu verweisen.You can also use the docker assigned container ID to refer to any container. Wenn Sie in docker run keinen Namen für den Container angegeben haben, müssen Sie die Container-ID verwenden.If you didn't specify a name for your container in docker run you must use the container id.

Öffnen Sie einen Browser, und navigieren Sie zu Ihrem Dienst.Open a browser and navigate to your service. Sie sehen die Diagnosemeldungen des angefügten ausgeführten Containers in den Befehlsfenstern.You'll see the diagnostic messages in the command windows from the attached running container.

Drücken Sie Ctrl-C, um den Anfügungsprozess zu beenden.Press Ctrl-C to stop the attach process.

Wenn Sie die Arbeit mit Ihrem Container abgeschlossen haben, können Sie ihn stoppen:When you are done working with your container, you can stop it:

docker stop hello-docker

Container und Image stehen weiterhin für einen Neustart zur Verfügung.The container and image is still available for you to restart. Wenn Sie den Container von Ihrem Computer entfernen möchten, verwenden Sie diesen Befehl:If you want to remove the container from your machine, you use this command:

docker rm hello-docker

Wenn Sie nicht benutzte Images von Ihrem Computer entfernen möchten, verwenden Sie diesen Befehl:If you want to remove unused images from your machine, you use this command:

docker rmi weather-microservice

SchlussfolgerungConclusion

In diesem Tutorial haben Sie einen ASP.NET Core-Microservice erstellt und einige einfache Funktionen hinzugefügt.In this tutorial, you built an asp.net core microservice, and added a few simple features.

Sie haben ein Docker-Containerimage für diesen Dienst erstellt und diesen Container auf dem Computer ausgeführt.You built a docker container image for that service, and ran that container on your machine. Sie haben dem Dienst ein Terminalfenster angefügt und die Diagnosemeldungen Ihres Diensts gesehen.You attached a terminal window to the service, and saw the diagnostic messages from your service.

Nebenbei haben Sie verschiedene Features der C#-Sprache in Aktion gesehen.Along the way, you saw several features of the C# language in action.