目录

概述

NGINX Ingress Controller 是使用 Kubernetes Ingress 资源对象构建的,用 ConfigMap 来存储 Nginx 配置的一种 Ingress Controller 实现。

安装 ingress-nginx 有多种方式,可以通过yaml文件手动部署,本文通过helm来进行安装。

本文使用的集群是在Ubuntu 22.04.3 LTS系统上搭建的单Master集群,共三台主机。

NAME          STATUS   ROLES           AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
k8s-master    Ready    control-plane   88d   v1.28.0   10.0.2.15     <none>        Ubuntu 22.04.3 LTS   5.15.0-82-generic   containerd://1.6.22
k8s-worker1   Ready    <none>          88d   v1.28.0   10.0.2.15     <none>        Ubuntu 22.04.3 LTS   5.15.0-82-generic   containerd://1.6.22
k8s-worker2   Ready    <none>          88d   v1.28.0   10.0.2.15     <none>        Ubuntu 22.04.3 LTS   5.15.0-82-generic   containerd://1.6.22


helm介绍

Helm 是一个用于对需要在 k8s 上部署的复杂应用进行定义、安装和更新。Helm 以 Char 的方式对应用软件进行描述,可以方便地创建、版本化、共享和发布复杂的应用软件。

helm的主要概念

  • Chart

Helm的应用包,采用tgz格式。类似于 Yum 的 RPM 包,其包含了一组定义 Kubernetes 资源相关的 YAML 文件,也称为应用 Chart。

  • Repoistory

Helm 的应用仓库,Repository 本质上是一个 Web 服务器,该服务器保存了一系列的 Chart 应用包以供用户下载,并且提供了一个该 Repository 的 Chart 包的清单文件以供查询,Helm可以同时管理多个不同的Repository。

Helm社区官方提供了stable和incubator仓库,但Helm社区没有打算独占仓库,而是允许其他人和组织也可以搭建仓库。仓库可以是公共仓库,也可以是私有仓库。

  • Release

在 Kubernetes 集群上运行的 Chart 的一个实例。在同一个集群上,一个 Chart 可以安装很多次。每次安装都会创建一个新的 Release。例如一个 MySQL Chart,如果想在服务器上运行两个 MySQL 数据库,就可以把这个 Chart 安装两次。每次安装都会生成一个新的Release。

chart包的目录结构

# 创建一个chart,chart的名称叫 helm-test
\[root@k8s-master ~\]# helm create helm-test
Creating helm-test
\[root@k8s-master ~\]# cd helm-test/
 # 查看 chart 的目录结构
\[root@k8s-master helm-test\]# tree .
.
├── charts                
├── Chart.yaml          
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml              

3 directories, 10 files
\[root@k8s-master helm-test\]# 

chart 是 Helm 的应用打包格式。chart 由一系列文件组成,这些文件描述了 Kubernetes 部署应用时所需要的资源。上面通过 helm 命令创建了一个 chart 包,目录结构说明如下:

  • helm-test:是 chart 包的名称
  • charts 目录: 保存依赖文件的目录,如果依赖其他的 chart,则会保存在这里
  • Chart.yaml 文件:用于描述 chart 信息的 yaml 文件,如版本信息等
  • values.yaml 文件:chart 支持在安装的时根据参数进行定制化配置,而 values.yaml 则提供了这些配置参数的默认值,可以在安装前根据需要修改 values.yaml 的参数
  • templates 目录:各类 Kubernetes 资源的配置模板都放置在这里。Helm 会将 values.yaml 中的参数值注入到模板中生成标准的 YAML 配置文件

helm 安装 ingress-nginx

这里已经我已经修改好后Chart包链接会放在文章末尾,网络不好的同学可以直接使用我打包好的Chart部署。

[root@k8s-master ~\]# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
[root@k8s-master ~\]# helm repo update

如果此处报错无法访问:

[root@k8s-master ~\]# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
Error: looks like "https://kubernetes.github.io/ingress-nginx" is not a valid chart repository or cannot be reached: Get "https://kubernetes.github.io/ingress-nginx/index.yaml": dial tcp \[::1\]:443: connect: connection refused

在站长之家通过域名解析地址(或使用dnsloop命令):

image_luUjdKpu7f
获取到 IP 地址后,选择一个IP地址,配置本地hosts解析:

[root@k8s-master ~\]# echo "185.199.108.153 kubernetes.github.io" >> /etc/hosts

再次添加仓库:

# 添加仓库
[root@k8s-master ~\]# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
"ingress-nginx" has been added to your repositories
 # 更新
[root@k8s-master ~\]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "ingress-nginx" chart repository
Update Complete. ⎈Happy Helming!⎈

下载ingress-nginx的chart包

[root@k8s-master ~\]# cd /usr/local/src/
 # 查找ingress-nginx的chart包
[root@k8s-master src\]# helm search repo ingress-nginx
NAME                            CHART VERSION   APP VERSION     DESCRIPTION                                       
ingress-nginx/ingress-nginx     4.0.1           1.0.0           Ingress controller for Kubernetes using NGINX a...
 # 下载下来
[root@k8s-master src\]# helm pull ingress-nginx/ingress-nginx
 # 以tgz为后缀的包就是我们下载的chart包
[root@k8s-master src\]# ls
ingress-nginx-4.0.1.tgz
 # 解压
[root@k8s-master src\]# tar -zxvf ingress-nginx-4.0.1.tgz 
 # 目录结构如下
[root@k8s-master src\]# cd ingress-nginx
[root@k8s-master ingress-nginx\]# ls
CHANGELOG.md  Chart.yaml  ci  OWNERS  README.md  templates  values.yaml

修改 values.yaml 文件

下载下来的 chart 包,需要修改一下资源清单配置文件,修改 values.yaml 文件如下:

修改 ingress-nginx-contorller 的镜像仓库地址,默认地址是registry.k8s.io国内无法访问,这里需要替换为阿里云的k8s镜像仓库地址:
image_rayIo7PsCF
修改 hostNetwork 的值为 true
image_8_xBcda8BA
dnsPolicy的值改为: ClusterFirstWithHostNet

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

image_wR4zzE7VO-
kind类型更改为:DaemonSet

image_bbeoGn5qAf
kube-webhook-certgen的镜像地址改为阿里云仓库地址:

image_OaoHyGldIp
注:此处的tag如果没有特殊需要可以不修改,保留即可。

这里的两个镜像可以提前pull下来,使用ctr image pull

ctr image pull registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.9.4
ctr image pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v20231011-8b53cabe0
# 如果你的容器运行时是docker就用docker命令

执行安装

values.yaml修改完成后,执行helm安装:

先创建一个名称空间:kubectl create ns ingress-nginx

 # 进入chart目录
[root@k8s-master ~\]# cd /usr/local/src/ingress-nginx
 # helm安装
[root@k8s-master ingress-nginx\]# helm install ingress-nginx -n ingress-nginx .
NAME: ingress-nginx
LAST DEPLOYED: Wed Sep 15 10:17:09 2021
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:
    annotations:
      kubernetes.io/ingress.class: 
    name: example
    namespace: foo
  spec:
    rules:
      \- host: www.example.com
        http:
          paths:
            \- backend:
                serviceName: exampleService
                servicePort: 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
[root@k8s-master ingress-nginx\]# 

出现上面的命令输出表示安装完成了,安装完成后,需要给节点打上刚刚设置的标签ingress=true,让 Pod 调度到指定的节点,比如调度到 k8s-worker1节点:

kubectl label node k8s-worker1 ingress=true
node/k8s-worker1 labeled

要删除一个node的标签,命令如下:

kubectl label node k8s-worker1 ingress=true-

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

root@k8s-master:~/ingress-nginx# kubectl get all -n ingress-nginx
NAME                                 READY   STATUS    RESTARTS   AGE
pod/ingress-nginx-controller-4fqcd   1/1     Running   0          152m

NAME                                         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             LoadBalancer   10.105.94.53   <pending>     80:32292/TCP,443:30881/TCP   152m
service/ingress-nginx-controller-admission   ClusterIP      10.97.242.20   <none>        443/TCP                      152m

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   152m

Pod也是部署在了k8s-worker1节点:

root@k8s-master:~/ingress-nginx# kubectl get pods -n ingress-nginx -o wide
NAME                             READY   STATUS    RESTARTS   AGE    IP          NODE          NOMINATED NODE   READINESS GATES
ingress-nginx-controller-4fqcd   1/1     Running   0          153m   10.0.2.15   k8s-worker1   <none>           <none>

测试 ingress-nginx

mkdir nginx_ingress_test
cd nginx_ingress_test
root@k8s-master:~/nginx_ingress_test# ls
ingress-nginx.yaml  nginx_pod_service.yaml

创建测试nginx 的 Pod 和 Service:

nginx_pod_service.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: svc-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - image: nginx:latest
        name: svc-demo
        ports:
        - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: svc-demo
spec:
  selector:  
    app: myapp
  ports:
  - targetPort: 80  # 后端Pod的端口
    port: 8080 # 服务要暴露的端口

# 应用nginx_pod_service.yaml
kubectl apply -f nginx_pod_service.yaml

root@k8s-master:~/nginx_ingress_test# kubectl get pods,svc 
NAME                                     READY   STATUS             RESTARTS          AGE
pod/svc-demo-57fb797c86-r56mj            1/1     Running            0                 147m
pod/svc-demo-57fb797c86-sgvs7            1/1     Running            0                 147m

NAME                            TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/svc-demo                ClusterIP      10.108.252.130   <none>        8080/TCP         147m

创建 ingress 规则:

ingress-nginx.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: foo.bar.com
    http:
      paths:
      - pathType: Prefix
        path: /*
        backend:
          service:
            name: svc-demo
            port:
              number: 8080

# 应用ingress-nginx.yaml
kubectl apply -f ingress-nginx.yaml

root@k8s-master:~/nginx_ingress_test# kubectl get ingress
NAME            CLASS    HOSTS         ADDRESS   PORTS   AGE
ingress-nginx   <none>   foo.bar.com             80      137m

配置windows解析,访问域名

修改hosts文件:

192.168.58.31 foo.bar.com
# 注意这里的ip对应是你服务器容器部署节点的主机ip,不是Controller主机的IP

image_YAGV2_cJC5


Helm Chart包链接:

http://files.dhwark.xyz/ingress-nginx-4.8.3.tgz

参考文章:

使用Helm3.6 安装 Ingress-nginx - syushin - 博客园 (cnblogs.com)