赞
踩
在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一下使配置生效,以此达到分配和动态更新问题。
以nginx为例,流程图如下:
架构图如下:
以上图片来源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 <none> <none> ingress-nginx-admission-patch-h6f5d 0/1 Completed 0 43h 172.16.28.8 node3 <none> <none> ingress-nginx-controller-6c88c85c98-v8mgs 1/1 Running 0 30h 192.168.5.79 node1 <none> <none> [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 <none> <none> tomcat-656df44d6c-6znd9 1/1 Running 0 29h 172.16.28.13 node3 <none> <none> [root@node1 yaml]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-svc ClusterIP 10.233.43.219 <none> 80/TCP 30h tomcat-svc ClusterIP 10.233.52.85 <none> 8080/TCP 30h #################################################### 3:测试nginx服务没问题 [root@node1 yaml]# curl 10.233.43.219 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> [root@node1 yaml]# ################################### 4:测试tomcat 服务 [root@node1 yaml]# curl 10.233.52.85:8080 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Apache Tomcat/8.0.53</title> <link href="favicon.ico" rel="icon" type="image/x-icon" /> <link href="favicon.ico" rel="shortcut icon" type="image/x-icon" /> <link href="tomcat.css" rel="stylesheet" type="text/css" /> </head> <body> <div id="wrapper"> <div id="navigation" class="curved container"> <span id="nav-home"><a href="https://tomcat.apache.org/">Home</a></span> <span id="nav-hosts"><a href="/docs/">Documentation</a></span>
1:编写ingress yaml --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-test spec: ingressClassName: nginx ########使用的实际负载均衡器类型 rules: - host: "test.nginx.com" #########nginx的域名 http: paths: - path: "/" pathType: Prefix backend: service: name: nginx-svc ###nginx的svc name port: number: 80 - host: "test.tomcat.com" ######tomcat的域名 http: paths: - path: "/" pathType: Prefix backend: service: name: tomcat-svc ###tomcat的svc name port: number: 8080 ############################################### 2:apply创建规则 [root@node1 yaml]# kubectl apply -f ingress.yaml [root@node1 ~]# [root@node1 ~]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-test nginx test.nginx.com,test.tomcat.com 192.168.5.79 80 29h 可以看到address为ingress-controller pod所在节点的物理地址,port为80 ################################################## 3:进入ingress-controller pod里面,查看更新的规则 [root@node1 ~]# kubectl exec -it ingress-nginx-controller-6c88c85c98-v8mgs -n ingress-nginx bash kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. bash-5.1$ bash-5.1$ cat /etc/nginx/nginx.conf ## start server test.nginx.com server { server_name test.nginx.com ; ###ingress中定义的host listen 80 ; ###container port listen [::]:80 ; listen 443 ssl http2 ; listen [::]:443 ssl http2 ; set $proxy_upstream_name "-"; ssl_certificate_by_lua_block { certificate.call() } location / { set $namespace "default"; ###命名空间 set $ingress_name "ingress-test"; ###ingress 名称 set $service_name "nginx-svc"; ###nginx svc名称 set $service_port "80"; set $location_path "/"; set $global_rate_limit_exceeding n; #############下面是tomcat的配置 ## start server test.tomcat.com server { server_name test.tomcat.com ; listen 80 ; listen [::]:80 ; listen 443 ssl http2 ; listen [::]:443 ssl http2 ; set $proxy_upstream_name "-"; ssl_certificate_by_lua_block { certificate.call() } location / { set $namespace "default"; set $ingress_name "ingress-test"; set $service_name "tomcat-svc"; set $service_port "8080"; set $location_path "/"; set $global_rate_limit_exceeding n;
windows 机器添加host解析
文件位置:C:\WINDOWS\System32\drivers\etc\hosts
192.168.5.79 test.nginx.com test.tomcat.com
访问nginx界面
访问tomcat界面
1:生成证书 [root@node1 cert]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BJ/O=nginx/CN=test.com" ###注意此处的域名 Generating a RSA private key .........................................................+++++ ...+++++ writing new private key to 'tls.key' ----- [root@node1 cert]# ll total 8 -rw-r--r-- 1 root root 1261 Nov 10 16:55 tls.crt -rw------- 1 root root 1704 Nov 10 16:55 tls.key [root@node1 cert]# 2:创建secret [root@node1 cert]# kubectl create secret tls tls-secret --key tls.key --cert tls.crt secret/tls-secret created [root@node1 cert]# kubectl get secret | grep tls-secret tls-secret kubernetes.io/tls 2 19s [root@node1 cert]#
1:编辑yaml文件 [root@node1 yaml]# cat ingress-https.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-test spec: tls: - hosts: - nginx.test.com ###制定使用tls的主机 - tomcat.test.com secretName: tls-secret ###指定secret ingressClassName: nginx rules: - host: "nginx.test.com" http: paths: - path: "/" pathType: Prefix backend: service: name: nginx-svc port: number: 80 - host: "tomcat.test.com" http: paths: - path: "/" pathType: Prefix backend: service: name: tomcat-svc port: number: 8080 [root@node1 yaml]# ######################################## 2:创建ingress,如下可以看到ports 多了个443端口 [root@node1 yaml]# kubectl apply -f ingress-https.yaml ingress.networking.k8s.io/ingress-test created [root@node1 yaml]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-test nginx nginx.test.com,tomcat.test.com 80, 443 7s [root@node1 yaml]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-test nginx nginx.test.com,tomcat.test.com 192.168.5.79 80, 443 43s
windows 机器添加host解析
文件位置:C:\WINDOWS\System32\drivers\etc\hosts
192.168.5.79 nginx.test.com tomcat.test.com
访问nginx,如下:
访问tomcat,如下:
注意:如果显示以下问题,可以在当前浏览器页面,直接敲键盘输入thisisunsafe就可以了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。