如何在 DigitalOcean Kubernetes 上使用 Ambassador 创建 API 网关

作者选择了 自由和开源基金作为 写给捐款计划的一部分接受捐款。

介绍

Ambassador 是云应用程序的 API 网关,可在异质服务之间路由流量,维护分散工作流程,作为一个单一的入口点,并支持服务发现、配置管理、路由规则和速度限制等任务。

Envoy是一个为云本地应用程序设计的开源服务代理。在Kubernetes中,Ambassador可用于安装和管理Envoy配置。Ambassador支持零停机配置更改和与其他功能的集成,如身份验证、服务发现和服务网格

在本教程中,您将使用 Helm 在 Kubernetes 集群上设置一个 Ambassador API Gateway,并根据路由规则将其配置为将流量路由到各种服务。

如果您正在寻找一个管理的Kubernetes托管服务,请查看我们的简单的,用于增长的管理的Kubernetes服务(https://www.digitalocean.com/products/kubernetes)。

前提条件

在您开始本指南之前,您将需要以下内容:

第1步:安装大使

在本节中,您将在您的 Kubernetes 集群上安装 Ambassador. Ambassador 可以使用 Helm 图表或通过将 YAML 配置文件传输到 kubectl 命令来安装。

注意:DigitalOcean Kubernetes 默认情况下已启用 RBAC,因此在安装 YAML 配置文件时,您需要确保使用 RBAC 启用文件。

对于本教程的目的,您将使用 Helm图表来安装Ambassador到您的集群. 遵循前提条件后,您将安装Helm到您的集群。

首先,运行以下命令来通过 Helm 安装 Ambassador:

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

您将看到类似于以下的输出:

 1[secondary_label Output]
 2Release "ambassador" does not exist. Installing it now.
 3NAME:   ambassador
 4LAST DEPLOYED: Tue Jun 18 02:15:00 2019
 5NAMESPACE: default
 6STATUS: DEPLOYED
 7
 8RESOURCES:
 9==> v1/Deployment
10NAME READY UP-TO-DATE AVAILABLE AGE
11ambassador 3/3 3 3 2m39s
12
13==> v1/Pod(related)
14NAME READY STATUS RESTARTS AGE
15ambassador-7d55c468cb-4gpq9 1/1 Running 0 2m38s
16ambassador-7d55c468cb-jr9zr 1/1 Running 0 2m38s
17ambassador-7d55c468cb-zhm7l 1/1 Running 0 2m38s
18
19==> v1/Service
20NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)                     AGE
21ambassador LoadBalancer 10.245.183.114 139.59.52.164 80:30001/TCP,443:31557/TCP 2m40s
22ambassador-admins ClusterIP 10.245.46.43    <none>         8877/TCP 2m41s
23
24==> v1/ServiceAccount
25NAME SECRETS AGE
26ambassador 1 2m43s
27
28==> v1beta1/ClusterRole
29NAME AGE
30ambassador 2m41s
31
32==> v1beta1/ClusterRoleBinding
33NAME AGE
34ambassador 2m41s
35
36==> v1beta1/CustomResourceDefinition
37NAME AGE
38authservices.getambassador.io 2m42s
39consulresolvers.getambassador.io 2m41s
40kubernetesendpointresolvers.getambassador.io 2m42s
41kubernetesserviceresolvers.getambassador.io 2m43s
42mappings.getambassador.io 2m41s
43modules.getambassador.io 2m41s
44ratelimitservices.getambassador.io 2m42s
45tcpmappings.getambassador.io 2m41s
46tlscontexts.getambassador.io 2m42s
47tracingservices.getambassador.io 2m43s
48
49. . .

这将创建一个 Ambassador 部署、服务和负载平衡器,并附加到您的 Kubernetes 集群节点。

要获取您的 Ambassador 负载平衡器的 IP 地址,请执行以下操作:

1kubectl get svc --namespace default ambassador

你会看到类似的输出:

1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)                      AGE
3ambassador LoadBalancer your_cluster_IP your-IP-address 80:30001/TCP,443:31557/TCP 8m4s

在此步骤中记住外部 IP 地址您的 IP 地址,并将域名(通过您的域提供商)svc1.your-domain,svc2.your-domainsvc3.your-domain绘制到该 IP 地址。

您可以使用 如何配置 SSL 终止的步骤启用 HTTPS 与您的 DigitalOcean 负载平衡器。建议通过 Load Balancer 配置 TLS 终止。

您已使用 Helm 安装 Ambassador 到您的 Kubernetes 集群中,该集群创建了一个 Ambassador 部署,在默认名称空间中有三个复制品。这也创建了一个负载平衡器,具有公共 IP,可将所有流量路由到 API 网关。

步骤2 - 设置 Web 服务器部署

在本节中,您将创建三种部署来运行三个不同的 Web 服务器容器. 您将创建具有 Kubernetes 部署定义的 YAML 文件,并使用kubectl部署三种不同的 Web 服务器容器。

打开您喜爱的文本编辑器,为 Nginx Web 服务器创建您的第一个部署:

1nano svc1-deploy.yaml

在你的文件中输入下面的 yaml 配置:

 1[label svc1-deploy.yaml]
 2apiVersion: extensions/v1beta1
 3kind: Deployment
 4metadata:
 5  name: svc1
 6spec:
 7  replicas: 1
 8  selector:
 9    matchLabels:
10      app: nginx
11      name: svc1
12  strategy:
13    type: RollingUpdate
14  template:
15    metadata:
16      labels:
17        app: nginx
18        name: svc1
19    spec:
20      containers:
21      - name: nginx
22        image: nginx:latest
23        ports:
24        - name: http
25          containerPort: 80

在这里,您已经定义了 Kubernetes 的部署,其中包含 [nginx:latest](https://hub.docker.com/_/nginx)的容器图像,该图像将与1复制件一起部署,称为svc1`。

保存并关闭文件。

然后运行以下命令来应用此配置:

1kubectl apply -f svc1-deploy.yaml

您将看到确认创建的输出:

1[secondary_label Output]
2deployment.extensions/svc1 created

现在,创建第二个 Web 服务器部署,打开一个名为 svc2-deploy.yaml 的文件:

1nano svc2-deploy.yaml

在文件中输入以下YAML配置:

 1[label svc2-deploy.yaml]
 2apiVersion: extensions/v1beta1
 3kind: Deployment
 4metadata:
 5  name: svc2
 6spec:
 7  replicas: 1
 8  selector:
 9    matchLabels:
10      app: httpd
11      name: svc2
12  strategy:
13    type: RollingUpdate
14  template:
15    metadata:
16      labels:
17        app: httpd
18        name: svc2
19    spec:
20      containers:
21      - name: httpd
22        image: httpd:latest
23        ports:
24        - name: http
25          containerPort: 80

在这里,您已经定义了 Kubernetes 的部署,其中包含 httpd的容器图像,该图像将与 1 复制件一起部署,称为 svc2

保存并关闭文件。

运行以下命令来应用此配置:

1kubectl apply -f svc2-deploy.yaml

你会看到这个输出:

1[secondary_label Output]
2deployment.extensions/svc2 created

最后,对于第三个部署,打开并创建‘svc3-deploy.yaml’文件:

1nano svc3-deploy.yaml

将以下行添加到文件中:

 1[label svc3-deploy.yaml]
 2apiVersion: extensions/v1beta1
 3kind: Deployment
 4metadata:
 5  name: svc3
 6spec:
 7  replicas: 1
 8  selector:
 9    matchLabels:
10      app: httpbin
11      name: svc3
12  strategy:
13    type: RollingUpdate
14  template:
15    metadata:
16      labels:
17        app: httpbin
18        name: svc3
19    spec:
20      containers:
21      - name: httpbin
22        image: kennethreitz/httpbin:latest
23        ports:
24        - name: http
25          containerPort: 80

在这里,您已经定义了 Kubernetes 的部署,其中包含 httpbin的容器图像,该图像将与 1 副本一起部署,称为 svc3

保存并关闭文件。

最后,执行以下命令:

1kubectl apply -f svc3-deploy.yaml

你会看到以下的输出:

1[secondary_label Output]
2deployment.extensions/svc3 created

您已使用 Kubernetes 部署部署了三个 Web 服务器容器,在下一步,您将将这些部署暴露在互联网流量中。

步骤 3 – 使用 Ambassador 注释的服务曝光应用程序

在本节中,您将将 Web 应用程序暴露在互联网上,创建 Kubernetes 服务,使用 大使注释来配置规则,以便将流量导向它们。

作为提醒,您需要将您的域名(例如:‘svc1.your-domain’,‘svc2.your-domain’,和‘svc3.your-domain’)在您的 DNS 记录中映射到负载平衡器的公共 IP。

通过创建和打开此文件来定义一个 Kubernetes 服务,用于使用 Ambassador 注释的 svc1 部署:

1nano svc1-service.yaml

<$>[注] 注: 地图名称应为每个大使注释块独一无二,地图作为每个注释块的标识符,如果重复,它将重叠旧注释块。

 1[label svc1-service.yaml]
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: svc1
 6  annotations:
 7    getambassador.io/config: |
 8      ---
 9      apiVersion: ambassador/v1
10      kind: Mapping
11      name: svc1-service_mapping
12      host: svc1.your-domain
13      prefix: /
14      service: svc1:80      
15spec:
16  selector:
17    app: nginx
18    name: svc1
19  ports:
20  - name: http
21    protocol: TCP
22    port: 80

在此 YAML 代码中,您已定义了一个 Kubernetes 服务 svc1 与 Ambassador 注释来将主机名 svc1.your-domain 与该服务进行地图。

保存和退出「svc1-service.yaml」,然后执行以下操作来应用此配置:

1kubectl apply -f svc1-service.yaml

你会看到这个输出:

1[secondary_label Output]
2service/svc1 created

创建你的第二个 Kubernetes 服务以使用 Ambassador 注释来部署 svc2

1svc2-service.yaml

将以下配置添加到文件中:

 1[label svc2-service.yaml]
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: svc2
 6  annotations:
 7    getambassador.io/config: |
 8      ---
 9      apiVersion: ambassador/v1
10      kind: Mapping
11      name: svc2-service_mapping
12      host: svc2.your-domain
13      prefix: /
14      service: svc2:80      
15spec:
16  selector:
17    app: httpd
18    name: svc2
19  ports:
20  - name: http
21    protocol: TCP
22    port: 80

在这里,您已经定义了另一个 Kubernetes 服务与大使注释以将流量路由到svc2,当任何请求被大使接收时,其主机标题值为svc2.your-domain

要创建此服务,执行以下操作:

1kubectl apply -f svc2-service.yaml

您将看到以下输出:

1[secondary_label Output]
2service/svc2 created

创建第三个 Kubernetes 服务,用于你的svc3部署,并通过svc2.your-domain/bin路径服务。

 1[label svc3-service.yaml]
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: svc3
 6spec:
 7  selector:
 8    app: httpbin
 9    name: svc3
10  ports:
11  - name: http
12    protocol: TCP
13    port: 80

将此保存为svc3-service.yaml,然后运行以下操作来应用配置:

1kubectl apply -f svc3-service.yaml

你的输出将是:

1[secondary_label Output]
2service/svc3 created

编辑svc2-service.yaml,将第二个大使注释块附加到路由/binsvc3服务:

1nano svc2-service.yaml
 1[label svc2-service.yaml]
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: svc2
 6  annotations:
 7    getambassador.io/config: |
 8      ---
 9      apiVersion: ambassador/v1
10      kind: Mapping
11      name: svc2-service_mapping
12      host: svc2.your-domain
13      prefix: /
14      service: svc2:80
15      ---
16      apiVersion: ambassador/v1
17      kind: Mapping
18      name: svc3-service_mapping
19      host: svc2.your-domain
20      prefix: /bin
21      service: svc3:80      
22spec:
23  selector:
24    app: httpd
25    name: svc2
26  ports:
27  - name: http
28    protocol: TCP
29    port: 80

你添加了第二个大使注释块,以配置从/bin'开始的路径,将路径映射到您的svc3' Kubernetes服务。 为了将svc2.your-domain/bin'的请求传送到svc3',你在这里增加了第二个注释块,作为主机值svc2.your-domain',这两个区块都一样。 因此,基于路径的路由将允许您向svc2. your-domain/bin发送请求,该请求将由svc3服务接收,并由httpbin`应用程序在此教程中提供

现在运行以下操作来应用这些更改:

1kubectl apply -f svc2-service.yaml

你会看到这个输出:

1[secondary_label Output]
2service/svc2 configured

您为这三个部署创建了 Kubernetes 服务,并通过 Ambassador 注释添加了基于主机和基于路径的路由规则,接下来,您将为这些服务添加高级配置,以配置路由、重定向和自定义标题。

步骤 4 — 用于路由的先进大使配置

在本节中,您将配置其他大使注释的服务为 更改标题配置重定向

curl 域名 svc1.your-domain 并检查响应标题:

1curl -I svc1.your-domain

你的输出将是相似的如下:

 1[secondary_label Output]
 2HTTP/1.1 200 OK
 3server: envoy
 4date: Mon, 17 Jun 2019 21:41:00 GMT
 5content-type: text/html
 6content-length: 612
 7last-modified: Tue, 21 May 2019 14:23:57 GMT
 8etag: "5ce409fd-264"
 9accept-ranges: bytes
10x-envoy-upstream-service-time: 0

此输出显示了从使用 Ambassador 路由的服务接收的标题,您将使用 Ambassador 注释将自定义标题添加到服务响应中,并对新添加标题的输出进行验证。

若要在服务响应中添加自定义标题,请从响应中删除标题x-envoy-upstream-service-time,并为svc1添加新的响应标题x-geo-location: India

编辑文件 svc1-service.yaml:

1nano svc1-service.yaml

用以下突出的行更新注释:

 1[label svc1-service.yaml]
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: svc1
 6  annotations:
 7    getambassador.io/config: |
 8      ---
 9      apiVersion: ambassador/v1
10      kind: Mapping
11      name: svc1-service_mapping
12      host: svc1.example.com
13      prefix: /
14      remove_response_headers:
15      - x-envoy-upstream-service-time
16      add_response_headers:
17        x-geo-location: India
18      service: svc1:80      
19spec:
20  selector:
21    app: nginx
22    name: svc1
23  ports:
24  - name: http
25    protocol: TCP
26    port: 80

在这里,您已经修改了svc1服务以删除x-envoy-upstream-service-time,并在HTTP响应中添加了x-geo-location: India标题。

应用您所做的更改:

1kubectl apply -f svc1-service.yaml

您将看到以下结果:

1[secondary_label Output]
2service/svc1 configured

现在运行弯曲,以验证服务响应中的更新标题:

1curl -I svc1.your-domain

结果将类似于此:

 1[secondary_label Output]
 2HTTP/1.1 200 OK
 3server: envoy
 4date: Mon, 17 Jun 2019 21:45:26 GMT
 5content-type: text/html
 6content-length: 612
 7last-modified: Tue, 21 May 2019 14:23:57 GMT
 8etag: "5ce409fd-264"
 9accept-ranges: bytes
10x-geo-location: India

现在编辑svc3-service.yaml,将您的主机名称svc3.your-domain的请求重定向到路径svc2.your-domain/bin:

1nano svc3-service.yaml

附上如下YAML中所示的大使注释块并保存它:

 1[label svc3-service.yaml]
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: svc3
 6  annotations:
 7    getambassador.io/config: |
 8      ---
 9      apiVersion: ambassador/v1
10      kind:  Mapping
11      name:  redirect_mapping
12      host: svc3.your-domain
13      prefix: /
14      service: svc2.your-domain
15      host_redirect: true
16      path_redirect: /bin      
17spec:
18  selector:
19    app: httpbin
20    name: svc3
21  ports:
22  - name: http
23    protocol: TCP
24    port: 80

您已添加「host_redirect: true」以配置「svc3」的301重定向响应到「svc2.your-domain/bin」为「svc3.your-domain」的托管名称。「host_redirect」参数会向客户端发送301重定向响应。

现在运行以下命令来应用这些更改:

1kubectl apply -f svc3-service.yaml

你会看到类似的输出:

1[secondary_label Output]
2service/svc3 configured

现在您可以使用curl来检查svc3.your-domain的答案:

1curl -I svc3.your-domain

你的输出将是相似的如下:

1[secondary_label Output]
2HTTP/1.1 301 Moved Permanently
3location: http://svc2.your-domain/bin
4date: Mon, 17 Jun 2019 21:52:05 GMT
5server: envoy
6transfer-encoding: chunked

输出是一个 HTTP 标题,用于请求对服务 svc3.your-domain的响应,显示您的服务注释中的 host_redirect: true' 配置正确地提供了 HTTP 状态代码: 301 Moved Permanently`。

您已配置 Ambassador 注释以修改 HTTP 标题并配置重定向,接下来您将向 Ambassador API Gateway 服务添加全球配置。

步骤5:设置全球大使配置

在本节中,您将编辑大使服务,以添加全球GZIP压缩配置。 GZIP压缩将压缩HTTP资产大小并减少网络带宽要求,从而导致网络客户端更快的响应时间. 这一配置影响到所有通过大使API网关的流量。 同样,你可以与大使一起配置其他全球模块,从而使大使在全球一级能够采取特殊的行为。 这些全球组合可使用大使服务说明加以应用。 您可参考大使全球配置文件获取更多信息.

例如,要使用 nano,您可以将环境变量 KUBE_EDITOR 设置为 nano:

1export KUBE_EDITOR="nano"

编辑大使服务:

1kubectl edit service ambassador

现在将突出的行添加到 GZIP 压缩的新注释块中:

 1[label Editing Ambassador Service]
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  annotations:
 6    getambassador.io/config: |
 7      ---
 8      apiVersion: ambassador/v1
 9      kind: Module
10      name: ambassador
11      config:
12        service_port: 8080
13      ---
14      apiVersion: ambassador/v0
15      kind:  Module
16      name:  ambassador
17      config:
18        gzip:
19          memory_level: 5
20          min_content_length: 256
21          compression_level: BEST
22          compression_strategy: DEFAULT
23          content_type:
24          - application/javascript
25          - application/json
26          - text/html
27          - text/plain
28          disable_on_etag_header: false
29          remove_accept_encoding_header: false      
30  creationTimestamp: "2019-06-17T20:45:04Z"
31  labels:
32    app.kubernetes.io/instance: ambassador
33    app.kubernetes.io/managed-by: Tiller
34    app.kubernetes.io/name: ambassador
35    helm.sh/chart: ambassador-2.8.2
36  name: ambassador
37  namespace: default
38  resourceVersion: "2153"
39  . . .

你为大使服务增加了大使注解栏目,并为API网关在全球配置了GZIP. 在此您已包含配置, 以控制使用 memory_level 的内部内存的量, 它可以是 1 到 9 的值 。 BEST ' 设置的 " 压缩-平面 " 保证了较高的压缩速率,以较高的延迟率为代价。 您已将最小响应长度配置为 256 字节 。 对于content_type`,您已经专门包括了一组产生压缩的介质类型(原为MIME-types). 最后你加入了最后两个配置作为"假"来进行压缩.

您可以在 Envoy 的 GZIP 页面上阅读有关 GZIP 压缩的更多信息。

本服务的任何更改都适用于 API Gateway 的全球配置。

一旦你离开编辑器,你会看到类似于以下的输出:

1[secondary_label Output]
2service/ambassador edited

检查使用curlsvc1.your-domain为具有值gzip内容编码标题:

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

结果将类似于此:

 1[secondary_label Output]
 2HTTP/1.1 200 OK
 3server: envoy
 4date: Mon, 17 Jun 2019 22:25:35 GMT
 5content-type: text/html
 6last-modified: Tue, 21 May 2019 14:23:57 GMT
 7accept-ranges: bytes
 8x-geo-location: India
 9vary: Accept-Encoding
10content-encoding: gzip
11transfer-encoding: chunked
12
13<!DOCTYPE html>
14<html>
15<head>
16<title>Welcome to nginx!</title>
17<style>
18    body {
19        width: 35em;
20        margin: 0 auto;
21        font-family: Tahoma, Verdana, Arial, sans-serif;
22    }
23</style>
24</head>
25<body>
26<h1>Welcome to nginx!</h1>
27<p>If you see this page, the nginx web server is successfully installed and
28working. Further configuration is required.</p>
29
30<p>For online documentation and support please refer to
31<a href="http://nginx.org/">nginx.org</a>.<br/>
32Commercial support is available at
33<a href="http://nginx.com/">nginx.com</a>.</p>
34
35<p><em>Thank you for using nginx.</em></p>
36</body>
37</html>

在这里,您可以看到 Nginx 的默认 HTML 页面,其响应标题显示收到响应的内容编码gzip压缩的。

您已在 Ambassador 中添加了全球配置,以在 API 网关中启用选定的内容类型响应的 GZIP 配置。

结论

您使用 Ambassador 成功为您的 Kubernetes 集群设置了 API 网关,现在您可以使用基于主机和路径的路由、自定义标题和全球 GZIP 压缩来曝光您的应用程序。

有关大使注释和配置参数的更多信息,请参阅 大使官方文件

Published At
Categories with 技术
comments powered by Disqus