跳到主要内容

服务发现

2024年11月19日
柏拉文
越努力,越幸运

一、认识


Kubernetes 中,服务发现(Service Discovery) 是一种机制,帮助应用程序找到其他服务或 Pod,而无需硬编码 IP 或端口。Kubernetes 提供了两种服务发现方式:环境变量DNS。环境变量适用于简单场景,而 DNS 是生产环境的推荐方式,因其灵活性和动态性。结合 ServiceDNS 机制,Kubernetes 能够有效支持微服务架构中动态变化的服务依赖关系。

  • 环境变量: 在 Pod 启动时将 Service 信息注入为环境变量。

  • DNS: 通过 Kubernetes 内置的 DNS 服务(通常是 CoreDNS),允许服务通过域名解析访问。

二、DNS


2.1 认识

Kubernetes 提供了 DNS 服务(默认是 CoreDNS),为每个 Service 创建域名。Service 名称和命名空间会自动生成对应的 DNS 记录,支持跨命名空间和 FQDN 访问。

2.2 格式

  • 简单格式<service-name>.<namespace>.svc.cluster.local。示例:my-service.default.svc.cluster.local

  • 跨命名空间访问:示例:http://my-service.other-namespace.svc.cluster.local

  • 短域名:如果 ServicePod 在同一命名空间,可以省略部分路径,如 my-service.

2.3 发现

1. 创建 Service: 注意: 注意,环境变量仅在 Pod 启动时注入。因此,必须先创建 Service, 然后创建 Deployment.

apiVersion: v1
kind: Service
metadata:
name: test-service
spec:
selector:
app: test-nginx
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 80
kubectl apply -f test-service.yaml

2. 创建 Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
replicas: 3
selector:
matchLabels:
app: test-nginx
template:
metadata:
labels:
app: test-nginx
spec:
containers:
- name: test-nginx
image: registry.cn-hangzhou.aliyuncs.com/bolawen/nginx:1.27.1-perl-linux-arm64
ports:
- containerPort: 80
kubectl apply -f test-deployment.yaml

3. 进入容器访问服务

kubectl get pods // 1. 查看 Pod Name 

kubectl exec -it <POD_NAME> -- /bin/bash 或者 sh // 2. 进入 Pod 容器
curl http://test-service
# 或完整域名
curl http://test-service.default.svc.cluster.local

2.4 总结

优点:动态、灵活,适合生产环境。

缺点:依赖 DNS 服务,可能因网络问题导致解析失败。

三、环境变量


3.1 认识

每当一个 Pod 启动时,Kubernetes 会自动为集群中现有的 Service 注入环境变量 (必须先创建 Service 后创建 Deployment)。环境变量包含 ServiceClusterIP 和端口。

3.2 格式

3.3 发现

1. 创建 Service: 注意: 注意,环境变量仅在 Pod 启动时注入。因此,必须先创建 Service, 然后创建 Deployment.

apiVersion: v1
kind: Service
metadata:
name: test-service
spec:
selector:
app: test-nginx
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30000
kubectl apply -f test-service.yaml

2. 创建 Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
replicas: 3
selector:
matchLabels:
app: test-nginx
template:
metadata:
labels:
app: test-nginx
spec:
containers:
- name: test-nginx
image: registry.cn-hangzhou.aliyuncs.com/bolawen/nginx:1.27.1-perl-linux-arm64
ports:
- containerPort: 80
kubectl apply -f test-deployment.yaml

3. 查看环境变量

kubectl get pods // 查看 Pod Name 

kubectl exec -it <POD_NAME> -- /bin/bash 或者 sh // 进入 Pod
env | grep TEST_SERVICE 

// 或者

printenv | grep TEST_SERVICE

示例输出

TEST_SERVICE_SERVICE_HOST=10.96.0.2
TEST_SERVICE_SERVICE_PORT=8080
TEST_SERVICE_PORT=tcp://10.96.0.2:8080
TEST_SERVICE_PORT_8080_TCP_PORT=8080

3.4 总结

优点:简单、静态,适合早期 Kubernetes 集群或开发测试场景。

缺点:环境变量在 Pod 启动时注入,Service 的变更(如 IP 或端口变化)不会动态更新。