请启用 Javascript 以查看内容

实现Kubernetes跨Namespace Service访问的最佳实践

 ·  ☕ 4 分钟  ·  ✍ CNSRE · 👀... 阅读

作者:SRE运维博客
博客地址:https://www.cnsre.cn/
文章地址:https://www.cnsre.cn/posts/240906085714/
相关话题:https://www.cnsre.cn/tags/kubernetes/


实现Kubernetes跨Namespace Service访问的最佳实践

在Kubernetes运维场景中,经常会遇到跨Namespace(名称空间)的Service访问需求。为了实现不同Namespace下的Pod能够通过Service名称进行跨Namespace访问,我们可以利用Kubernetes的ExternalName类型Service来解决这个问题。

在本文中,我将展示如何配置和实现这种跨Namespace的通信。我们将通过一个完整的示例来详细说明配置过程和关键步骤。

1. 场景需求

假设我们有两个不同Namespace下的两个Service和Pod:

  • Namespace A:ServiceA (PodA)
  • Namespace B:ServiceB (PodB)

我们希望实现PodA通过ServiceB的名称进行通信,而不是通过Service的IP地址。由于Service的IP地址可能会在重启时发生变化,而Service的名称则保持不变,这样可以确保通信的稳定性。

2. 创建Service和Pod

首先,我们需要为两个Namespace分别创建对应的Pod和Service。

myns Namespace中创建Pod和Service

 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
apiVersion: v1
kind: Namespace
metadata:
  name: myns
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy1
  namespace: myns
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      release: v1
  template:
    metadata:
      labels:
        app: myapp
        release: v1
    spec:
      containers:
      - name: myapp
        image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
        ports:
        - name: http
          containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: myapp-clusterip1
  namespace: myns
spec:
  type: ClusterIP
  selector:
    app: myapp
    release: v1
  ports:
  - name: http
    port: 80
    targetPort: 80

mytest Namespace中创建Pod和Service

 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
apiVersion: v1
kind: Namespace
metadata:
  name: mytest
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy2
  namespace: mytest
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      release: v2
  template:
    metadata:
      labels:
        app: myapp
        release: v2
    spec:
      containers:
      - name: myapp
        image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v2
        ports:
        - name: http
          containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: myapp-clusterip2
  namespace: mytest
spec:
  type: ClusterIP
  selector:
    app: myapp
    release: v2
  ports:
  - name: http
    port: 80
    targetPort: 80

3. 检查创建结果

运行以下命令来应用这些YAML文件并检查Service和Pod的状态:

1
2
3
4
5
6
kubectl apply -f deply_service_myns.yaml
kubectl apply -f deply_service_mytest.yaml

kubectl get svc -n myns -o wide
kubectl get svc -n mytest -o wide
kubectl get pod -A -o wide

4. 跨Namespace Service通信问题

在默认情况下,PodA无法通过Service名称直接访问Namespace B中的Service。下面是PodA尝试访问PodB的日志输出:

1
2
3
# kubectl exec -it -n myns myapp-deploy1-36ds6g873r8-asy2us sh
/ # ping myapp-clusterip2
ping: bad address 'myapp-clusterip2'

这是因为默认的Kubernetes DNS解析只支持在同一Namespace内解析Service名称。

5. 解决方案:使用ExternalName类型的Service

为了解决这个问题,我们可以在每个Namespace中创建一个ExternalName类型的Service。ExternalName允许通过指定的FQDN(完全限定域名)来指向其他Namespace中的Service。

以下是实现跨Namespace通信的Service配置:

myns Namespace中创建ExternalName Service

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: v1
kind: Service
metadata:
  name: myapp-clusterip1-externalname
  namespace: myns
spec:
  type: ExternalName
  externalName: myapp-clusterip2.mytest.svc.cluster.local
  ports:
  - name: http
    port: 80
    targetPort: 80

mytest Namespace中创建ExternalName Service

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: v1
kind: Service
metadata:
  name: myapp-clusterip2-externalname
  namespace: mytest
spec:
  type: ExternalName
  externalName: myapp-clusterip1.myns.svc.cluster.local
  ports:
  - name: http
    port: 80
    targetPort: 80

运行以下命令来应用这些新的Service配置:

1
kubectl apply -f svc_ExternalName_visit.yaml

6. 验证跨Namespace通信

现在我们可以再次尝试从PodA访问PodB,应该可以成功解析并进行通信:

1
2
kubectl exec -it -n myns myapp-deploy1-36ds6g873r8-asy2us sh
/ # ping myapp-clusterip2.mytest.svc.cluster.local

这样,PodA就可以通过Service名称访问不同Namespace中的PodB了。

7. 总结

通过使用Kubernetes的ExternalName类型Service,我们成功实现了跨Namespace的Service名称解析和通信。此方法避免了直接使用IP地址通信的局限性,确保了即使Service的IP地址发生变化,通信依然可以通过名称进行。

这种跨Namespace通信的场景在多租户、多环境隔离的Kubernetes集群中尤为常见。如果你的集群架构中需要不同Namespace之间的Service互访,ExternalName是一个有效的解决方案。


作者:SRE运维博客
博客地址:https://www.cnsre.cn/
文章地址:https://www.cnsre.cn/posts/240906085714/
相关话题:https://www.cnsre.cn/tags/kubernetes/


您的鼓励是我最大的动力
alipay QR Code
wechat QR Code

Avatar
作者
CNSRE
一位只会重启的运维






目录