惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

A
About on SuperTechFans
Y
Y Combinator Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Microsoft Security Blog
Microsoft Security Blog
aimingoo的专栏
aimingoo的专栏
I
InfoQ
C
Check Point Blog
IT之家
IT之家
MyScale Blog
MyScale Blog
Apple Machine Learning Research
Apple Machine Learning Research
Vercel News
Vercel News
Last Week in AI
Last Week in AI
GbyAI
GbyAI
P
Proofpoint News Feed
量子位
Stack Overflow Blog
Stack Overflow Blog
Microsoft Azure Blog
Microsoft Azure Blog
月光博客
月光博客
阮一峰的网络日志
阮一峰的网络日志
人人都是产品经理
人人都是产品经理
B
Blog
T
The Blog of Author Tim Ferriss
H
Help Net Security
云风的 BLOG
云风的 BLOG

小松鼠的博客

记录一次线上k8s工作节点无法创建容器的问题排查思路与解决办法 记一次线上GoLang项目OOM排查过程 从LastPass转向拥抱开源KeePass的心路历程 故障定位与 AI 结合前后端编码实践 FileBeat收集nginx-ingress-controller日志 K8s云原生环境下文件描述符占用过高查询思路 2024年最新关闭火绒安全工具的开机自启方法 Kubernetes任务调度实践-Go语言实现Job和CronJob对比分析 离线更新k8s环境下的trivy漏洞库方法 使用Go语言接入Choerodon实现基于OAuth2的统一身份认证登录 在Vue2中自定义Switch组件并实现父子组件双向数据绑定 关于docker jdk1.8镜像中的GB18030-2022标准支持及验证 Go框架gin中的session存储gin-contrib-sessions和go-session 关于修改node_module中的源码问题记录 docker-compose网络和内网服务IP冲突问题 慎用存储过程:一条语句引发的数据库存储100%占用 Spring Boot中4种文件下载方法的实现 避坑-不能将specific类型的gitlab-runner改变为share类型 Docker compose中的MySQL主从复制模式和percona-toolkit工具使用 在minio中开启https访问以及使用rclone备份minio桶 在多机Docker环境下部署Choerodon的解决方案 Prometheus中Monitor添加对SpringBoot Actuator的Basic认证 在Nginx的容器镜像中隐藏Nginx的Server响应头 K8s中的两种nginx-ingress-controller及其区别 两个docker工具:runlike和whaler Grafana中的邮件报警和截图插件grafana-image-enderer maven配置文件settings.xml中的一些概念总结 K8s中flexvolume插件驱动的安装 K8s中的coredns无法解析svc问题排查 K8s中使用Ingress访问请求体过大问题解决
K8s中externalName-service和services-without-selectors
ycyin · 2022-09-01 · via 小松鼠的博客

我们都知道在k8s中,NameSpace是资源隔离的,那如何在命名空间A中调用B中的服务呢?直接使用服务名.命名空间名.svc.cluster.local就可以实现,那么还有其它办法吗?

先说答案:第一种方式:在NameSpace A中创建无Selecter选择运算符的Service,然后手动创建EndPoints指向NameSpace B中的Service IP。或者第二种方式使用ExternalName 类型的Service

其实原理很简单,和我们创建平时创建普通Service一样:创建Service时一般会使用selecter选择Pod,会创建一个与Serivce同名EndPoints去调用Pod,使用kubectl get endpoints -n ns xxx -o yaml可以看到在EndPoints中指定了Pod Ip和端口。

我们这里就是将自动创建EndPoints的过程变为手动,EndPoints指向Pod Ip变为指向Service IP。

遇到一个实际需求案例:

Ingress 创建了域名web.app.x指向NameSpace A中的Service A,同时NameSpace B中有Service B,现在的需求是我要相同域名不同前缀访问两个ServiceA和B,即web.app.x/app访问Service A,web.app.x/web访问Service B。如下图

                                   |-----NameSpace A------|
       ---------web.app.x/app→→→   |     Service A        | 
       ↑                           |----------------------|
Ingress             
       ↓                           |-----NameSpace B------|
       ---------web.app.x/web→→→   |     Service B        |
                                   |----------------------|

如果ServiceA和ServiceB同时在一个NameSpace中这很容易实现,只需要创建一个Ingress分别指定前缀url指向两个Service就OK。

这种情况,很容易想到的就是分别在两个NameSpace中创建一个Ingress,域名都写web.app.x同时分别指定前缀url,其实这是不行的,实际操作下来发现第二个是不生效的,访问404。

ExternalName 类型的Service

网络上搜了一番,都是在说使用ExternalName 类型的Service,官方文档说明如下:

image-20220902145952351
image-20220902145952351

在官方文档的说明和警告中可以发现可能有一些限制,在实际使用中我也发现了。

在之前的实际需求案例中,需要在NameSpace A中创建一个ExternalName 类型的Service指向NameSpace A,当我像网上一样创建如下Service是访问不到的。

kind: Service
apiVersion: v1
metadata:
  name: test-service-1
  namespace: namespace-a
spec:
  type: ExternalName
  externalName: test-service-2.namespace-b.svc.cluster.local # 需要改为test-service-2的IP
  ports:
  - port: 8080

似乎是无法解析test-service-2.namespace-b.svc.cluster.local这个service的IP,指定test-service-2的ip就可以访问externalName: 10.43.6.139

2024-01-19补充: 实际上ExternalName 类型的Service的真正用处在于使用DNS CNAME机制把自己CNAME到集群外部的域名,而在集群中就可以直接使用这个ExternalName 类型的Service名字来请求而不是用集群外部的域名,无须知道集群外部的域名是怎样的。但是前提是在集群内部也得对这个集群外部的域名能正常访问(比较常见的就是DNS无法解析,需要在域名解析器如CoreDNS里配置这个外部域名的host),比如:

apiVersion: v1
kind: Namespace
metadata:
  name: dev
---
apiVersion: v1
kind: Service
metadata:
  name: search
  namespace: dev
spec:
  type: ExternalName
  externalName: www.baidu.com

创建这个yaml,就可以在集群内部的pod中就可以通过search.dev.svc.cluster.local 访问www.baidu.com了,前提是在集群内本身能访问www.baidu.com(DNS能解析+网络可达),可以通过curl或者dig命令验证。参考:Kubernetes----ExternalName类型的Service-CSDN博客

没有选择算符的 Service

在官方文档中没有选择算符的 Service说明很详细。注意区别于无头服务(headless-services Service) | Kubernetes。官网截图如下:

image-20220902153307127
image-20220902153307127

创建没有选择算符的Service,由于此服务没有选择算符,因此不会自动创建相应的 Endpoints 对象。 需要通过手动添加 Endpoints 对象,将服务手动映射到运行该服务的网络地址和端口。

apiVersion: v1
kind: Service
metadata:
  name: test-service-1
  namespace: namespace-a
spec:
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
	  
---
apiVersion: v1
kind: Endpoints
metadata:
  name: test-service-1   # 这里的 name 要与 Service 的名字相同
  namespace: namespace-a
subsets:
  - addresses:
      - ip: 10.43.6.139
    ports:
      - port: 8080

最后,根据实际需求,只需要在namespace-a中创建Ingress即可。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test
  namespace: namespace-a
spec:
  rules:
  - host: web.app.x
    http:
      paths:
      - backend:
          serviceName: tt2 # namespace-a中的一般Service
          servicePort: 8080
        path: /app
      - backend:
          serviceName: test-service-1 # namespace-a中without-selectors的Service或者ExternalName类型的Service:指向namespace-b的Service
          servicePort: 8080
        path: /web

参考

ExternalName 类型 服务(Service) | Kubernetes

没有选择算符的 Service 服务(Service) | Kubernetes

Kubernetes Tips - Part 1 (akomljen.com)

ingress跨namespace访问service服务_ouyanglk的博客-CSDN博客_ingress 跨命名空间

Kubernetes 外部服务入口规则(ExternalName 类型) | (1r1g.com)

k8s - Service ExternalName_牛牛Blog的博客-CSDN博客_externalname