k8s svc网络之ExternalName代理外部服务,域名
需求场景:
1. 代理不同环境,测试、正式、开发
2. 代理外部数据库,es等服务。因为数据库并不适合部署到k8s,也有可能是迁移量巨大。
如何让集群内资源访问到互联网资源
思考:namespace是作为资源隔离,不同服务放在不同namespace下,如果希望服务之间可以互相访问,也就是跨namespace的服务访问,应该怎么处理呢?
ExternalName(外部名称 )模式
参考文档:https://www.jianshu.com/p/deaa98210827
使用service代理外部ip和端口
创建service
当不指定selector的时候,不会创建endpoint,这个时候就需要手动创建endpoint
apiVersion: v1
kind: Service
metadata:
name: my-mysql-endpoint #此名字需与 my-mysql-endpoints.yaml文件中的 metadata.name 的值一致
namespace: my-first-app #在固定的命名空间下
spec:
ports:
- name: http # 名称必须和ep的一致
port: 3306
protocol: TCP
创建endpoint
apiVersion: v1 kind: Endpoints metadata: name: my-mysql-endpoint #此名字需与 my-mysql-service.yaml文件中的 metadata.name 的值一致 namespace: my-first-app #需要和svc在同一个ns subsets: - addresses: - ip: 39.156.69.79 # 公网mysql地址 ports: - name: http # 名称必须和svc一致
port: 3306 # 服务端口
protocol: TCP
查看ep
测试
如果外部IP变更,只需要更改endpoint配置文件即可。
此种方式只适合Ip+端口访问,对于像阿里云rds等数据库的。需要用域名。则需要用ExternalName
方式不而不是Endpoints
方式
示例:
清单文件
apiVersion: v1 kind: Endpoints metadata: name: nginx-endpoint #此名字需与 my-mysql-service.yaml文件中的 metadata.name 的值一致 namespace: default # 与需要代理的pod在同一namespace subsets: - addresses: - ip: 192.168.43.129 ports: - name: http # 名称必须一致 port: 10086 protocol: TCP --- apiVersion: v1 kind: Service metadata: name: nginx-endpoint namespace: default spec: ports: - name: http port: 10086 protocol: TCP
测试阶段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | [root@master-1 external-ip]# kubectl get pod NAME READY STATUS RESTARTS AGE busybox 1/1 Running 0 69m ingressclass-ingress-nginx-controller-p22gm 1/1 Running 4 3d ingressclass-ingress-nginx-controller-t5wz9 1/1 Running 4 3d ingressclass-ingress-nginx-controller-tt7wg 1/1 Running 4 3d nfs-client-provisioner-7d4f48bb8f-zbhfd 1/1 Running 4 3d1h [root@master-1 external-ip]# kubectl get ep NAME ENDPOINTS AGE ingressclass-ingress-nginx-controller 192.168.43.129:443,192.168.43.130:443,192.168.43.131:443 + 3 more... 3d ingressclass-ingress-nginx-controller-admission 192.168.43.129:8443,192.168.43.130:8443,192.168.43.131:8443 3d k8s-sigs.io-nfs-subdir-external-provisioner <none> 3d1h kubernetes 192.168.43.129:6443 3d1h nginx-endpoint 192.168.43.129:10086 14s [root@master-1 external-ip]# kubectl describe svc nginx-endpoint Name: nginx-endpoint Namespace: default Labels: <none> Annotations: <none> Selector: <none> Type: ClusterIP IP Families: <none> IP: 10.0.54.244 IPs: 10.0.54.244 Port: http 10086/TCP TargetPort: 10086/TCP Endpoints: 192.168.43.129:10086 Session Affinity: None Events: <none> [root@master-1 external-ip]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingressclass-ingress-nginx-controller ClusterIP 10.0.229.195 <none> 80/TCP,443/TCP 3d ingressclass-ingress-nginx-controller-admission ClusterIP 10.0.225.25 <none> 443/TCP 3d kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 3d1h nginx-endpoint ClusterIP 10.0.54.244 <none> 10086/TCP 8m53s 集群外访问svc [root@master-1 external-ip]# curl 10.0.54.244:10086 ... <a href= "http://nginx.com/" >nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> <p><em>From 192.168.43.129.</em></p> </body> </html> pod内访问 [root@master-1 external-ip]# kubectl exec -it ingressclass-ingress-nginx-controller-p22gm -- curl nginx-endpoint:10086 ... <p><em>Thank you for using nginx.</em></p> <p><em>From 192.168.43.129.</em></p> </body> </html> |
EXternalName反代外部域名
创建连接外部MySQL数据库的svc,EXternalName需要和需要访问外网的pod在同一个namespace,pod通过访问service,cname到externalName指定的地址。
kind: Service
apiVersion: v1
metadata:
name: my-service-1
namespace: default
spec:
type: ExternalName
externalName: www.baidu.com //当访问my-service-1.default.svc.cluster.local时,会由coredns cname到www.baidu.com
kind: Service apiVersion: v1 metadata: name: external-domain namespace: default spec: type: ExternalName externalName: nginx-configmap.app # 错误配置示例 [root@master-1 opt]# kubectl get svc -n app NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-configmap NodePort 10.0.225.138 <none> 80:40395/TCP,443:33828/TCP 33m [root@master-1 opt]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE external-domain ExternalName <none> nginx-configmap.app <none> 32m [root@master-1 opt]# kubectl exec ingressclass-ingress-nginx-controller-p22gm -- curl external-domain.default.svc.cluster.local % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (6) Could not resolve host: external-domain.default.svc.cluster.local command terminated with exit code 6 # 直接访问可以通 [root@master-1 opt]# kubectl exec ingressclass-ingress-nginx-controller-p22gm -- curl -i nginx-configmap.app % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 692 100 692 0 0 109k 0 --:--:-- --:--:-- --:--:-- 135k HTTP/1.1 200 OK Server: nginx/1.27.2
修改后
kind: Service apiVersion: v1 metadata: name: external-domain namespace: default spec: type: ExternalName externalName: nginx-configmap.app.svc.cluster.local [root@master-1 externaldomain]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE external-domain ExternalName <none> nginx-configmap.app.svc.cluster.local <none> [root@master-1 externaldomain]# kubectl exec ingressclass-ingress-nginx-controller-p22gm -- curl -i external-domain % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0HTTP/1.1 200 OK Server: nginx/1.27.2 Date: Thu, 28 Nov 2024 06:32:23 GMT [root@master-1 externaldomain]# kubectl exec ingressclass-ingress-nginx-controller-p22gm -- curl -i external-domain.default.svc.cluster.local. % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0HTTP/1.1 200 OK 总结: 在清单文件 externalName: nginx-configmap.app.svc.cluster.local 必须写完整域名路径
pod跨namespace
]# cat svc_ExternalName_visit.yaml 5 # 实现 myns 名称空间的pod,访问 mytest 名称空间的Service:myapp-clusterip2 6 apiVersion: v1 7 kind: Service 8 metadata: 9 name: myapp-clusterip1-externalname 10 namespace: myns 11 spec: 12 type: ExternalName # 指定类型 13 externalName: myapp-clusterip2.mytest.svc.cluster.local # 对方的svcname.namespace.svc.cluster.local. 14 ports: 15 - name: http 16 port: 80 17 targetPort: 80
19 # 实现 mytest 名称空间的Pod,访问 myns 名称空间的Service:myapp-clusterip1 20 apiVersion: v1 21 kind: Service 22 metadata: 23 name: myapp-clusterip2-externalname 24 namespace: mytest 25 spec: 26 type: ExternalName 27 externalName: myapp-clusterip1.myns.svc.cluster.local //填写对端完整域名 28 ports: 29 - name: http 30 port: 80 31 targetPort: 80
测试是否可以跨namespace访问
如下说明通过Service externalname类型,实现了Pod跨namespace名称空间与Service访问 18 ~ # ping myapp-clusterip2-externalname //ExternalName名称实现了cname转发 19 PING myapp-clusterip2-externalname (10.100.61.11): 56 data bytes 20 64 bytes from 10.100.61.11: seq=0 ttl=64 time=0.089 ms 21 64 bytes from 10.100.61.11: seq=1 ttl=64 time=0.071 ms
24 ~ # wget myapp-clusterip2-externalname -O myns.html 25 Connecting to myapp-clusterip2-externalname (10.100.61.11:80) 26 myns.html 100%
28 ~ # cat myns.html 29 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
越学越感到自己的无知
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
2022-05-29 zabbix-基于Java Gateway监控Tomcat