1. 概述
网络是 Kubernetes 的核心组成部分,其中*服务*是其基础网络对象之一。Kubernetes 服务允许我们将网络应用暴露给外部世界。但访问它时,我们必须知道其 URL。
本篇实战教程将讨论如何查找并使用 Kubernetes 服务的 URL 作为可靠的网络接口。
2. 搭建示例环境
我们需要创建几个 Kubernetes 对象作为示例。首先创建*命名空间*对象。
2.1. 创建 Kubernetes 命名空间
Kubernetes 命名空间允许我们在同一集群内隔离资源。使用create命令创建两个命名空间——dev 和 stg:
$ kubectl create ns dev
namespace/dev created
$ kubectl create ns stg
namespace/stg created
2.2. 创建 Kubernetes 部署
上一步创建了两个命名空间。现在将 Redis Pod 部署到这些命名空间:
$ kubectl create deploy redis-dev --image=redis:alpine -n dev
deployment.apps/redis-dev created
$ kubectl create deploy redis-stg --image=redis:alpine -n stg
deployment.apps/redis-stg created
验证 Pod 是否创建成功并处于健康状态:
$ kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
redis-dev-7b647c797c-c2mmg 1/1 Running 0 16s
$ kubectl get pods -n stg
NAME READY STATUS RESTARTS AGE
redis-stg-d66978466-plfpv 1/1 Running 0 9s
两个 Pod 状态均为 Running。基础环境已就绪,接下来我们将创建几个服务对象与这些 Pod 建立通信。
3. 查找 ClusterIP 服务的 URL
在 Kubernetes 中,默认服务类型是ClusterIP。对于 ClusterIP 服务,我们可以使用服务名或其 IP 地址作为 URL。这能将通信限制在集群内部。通过简单示例理解这一点。
3.1. 创建 ClusterIP 服务
在两个命名空间中创建 ClusterIP服务对象:
$ kubectl expose deploy redis-dev --port 6379 --type ClusterIP -n dev
service/redis-dev exposed
$ kubectl expose deploy redis-stg --port 6379 --type ClusterIP -n stg
service/redis-stg exposed
这里使用expose命令创建服务。expose 命令会复用*部署*对象的标签选择器创建服务。
后续章节将讨论如何查找并使用这些服务名作为 URL。
3.2. 在同一命名空间使用 ClusterIP 服务 URL
使用get命令查找 dev 命名空间的服务名:
$ kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-dev ClusterIP 10.100.18.154 <none> 6379/TCP 9s
输出第一列显示服务名(本例为 redis-dev)。
现在exec进入 dev 命名空间的 Redis Pod,使用 redis-dev 作为主机名连接 Redis 服务器,执行PING命令:
$ kubectl exec -it redis-dev-7b647c797c-c2mmg -n dev -- sh
/data # redis-cli -h redis-dev PING
PONG
/data # exit
Redis 服务器返回 PONG 响应。执行exit命令退出 Pod。
3.3. 从其他命名空间使用 ClusterIP 服务 URL
ClusterIP 服务 URL 的格式:
<服务名>.<命名空间>.<集群名>:<服务端口>
前例未使用命名空间和集群名,因为命令在同一命名空间和集群执行。同时省略了服务端口,因为服务暴露的是 Redis 默认端口 6379。
但从其他命名空间访问 ClusterIP 服务时必须指定命名空间。通过示例理解:
先查找 stg 命名空间的服务名:
$ kubectl get svc -n stg
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-stg ClusterIP 10.110.213.51 <none> 6379/TCP 9s
现在exec进入 dev 命名空间的 Redis Pod,使用 redis-stg.stg 作为主机名连接 Redis 服务器,执行 PING 命令:
$ kubectl exec -it redis-dev-7b647c797c-c2mmg -n dev -- sh
/data # redis-cli -h redis-stg.stg PING
PONG
/data # exit
Redis 服务器返回 PONG 响应。
⚠️ 关键点:我们使用 redis-stg.stg 作为主机名,其中 redis-stg 是服务名,stg 是服务对象所在的命名空间。
3.4. 清理资源
前文展示了如何使用服务名作为 URL。现在用delete命令清理 dev 和 stg 命名空间的服务:
$ kubectl delete svc redis-dev -n dev
service "redis-dev" deleted
$ kubectl delete svc redis-stg -n stg
service "redis-stg" deleted
4. 查找 NodePort 服务的 URL
NodePort服务允许通过 Kubernetes 节点的 IP 和端口从外部访问应用。通过创建 NodePort 服务理解这一点。
4.1. 创建 NodePort 服务
使用 expose 命令创建 NodePort 类型的服务:
$ kubectl expose deploy redis-dev --port 6379 --type NodePort -n dev
service/redis-dev exposed
验证服务创建成功:
$ kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-dev NodePort 10.111.147.176 <none> 6379:30243/TCP 2s
服务类型为 NodePort。倒数第二列显示 Kubernetes 节点端口 30243 映射到 Pod 端口 6379。
现在可以从集群外部使用节点 IP 和端口 30243 访问 Redis 服务器。实际操作验证:
4.2. 使用 NodePort 服务 URL
先获取 Kubernetes 节点的 IP 地址:
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
baeldung Ready control-plane 24h v1.28.3 192.168.49.2 <none> Ubuntu 22.04.3 LTS 5.15.0-41-generic docker://24.0.7
使用 -o wide 选项显示节点额外字段。INTERNAL-IP 列显示 Kubernetes 节点的 IP 地址。
从外部机器连接 Redis 服务器,使用 192.168.49.2 作为主机名,30243 作为端口号,执行 PING 命令:
$ redis-cli -h 192.168.49.2 -p 30243 PING
PONG
Redis 服务器返回 PONG 响应。
4.3. 清理资源
下一节将介绍LoadBalancer服务。先清理 dev 命名空间的 NodePort 服务:
$ kubectl delete svc redis-dev -n dev
service "redis-dev" deleted
5. 查找 LoadBalancer 服务的 URL
与 NodePort 服务类似,LoadBalancer 服务也允许通过负载均衡器的 IP 从外部访问应用。通过创建 LoadBalancer 服务理解:
5.1. 创建 LoadBalancer 服务
在 dev 命名空间创建 LoadBalancer 服务:
$ kubectl expose deploy redis-dev --port 6379 --type LoadBalancer -n dev
service/redis-dev exposed
5.2. 使用 LoadBalancer 服务 URL
使用 get 命令查找负载均衡器的 IP 地址:
$ kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-dev LoadBalancer 10.111.167.249 192.168.49.10 6379:32637/TCP 7s
EXTERNAL-IP 列表示 LoadBalancer 服务的 IP 地址。本例中负载均衡器 IP 为 192.168.49.10。
从外部机器连接 Redis 服务器,使用 192.168.49.10 作为主机名,执行 PING 命令:
$ redis-cli -h 192.168.49.10 PING
PONG
Redis 服务器返回 PONG 响应。
6. 清理资源
删除不需要的对象是良好实践,能降低硬件消耗成本。使用 delete 命令移除 dev 和 stg 命名空间:
$ kubectl delete ns dev
namespace "dev" deleted
$ kubectl delete ns stg
namespace "stg" deleted
此命令会删除命名空间及其包含的所有对象。
⚠️ 注意:我们直接删除了命名空间(因为是测试环境),但在生产环境执行删除操作时务必谨慎!
7. 总结
本文讨论了如何在 Kubernetes 中查找并使用服务的 URL:
✅ ClusterIP 服务:
- 同命名空间内直接使用服务名
- 跨命名空间使用
<服务名>.<命名空间>
格式
✅ NodePort 服务:
- 使用
<节点IP>:<NodePort>
从外部访问
✅ LoadBalancer 服务:
- 使用负载均衡器的
EXTERNAL-IP
从外部访问
掌握这些方法能帮你快速定位服务访问地址,避免在 Kubernetes 网络配置中踩坑。