Helm部署Nginx Ingress:Silicon Cloud Kubernetes实战指南

导语

Kubernetes 的 Ingress 提供了灵活的方式,将集群外部的流量路由到内部的 Kubernetes 服务。Ingress 资源是 Kubernetes 中定义 HTTP 和 HTTPS 流量路由规则到服务的对象。要使其生效,必须有一个 Ingress 控制器来实现这些规则,它通过接收流量(通常通过负载均衡器)并将其路由到适当的服务。大多数 Ingress 控制器只使用一个全局负载均衡器来处理所有的 Ingress,这比为每个要暴露的服务创建一个负载均衡器更高效。

Helm 是用于管理 Kubernetes 的软件包管理器。在 Kubernetes 中使用 Helm Charts 可以提供配置性和生命周期管理,用于更新、回滚和删除 Kubernetes 应用程序。

在本指南中,您将使用 Helm 设置 Kubernetes 维护的 Nginx Ingress 控制器。然后,您将创建一个 Ingress 资源,将流量从您的域名路由到示例“Hello World”后端服务。一旦设置了 Ingress,您将向集群安装 Cert Manager,以自动提供 Let’s Encrypt TLS 证书来保护您的 Ingresses。

如果您正在寻找一种托管的 Kubernetes 主机服务,那么请查看我们专为增长而构建的简单、托管的 Kubernetes 服务。

先决条件

  • 一个 Kubernetes 集群,版本高于 1.20,并且其连接配置已设置为 kubectl 默认。本设置将使用一个包含三个节点的 Silicon Cloud Kubernetes 集群,但您也可以手动创建一个集群。要在 Silicon Cloud 控制面板中创建 Kubernetes 集群,请参阅我们的 Kubernetes 快速入门
  • kubectl 命令行工具已安装在您的本地环境中,并配置为连接到您的集群。您可以阅读官方文档了解更多关于安装 kubectl 的信息。如果您正在使用 Silicon Cloud Kubernetes 集群,关于如何配置 kubectl 的说明在您创建集群时的“连接到您的集群”部分中,您也可以参考 如何连接到 Silicon Cloud Kubernetes 集群 文档。
  • Silicon Cloud 命令行客户端 doctl 已安装在您的机器上。有关使用 doctl 的更多信息,请参阅 如何使用 doctl
  • Helm 3 包管理器在您的开发环境中可用。请完成 使用 Helm 3 包管理器在 Kubernetes 集群上安装软件 教程的第 1 步。
  • 一个完全注册的域名,并有两个可用的 A 记录。本教程将全程使用 hw1.your_domain 和 hw2.your_domain。您可以在 Namecheap 购买域名,在 Freenom 免费获取一个,或者使用您选择的域名注册商。这些 A 记录将指向您将在第 2 步中创建的负载均衡器。

步骤一:建立“Hello World”部署

在部署 Nginx Ingress 之前,您将部署一个名为 hello-kubernetes 的“Hello World”应用程序,以便有一些服务可以通过路由发送流量。为了确认 Nginx Ingress 在接下来的步骤中正常工作,您将部署两次,每次使用不同的欢迎消息,在您从浏览器访问时将显示。

您将在本地计算机上存储部署配置。如果您愿意,您还可以创建一个目录,用于存储此教程中的配置。第一个部署配置文件将命名为 hello-kubernetes-first.yaml。请使用您喜欢的文本编辑器创建它。

  1. nano hello-kubernetes-first.yaml

 

请加入以下内容:

这是文章《如何在Silicon Cloud Kubernetes上使用Helm设置Nginx Ingress》的第2部分(共10部分)。

apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes-first
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: hello-kubernetes-first
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes-first
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-kubernetes-first
  template:
    metadata:
      labels:
        app: hello-kubernetes-first
    spec:
      containers:
      - name: hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.10
        ports:
        - containerPort: 8080
        env:
        - name: MESSAGE
          value: Hello from the first deployment!

此配置定义了一个部署(Deployment)和一个服务(Service)。该部署由三个副本的paulbouwer/hello-kubernetes:1.7镜像和一个名为MESSAGE的环境变量组成(当您访问应用程序时,您会看到其值)。此处定义的服务旨在将部署在集群内部通过80端口暴露。

保存并关闭文件。

然后,在Kubernetes中运行以下命令来创建hello-kubernetes应用的第一个变体。

  1. kubectl create -f hello-kubernetes-first.yaml

 

-f选项指示create命令使用文件hello-kubernetes-first.yaml

您将收到以下输出:

输出

这是文章《如何使用Helm在Silicon Cloud Kubernetes上设置Nginx Ingress》的第3部分(共10部分)。

service/hello-kubernetes-first created
deployment.apps/hello-kubernetes-first created

运行以下命令以验证服务的创建。

  1. kubectl get service hello-kubernetes-first

输出将会是以下内容:

输出
NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
hello-kubernetes-first   ClusterIP   10.245.124.46    <none>        80/TCP    7s

你会发现新创建的Service(服务)有一个分配的ClusterIP(集群IP),这意味着它正常工作。所有发送到它的流量将被转发到选定的8080端口上的Deployment(部署)。现在你已经部署了hello-kubernetes应用的第一个变体,接下来你将处理第二个。

创建一个名为hello-kubernetes-second.yaml的新文件。

  1. nano hello-kubernetes-second.yaml

请添加以下行:

你好,kubernetes-second.yaml

这是文章《如何在Silicon Cloud Kubernetes上使用Helm设置Nginx Ingress》的第4部分(共10部分)。

apiVersion: v1
kind: Service
metadata:
  name: hello-kubernetes-second
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: hello-kubernetes-second
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes-second
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-kubernetes-second
  template:
    metadata:
      labels:
        app: hello-kubernetes-second
    spec:
      containers:
      - name: hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.10
        - containerPort: 8080
        env:
        - name: MESSAGE
          value: Hello from the second deployment!

这个变体与之前的配置具有相同的结构。为了避免冲突,您需要更改部署和服务名称。同时,您还需要更新将在浏览器中显示的信息值。

保存并关闭文件。

现在使用下面的命令在Kubernetes中创建它:

  1. kubectl create -f hello-kubernetes-second.yaml

 

输出将是:

输出

这是文章《如何使用Helm在Silicon Cloud Kubernetes上设置Nginx Ingress》的第5部分(共10部分)。

service/hello-kubernetes-second created
deployment.apps/hello-kubernetes-second created

通过列出所有服务来验证第二个服务是否正常运行。

  1. kubectl get service

输出将类似于这样:

输出
NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
hello-kubernetes-first  ClusterIP   10.245.124.46   <none>        80/TCP          49s
hello-kubernetes-second ClusterIP   10.245.254.124  <none>        80/TCP          10s
kubernetes              ClusterIP   10.245.0.1      <none>        443/TCP         65m

hello-kubernetes-firsthello-kubernetes-second 都已列出,这意味着 Kubernetes 已经成功创建了它们。

在测试过程中,您创建了两个 hello-kubernetes 应用的部署及其相应的服务。每个部署规范中都设置了不同的消息,以便在测试中进行区分。接下来,您将安装 Nginx Ingress Controller。

第二步 – 安装 Kubernetes Nginx Ingress 控制器

现在您将使用 Helm 安装 Kubernetes 维护的 Nginx Ingress 控制器。

Nginx Ingress Controller 由一个 Pod 和一个 Service 组成。Pod 运行 Controller,它会不断轮询集群的 API 服务器上的 /ingresses 端点,以获取可用的 Ingress 资源的更新。Service 的类型是 LoadBalancer。由于您将其部署到 Silicon Cloud Kubernetes 集群,集群将自动创建一个 Silicon Cloud 负载均衡器,通过该负载均衡器将所有外部流量流向 Controller。然后,Controller 将根据 Ingress 资源中定义的规则,将流量路由到适当的 Services。

只有负载均衡器服务才知道自动创建的负载均衡器的 IP 地址。一些应用程序(例如 ExternalDNS)需要知道其 IP 地址,但只能读取 Ingress 的配置。在 Helm 安装期间,可以通过将 controller.publishService.enabled 参数设置为 true 来配置控制器在每个 Ingress 上发布 IP 地址。建议启用此设置以支持可能依赖负载均衡器 IP 地址的应用程序。

要将 Nginx Ingress Controller 安装到您的集群中,首先需要通过运行以下命令将其存储库添加到 Helm 中:

  1. helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

结果将是:

输出
"ingress-nginx" has been added to your repositories

更新您的系统,使得 Helm 知道其中包含的内容。

  1. helm repo update

可能需要一点时间来加载。

输出
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "ingress-nginx" chart repository
Update Complete. ⎈Happy Helming!⎈

最后,运行以下命令来安装 Nginx Ingress:

  1. helm install nginx-ingress ingress-nginx/ingress-nginx –set controller.publishService.enabled=true

使用以下命令从稳定图表存储库安装 Nginx Ingress Controller,将 Helm 发布命名为 nginx-ingress,并将 publishService 参数设置为 true

一旦程序运行完毕,您将会收到一个类似如下的输出(此输出已被截断)。

输出
NAME: nginx-ingress
LAST DEPLOYED: Thu Dec  1 11:40:28 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES: ...

Helm 在安装图表的过程中,已将其所创建的资源记录在 Kubernetes 中。

运行此命令以观察负载均衡器变为可用状态:

  1. kubectl –namespace default get services -o wide -w nginx-ingress-ingress-nginx-controller

这个命令从默认命名空间获取 Nginx Ingress 服务的信息并输出,但命令不会立即退出。使用 -w 参数后,当发生变化时,它会监视并刷新输出。

当等待负载均衡器变得可用时,您可能会收到一个挂起的响应。

输出
NAME                                     TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE   SELECTOR
nginx-ingress-ingress-nginx-controller   LoadBalancer   10.245.3.122    <pending>     80:30953/TCP,443:30869/TCP   36s   ...

过一段时间后,您新创建的负载均衡器的 IP 地址将会显示出来。

输出

这是文章《如何使用Helm在Silicon Cloud Kubernetes上设置Nginx Ingress》的第6部分(共10部分)。

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
nginx-ingress-ingress-nginx-controller LoadBalancer 10.245.3.122 167.99.16.184 80:30953/TCP,443:30869/TCP 2m29s ...

接下来,您需要确保通过A记录将您的两个域名指向负载均衡器。这需要通过您的DNS提供商完成。要在Silicon Cloud上配置您的DNS记录,请参阅《如何管理DNS记录》。

您已经安装了由Kubernetes社区维护的Nginx Ingress。它将把HTTP和HTTPS流量从负载均衡器路由到在Ingress资源中配置的适当后端服务。下一步,您将使用Ingress资源来暴露hello-kubernetes应用程序的部署。

第三步 – 使用 Ingress 来暴露应用程序

现在您将创建一个Ingress资源,并使用它来将hello-kubernetes应用的部署暴露在您期望的域名下。然后您将通过浏览器访问来测试它。

使用编辑器创建一个名为hello-kubernetes-ingress.yaml的文件,并将Ingress配置存储在其中。

  1. nano hello-kubernetes-ingress.yaml

在您的文件中添加以下内容:

你好,Kubernetes Ingress 的配置文件 hello-kubernetes-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-kubernetes-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: "hw1.your_domain_name"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-kubernetes-first
            port:
              number: 80
  - host: "hw2.your_domain_name"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-kubernetes-second
            port:
              number: 80

您可以通过命名为hello-kubernetes-ingress的Ingress资源来定义。然后,您可以指定两个主机规则,将hw1.your_domain路由到hello-kubernetes-first服务,并将hw2.your_domain路由到第二个部署(hello-kubernetes-second)的服务。

请记得将高亮显示的域名替换为您自己的域名,然后保存并关闭文件。

通过运行以下命令在Kubernetes中创建它:

  1. kubectl apply -f hello-kubernetes-ingress.yaml

您现在可以在浏览器中导航到 hw1.your_domain。首次部署将会加载。

Hello Kubernetes - First Deployment

第二个变量(hw2.your_domain)将显示不同的消息。

Hello Kubernetes - 第二次部署

您已验证,Ingress Controller 正确地将请求路由到两个不同的服务,这些服务分别来自您的两个域名。

您已经创建并配置了一个 Ingress 资源,以便在您的域名上提供 hello-kubernetes 应用程序的部署。接下来,您将设置 Cert-Manager,以使用来自 Let’s Encrypt 的免费 TLS 证书来保护您的 Ingress 资源。

第四步 – 使用 Cert-Manager 保护 Ingress

为了保护您的 Ingress 资源,您需要安装 Cert-Manager,并为生产环境创建一个 ClusterIssuer,然后修改 Ingress 的配置以使用 TLS 证书。安装和配置完成后,您的应用程序将在 HTTPS 背后运行。

ClusterIssuer 是 Kubernetes 中的 Cert-Manager 资源,用于为整个集群提供 TLS 证书。ClusterIssuer 是一种特定类型的颁发者。

在使用 Helm 将 Cert-Manager 安装到您的集群之前,您需要为其创建一个命名空间。

  1. kubectl create namespace cert-manager

 

您需要将 Jetstack Helm 存储库添加到 Helm 中,该存储库托管 Cert-Manager 图表。要执行此操作,请运行以下命令:

  1. helm repo add jetstack https://charts.jetstack.io

 

Helm 将返回以下输出:

输出

“jetstack” 已添加到您的存储库中

然后,更新 Helm 的图表缓存。

  1. helm repo update

 

更新可能需要一点时间。

输出

请稍等,我们正在从您的图表存储库中获取最新内容… …成功从 “ingress-nginx” 图表存储库获取更新 …成功从 “jetstack” 图表存储库获取更新 更新完成。 ⎈祝您 Helm 使用愉快!⎈

最后,通过运行以下命令将 Cert-Manager 安装到 cert-manager 命名空间中:

  1. helm install cert-manager jetstack/cert-manager –namespace cert-manager –version v1.10.1 –set installCRDs=true

 

在此命令中,您还需要将 installCRDs 参数设置为 true,以便在 Helm 安装期间安装 cert-manager 的 CustomResourceDefinition 清单。在撰写本文时,v1.10.1 是最新版本。您可以参考 ArtifactHub 查找最新的版本号。

您将收到以下输出结果:

输出

名称: cert-manager 最后部署: 2022年11月30日 19:46:39 命名空间: cert-manager 状态: 已部署 修订版本: 1 测试套件: 无 注意: cert-manager v1.10.1 已成功部署! …

输出表明安装成功。

上面显示的输出(已截断)的注释说明您需要设置颁发者(Issuer)以颁发 TLS 证书。

现在您将创建一个用于发布 Let’s Encrypt 证书的工具,并将其配置保存在名为 production_issuer.yaml 的文件中。创建并打开这个文件。

  1. nano production_issuer.yaml

 

请添加以下内容:

生产_发行者.yaml

这是文章《如何在Silicon Cloud Kubernetes上使用Helm设置Nginx Ingress》的第8部分(共10部分)。

内容片段:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    # 用于ACME注册的电子邮件地址
    email: your_email_address
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      # 用于存储ACME账户私钥的Secret名称
      name: letsencrypt-prod-private-key
    # 添加一个挑战求解器,使用nginx的HTTP01
    solvers:
    - http01:
        ingress:
          class: nginx

此配置定义了一个ClusterIssuer,它将联系Let’s Encrypt以颁发证书。您需要将your_email_address替换为您的电子邮件地址,以便接收有关证书安全性和过期时间的通知。

保存并关闭文件。

使用kubectl进行部署。

  1. kubectl apply -f production_issuer.yaml

您将收到以下输出结果。

输出

clusterissuer.cert-manager.io/letsencrypt-prod created

安装Cert-Manager后,您可以准备将证书引入到之前步骤中定义的Ingress资源中。打开hello-kubernetes-ingress.yaml进行编辑。

  1. nano hello-kubernetes-ingress.yaml

请添加这些标记的句子。

添加标记的句子。

你好,Kubernetes入口配置文件。

这是文章《如何在Silicon Cloud Kubernetes上使用Helm设置Nginx Ingress》的第9部分(共10部分)。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-kubernetes-ingress
annotations:
  kubernetes.io/ingress.class: nginx
  cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - hw1.your_domain
    - hw2.your_domain
    secretName: hello-kubernetes-tls
  rules:
  - host: "hw1.your_domain_name"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-kubernetes-first
            port:
              number: 80
  - host: "hw2.your_domain_name"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-kubernetes-second
            port:
              number: 80

spec下的tls块定义了将存储您网站证书(列在hosts下)的Secret,该证书由letsencrypt-prod ClusterIssuer颁发。对于您创建的每个Ingress,secretName必须不同。

请记得将hw1.your_domainhw2.your_domain替换为您自己的域名。完成编辑后,请保存并关闭文件。

通过运行以下命令,重新将此配置应用到您的集群中。

  1. kubectl apply -f hello-kubernetes-ingress.yaml

 

您将收到以下输出:

输出

ingress.networking.k8s.io/hello-kubernetes-ingress 已配置。

您需要等待几分钟,让 Let’s Encrypt 服务器为您的域名颁发证书。在此期间,您可以通过检查以下命令的输出来跟踪进度:

  1. kubectl describe certificate hello-kubernetes-tls

 

输出的结尾将类似于这样:

输出

Events: Type Reason Age From Message

—- —— —- —- ——-

Normal Issuing 2m34s cert-manager-certificates-trigger Issuing certificate as Secret does not exist

Normal Generated 2m34s cert-manager-certificates-key-manager Stored new private key in temporary Secret resource “hello-kubernetes-tls-hxtql”

Normal Requested 2m34s cert-manager-certificates-request-manager Created new CertificateRequest resource “hello-kubernetes-tls-jnnwx”

Normal Issuing 2m7s cert-manager-certificates-issuing The certificate has been successfully issued

当输出的最后一行显示证书已成功颁发时,您可以通过按 CTRL + C 退出。

在浏览器中导航到您的任一域名。您会发现 URL 旁边出现小锁图标,表示您的连接现在是安全的。

在此步骤中,您使用 Helm 安装了证书管理器 Cert-Manager,并创建了一个 Let’s Encrypt Cluster Issuer。然后,您更新了 Ingress 资源,以利用该 Issuer 来生成 TLS 证书。最后,您通过在浏览器中导航到其中一个域名,确认 HTTPS 正常工作。

结论

您已成功地在您的 Silicon Cloud Kubernetes 集群上使用 Helm 设置了 Nginx Ingress Controller 和 Cert-Manager。现在,您可以使用 Let’s Encrypt TLS 证书来保护您的应用程序,并将其暴露在您的域名下,使其可以通过互联网访问。

了解有关 Helm 软件包管理器的更多信息,请阅读这份关于 Helm 的介绍

bannerAds