参考文献: Kubernetes修炼⼿册/(英)奈吉尔·波尔顿(Nigel Poulton)著;刘康,李瑞丰译.--北京:⼈⺠邮电出版社,2021.5

概述

本文实际上讲述的是服务发现是如何在namespace之间和之内work的。

总的来说,每一个集群中都有一个基于DNS domain地址空间,称为cluster domain,默认名称是cluster.local,Service对象都在这个地址空间中。

对象的全限定域名格式为<object-name>.<namespace>.svc.cluster.local,namespace可以对cluster domain下的地址空间进行分区,同一namespace的Pods可以直接使用本namespace下对象的短名称<object-name>来进行访问,但是如果想要对其他namespace下的对象进行访问,则必须使用全限定域名。

实战

使用以下yaml文件部署两个命名空间,两个Deployment、两个Service和⼀个单独的Pod。这两个Deployment有同样的名字,Service也是。

apiVersion: v1
kind: Namespace
metadata:
  name: dev
---
apiVersion: v1
kind: Namespace
metadata:
  name: prod
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: enterprise
  namespace: dev
  labels:
    app: enterprise
spec:
  selector:
    matchLabels:
      app: enterprise
  replicas: 2
  template:
    metadata:
      labels:
        app: enterprise
    spec:
      terminationGracePeriodSeconds: 1
      containers:
      - image: nigelpoulton/k8sbook:text-dev
        name: enterprise-ctr
        ports:
        - containerPort: 8080
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: enterprise
  namespace: prod
  labels:
    app: enterprise
spec:
  selector:
    matchLabels:
      app: enterprise
  replicas: 2
  template:
    metadata:
      labels:
        app: enterprise
    spec:
      terminationGracePeriodSeconds: 1
      containers:
      - image: nigelpoulton/k8sbook:text-prod
        name: enterprise-ctr
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: ent
  namespace: dev
spec:
  ports:
  - port: 8080
  selector:
    app: enterprise
---
apiVersion: v1
kind: Service
metadata:
  name: ent
  namespace: prod
spec:
  ports:
  - port: 8080
  selector:
    app: enterprise
---
apiVersion: v1
kind: Pod
metadata:
  name: jump
  namespace: dev
spec:
  terminationGracePeriodSeconds: 5
  containers:
  - image: ubuntu
    name: jump
    tty: true
    stdin: true

Deployment管理的容器中含有两个程序,若是访问dev命名空间下的Pods,则会返回“Hello from the DEV Namespace!”以及该Pod的hostname,prod命名空间下的Pods同理。

进入到dev命名空间下的jump Pod,执行命令cat /etc/resolv.conf,可以看到搜索域中只包含dev命名空间:

root@jump:/# cat /etc/resolv.conf
search dev.svc.cluster.local svc.cluster.local cluster.local
nameserver 192.168.0.10
options ndots:5

安装curl命令之后,使用ent的短名称访问Service

root@jump:/# curl ent:8080
Hello from the DEV Namespace!
Hostname: enterprise-cfdbf9b59-wnc8b

结果表明获得了dev命名空间下名为enterprise-cfdbf9b59-wnc8b的Pod的响应。

当curl命令执⾏的时候,容器会⾃动在ent后追加dev.svc.cluster.local,然后向/etc/resolv.conf中指定的集群DNS的IP地址发送解析请求。DNS会返回dev命名空间中ent Service的ClusterIP,从⽽使请求被发送⾄该地址。然后它会被路由到节点的默认⽹关,并被节点的内核捕获,然后转发到其中的⼀个Pod上。

使用全限定域名访问prod中的应用

root@jump:/# curl ent.prod.svc.cluster.local:8080
Hello from the PROD Namespace!
Hostname: enterprise-6f596b64fc-kf7wx

结果表明获得了prod命名空间下名为enterprise-6f596b64fc-kf7wx的pod的响应,成功实现了跨namespace访问。