Kubernetes服务:连接内外部服务与对外暴露服务
立即解锁
发布时间: 2025-08-21 00:51:31 阅读量: 3 订阅数: 11 


Kubernetes实战:从入门到精通
### Kubernetes 服务连接与暴露指南
#### 1. 集群内访问服务
在 Kubernetes 集群中,你可以通过服务名作为请求 URL 中的主机名来访问服务。由于每个 Pod 容器内的 DNS 解析器配置,你可以省略命名空间和 `svc.cluster.local` 后缀。例如:
```bash
root@kubia-3inly:/# curl http://kubia
You’ve hit kubia-8awf3
```
查看容器内的 `/etc/resolv.conf` 文件,你会发现如下配置:
```bash
root@kubia-3inly:/# cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local ...
```
另外,当你尝试调试无法访问的服务时,可能会尝试使用 `ping` 命令来检查服务 IP 是否可达。但需要注意的是,服务的集群 IP 是虚拟 IP,只有与服务端口结合才有意义。例如:
```bash
root@kubia-3inly:/# ping kubia
PING kubia.default.svc.cluster.local (10.111.249.153): 56 data bytes
^C--- kubia.default.svc.cluster.local ping statistics ---
54 packets transmitted, 0 packets received, 100% packet loss
```
这里 `curl` 可以访问服务,但 `ping` 却失败了。
#### 2. 连接集群外的服务
到目前为止,我们讨论的是由集群内一个或多个 Pod 支持的服务。但有时你可能希望通过 Kubernetes 服务功能暴露外部服务,让服务将连接重定向到外部 IP 和端口,这样可以利用服务的负载均衡和服务发现功能,集群内的客户端 Pod 可以像连接内部服务一样连接外部服务。
##### 2.1 服务端点介绍
服务并不直接连接到 Pod,而是通过 `Endpoints` 资源进行关联。使用 `kubectl describe` 命令查看服务时,你可以看到端点信息。例如:
```bash
$ kubectl describe svc kubia
Name: kubia
Namespace: default
Labels: <none>
Selector: app=kubia
Type: ClusterIP
IP: 10.111.249.153
Port: <unset> 80/TCP
Endpoints: 10.108.1.4:8080,10.108.2.5:8080,10.108.2.6:8080
Session Affinity: None
No events.
```
`Endpoints` 资源是一个暴露服务的 IP 地址和端口列表,你可以使用 `kubectl get` 命令查看其基本信息:
```bash
$ kubectl get endpoints kubia
NAME ENDPOINTS AGE
kubia 10.108.1.4:8080,10.108.2.5:8080,10.108.2.6:8080 1h
```
虽然服务规范中定义了 Pod 选择器,但在重定向传入连接时并不直接使用,而是用于构建 IP 和端口列表并存储在 `Endpoints` 资源中。当客户端连接到服务时,服务代理会选择其中一个 IP 和端口对,并将传入连接重定向到该位置的服务器。
##### 2.2 手动配置服务端点
服务的端点与服务解耦,这使得它们可以手动配置和更新。如果你创建一个没有 Pod 选择器的服务,Kubernetes 不会自动创建 `Endpoints` 资源,需要你手动创建。
- **创建无选择器的服务**
以下是创建服务的 YAML 文件示例:
```yaml
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
ports:
- port: 80
```
这里定义了一个名为 `external-service` 的服务,它将接受端口 80 上的传入连接,并且没有定义 Pod 选择器。
- **为无选择器的服务创建 Endpoints 资源**
以下是创建 `Endpoints` 资源的 YAML 文件示例:
```yaml
apiVersion: v1
kind: Endpoints
metadata:
name: external-service
subsets:
- addresses:
- ip: 11.11.11.11
- ip: 22.22.22.22
ports:
- port: 80
```
`Endpoints` 对象的名称必须与服务名称匹配,并包含服务的目标 IP 地址和端口列表。将 `Service` 和 `Endpoints` 资源提交到服务器后,该服务就可以像有 Pod 选择器的常规服务一样使用。
如果后续你决定将外部服务迁移到 Kubernetes 集群内的 Pod 中,可以为服务添加选择器,使其 `Endpoints` 自动管理;反之,移除服务的选择器,Kubernetes 将停止更新其 `Endpoints`。这意味着服务 IP 地址可以保持不变,而服务的实际实现可以更改。
##### 2.3 为外部服务创建别名
除了手动配置服务端点来暴露外部服务,还可以通过创建 `ExternalName` 类型的服务为外部服务创建别名。例如:
```yaml
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
type: ExternalName
externalName: someapi.somecompany.com
ports:
- port: 80
```
服务创建后,Pod 可以通过 `external-service.default.svc.cluster.local` 域名(甚至 `external-service`)连接到外部服务,而不是使用服务的实际 FQDN。`ExternalName` 服务仅在 DNS 级别实现,会为服务创建一个简单的 CNAME DNS 记录,客户端连接到该服务时将直接连接到外部服务,完全绕过服务代理,因此此类服务甚至没有集群 IP。
#### 3. 向外部客户端暴露服务
前面我们讨论了集群内 Pod 如何使用服务,现在我们将探讨如何将某些服务(如前端 Web 服务器)暴露给外部客户端。有以下几种方法可以使服务对外可访问:
- 将服务类型设置为 `NodePort`:每个集群节点会在自身打开一个端口,并将该端口收到的流量重定向到基础服务。
- 将服务类型设置为 `LoadBalancer`:这是 `NodePort` 类型的扩展,会从 Kubernetes 运行的云基础设施中自动配置一个专用负载均衡器,客户端通过负载均衡器的 IP 访问服务。
- 创建 `Ingress` 资源:这是一种通过单个 IP 地址暴露多个服务的不同机制,它在 HTTP 级别(网络层 7)运行,因此可以
0
0
复制全文
相关推荐










