创建服务
在 Kubernetes 中,Service 是一种用于暴露运行在集群中一个或多个 Pod 上的网络应用的方法。
目录
为什么需要 Service
-
Pod 有自己的 IP,但:
-
Service 通过提供以下功能解决了这个问题:
-
稳定的 IP 和 DNS 名称。
-
自动负载均衡到匹配的 Pods。
ClusterIP 类型 Service 示例:
# simple-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 80
- 可用的 type 值及其行为包括
ClusterIP、NodePort、LoadBalancer、ExternalName
- Service 目标的 Pod 集合通常由你定义的 selector 决定。
Service 端口。
- 将 Service 的
targetPort 绑定到 Pod 的 containerPort。此外,也可以引用 Pod 容器下的 port.name。
Headless Service(无头服务)
有时你不需要负载均衡和单一的 Service IP,这种情况下可以创建所谓的无头服务:
无头服务适用于:
-
你想要发现单个 Pod 的 IP,而不仅仅是单一的服务 IP。
-
你需要直接连接到每个 Pod(例如,像 Cassandra 或 StatefulSet 这类数据库)。
-
你使用 StatefulSet,且每个 Pod 必须有稳定的 DNS 名称。
通过 Web 控制台创建服务
-
进入 Container Platform。
-
在左侧导航栏点击 Network > Services。
-
点击 Create Service。
-
参考以下说明配置相关参数。
-
点击 Create。
通过 CLI 创建服务
kubectl apply -f simple-service.yaml
基于已有的部署资源 my-app 创建服务。
kubectl expose deployment my-app \
--port=80 \
--target-port=8080 \
--name=test-service \
--type=NodePort \
-n p1-1
示例:集群内访问应用
# access-internal-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-clusterip
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80
targetPort: 80
-
应用该 YAML:
kubectl apply -f access-internal-demo.yaml
-
启动另一个 Pod:
kubectl run test-pod --rm -it --image=busybox -- /bin/sh
-
在 test-pod Pod 中访问 nginx-clusterip 服务:
wget -qO- http://nginx-clusterip
# 或使用 Kubernetes 自动创建的 DNS 记录:<service-name>.<namespace>.svc.cluster.local
wget -qO- http://nginx-clusterip.default.svc.cluster.local
你应该能看到包含 “Welcome to nginx!” 字样的 HTML 响应。
示例:集群外访问应用
# access-external-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
-
应用该 YAML:
kubectl apply -f access-external-demo.yaml
-
查看 Pods:
kubectl get pods -l app=nginx -o wide
-
curl 访问 Service:
curl http://{NodeIP}:{nodePort}
你应该能看到包含 “Welcome to nginx!” 字样的 HTML 响应。
当然,也可以通过创建 LoadBalancer 类型的 Service 从集群外访问应用。
注意:请提前配置 LoadBalancer 服务。
# access-external-demo-with-loadbalancer.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-lb-service
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- port: 80
targetPort: 80
-
应用该 YAML:
kubectl apply -f access-external-demo-with-loadbalancer.yaml
-
获取外部 IP 地址:
kubectl get svc nginx-lb-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service LoadBalancer 10.0.2.57 34.122.45.100 80:30005/TCP 30s
EXTERNAL-IP 即为你从浏览器访问的地址。
curl http://34.122.45.100
你应该能看到包含 “Welcome to nginx!” 字样的 HTML 响应。
如果 EXTERNAL-IP 显示为 pending,说明 LoadBalancer 服务尚未在集群中部署。
示例:ExternalName 类型 Service
apiVersion: v1
kind: Service
metadata:
name: my-external-service
namespace: default
spec:
type: ExternalName
externalName: example.com
-
应用该 YAML:
kubectl apply -f external-service.yaml
-
在集群内的 Pod 中尝试解析:
kubectl run test-pod --rm -it --image=busybox -- sh
然后执行:
nslookup my-external-service.default.svc.cluster.local
你会看到它解析为 example.com。
LoadBalancer 类型 Service 注解
AWS EKS 集群
有关 EKS LoadBalancer Service 注解的详细说明,请参阅 Annotation Usage Documentation 。
华为云 CCE 集群
有关 CCE LoadBalancer Service 注解的详细说明,请参阅 Annotation Usage Documentation 。
Azure AKS 集群
有关 AKS LoadBalancer Service 注解的详细说明,请参阅 Annotation Usage Documentation 。
Google GKE 集群
有关 GKE LoadBalancer Service 注解的详细说明,请参阅 Annotation Usage Documentation 。