Ingress 是什么
NodePort存在的不足
001 一个端口只能一个服务使用,端口需提前规划
002 只支持4层负载均衡(只支持4层的负载均衡,iptables和ipvs都是4层之间的数据包转发,不支持基于域名做分流,不支持基于url做匹配,不支持正则匹配)
Ingress
001 Ingress公开了从集群外部到集群内服务的HTTP和HTTPS路由的规则集合,而具体实现流量路
由则是由Ingress Controller负责
002 Ingress是K8s中的一个抽象资源,给管理员提供一个暴露应用的入口定义方法
003 Ingress Controller根据Ingress生成具体的路由规则,并对Pod负载均衡器

1637448291198.png
Ingress Controller
启动
[root@k8smaster ingress]# kubectl apply -f ingress-controller.yaml
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
[root@k8smaster ingress]# kubectl get pods -n ingress-nginx -o wide
NAME READY STATUS IP NODE
nginx-ingress-controller-5dc64b58f-kh98n 1/1 Running 192.168.153.22 k8snode1
-------------------------------------------------------
hostNetwork: true 这个配置是pod使用节点上的网络
规则模板
apiVersion: apps/v1
kind: Deployment
metadata:
name: web1
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: web1
template:
metadata:
labels:
app: web1
spec:
containers:
- name: web
image: nginx:1.18
---
apiVersion: v1
kind: Service
metadata:
name: web1
namespace: default
spec:
ports:
- port: 80 # service端口
protocol: TCP # 协议
targetPort: 80 # 容器端口
selector: # 标签选择器
app: web1 # 指定关联Pod的标签
type: ClusterIP # 服务类型
规则一
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web1
spec:
rules:
- host: web1.ctnrs.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web1
port:
number: 80
-----------------------------------------------------------------------------
[root@k8smaster ingress]# kubectl get Ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
web1 <none> web1.ctnrs.com 80 3m9s
[root@k8smaster ingress]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/web1-d59d4b5f5-cq745 1/1 Running 0 5m23s
pod/web1-d59d4b5f5-glbnl 1/1 Running 0 5m23s
pod/web1-d59d4b5f5-hl6w2 1/1 Running 0 5m23s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
service/web1 ClusterIP 10.105.215.243 <none> 80/TCP 5m23s
-------------------------------------------------------------------------------------
#hosts:
192.168.153.22 web1.ctnrs.com
#访问
http://web1.ctnrs.com/

1637467965896.png
规则二 基于URI路由多个服务

1637472749859.png
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web2
spec:
rules:
- host: web2.ctnrs.com
http:
paths:
- path: /foo
pathType: Prefix
backend:
service:
name: web2
port:
number: 80
- path: /bar
pathType: Prefix
backend:
service:
name: web3
port:
number: 80
--------------------------------------------------------------------------
#访问
http://web2.ctnrs.com/foo/index.html ->service:80/foo/index.html
http://web2.ctnrs.com/bar/index.html ->service:80/bar/index.html
[root@k8smaster ingress]# kubectl get pod
NAME READY STATUS RESTARTS AGE
......
web2-5fbc85ff4-5gldl 1/1 Running 0 8m17s
web3-77d6ccfff7-24bcz 1/1 Running 0 7m37s
[root@k8smaster ingress]# kubectl exec -it web2-5fbc85ff4-5gldl bash
root@web2-5fbc85ff4-5gldl:/# cd /usr/share/nginx/html/
root@web2-5fbc85ff4-5gldl:/usr/share/nginx/html# ls
50x.html index.html
root@web2-5fbc85ff4-5gldl:/usr/share/nginx/html# mkdir foo
root@web2-5fbc85ff4-5gldl:/usr/share/nginx/html# cd foo
root@web2-5fbc85ff4-5gldl:/usr/share/nginx/html/foo# echo foo > index.html
root@web2-5fbc85ff4-5gldl:/usr/share/nginx/html# cp -r foo/index.html ./
[root@k8smaster ingress]# kubectl exec -it web3-77d6ccfff7-24bcz bash
root@web3-77d6ccfff7-24bcz:/# cd /usr/share/nginx/html/
root@web3-77d6ccfff7-24bcz:/usr/share/nginx/html# mkdir bar
root@web3-77d6ccfff7-24bcz:/usr/share/nginx/html# cd bar/
root@web3-77d6ccfff7-24bcz:/usr/share/nginx/html/bar# echo bar > index.html
http://web2.ctnrs.com/foo/
foo
http://web2.ctnrs.com/bar/
bar
规则三 基于名称的虚拟主机

1637472800254.png
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web3
spec:
rules:
- host: web3-1.ctnrs.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: web2
port:
number: 80
- host: web3-2.ctnrs.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: web3
port:
number: 80
------------------------------------------------------------------
http://web3-1.ctnrs.com/
foo
http://web3-2.ctnrs.com/
bar
HTTPS
准备域名证书文件
[root@k8smaster ssl]# yum -y install wget
[root@k8smaster ssl]# ./cfssl.sh
[root@k8smaster ssl]# ./certs.sh
将证书文件保存到Secret
[root@k8smaster ssl]# kubectl create secret tls blog-ctnrs-com --cert=blog.ctnrs.com.pem --key=blog.ctnrs.com-key.pem
...
secret/blog-ctnrs-com created
[root@k8smaster ssl]# kubectl get secret
NAME TYPE DATA AGE
blog-ctnrs-com kubernetes.io/tls 2 21s
Ingress规则配置tls
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: blog
spec:
tls:
- hosts:
- blog.ctnrs.com
secretName: blog-ctnrs-com
rules:
- host: blog.ctnrs.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web2
port:
number: 80
------------------------------------------------------------------------
blog.ctnrs.com是证书里注册域名
https://blog.ctnrs.com/
个性化配置
设置代理超时参数
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: annotation-test
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
设置客户端上传文件大小
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: annotation-test
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/proxy-body-size: "1000m"
示例一
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: annotation-test
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-body-size: "1000m"
spec:
rules:
- host: annotation.ctnrs.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web1
port:
number: 80
---------------------------------------------------------------------
[root@k8smaster ingress]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-5dc64b58f-kh98n 1/1 Running 3 20h
[root@k8smaster ingress]# kubectl exec -it nginx-ingress-controller-5dc64b58f-kh98n bash -n ingress-nginx
bash-5.0$ vi /etc/nginx/nginx.conf
#所有的生效信息都在/etc/nginx/nginx.conf中
重定向
java-demo
apiVersion: apps/v1
kind: Deployment
metadata:
name: web5
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: web5
template:
metadata:
labels:
app: web5
spec:
containers:
- name: javademo
image: lizhenliang/java-demo
---
apiVersion: v1
kind: Service
metadata:
name: web5
namespace: default
spec:
ports:
- port: 80 # service端口
protocol: TCP # 协议
targetPort: 8080 # 容器端口
selector: # 标签选择器
app: web5 # 指定关联Pod的标签
type: NodePort # 服务类型
--------------------------------------------------------------------------
[root@k8smaster ingress]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
web5 NodePort 10.107.201.128 <none> 80:32502/TCP 77s
#此时访问http://192.168.153.22:32502/
规则
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web5
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/server-snippet: |
rewrite ^/css/(.*)$ /bar/css/$1 redirect;
rewrite ^/images/(.*)$ /bar/images/$1 redirect;
rewrite ^/js/(.*)$ /bar/js/$1 redirect;
spec:
rules:
- host: web5.ctnrs.com
http:
paths:
- path: /foo # Nginx
pathType: Prefix
backend:
service:
name: web1
port:
number: 80
- path: /bar(/|$)(.*) # Java网站
pathType: Prefix
backend:
service:
name: web5
port:
number: 80
-------------------------------------------------------------------------
#访问nginx
http://web5.ctnrs.com/foo
#访问java-demo
http://web5.ctnrs.com/bar
此示例中包含了重定向和自定义规则
自定义规则
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: snippet-test
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
if ($http_user_agent ~* '(Android|iPhone)') {
rewrite ^/(.*) http://m.baidu.com break;
}
spec:
rules:
- host: snippet.ctnrs.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web5
port:
number: 80
--------------------------------------------------------------------------------
http://snippet.ctnrs.com/
#正常页面访问是java-demo
#调整成手机端访问是m.baidu.com
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
ports:
- port: 80 # service端口
protocol: TCP # 协议
targetPort: 80 # 容器端口
selector: # 标签选择器
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
type: ClusterIP # 服务类型
--------------------------------------------------
[root@k8smaster ingress]# kubectl apply -f ingress-nginx.yaml
[root@k8smaster ingress]# kubectl delete -f ingress-controller.yaml
Ingress Controller怎么工作
001 Ingress Contronler通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取 它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,
002 生成一段 Nginx 配置,应用到管理的Nginx服务,然后热加载生效。
003 以此来达到Nginx负载均衡器配置及动态更新的问题。
004 流程包流程:客户端 ->Ingress Controller(nginx) -> 分布在各节点Pod
Ingress Controller高可用方案
一般Ingress Controller会以DaemonSet+nodeSelector部署到几台特定Node,然后将这几台挂载到公网负载均衡器对外提供服务。

1637544899257-1637544899305.png
网友评论