kubernetes 服务跨命名空间访问

大家都知道namespace是作为资源隔离,用于分组,可以把我不同组件,不同服务放在不同namespace下,便于管理。那么我现在有需求,希望服务之间可以互相访问,也就是跨namespace的服务访问,应该怎么处理呢?

svc 的 4种类型
ClusterIP 默认,分配一个VIP,只能内部访问
NodePort ClusterIP基础上,在每个节点绑定一个对外访问端口
LoadBalancer 在NodePort基础上,外部负载均衡器转发到NodePort
ExternalName 集群外部的服务引入到集群内部来,集群内部使用

实现上述功能,就需要使用大svc的ExternalName 这种类型。

情况:v2 namespace需要访问default namespace的rabbitmq服务

解决办法:在v2 namespace里面创建service,不指定selector, 采用type=ExternalName的方式,externalName定义成为指向namespace=default中的rabbitmq-service

# vi rabbitmq.yaml

  1. apiVersion: v1

  2. kind: Service

  3. metadata:

  4. name: rabbitmq

  5. namespace: v2

  6. spec:

  7. ports:

  8. - port: 5672

  9. name: amqp

  10. sessionAffinity: None

  11. type: ExternalName

  12. externalName: rabbitmq.default.svc.cluster.local

  13.  

[root@bdy-master1]# kubectl create -f rabbitmq.yaml

[root@bdy-master1]# kubectl get service -A |grep rabbit

default rabbitmq ClusterIP None <none> 5672/TCP 108d

default rabbitmq-service NodePort 10.254.252.174 <none> 15672:32001/TCP,5672:32002/TCP 115d

v2 rabbitmq ExternalName <none> rabbitmq.default.svc.cluster.local 5672/TCP 25h

测试是否可以跨namespace访问

[root@bdy-master1 rabbitmq-service]# kubectl exec -it -n v2 api-57596df5b8-sx2hc sh

 

/var/www/html # nslookup rabbitmq

nslookup: can't resolve '(null)': Name does not resolve

Name: rabbitmq

Address 1: 172.30.28.24 172-30-28-24.rabbitmq.default.svc.cluster.local

Address 2: 172.30.3.4 rabbitmq-1.rabbitmq.default.svc.cluster.local

Address 3: 172.30.43.8 172-30-43-8.rabbitmq.default.svc.cluster.local

Address 4: 172.30.43.2 rabbitmq-2.rabbitmq.default.svc.cluster.local

Address 5: 172.30.3.30 172-30-3-30.rabbitmq.default.svc.cluster.local

Address 6: 172.30.28.2 rabbitmq-0.rabbitmq.default.svc.cluster.local

/var/www/html # ping rabbitmq

PING rabbitmq (172.30.43.2): 56 data bytes

64 bytes from 172.30.43.2: seq=0 ttl=62 time=0.720 ms

64 bytes from 172.30.43.2: seq=1 ttl=62 time=0.650 ms

^C

--- rabbitmq ping statistics ---

2 packets transmitted, 2 packets received, 0% packet loss

round-trip min/avg/max = 0.650/0.685/0.720 ms

/var/www/html # nc -n -v rabbitmq 5672

rabbitmq (172.30.43.2:5672) open

情况v2

具体操作方法如下

1.在default 下创建服务 ,以echoservice 为例

$ kubectl apply -f https://bit.ly/echo-service

service/echo created

deployment.apps/echo created

可以通过kubectl 查看服务

$ kubectl get svc echo

NAME   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE

echo   ClusterIP   10.102.214.18   <none>        8080/TCP,80/TCP   69m

2.新建一个namespace test

 

$ kubectl create namespace test

3.在test下创建svc ,关联到default下svc

apiVersion: v1

kind: Service

metadata:

  name: echo-default

  namespace: test

spec:

  type: ExternalName

  externalName: echo.default.svc.cluster.local

 

$ kubectl get svc -n test

NAME           TYPE           CLUSTER-IP   EXTERNAL-IP                      PORT(S)   AGE

echo-default   ExternalName   <none>       echo.default.svc.cluster.local   <none>    29m

 

4.在 test 下创建ingres ,指向test下svc,这样就可以访问default下的echo服务了

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: demo

  namespace: test

spec:

  rules:

  - http:

      paths:

      - path: /bar

        backend:

          serviceName: echo-default

          servicePort: 80

 

$ kubectl get ingress -n test

NAME   HOSTS   ADDRESS           PORTS   AGE

demo   *       192.168.159.129   80      31m

 

$   curl -i 192.168.159.129:32359/bar

HTTP/1.1 200 OK

Content-Type: text/plain; charset=UTF-8

Transfer-Encoding: chunked

Connection: keep-alive

Date: Sat, 09 May 2020 09:08:48 GMT

Server: echoserver

X-Kong-Upstream-Latency: 1

X-Kong-Proxy-Latency: 1

Via: kong/2.0.3

 

 

 

Hostname: echo-c4cb89895-pnf85

 

Pod Information:

        node name:      192.168.159.129

        pod name:       echo-c4cb89895-pnf85

        pod namespace:  default

        pod IP: 10.32.0.7

 

Server values:

        server_version=nginx: 1.13.3 - lua: 10008

 

Request Information:

        client_address=::ffff:10.32.0.6

        method=GET

        real path=/

        query=

        request_version=1.1

        request_scheme=http

这样就可以通过svc 的ExternalName实现跨namespace的访问了

 

还有另外一种方式

 

如果你要连接namespace是redis的,服务名是redis-master的服务,你可以这样去配置你的连接:

spring:  
  profiles: redis-prod  
  redis:    
    host: redis-master.redis 
    port: 6379
    password: 123456
    database: 1

它采用了服务名+命名空间的格式,如果是相同的namespace,可以直接使用服务名来解析。