Kubernetes Service 是一个抽象层,用于定义一组 Pod 的访问方式。它为应用程序提供了一个稳定的网络终结点,使得其他服务或外部用户能够访问这组 Pod,而无需关心 Pod 的具体 IP 地址或具体的运行位置。
Service 类型: Kubernetes Service 有不同的类型,用于满足不同的需求。
<NodeIP>:<NodePort>
访问服务。Selector 与 Endpoint: 使用标签选择器将 Pod 添加到服务。当 Pod 匹配 Service 的标签选择器时,它们会被添加到服务的 Endpoint 中,用于流量的转发。Service Discovery: Kubernetes Service 提供了一种简单的服务发现机制,允许一个 Pod 通过服务名访问另一个 Pod,而不必知道其具体 IP 地址。Headless Service: 创建一个 Headless Service,它不提供 ClusterIP,但可以通过 DNS 解析返回所有与服务相关的 Pod 的 IP 地址。Annotations 和 Labels: 可以使用 Annotations 和 Labels 为 Service 添加元数据,提供更多信息或配置额外的行为。
创建一个Deployment ,方便后面测试
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
labels:
app: deployment-nginx
spec:
replicas: 3
selector:
matchLabels:
app: deployment-nginx
template:
metadata:
labels:
app: deployment-nginx
spec:
containers:
- name: deployment-nginx
image: nginx:1.14.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
定义一个基本Service
apiVersion: v1
kind: Service
metadata:
name: clusterip-service
spec:
selector:
app: deployment-nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
kubectl get svc,pod
默认Service type是cluster IP,我们可以通过clusterIP在集群内部访问 为了能够证明 service 负载的能力,我们需要修改pod的内容
kubectl exec -it deployment-nginx-584f786477-d8vm4 -- /bin/bash
echo 'pod/deployment-nginx-584f786477-d8vm4' > /usr/share/nginx/html/index.html
exit
kubectl exec -it deployment-nginx-584f786477-fsmnq -- /bin/bash
echo 'pod/deployment-nginx-584f786477-fsmnq' > /usr/share/nginx/html/index.html
exit
kubectl exec -it deployment-nginx-584f786477-srmf8 -- /bin/bash
echo 'pod/deployment-nginx-584f786477-srmf8' > /usr/share/nginx/html/index.html
exit
curl 10.86.236.109
从结果可以看到通过访问serviced的clusterIP,被负载到各个Pod中
其它Pod可以通过 http://clusterip-service直接访问 创建一个pod,用来测试
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- name: busybox
image: busybox:1.34
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
restartPolicy: Always
EOF
# 进入容器
kubectl exec -it busybox -- /bin/sh
wget http://clusterip-service -O -
Service默认是ClusterIP 类型,接下来我们学习另外几种
<NodeIP>:<NodePort>
访问服务。nodePort: 30000-32767,不填则随机生成apiVersion: v1
kind: Service
metadata:
name: nodeport-service
spec:
selector:
app: deployment-nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
#(默认:30000-32767)
nodePort: 30007
type: NodePort
直接访问
curl 127.0.0.1:30007
apiVersion: v1
kind: Service
metadata:
name: service-external
spec:
type: ExternalName
externalName: www.jianshu.com
进入到busybox容器,可以通过serviceName直接访问 jianshu,但是会被拒绝,因为服务端有安全校验,但是不影响我们验证这种方式
上面的service 有selector选择符,默认会创建对应的EndpointSlice,可以通过如下命令查看
kubectl get svc,ep
EndpointSlice 名称默认和Service名称相同,并且暴露的Endpoints 和 Pod个数对应
如果你不配置Selector选择,Endpoints将不会创建
apiVersion: v1
kind: Service
metadata:
name: service-without-selector
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
创建一个同名的EP
apiVersion: v1
kind: Endpoints
metadata:
name: service-without-selector
subsets:
- addresses:
- ip: 10.188.169.155
- ip: 10.188.36.123
ports:
- port: 80
访问service 因为我只配置了两个IP,所以只会访问到对应两个Pod
—END—