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

作为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_domainhw2.your_domain通篇。你可以购买一个域名Namecheap,免费获得一个在Freenom,或使用你选择的域名注册商。

第 1 步 – 设置 Hello World 部署

在本节中,在部署 Nginx Ingress 之前,您将部署一个 Hello World 应用程序hello-kubernetes,该应用程序被调用来拥有一些您将流量路由到的服务。为了确认 Nginx Ingress 在接下来的步骤中正常工作,您将部署它两次,每次都带有不同的欢迎消息,当您从浏览器访问它时将显示不同的欢迎消息。

您将在本地计算机上存储部署配置。第一个部署配置将位于名为hello-kubernetes-first.yaml. 使用文本编辑器创建它:

  • nano hello-kubernetes-first.yaml

添加以下几行:

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

您将收到以下输出:

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

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

  • kubectl get service hello-kubernetes-first

输出如下:

Output
NAME 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

添加以下几行:

你好-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

输出将是:

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

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

  • kubectl get service

输出将类似于:

Output
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 入口控制器本身。

第 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参数设置trueduring ,可以将 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

此命令从stablecharts 存储库安装 Nginx Ingress Controller ,将 Helm 版本命名为nginx-ingress,并将publishService参数设置true

输出如下:

Output
NAME: 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

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

你好-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在浏览器中导航到您将看到以下内容:

你好 Kubernetes - 第一次部署

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

你好 Kubernetes - 第二次部署

至此,您已验证 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

您将看到以下输出:

Output
NAME: 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

添加以下几行:

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

您将看到以下输出:

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

安装 Cert-Manager 后,您就可以将证书引入上一步中定义的入口资源。打开hello-kubernetes-ingress.yaml编辑:

  • nano hello-kubernetes-ingress.yaml

添加突出显示的行:

你好-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

下面的tlsspec定义了您站点的证书(在 下列出hosts)将存储其证书的Secret 中,这些证书由letsencrypt-prodClusterIssuer颁发对于您创建的每个 Ingress,这必须不同。

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

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

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

您将看到以下输出:

Output
ingress.networking.k8s.io/hello-kubernetes-ingress configured

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

  • kubectl describe certificate hello-kubernetes-tls

输出的结尾将类似于:

Output
Events: 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 包管理器的更多信息,请阅读这篇介绍文章

觉得文章有用?

点个广告表达一下你的爱意吧 !😁