k8s网络-ingress
Ingress资源
https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/
Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。
Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。
1.为什么会出现Ingress
将应用部署在k8s中,也就是pod后,如何在集群内访问、以及如何在集群外访问,才是核心目的,毕竟还是以web项目为主。
1.在没有ingress(入口)之前,pod对集群外提供访问,只能通过NodePort方式,也就是端口映射方式,但是这个缺点很明显,一个Node上的port有限,并且不能重复使用。
podA占用了80端口,其他服务就无法使用了。
2.我们上一节使用的Service且NodePort类型,是基于四层的代理转发,基于TCP、UDP协议转发。
缺点已经说过了,就像早期于超老师带着大家学nginx一样,Nginx也是支持基于四层、七层的代理转发的。
很明显,基于七层的http转发,粒度更细,能直接基于域名区分请求。
基于七层的http、https协议转发,以及通过域名、路径的转发,能实现更细粒度的请求划分,并且解决端口问题。
【思考下多端口虚拟主机、多域名虚拟主机,是不是区别很大?】
3.为了解决这个问题,Ingress控制器资源出现了,作用就是实现七层的协议转发,通过域名、路径的匹配转发,提供k8s集群的访问入口。
4.有同学想,既然nginx可以实现传统的七层代理转发,为什么还要有ingress?
毕竟你要注意你的应用,以pod形式在k8s环境内运行,外部的nginx无法动态发现k8s创建的资源。
5.k8s下的ingress控制器,具体实现的产品,有ingress-nginx、traefik。
2.图解Ingress工作原理
3.Ingress工作机制
想要使用Ingress功能,得先在k8s集群上安装ingress controller。
目前也有很多种软件实现了Ingress控制器,官网维护的就是
https://github.com/kubernetes/ingress-nginx
外部请求先到达Ingress控制器,控制器根据路由规则,找到对应的Service,然后通过Endpoint记录的pod地址列表,将请求最终转发给pod。
4.创建基于域名的Ingress
https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/#path-types
先安装ingress-nginx,使用k8s权威指南第五版的ingress.yaml即可。
https://github.com/kubeguide/K8sDefinitiveGuide-V5-Sourcecode/blob/main/Chapter04/4.6.1%20ingress.yaml
创建Ingress-nginx控制器
[root@k8s-master-10 ~/ingress]#kubectl apply -f ingress.yml
namespace/nginx-ingress created
serviceaccount/nginx-ingress created
clusterrole.rbac.authorization.k8s.io/nginx-ingress created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress created
secret/default-server-secret created
configmap/nginx-config created
deployment.apps/nginx-ingress created
# [root@k8s-master-10 ~/ingress]#kubectl -n nginx-ingress describe po nginx-ingress-75c88594dc-klfqc
# 发现需要有node-Selector
# 给节点打上标签
[root@k8s-master-10 ~/ingress]#kubectl label nodes k8s-master-10 role=ingress-nginx-controller
# 又发现,k8s-master默认有污点,pod不能容忍,因此没法部署。
设置master也参与pod调度
[root@k8s-master-10 ~/ingress]#kubectl describe nodes k8s-master-10 |grep Taint
Taints: node-role.kubernetes.io/master:NoSchedule
# 去掉污点
kubectl taint node k8s-master-10 node-role.kubernetes.io/master:NoSchedule-
验证ingress-nginx控制正常
[root@k8s-master-10 ~/ingress]#kubectl -n nginx-ingress get po -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-ingress-75c88594dc-klfqc 1/1 Running 0 7m47s 10.2.0.6 k8s-master-10 <none> <none>
[root@k8s-master-10 ~/ingress]#kubectl -n nginx-ingress get all -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/nginx-ingress-75c88594dc-klfqc 1/1 Running 0 8m33s 10.2.0.6 k8s-master-10 <none> <none>
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/nginx-ingress 1/1 1 1 8m33s nginx-ingress nginx/nginx-ingress:1.7.2 app=nginx-ingress
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/nginx-ingress-75c88594dc 1 1 1 8m33s nginx-ingress nginx/nginx-ingress:1.7.2 app=nginx-ingress,pod-template-hash=75c88594dc
# 其实就是运行了一个nginx在pod里
创建ingree规则
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
namespace: yuchaoit
spec:
rules: # 转发规则
- host: "www.yuchaoit.cn" # 填入你们的业务域名
http: # 基于http协议解析
paths: # 基于url路径匹配
- pathType: Prefix #要设置路径类型,否则不合法,
path: "/" # 以 / 分割的URL路径前缀匹配,区分大小写,这里表默认所有路径。
backend: # 后端Service信息的组合
service:
name: service1 # 代理到名字是service1的ClusterIP
port: # 代理到的Service的端口号。
number: 80
创建,查看ingress
[root@k8s-master-10 ~/ingress]#kubectl create -f my-ingress.yml
ingress.networking.k8s.io/test-ingress created
[root@k8s-master-10 ~/ingress]#kubectl -n yuchaoit get ingress -o wide
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
test-ingress <none> www.yuchaoit.cn 80 10s
# 查看ingress是否正确
[root@k8s-master-10 ~/ingress]#kubectl -n yuchaoit describe ingress test-ingress
创建ingress后端的service、pod
apiVersion: apps/v1 # 注意这里与Pod的区别,Deployment是apps/v1而不是v1
kind: Deployment # 资源类型为Deployment
metadata:
name: nginx-deployment # Deployment的名称
namespace: yuchaoit
spec:
replicas: 2 # Pod的数量,Deployment会确保一直有2个Pod运行
selector: # Label Selector
matchLabels:
app: nginx
template: # Pod的定义,用于创建Pod,也称为Pod template
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.14.0
name: nginx-containers
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80 # 指明容器内要暴露的端口
resources:
limits:
cpu: 100m
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
创建svc
apiVersion: v1
kind: Service
metadata:
name: service1 # Service的名称
namespace: yuchaoit
spec:
selector: # Label Selector,选择包含app=nginx标签的Pod
app: nginx
ports:
- name: service0
targetPort: 80 # Pod的端口
port: 80 # Service对外暴露的端口,也就是ClusterIP的port
protocol: TCP # 转发协议类型,支持TCP和UDP
type: ClusterIP # Service的类型
创建结果
[root@k8s-master-10 ~/ingress]#kubectl -n yuchaoit get svc service1 -owide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service1 ClusterIP 10.1.56.133 <none> 80/TCP 15s app=nginx
检验ingress状态
访问七层负载均衡的k8s集群
修改pod首页,查看效果。
kubectl -n yuchaoit exec -it nginx-deployment-6f7886b6db-xsj8n -- bash -c 'echo "<meta charset=utf8>老司机带你学k8s,222" > /usr/share/nginx/html/index.html'
kubectl -n yuchaoit exec -it nginx-deployment-6f7886b6db-pvjd5 -- bash -c 'echo "<meta charset=utf8>老司机带你学k8s,111" > /usr/share/nginx/html/index.html'
ingress七层代理原理(面试背)
在生产下,ingress的七层域名,就直接绑定到SLB的地址即可。
1. ingress controller 通过和 api-server交互,动态感知集群中ingress规则的变化
2. ingress controller 读取ingress规则,也就是你们的业务域名,对应哪个Service、自动生成nginx配置,再写入到ingress控制器所处的pod,里面的nginx.conf
3. 自动reload nginx,实现域名,配置动态更新。
grep -E '[a-z]' /etc/nginx/conf.d/yuchaoit-test-ingress.conf