DigitalOceanKubernetesでAmbassadorを使用してAPIゲートウェイを作成する方法

提供:Dev Guides
移動先:案内検索

著者は、 Write for DOnations プログラムの一環として、 Free and Open SourceFundを選択して寄付を受け取りました。

序章

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

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

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

前提条件

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

ステップ1—アンバサダーのインストール

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

注:DigitalOceanKubernetesではデフォルトでRBACが有効になっているため、インストールにYAML構成ファイルを使用する場合は、RBACが有効な構成ファイルを使用する必要があります。 Ambassadorのドキュメントで、YAMLを介した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    <none>         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が必要です。

アンバサダーロードバランサーの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アドレスを指すようにします。 。

SSLターミネーションの構成方法に記載されている手順を使用して、DigitalOceanロードバランサーでHTTPSを有効にできます。 ロードバランサーを介してTLSターミネーションを構成することをお勧めします。 TLSターミネーションを設定する別の方法は、AmbassadorのTLSサポートを使用することです。

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

ステップ2—Webサーバー展開のセットアップ

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

好みのテキストエディタを開いて、NginxWebサーバーの最初のデプロイメントを作成します。

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

ここでは、[X118X]と呼ばれる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つのウェブサーバーコンテナをデプロイしました。 次のステップでは、これらの展開をインターネットトラフィックに公開します。

ステップ3—アンバサダーアノテーション付きのサービスを使用してアプリを公開する

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

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

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

nano svc1-service.yaml

注:マッピング名は、すべての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をこのサービスにマッピングするために、Ambassadorアノテーションを使用してKubernetesサービスsvc1を定義しました。

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

kubectl apply -f svc1-service.yaml

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

Outputservice/svc1 created

アンバサダーアノテーションを使用して、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として保存します。 ここでは、Ambassadorがhostヘッダー値をsvc2.your-domainとしてリクエストを受信したときに、トラフィックをsvc2にルーティングするために、Ambassadorアノテーションを使用して別の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を編集して、/binsvc3サービスにルーティングする2番目のアンバサダーアノテーションブロックを追加します。

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アノテーションを使用してホストベースおよびパスベースのルーティングルールを追加しました。 次に、これらのサービスに高度な構成を追加して、ルーティング、リダイレクト、およびカスタムヘッダーを構成します。

ステップ4—ルーティング用の高度なアンバサダー構成

このセクションでは、ヘッダーの変更およびリダイレクトの構成を行うために、さらにアンバサダーアノテーションを使用してサービスを構成します。

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-domainsvc3からsvc2.your-domain/binへの301リダイレクト応答を構成しました。 host_redirectパラメーターは、301リダイレクト応答をクライアントに送信します。 設定されていない場合、リクエストは301HTTP応答ではなく200HTTP応答を受信します。

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

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に対するリクエストの応答のHTTPヘッダーであり、サービスアノテーションのhost_redirect: trueの構成がHTTPステータスコード301 Moved Permanentlyを正しく提供していることを示しています。

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

ステップ5—アンバサダーグローバル構成のセットアップ

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

次の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サービスに追加し、APIGateway用にGZIPをグローバルに構成しました。 ここには、memory_levelで使用される内部メモリの量を制御するための構成が含まれています。これは1から9までの値にすることができます。 BESTに設定されたcompression_levelは、より高いレイテンシーを犠牲にして、より高い圧縮率を保証します。 min_content_lengthを使用して、最小応答長を256バイトに構成しました。 content_typeには、圧縮を生成するメディアタイプ(以前のMIMEタイプ)のセットが具体的に含まれています。 最後に、圧縮を可能にするために、最後の2つの構成をfalseとして追加しました。

GZIP圧縮の詳細については、EnvoyのGZIPページを参照してください。

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

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

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

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

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

アンバサダーにグローバル構成を追加して、APIゲートウェイ全体で選択したコンテンツタイプの応答に対してGZIP構成を有効にしました。

結論

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

アンバサダーの注釈と構成パラメーターの詳細については、アンバサダーの公式ドキュメントを参照してください。