Service的四种类型使用
- ClusterIP
- 使用示例
- Pod里使用service的服务名访问应用
- NodePort
- 使用示例
- ExternalName
- 使用示例
- LoadBalancer
K8S支持以下4种Service类型:ClusterIP、NodePort、ExternalName、LoadBalancer
以下是使用4种类型进行Service创建,应对不同场景
ClusterIP
默认类型,适用于仅在集群内部提供服务的应用。创建的Service仅可在集群内部访问,由K8S自动分配IP地址。
使用示例
1、创建pod
vim pod_test_1.yaml
编写pod的yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-test-1
spec:selector:matchLabels:test: cluster # 配置deployment的标签,必须与pod标签一致replicas: 2 # 配置deployment的pod数template:metadata:labels:test: cluster # 配置pod的标签spec:containers:- name: my-nginximage: docker.io/library/nginx:latest # 使用的镜像imagePullPolicy: IfNotPresent # 节点本地没找到镜像再去远程仓库拉取ports:- containerPort: 80 #pod中的容器需要暴露的端口startupProbe: # 配置启动探测periodSeconds: 5initialDelaySeconds: 60timeoutSeconds: 10httpGet: scheme: HTTPport: 80path: /livenessProbe: # 配置存活探测periodSeconds: 5initialDelaySeconds: 60timeoutSeconds: 10httpGet:scheme: HTTPport: 80path: /readinessProbe: # 配置就绪探测(只有探测就绪成功后才会记录到Service里的endpoint)periodSeconds: 5initialDelaySeconds: 60 # pod启动后首次检查就绪探测的时间,单位为秒。timeoutSeconds: 10httpGet: # 探测方式是HTTP发起GET请求服务的80端口访问根路径scheme: HTTPport: 80path: /
更新启动资源
kubectl apply -f pod_test_1.yaml
查看刚才创建的Pod ip地址
kubectl get pods -owide -l test=cluster
查看 ReplicaSet信息
kubectl get replicaset -l test=cluster
请求pod的 IP地址,访问应用
curl 10.244.36.75:80
curl 10.244.169.133
在pod1中请求pod2的应用,可以访问
kubectl exec -it nginx-test-1-69ddb65d98-vq2r6 -- /bin/bash
“误”删除其中一个Pod,查看Pod集群变化
kubectl delete pods nginx-test-1-69ddb65d98-vq2r6
kubectl get pods -owide -l test=cluster
通过上面可以看到重新生成了一个pod:nginx-test-1-69ddb65d98-nkjnv,IP是110.244.36.76,在k8s中创建pod,如果pod被删除了,重新生成的pod的IP地址会发生变化,所以需要在pod前端加一个固定接入层。
2、创建service
vim service_test_1.yaml
编写service的yaml文件
apiVersion: v1
kind: Service
metadata:name: nginx-test-1labels:test: cluster
spec:type: ClusterIPports:- port: 80 #service的端口,暴露给k8s集群内部服务访问protocol: TCPtargetPort: 80 #pod容器中定义的端口selector:test: cluster #选择拥有test=cluster标签的pod
上述yaml文件将创建一个 Service,关联具有标签test=cluster的Pod,目标TCP端口80
(targetPort:容器接收流量的端口;port:抽象的 Service 端口,可以使任何其它 Pod访问该 Service的端口)。
更新启动Service
kubectl apply -f service_test_1.yaml
查看Service
kubectl get svc -l test=cluster
在k8s控制节点访问service的 IP:port 就可以把请求代理到后端pod
curl 10.111.10.207:80
通过上面可以看到请求Service IP:port 跟直接访问pod IP:port 看到的结果一样,这就说明Service可以把请求代理到它所关联的后端Pod
注意:上图的 “10.111.10.207:80” 地址只能是在k8s集群内部访问,在外部无法访问,想要通过浏览器是访问不通的
Pod里使用service的服务名访问应用
service只要创建完成,就可以直接解析它的服务名,每一个服务创建完成后都会在集群dns中动态添加一个资源记录,添加完成后就可以解析了,资源记录格式是:
SVC_NAME.NS_NAME.DOMAIN.LTD. 服务名.命名空间.域名后缀
集群默认的域名后缀是:svc.cluster.local
上面创建的nginx-test-1服务,完整名称解析是:nginx-test-1.default.svc.cluster.local
在Pod里通过Service的服务名访问应用
kubectl exec -it nginx-test-1-69ddb65d98-nkjnv -- /bin/bash
curl nginx-test-1.default.svc.cluster.local
NodePort
适用于需要从外部访问Service的应用。创建的Service在每个节点上公开一个静态端口,使得外部客户端可以通过公开的端口访问Service的应用。
使用示例
1、创建pod
vim pod_test_2.yaml
编写pod的yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-test-2
spec:selector:matchLabels:test: nodeportreplicas: 2template:metadata:labels:test: nodeportspec:containers:- name: my-nginximage: docker.io/library/nginx:latestimagePullPolicy: IfNotPresentports:- containerPort: 80 #pod中的容器需要暴露的端口startupProbe:periodSeconds: 5initialDelaySeconds: 60timeoutSeconds: 10httpGet:scheme: HTTPport: 80path: /livenessProbe:periodSeconds: 5initialDelaySeconds: 60timeoutSeconds: 10httpGet:scheme: HTTPport: 80path: /readinessProbe:periodSeconds: 5initialDelaySeconds: 60timeoutSeconds: 10httpGet:scheme: HTTPport: 80path: /
更新启动资源
kubectl apply -f pod_test_2.yaml
查看pod是否创建成功
kubectl get pods -owide -l test=nodeport
2、创建service,代理pod
vim service_test_2.yaml
编写service的yaml文件
apiVersion: v1
kind: Service
metadata:name: nginx-test-2labels:test: nodeport
spec:type: NodePortports:- port: 80protocol: TCPtargetPort: 80nodePort: 30380selector:test: nodeport
更新启动Service
kubectl apply -f service_test_2.yaml
查看Service
kubectl get svc -l test=nodeport
kubectl describe svc nginx-test-2
访问Service
curl 10.102.33.103
注意:10.102.33.103是k8s集群内部的Service的IP地址,只能在k8s集群内部访问,在集群外无法访问。
在集群外访问Service(K8S的node节点IP:nodePort)
PS. 我本地搭建是一个控制节点+2个工作节点
- 192.168.40.182:30380(控制节点)
- 192.168.40.183:30380(工作节点1)
- 192.168.40.184:30380(工作节点2)
以上3个地址都能访问到应用
数据转发流程
ipvsadm -Ln
ip addr
客户端请求(任何一个节点IP+端口)http://192.168.40.182:30380->docker0
虚拟网卡:172.17.0.1:30380->10.244.36.80:80,10.244.169.137:80
ExternalName
适用于跨名称空间访问。例如:命名空间为“default”下的client 服务,想要访问命名空间为“nginx-ns”下的nginx-svc服务。可通过DNS解析直接访问该服务,不需要其他负载均衡器。
使用示例
1、新建一个命名空间
kubectl create ns nginx-ns
2、搭建nginx-svc服务
2.1 创建pod
vim nginx_deployment.yaml
编写pod的yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:name: nginxnamespace: nginx-ns
spec: replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresent
更新启动资源
kubectl apply -f nginx_deployment.yaml
查看pod是否创建成功
kubectl get pods -n nginx-ns
2.2 创建service
vim nginx_svc.yaml
编写service的yaml文件
apiVersion: v1
kind: Service
metadata:name: nginx-svcnamespace: nginx-ns
spec:selector:app: nginxports:- name: httpprotocol: TCPport: 80targetPort: 80
更新启动Service
kubectl apply -f nginx_svc.yaml
查看Service信息
kubectl get svc -n nginx-nskubectl describe svc nginx-svc -n nginx-ns
3、搭建client 服务
3.1 创建pod
vim client.yaml
编写pod的yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:name: client
spec: replicas: 1selector:matchLabels:app: busyboxtemplate:metadata:labels:app: busyboxspec:containers:- name: busyboximage: busyboximagePullPolicy: IfNotPresentcommand: ["/bin/sh","-c","sleep 36000"]
更新启动资源
kubectl apply -f client.yaml
该文件中指定了到 nginx-svc 的软链,让使用者感觉就好像调用自己命名空间的服务一样
查看pod是否正常运行
kubectl get pods -l app=busybox
3.2 创建service
vim client_svc.yaml
编写service的yaml文件
apiVersion: v1
kind: Service
metadata:name: client-svc
spec:type: ExternalNameexternalName: nginx-svc.nginx-ns.svc.cluster.localports:- name: httpport: 80targetPort: 80
更新启动Service
kubectl apply -f client_svc.yaml
登录到client pod
kubectl exec -it client-568955849b-mt47t -- /bin/sh
wget -q -O - client-svc.default.svc.cluster.local
wget -q -O - nginx-svc.nginx-ns.svc.cluster.local
上面两个请求的结果一样
LoadBalancer
LoadBalancer类型适用于需要提供公共服务并且需要高可用性和高伸缩性的场景。与其他类型的Service相比实现更复杂,需要绑定到云平台的负载均衡器服务上,因此通常适用于云平台环境。
(ps. 设备有限,没有做这块的实验。
特放官网的链接:https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#loadbalancer)