目录
概述
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 的方式对应用软件进行描述,可以方便地创建、版本化、共享和发布复杂的应用软件。
- 官方英文文档:https://helm.sh/docs/
- 官方中文文档:https://helm.sh/zh/docs/
- Helm安装官方文档:https://helm.sh/docs/intro/install/
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命令):
获取到 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镜像仓库地址:
修改 hostNetwork 的值为 true
:
dnsPolicy的值改为: ClusterFirstWithHostNet
:
nodeSelector 添加标签: ingress: "true"
,用于部署 ingress-controller 到指定节点:
kind类型更改为:DaemonSet
:
kube-webhook-certgen的镜像地址改为阿里云仓库地址:
注:此处的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
Helm Chart包链接:
http://files.dhwark.xyz/ingress-nginx-4.8.3.tgz
参考文章: