kubernetes-1.20 ingress-nginx 配置案例
一、基础概念和背景
技术背景:
k8s的service资源类型负责处理四层负载,解决了pod漂移问题,但是随着服务的增多,nodeport的方式会导致要配置使用很多的端口,进而出现端口管理维护的问题,最初就有了使用nginx来代理端口访问的处理方案,通过nginx做反向代理,可以无需使用过多的宿主机端口,但是将nginx部署在pod中运行的话,后续服务以及域名的变更配置会要求频繁的修改nginx配置文件,为了进一步解决问题,这才有了Ingress Controoler ,通过与 Kubernetes API交互,动态的去感知集群中 Ingress 规则变化,然后读取他,按照他自己模板生成一段 Nginx 配置,再写到 Nginx Pod 里。
案例需求:
通过http或者https的方式,配合ingress-nginx以不同的url后缀区分访问k8s中部署的服务。
本次案例搭建的测试应用服务为kunpeng search 和 metabase。
1.1、ingress
- ingress服务:指的是k8s中的一个api对象,一般用yaml配置。作用是定义请求如何转发到service的规则,可以理解为配置模板。
ingress 是一个API对象,和其他对象一样,通过yaml文件来配置,作用是定义请求如何转发到 service 的规则
ingress 通过 http或https 暴露集群内部 service,给 service 提供外部URL、负载均衡、SSL/TLS能力以及基于host的方向代理
ingress-controller 是具体实现反向代理及负载均衡的程序,对 ingress 定义的规则进行解析,根据配置的规则来实现请求转发
ingress 要依靠 ingress-controller 来具体实现以上功能
官方解释:入口|Kubernetes
1.2、ingress-controller
- ingress controller:具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。
ingress-controller 并不是 k8s 自带的组件,实际上 ingress-controller 只是一个统称,用户可以选择不同的 ingress-controller 实现,目前,由 k8s 维护的 ingress-controller 只有google云的 GCE 与 ingress-nginx 两个,其他还有很多第三方维护的 ingress-controller,具体可以参考官方文档。类似的还有:Traefik、HAProxy、Istio.
但是不管哪一种 ingress-controller,实现的机制都大同小异,只是在具体配置上有差异。一般来说,ingress-controller 的形式都是一个 pod,里面跑着 daemon 程序和反向代理程序。daemon 负责不断监控集群的变化,根据 ingress 对象生成配置并应用新配置到反向代理,比如 nginx-ingress 就是动态生成 nginx 配置,动态更新 upstream,并在需要的时候reload程序应用新配置。本例子以 k8s 官方维护的 nginx-ingress 进行演示
官方解释:入口控制器|Kubernetes
简单来说,ingress-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到ingress-controller,而ingress对象是用来告诉ingress-controller该如何转发请求,比如哪些域名哪些path要转发到哪些服务等等。
二、ingress-controller部署
这里选用kubernetes/ingress-nginx作为ingress-controller进行部署
部署参考官方文档,使用官方提供的yaml文件进行部署,文件中有2个镜像是国内网络无法拉取的需要提前单独拉取下来并修改yaml文件中的进行镜像标签
2.1、下载deploy.yaml模板
首先进入官方项目仓库查看需部署的对应版本
Support Versions table
| Ingress-NGINX version | k8s supported version | Alpine Version | Nginx Version |
|---|---|---|---|
| v1.1.3 | 1.23, 1.22, 1.21, 1.20, 1.19 | 3.14.4 | 1.19.10† |
| v1.1.2 | 1.23, 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† |
| v1.1.1 | 1.23, 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† |
| v1.1.0 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† |
| v1.0.5 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† |
| v1.0.4 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† |
| v1.0.3 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† |
| v1.0.2 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† |
| v1.0.1 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† |
| v1.0.0 | 1.22, 1.21, 1.20, 1.19 | 3.13.5 | 1.20.1 |
| v0.50.0 | 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† |
| v0.49.3 | 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† |
| v0.49.2 | 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† |
| v0.49.1 | 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† |
| v0.49.0 | 1.21, 1.20, 1.19 | 3.13.5 | 1.20.1 |
| v0.48.1 | 1.21, 1.20, 1.19 | 3.13.5 | 1.20.1 |
当前环境k8s版本为1.20 这里选用的ingress-nginx版本为v1.1.2
进入对应版本源码目录下载deploy.yaml文件
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/cloud/deploy.yaml
2.2、修改yaml替换镜像
查看yaml文件找到image 标签拉取的镜像分别有
k8s.gcr.io/ingress-nginx/controller:v1.1.2
k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1
由于网络原因国内拉取不到该镜像,可以从阿里云镜像仓库单独获取
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.1.2
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.1.2 nginx-ingress-controller:v1.1.2
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1 kube-webhook-certgen:v1.1.1
接下来修改yaml文件替换docker镜像,并修改其他配置,修改处查看diff
[root@ecs-1213 shilitao]# cat diff.log
--- ingress_deploy_bak.yaml 2022-04-02 10:02:18.563209218 +0800
+++ ingress_deploy.yaml 2022-04-01 16:22:08.866556657 +0800
@@ -380,7 +380,7 @@
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
- type: LoadBalancer
+ type: NodePort
---
apiVersion: v1
kind: Service
@@ -457,7 +457,7 @@
fieldPath: metadata.namespace
- name: LD_PRELOAD
value: /usr/local/lib/libmimalloc.so
- image: k8s.gcr.io/ingress-nginx/controller:v1.1.2@sha256:28b11ce69e57843de44e3db6413e98d09de0f6688e33d4bd384002a44f78405c
+ image: nginx-ingress-controller:v1.1.2
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -477,9 +477,11 @@
name: controller
ports:
- containerPort: 80
+ hostPort: 80
name: http
protocol: TCP
- containerPort: 443
+ hostPort: 443
name: https
protocol: TCP
- containerPort: 8443
@@ -561,7 +563,7 @@
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- image: k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
+ image: kube-webhook-certgen:v1.1.1
imagePullPolicy: IfNotPresent
name: create
securityContext:
@@ -617,7 +619,7 @@
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- image: k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
+ image: kube-webhook-certgen:v1.1.1
imagePullPolicy: IfNotPresent
name: patch
securityContext:
除了修改容器标签还要修改ingress-nginx-controller的service中的类型为NodePort或者ingress 使用到物理机的80/443 端口,所以增加hostport相应配置,两种方式都可以实现访问,这里为了演示都进行了配置。
2.3、修改完成后部署
[root@ecs-1213 nginx]# mv deploy.yaml ingress-nginx-controller.yaml
[root@ecs-1213 nginx]# kubectl apply -f ingress-nginx-controller.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
[root@ecs-1213 nginx]# kubectl get all -n ingress-nginx
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-admission-create-dp5gd 0/1 Completed 0 36s
pod/ingress-nginx-admission-patch-w4c5f 0/1 Completed 1 36s
pod/ingress-nginx-controller-78d8d9f697-g6zfd 1/1 Running 0 36s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller NodePort 10.110.248.97 <none> 80:30747/TCP,443:32755/TCP 36s
service/ingress-nginx-controller-admission ClusterIP 10.97.90.192 <none> 443/TCP 36s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ingress-nginx-controller 1/1 1 1 36s
NAME DESIRED CURRENT READY AGE
replicaset.apps/ingress-nginx-controller-78d8d9f697 1 1 1 36s
NAME COMPLETIONS DURATION AGE
job.batch/ingress-nginx-admission-create 1/1 2s 36s
job.batch/ingress-nginx-admission-patch 1/1 3s 36s
[root@ecs-1213 nginx]#
查看资源状态运行正常即部署完成,接下来可以配置两个测试服务并配置ingress规则进一步测试。
三、部署测试应用
3.1、部署测试应用鲲鹏search的前端页面
- 应用背景:在部署环境中已经存在foliant search的服务,经过服务搭建测试也对该服务有了一定认识,根据服务之间的关系可知,foliant转换后的静态文件资源挂载在httpd的容器中可对外提供web访问,其中search页面的静态资源挂载在httpd容器中,页面中包含css和js文件,连接跳转foliant处理后的页面资源,同时连接es的索引。
nginx也可以代理静态页面资源提供http服务访问,下面将直接通过k8s部署nginx服务代理kunpeng search的静态页面作为测试应用。
- 准备部署文件
```yaml [root@ecs-1213 nginx]# cat nginx-app-svc.yaml
kind: Deployment apiVersion: apps/v1 metadata: name: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.21.6 ports: - containerPort: 80 protocol: TCP volumeMounts: - mountPath: /usr/share/nginx/html/ name: search volumes: - name: search hostPath: path: /data/shilitao/nginx/webapp_example type: Directory
kind: Service apiVersion: v1 metadata: name: nginx labels: name: nginx spec: # type: ClusterIP ports: - protocol: TCP # nodePort: 31010 targetPort: 80 #容器端口 port: 32230 #pod端口 selector: app: nginx ```
- 挂载search页面资源到容器目录,注释service中暴露端口的方式,后期使用ingress进行配置
bash
[root@ecs-1213 nginx]# kubectl apply -f nginx-app-svc.yaml
deployment.apps/nginx created
service/nginx created
将服务部署到default命名空间进行测试,部署完毕可以在内部进行访问测试服务是否正常
[root@ecs-1213 nginx]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 110d
nginx ClusterIP 10.99.139.43 <none> 32230/TCP 2m32s
[root@ecs-1213 nginx]# curl 10.99.139.43:32230
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Search</title>
<link rel="stylesheet" href="foliant_elasticsearch.css">
<script src="foliant_elasticsearch.js"></script>
</head>
<body class="foliant_elasticsearch">
<h1>Kunpeng Search</h1>
<div>
<input id="foliant_elasticsearch_input" type="text" oninput="performSearch(this.value);">
</div>
<div id="foliant_elasticsearch_total"></div>
<div id="foliant_elasticsearch_results"></div>
</body>
</html>
测试正常。
3.2、部署Metabase应用
-
应用背景:目前环境中有做好的Metabase镜像可以直接启动进行测试,默认启动使用的内置数据库,启动后可以访问服务初始化页面。
-
准备部署文件
```yaml [root@ecs-1213 nginx]# cat metabase-app-svc.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: metabase2 namespace: default spec: replicas: 1 selector: matchLabels: app: metabase2 template: metadata: labels: app: metabase2 spec: containers: - name: metabase image: metabase/metabase:v0.39.4_zhai_aarch64 imagePullPolicy: IfNotPresent ports: - containerPort: 3000
apiVersion: v1 kind: Service metadata: name: metabase2 namespace: default spec: # type: NodePort selector: app: metabase2 ports: - name: http port: 32240 # nodePort: 32240 targetPort: 3000 ```
同样注释service中端口的暴露方式
```bash
[root@ecs-1213 nginx]# kubectl apply -f metabase-app-svc.yaml
deployment.apps/metabase2 created
service/metabase2 created
[root@ecs-1213 nginx]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1
[root@ecs-1213 nginx]# cat nginx_ingress.yaml
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-app-ingress
annotations:
kubernetes.io/ingress.class: "nginx" #指定使用后端ingress controller的类别,如果后端有多个ingress controller的时候很重要
nginx.ingress.kubernetes.io/use-regex: "true" #指定rules的path可以使用正则表达式,如果没有使用正则表达式,此项则可不使用
nginx.ingress.kubernetes.io/rewrite-target: /$2 #必须重定向流量的目标 URI 正则匹配的参数,$1表示第一个()内的正则匹配内容,$2为第二个,以此类推
spec:
rules:
- host:
http:
paths:
- pathType: Prefix #基于以 / 分隔的 URL 路径前缀匹配
path: /nginx(/|$)(.*) #(/|$)匹配/或者字符串结束 (.*)配置所有字符
backend:
service:
name: nginx
port:
number: 32230 #nginx-service的nodeport端口
- pathType: Prefix
path: /metabase(/|$)(.*)
backend:
service:
name: metabase2
port:
number: 32240 #metabase-service的nodeport端口
defaultBackend: #默认的页面也就是nginx80端口页面,如果以上规则都未匹配到将会转到以下服务
service:
name: metabase2
port:
number: 32240
### 4.2、相关参数解释
- defaultBackend:没有设置规则的 Ingress 将所有流量发送到同一个默认后端,而 `.spec.defaultBackend` 则是在这种情况下处理请求的那个默认后端。 `defaultBackend` 通常是 [Ingress 控制器](https://kubernetes.io/zh/docs/concepts/services-networking/ingress-controllers)的配置选项,而非在 Ingress 资源中指定。 如果未设置任何的 `.spec.rules`,那么必须指定 `.spec.defaultBackend`。 如果未设置 `defaultBackend`,那么如何处理所有与规则不匹配的流量将交由 Ingress 控制器决定(请参考你的 Ingress 控制器的文档以了解它是如何处理那些流量的)。
如果没有 `hosts` 或 `paths` 与 Ingress 对象中的 HTTP 请求匹配,则流量将被路由到默认后端。
https://kubernetes.io/zh/docs/concepts/services-networking/ingress/#default-backend
- Ingress 中的每个路径都需要有对应的路径类型(Path Type)。未明确设置 `pathType` 的路径无法通过合法性检查。当前支持的路径类型有三种:ImplementationSpecific:对于这种路径类型,匹配方法取决于 IngressClass。 具体实现可以将其作为单独的 `pathType` 处理或者与 `Prefix` 或 `Exact` 类型作相同处理。
Exact:精确匹配 URL 路径,且区分大小写。
Prefix:基于以 `/` 分隔的 URL 路径前缀匹配。匹配区分大小写,并且对路径中的元素逐个完成。 路径元素指的是由 `/` 分隔符分隔的路径中的标签列表。 如果每个 *p* 都是请求路径 *p* 的元素前缀,则请求与路径 *p* 匹配。
- ingress文件的配置更新:
通过命令`kubectl edit ingress test`打开yaml文件直接进行编辑,保存之后配置将自动生效。
- host 字段配置域名,可以是精确匹配(例如“`foo.bar.com`”)或者使用通配符来匹配 (例如“`*.foo.com`”
- 注解Annotations:可以使用 Kubernetes 注释将任意非识别元数据附加到对象,这里附注的有nginx配置的元数据,用以设置当前 Ingress 资源实例中 Nginx 虚拟主机的相关配置,对应配置的是 Nginx 当前虚拟主机的 server 指令域内容。其他的Nginx Ingress注解Annotations 参数可参考:[Nginx Ingress注解Annotations_微学苑 (weixueyuan.net)](https://www.weixueyuan.net/a/884.html)
### 4.3、使用IP进行访问测试
配置文件编写完成可以应用配置生效
- 由于ingress-nginx-controller的service已经定义了nodeport的端口,所以可以通过该宿主机的IP地址加nodeport端口访问ingress-nginx-controller,然后根据请求的url后缀匹配我们pod上的服务,例如:
k8s集群内访问地址http://10.108.14.78:80是ingress-nginx-controller的service,增加后缀/nginx 或者 /metabase 会访问到相应的服务
k8s集群外部访问地址http://1.1.1.1:30343是ingress-nginx-controller的service对外nodeport服务地址,增加后缀/nginx 或者 /metabase 会访问到相应的服务
- ingress-nginx-controller的yaml配置文件中还配置了hostport的80和443端口,所以这里也是可以通过直接访问该主机的80端口就能够访问ingress-nginx-controller的service,即:
访问http://1.1.1.1是ingress-nginx-controller的service,增加后缀/nginx 或者 /metabase 会访问到相应的服务
[root@ecs-1213 nginx]# kubectl apply -f nginx_ingress.yaml
ingress.networking.k8s.io/nginx-app-ingress configured
[root@ecs-1213 nginx]# kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-app-ingress <none> * 10.108.14.78 80 3d16h
[root@ecs-1213 nginx]# kubectl describe ingress nginx-app-ingress
Name: nginx-app-ingress
Namespace: default
Address: 10.108.14.78
Default backend: nginx:32230 (10.32.0.10:80)
Rules:
Host Path Backends
---- ---- --------
*
/nginx(/|$)(.*) nginx:32230 (10.32.0.10:80)
/metabase(/|$)(.*) metabase2:32240 (10.32.0.8:3000)
Annotations: kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/use-regex: true
Events: <none>
[root@ecs-1213 nginx]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.108.14.78 <none> 80:30343/TCP,443:30600/TCP 3d16h
ingress-nginx-controller-admission ClusterIP 10.108.133.238 <none> 443/TCP 3d16h
[root@ecs-1213 nginx]#[root@ecs-1213 nginx]# curl http://10.108.14.78:80/nginx/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Search</title>
<link rel="stylesheet" href="foliant_elasticsearch.css">
<script src="foliant_elasticsearch.js"></script>
</head>
<body class="foliant_elasticsearch">
<h1>Kunpeng Search</h1>
<div>
<input id="foliant_elasticsearch_input" type="text" oninput="performSearch(this.value);">
</div>
<div id="foliant_elasticsearch_total"></div>
<div id="foliant_elasticsearch_results"></div>
</body>
</html>
[root@ecs-1213 nginx]# curl http://1.1.1.1/nginx/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Search</title>
<link rel="stylesheet" href="foliant_elasticsearch.css">
<script src="foliant_elasticsearch.js"></script>
</head>
<body class="foliant_elasticsearch">
<h1>Kunpeng Search</h1>
<div>
<input id="foliant_elasticsearch_input" type="text" oninput="performSearch(this.value);">
</div>
<div id="foliant_elasticsearch_total"></div>
<div id="foliant_elasticsearch_results"></div>
</body>
</html>
## 五、搭配域名进行访问
以上通过IP能够访问ingress-nginx-controller并根据后缀匹配相应的服务,那么就说明服务已经搭建完成可以正常使用,下面就可以通过配置ingress的yaml文件中spec.rules.host的的字段,设置域名进行访问,这里的域名可以精确设置,也可以使用通配符匹配,下面简要记录一下域名的准备流程和后续配置。
### 5.1、域名准备
可以在域名注册服务商处注册域名,相应的域名会收取不同的费用,最便宜的一年几块钱。
阿里、腾讯、华为等公有云都有域名注册服务,可以直接进行域名申请注册,注册成功之后,需要进行实名认证以及办理域名网站备案,否则域名是无法被解析使用的。
下面是腾讯云域名管理添加解析记录的过程:
- 添加域名解析
登录管理腾讯云的管理控制台,进入域名注册栏、找到我的域名、点击解析

点击解析后跳转到域名管理控制台-我的域名-记录管理页面,在这里可以添加新的解析记录到公网IP,如下



新添加的解析地址为1.1.1.1 主机记录为test 那么访问域名test.shilitao.top 就会解析到该地址
以上为域名解析配置案例,下面测试用的域名为haha.online 已解析到地址1.1.1.1
### 5.2、修改ingress配置文件
[root@ecs-1213 nginx]# kubectl edit ingress nginx-app-ingress
ingress.networking.k8s.io/nginx-app-ingress edited
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-app-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: haha.online #增加域名设置
http:
paths:
- pathType: Prefix
path: /nginx(/|$)(.*)
backend:
service:
name: nginx
port:
number: 32230
- pathType: Prefix
path: /metabase(/|$)(.*)
backend:
service:
name: metabase2
port:
number: 32240
defaultBackend:
service:
name: nginx
port:
number: 32230
### 5.3、域名访问测试
域名配置完成后可以进行访问测试
[root@ecs-1213 nginx]# kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-app-ingress <none> haha.online 10.108.14.78 80 3d16h
访问Search (http://haha.online/nginx/)
访问Metabase (http://haha.online/metabase/)
- 注意必须后缀要有 / 否则无法加载到动态资源
- 匹配不到的规则会默认转发到defaultBackend配置的service,只有静态页面资源

### 5.4、配置https访问
ingress是有tls配置项用于证书配置,这里在配置之前需要准备一个和域名绑定的ssl证书或者tls证书。
- 相关概念可以查看该资料,可以对https和证书有基本的了解[HTTPS、SSL、TLS三者之间的联系和区别]([HTTPS、SSL、TLS三者之间的联系和区别_天府云创的博客-CSDN博客_tls和ssl区别](https://blog.csdn.net/enweitech/article/details/81781405))
**关于证书的申请,这里可以推荐两种方式进行:**
第一种:直接通过域名管理平台申请,一般都有这种业务,由于本次测试使用的域名在腾讯云管理,关于证书这方面是有专门的ssl证书可以免费申请使用



之后根据操作提示输入相关基本信息,基本就可以一键完成证书申请,证书有限期为一年,申请成功之后可以将证书下载下来上传到服务器中,就可以进行后续k8s secret配置。
第二种:通过相关免费的证书申请平台手动去申请证书,这里演示通过网站[FreeSSL首页 - FreeSSL.cn一个提供免费HTTPS证书申请的网站](https://freessl.cn/)申请免费证书

输入域名点击创建后,根据要求填写域名配置


然后进行第二步,上域名控制台添加解析记录,进行检测

检测完成后,就可以根据给出的部署命令进行证书部署了,这里推荐使用acme.sh进行部署
先安装acme.sh脚本
curl https://gitcode.net/cert/cn-acme.sh/-/raw/master/install.sh?inline=false | sh -s email=my@example.com
然后执行部署命令
acme.sh --issue -d haha.online --dns dns_dp --server https://acme.freessl.cn/v2/DV90/directory/i1sbcebv31zxdu039l5e

执行完毕后返回证书保存的位置,到此就完成了证书部署。
**下面创建k8s secret资源载入证书信息**
[root@ecs-1213 nginx]# kubectl create secret tls haha.online --cert=/root/.acme.sh/haha.online/haha.online.cer --key=/root/.acme.sh/haha.online/haha.online.key
secret/haha.online created
[root@ecs-1213 nginx]# kubectl get secret
NAME TYPE DATA AGE
default-token-gqq4x kubernetes.io/service-account-token 3 114d
haha.online kubernetes.io/tls 2 15s
**修改ingress配置规则生效tls**
[root@ecs-1213 nginx]# cat nginx_ingress.yaml
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-app-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/ssl-redirect: "false" #关闭强制https的定向访问
spec:
tls: #配置tls
- hosts:
- haha.online #域名
secretName: haha.online #secret资源名称
rules:
- host: haha.online
http:
paths:
- pathType: Prefix
path: /nginx(/|$)(.*)
backend:
service:
name: nginx
port:
number: 32230
- pathType: Prefix
path: /metabase(/|$)(.*)
backend:
service:
name: metabase2
port:
number: 32240
defaultBackend:
service:
name: nginx
port:
number: 32230
**访问测试**


这里需要注意的是kunpeng search服务本身启动的nginx容器对原有httpd服务进行了代理,所以只能访问静态页面,后面search的结果页面是httpd服务提供的,默认没有配置https, 所以搜索不到结果,可以将原有服务中的httpd服务完全替换到nginx后,就可以实现相同的效果。
- 关于证书的自动续签,可以搭建cert-manager+Let‘s Encrypt实现自动证书签发,配置参考[k8s中级篇-cert-manager+Let‘s Encrypt自动证书签发](https://blog.csdn.net/ai524719755/article/details/116712931)
访问Search (https:/haha.online/nginx/)
访问Metabase (https://haha.online/metabase/)
但是已经可以反馈到ingress通过https访问配置完成。
## 六、利用ingress进行访问控制
### 6.1 黑白名单控制
ingress后台是基于nginx在运作,所以nginx可以实现的功能,在ingress也是可以实现的。
有几种配置方式都可以实现。
第一种、使用configmap配置实现,配置文件参考如下
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.1.2
helm.sh/chart: ingress-nginx-4.0.18
name: ingress-nginx-controller
namespace: ingress-nginx
data:
allow-snippet-annotations: "true" #该功能开启了在ingress配置文件中annotations的server-snippet写法,表示可以直接使用该字段插入到nginx—server块的配置
whitelist-source-range: 'x.x.x.x/24,x.x.x.x' #白名单
block-cidrs: 'x.x.x.x/24,x.x.x.x' #黑名单
第二种,上一步在configmap中设置了`allow-snippet-annotations: "true"`就可以在ingress文件进行配置,不用在cofigmap中设置`whitelist-source-range`和`block-cidrs`字段,参考如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: metabase-ingress
namespace: service
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/server-snippet: |-
deny 121.4.51.168;
allow all;
spec:
rules:
- host:
http:
paths:
- path: /m(/|$)(.*)
pathType: Prefix
backend:
service:
name: metabase
port:
number: 3000
- nginx.ingress.kubernetes.io/server-snippet (用于插入 server 块中的代码段)
nginx.ingress.kubernetes.io/server-snippet: |-
allow 121.4.51.168;
deny all;
相应修改也可以实现白名单功能。
第三种、还是通过修改ingress配置实现,只是相比第二种的写法不同,例如
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: metabase-ingress
namespace: service
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/whitelist-source-range: 'x.x.x.x/24,x.x.x.x' #白名单
nginx.ingress.kubernetes.io/block-cidrs: 'x.x.x.x/24,x.x.x.x' #黑名单
spec:
rules:
- host:
http:
paths:
- path: /m(/|$)(.*)
pathType: Prefix
backend:
service:
name: metabase
port:
number: 3000
### 6.2 使用基本认证功能
ingress-nginx可以实现访问页面跳出需要输入用户名和密码的认证功能,下面通过演示进行测试
首先,创建一个用户名密码,使用http的命令工具来生成
[root@k8s-master01 ingress]# htpasswd -c auth service
New password: 123456
Re-type new password: 123456
Adding password for user service
[root@k8s-master01 ingress]# ls
auth tls.cert tls.key
[root@k8s-master01 ingress]# cat auth
service:$apr1$UDKoFAUq$kPM0AaEB.qTEzzwB1SHSC.
然后根据生成的auth文件创建secret
[root@k8s-master01 ingress]# kubectl create secret generic basic-auth --from-file=auth -n service
secret/basic-auth created
最后配置ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress1
namespace: service
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/auth-realm: Need to longin #需要登录认证
nginx.ingress.kubernetes.io/auth-secret: basic-auth #认证的secret名称
nginx.ingress.kubernetes.io/auth-type: basic #基本认证类型
spec:
rules:
- host:
http:
paths:
- path: /s(/|$)(.*)
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
defaultBackend:
service:
name: gitea
port:
number: 3000
[root@ecs-arm-k8s-master01 shilitao]# kubectl apply -f ingress.yaml
ingress.networking.k8s.io/ingress1 configured
生效配置后进行访问测试

输入用户名: 密码: ,即可出现search页面

