Freigeben über



Juni 2019

Band 34, Nummer 6

Dieser Artikel wurde maschinell übersetzt.

[Data Points]

EF Core in einer containerisierten Docker-App, Teil 3

Durch Julie Lerman

Julie LermanIn den letzten beiden Artikeln habe ich Sie durchlaufen, durch die Erstellung einer kleinen ASP.NET Core-API aus, die mithilfe von Entity Framework, die in einem Docker-Container gekapselt sind. Im ersten Artikel habe ich eine SQLite-Datenbank innerhalb des Containers eingefügt werden. Im zweiten Fall Ziel ich Azure SQL-Datenbank, die von überall aus erreichbar sind. Die größere Herausforderung wurde in diesem Fall wie Geheimnisse (z.B. Datenbankkennwörter) geheimzuhalten und Konfigurationen (z. B. Verbindungszeichenfolgen für Datenbanken für Entwicklung oder Produktion) Fluid. Diese Zielsetzung bedingte den lernen, wie Sie die Möglichkeit von Docker Compose-zum Lesen von Umgebungsvariablen aus dem Host nutzen.

Es gibt einen anderen sehr interessanter Pfad für die Beibehaltung von Daten, d. h. sowohl einen Datenbank-Server und die Daten in Containern. Ich habe zur Verwendung von SQL Server für Linux in Docker-Containern in früheren Artikeln, z. B. unter geschrieben msdn.com/magazine/mt784660. Mir gefällt die Möglichkeit, die von Microsoft Steve Lasker drückt aus, der Verwendung von SQL Server auf den Container für Dev / Test:

Einrichten von SQL-Code in einem Container bietet Entwicklern die Möglichkeit, Isolieren/einer Umgebung zu simulieren. Eine andere Version von SQL Server, einschließlich. Zum Starten des Tests aus dem Zustand ist, jedes Mal die Qualität. Insbesondere, wenn eine DB-Aktualisierung, statt herauszufinden, wie das Update DB zurücksetzen testen starten einfach den Container neu.

Im Artikel auf SQL Server für Linux interagiert ich mit der Datenbank nur Sqlcmd an der Befehlszeile verwenden. In einem aktuelleren Artikel (msdn.com/magazine/mt832858), ich Azure Data Studio für die Interaktion mit einem Container ausgeführte SQL Server und Datenbank verwendet. Jetzt möchte ich auf einem dedizierten, Container ausgeführte SQL-Server in meinem-API-Entwicklung zu integrieren. Ich zeige Ihnen wie Sie dazu in Visual Studio mit dem im vorigen Artikel verwendete Beispiel fortfahren.

Kurze Übersicht über die API

Die API ist einfach, mit einer einzelnen Eigenschaft zwei Magazine-Klasse (Id und Name), einen Controller Zeitschriften und ein EF Core-DbContext, die Migrationen verwendet, um neue Datenbanken mit vier Zeitschriften zu starten.

Die nächste Iteration der app in Teil 2 dieser Reihe (msdn.com/magazine/mt833438), containerorchestrierung über eine docker-Compose-Datei, eingeführt. Bei der, die eine Lösung für die einzelnen-Containers ist, die tatsächlich die Orchestrierung nicht nötig, Docker-compose-boten die Möglichkeit, um Umgebungsvariablen in den Container zu übergeben, ohne die Werte direkt in der Abbildung zu speichern. Aber selbst bei einzelnen-Containers-Lösungen kann eine Compose-Datei zum Ausführen der app in einem Docker Swarm oder Kubernetes-Cluster, sodass Sie von Skalierung und Selbstreparatur verwendet werden.

Die MagazinesContext-Klasse verwendet die Umgebungsvariablen, ein Kennwort für die Datenbank-Verbindungszeichenfolge einzufügen.

Verschieben in einen Container-Datenbank

Das Ziel dieses Artikels ist für einen SQL Server für Linux-Server und einer Datenbank in Containern auf meinem Entwicklungscomputer anzugeben. Dies bedeutet Aktualisieren der vorhandenen docker-Compose-Datei, und Aktualisieren von Verbindungszeichenfolgen in der app. In allen, nicht sehr aufwändig. Aber wenn Sie zuvor noch nie verwendet haben, es ist sicherlich gut, wenn ein Benutzer zu zeigen, wie Sie haben!

Die größten Änderungen werden in die Datei "Docker-Compose.yml". Und sehr "cool" ist, dass Docker die schwierigsten Teile, kümmern wird einfach durch Lesen die Anweisungen weitergeleitet, die in Docker-compose. Da all dies wird in Visual Studio 2017 gestartet, werden die enthaltenen Tools für Docker auch beteiligen, beim Ausführen oder in Visual Studio debuggen. Wenn Sie Visual Studio-2019 verwenden (die, während ich dies schreibe offiziell nur gestern, freigegeben wurde, damit diese Reihe in 2017 weiter), die Tools integriert ist, und die Oberfläche sollte identisch sein.

So sieht die vorherige Version der Datei "Docker-Compose.yml" aus:

version: '3.4'
services:
  dataapidocker:
    image: ${DOCKER_REGISTRY-}dataapidocker
    build:
      context: .
      dockerfile: DataAPIDocker/Dockerfile
    environment:
      - DB_PW

Diese docker-Compose-Datei wurde nur mit einem Bild, das in der Dataapidocker Dienst definierten verwalten. Das Tool stellt sicher, dass die DOCKER_REGISTRY Variable zur Laufzeit ersetzt wird, mit der Docker-Engine, die auf meinem Entwicklungscomputer ausgeführt wird. Klicken Sie dann findet mithilfe des Abbilds, die dockerfile-Datei (definiert in sowohl Teil 1 und Teil 2 dieser Serie), erhalten weitere Anweisungen darüber, was Sie mit dem Image, wenn der Containerinstanz erstellt wird. Da ich einen Wert für die Umgebungsvariable DB_PW, direkt in der docker-Compose-Datei angegeben haben, kann ich einen Wert aus der Shell, in dem ich den Container ausführe, oder aus einer anderen Quelle, z. B. eine Docker-env-Datei übergeben werden sollen. Ich habe verwendet eine env-Datei in Teil 2 zum Speichern von Schlüssel-Wert-Paar DB_PW und mein Kennwort, Eiluj.

Also jetzt werde ich Teilen Sie Docker-compose-, dass ich auch veranlassen, dass ein SQL Server-Container einrichten möchten. Der SQL Server für Linux-Image ist offizielles Image in der Microsoft Container Registry (MCR), obwohl er auch auf Docker Hub für die Erkennbarkeit aufgeführt ist. Durch Verweisen auf finden sie hier, Docker sucht zuerst in der lokalen Registrierung (auf dem Entwicklungscomputer, in denen ich arbeite) und wenn es das Image nicht gefunden wird, wird es dann aus der MCR pull für das Image. Finden Sie unter Abbildung1 ein Beispiel für diese Änderungen.

Abbildung 1 der-Docker-Compose-Datei ändert sich in einem Mssql/Server-Container

version: '3.4'
services:
  dataapidocker:
    image: ${DOCKER_REGISTRY-}dataapidocker
    build:
      context: .
      dockerfile: DataAPIDocker/Dockerfile
    environment:
      - DB_PW
    depends_on:
      - db
  db:
    image: mcr.microsoft.com/mssql/server
    environment:
      SA_PASSWORD: "${DB_PW}"
      ACCEPT_EULA: "Y"
    ports:
      - "1433:1433"

Allerdings wird der neue Dienst hinzugefügt wurde, die ich Db genannt, mehr als nur zum Mssql/Server-Image. Lassen Sie uns, wie sie b. z. Entpacken Sie die Änderungen aus. Bedenken Sie, dass eine andere Änderung verfügbar, nachdem ich diesen Schritt durcharbeiten vorhanden ist.

Die erste Änderung ist innerhalb des Diensts Dataapidocker – ursprüngliche derjenige, der den Container für die API zu beschreiben. Ich habe eine Zuordnung wird aufgerufen, Depends_on, was YAML als ein Sequence-Element, das mit dem Namen Db bezeichnet enthält hinzugefügt. Dies bedeutet, dass vor dem Ausführen des Dataapidocker-Containers, Docker Docker prüft-compose-Datei für einen anderen Dienst, mit dem Namen Db und müssen die Details zu verwenden, um den Container definiert, die von diesen Diensten zu instanziieren.

Der Db-Dienst beginnt mit dem auf der SQL Server für Linux-Image mit dem offiziellen Docker-Namen verweist. Dieses Image ist erforderlich, dass Sie zwei Umgebungsvariablen übergeben, bei der Ausführung eines Containers – SA_Password und ACCEPT_EULA – also die Beschreibung des Diensts auch diese Informationen enthält. Und schließlich müssen Sie den Port angeben, dem der Server verfügbar sein soll: 1433:1433. Der erste Wert bezieht sich auf den Host Port und das zweite an den Port im Container. Verfügbarmachen von dem Server über den Host der Standardport 1433 erleichtert Ihnen Zugriff auf die Datenbank auf dem Hostcomputer. Ich zeige Ihnen, wie dies funktioniert, nachdem ich das Projekt einsatzbereit erhalten haben.

Wenn es Zeit für die Ausführung ist Docker-compose-außerhalb von Visual Studio, muss ich auch Ports aus dem Dataapidocker-Dienst verfügbar machen. Visual Studio-Tools erstellt eine zweite docker-Compose-Datei, Docker-compose.override.yml, mit denen Visual Studio während der Entwicklung. In dieser Datei sind einige zusätzliche Zuordnungen, einschließlich der Ports zuordnen (Ports:: 80) für den Dienst Dataapidocker. Also überlassen wir es jetzt die Tools, die Betreuung der auswähle, um die Website zu suchen, beim Debuggen in Visual Studio nutzen.

Definieren ein separates Volume für persistente Daten

Es ist sogar noch mehr Arbeit durchgeführt werden, Docker-compose jedoch. Mit der vorhandenen Beschreibung werden aller Datenbanken und die Daten innerhalb desselben Containers erstellt, die der SQL Server ausgeführt wird. Dies ist wahrscheinlich kein Problem zum Testen, ob eine fehlerfreie Datenbank für jeden Test erforderlich ist. Es ist empfehlenswert, jedoch die Daten separat beibehalten werden. Es gibt einige Möglichkeiten zur Verfügung, aber ich verwende hier genannten ein Datenvolume. Sehen Sie sich mein Blogbeitrag unter bit.ly/2pZ7dDb, wobei ich im Detail behandelt Datenvolumes und veranschaulichen, wie sie bleiben, auch wenn Sie beenden oder des Containers entfernen, der SQL Server ausgeführt wird.

Lassen Sie in der docker-Compose-Datei für die Beibehaltung der Daten getrennt von den SQL Server-Container, ein Volume angeben, wie schon Anweisungen abbildung2. Ein Volume stimmt nicht mit einem Container, damit es sich um einen anderen Dienst nicht. Stattdessen erstellen Sie einen neuen Schlüssel namens Volumes, die einen gleichgeordneten Knoten zu Diensten. In dem Schlüssel bieten Sie Ihren eigenen Namen für das Volume (Ich habe mir Mssql-Server-Julie-Daten genannt). Es wird kein Wert, der diesem Schlüssel zugeordnet ist. Benennen ein Volume auf diese Weise können Sie bei Bedarf für andere Container wiederzuverwenden. Erfahren Sie mehr über die Volumes in der Docker-Referenz für Docker-compose auf docs.docker.com/compose/compose-file und weitere Details finden Sie in Elton Stonemans Pluralsight-Kurs zu zustandsbehafteten Daten mit Docker (pluralsight.pxf.io/yoLYv).

Abbildung 2: Definieren eines Datenvolumes im Docker-Compose

services:
  dataapidocker: [etc]
  db:
    image: mcr.microsoft.com/mssql/server
    volumes:
      - mssql-server-julie-data:/var/opt/mssql/data
    environment:
      SA_PASSWORD: "${DB_PW}"
      ACCEPT_EULA: "Y"
    ports:
      - "1433:1433"
volumes:
  mssql-server-julie-data: {}

Beachten Sie, dass die datenbankzuordnung auch eine neue Zuordnung für Volumes verfügt. Diese Zuordnung enthält ein Sequence-Element, in dem ich den benannten Datenträger in einen Zielpfad in den Quellcontainer zugeordnet haben, in dem die Daten- und Protokolldateien-Datenbankdateien gespeichert werden sollen.

Die Verbindungszeichenfolge einrichten für den Container ausgeführte SQLServer

Zur Erinnerung: Links in der vorherigen Version der app, ich eine Verbindungszeichenfolge nach SQL Server LocalDB in "appSettings". Development.JSON für Zeiten möchte ich die API ausgeführt wird, in der Kestrel oder lokalen IIS-Server zu testen.  Die Verbindungszeichenfolge für Azure SQL-Datenbank, mit dem Namen ConnectionStrings:MagsConnectionMssql, befindet sich in einer Umgebungsvariablen in die API dockerfile-Datei direkt über den Abschnitt, der das buildimage definiert. Hier sind die ersten Zeilen der dieser dockerfile-Datei. Die Verbindungszeichenfolge enthält Platzhalter für den Benutzer-Id und das Kennwort an. Die Benutzer-Id ist noch in der dockerfile-Datei, nur weil ich durch das Ausblenden des Kennworts konzentrieren und diese noch nicht entfernt wurde noch:

FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
ENV ConnectionStrings:MagsConnectionMssql="Server=[Azure SQL endpoint];
    Initial Catalog=DP0419Mags;Persist Security Info=False;
    User ID=ENVID;Password=ENVPW;MultipleActiveResultSets=False;
    Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
ENV DB_UserId="lerman"
FROM microsoft/dotnet:2.2-sdk AS build

Diese Verbindungszeichenfolge kann ganz einfach zu "Docker-Compose.yml" verschoben und externen Art und Weise, wie gut gesteuert werden. Die API Startkonfiguration Methode überschreibt die Platzhalter für Benutzer und Kennwort mit den Werten der angegebenen Umgebungsvariablen, einschließlich des Kennworts DB_PW, die ich in the.env-Datei gespeichert, deren Inhalt wie folgt aussehen:

DB_PW=eiluj

Der env-Datei und dessen DB_PW-Wert gelesen werden vom Docker-compose, und übergeben in den Container für die dockerfile-Datei zum Lesen und die app zur Verfügung stellen. Am Ende werde ich die Verbindungszeichenfolge und die DB_UserId Variablen aus der dockerfile-Datei entfernt.

Aber, dass die Verbindungszeichenfolge für Azure SQL war. Ich muss nun so ändern Sie den Wert, um auf den SQL Server-Container zu verweisen:

ENV ConnectionStrings:MagsConnectionMssql
  "Server=db;Database=DP0419Mags;User=sa;Password=ENVPW;"

Ich verwende den gleichen Variablennamen, denn das ist was Startup.ConfigureServices erwartet wird. Was mir interessant, ist, dass die containerlaufzeit, der Name verstehen wird der Datenbank Dienste, die Docker-compose-als Servernamen ein. In der Verbindungszeichenfolge angegeben ist, kann ich also den Server als Datenbank angeben. Der Standardbenutzer, den das Mssql/Server-Image verwendet, um den Server einzurichten ist sa, damit ich codiert haben, direkt in der Verbindungszeichenfolge der ist Grund, warum ich eine ENV-Variable für die Benutzer-Id nicht mehr benötigen. Allerdings verwende ich immer noch einen Platzhalter, ENVPW, für das Kennwort ein.

Wie bei dem Beispiel in der vorherigen Spalte wird der Platzhalter durch den Wert der Umgebungsvariablen DB_PW letztendlich ersetzt. So sieht der Code jetzt wie, die liest die Verbindungszeichenfolge und die DB_PW-Variable, und aktualisiert dann die Verbindungszeichenfolge vor der Übergabe an dem SQL Server-Anbieter:

public void ConfigureServices(IServiceCollection services)
{
  services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
  var config = new StringBuilder(
    Configuration["ConnectionStrings:MagsConnectionMssql"]);
  string conn = config.Replace("ENVPW", Configuration["DB_PW"])
                      .ToString();
  services.AddDbContext<MagContext>(options => options.UseSqlServer(conn));
}

Sie haben alle erforderlichen Änderungen. Jetzt sehen wir Debuggen und was passiert.

Debuggen mit der Datenbankcontainer

Stellen Sie sicher, dass der Docker-compose-Projekt ist das Startprojekt in der Projektmappe, und, dass die Schaltfläche "Debuggen" auf die Erstellung über Docker festgelegt wird, drücken Sie F5, um die API zu debuggen.

Wenn dies das erste Mal ist, die Sie die app ausführen haben auf diese Weise, und Sie nie das Mssql/Server-Image, abgerufen, das zuerst ausgeführt werden.  SQL Server-Image nicht klein – 1,45 GB ist. Also, Sie, per Pull, zum ersten Mal etwas Geduld. Beachten Sie, dass sie 2 GB RAM erfordert, daher Sie sicher, dass ausreichend Arbeitsspeicher für die Ausführung Ihrer Docker-Engine (in der Docker-Einstellungen) zuweisen. Dennoch ist es möglich, dies ist immer noch schneller als die Installation von SQL Server auf Ihrem Computer, und es verwendet nur den bereits zugewiesene Ressourcen Docker nicht zusätzliche Ressourcen auf dem Hostcomputer. Und sobald das Bild vorhanden ist, ist die Bereitstellung – locker und viele Instanzen in Betrieb. Ein weiterer Vorteil ist, dass alle Updates für das Basisimage als kleine Ebenen, nicht die ganze Sache erneut entnommen werden. Beachten Sie, dass die Microsoft/Dotnet-SDKs und der Aspnetcore-Runtime-Images sind bereits auf meinem System aufgrund der Arbeitsprofils habe ich in den vorherigen Spalten.

Wenn Sie die Ausgabe des Buildvorgangs ansehen, sehen Sie, dass die app das Datenvolumen vor der Verarbeitung des Mssql-Server-Containers erstellt, in meinem Fall "Verarbeitung" bedeutet, dass zuerst von Docker Hub bezogen, da sie noch nicht mit meinem System ist. Diese Reihenfolge der Vorgänge tritt auf, da der Server auf dem Volume, abhängig ist, damit die Volumes zuerst Maßnahmen ergriffen ruft. Sobald das geschehen ist, startet es die API Abbild erstellen, falls erforderlich, und klicken Sie dann der Container startet. Die Schritte werden eindeutig in der Buildausgabe, Dank der Tools übertragen.

Wie bei früheren Versionen von dieser app, werden die Ergebnisse der GET-Methode des Controllers Zeitschriften in einem Browserfenster angezeigt.

Untersuchen die Container erstellt von Docker-compose

Jetzt sehen wir uns an, was mit Docker vor sich geht. Die in der Befehlszeile, mache ich auch die Docker-Erweiterung für Visual Studio Code coole Möglichkeit hierfür ist.

Zunächst werde ich die Images mit Docker-Images den Befehl auflisten. Wenn Sie mit der Docker CLI vertraut sind, empfiehlt es sich, die expliziter Befehl Docker-Image ls verwenden. Siehe können Abbildung 3, zeigt, dass das Mssql-Image jetzt auf meinem Computer und eine neue Version des mein Dataapidocker-Image, ebenfalls erstellt wurde.

Überprüfen die Bilder
Abbildung 3 überprüfen die Bilder

Als Nächstes werden die Container mit docker.PS "," die verkürzte Entsprechung des Docker-Container ls ausgecheckt werden. Diese Ausgabe breit ist, damit ich die linke Hälfte des Bildschirms oben in der rechten Hälfte zeige Abbildung 4.

Die Container ausgeführt wird

Die Container ausgeführt wird
Abbildung 4: die Container ausgeführt wird

Und schließlich um das Volume, das erstellt wurde, finden Sie unter der jetzt an der Db-Container gebunden ist, verwende ich die können die Docker-Volume-Lscommand Siehe Abbildung 5.

Der Befehl "Docker-Volume"
Abbildung 5: der Befehl "Docker-Volume"

Beachten Sie, dass die Namen der sowohl als auch das Volumen für Daten mit dem gleichen Text, der von den Visual Studio-Debug-Prozess in Kombination mit den Tools generierte eingeleitet werden.

Denken Sie daran, dass ich die Datenbank aus dem Container Host Port 1433 verfügbar gemacht haben, damit ich Tools auf meinem Entwicklungscomputer verwenden kann, auf dem Server zu suchen, die in der Db-Container, zusammen mit den Datenbanken auf dem angeschlossenen Volume befindet. Ich verwende Studio für Azure Data, um Sie zu diesem Zweck; Abbildung 6 veranschaulicht, wie ich die Verbindung definiert.

Das Herstellen einer Verbindung mit meiner Datenbank in Containern
Abbildung 6: Einrichten einer Verbindungs mit meiner Datenbank in Containern

Mit der Verbindung, die vorgenommen wird kann ich dann mit dem Server und meine neue Datenbank interagieren. Abbildung 7 zeigt den Datenbank-Explorer auf der linken Seite, zusammen mit einer Abfrage wird daraufhin auf der rechten Seite.

Interagieren mit der Container-Datenbank in Azure Data Studio
Abbildung 7, die Interaktion mit der Container-Datenbank in Azure Data Studio

Ihrer App-Container sind bereit für die Aktion

Müssen Ihre apps in Docker-Images gekapselt ist es so einfach die apps und alle ihre Abhängigkeiten als Container bereitzustellen. Aber für die Container-Einsteiger und Experten gleichsam, ich denke, dass mit den Tools zum Entwickeln von apps, sodass sie bereits mit Bildern und Orchestrierung verknüpft sind die Nutzung der Container so viel einfacher macht. Und in dieser Serie konzentriere ich mich auf die Entwicklung und das lokale Debuggen. Gemäß Teil 2, habe ich einen Blogbeitrag zum Bereitstellen der Lösung für Einzelabbilder für Azure zum Testen zur veröffentlicht bit.ly/2CR40x3. Diese Lösung speichert die Daten in Azure SQL-Datenbank, und ich den Testcontainer mit Azure Container Instances ausgeführt. Ich habe auch einen Blogbeitrag zur Veröffentlichung der Dataapidocker-Image auf Docker Hub in diesem Artikel, und klicken Sie dann die vollständige Lösung in einer Linux-VM in Azure wird eine weitere hervorragende Möglichkeit zum Testen Ihrer orchestrierten Container-hosting. Dieser Blogbeitrag finden Sie unter bit.ly/2VBaN8M.


Julie Lerman ist Microsoft Regional Director, Microsoft MVP, Coach für das Softwareteam und Unternehmensberaterin. Sie lebt in den Bergen von Vermont. Sie hält bei User Groups und Konferenzen in der ganzen Welt Vorträge zum Thema Datenzugriff und zu anderen Themen. Julie Lerman führt unter thedatafarm.com/blog einen Blog. Sie ist die Autorin von „Programming Entity Framework“ sowie der Ausgaben „Code First“ und „DbContext“ (alle bei O’Reilly Media erschienen). Folgen Sie ihr auf Twitter: @julielerman, und sehen Sie sich ihre Pluralsight-Kurse unter bit.ly/PS-Julie an.

Unser Dank gilt den folgenden technischen Experten für die Durchsicht dieses Artikels: Elton Stoneman (Docker), Travis Wright (Microsoft)


Diesen Artikel im MSDN Magazine-Forum diskutieren