作为Write for DOnations计划的一部分,作者选择了免费和开源基金来接受捐赠。
介绍
Kubernetes Ingress为您提供了一种灵活的方式,将流量从集群外路由到内部 Kubernetes 服务。入口资源是 Kubernetes 中的对象,用于定义将 HTTP 和 HTTPS 流量路由到服务的规则。为了让这些工作,入口控制器必须存在;它的作用是通过接受流量(最有可能通过负载均衡器)并将其路由到适当的服务来实施规则。大多数 Ingress Controller 仅对所有 Ingress 使用一个全局负载均衡器,这比为您希望公开的每个服务创建一个负载均衡器更有效。
Helm是用于管理 Kubernetes 的包管理器。将 Helm Charts 与 Kubernetes 结合使用提供了可配置性和生命周期管理,以更新、回滚和删除 Kubernetes 应用程序。
在本指南中,您将使用 Helm设置由 Kubernetes 维护的Nginx 入口控制器。然后,您将创建一个入口资源以将流量从您的域路由到示例 Hello World 后端服务。设置 Ingress 后,您将在集群中安装Cert Manager,以便能够自动配置 Let’s Encrypt TLS 证书以保护您的 Ingress。
先决条件
-
一个 DigitalOcean Kubernetes 1.16+ 集群,您的连接配置被配置为
kubectl
默认配置。创建集群时kubectl
显示的“连接到集群”步骤下显示了有关如何配置的说明。要了解如何在 DigitalOcean 上创建 Kubernetes 集群,请参阅Kubernetes 快速入门。 -
安装在本地机器上的 Helm 3 包管理器。完成第1步的如何与头盔3包管理器上Kubernetes集群上安装软件的教程。
-
一个完全注册的域名,有两个可用的 A 记录。本教程将使用
hw1.your_domain
和hw2.your_domain
通篇。你可以购买一个域名Namecheap,免费获得一个在Freenom,或使用你选择的域名注册商。
第 1 步 – 设置 Hello World 部署
在本节中,在部署 Nginx Ingress 之前,您将部署一个 Hello World 应用程序hello-kubernetes
,该应用程序被调用来拥有一些您将流量路由到的服务。为了确认 Nginx Ingress 在接下来的步骤中正常工作,您将部署它两次,每次都带有不同的欢迎消息,当您从浏览器访问它时将显示不同的欢迎消息。
您将在本地计算机上存储部署配置。第一个部署配置将位于名为hello-kubernetes-first.yaml
. 使用文本编辑器创建它:
- nano hello-kubernetes-first.yaml
添加以下几行:
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.8
ports:
- containerPort: 8080
env:
- name: MESSAGE
value: Hello from the first deployment!
此配置定义了一个部署和一个服务。Deployment 由镜像的三个副本paulbouwer/hello-kubernetes:1.7
和一个名为的环境变量组成MESSAGE
——您将在访问应用程序时看到它的值。这里的 Service 被定义为在端口 暴露集群内部署80
。
保存并关闭文件。
然后,hello-kubernetes
通过运行以下命令在 Kubernetes 中创建应用程序的第一个变体:
- kubectl create -f hello-kubernetes-first.yaml
您将收到以下输出:
Outputservice/hello-kubernetes-first created
deployment.apps/hello-kubernetes-first created
要验证服务的创建,请运行以下命令:
- kubectl get service hello-kubernetes-first
输出如下:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-kubernetes-first ClusterIP 10.245.124.46 <none> 80/TCP 7s
您会发现新创建的 Service 分配了一个 ClusterIP,这意味着它可以正常工作。发送到它的所有流量都将转发到端口上的选定部署8080
。现在您已经部署了hello-kubernetes
应用程序的第一个变体,您将处理第二个变体。
打开一个hello-kubernetes-second.yaml
需要编辑的文件:
- nano hello-kubernetes-second.yaml
添加以下几行:
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.8
ports:
- containerPort: 8080
env:
- name: MESSAGE
value: Hello from the second deployment!
保存并关闭文件。
此变体与之前的配置具有相同的结构;唯一的区别在于部署和服务名称,以避免冲突,以及消息。
现在使用以下命令在 Kubernetes 中创建它:
- kubectl create -f hello-kubernetes-second.yaml
输出将是:
Outputservice/hello-kubernetes-second created
deployment.apps/hello-kubernetes-second created
通过列出您的所有服务来验证第二个服务是否已启动并正在运行:
- kubectl get service
输出将类似于:
OutputNAME 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-first
并hello-kubernetes-second
上市,这意味着Kubernetes创造了他们成功。
您已经创建了hello-kubernetes
应用程序的两个部署以及随附的服务。每个在部署规范中都有不同的消息集,这允许您在测试期间区分它们。在下一步中,您将安装 Nginx 入口控制器本身。
第 2 步 – 安装 Kubernetes Nginx 入口控制器
现在,您将使用 Helm安装 Kubernetes 维护的Nginx 入口控制器。请注意,有几个Nginx Ingresses。
Nginx Ingress Controller 由 Pod 和 Service 组成。Pod 运行控制器,它会不断轮询/ingresses
集群 API 服务器上的端点,以获取可用 Ingress 资源的更新。Service 属于 LoadBalancer 类型,因为您将其部署到 DigitalOcean Kubernetes 集群,该集群将自动创建一个DigitalOcean Load Balancer,所有外部流量都将通过它流向 Controller。然后,控制器会将流量路由到适当的服务,如入口资源中所定义。
只有 LoadBalancer Service 知道自动创建的 Load Balancer 的 IP 地址。一些应用程序(例如ExternalDNS)需要知道其 IP 地址,但只能读取 Ingress 的配置。通过将controller.publishService.enabled
参数设置为true
during ,可以将 Controller 配置为在每个 Ingress 上发布 IP 地址helm install
。建议启用此设置以支持可能依赖负载均衡器 IP 地址的应用程序。
要将 Nginx Ingress Controller 安装到您的集群,您首先需要通过运行将其存储库添加到 Helm:
- helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
输出将是:
Output"ingress-nginx" has been added to your repositories
更新以让 Helm 知道它包含的内容:
- helm repo update
最后,运行以下命令安装 Nginx ingress:
- helm install nginx-ingress ingress-nginx/ingress-nginx --set controller.publishService.enabled=true
此命令从stable
charts 存储库安装 Nginx Ingress Controller ,将 Helm 版本命名为nginx-ingress
,并将publishService
参数设置为true
。
输出如下:
OutputNAME: nginx-ingress
LAST DEPLOYED: Fri Apr 3 17:39:05 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
...
Helm 已经记录了它在 Kubernetes 中创建的资源作为 chart 安装的一部分。
您可以通过运行以下命令来观察负载均衡器变得可用:
- kubectl --namespace default get services -o wide -w nginx-ingress-ingress-nginx-controller
您已经安装了 Kubernetes 社区维护的 Nginx Ingress。它将 HTTP 和 HTTPS 流量从负载均衡器路由到适当的后端服务,在入口资源中配置。在下一步中,您将hello-kubernetes
使用 Ingress 资源公开应用程序部署。
第 3 步 – 使用 Ingress 公开应用程序
现在,您将创建一个 Ingress 资源并使用它来公开hello-kubernetes
您所需域中的应用程序部署。然后,您将通过从浏览器访问它来测试它。
您将把 Ingress 存储在一个名为hello-kubernetes-ingress.yaml
. 使用您的编辑器创建它:
- nano 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
。然后,您指定两个主机规则,以便将hw1.your_domain
其路由到hello-kubernetes-first
服务,并hw2.your_domain
从第二个部署 ( hello-kubernetes-second
)路由到服务。
接下来,您需要确保您的两个域通过 A 记录指向负载均衡器。这是通过您的 DNS 提供商完成的。要在 DigitalOcean 上配置您的 DNS 记录,请参阅如何管理 DNS 记录。
请记住将突出显示的域替换为您自己的域,然后保存并关闭文件。
通过运行以下命令在 Kubernetes 中创建它:
- kubectl 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
为了保护您的 Ingress 资源,您将安装 Cert-Manager,为生产创建一个 ClusterIssuer,并修改您的 Ingress 配置以利用 TLS 证书。ClusterIssuers 是 Kubernetes 中的 Cert-Manager 资源,为整个集群提供 TLS 证书。安装和配置后,您的应用程序将在 HTTPS 之后运行。
在通过 Helm 将 Cert-Manager 安装到集群之前,您将通过运行以下命令为其手动创建命名空间:
- kubectl create namespace cert-manager
您需要将Jetstack Helm 存储库添加到托管 Cert-Manager 图表的 Helm。为此,请运行以下命令:
- helm repo add jetstack https://charts.jetstack.io
Helm 将显示以下输出:
Output"jetstack" has been added to your repositories
然后,更新 Helm 的图表缓存:
- helm repo update
最后,cert-manager
通过运行以下命令将 Cert-Manager 安装到命名空间中:
- helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.2.0 --set installCRDs=true
您将看到以下输出:
OutputNAME: cert-manager
LAST DEPLOYED: Sun Dec 13 11:29:32 2020
NAMESPACE: cert-manager
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
cert-manager has been deployed successfully!
...
输出显示安装成功。如NOTES
输出中所列,您需要设置一个颁发者来颁发 TLS 证书。
您现在将创建一个颁发 Let’s Encrypt 证书的证书,并将其配置存储在名为production_issuer.yaml
. 创建它并打开它进行编辑:
- nano production_issuer.yaml
添加以下几行:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# Email address used for ACME registration
email: your_email_address
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Name of a secret used to store the ACME account private key
name: letsencrypt-prod-private-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
此配置定义了一个 ClusterIssuer,它与 Let’s Encrypt 联系以颁发证书。您需要将其替换your_email_address
为您的电子邮件地址,以便接收有关证书安全性和过期的紧急通知。
保存并关闭文件。
推出它kubectl
:
- kubectl apply -f production_issuer.yaml
您将看到以下输出:
Outputclusterissuer.cert-manager.io/letsencrypt-prod created
安装 Cert-Manager 后,您就可以将证书引入上一步中定义的入口资源。打开hello-kubernetes-ingress.yaml
编辑:
- nano hello-kubernetes-ingress.yaml
添加突出显示的行:
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
下面的tls
块spec
定义了您站点的证书(在 下列出hosts
)将存储其证书的Secret 中,这些证书由letsencrypt-prod
ClusterIssuer颁发。对于您创建的每个 Ingress,这必须不同。
请记住将hw1.your_domain
和替换为hw2.your_domain
您自己的域。完成编辑后,保存并关闭文件。
通过运行以下命令将此配置重新应用到您的集群:
- kubectl apply -f hello-kubernetes-ingress.yaml
您将看到以下输出:
Outputingress.networking.k8s.io/hello-kubernetes-ingress configured
您需要等待几分钟,让 Let’s Encrypt 服务器为您的域颁发证书。同时,您可以通过检查以下命令的输出来跟踪其进度:
- kubectl describe certificate hello-kubernetes-tls
输出的结尾将类似于:
OutputEvents:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Issuing 26s cert-manager Issuing certificate as Secret does not exist
Normal Generated 26s cert-manager Stored new private key in temporary Secret resource "hello-kubernetes-tls2-nfsgp"
Normal Requested 26s cert-manager Created new CertificateRequest resource "hello-kubernetes-tls2-wzl8z"
Normal Issuing 24s cert-manager The certificate has been successfully issued
当您的最后一行输出读取时The certificate has been successfully issued
,您可以按 退出CTRL + C
。在浏览器中导航到您的域之一进行测试。您会在浏览器地址栏的左侧找到挂锁,这表示您的连接是安全的。
在这一步中,您已经使用 Helm 安装了 Cert-Manager 并创建了一个 Let’s Encrypt ClusterIssuer。之后,您更新了 Ingress Resource 以利用 Issuer 来生成 TLS 证书。最后,您已通过在浏览器中导航到您的域之一来确认 HTTPS 正常工作。
结论
您现在已经使用 Helm 在 DigitalOcean Kubernetes 集群上成功设置了 Nginx Ingress Controller 和 Cert-Manager。您现在可以在您的域中将您的应用程序公开到互联网,并使用 Let’s Encrypt TLS 证书进行保护。
有关 Helm 包管理器的更多信息,请阅读这篇介绍文章。