使用Helm安装Ingress-nginx

管理员

介绍

Nginx Ingress

在Kubernetes集群中,Ingress作为集群内服务对外暴露的访问接入点,其几乎承载着集群内服务访问的所有流量。Ingress是Kubernetes中的一个资源对象,用来管理集群外部访问集群内部服务的方式。您可以通过Ingress资源来配置不同的转发规则,从而达到根据不同的规则设置访问集群内不同的Service所对应的后端Pod。

Nginx Ingress Controller 工作原理

为了使得Nginx Ingress资源正常工作,集群中必须要有个Nginx Ingress Controller来解析Nginx Ingress的转发规则。Nginx Ingress Controller收到请求,匹配Nginx Ingress转发规则转发到后端Service所对应的Pod,由Pod处理请求。Kubernetes中Service、Nginx Ingress与Nginx Ingress Controller有着以下关系:

  • Service是后端真实服务的抽象,一个Service可以代表多个相同的后端服务。
  • Nginx Ingress是反向代理规则,用来规定HTTP/HTTPS请求应该被转发到哪个Service所对应的Pod上。例如根据请求中不同的Host和URL路径,让请求落到不同Service所对应的Pod上。
  • Nginx Ingress Controller是一个反向代理程序,负责解析Nginx Ingress的反向代理规则。如果Nginx Ingress有增删改的变动,Nginx Ingress Controller会及时更新自己相应的转发规则,当Nginx Ingress Controller收到请求后就会根据这些规则将请求转发到对应Service的Pod上。

Nginx Ingress Controller通过API Server获取Ingress资源的变化,动态地生成Load Balancer(例如Nginx)所需的配置文件(例如nginx.conf),然后重新加载Load Balancer(例如执行nginx -s load重新加载Nginx)来生成新的路由转发规则。

使用 Helm 安装

参考文档:https://kubernetes.github.io/ingress-nginx/deploy/

添加 ingress-nginx 官方 helm 仓库

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

下载 chart 包

# 查找所有的版本
$ helm search repo ingress-nginx/ingress-nginx -l
NAME                       	CHART VERSION	APP VERSION	DESCRIPTION                                       
ingress-nginx/ingress-nginx	4.4.0        	1.5.1      	Ingress controller for Kubernetes using NGINX a...
ingress-nginx/ingress-nginx	4.3.0        	1.4.0      	Ingress controller for Kubernetes using NGINX a...
ingress-nginx/ingress-nginx	4.2.5        	1.3.1      	Ingress controller for Kubernetes using NGINX a...

# 下载
$ helm fetch ingress-nginx/ingress-nginx --version 4.3.0

# 解压缩
$ tar -zxvf ingress-nginx-4.3.0.tgz
$ cd ingress-nginx

拉取 ingress-nginx-controller 镜像

官方提供的 registry.k8s.io/ingress-nginx/controller无法直接拉取,需要使用替代的镜像
dockerhub地址:https://hub.docker.com/r/giantswarm/ingress-nginx-controller/tags

# 拉取
$ docker pull giantswarm/ingress-nginx-controller:v1.4.0

# 修改tag
$ docker tag giantswarm/ingress-nginx-controller:v1.4.0 registry.k8s.io/ingress-nginx/controller:v1.4.0

# 删除之前的tag
$ docker rmi giantswarm/ingress-nginx-controller:v1.4.0

修改 values.yaml 文件

修改 ingress-nginx-contorller,注释掉 digest

修改 hostNetwork 的值为 true

修改 dnsPolicy 的值为 ClusterFirstWithHostNet

nodeSelector 添加标签: ingress: "true",用于部署 ingress-controller 到指定节点

修改 kind 类型为 DaemonSet

修改 kube-webhook-certgen 的镜像地址为国内仓库 registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller

安装

# 创建命名空间
$ kubectl create ns ingress-nginx

# helm安装
$ helm install ingress-nginx -n ingress-nginx .
NAME: ingress-nginx
LAST DEPLOYED: Thu Nov 24 17:12:22 2022
NAMESPACE: ingress-nginx
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The ingress-nginx controller has been installed.
It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status by running 'kubectl --namespace ingress-nginx get services -o wide -w ingress-nginx-controller'

An example Ingress that makes use of the controller:
  apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    name: example
    namespace: foo
  spec:
    ingressClassName: nginx
    rules:
      - host: www.example.com
        http:
          paths:
            - pathType: Prefix
              backend:
                service:
                  name: exampleService
                  port:
                    number: 80
              path: /
    # This section is only required if TLS is to be enabled for the Ingress
    tls:
      - hosts:
        - www.example.com
        secretName: example-tls

If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:

  apiVersion: v1
  kind: Secret
  metadata:
    name: example-tls
    namespace: foo
  data:
    tls.crt: <base64 encoded cert>
    tls.key: <base64 encoded key>
  type: kubernetes.io/tls

安装完成后,需要给节点打上刚刚设置的标签ingress=true,让 Pod 调度到指定的节点

# 查看节点
$ kubectl get nodes
NAME          STATUS   ROLES                      AGE   VERSION
hecs-357699   Ready    controlplane,etcd,worker   19h   v1.23.12

# 设置标签
$ kubectl label node hecs-357699 ingress=true

k8s默认集群中,出于安全考虑,默认配置下 Kubernetes 不会将 Pod 调度到 Master 节点。测试环境无所谓,所以执行下面命令去除master的污点:

$ kubectl taint node master1 node-role.kubernetes.io/master-

执行完成之后,就可以看到 ingress-nginx 部署到了master节点了

kubectl get all -n ingress-nginx
NAME                                 READY   STATUS    RESTARTS   AGE
pod/ingress-nginx-controller-2xn6d   1/1     Running   0          65m

NAME                                         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             LoadBalancer   10.43.17.53    <pending>     80:32163/TCP,443:31541/TCP   70m
service/ingress-nginx-controller-admission   ClusterIP      10.43.164.91   <none>        443/TCP                      70m

NAME                                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR                         AGE
daemonset.apps/ingress-nginx-controller   1         1         1       1            1           ingress=true,kubernetes.io/os=linux   70m

参考: