Teambasierter Datenschutz unter Verwendung von IAM, VPC, Transit Gateway und DNS

Für dieses Lernprogramm können Kosten anfallen. Mit dem Kostenschätzer können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung generieren.

Mikroservices sind beliebt, weil sie es einem Unternehmen ermöglichen, ihre Entwicklungsteams rund um die von ihnen entwickelten Services zu organisieren. Dieses Tutorial führt Sie durch die Schritte zur Erstellung der Infrastruktur für eine IBM Cloud® Virtual Private Cloud (VPC) basierte Microservice-Architektur. In dieser Architektur sind die VPCs über IBM Cloud® Transit Gateway miteinander verbunden. Auf eine Reihe gemeinsam genutzter Mikrodienste wird über Hostnamen zugegriffen, die in der IBM Cloud® DNS Services registriert sind. Jede VPC wird von einem separaten Team verwaltet, das von IBM Cloud® Identity and Access Management isoliert wurde. Optional kann ein IBM Cloud® Load Balancer verwendet werden, um den gemeinsamen Microservice zu skalieren.

Ziele

  • Vorgehensweise zum Isolieren der Infrastruktur mithilfe von IAM und Ressourcengruppen
  • Erstellen der VPCs und zugehörigen Ressourcen, wie z. B. Teilnetze, Netz-ACLs, Sicherheitsgruppen oder Instanzen.
  • Adressierung von Microservices durch DNS-Namensauflösung mit DNS Services.
  • Verbinden von VPCs über Transit Gateway.
  • Transparente Konfiguration eines Load Balancer für eine Anwendung.

Kurzdarstellung der Architektur

des

Im obigen Diagramm greift der Endbenutzer auf die Anwendungen zu. Die Anwendungen nutzen gemeinsam genutzte Microservices. Das Unternehmen verfügt über separate Entwicklungsteams, die Eigner von application1, application2 und shared sind. Ein Netzwerk-Team konzentriert sich auf Konnektivität und Netzwerksicherheit. Die Entwicklungsteams verwalten Instanzen virtueller Services oder VSIs, die zum Bereitstellen der Services verwendet werden, die die Teams erstellen und unterstützen.

Konkrete Architektur

Die folgende Architektur setzt die Anforderungen an Isolation und Konnektivität um, die von dem Unternehmen festgelegt werden. Beachten Sie, dass es sich bei application1, shared und application2 um VPCs handelt. Die einzelne Zone und das Teilnetz in jeder VPC können im Laufe der Zeit zu einer detaillierteren Bereitstellung mit mehreren Zonen erweitert werden.

Architektur des Lernprogramms
Architektur des Lernprogramms

Vorbereitende Schritte

Für dieses Lernprogramm ist Folgendes erforderlich:

  • IBM Cloud-CLI mit den folgenden Plug-ins:
    • Transit Gateway (tg)
    • IBM Cloud VPC (vpc-infrastructure)
    • DNS Services (dns)
  • git zum Klonen des Quellcode-Repositorys
  • terraform zum Ausführen der Terraform-Befehle.

Anleitungen zum Herunterladen und Installieren dieser Tools für Ihre Betriebsumgebung finden Sie in der Anleitung Erste Schritte mit Lösungs-Tutorials.

Darüber hinaus:

  • Überprüfen Sie die Benutzerberechtigungen. Stellen Sie sicher, dass Ihr Benutzerkonto über die entsprechenden Berechtigungen verfügt, um VPC-Ressourcen erstellen und verwalten zu können. Erstellen Sie IBM Cloud® Transit Gateway und einen IBM Cloud® Transit Gateway-Service. Weitere Informationen bietet die Liste der erforderlichen Berechtigungen für VPC. Sie benötigen auch die Möglichkeit, Ressourcengruppen und IAM-Ressourcen wie Zugriffsgruppen, Richtlinien, Service-IDs, ... zu erstellen.
  • Sie benötigen einen SSH-Schlüssel für die Herstellung einer Verbindung zu den virtuellen Servern. Wenn Sie noch keinen SSH-Schlüssel besitzen, befolgen Sie die Anweisungen zum Erstellen eines Schlüssels für VPC.

IAM (Identity and Access Management)-Umgebung planen

Das Team 'admin' aktiviert für die anderen Teams so weit es geht die Verwaltung ihrer Ressourcen. Das Team 'admin' verwaltet die Benutzer und steuert den Zugriff, erstellt und vernichtet jedoch nicht die Ressourcen, die im Architekturdiagramm dargestellt sind.

Bearbeiter, Operator, Anzeigeberechtigter und Manager sind IAM-Zugriffsrollen. Jeder Service definiert die genaue Bedeutung der Rollen und der zugehörigen Aktionen.

Teams:

  • admin: definiert die Kontenstruktur, z. B. Ressourcengruppen, Zugriffsgruppen, Benutzer und Rollen.
  • Netz - Netzressourcen wie DNS Services, Transit Gateway-Service, VPC und Teilnetze erstellen.
  • shared: erstellt VSI und blockiert Geräte in der gemeinsam genutzten VPC. erstellt DNS-Datensätze für gemeinsam genutzte Services.
  • application1: erstellt VSI und blockiert Geräte in der VPC 'application1'.
  • application2: erstellt VSI und blockiert Geräte in der VPC 'application2'.

Die Konzeption von IAM

Team 'network'

Es wurde ein konzeptionelles Modell für Teameigentumsrechte implementiert. Das Team network verwaltet alle Netzressourcen und damit die meisten der im Diagramm gezeigten Ressourcen.

Architektur mit Schwerpunkt auf dem Netzteam
Architektur mit Schwerpunkt auf dem Netzteam

Team 'shared'

Das Team shared erstellt die VSI in ihrer isolierten VPC. Darüber hinaus muss das Team Einträge in den DNS-Dienst schreiben, da die IP-Adressen der VSI zum Zeitpunkt der Erstellung festgelegt werden. Operator-Zugriff auf die VPC, die Teilnetze und Sicherheitsgruppen ist für die Erstellung einer VSI erforderlich.

Architektur mit Schwerpunkt auf dem gemeinsam genutzten Team
Architektur mit Schwerpunkt auf dem gemeinsam genutzten Team

Die Teams application benötigen denselben Zugriff wie das gemeinsam genutzte Team, außer Managerzugriff auf DNS Services.

Zugriff der application-Teams:

Architektur mit Schwerpunkt auf dem Anwendungsteam
Architektur mit Schwerpunkt auf dem Anwendungsteam

IAM-Architektur

Wenn Sie über gute Kenntnisse der Ressourcengruppen und IAM-Zugriffsgruppen verfügen, können Sie diesen Abschnitt einfach überfliegen und mit den Schritten zur Erstellung der Ressourcen beginnen.

Zugriffsgruppen

Für jedes Team wird eine Zugriffsgruppe erstellt. Den Zugriffsgruppen werden Zugriffsrichtlinien hinzugefügt und anschließend werden der Zugriffsgruppe Benutzer (Teammitglieder) hinzugefügt, um Zugriff zu erteilen.

Die Transit Gateway-Serviceinstanz wird ausschließlich vom Team network verwaltet. Für die Erstellung ist Bearbeiterzugriff erforderlich. Managerzugriff auf die erstellte Instanz ermöglicht die Verbindung der VPCs mit Transit Gateway.

In diesem Beispiel wird eine einzelne DNS-Zone widgets.example.com erstellt und der Zugriff auf die DNS-Zone wird allen VPCs gestattet. Die DNS-Serviceinstanz wird vom Team network (Bearbeiterrolle) erstellt. Um den Zugriff auf die Zonen zu erteilen, ist die Managerrolle erforderlich. Die DNS-Auflösung zur Laufzeit in einer Instanz auf einer VPC erfordert keinen IAM-Zugriff. Das gemeinsam genutzte Team muss die DNS-Instanzen auflisten (Rolle "Anzeigeberechtigter") und einen A- oder CNAME-Datensatz hinzufügen (Rolle "Manager").

Der VPC-Infrastructure Service (IS) besteht aus etwa 15 unterschiedlichen Servicetypen. Einige sind nur für das Netzwerkteam von Bedeutung, wie z. B. Netzwerk-ACLs (Access Control Lists). Andere sind nur für die Microservice-Teams von Bedeutung, wie VSI-Instanzen. Einige werden jedoch vom Netzwerkteam bearbeitet und vom Microservice-Team betrieben, wie zum Beispiel Subnetze. Das Netzwerkteam erstellt das Subnetz und ein Microservice-Team erstellt eine Instanz in einem Subnetz. Für die Zwecke dieses Lernprogramms werden die VPC-IS-Servicetypen, Transit Gateway und DNS für jede Zugriffsgruppe in der folgenden Tabelle zusammengefasst. Der Inhalt der Tabelle stellt die erforderliche Rolle dar.

Erforderliche Rollen, die Teams basierend auf ihren Zuständigkeiten zugewiesen werden
Service network shared Anwendung
Transit Gateway Bearbeiter, Manager
DNS Bearbeiter, Manager Anzeigeberechtigter, Manager
IS: Netz-ACL Bearbeiter
IS: Instanz, Datenträger, variable IP-Adresse, SSH-Schlüssel, Image, Load Balancer Bearbeiter Bearbeiter
IS: VPC, Teilnetz, Sicherheitsgruppe Bearbeiter Operator Operator

Ressourcengruppen

Das Team shared und das Team network sind jetzt deutlich voneinander getrennt. Aber wie wird 'application1' von 'shared' und 'application2' isoliert? Sie sind Bearbeiter für die gleichen Servicetypen.

An dieser Stelle können Ressourcengruppen weiterhelfen. Jede Dienstinstanz (d. h. Ressource) hat ein Ressourcengruppenattribut, das bei der Erstellung initialisiert wird und nicht geändert werden kann. Mit anderen Worten: Jede Ressource gehört zu einer Ressourcengruppe.

Ressourcengruppendiagramm:

Ressourcengruppendiagramm
Ressourcengruppendiagramm

Jedem Microservice-Team wird der Zugang in der entsprechenden Ressourcengruppe gewährt. Das Netzteam hat Zugriff auf alle derartigen Ressourcengruppen.

Die Netzressourcengruppe enthält Transit Gateway und den DNS-Service. Das Netzteam hat Zugriff auf diese Ressourcen. Das gemeinsame Team hat als Manager Zugriff auf den DNS-Dienst. Das gemeinsam genutzte Team muss die DNS-Einträge für die gemeinsam genutzten Services schreiben.

Später im Tutorial, nachdem alle Ressourcen erstellt wurden, kann es informativ sein, die Ressourcenliste in der Konsole IBM Cloud zu öffnen. Die Ressourcengruppe kann gefiltert werden.

Lokale Arbeitsumgebung erstellen

Alle Operationen werden in einer bash Shell und unter Verwendung der Befehle terraform und ibmcloud durchgeführt. Anleitungen zum Herunterladen und Installieren dieser Tools für Ihre Betriebsumgebung finden Sie in der Anleitung Erste Schritte mit Lösungs-Tutorials.

  1. Git Klonen Sie das folgende -Repository:

    git clone https://github.com/IBM-Cloud/vpc-tg-dns-iam
    cd vpc-tg-dns-iam
    

    Stellen Sie sicher, dass für jedes Team ein Verzeichnis vorhanden ist ('application2' wird vorerst übersprungen):

    • admin/
    • Netzwerk/
    • shared/
    • application1/
  2. Erstellen Sie die Datei terraform.tfvars :

    cp terraform.tfvars.template terraform.tfvars
    

    Bearbeiten Sie als Nächstes terraform.tfvars, um die folgenden Variablen festzulegen:

    • ssh_key_name- es muss ein vorhandener SSH-Schlüssel in der ibm_region angegeben werden, wie oben im Abschnitt Bevor Sie beginnen beschrieben.
    • ibm_region- ersetzen Sie den Standardwert us-south, falls erforderlich. Mit dem CLI-Befehl ibmcloud regions können alle möglichen Regionen angezeigt werden.
    • basename- ersetzen Sie den Standardwert widget0 durch einen Namen, der höchstens 7 Zeichen lang ist, falls erforderlich. Die meisten erstellten Ressourcen verwenden dies als Namenspräfix.
    • Entfernen Sie zu diesem Zeitpunkt nicht die Kommentarzeichen für transit_gateway oder shared_lb.
  3. Nur für Windows-Benutzer: Wenn git den symbolischen Link auf Ihrem Windows-Computer nicht erstellt, müssen Sie die Dateiinhalte in die Teamordner kopieren:

    cp variables.tf terraform.tfvars admin
    cp variables.tf terraform.tfvars network
    cp variables.tf terraform.tfvars shared
    cp variables.tf terraform.tfvars application1
    

Ein Hinweis über die Herstellung einer Teammitgliedschaft

Es ist möglich, die Zugriffsgruppe jedes Teams mit Benutzern zu befüllen. In diesem Lernprogramm werden jedoch keine Benutzer erstellt, sondern eine Dienst-ID in der Zugriffsgruppe jedes Teams angelegt. Sie sind der Administrator und werden ein Mitglied der verschiedenen Zugriffsgruppen, indem Sie den API-Schlüssel für die Service-ID für das Team verwenden. Die Service-ID-Namen lauten ${basename}-x. Dabei gibt x 'network', 'shared', 'application1' bzw. 'application2' an. Später füllen Sie eine Datei local.env in den Verzeichnissen jedes einzelnen Teams mit Inhalten ähnlich dem folgenden:

export TF_VAR_ibmcloud_api_key=0thisIsNotARealKeyALX0vkLNSUFC7rMLEWYpVtyZaS9

In jedem Schritt, wenn Sie cd in ein Teamverzeichnis gehen, werden Sie an die Ausführung erinnert: source local.env

Mit Terraform werden die Ressourcen erstellt. Öffnen Sie admin/main.tf und beachten Sie die Klausel provider ibm und den Verweis auf den ibmcloud_api_key, der aus der Umgebungsvariablen initialisiert wurde:

provider ibm {
 ibmcloud_api_key = var.ibmcloud_api_key # initialized with the TF_VAR_ibmcloud_api_key
}

Wenn Sie die IBM Cloud CLI als Teammitglied verwenden:

ibmcloud login --apikey $TF_VAR_ibmcloud_api_key

IAM-fähige Ressourcen erstellen (Team 'admin')

Das Team 'admin' muss über Administratorzugriff auf die IAM-fähigen Ressourcen in dem für dieses Lernprogramm verwendeten Konto verfügen. Weitere Informationen hierzu finden Sie unter Wie weise ich einem Benutzer die volle Zugriffsberechtigung als Kontoadministrator zu?. Das Administratorenteam ist für die Erstellung der IAM-Ressourcen verantwortlich. In den nachfolgenden Anweisungen wird der Befehl ibmcloud iam api-key-create verwendet, um einen API-Schlüssel für das Team 'admin' zu erstellen. Der API-Schlüssel wird von Terraform verwendet, um Tasks für Sie auszuführen.

Die PI-Schlüssel sind dasselbe wie ein Passwort für Ihr Konto. Verwahren Sie die API-Schlüssel sicher.

  1. Initialisieren und überprüfen Sie die Shellvariable 'basename'. Überprüfen Sie, ob sie mit dem Basisnamen in der Datei 'terraform.tfvars' übereinstimmt:

    eval $(grep basename terraform.tfvars | sed -e 's/  *//g' -e 's/#.*//')
    echo basename=$basename
    
  2. Wechseln Sie das Verzeichnis, generieren Sie Ihren persönlichen API-Schlüssel in 'local.env' und machen Sie ihn zur Quelle. Wenn Terraform aufgerufen wird, nimmt es Ihre Identität an. Terraform ist dann der Administrator:

    cd admin
    echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam api-key-create $basename-admin --output json | jq .apikey) > local.env
    cat local.env
    source local.env
    
  3. Die Anwendung der main.tf Terraform-Konfigurationsdatei erzeugt die folgenden Ressourcen:

    • Ressourcengruppen für jedes Team
    • Zugriffsgruppen für jedes Team und eine Service-ID in jeder Zugriffsgruppe
    • Zugriffsgruppenrichtlinien für die Ressourcengruppen
    • Zugriffsgruppenrichtlinie für die Ressourcen
    terraform init
    terraform apply
    
  4. Überprüfen Sie, ob die Ressourcen erstellt wurden:

    ibmcloud resource groups | grep $basename
    
    ibmcloud iam access-groups | grep $basename
    
    ibmcloud iam service-ids | grep $basename
    
    ibmcloud iam access-group-policies $basename-network
    

    Die Ausgabe ähnelt der folgenden:

    $ ibmcloud resource groups | grep $basename
    widget0-application2   36b06a303f224f28ad42aebbb491cc44   false           ACTIVE
    widget0-shared         91518c45e47a427fa4f63edb58e4f227   false           ACTIVE
    widget0-network        bf6e75cd71854576a31056abced2abf0   false           ACTIVE
    widget0-application1   db2f3dc8aacf4a6aa2d2fa07e795cb57   false           ACTIVE
    $ ibmcloud iam access-groups | grep $basename
    widget0-application1   AccessGroupId-26b7ef37-78db-4a2c-a2af-7f6591e73c15   application1 administrators
    widget0-application2   AccessGroupId-8afdec20-f760-4a15-8f3e-296d81818028   application2 administrators
    widget0-network        AccessGroupId-d50b129d-9adc-4fc4-b297-487b3f938ec5   network administrators
    widget0-shared         AccessGroupId-30d73f44-5602-47a7-846e-e6480c9dceff   shared administrators
    $ ibmcloud iam service-ids | grep $basename
    ServiceId-5e919b97-380c-4343-a337-3901cafbd956   widget0-application2                                                                                                       2020-07-15T21:25+0000   2020-07-15T22:03+0000   application 2 service id                                                                                                                                              false
    ServiceId-307df062-f4b7-45f8-8ec8-94ad1ed61730   widget0-network                                                                                                            2020-07-15T21:49+0000   2020-07-15T22:03+0000   network service id                                                                                                                                                    false
    $ ibmcloud iam access-group-policies $basename-network
    Retrieving all policies of access group widget0-network under account 8675309 as jenny@example.com
    OK
    
    Policy ID:   00ceb354-7360-4ad5-9fda-5c03e462c5c0
    Roles:       Editor
    Resources:
                 Resource Group ID     91518c45e47a427fa4f63edb58e4f227
                 Resource Group Name   widget0-shared
                 Service Name          is
                 flowLogCollectorId    *
                 Memo                  Policy applies to the resource(s) within the resource group
    
    Policy ID:   115ebe9f-eea0-4308-9e7f-bb887d64426b
    Roles:       Editor
    Resources:
                 Resource Group ID     db2f3dc8aacf4a6aa2d2fa07e795cb57
                 Resource Group Name   widget0-application1
                 Service Name          is
                 vpnGatewayId          *
                 Memo                  Policy applies to the resource(s) within the resource group
    ...
    
  5. Navigieren Sie optional zum Konto Ressourcengruppen und suchen Sie die Ressourcengruppen.

  6. Klicken Sie auf eine Zugangsgruppe und dann oben auf das Feld Service-IDs, um die erstellte Service-ID zu sehen.

VPCs und DNS erstellen (Team 'network')

Das Team network erstellt die Netzressourcen entsprechend der Architektur und stellt sicher, dass die Konnektivitätsziele erreicht werden und die Teams in ihrer VPC isoliert sind. Es will die Details der VPC-Instanzen nicht steuern. Es ist wahrscheinlich, dass die Anzahl der Anwendungen, die Größe der Computer, die DNS-Einträge für Microservices usw. einem ständigen Wandel unterworfen sind und dem Netzwerkteam keine Sorgen bereiten.

Das Team 'admin' hat ihm genau den richtigen Umfang an Berechtigungen zum Erstellen der VPC-is-Ressourcen, des DNS Services und des Transit Gateway-Service bereitgestellt.

  1. Wechseln Sie das Verzeichnis, erzeugen Sie einen API-Schlüssel im local.env und werden Sie Mitglied der Netzzugangsgruppe:

    team=network
    cd ../$team
    echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam service-api-key-create $team $basename-$team --output json | jq .apikey) > local.env
    cat local.env
    source local.env
    
  2. Optional können Sie die variables_network.tf öffnen und die CIDR-Blockspezifikation und das Zonenlayout beachten. Beachten Sie im folgenden Ausschnitt, dass die IP-Adressen von shared und application1 sich nicht überschneiden:

    variable network_architecture {
      default = {
        shared = {
          cidr        = "10.0.0.0/16"
          cidr_remote = "10.0.0.0/8"
          zones = {
            z1 = {
              zone_id = "1",
              cidr    = "10.0.0.0/24",
            }
            z2 = {
              zone_id = "2",
              cidr    = "10.0.1.0/24",
        ...
        application1 = {
          cidr        = "10.1.0.0/16"
          cidr_remote = "0.0.0.0"
          zones = {
            z1 = {
              zone_id = "1",
              cidr    = "10.1.0.0/24",
            }
            z2 = {
              zone_id = "2",
              cidr    = "10.1.1.0/24",
         ...
    

    Transit Gateway hat eine Verbindung zu jeder VPC und leitet den Datenverkehr basierend auf den CIDR-Bereichen weiter. Daher wird die Vermeidung von Überlappungen zum Erfolg führen.

  3. Erstellen Sie die Ressourcen:

    terraform init
    terraform apply
    
  4. VPC-Ressourcen auflisten

    Die erstellten VPC-Ressourcen werden wie unten (verkürzt) gezeigt durch die Ausgabe des Befehls 'subnets' zusammengefasst. Beachten Sie die drei VPCs, die sich nicht überschneidenden CIDR-Blöcke und die Mitgliedschaft in den Ressourcengruppen:

    ibmcloud target -r $(grep ibm_region terraform.tfvars | sed -e 's/  *//g' -e 's/#.*//' -e 's/.*=//' -e 's/"//g')
    ibmcloud is subnets --all-resource-groups | grep $basename
    

    Die Ausgabe sieht so aus:

    $ ibmcloud is subnets --all-resource-groups | grep $basename
    widget0-shared-z1           available   10.0.0.0/24    widget0-shared           us-south-1   widget0-shared
    widget0-shared-z2           available   10.0.1.0/24    widget0-shared           us-south-2   widget0-shared
    widget0-shared-z3           available   10.0.2.0/24    widget0-shared           us-south-3   widget0-shared
    widget0-application1-z1     available   10.1.0.0/24    widget0-application1     us-south-1   widget0-application1
    widget0-application1-z2     available   10.1.1.0/24    widget0-application1     us-south-2   widget0-application1
    widget0-application1-z3     available   10.1.2.0/24    widget0-application1     us-south-3   widget0-application1
    widget0-application2-z1     available   10.2.0.0/24    widget0-application2     us-south-1   widget0-application2
    widget0-application2-z2     available   10.2.1.0/24    widget0-application2     us-south-2   widget0-application2
    widget0-application2-z3     available   10.2.2.0/24    widget0-application2     us-south-3   widget0-application2
    
  5. Optional können Sie zu den Virtual Private Clouds navigieren und die VPCs, Subnetze und alle anderen oben erstellten Ressourcen finden.

  6. Optional können Sie die Terraform-Konfiguration in main.tf untersuchen, um die DNS Services Initialisierung zu verstehen. Die DNS Services-Instanz und -Zone wurden mit dem Terraform-Snippet erstellt:

    resource "ibm_resource_instance" "dns" {
      name              = "${var.basename}-dns"
      resource_group_id = data.ibm_resource_group.shared.id
      location          = "global"
      service           = "dns-svcs"
      plan              = "standard-dns"
    }
    
    resource "ibm_dns_zone" "widgets_example_com" {
      name        = "widgets.example.com"
      instance_id = ibm_resource_instance.dns.guid
      description = "this is a description"
      label       = "this-is-a-label"
    }
    

    Anschließend wird die Zone als zulässiges Netzwerk zu einer VPC hinzugefügt:

    resource "ibm_dns_permitted_network" "shared" {
      instance_id = ibm_resource_instance.dns.guid
      zone_id     = ibm_dns_zone.widgets_example_com.zone_id
      vpc_crn     = module.vpc_shared.vpc.crn
      type        = "vpc"
    }
    
    
  7. Listen Sie die DNS-Konfiguration auf. Eine DNS Services-Instanz wurde erstellt. Die Zone widgets.example.com wurde erstellt. Schließlich wurde die Zone zu allen VPCs hinzugefügt.

    ibmcloud dns instances
    
    ibmcloud dns zones -i $basename-dns
    
    zone_id=$(ibmcloud dns zones -i $basename-dns --output json | jq -r '.[] | .id')
    ibmcloud dns permitted-networks $zone_id -i $basename-dns
    

    Die Ausgabe sieht dann so aus:

    $ ibmcloud dns instances
    Retrieving service instances for service 'dns-svcs' ...
    OK
    Name          ID                                     Location   State    Service Name   
    widget0-dns   3b0d5546-5999-4c7e-a757-f5fd21dd44ed   global     active   dns-svcs   
    $ ibmcloud dns zones -i $basename-dns
    Listing zones for service instance 'widget0-dns' ...
    OK
    ID                                               Name                  Status   
    5a1a2295-1c38-49dd-9809-aaaf5a127e79c1b          widgets.example.com   ACTIVE   
    $ zone_id=$(ibmcloud dns zones -i $basename-dns --output json | jq -r '.[] | .id')
    $ ibmcloud dns permitted-networks $zone_id -i $basename-dns
    Listing permitted networks for zone '5a1a2295-1c38-49dd-9809-f5a127e79c1b' ...
    OK
    Name                   ID                                          Type   VPC_CRN                                                                                                               State   
    widget0-shared         r006-353208ab-4e95-46fb-934b-b5566cde8975   vpc    crn:v1:bluemix:public:is:us-south:a/713c783d9a507a53135fe6793c37cc74::vpc:r006-353208ab-4e95-46fb-934b-b5566cde8975   ACTIVE   
    widget0-application1   r006-287258c6-2eb3-4908-b326-6f03c3e47aa6   vpc    crn:v1:bluemix:public:is:us-south:a/713c783d9a507a53135fe6793c37cc74::vpc:r006-287258c6-2eb3-4908-b326-6f03c3e47aa6   ACTIVE   
    widget0-application2   r006-fa51e99e-bd93-4451-a4eb-76eed9939d3c   vpc    crn:v1:bluemix:public:is:us-south:a/713c783d9a507a53135fe6793c37cc74::vpc:r006-fa51e99e-bd93-4451-a4eb-76eed9939d3c   ACTIVE   
    
  8. Sie können auch zur Ressourcenliste navigieren und das DNS Services suchen, anklicken und untersuchen.

Erstellen Sie den gemeinsamen Microservice und den zugehörigen DNS-Eintrag (Shared Team)

  1. Wechseln Sie das Verzeichnis, erzeugen Sie einen API-Schlüssel im local.env und werden Sie Mitglied der gemeinsamen Zugriffsgruppe:

    team=shared
    cd ../$team
    echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam service-api-key-create $team $basename-$team --output json | jq .apikey) > local.env
    cat local.env
    source local.env
    
  2. Optional können Sie an dieser Stelle tiefer in den Terraform-Quellcode eindringen. Das gemeinsame Team wird Microservices bereitstellen. Auch wenn das Team network die gemeinsam genutzte VPC und einige Netzressourcen bereits erstellt, erstellt das Team shared die Instanz und wählt das Instanzprofil auf. Ein Linux-Konfigurationsscript und eine einfache Demo-Anwendung werden im Attribut 'user_data' bereitgestellt und im Abschnitt Team 'application' weiter unten beschrieben.

    Beachten Sie in main.tf diese beiden Ressourcen:

    locals {
      network_context = data.terraform_remote_state.network.outputs.shared
    }
    
    resource ibm_is_instance "vsishared" {
      name           = "${var.basename}-shared-vsi"
      vpc            = local.network_context.vpc.id
      resource_group = data.ibm_resource_group.shared.id
      zone           = local.network_context.subnets["z1"].zone
      keys           = [data.ibm_is_ssh_key.ssh_key.id]
      image          = data.ibm_is_image.image.id
      profile        = var.profile[var.generation]
    
      primary_network_interface {
        subnet = local.network_context.subnets["z1"].id
        security_groups = [
          local.network_context.security_group_outbound_all.id, # nodejs is not available on an IBM mirror
          local.network_context.security_group_ibm_dns.id,
          local.network_context.security_group_data_inbound.id,
        ]
      }
      user_data = module.user_data_app.user_data_centos
    }
    
    resource ibm_dns_resource_record "shared" {
      count = var.shared_lb ? 0 : 1 # shared load balancer?
      instance_id = local.network_context.dns.guid
      zone_id     = local.network_context.dns.zone_id
      type        = "A"
      name        = "shared"
      rdata       = ibm_is_instance.vsishared.primary_network_interface[0].primary_ip.address
      ttl         = 3600
    }
    

    Das obige local.network_context ist die Ausgabe, die vom Team network spezifisch für das Team shared generiert wird.

  3. Erstellen Sie die gemeinsam genutzten Ressourcen:

    terraform init
    terraform apply
    
  4. Optional können Sie zu den virtuellen Serverinstanzen für VPC navigieren und die gemeinsam genutzte Instanz suchen. Klicken Sie darauf und überprüfen Sie Folgendes:

    • Die Instanz verfügt über keine eingehende Konnektivität aus dem öffentlichen Internet (überprüfen Sie die Sicherheitsgruppen).
    • Suchen Sie die private IP-Adresse.
  5. Sie können auch zur Ressourcenliste navigieren und den Eintrag DNS Services suchen, darauf klicken und den DNS-Eintrag mit dem gemeinsamen Namen finden. Beachten Sie, dass der Wert die private IP-Adresse der Instanz ist.

Erstellen eines öffentlich zugänglichen Microservices für eine AnwendungApplication1 Team)

  1. Wechseln Sie das Verzeichnis, generieren Sie einen API-Schlüssel in 'local.env' und machen Sie sich zum Mitglied der Zugriffsgruppe 'application1':

    team=application1
    cd ../$team
    echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam service-api-key-create $team $basename-$team --output json | jq .apikey) > local.env
    cat local.env
    source local.env
    

    Die Ressourcen des Teams 'application1' haben starke Ähnlichkeit mit denen des Teams shared. Sie sind sogar etwas einfacher, da es nicht erforderlich ist, Datensätze in die DNS Services aufzunehmen. Die Anwendung verwendet die Adresse http://shared.widgets.example.com für den Zugriff auf den gemeinsamen Mikrodienst.

  2. Untersuchen Sie optional den Quellcode, der die CentOS initialisiert. Es wurde in einem Terraform-Modul erfasst, das von allen Teams während dieser Sondierungsphase gemeinsam genutzt wird.

    ../common/user_data_app/main.tf:

    locals {
      shared_app_user_data_centos = <<EOS
    #!/bin/sh
    curl -sL https://rpm.nodesource.com/setup_20.x | sudo bash -
    yum install nodejs -y
    cat > /app.js << 'EOF'
    ${file("${path.module}/app.js")}
    EOF
    cat > /lib/systemd/system/a-app.service << 'EOF'
    ${file("${path.module}/a-app.service")}
    EOF
    systemctl daemon-reload
    systemctl start a-app
    EOS
    }
    
    output user_data_centos {
      value = replace(local.shared_app_user_data_centos, "REMOTE_IP", var.remote_ip)
    }
    

    Ausführliche Erläuterung:

    • Node.js wird mit den Befehlen curl und yum installiert.
    • Die Node.js-Anwendung wird in /app.js gestellt.
    • Ein Services 'systemctl' wird für app.js erstellt.
    • Der Service wird gestartet.
  3. Optional untersuchen Sie den Inhalt von 'app.js'. Er hat zwei besonders interessante Abschnitte. Zunächst gibt es einen Link /info, der eine Beschreibung der Instanz liefert, auf der die Anwendung läuft. ../common/user_data_app/app.js:

    const server = http.createServer((req, res) => {
      switch(req.url) {
      case '/info':
        res.statusCode = 200;
        res.setHeader('Content-Type', 'application/json');
        res.end(JSON.stringify({
          req_url:  req.url,
          os_hostname:  os.hostname(),
          ipArrays: ips()
        }, null, 3));
        break
      case '/remote':
        getRemote(req, res)
        break
    

    Zweitens ruft der /remote-Link die IP eines entfernten Servers auf und gibt die Beschreibung dieses entfernten Servers zusammen mit den Adressen remote_url und remote_ip zurück, die für den Zugriff auf den entfernten Server verwendet werden.

    const IP='REMOTE_IP'
    
    function getRemote(req, res) {
      path = '/info'
      remote_url = 'http://' + IP + ':3000' + path
      http.get(remote_url, (resp) => {
        let rawData = '';
        resp.on('data', (chunk) => { rawData += chunk; });
        resp.on('end', () => {
          try {
            console.log(rawData)
            rawObj = JSON.parse(rawData)
            res.statusCode = 200;
            res.end(JSON.stringify({remote_url: remote_url, remote_ip: resp.connection.remoteAddress, remote_info: rawObj}, null, 3))
    

    In unserem Fall wird die REMOTE_IP shared.widgets.example.com sein, weil die folgenden Angaben in common/user_data_app/main.tf:

    output user_data_centos {
      value = replace(local.shared_app_user_data_centos, "REMOTE_IP", var.remote_ip)
    }
    

    Wieder in 'application1/main.tf':

    module user_data_app {
      source    = "../common/user_data_app"
      remote_ip = "shared.widgets.example.com"
    }
    
  4. Erstellen Sie die Ressourcen:

    terraform init
    terraform apply
    

    Die Ergebnisse sehen ungefähr wie folgt aus:

    $ terraform apply
    ...
    Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
    
    Outputs:
    
    ibm1_private_ip = "10.1.0.4"
    ibm1_public_ip = "52.116.140.202"
    test_info = "curl 52.116.140.202:3000/info"
    test_remote = "curl 52.116.140.202:3000/remote"
    

    Probieren Sie die beiden oben vorgeschlagenen curl-Befehle (test_info, test_remote) aus. Kopieren Sie die Anweisungen aus Ihrer Ausgabe.

    curl 52.116.140.202:3000/info
    

    Die erste ergibt etwas wie das, was unten erfasst wurde:

    {
       "req_url": "/info",
       "os_hostname": "widget0-application1-vsi",
       "ipArrays": [
          [
             "10.1.0.4"
          ]
       ]
    }
    

    Versuchen Sie dann den zweiten Befehl (aus Ihrer Ausgabe):

    curl 52.116.140.202:3000/remote
    

    Wie Sie sehen, hat dieser zweite cURL-Befehl nicht funktioniert. Beheben Sie den Fehler im nächsten Schritt. Merken Sie sich diese curl-Befehle, Sie werden sie bald wieder verwenden.

Transit Gateway erstellen

IBM Cloud Transit Gateway ist ein Netzwerkdienst, der zur Verbindung von IBM Cloud VPC-Ressourcen und bietet dynamische Skalierbarkeit, hohe Verfügbarkeit und die Gewissheit, dass die Daten nicht über das öffentliche Internet übertragen werden. Früher wurden die CIDR-Blöcke für jede einzelne VPC ohne Überschneidung ausgewählt, damit Transit Gateway Pakete nach IP-Adresse weiterleiten konnte.

  1. Wechseln Sie das Verzeichnis und machen Sie sich zum Mitglied der Gruppe 'network' (verwenden Sie den vorhandenen API-Schlüssel):

    cd ../network
    source local.env
    
  2. Untersuchen Sie optional die Terraform-Dateien. Öffnen Sie die Datei 'main.tf' und beachten Sie die Transit Gateway-Ressourcen (ibm_tg). Jedes hat einen count = var.transit_gateway ? 1 : 0. Dies ist ein Terraform-Konstrukt, das ein Array von Ressourcen mit der Länge 1 oder 0 erstellt, je nach dem Wert für transit_gateway. Ein Array mit der Länge 0 führt zu keiner Ressource. Beispiel:

    resource "ibm_tg_gateway" "tgw"{
      count = var.transit_gateway ? 1 : 0
      name              = "${var.basename}-tgw"
      location          = var.ibm_region
      global            = false
      resource_group    = data.ibm_resource_group.network.id
    }
    
  3. Bearbeiten Sie die terraform.tfvars Datei und entfernen Sie die Markierung in der Zeile transit_gateway = true, um die Bereitstellung von Transit Gateway zu aktivieren.

  4. Wenden Sie die Änderung an.

    terraform apply
    
  5. Erstellen Sie mit den nachstehenden Befehlen eine Ausgabe für Transit Gateway.

    ibmcloud tg gateways
    GATEWAY_ID=$(ibmcloud tg gateways --output json | sed -e '/^OK$/d' | jq -r '.[]|select(.name=="'$basename-tgw'")|.id')
    ibmcloud tg connections $GATEWAY_ID
    

    Beachten Sie die drei VPC-Verbindungen in der Ausgabe. Die Ausgabe ist ungefähr wie folgt:

    $ ibmcloud tg gateways
    Listing gateways under account
    OK
    
    GatewayID           e2801c16-1a6d-4d47-9c58-1a3b3c1d9b1b
    CRN                 crn:v1:bluemix:public:transit:us-south:a/86785309::gateway:e2801c16-1a6d-4d47-9c58-1a3b3c1d9b1b
    Name                widget0-tgw
    Routing             local
    Location            us-south
    Created             2020-07-16T09:09:38.048-07:00
    Resource group ID   bf6e75cd71854576a31056abced2abf0
    Status              available
    
    $ GATEWAY_ID=$(ibmcloud tg gateways --output json | sed -e '/^OK$/d' | jq -r '.[]|select(.name=="'$basename-tgw'")|.id')
    $ ibmcloud tg connections $GATEWAY_ID
    Listing connections for gateway e2801c16-1a6d-4d47-9c58-1a3b3c1d9b1b under account
    OK
    
    Name                    widget0-shared
    Network Type            vpc
    Connection ID           dff6ecfd-388d-471a-908a-98880426fbee
    Status                  attached
    Default Prefix Filter   permit
    NetworkID               crn:v1:bluemix:public:is:us-south:a/86785309::vpc:r006-b08a7c2c-c0ea-4908-b0ab-b96cd8ba221a
    
    Name                    widget0-application1
    Network Type            vpc
    Connection ID           bbce29f9-9ce4-47d4-911d-5341601cea07
    Status                  attached
    Default Prefix Filter   permit
    NetworkID               crn:v1:bluemix:public:is:us-south:a/86785309::vpc:r006-8fdc0e7e-3a98-4f6b-93e0-505c61e3faac
    
    Name                    widget0-application2
    Network Type            vpc
    Connection ID           208c00cc-aee2-498e-8b1c-37ddc276f200
    Status                  attached
    Default Prefix Filter   permit
    NetworkID               crn:v1:bluemix:public:is:us-south:a/86785309::vpc:r006-fa80afa7-b16b-4db7-95dd-69a558db4285
    
  6. Navigieren Sie optional zum Transit Gateway und suchen Sie das oben erstellte Gateway.

  7. Führen Sie den Curl-Befehl von oben aus, der zuvor fehlgeschlagen ist, um zu überprüfen, ob es einen Pfad von der application1 VPC zur gemeinsamen VPC gibt. Dies sieht ungefähr wie folgt aus:

    $ curl 169.48.152.220:3000/remote
    
    {
       "remote_url": "http://shared.widgets.example.com:3000/info",
       "remote_ip": "10.0.0.4",
       "remote_info": {
          "req_url": "/info",
          "os_hostname": "widget0-shared-vsi",
          "ipArrays": [
             [
                "10.0.0.4"
             ]
          ]
       }
    }
    

Fügen Sie einen Load Balancer ein und ersetzen Sie den DNS-Datensatz.

Lastausgleichsfunktion zur Architektur hinzufügen
Lastausgleichsfunktion zur Architektur hinzufügen

  1. Wechseln Sie das Verzeichnis und machen Sie sich zum Mitglied der gemeinsam genutzten Gruppe (verwenden Sie den vorhandenen API-Schlüssel):

    cd ../shared
    source local.env
    
  2. Untersuchen Sie optional die Terraform-Konfigurationsdateien. Der Load Balancer für den VPC-Service verteilt den Datenverkehr unter mehrere Serverinstanzen innerhalb derselben Region Ihrer VPC. Das Team shared kann die Last zwischen mehreren Instanzen ausgleichen. Vorerst hat der Load-Balancer-Pool nur die eine Instanz, die zuvor erstellt wurde. Siehe die lb.tf für die Umsetzung. Verwenden Sie in der ibm_is_lb-Ressource die DNS-Klausel, um die private DNS-Zone anzugeben, in der die DNS-Adresse der Lastausgleichsfunktion platziert werden soll:

    resource "ibm_is_lb" "shared_lb" {
      ...
      dns {
        instance_crn = local.network_context.dns.crn
        zone_id      = local.network_context.dns.zone_id
      }
    }
    
  3. Geben Sie einen DNS-CNAME-Datensatz shared.widgets.example.com an, um die Lastausgleichsfunktion anzugeben, damit die Anwendungen weiterhin ohne Quellcodeänderungen funktionieren:

    # shared.widgets.example.com
    resource ibm_dns_resource_record "shared_lb" {
      count = var.shared_lb ? 1 : 0 # shared load balancer?
      instance_id = local.network_context.dns.guid
      zone_id     = local.network_context.dns.zone_id
      type        = "CNAME"
      name        = "shared"
      rdata       = ibm_is_lb.shared_lb[0].hostname
      ttl         = 3600
    }
    

    Dieselbe count = var.shared_lb ? 1 : 0 wird verwendet. Der Hostname der Lastausgleichsfunktion ist ungefähr b7911a41-us-south.widgets.example.com. Der CNAME-Datensatz wird von den Anwendungen verwendet.

  4. Bearbeiten Sie die Datei terraform.tfvars und entfernen Sie das Kommentarzeichen shared_lb = true. Wenden Sie dann die Änderungen an:

    terraform apply
    
  5. Führen Sie den curl .../remote aus dem vorherigen Abschnitt application1 aus (ignorieren Sie die soeben erzeugte Ausgabe für den gemeinsam genutzten Mikrodienst). Beachten Sie, dass die remote_ip 10.0.1.4, der Load Balancer, und die remote_info 10.0.0.4, die Instanz, ist. Curl a few more times and notice the remote_ip for the load balancer may change.

    $ curl 169.48.152.220:3000/remote
    
    {
       "remote_url": "http://shared.widgets.example.com:3000/info",
       "remote_ip": "10.0.1.4",
       "remote_info": {
          "req_url": "/info",
          "os_hostname": "widget0-shared-vsi",
          "ipArrays": [
             [
                "10.0.0.4"
             ]
          ]
       }
    }
    

Erstellen eines öffentlich zugänglichen Microservices für eine AnwendungApplication2 Team)

Die zweite Umgebung des Teams application ist mit der ersten identisch. Optional können Sie application2 durch Änderung von application1 erstellen.

  1. Geben Sie das Verzeichnis './application1' ein und erstellen Sie das Verzeichnis 'application2'.

    cd ../application1
    mkdir ../application2
    sed -e 's/application1/application2/g' main.tf > ../application2/main.tf
    cp terraform.tfvars variables.tf versions.tf ../application2
    
  2. Wechseln Sie das Verzeichnis, erzeugen Sie einen API-Schlüssel im local.env und werden Sie Mitglied der Zugriffsgruppe application2:

    team=application2
    cd ../$team
    echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam service-api-key-create $team $basename-$team --output json | jq .apikey) > local.env
    cat local.env
    source local.env
    
  3. Erstellen Sie die Ressourcen:

    terraform init
    terraform apply
    
  4. Testen Sie die cURL-Befehle.

Ressourcen entfernen

  1. Löschen Sie die Ressourcen. Sie können cd) in der Reihenfolge der Teamverzeichnisse ändern und source local.env; terraform destroy ausführen. Die Reihenfolge ist: application2, application1, shared, network, admin. Es gibt auch ein Script, das diese Arbeit für Sie übernimmt:

    cd ..
    ./bin/destroy.sh
    

Lernprogramm erweitern

Weitere Hinweise

  • Das Team application stellt den Zugang zur Anwendung über eine variable IP-Adresse bereit. Erwägen Sie eine Verbindung zu IBM Cloud Internet Services. Es kann das öffentliche DNS verwalten und Sicherheit bieten. Unter Isolierte Workloads in mehreren Standorten und Zonen bereitstellen finden Sie ein Beispiel.
  • Das Anwendungsteam kann wie das geteilte Team mit Hilfe eines Load Balancers horizontal skaliert werden.
  • Das gemeinsame Team kann dem Load Balancer weitere Instanzen hinzufügen, indem es die Instanzen der shared/main.tf.
  • Das gemeinsame Team könnte seine Implementierungsplattform auf Kubernetes umstellen.

Continuous Delivery

  • Die Installation von Software erfolgt derzeit dann, wenn die VPC-Instanz erstellt wird. Die Bereitstellung neuer Softwareversionen in der Produktion wurde nicht berücksichtigt.
  • Bei gemeinsam genutzten Mikrodiensten könnte eine neue VSI mit einer neuen Version erstellt werden und nach der Überprüfung könnte DNS angepasst oder der gemeinsam genutzte Load Balancer verwendet werden, um auf die neue Version umzuschalten.

Automatisierung, Staging und Entwicklung

  • Für die Produktion können die Teams jeweils ihren eigenen Schematics Arbeitsbereich haben. Mithilfe von Schematics können Terraform-Konfigurationen direkt in der Cloud ausgeführt werden, wo Status und Ausgabe geteilt werden können.
  • Die Terraform-Scripts können angepasst werden, um Staging- und Entwicklungsumgebungen zu ermöglichen. Stellen Sie diese Umgebungen in neue Konten ein.
  • Eine kontinuierliche Bereitstellungsumgebung kann erstellt werden, um den Code und die Umgebungen durch Entwicklung und Staging bis in die Produktion zu verschieben. Wird ein Rollback benötigt? Wie könnte man dies erreichen?

Schlussbemerkungen

Die Architektur eines Systems wird durch Abgrenzung und Eigentümerschaft an Cloud-Ressourcen beeinflusst. Es ist wichtig, dass Architekten aus allen Aspekten des Systems ihre Anforderungen an die Architektur beitragen. Jedes Team muss die Möglichkeit haben, die von ihnen produzierten und freigegebenen Ressourcen zu steuern. Die Isolation verringert die Wahrscheinlichkeit von Problemen und begrenzt bei Auftreten von Problemen das Schadenausmaß.