DigitalOceanKubernetesでAmbassadorを使用してAPIゲートウェイを作成する方法
著者は、 Write for DOnations プログラムの一環として、 Free and Open SourceFundを選択して寄付を受け取りました。
序章
Ambassador は、クラウドネイティブアプリケーション用のAPIゲートウェイであり、異種サービス間でトラフィックをルーティングし、分散型ワークフローを維持します。 単一のエントリポイントとして機能し、サービスディスカバリ、構成管理、ルーティングルール、レート制限などのタスクをサポートします。 それはあなたのサービスに大きな柔軟性と設定の容易さを提供します。
Envoy は、クラウドネイティブアプリケーション向けに設計されたオープンソースのサービスプロキシです。 Kubernetesでは、Ambassadorを使用してEnvoy構成をインストールおよび管理できます。 Ambassadorは、ダウンタイムなしの構成変更と、認証、サービスディスカバリ、サービスメッシュなどの他の機能との統合をサポートします。
このチュートリアルでは、Helmを使用してKubernetesクラスターにAmbassador API Gatewayをセットアップし、ルーティングルールに基づいて着信トラフィックをさまざまなサービスにルーティングするように構成します。 ホスト名または関連するサービスへのパスに基づいてトラフィックをルーティングするように、これらのルールを構成します。
前提条件
このガイドを開始する前に、次のものが必要です。
- kubectlが構成されたDigitalOceanKubernetesクラスター。 DigitalOceanでKubernetesクラスタを作成するには、Kubernetesクイックスタートをご覧ください。
- ローカルマシンにインストールされているHelmパッケージマネージャーと、クラスターにインストールされているTiller。 HelmPackageManagerを使用してKubernetesクラスターにソフトウェアをインストールする方法のステップ1と2を完了します
- 少なくとも2つのAレコードが構成された完全に登録されたドメイン名。 このチュートリアルでは、全体を通して
svc1.your-domain
、svc2.your-domain
、およびsvc3.your-domain
を使用します。 DNSクイックスタートに従って、DigitalOceanにレコードを設定できます。
ステップ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-domain
、svc2.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-domain
、svc2.your-domain
、svc3.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
にルーティングされ、httpd
Webサーバーからリクエストが処理されます。 。
このサービスを作成するには、次を実行します。
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
を編集して、/bin
をsvc3
サービスにルーティングする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
で始まるパスをsvc3
Kubernetesサービスにマッピングするように構成しました。 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-domain
のsvc3
から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-encoding
がgzip
圧縮されていることを示す応答ヘッダーを含むNginxのデフォルトのHTMLページを見ることができます。
アンバサダーにグローバル構成を追加して、APIゲートウェイ全体で選択したコンテンツタイプの応答に対してGZIP構成を有効にしました。
結論
これで、Ambassadorを使用してKubernetesクラスターのAPIゲートウェイが正常にセットアップされました。 ホストベースおよびパスベースのルーティング、カスタムヘッダー、グローバルGZIP圧縮を使用してアプリを公開できるようになりました。
アンバサダーの注釈と構成パラメーターの詳細については、アンバサダーの公式ドキュメントを参照してください。