DigitalOcean KubernetesでAmbassadorを使用してAPI Gatewayを作成する方法

著者は、Write for DOnationsプログラムの一部として寄付を受け取るためにFree and Open Source Fundを選択しました。

前書き

Ambassadorは、クラウドネイティブアプリケーション用のAPIゲートウェイであり、異種サービス間でトラフィックをルーティングし、分散型ワークフローを維持します。 単一のエントリポイントとして機能し、サービス検出、構成管理、ルーティングルール、レート制限などのタスクをサポートします。 サービスの優れた柔軟性と構成の容易さを提供します。

Envoyは、クラウドネイティブアプリケーション用に設計されたオープンソースのサービスプロキシです。 Kubernetesでは、アンバサダーを使用してEnvoy設定をインストールおよび管理できます。 Ambassadorは、ダウンタイムゼロの構成変更と、認証、サービスディスカバリ、services meshesなどの他の機能との統合をサポートします。

このチュートリアルでは、Helmを使用してKubernetesクラスターにAmbassador API Gatewayをセットアップし、ルーティングルールに基づいて着信トラフィックをさまざまなサービスにルーティングするように構成します。 ホスト名または関連するサービスへのパスに基づいてトラフィックをルーティングするようにこれらのルールを構成します。

前提条件

このガイドを始める前に、次のものが必要です。

  • kubectlが構成されたDigitalOceanKubernetesクラスター。 DigitalOceanでKubernetesクラスターを作成するには、Kubernetes Quickstartを参照してください。

  • ローカルマシンにインストールされたHelmパッケージマネージャー、およびクラスターにインストールされたTiller。 How To Install Software on Kubernetes Clusters with the Helm Package Managerのステップ1と2を完了します

  • 少なくとも2つのAレコードが設定された完全に登録されたドメイン名。 このチュートリアルでは、全体を通してsvc1.your-domainsvc2.your-domain、およびsvc3.your-domainを使用します。 DNS Quickstartをたどって、DigitalOceanにレコードを設定できます。

[[step-1 -—- installing-ambassador]] ==ステップ1—Ambassadorのインストール

このセクションでは、KubernetesクラスターにAmbassadorをインストールします。 Ambassadorは、Helmチャートを使用するか、YAML構成ファイルをkubectlコマンドに渡すことでインストールできます。

[.note]#Note: DigitalOcean KubernetesではデフォルトでRBACが有効になっているため、インストールにYAML構成ファイルを使用する場合は、RBACが有効な構成ファイルを使用する必要があります。 Ambassadorのdocumentation
#で、YA​​MLを介してAmabassadorをKubernetesにデプロイする方法の詳細を確認できます。

このチュートリアルでは、Helmチャートを使用して、Ambassadorをクラスターにインストールします。 前提条件に従って、クラスターにHelmをインストールします。

開始するには、次のコマンドを実行して、Helm経由でAmbassadorをインストールします。

helm upgrade --install --wait ambassador stable/ambassador

次のような出力が表示されます。

OutputRelease "ambassador" does not exist. Installing it now.
NAME:   ambassador
LAST DEPLOYED: Tue Jun 18 02:15:00 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME        READY  UP-TO-DATE  AVAILABLE  AGE
ambassador  3/3    3           3          2m39s

==> v1/Pod(related)
NAME                         READY  STATUS   RESTARTS  AGE
ambassador-7d55c468cb-4gpq9  1/1    Running  0         2m38s
ambassador-7d55c468cb-jr9zr  1/1    Running  0         2m38s
ambassador-7d55c468cb-zhm7l  1/1    Running  0         2m38s

==> v1/Service
NAME               TYPE          CLUSTER-IP      EXTERNAL-IP    PORT(S)                     AGE
ambassador         LoadBalancer  10.245.183.114  139.59.52.164  80:30001/TCP,443:31557/TCP  2m40s
ambassador-admins  ClusterIP     10.245.46.43             8877/TCP                    2m41s

==> v1/ServiceAccount
NAME        SECRETS  AGE
ambassador  1        2m43s

==> v1beta1/ClusterRole
NAME        AGE
ambassador  2m41s

==> v1beta1/ClusterRoleBinding
NAME        AGE
ambassador  2m41s

==> v1beta1/CustomResourceDefinition
NAME                                          AGE
authservices.getambassador.io                 2m42s
consulresolvers.getambassador.io              2m41s
kubernetesendpointresolvers.getambassador.io  2m42s
kubernetesserviceresolvers.getambassador.io   2m43s
mappings.getambassador.io                     2m41s
modules.getambassador.io                      2m41s
ratelimitservices.getambassador.io            2m42s
tcpmappings.getambassador.io                  2m41s
tlscontexts.getambassador.io                  2m42s
tracingservices.getambassador.io              2m43s

. . .

これにより、Kubernetesクラスターノードが接続されたAmbassadorデプロイメント、サービス、およびロードバランサーが作成されます。 ドメインのAレコードにマップするには、ロードバランサーのIPが必要です。

Ambassador Load BalancerのIPアドレスを取得するには、次を実行します。

kubectl get svc --namespace default ambassador

次のような出力が表示されます。

OutputNAME         TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
ambassador   LoadBalancer   your_cluster_IP   your-IP-address   80:30001/TCP,443:31557/TCP   8m4s

このステップの外部IPyour-IP-addressに注意し、ドメインを(ドメインプロバイダー経由で)svc1.your-domainsvc2.your-domain、およびsvc3.your-domainをマップしてこのIPアドレスを指すようにします。

How to Configure SSL Terminationで指定された手順を使用して、DigitalOceanロードバランサーでHTTPSを有効にできます。 Load Balancerを介してTLS終了を構成することをお勧めします。 TLSターミネーションを構成する別の方法は、Ambassador’s TLS Supportを使用することです

Helmを使用してKubernetesクラスターにAmbassadorをインストールし、デフォルトのネームスペースに3つのレプリカを持つAmbassadorデプロイメントを作成しました。 これにより、すべてのトラフィックをAPI GatewayにルーティングするパブリックIPを備えたロードバランサーも作成されました。 次に、このAPI Gatewayのテストに使用する3つの異なるサービス用のKubernetesデプロイを作成します。

[[step-2 -—- setting-up-web-server-deployments]] ==ステップ2—Webサーバーデプロイメントのセットアップ

このセクションでは、3つの異なるWebサーバーコンテナを実行する3つの展開を作成します。 3つの異なるウェブサーバーコンテナのKubernetesデプロイの定義を使用してYAMLファイルを作成し、kubectlを使用してデプロイします。

好みのテキストエディターを開いて、Nginx Webサーバーの最初の展開を作成します。

nano svc1-deploy.yaml

ファイルに次のyaml設定を入力します。

svc1-deploy.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: svc1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
      name: svc1
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
        name: svc1
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - name: http
          containerPort: 80

ここでは、svc1と呼ばれる1レプリカでデプロイされるnginx:latestコンテナイメージを使用してKubernetesDeploymentを定義しました。 Deploymentは、ポート80でクラスター内を公開するように定義されています。

ファイルを保存して閉じます。

次に、次のコマンドを実行してこの構成を適用します。

kubectl apply -f svc1-deploy.yaml

作成を確認する出力が表示されます。

Outputdeployment.extensions/svc1 created

次に、2番目のWebサーバーのデプロイメントを作成します。 次のコマンドでsvc2-deploy.yamlというファイルを開きます。

nano svc2-deploy.yaml

ファイルに次のYAML設定を入力します。

svc2-deploy.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: svc2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpd
      name: svc2
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: httpd
        name: svc2
    spec:
      containers:
      - name: httpd
        image: httpd:latest
        ports:
        - name: http
          containerPort: 80

ここでは、svc2と呼ばれる1レプリカでデプロイされるhttpdコンテナイメージを使用してKubernetesDeploymentを定義しました。

ファイルを保存して閉じます。

次のコマンドを実行して、この構成を適用します。

kubectl apply -f svc2-deploy.yaml

次の出力が表示されます。

Outputdeployment.extensions/svc2 created

最後に、3番目の展開では、svc3-deploy.yamlファイルを開いて作成します。

nano svc3-deploy.yaml

ファイルに次の行を追加します。

svc3-deploy.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: svc3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
      name: svc3
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: httpbin
        name: svc3
    spec:
      containers:
      - name: httpbin
        image: kennethreitz/httpbin:latest
        ports:
        - name: http
          containerPort: 80

ここでは、svc3と呼ばれる1レプリカでデプロイされるhttpbinコンテナイメージを使用してKubernetesDeploymentを定義しました。

ファイルを保存して閉じます。

最後に、次のコマンドを実行して適用します。

kubectl apply -f svc3-deploy.yaml

次の出力が表示されます。

Outputdeployment.extensions/svc3 created

Kubernetes展開を使用して3つのWebサーバーコンテナを展開しました。 次のステップでは、これらの展開をインターネットトラフィックに公開します。

[[step-3 -—- exposed-apps-using-services-with-ambassador-annotations]] ==ステップ3—アンバサダーアノテーション付きのサービスを使用してアプリを公開する

このセクションでは、Webアプリをインターネットに公開し、Ambassador annotationsを使用してKubernetesサービスを作成し、トラフィックをそれらにルーティングするルールを構成します。 Kubernetesの注釈は、オブジェクトにメタデータを追加する方法です。 Ambassadorは、サービスからのこれらの注釈値を使用して、ルーティングルールを構成します。

念のため、ドメイン(たとえば、svc1.your-domainsvc2.your-domainsvc3.your-domain)をDNSレコードのロードバランサーのパブリックIPにマッピングする必要があります。

次のファイルを作成して開くことにより、アンバサダーアノテーションを使用してsvc1デプロイメントのKubernetesサービスを定義します。

nano svc1-service.yaml

[.note]#Note:マッピング名は、すべてのAmbassadorアノテーションブロックで一意である必要があります。 マッピングはすべての注釈ブロックの識別子として機能し、繰り返されると、古い注釈ブロックとオーバーラップします。

svc1-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc1
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind: Mapping
      name: svc1-service_mapping
      host: svc1.your-domain
      prefix: /
      service: svc1:80
spec:
  selector:
    app: nginx
    name: svc1
  ports:
  - name: http
    protocol: TCP
    port: 80

このYAMLコードでは、ホスト名svc1.your-domainをこのサービスにマップするために、アンバサダーアノテーションを使用してKubernetesサービスsvc1を定義しました。

svc1-service.yamlを保存して終了し、以下を実行してこの構成を適用します。

kubectl apply -f svc1-service.yaml

次の出力が表示されます。

Outputservice/svc1 created

Ambassadorアノテーションを使用してsvc2デプロイメント用の2番目のKubernetesサービスを作成します。 これは、Ambassadorを使用したホストベースのルーティングの別の例です。

svc2-service.yaml

次の構成をファイルに追加します。

svc2-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc2
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind: Mapping
      name: svc2-service_mapping
      host: svc2.your-domain
      prefix: /
      service: svc2:80
spec:
  selector:
    app: httpd
    name: svc2
  ports:
  - name: http
    protocol: TCP
    port: 80

これをsvc2-service.yamlとして保存します。 ここでは、hostヘッダー値をsvc2.your-domainとしてアンバサダーがリクエストを受信したときに、トラフィックをsvc2にルーティングするために、アンバサダーアノテーションを使用して別のKubernetesサービスを定義しました。 したがって、このホストベースのルーティングにより、サブドメインsvc2.your-domainにリクエストを送信できます。これにより、トラフィックがサービスsvc2にルーティングされ、httpdWebサーバーからリクエストが処理されます。

このサービスを作成するには、次を実行します。

kubectl apply -f svc2-service.yaml

次の出力が表示されます。

Outputservice/svc2 created

svc3デプロイメント用に3番目のKubernetesサービスを作成し、パスsvc2.your-domain/binを介して提供します。 これにより、Ambassadorのパスベースのルーティングが構成されます。

svc3-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc3
spec:
  selector:
    app: httpbin
    name: svc3
  ports:
  - name: http
    protocol: TCP
    port: 80

これをsvc3-service.yamlとして保存し、以下を実行して構成を適用します。

kubectl apply -f svc3-service.yaml

あなたの出力は次のようになります。

Outputservice/svc3 created

svc2-service.yamlを編集して、2番目のAmbassadorアノテーションブロックを追加し、/binsvc3サービスにルーティングします。

nano svc2-service.yaml

svc2-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc2
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind: Mapping
      name: svc2-service_mapping
      host: svc2.your-domain
      prefix: /
      service: svc2:80
      ---
      apiVersion: ambassador/v1
      kind: Mapping
      name: svc3-service_mapping
      host: svc2.your-domain
      prefix: /bin
      service: svc3:80
spec:
  selector:
    app: httpd
    name: svc2
  ports:
  - name: http
    protocol: TCP
    port: 80

2番目のAmbassadorアノテーションブロックを追加して、/binで始まるパスを構成し、svc3Kubernetesサービスにマッピングしました。 svc2.your-domain/binのリクエストをsvc3にルーティングするために、ここに2番目のアノテーションブロックをホスト値svc2.your-domainとして追加しました。これは、両方のブロックで同じです。 したがって、パスベースのルーティングを使用すると、svc2.your-domain/binにリクエストを送信できます。このリクエストは、サービスsvc3によって受信され、このチュートリアルのhttpbinアプリケーションによって提供されます。

次に、以下を実行して変更を適用します。

kubectl apply -f svc2-service.yaml

次の出力が表示されます。

Outputservice/svc2 configured

3つの展開用にKubernetesサービスを作成し、Ambassadorアノテーションを使用してホストベースおよびパスベースのルーティングルールを追加しました。 次に、これらのサービスに高度な構成を追加して、ルーティング、リダイレクト、カスタムヘッダーを構成します。

[[step-4 -—- advanced-ambassador-configurations-for-routing]] ==ステップ4—ルーティング用の高度なアンバサダー構成

このセクションでは、modify headersおよびconfigure redirectionへのアンバサダーアノテーションを追加してサービスを構成します。

curlはドメインsvc1.your-domainであり、応答ヘッダーを確認します。

curl -I svc1.your-domain

出力は次のようになります。

OutputHTTP/1.1 200 OK
server: envoy
date: Mon, 17 Jun 2019 21:41:00 GMT
content-type: text/html
content-length: 612
last-modified: Tue, 21 May 2019 14:23:57 GMT
etag: "5ce409fd-264"
accept-ranges: bytes
x-envoy-upstream-service-time: 0

この出力は、Ambassadorを使用してルーティングされたサービスから受信したヘッダーを示しています。 Ambassadorアノテーションを使用してサービスレスポンスにカスタムヘッダーを追加し、新しく追加されたヘッダーの出力を検証します。

サービス応答にカスタムヘッダーを追加するには、応答からヘッダーx-envoy-upstream-service-timeを削除し、svc1に新しい応答ヘッダーx-geo-location: Indiaを追加します。 (要件に応じてこのヘッダーを変更できます。)

ファイルsvc1-service.yamlを編集します。

nano svc1-service.yaml

次の強調表示された行で注釈を更新します。

svc1-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc1
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind: Mapping
      name: svc1-service_mapping
      host: svc1.example.com
      prefix: /
      remove_response_headers:
      - x-envoy-upstream-service-time
      add_response_headers:
        x-geo-location: India
      service: svc1:80
spec:
  selector:
    app: nginx
    name: svc1
  ports:
  - name: http
    protocol: TCP
    port: 80

ここでは、svc1サービスを変更してx-envoy-upstream-service-timeを削除し、HTTP応答にx-geo-location: Indiaヘッダーを追加しました。

行った変更を適用します。

kubectl apply -f svc1-service.yaml

次の出力が表示されます。

Outputservice/svc1 configured

次に、curlを実行して、サービス応答の更新されたヘッダーを検証します。

curl -I svc1.your-domain

出力は次のようになります。

OutputHTTP/1.1 200 OK
server: envoy
date: Mon, 17 Jun 2019 21:45:26 GMT
content-type: text/html
content-length: 612
last-modified: Tue, 21 May 2019 14:23:57 GMT
etag: "5ce409fd-264"
accept-ranges: bytes
x-geo-location: India

次に、svc3-service.yamlを編集して、ホスト名svc3.your-domainの要求をパスsvc2.your-domain/binにリダイレクトします。

nano svc3-service.yaml

次のYAMLに示すようにAmbassador注釈ブロックを追加して保存します。

svc3-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc3
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind:  Mapping
      name:  redirect_mapping
      host: svc3.your-domain
      prefix: /
      service: svc2.your-domain
      host_redirect: true
      path_redirect: /bin
spec:
  selector:
    app: httpbin
    name: svc3
  ports:
  - name: http
    protocol: TCP
    port: 80

host_redirect: trueを追加して、ホスト名svc3.your-domainsvc2.your-domain/binへのsvc3の301リダイレクト応答を構成しました。 host_redirectパラメータは、301リダイレクト応答をクライアントに送信します。 設定しない場合、要求は301 HTTP応答ではなく200 HTTP応答を受け取ります。

次のコマンドを実行して、これらの変更を適用します。

kubectl apply -f svc3-service.yaml

次のような出力が表示されます。

Outputservice/svc3 configured

これで、curlを使用してsvc3.your-domainの応答を確認できます。

curl -I svc3.your-domain

出力は次のようになります。

OutputHTTP/1.1 301 Moved Permanently
location: http://svc2.your-domain/bin
date: Mon, 17 Jun 2019 21:52:05 GMT
server: envoy
transfer-encoding: chunked

出力は、サービスアノテーションのサービスsvc3.your-domain+`showing that the configuration of `+host_redirect: trueに対するリクエストの応答のHTTPヘッダーであり、HTTPステータスコード301 Moved Permanentlyが正しく提供されています。

HTTPヘッダーを変更し、リダイレクトを構成するために、Ambassadorアノテーションを使用してサービスを構成しました。 次に、Ambassador API Gatewayサービスにグローバル構成を追加します。

[[step-5 -—- setting-up-ambassador-global-configurations]] ==ステップ5—Ambassadorグローバル構成のセットアップ

このセクションでは、Ambassadorサービスを編集して、グローバルGZIP圧縮構成を追加します。 GZIP圧縮により、HTTPアセットのサイズが圧縮され、ネットワーク帯域幅の要件が軽減され、Webクライアントの応答時間が短縮されます。 この構成は、Ambassador API Gatewayを介してルーティングされるすべてのトラフィックに影響します。 同様に、Ambassadorを使用して他のグローバルモジュールを構成できます。これにより、グローバルレベルでAmbassadorの特別な動作を有効にできます。 これらのグローバル構成は、注釈を使用してAmbassadorサービスに適用できます。 詳細については、Ambassador’s Global Configurationのドキュメントを参照してください。

次のkubectl editコマンドは、デフォルトのエディターであるvimを開きます。 たとえば、nanoを使用するには、環境変数KUBE_EDITORをnanoに設定します。

export KUBE_EDITOR="nano"

アンバサダーサービスを編集します。

kubectl edit service ambassador

GZIP圧縮のために、強調表示された行を新しい注釈ブロックに追加します。

アンバサダーサービスの編集

apiVersion: v1
kind: Service
metadata:
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind: Module
      name: ambassador
      config:
        service_port: 8080
      ---
      apiVersion: ambassador/v0
      kind:  Module
      name:  ambassador
      config:
        gzip:
          memory_level: 5
          min_content_length: 256
          compression_level: BEST
          compression_strategy: DEFAULT
          content_type:
          - application/javascript
          - application/json
          - text/html
          - text/plain
          disable_on_etag_header: false
          remove_accept_encoding_header: false
  creationTimestamp: "2019-06-17T20:45:04Z"
  labels:
    app.kubernetes.io/instance: ambassador
    app.kubernetes.io/managed-by: Tiller
    app.kubernetes.io/name: ambassador
    helm.sh/chart: ambassador-2.8.2
  name: ambassador
  namespace: default
  resourceVersion: "2153"
  . . .

AmbassadorアノテーションブロックをAmbassadorサービスに追加し、GZIPをAPI Gateway用にグローバルに設定しました。 ここには、memory_levelで使用される内部メモリの量を制御するための構成が含まれています。これは1から9までの値です。 BESTに設定されたcompression_levelは、より高いレイテンシーを犠牲にして、より高い圧縮率を保証します。 min_content_lengthを使用して、最小応答長を256バイトに構成しました。 content_typeの場合、圧縮を生成する一連のmedia types(以前のMIMEタイプ)を具体的に含めました。 最後に、最後の2つの構成をfalseとして追加して、圧縮を可能にしました。

Envoy’s GZIP pageでのGZIP圧縮の詳細を読むことができます。

このサービスの変更は、API Gatewayのグローバル構成として適用されます。

エディターを終了すると、次のような出力が表示されます。

Outputservice/ambassador edited

gzipを持つcontent-encodingヘッダーのcurlを使用してsvc1.your-domainを確認します。

curl --compressed -i http://svc1.example.com

出力は次のようになります。

OutputHTTP/1.1 200 OK
server: envoy
date: Mon, 17 Jun 2019 22:25:35 GMT
content-type: text/html
last-modified: Tue, 21 May 2019 14:23:57 GMT
accept-ranges: bytes
x-geo-location: India
vary: Accept-Encoding
content-encoding: gzip
transfer-encoding: chunked




Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

ここでは、NginxのデフォルトのHTMLページと、受信した応答のcontent-encodinggzip圧縮されていることを示す応答ヘッダーを確認できます。

APIゲートウェイ全体の選択されたコンテンツタイプレスポンスのGZIP構成を有効にするために、グローバル構成をAmbassadorに追加しました。

結論

Ambassadorを使用してKubernetesクラスターのAPI Gatewayを正常にセットアップしました。 ホストおよびパスベースのルーティング、カスタムヘッダー、グローバルGZIP圧縮を使用して、アプリを公開できるようになりました。

アンバサダーの注釈と構成パラメーターの詳細については、Ambassador’s official documentationを参照してください。

Related