基本概念
Service 是个抽象的概念。Service 会创建一个虚拟的服务,来整合集群内的 Pod。Service 会虚拟出一个 VIP,并在被摧毁前一直存在。通过对它的访问,以代理的方式负载到对应的 Pod 上,同时 Pod 生命周期的变换,也会及时反应在代理上.
Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 通常称为微服务, 这一组 Pod 能够被 Service 访问到,通常是通过Label Selector实现.
Service的四种类型
ClusterIP: 使用集群内的私有ip, 默认值
NodePort: 通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 <NodeIP>:<NodePort>,可以从集群的外部访问一个 NodePort 服务. The range of valid ports is 30000-32767
LoadBalancer: 使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。
ExternalName: 通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容(例如, foo.bar.example.com)。 没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持
Service的工作模式
工作模式
userspace: 1.1-
iptables: 1.10-
ipvs: 1.11+
定义Service资源清单
通过selector提供集群内部服务
ClusterIP类型
[root@k8s-master01 learning]# vim Service-selector-ClusterIP.yamlapiVersion: v1kind: Servicemetadata:
name: depoly-demo namespace: learningspec:
type: ClusterIP #默认类型,可以不写
clusterIP: 10.99.254.30 #自定义Service的IP,默认自动选择,建议不手动指定
selector: #选择符合此标签的Pod进行转发
app: deploy-demo tag: learn-deploy ports:
- port: 80 #暴露的端口
targetPort: 80 #Pod的端口,默认和port保持一致
protocol: TCP #使用协议,默认TCP# 启动和查看资源[root@k8s-master01 learning]# kubectl apply -f Service-selector-ClusterIP.yamlservice/depoly-demo created
[root@k8s-master01 learning]# kubectl get svc -n learningNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
depoly-demo ClusterIP 10.99.254.29 <none> 80/TCP 39s
[root@k8s-master01 learning]# kubectl describe -n learning service depoly-demoName: depoly-demoNamespace: learningLabels: <none>Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"depoly-demo","namespace":"learning"},"spec":{"ports":[{"port":80,...Selector: app=deploy-demo,tag=learn-deployType: ClusterIPIP: 10.99.254.29Port: <unset> 80/TCPTargetPort: 80/TCPEndpoints: 10.244.0.21:80,10.244.1.28:80 #后端pod的地址Session Affinity: NoneEvents: <none># 进入Pod修改nginx的index页面为Pod的ip地址,查看负载是否生效[root@k8s-master01 learning]# kubectl get pods -n learning -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deploy-demo-9b4887666-p2jsr 1/1 Running 0 26m 10.244.0.22 k8s-master01 <none> <none>
deploy-demo-9b4887666-xchsg 1/1 Running 0 26m 10.244.1.29 k8s-node01 <none> <none>
[root@k8s-master01 learning]# kubectl -n learning exec -it deploy-demo-9b4887666-p2jsr -- /bin/sh# echo '10.244.0.22' > /usr/share/nginx/html/index.html[root@k8s-master01 learning]# kubectl -n learning exec -it deploy-demo-9b4887666-xchsg -- /bin/sh# echo '10.244.1.29' > /usr/share/nginx/html/index.html# 访问测试[root@k8s-master01 learning]# curl 10.99.254.2910.244.1.29[root@k8s-master01 learning]# curl 10.99.254.2910.244.0.22NodePort类型
# 把刚创建的ClusterIP类型的SVC删掉[root@k8s-master01 learning]# kubectl delete -f Service-selector-ClusterIP.yaml service "depoly-demo" deleted# 定义新的资源清单[root@k8s-master01 learning]# vim Service-selector-NodePort.yaml apiVersion: v1kind: Servicemetadata:
name: depoly-demo namespace: learningspec:
type: NodePort #Service类型
selector:
app: deploy-demo tag: learn-deploy ports:
- port: 80
targetPort: 80
nodePort: 30080 #node节点上监听的ip地址,端口范围为30000-32767
protocol: TCP
[root@k8s-master01 learning]# kubectl apply -f Service-selector-NodePort.yaml service/depoly-demo created
[root@k8s-master01 learning]# kubectl get svc -n learning NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
depoly-demo NodePort 10.101.14.46 <none> 80:30080/TCP 2m10s
[root@k8s-master01 learning]# kubectl describe svc -n learning Name: depoly-demoNamespace: learningLabels: <none>Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"depoly-demo","namespace":"learning"},"spec":{"ports":[{"nodePort"...Selector: app=deploy-demo,tag=learn-deployType: NodePortIP: 10.101.14.46Port: <unset> 80/TCPTargetPort: 80/TCPNodePort: <unset> 30080/TCPEndpoints: 10.244.0.22:80,10.244.1.29:80Session Affinity: None
External Traffic Policy: ClusterEvents: <none># 访问任意node节点的30080端口[root@mq1 ~]# curl http://192.168.88.137:30080/10.244.1.29[root@mq1 ~]# curl http://192.168.88.137:30080/10.244.0.22通过Endpoint访问外部服务
注意:Endpoints 与 Service 的绑定关系通过名称来关联的,所以这两者的名称(name)一定要一致。
Servcie 抽象了该如何访问 Kubernetes Pod,但也能够抽象其它类型的 backend
希望在生产环境中使用外部的数据库集群,但测试环境使用自己的数据库
希望服务指向另一个 Namespace 中或其它集群中的服务
正在将工作负载转移到 Kubernetes 集群,和运行在 Kubernetes 集群之外的 backend
[root@k8s-master01 learning]# vim Service-Endpoint.yaml kind: Service
apiVersion: v1
metadata:
name: my-blog
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
---
kind: Endpoints
apiVersion: v1
metadata:
name: my-blog
subsets:
- addresses:
- ip: 47.105.40.216
ports:
- port: 80# 启动和查看资源[root@k8s-master01 learning]# kubectl apply -f Service-Endpoint.yaml service/my-blog created
endpoints/my-blog created# 查看现有服务[root@k8s-master01 learning]# kubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d20h
my-blog ClusterIP 10.106.53.179 <none> 80/TCP 84s# 查看外部服务[root@k8s-master01 learning]# kubectl get endpoints NAME ENDPOINTS AGE
kubernetes 192.168.88.137:6443 6d20h
my-blog 47.105.40.216:80 66s# 内部服务的详细信息[root@k8s-master01 learning]# kubectl describe sesecrets serviceaccounts services
[root@k8s-master01 learning]# kubectl describe service my-blog Name: my-blog
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"my-blog","namespace":"default"},"spec":{"ports":[{"port":80,"prot...
Selector: <none>
Type: ClusterIP
IP: 10.106.53.179
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 47.105.40.216:80
Session Affinity: None
Events: <none>
# 外部服务的详细信息
[root@k8s-master01 learning]# kubectl describe endpoints my-blog
Name: my-blog
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Endpoints","metadata":{"annotations":{},"name":"my-blog","namespace":"default"},"subsets":[{"addresses":[{"ip":...
Subsets:
Addresses: 47.105.40.216
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
<unset> 80 TCP
Events: <none>
# 访问svc的地址测试
[root@k8s-master01 learning]# curl 10.106.53.179
<html>
<meta http-equiv="refresh" content="0;url=https://baiyongjie.com">
</html>
# 访问原来的地址,可以看到已经正常生效
[root@k8s-master01 learning]# curl 47.105.40.216
<html>
<meta http-equiv="refresh" content="0;url=https://baiyongjie.com">
</html>
作者:baiyongjie
链接:https://www.jianshu.com/p/4930ad89cf33