最近接到很多用户在将服务迁移到tke的时候遇到一个问题,那就是我的服务以前是部署在集群外的cvm上,但是现在我将一部分迁移到了tke,现在我需要用一个同一个的入口来提供访问。
一般集群提供对外服务,都是用clb类型的ingress,那么如何将集群外cvm自建的服务也加到ingress的clb上呢?
由于tke这边关联的clb,有自己的生命周期管理,所以不能直接单独在clb那边加上监听配置,一旦ingress触发更新,就会覆盖手动在clb加的配置。
既然这样的话,是不是没有其他办法来解决呢?其实这里还是有办法的,我们可以用endpoint的方式来引入外部服务到集群内,然后ingress转发到外部服务的svc即可。
但是这里还是有限制,就是ingress不能用直连类型,为什么不行呢?这里我解释下因为endpoint的方式是将外部服务ip和端口加进来,在k8s集群内实际是不存在pod的,如果是直连的ingress,clb监听后端rs是pod,所以直连,clb会找不到监听的后端rs。
这里只能用非直连的ingress,非直连的ingress,是绑定的集群内每个节点nodeport,我们只需要用endpoint引入外部服务,然后创建一个nodeport类型的svc绑定这个endpoint,最后ingress将请求转发到这个svc即可。
下面我们具体来实践下,首先我们在集群外部署一个nginx服务,然后集群内有一个springboot的接口服务,我们通过一个clb类型ingress来转发
创建下endpoint和svc将外部服务引入到集群
代码语言:javascript复制kind: Endpoints
apiVersion: v1
metadata:
# 此处 metadata.name 的值要和 service 中的 metadata.name 的值保持一致
# endpoint 的名称必须和服务的名称相匹配
name: out-cluster-nginx
namespace: weixnie
subsets:
- addresses:
# 服务将连接重定向到 endpoint 的 IP 地址
- ip: 172.16.0.4
ports:
# 外部服务端口
# endpoint 的目标端口
- port: 8088
---
apiVersion: v1
kind: Service
metadata:
# 此处 metadata.name 的值要和 endpoints 中的 metadata.name 的值保持一致
name: out-cluster-nginx
# 外部服务服务统一在固定的名称空间中
namespace: weixnie
spec:
type: NodePort
ports:
- protocol: TCP
port: 8088
targetPort: 8088
然后配置下集群内的springboot服务
代码语言:javascript复制apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: springboot
qcloud-app: springboot
name: springboot
namespace: weixnie
spec:
externalTrafficPolicy: Cluster
ports:
- name: 8080-8080-tcp
port: 8080
protocol: TCP
targetPort: 8080
selector:
k8s-app: springboot
qcloud-app: springboot
sessionAffinity: None
type: NodePort
然后配置下clb类型的ingress来转发到这2个后端的svc服务
代码语言:javascript复制apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: qcloud
name: ingress-test
namespace: weixnie
spec:
rules:
- http:
paths:
- backend:
serviceName: springboot
servicePort: 8080
path: /hello
pathType: ImplementationSpecific
- http:
paths:
- backend:
serviceName: out-cluster-nginx
servicePort: 8088
path: /
pathType: ImplementationSpecific
创建好之后,我们就可以通过ingress对应clb的vip来进行访问了
可以发现,我们可以通过一个一个clb的不同路径访问到集群内和集群外服务了
注意: 如果ingress转发到endpoint引导外部服务的svc失败,需要升级下ingress控制器的版本,v1.7.3版本控制器转发存在问题,可以用下面命令升级下 kubectl set image deployment/l7-lb-controller l7-lb-controller=ccr.ccs.tencentyun.com/library/qcloud_ingress_controller:v1.7.4 -nkube-system