在k8s集群中,service和pod的ip为内网ip,仅集群内部才可以访问。如果外部应用想要直接访问集群内的服务,就需要把外部请求通过负载均衡转发到service上,然后再由kube-proxy组件将其转发给后端pod。一般service可以通过NodePort和LoadBalancer两种方式对外提供访问,但是这两种方式都有以下缺点
NodePort:将service暴露在节点网络上,NodePort背后就是Kube-Proxy,Kube-Proxy是沟通service网络、Pod网络和节点网络的桥梁。
小集群使用还行,当集群规模较大时,NodePort的端口管理就是个灾难。因为每个端口只能是一种服务,端口范围只能是 30000-32767。
LoadBalancer:通过设置LoadBalancer映射到云服务商提供的LoadBalancer地址。这种用法仅用于在公有云服务提供商的云平台上设置 Service 的场景。受限于云平台,且通常在云平台部署LoadBalancer还需要额外的费用。在service提交后,Kubernetes就会调用CloudProvider在公有云上为你创建一个负载均衡服务,并且把被代理的Pod的IP地址配置给负载均衡服务做后端。
基于这种现状,kubernetes提供了Ingress资源对象,Ingress只需要一个NodePort或者一个LB就可以满足暴露多个Service的需求。
Ingress 是对集群中服务的外部访问进行管理的 API 对象,通过yaml文件来配置,定义请求如何转发到service的规则。ingress通过http或https暴露集群内部service,给service提供外部URL、负载均衡、SSL/TLS能力以及基于域名的反向代理。Ingress相当于一个7层的负载均衡器,它的工作原理类似于Nginx,当在Ingress中建立映射规则,Ingress Controller通过监听这些配置规则并转化成Nginx的反向代理配置 , 然后对外部提供服务。ingress要依靠 ingress-controller 来具体实现以上功能。
通过yaml文件定义的规则集合,一个api对象。
反向代理负载均衡器就是 nginx、apache等中间件,新版k8s已经将Nginx与Ingress Controller合并为一个组件,所以Nginx无需单独部署,只需要部署Ingress Controller即可。在集群中反向代理负载均衡器可以自由部署,可以使用Replication Controller、Deployment、DaemonSet等等方式。常用的负载均衡器有以下几种
1:Kubernetes Ingress作为"官方"控制器,它是由社区基于NGINX Web服务器开发的,并补充了一组用于实现额外功能的Lua插件。
2:NGINX Ingress 这是NGINX开发人员的官方产品,NGINX控制器具有很高的稳定性,持续的向后兼容性,没有任何第三方模块,并且由于消除了Lua代码而保证了较高的速度(与官方控制器相比)
3:Kong Ingress 由Kong Inc开发,并且有两个版本:商业版本和免费版本。Kong Ingress建立在NGINX之上,并增加了扩展其功能的Lua模块。
4:HAProxy Ingress 由HAProxy开发,它提供了“软”配置更新(无流量丢失),基于DNS的服务发现,通过API的动态配置。
5:Traefik 是一个全功能的 ingress 控制器 (Let’s Encrypt,secrets,http2,websocket),并且它也有来自 Containous 的商业支持。
6:Istio 是IBM,Google和Lyft(Envoy的原始作者)的联合项目,它是一个全面的服务网格解决方案。它不仅可以管理所有传入的外部流量(作为Ingress控制器),还可以控制集群内部的所有流量。
监听apiserver,获取服务新增,删除等变化,并结合ingress规则动态更新到反向代理负载均衡器上,并重载配置使其生效。
使用watch机制: Service始终watch着后端pod变化。只要pod发生变化,api-server立刻检测到
1:ingress controller通过和kubernetes api交互,动态的去感知集群中ingress规则变化。
2:读取ingress自定义的规则,规则就是写明了那个域名对应哪个service,生成一段nginx配置。
3;写入nginx-ingress-controller的pod里,这个Ingress controller的pod里运行着一个Nginx服务,控制器会把生成的nginx配置写入/etc/nginx/nginx.conf文件中的upstream里面
4:重新加载配置,nginx -s reload一下使配置生效,以此达到分配和动态更新问题。
以上图片来源https://cloud.tencent.com/developer/article/1718482
通过wget下载需要用到的ingress文件,此次部署用的是1.9.0版本。
[root@node1 ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.0/deploy/static/provider/baremetal/deploy.yaml
目前国外的镜像源已经不可用,需要修改镜像的源地址,如下:
1:修改ingress-controller的镜像源地址
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: LD_PRELOAD
value: /usr/local/lib/libmimalloc.so
image: registry.aliyuncs.com/google_containers/nginx-ingress-controller:v1.9.0 ###此处修改为阿里的源
imagePullPolicy: IfNotPresent
#############################
2:修改webhook-certgen的镜像源地址(有两处需要修改)
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: registry.aliyuncs.com/google_containers/kube-webhook-certgen:v20230407 #####修改镜像源地址
imagePullPolicy: IfNotPresent
3:修改ingress-controller的网络模式
spec:
hostNetwork: true #####添加此处配置,修改为主机模式
containers:
- args:
- /nginx-ingress-controller
- --election-id=ingress-nginx-leader
- --controller-class=k8s.io/ingress-nginx
- --ingress-class=nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
env:
- name: POD_NAME
[root@node1 ingress]# kubectl apply -f deploy.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@node1 ingress]# kubectl get po -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-hk2sx 0/1 ContainerCreating 0 3s
ingress-nginx-admission-patch-h6f5d 0/1 ContainerCreating 0 3s
ingress-nginx-controller-548689bbd7-8lzrj 0/1 ContainerCreating 0 3s
[root@node1 ~]# kubectl get po -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-admission-create-hk2sx 0/1 Completed 0 43h 172.16.44.4 node2
ingress-nginx-admission-patch-h6f5d 0/1 Completed 0 43h 172.16.28.8 node3
ingress-nginx-controller-6c88c85c98-v8mgs 1/1 Running 0 30h 192.168.5.79 node1
[root@node1 ~]#
###########以上可以看到ingress-controller的ip使用的是主机的ip。
1:编写yaml如下:
[root@node1 yaml]# cat nginx-tomcat.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: docker.io/library/nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx
ports:
- port: 80
protocol: TCP
targetPort: 80
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat
labels:
app: tomcat
spec:
replicas: 1
selector:
matchLabels:
app: tomcat
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: docker.io/library/tomcat:8.0-alpine ###测试了好几个镜像,就这个能显示tom 猫
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-svc
spec:
selector:
app: tomcat
ports:
- port: 8080
protocol: TCP
targetPort: 8080
type: ClusterIP
[root@node1 yaml]#
#################################################
2;启动nginx 和tomcat
[root@node1 yaml]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-5977dc5756-glczk 1/1 Running 0 30h 172.16.44.6 node2
tomcat-656df44d6c-6znd9 1/1 Running 0 29h 172.16.28.13 node3
[root@node1 yaml]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc ClusterIP 10.233.43.219 80/TCP 30h
tomcat-svc ClusterIP 10.233.52.85 8080/TCP 30h
####################################################
3:测试nginx服务没问题
[root@node1 yaml]# curl 10.233.43.219
Welcome to nginx!
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.
For online documentation and support please refer to
nginx.org.
Commercial support is available at
nginx.com.
Thank you for using nginx.
[root@node1 yaml]#
###################################
4:测试tomcat 服务
[root@node1 yaml]# curl 10.233.52.85:8080
Apache Tomcat/8.0.53