如何在DigitalOceanKubernetes上使用大使创建API网关

来自菜鸟教程
跳转至:导航、​搜索

作为 Write for DOnations 计划的一部分,作者选择了 Free and Open Source Fund 来接受捐赠。

介绍

Ambassador 是用于云原生应用程序的 API 网关,用于在异构服务之间路由流量并维护分散的工作流。 它充当单一入口点,支持服务发现、配置管理、路由规则和速率限制等任务。 它为您的服务提供了极大的灵活性和易于配置。

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

在本教程中,您将使用 Helm 在 Kubernetes 集群上设置 Ambassador API 网关,并将其配置为根据路由规则将传入流量路由到各种服务。 您将配置这些规则以根据主机名或路径将流量路由到相关服务。

先决条件

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

第 1 步 — 安装大使

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

注意: DigitalOcean Kubernetes 默认启用了RBAC,所以在使用YAML配置文件进行安装时,您需要确保使用启用RBAC的配置文件。 您可以在 Ambassador 的 文档 中找到有关通过 YAML 将 Ambassador 部署到 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

. . .

这将创建一个 Ambassador 部署、服务和一个负载均衡器,并附加您的 Kubernetes 集群节点。 您需要负载均衡器的 IP 将其映射到您域的 A 记录。

要获取您的 Ambassador 负载均衡器的 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

请注意此步骤中的外部 IP your-IP-address 并映射域(通过您的域提供商)svc1.your-domainsvc2.your-domainsvc3.your-domain 以指向该 IP 地址.

您可以使用 如何配置 SSL 终止 中给出的步骤,使用 DigitalOcean 负载均衡器启用 HTTPS。 建议通过负载均衡器配置 TLS 终止。 配置 TLS 终止的另一种方法是使用 Ambassador 的 TLS Support

您已经使用 Helm 在您的 Kubernetes 集群上安装了 Ambassador,Helm 在默认命名空间中创建了一个带有三个副本的 Ambassador 部署。 这还创建了一个具有公共 IP 的负载均衡器,以将所有流量路由到 API 网关。 接下来,您将为三个不同的服务创建 Kubernetes 部署,您将使用这些服务来测试此 API 网关。

第 2 步 — 设置 Web 服务器部署

在本节中,您将创建三个部署来运行三个不同的 Web 服务器容器。 您将为三个不同的 Web 服务器容器创建包含 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

在这里,您定义了一个带有 nginx:latest 容器镜像的 Kubernetes Deployment,该容器镜像将与 1 副本一起部署,称为 svc1Deployment 被定义为在端口 80 处公开集群内。

保存并关闭文件。

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

kubectl apply -f svc1-deploy.yaml

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

Outputdeployment.extensions/svc1 created

现在,创建第二个 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

在这里,您定义了一个带有 httpd 容器镜像的 Kubernetes Deployment,该容器镜像将与 1 副本一起部署,称为 svc2

保存并关闭文件。

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

kubectl apply -f svc2-deploy.yaml

你会看到这个输出:

Outputdeployment.extensions/svc2 created

最后,对于第三次部署,打开并创建 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

在这里,您定义了一个带有 httpbin 容器镜像的 Kubernetes Deployment,该容器镜像将与 1 副本一起部署,称为 svc3

保存并关闭文件。

最后,运行以下命令进行应用:

kubectl apply -f svc3-deploy.yaml

您将看到以下输出:

Outputdeployment.extensions/svc3 created

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

第 3 步 — 使用带大使注释的服务公开应用程序

在本节中,您将向 Internet 公开您的 Web 应用程序,使用 Ambassador annotations 创建 Kubernetes 服务,以配置规则以将流量路由到它们。 Kubernetes 中的注解是一种向对象添加元数据的方法。 Ambassador 使用来自服务的这些注释值来配置其路由规则。

提醒一下,您需要在 DNS 记录中将您的域(例如:svc1.your-domainsvc2.your-domainsvc3.your-domain)映射到负载均衡器的公共 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 代码中,您定义了一个带有 Ambassador 注解的 Kubernetes 服务 svc1 以将主机名 svc1.your-domain 映射到此服务。

保存并退出svc1-service.yaml,然后执行以下命令应用此配置:

kubectl apply -f svc1-service.yaml

你会看到这个输出:

Outputservice/svc1 created

使用大使注释为 svc2 部署创建您的第二个 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 注解的 Kubernetes 服务,当 Ambassador 收到任何带有 host 标头值为 svc2.your-domain 的请求时,将流量路由到 svc2。 因此,此基于主机的路由将允许您向子域 svc2.your-domain 发送请求,该子域会将流量路由到服务 svc2 并从 httpd Web 服务器处理您的请求.

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

kubectl apply -f svc2-service.yaml

您将看到以下输出:

Outputservice/svc2 created

为您的 svc3 部署创建第三个 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 以将第二个 Ambassador 注释块附加到将 /bin 路由到 svc3 服务:

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

您已添加第二个 Ambassador 注释块来配置以 /bin 开头的路径以映射到您的 svc3 Kubernetes 服务。 为了将 svc2.your-domain/bin 的请求路由到 svc3,您在此处添加了第二个注释块作为主机值 svc2.your-domain,这对于两个块都是相同的。 因此,基于路径的路由将允许您向 svc2.your-domain/bin 发送请求,该请求将由服务 svc3 接收并由本教程中的 httpbin 应用程序提供服务

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

kubectl apply -f svc2-service.yaml

你会看到这个输出:

Outputservice/svc2 configured

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

第 4 步 — 路由的高级大使配置

在本节中,您将使用进一步的 Ambassador 注释来配置服务,以 修改标头配置重定向

curlsvc1.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 路由的服务接收到的标头。 您将使用大使注释将自定义标头添加到您的服务响应中,并验证新添加的标头的输出。

要将自定义标头添加到您的服务响应,请从响应中删除标头 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 配置 svc3svc2.your-domain/bin 的 301 重定向响应。 host_redirect 参数向客户端发送 301 重定向响应。 如果未设置,请求将收到 200 个 HTTP 响应而不是 301 个 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 的 HTTP 标头,表明您的服务注释中的 host_redirect: true 配置已正确提供 HTTP 状态代码:301 Moved Permanently

您已使用大使注释配置服务以修改 HTTP 标头并配置重定向。 接下来,您将向 Ambassador API 网关服务添加全局配置。

第 5 步 — 设置大使全局配置

在本节中,您将编辑大使服务以添加全局 GZIP 压缩配置。 GZIP 压缩将压缩 HTTP 资产大小并减少网络带宽需求,从而加快 Web 客户端的响应时间。 此配置会影响通过大使 API 网关路由的所有流量。 同样,您可以使用 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 服务并为 API 网关全局配置 GZIP。 此处包含用于控制 memory_level 使用的内部内存量的配置,该值可以是 1 到 9 之间的值。 设置为 BESTcompression_level 以更高的延迟为代价确保更高的压缩率。 使用 min_content_length 已将最小响应长度配置为 256 字节。 对于 content_type,您特别包含了一组产生压缩的 媒体类型 (以前的 MIME 类型)。 最后,您将最后两个配置添加为 false 以允许压缩。

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

此服务中的任何更改都将作为 API 网关的全局配置应用。

退出编辑器后,您将看到类似于以下内容的输出:

Outputservice/ambassador edited

使用 curl 检查 svc1.your-domain 以获取具有值 gzipcontent-encoding 标头:

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>

在这里您可以看到 Nginx 的默认 HTML 页面,其响应标头显示接收到的响应的 content-encodinggzip 压缩的。

您已将全局配置添加到 Ambassador,以便为跨 API 网关的选定内容类型响应启用 GZIP 配置。

结论

您已使用 Ambassador 为您的 Kubernetes 集群成功设置 API 网关。 您现在可以使用基于主机和路径的路由、自定义标头和全局 GZIP 压缩来公开您的应用程序。

有关大使注解和配置参数的更多信息,请阅读 Ambassador 的官方文档