

理解Kubernetes中的Nginx Ingress
source link: https://www.51cto.com/article/703951.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Ingress有什么作用?管理集群外部对集群内服务的访问,典型如HTTP请求。它可以提供负载均衡、SSL终结和基于域名的虚拟主机访问。我们发现这些功能都比较容易实现,将集群内的服务暴露到集群外部,可以使用“NodePort”类型的Service,负载均衡可以使用HAProxy来实现,SSL终结功能部署七层反向代理就可以,基于域名的虚拟主机访问也同样比较容易实现,那为什么Kubernetes要引入Ingress API对象呢?
Ingress的潜力
Ingress的功能如开篇所述,可以使用其他技术实现,但是实际在操作过程中发现并没那么简单。在没有Ingress参与的情况下,将集群内服务暴露到集群外使用“NodePort”类型的Service,那需要给每个微服务都创建此类Service,当服务较多时,排障将非常复杂,协调主机端口使用也会让人抓狂。在集群外部署Nginx或Apache,SSL终结和基于域名的虚拟主机访问可以实现,但是服务发现和配置管理又是个挑战,集群外的Nginx和Apache感知不到集群中服务的增加和减少,需要人为配置,这对集群管理员来说,简直是个噩梦。幸好,Ingress来了。
安装服务到Kubernetes一般都比较容易,使用“kubectl apply”后面跟上yaml文件即可。当然也可以使用Kubernetes的包管理工具-Helm。“nginx ingress”根据环境,可选有三种安装方法:
- 使用helm。
- kubectl apply + yamlfiles。
- 在minikube或MicroK8s中,插件方式安装。
笔者使用这篇文章介绍的方法安装Kubernetes集群,这里选用第二种方式安装“nginx ingress ”,执行下面命令(因版本更新较快,实际部署请参考官网):
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/baremetal/deploy.yaml
安装会从“k8s.gcr.io”镜像仓拉取镜像,如果拉取失败可选择阿里云或其他。
查看增加的集群资源。
[root@master ~]# kubectl get all -n ingress-nginx
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-admission-create-7k9kt 0/1 Completed 0 14d
pod/ingress-nginx-admission-patch-5bcmq 0/1 Completed 1 14d
pod/ingress-nginx-controller-687578654b-f92bq 1/1 Running 3 (42d ago) 14d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller NodePort 10.1.70.249 <none> 80:30305/TCP,443:31330/TCP 14d
service/ingress-nginx-controller-admission ClusterIP 10.1.124.31 <none> 443/TCP 14d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ingress-nginx-controller 1/1 1 1 14d
NAME DESIRED CURRENT READY AGE
replicaset.apps/ingress-nginx-controller-687578654b 1 1 1 14d
NAME COMPLETIONS DURATION AGE
job.batch/ingress-nginx-admission-create 1/1 5s 14d
job.batch/ingress-nginx-admission-patch 1/1 7s 14d
因为集群是自建的,“ingress-nginx-controller”服务类型为“NodePort”,后面访问服务需要使用这样的方式:NodeIP+30305/31330+Path。
上步操作成功执行后,便可以创建Ingress类型的API对象了,笔者集群中提前部署一Web服务,Service信息如下:
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP 10.1.133.186 <none> 80/TCP 14h
创建Ingress API对象。
1> ---
2> apiVersion: networking.k8s.io/v1
3> kind: Ingress
4> metadata:
5> name: self-nginx
6> namespace: test
7> annotations:
8> nginx.ingress.kubernetes.io/rewrite-target: /
9> spec:
10> ingressClassName: nginx
11> rules:
12> - host: mynginx.example.com
13> http:
14> paths:
15> - path: /testpath
16> pathType: Prefix
17> backend:
18> service:
19> name: nginx
20> port:
21> number: 80
如果没有将前面安装的nginx ingress配置为默认的Ingress,需要加入第10行。否则即使ingress资源提交到API Server,“nginx ingress controller”也没有反应。获取“ingressClassName”的值。
[root@master ~]# kubectl get ingressclass
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 14d
查看创建的Ingress。
[root@master ~]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
self-nginx nginx mynginx.example.com 192.168.52.132 80 125m
通过Ingress访问Web服务(如果域名没有解析,修改/etc/hosts文件)。
[root@master nginx]# curl mynginx.example.com:30305/testpath
hello kubernetes!
Nginx Ingress的部署和使用不难,最重要是熟悉它的工作原理,这样在遇到问题时才能迅速定位。“ingress-nginx-controller” Pod里面仅运行一个容器,但是这个容器里面却有多个守护进程,重要的有两个:controller和nginx。进入Pod执行ps命令查看:
[root@master ~]# kubectl exec -it ingress-nginx-controller-687578654b-f92bq -n ingress-nginx -- /bin/bash
bash-5.1$ ps
PID USER TIME COMMAND
1 www-data 0:00 /usr/bin/dumb-init -- /nginx-ingress-controller --election-id=ingress-controller-leader --controller-class=k8s.io/ingress-nginx --config
7 www-data 11:28 /nginx-ingress-controller --election-id=ingress-controller-leader --controller-class=k8s.io/ingress-nginx --configmap=ingress-nginx/ingr
25 www-data 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /etc/nginx/nginx.conf
247 www-data 0:01 nginx: worker process
248 www-data 0:00 nginx: cache manager process
Controller是管理者,实现服务发现和自动配置功能,见下图(下载自官网)。
nginx ingress工作原理
这幅图看起来很复杂,其实用一句话就可以概括:“Ingress Controller”(即图中的IC)相当于系统管理员,需求者提交Ingress资源到API Server,IC从API Server获取Ingress资源,因为IC既了解Ingress资源又了解Nginx,它完成Ingress的“翻译”,随即更新Nginx的配置文件,并执行reload操作,核心逻辑就是这样。
上面我们给“nginx” Service创建了Ingress资源,访问路径配置为“/testpath”,现在进入“ingress-nginx-controller”Pod看下Nginx的配置文件:/etc/nginx/nginx.conf。
关于虚拟主机“mynginx.example.com”的配置有200多行,删掉无关的。
## start server mynginx.example.com
server {
server_name mynginx.example.com ;
listen 80 ;
listen 443 ssl http2 ;
set $proxy_upstream_name "-";
ssl_certificate_by_lua_block {
certificate.call()
}
location ~* "^/testpath" {
set $namespace "test";
set $ingress_name "self-nginx";
set $service_name "nginx";
set $service_port "80";
set $location_path "/testpath";
set $global_rate_limit_exceeding n;
......
set $balancer_ewma_score -1;
set $proxy_upstream_name "test-nginx-80";
set $proxy_host $proxy_upstream_name;
set $pass_access_scheme $scheme;
......
rewrite "(?i)/testpath" / break;
proxy_pass http://upstream_balancer;
proxy_redirect off;
}
location ~* "^/" {
set $namespace "test";
set $ingress_name "self-nginx";
set $service_name "";
set $service_port "";
set $location_path "/";
set $global_rate_limit_exceeding n;
......
proxy_pass http://upstream_balancer;
proxy_redirect off;
}
}
## end server mynginx.example.com
从配置文件中可以看到发往“/testpath”的请求完成一次跳转后最终发送给“upstream_balancer”,其在Nginx配置文件中的定义如下:
upstream upstream_balancer {
### Attention!!!
#
# We no longer create "upstream" section for every backend.
# Backends are handled dynamically using Lua. If you would like to debug
# and see what backends ingress-nginx has in its memory you can
# install our kubectl plugin https://kubernetes.github.io/ingress-nginx/kubectl-plugin.
# Once you have the plugin you can use "kubectl ingress-nginx backends" command to
# inspect current backends.
#
###
server 0.0.0.1; # placeholder
balancer_by_lua_block {
balancer.balance()
}
keepalive 320;
keepalive_timeout 60s;
keepalive_requests 10000;
}
因Nginx配置文件严重依赖Lua,这里看到的信息不直观。为了看到后端服务,按照注释,为kubectl安装“ingress-nginx”插件。在前面Nginx配置文件有下面一行:
set $proxy_upstream_name "test-nginx-80";
指出域名“mynginx.example.com”的backend名为“test-nginx-80”。查看Ingress的backends(省略无关行)。
[root@master ~]# kubectl ingress-nginx backends -n ingress-nginx
[
{
"name": "test-nginx-80",
"service": {
"metadata": {
"creationTimestamp": null
},
"spec": {
"ports": [
{
"name": "http",
"protocol": "TCP",
"port": 80,
"targetPort": 80
}
],
"selector": {
"app": "nginx"
},
"clusterIP": "10.1.133.186",
"clusterIPs": [
"10.1.133.186"
],
"type": "ClusterIP",
"sessionAffinity": "None",
"ipFamilies": [
"IPv4"
],
"ipFamilyPolicy": "SingleStack",
"internalTrafficPolicy": "Cluster"
},
"status": {
"loadBalancer": {}
}
},
"port": 80,
"sslPassthrough": false,
"endpoints": [
{
"address": "10.244.1.26",
"port": "80"
}
],
"sessionAffinityConfig": {
"name": "",
"mode": "",
"cookieSessionAffinity": {
"name": ""
}
},
"upstreamHashByConfig": {
"upstream-hash-by-subset-size": 3
},
"noServer": false,
"trafficShapingPolicy": {
"weight": 0,
"weightTotal": 0,
"header": "",
"headerValue": "",
"headerPattern": "",
"cookie": ""
}
},
......
]
从输出中可以看到后端其实就是名为“nginx”的Service对应的Endpoints,它的IP是“10.244.1.26”。
[root@master ~]# kb get endpoints
NAME ENDPOINTS AGE
nginx 10.244.1.26:80 19h
这里需要强调一点,Nginx Ingress并不将流量转发给nginx service,而是直接转发到后端的Pods,转发策略也完全由Ingress Controller来决定。这样不仅减少了一次DNAT,也能实现更丰富的负载均衡策略。Ingress资源中出现的Service对象只是为了选择后端的Endpoints。
文章对Nginx Ingress做了介绍,Kubernetes中可以选择的Ingress有很多,读者可以根据需要选择。
Recommend
-
43
由于 nginx 的优秀性能表现,所以很多企业在Kubernetes 中选择 Ingress Controller 的时候依然会选择基于 nginx 的 ingress-nginx ,前面文章中我们更多的是介绍更加云原生配...
-
27
在本系列的 第一篇文章 中,我讲了Pod跨Kubernetes集群中的节点相互连接的网络。 第二篇 重点讲了服务网络如何...
-
33
-
15
kubernetes-learn/chapter5/ingress-nginx at book-learn · JasonkayZK/kubernetes-learn · GitHub This branch is 7 commits ahead, 2 commits behind main.
-
16
Deploy Nginx Ingress Controller on Kubernetes using Helm ChartSearch ComputingForGeeksThe standard way of ex...
-
5
// Tutorial //How to Set Up an Nginx Ingress with Cert-Manager on DigitalOcean KubernetesPublished on December 14, 2018 · Updated on March 11, 2022By
-
8
最近发现好多人问 Ingress,同时一直也没去用 Nginx 的 Ingress,索性鼓捣了一把,发现跟原来确实有了点变化,在这里写篇文章记录一下一、Ingress 介绍Kubernetes 暴露服务的方式目前只有三种:LoadBlancer Service、...
-
9
在 kubernetes 中,ingress 负责转发、融断和限流。 我们以 Nginx ingress 为例,讨论一下这方面的问题。 一、Nginx ingress黑白名单 这个很简单了,丢进黑名单或者白名单,在入口前拦一刀。 我们只要在...
-
12
在Kubernetes集群中使用 HTTPS 协议,需要一个证书管理器、一个证书自动签发服务,主要通过 Ingress 来发布 H...
-
7
Kubernetes cluster on AWS EKS, Part 3: Setup NGINX Ingress Controller with Cert-Manager on AWS EKS Mar 21, 2023 •
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK