使用 Google 云重定向 URL

Redirect URLs using Google Cloud

我已经在 Cloud DNS 中配置了一个域 (example.com)。通过这个域,我可以访问 GKE 集群中的微服务。我在 CloudDNS 中使用 istio-ingressgateway IP 来建立集群之间的关联

现在我有了另一个域 (newexample.com),它带有用于 https 连接的自定义证书。有没有办法将所有对newexample.com的请求重定向到example.com?如果可能,我不想更改 gke/istio 配置中的任何内容。

每种方法都需要在任一 GKE/Istio 端进行一些重新配置。

其中一个解决方案是在云 DNS 中有一个 CNAME 记录和一个带有 Alternative Names 的 SSL 证书。

使用上述解决方案,假设正确的 Istio 配置,您将能够使用两个域名向您的 GKE/Istio 集群发送请求。


什么是CNAME

CNAME is a Canonical Name Record or Alias Record.

A type of resource record in the Domain Name System (DNS), that specifies that one domain name is an alias of another canonical domain name.

CNAME 记录示例:

DNS name       Type      TTL     Data
old.domain.    A         60      1.2.3.4
new.domain.    CNAME     60      old.domain.

替代名称:

A SAN or subject alternative name is a structured way to indicate all of the domain names and IP addresses that are secured by the certificate.

Enstrustdatacard.com: What is a san and how is it used

您可以创建 SSL 证书以支持两者:

  • old.domain
  • new.domain

有很多选项可以做到这一点,例如 Let's Encrypt 或 Cert Manager。


例子

我创建了一个示例来向您展示如何操作:

  • 在 Cloud DNS 中配置 DNS zone
  • 使用服务创建基本应用程序
  • 为示例应用创建证书
  • 创建 Istio 资源以允许连接到示例应用程序
  • 测试

在云 DNS 中配置 DNS zone

您需要有 2 条记录:

  • A 记录您的 Ingress Gateway 的 IP 和名称:old.domain
  • CNAME 记录指向 old.domain,名称为:new.domain

请查看官方文档:Cloud.google.com: DNS: Records

创建带有服务的基本应用程序

下面是一个示例应用程序,其服务将以基本的问候响应:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-dp
spec:
  selector:
    matchLabels:
      app: hello-dp
  replicas: 1
  template:
    metadata:
      labels:
        app: hello-dp
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50001"
---
apiVersion: v1
kind: Service
metadata:
  name: hello-sv
spec:
  selector:
    app: hello-dp
  ports:
    - name: hello-port
      protocol: TCP
      port: 50001
      targetPort: 50001
  type: ClusterIP

为示例应用创建证书

如前所述,可以使用 Let's Encrypt 创建具有 Alternative Names 的证书。我创建了它:

  • GCE VM Ubuntu 16.04
  • 打开80端口
  • 域名old.domain指向public虚拟机ip地址
  • 指南:Linode.com: Docs: Install let's encrypt to create a SSL certificate
  • 创建证书的命令:

    $ ./letsencrypt-auto certonly --standalone -dold.domain-dnew.domain

  • 在 /etc/letsencrypt/archive/ 中创建的证书用于使用命令为 GKE 创建 tls 机密:

    $ kubectl create secret tlsssl-certificate--cert cert1.pem --key privkey1.pem

请记住,此证书仅用于测试目的,我强烈建议使用专用解决方案,例如:Cert-manager

PS:如果您使用此方法,请还原云 DNS 中的更改以指向 Istio 网关。


创建 Istio 资源以允许连接到示例应用程序

下面是示例 Istio 资源,允许连接到支持 HTTPS 的示例应用程序:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: hello-gw
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: ssl-certificate
    hosts:
    - "old.domain"
    - "new.domain"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: hello-vs
spec:
  hosts:
  - "old.domain"
  - "new.domain"
  gateways:
  - hello-gw
  http:
  - route:
    - destination:
        host: hello-sv
        port:
          number: 50001

具体请看:

    tls:
      mode: SIMPLE
      credentialName: ssl-certificate

这部分将确保与集群的连接将使用 HTTPS

此外:

  hosts:
  - "old.domain"
  - "new.domain"

两个资源中的以上定义将只允许与指定域的连接。

测试

应用上述所有资源后,您应该能够在浏览器中输入:

  • https://old.domain
  • https://new.domain

并收到以下消息和有效的 SSL 证书:

Hello, world!
Version: 2.0.0
Hostname: hello-dp-5dd8b85b56-bk7zr