如何使用 Helm 在 DigitalOcean Kubernetes 上设置 Nginx Ingress

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

介绍

Kubernetes Ingresses提供了一种灵活的方式来将流量从群集之外路由到内部的Kubernetes服务。Ingress _Resources_是Kubernetes中定义路由HTTP和HTTPS流量到服务的规则的对象。为了这些工作,Ingress _Controller必须通过接受流量(最有可能通过负载平衡器)并将其路由到相应的服务来执行规则。

Helm是用于管理Kubernetes的包管理器。使用Kubernetes的Helm图表提供可配置性和生命周期管理,以更新、重置和删除Kubernetes应用程序。

在本指南中,您将使用 Helm 设置 Kubernetes 维护的 Nginx Ingress Controller 然后创建 Ingress 资源,将流量从您的域路由到例如 Hello World 后端服务。

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

前提条件

步骤 1 – 设置 Hello World 部署

在部署 Nginx Ingress 之前,您将部署一个名为 hello-kubernetesHello World应用程序,以便提供一些服务,您将向其路由流量。

您将将部署配置存储在本地机器上. 如果您想要,您也可以为本教程创建一个目录,在其中您将存储配置。 首个部署配置将在名为hello-kubernetes-first.yaml的文件中。 使用您喜欢的文本编辑器创建它:

1nano hello-kubernetes-first.yaml

添加以下几行:

 1[label hello-kubernetes-first.yaml]
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: hello-kubernetes-first
 6spec:
 7  type: ClusterIP
 8  ports:
 9  - port: 80
10    targetPort: 8080
11  selector:
12    app: hello-kubernetes-first
13---
14apiVersion: apps/v1
15kind: Deployment
16metadata:
17  name: hello-kubernetes-first
18spec:
19  replicas: 3
20  selector:
21    matchLabels:
22      app: hello-kubernetes-first
23  template:
24    metadata:
25      labels:
26        app: hello-kubernetes-first
27    spec:
28      containers:
29      - name: hello-kubernetes
30        image: paulbouwer/hello-kubernetes:1.10
31        ports:
32        - containerPort: 8080
33        env:
34        - name: MESSAGE
35          value: Hello from the first deployment!

该配置定义了部署服务部署paulbouwer/hello-kubernetes:1.7图像的三个副本和一个名为MESSAGE的环境变量组成(当您访问应用程序时,您将看到其值)。

保存并关闭文件。

然后,通过运行以下命令在Kubernetes中创建hello-kubernetes应用程序的第一个变体:

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

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

您将收到以下输出:

1[secondary_label Output]
2service/hello-kubernetes-first created
3deployment.apps/hello-kubernetes-first created

若要验证服务的创建,请运行以下命令:

1kubectl get service hello-kubernetes-first

产出将如下:

1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)   AGE
3hello-kubernetes-first ClusterIP 10.245.124.46   <none>        80/TCP 7s

您会发现新创建的服务具有ClusterIP的分配,这意味着它正在正常工作。向其发送的所有流量将被转移到选择的部署端口8080

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

1nano hello-kubernetes-second.yaml

添加以下几行:

 1[label hello-kubernetes-second.yaml]
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: hello-kubernetes-second
 6spec:
 7  type: ClusterIP
 8  ports:
 9  - port: 80
10    targetPort: 8080
11  selector:
12    app: hello-kubernetes-second
13---
14apiVersion: apps/v1
15kind: Deployment
16metadata:
17  name: hello-kubernetes-second
18spec:
19  replicas: 3
20  selector:
21    matchLabels:
22      app: hello-kubernetes-second
23  template:
24    metadata:
25      labels:
26        app: hello-kubernetes-second
27    spec:
28      containers:
29      - name: hello-kubernetes
30        image: paulbouwer/hello-kubernetes:1.10
31        ports:
32        - containerPort: 8080
33        env:
34        - name: MESSAGE
35          value: Hello from the second deployment!

此变体具有与以前的配置相同的结构. 为了避免碰撞,您可以更改用于部署和服务名称的名称

保存并关闭文件。

现在用以下命令在 Kubernetes 中创建它:

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

产量将是:

1[secondary_label Output]
2service/hello-kubernetes-second created
3deployment.apps/hello-kubernetes-second created

通过列出您的所有服务来验证第二个服务是否正在运行:

1kubectl get service

结果将类似于此:

1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)   AGE
3hello-kubernetes-first ClusterIP 10.245.124.46    <none>        80/TCP 49s
4hello-kubernetes-second ClusterIP 10.245.254.124   <none>        80/TCP 10s
5kubernetes ClusterIP 10.245.0.1       <none>        443/TCP 65m

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

您已经创建了两个hello-kubernetes应用程序的部署,并附有服务,每个部署在部署规格中都有不同的消息,在测试过程中将其区分开来。

步骤 2 — 安装 Kubernetes Nginx Ingress 控制器

现在您将使用 Helm 安装由 Kubernetes 维护的 Nginx Ingress Controller

Nginx Ingress 控制器由一个 Pod 和一个服务组成。 该 Pod 运行控制器,该控制器会不断查询您集群的 API 服务器上的/ingresses终端点,以便更新可用的 Ingress 资源。 该服务是LoadBalancer类型。 由于您正在部署到 DigitalOcean Kubernetes 集群中,集群会自动创建一个 DigitalOcean Load Balancer,通过它将所有外部流量流向控制器。

只有 LoadBalancer 服务知道自动创建的 LoadBalancer 的 IP 地址。 一些应用程序(如 ExternalDNS)需要知道其 IP 地址,但只能读取 Ingress 的配置。 控制器可以通过将 controller.publishService.enabled 参数设置为 true 来配置每一个 Ingress 的 IP 地址。

要将 Nginx Ingress 控制器安装到您的集群中,您首先需要通过运行将其存储库添加到 Helm:

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

产量将是:

1[secondary_label Output]
2"ingress-nginx" has been added to your repositories

更新您的系统,让Helm知道它包含的内容:

1helm repo update

它可能需要一段时间来加载:

1[secondary_label Output]
2Hang tight while we grab the latest from your chart repositories...
3...Successfully got an update from the "ingress-nginx" chart repository
4Update Complete. ⎈Happy Helming!⎈

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

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

此命令会从稳定图表存储库中安装 Nginx Ingress Controller,命名 Helm 释放为nginx-ingress,并将publishService参数设置为true

一旦运行,您将收到类似于此的输出(此输出已被缩小):

1[secondary_label Output]
2NAME: nginx-ingress
3LAST DEPLOYED: Thu Dec 1 11:40:28 2022
4NAMESPACE: default
5STATUS: deployed
6REVISION: 1
7TEST SUITE: None
8NOTES:
9...

Helm 记录了它在 Kubernetes 中创建的资源,作为图表安装的一部分。

运行此命令,查看负载平衡器可用:

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

此命令将 Nginx Ingress 服务提取到默认名称空间并输出其信息,但命令不会立即退出。

在等待负载平衡器可用时,您可能会收到一个等待的响应:

1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)                      AGE SELECTOR
3nginx-ingress-ingress-nginx-controller LoadBalancer 10.245.3.122   <pending>     80:30953/TCP,443:30869/TCP 36s   ...

过了一段时间后,新创建的负载平衡器的IP地址会出现:

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

接下来,您需要确保您的两个域通过 A 记录指向 Load Balancer. 通过您的 DNS 提供商进行此操作. 若要在 DigitalOcean 上配置您的 DNS 记录,请参阅 如何管理 DNS 记录

您已经安装了由 Kubernetes 社区维护的 Nginx Ingress. 它将从负载平衡器中路由 HTTP 和 HTTPS 流量到 Ingress 资源中配置的适当的后端服务。

步骤 3 – 使用 Ingress 曝光应用程序

现在你要创建一个 Ingress 资源,并使用它来暴露你想要的域上的hello-kubernetes应用部署,然后通过从你的浏览器访问它来测试它。

您将将 Ingress 存储在名为 hello-kubernetes-ingress.yaml 的文件中。

1nano hello-kubernetes-ingress.yaml

将以下行添加到您的文件中:

 1[label hello-kubernetes-ingress.yaml]
 2apiVersion: networking.k8s.io/v1
 3kind: Ingress
 4metadata:
 5  name: hello-kubernetes-ingress
 6  annotations:
 7    kubernetes.io/ingress.class: nginx
 8spec:
 9  rules:
10  - host: "hw1.your_domain_name"
11    http:
12      paths:
13      - pathType: Prefix
14        path: "/"
15        backend:
16          service:
17            name: hello-kubernetes-first
18            port:
19              number: 80
20  - host: "hw2.your_domain_name"
21    http:
22      paths:
23      - pathType: Prefix
24        path: "/"
25        backend:
26          service:
27            name: hello-kubernetes-second
28            port:
29              number: 80

然后,您指定两个主机规则,以便hw1.your_domain路由到hello-kubernetes-first服务,而hw2.your_domain路由到第二个部署(‘hello-kubernetes-second’)的服务。

记住用自己的域代替突出的域名,然后保存和关闭文件。

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

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

您现在可以在浏览器中导航到‘hw1.your_domain’。 首个部署将加载:

Hello Kubernetes - First Deployment

第二个变体(hw2.your_domain)会显示不同的消息:

Hello Kubernetes - Second Deployment

您已经验证了 Ingress Controller 是否正确地将请求路由,在这种情况下,从您的两个域到两个不同的服务。

您已经创建并配置了一个 Ingress 资源,以便在您的域内部署hello-kubernetes应用程序. 在下一步中,您将设置 Cert-Manager 以从 Let's Encrypt 获得免费的 TLS 证书来保护您的 Ingress 资源。

步骤 4 – 使用 Cert-Manager 确保入境

为了保护您的 Ingress 资源,您将安装 Cert-Manager,创建一个ClusterIssuer用于生产,并修改您的 Ingress 配置以使用 TLS 证书。

ClusterIssuers是 Kubernetes 中的 Cert-Manager 资源,为整个集群提供 TLS 证书。

在通过 Helm 将 Cert-Manager 安装到您的集群之前,您将为其创建一个名称空间:

1kubectl create namespace cert-manager

您需要将 Jetstack Helm repository添加到Helm,它托管Cert-Manager图表。

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

Helm 会返回以下输出:

1[secondary_label Output]
2"jetstack" has been added to your repositories

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

1helm repo update

更新可能需要一段时间:

1[secondary_label Output]
2Hang tight while we grab the latest from your chart repositories...
3...Successfully got an update from the "ingress-nginx" chart repository
4...Successfully got an update from the "jetstack" chart repository
5Update Complete. ⎈Happy Helming!⎈

最后,在cert-manager名称空间中安装Cert-Manager,运行以下命令:

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

在此命令中,您还将installCRDs参数设置为true,以便在 Helm 安装期间安装 cert-manager CustomResourceDefinition 表达式。

您将获得以下输出:

 1[secondary_label Output]
 2NAME: cert-manager
 3LAST DEPLOYED: Wed Nov 30 19:46:39 2022
 4NAMESPACE: cert-manager
 5STATUS: deployed
 6REVISION: 1
 7TEST SUITE: None
 8NOTES:
 9cert-manager v1.10.1 has been deployed successfully!
10...

输出表明安装成功。

输出的NOTES(在上面的显示中被缩小)表示您需要设置一个发行商来发行TLS证书。

您现在将创建一个Let's Encrypt证书,并将其配置存储在名为 production_issuer.yaml的文件中。

1nano production_issuer.yaml

添加以下几行:

 1[label production_issuer.yaml]
 2apiVersion: cert-manager.io/v1
 3kind: ClusterIssuer
 4metadata:
 5  name: letsencrypt-prod
 6spec:
 7  acme:
 8    # Email address used for ACME registration
 9    email: your_email_address
10    server: https://acme-v02.api.letsencrypt.org/directory
11    privateKeySecretRef:
12      # Name of a secret used to store the ACME account private key
13      name: letsencrypt-prod-private-key
14    # Add a single challenge solver, HTTP01 using nginx
15    solvers:
16    - http01:
17        ingress:
18          class: nginx

此配置定义了一个ClusterIssuer,它与 Let's Encrypt 联系以发行证书. 您需要用您的电子邮件地址更换your_email_address以获取有关证书的安全性和期限的任何通知。

保存并关闭文件。

kubectl滚动它:

1kubectl apply -f production_issuer.yaml

您将获得以下输出:

1[secondary_label Output]
2clusterissuer.cert-manager.io/letsencrypt-prod created

安装了 Cert-Manager 后,您已经准备好将证书输入到前一步定义的 Ingress 资源中,打开 hello-kubernetes-ingress.yaml 以编辑:

1nano hello-kubernetes-ingress.yaml

添加突出的线条:

 1[label hello-kubernetes-ingress.yaml]
 2apiVersion: networking.k8s.io/v1
 3kind: Ingress
 4metadata:
 5name: hello-kubernetes-ingress
 6annotations:
 7  kubernetes.io/ingress.class: nginx
 8  cert-manager.io/cluster-issuer: letsencrypt-prod
 9spec:
10  tls:
11  - hosts:
12    - hw1.your_domain
13    - hw2.your_domain
14    secretName: hello-kubernetes-tls
15  rules:
16  - host: "hw1.your_domain_name"
17    http:
18      paths:
19      - pathType: Prefix
20        path: "/"
21        backend:
22          service:
23            name: hello-kubernetes-first
24            port:
25              number: 80
26  - host: "hw2.your_domain_name"
27    http:
28      paths:
29      - pathType: Prefix
30        path: "/"
31        backend:
32          service:
33            name: hello-kubernetes-second
34            port:
35              number: 80

spec下的tls块定义了什么秘密会为您的网站存储证书(列在主机下),而letsencrypt-prodClusterIssuer发行证书。

请记住,用你自己的域代替‘hw1.your_domain’和‘hw2.your_domain’。当你完成编辑后,保存并关闭文件。

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

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

您将获得以下输出:

1[secondary_label Output]
2ingress.networking.k8s.io/hello-kubernetes-ingress configured

您需要等待几分钟,让 Let’s Encrypt 服务器为您的域发行证书,同时,您可以通过检查以下命令的输出来跟踪进展:

1kubectl describe certificate hello-kubernetes-tls

输出的结尾将类似于此:

1[secondary_label Output]
2Events:
3  Type Reason Age From Message
4  ----    ------     ----   ----                                       -------
5  Normal Issuing 2m34s cert-manager-certificates-trigger Issuing certificate as Secret does not exist
6  Normal Generated 2m34s cert-manager-certificates-key-manager Stored new private key in temporary Secret resource "hello-kubernetes-tls-hxtql"
7  Normal Requested 2m34s cert-manager-certificates-request-manager Created new CertificateRequest resource "hello-kubernetes-tls-jnnwx"
8  Normal Issuing 2m7s cert-manager-certificates-issuing The certificate has been successfully issued

当最后一行输出表示证书已成功发行,您可以按CTRL + C来退出。

在您的浏览器中导航到您的域之一. 您会发现插座显示在URL旁边,表示您的连接现在是安全的。

在此步骤中,您使用 Helm 安装了 Cert-Manager,并创建了一个 Let's Encrypt ClusterIssuer. 然后更新您的 Ingress 资源以利用 Issuer 来生成 TLS 证书。

结论

您现在已经成功地在使用 Helm 的 DigitalOcean Kubernetes 集群上设置了 Nginx Ingress Controller 和 Cert-Manager. 您现在可以将应用程序暴露在您的域的互联网上,通过使用 Let's Encrypt TLS 证书进行保护。

有关 Helm 包管理器的更多信息,请阅读本文 Introduction to Helm

Published At
Categories with 技术
comments powered by Disqus