# 内部Pod发现Service

根据之前提到的**前端Pod**通过访问**后端Service**间接与**后端Pod**通信的架构，内部的Pod需要通过某种方式知道Service对象的存在。Kubernetes为其提供了发现Service的IP和端口的方式。

## 通过环境变量发现Service

在同命名空间中的所有的Pod中的系统环境变量中都会添加该命名空间下所有Service对象（除了HeadlessService）的IP地址和端口相关信息。

如有一个名为**kubia**的Service对象，在同命名空间下的任意一个Pod中查看环境变量可以看到：

```
KUBIA_PORT_80_TCP=tcp://10.96.113.237:80
KUBIA_PORT_80_TCP_PROTO=tcp
KUBIA_SERVICE_HOST=10.96.113.237
KUBIA_PORT_80_TCP_PORT=80
KUBIA_SERVICE_PORT=80
KUBIA_PORT=tcp://10.96.113.237:80
KUBIA_PORT_80_TCP_ADDR=10.96.113.237
```

> 最值得关注的就是`KUBIA_SERVICE_HOST`和`KUBIA_SERVICE_PORT`两个环境变量

## 通过DNS发现Service

DNS解析的前提是知道域名，在Kubernetes内部可以在知道服务名的前提下，通过**全限定域名（FQDN）**&#x6765;访问。

{% hint style="info" %}
**Tips:** 全限定域名（Fully Qualified Domain Name），同时带有主机名和域名的名称。
{% endhint %}

Kubernetes的**kube-system**命名空间下有一个Service名为**kube-dns**，所有Pod都会将DNS服务器设置为该Service，并由该Service将解析请求转发至其后端的名为**coredns**的Pod。例如，查看一个Pod的`/etc/resolv.conf`文件：

```
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
```

> `10.96.0.10`即为kube-dns这个Service的ClusterIP

{% hint style="info" %}
**Tips:**&#x20;

1. Pod是否使用内部的DNS服务器取决于Pod的`spec.dnsPolicy`，其默认为`ClusterFirst`；
2. Kubernetes中的所有Service对象的信息都会被集群内部DNS服务器记录，因此所有Pod都可以通过全限定域名访问指定Service对象；
   {% endhint %}

### 通过FQDN访问Service

直接举例子，假设在**default**命名空间下有一个名为**kubia**的Service对象，那么它的全限定域名则为`kubia.default.svc.cluster.local`，那么可以通过下面任何一种方式访问Service：

```bash
curl kubia.default.svc.cluster.local
curl kubia.default.svc
curl kubia.default
curl kubia
```

{% hint style="info" %}
**Tips:** 使用`kubia.default.svc.cluster.local`访问好理解，下面三种访问方式是由于上面提到的Pod中的`/etc/resolv.conf`中的**search default.svc.cluster.local svc.cluster.local cluster.local**。
{% endhint %}
