作者选择了 自由和开源基金作为 写给捐款计划的一部分接受捐款。
介绍
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.20版本上方的Kubernetes集群,由您配置的
kubectl
默认连接配置所设置。 此设置将使用有三个节点的 [数字海洋库伯内特斯] (https://www.digitalocean.com/products/kubernetes/) 集群, 但您也可以[手动创建集群] (https://andsky.com/tech/tutorials/how-to-create-a-kubernetes-cluster-using-kubeadm-on-ubuntu-20-04). 要在数字海洋云面板中创建一个库伯内特斯集群,请参见我们的[库伯内特斯快速起 (https://www.digitalocean.com/docs/kubernetes/quickstart/). kubectl' 命令行工具安装在您的本地环境中并配置到连接您的集群 。 您可以在 [正式文件] (https://kubernetes.io/docs/tasks/tools/install-kubectl/) 中读取更多关于安装
kubectl的内容。 如果您正在使用 Digital Ocean Kubernetes 集群, 关于如何配置
kubectl的指令会在创建您的集群时在 ** Connect 到您的集群** 中, 您也可以引用
如何连接到 Digital Ocean Kubernetes 集群`( https://docs.digitalocean.com/products/kubernetes/how-to/connect-to-cluster/) 文件 。- 数字海洋命令行客户端[`doctl' (https://docs.digitalocean.com/reference/doctl/how-to/install/),安装在您的机器上. 关于使用 " doctl " 的更多信息,见如何使用doctl。
- 您开发环境中可用的Helm 3 软件包管理器 。 完成 Helm 3 软件包管理器在Kubernetes集群上安装软件的步骤1。
- 一个完全注册的域名,有两个可用的A记录. 此教程将始终使用
hw1. 您的域
和hw2. 您的域
。 您可以在 [Namecheap] (https://www.namecheap.com/ 上购买域名, 在 [Freenom] (https://www.freenom.com/en/index.html?lang=en ) 上免费获取域名, 或者使用您选择的域名登记员 。 这些 A 记录将被引导到您将在第二步中创建的负载平衡器 。 (英语)
步骤 1 – 设置 Hello World 部署
在部署 Nginx Ingress 之前,您将部署一个名为 hello-kubernetes
的Hello 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-first
和hello-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’。 首个部署将加载:
第二个变体(hw2.your_domain
)会显示不同的消息:
您已经验证了 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-prod
的ClusterIssuer
发行证书。
请记住,用你自己的域代替‘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。