k8s在创建Service时,会根据标签选择器selector(lable selector)来查找Pod,并创建endpoint对象来存储pod集合的IP+端口信息,当Pod 地址发生变化时,endpoint也会随之发生变化,service接收前端client请求的时候,就会通过endpoint,找到转发到哪个Pod进行访问的地址。(至于转发到哪个节点的Pod,由负载均衡kube-proxy决定)
如图:
1、Node Network(节点网络):物理节点或者虚拟节点的网络,如ens33接口上的网路地址
2、Pod network(pod 网络),创建的Pod具有的IP地址
kubectl get pods -o wide
Node Network和Pod network这两种网络地址是配置的,其中节点网络地址是配置在节点接口之上,而pod网络地址是配置在pod资源之上的,因此这些地址都是配置在某些设备之上的,这些设备可能是硬件,也可能是软件模拟的
3、Cluster Network(也称为service network,表示集群地址),这个地址是虚拟的地址(virtual ip),没有配置在某个接口上,只是出现在service的规则当中。
kubectl get svc
查看定义Service资源需要的字段有哪些?
kubectl explain service
其中
FIELDS:
apiVersion <string> #service资源使用的api组
kind <string> #创建的资源类型
metadata <Object> #定义元数据
spec <Object>
kubectl explain service.spec
其中
FIELDS:
type <string> #定义service的类型
ports <[]Object> #定义service端口,用来和后端pod建立联系
查看定义Service.spec.type有哪些类型?
kubectl explain service.spec.type
查看service的spec.ports字段如何定义?
kubectl explain service.spec.ports
其中
FIELDS:
appProtocol <string>
name <string> #定义端口的名字
nodePort <integer> #service在物理机映射的端口,默认在 30000-32767 之间
port <integer> -required- #service的端口,这个是k8s集群内部服务可访问的端口
protocol <string>
targetPort <string> # targetPort是pod上的端口,从port和nodePort上来的流量,经过kube-proxy流入到后端pod的targetPort上,最后进入容器。
mkdir pods
vim pod_test_1.yaml
【pod_test_1.yaml】 文件内容
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-test-1
spec:
selector:
matchLabels:
test: cluster
replicas: 2
template:
metadata:
labels:
test: cluster
spec:
containers:
- name: my-nginx
image: docker.io/library/nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80 #pod中的容器需要暴露的端口
startupProbe:
periodSeconds: 5
initialDelaySeconds: 60
timeoutSeconds: 10
httpGet:
scheme: HTTP
port: 80
path: /
livenessProbe:
periodSeconds: 5
initialDelaySeconds: 60
timeoutSeconds: 10
httpGet:
scheme: HTTP
port: 80
path: /
readinessProbe:
periodSeconds: 5
initialDelaySeconds: 60
timeoutSeconds: 10
httpGet:
scheme: HTTP
port: 80
path: /
更新资源清单文件
kubectl apply -f pod_test_1.yaml
查看刚才创建的Pod ip地址
kubectl get pods -owide -l test=cluster
vim service_test_1.yaml
【service_test_1.yaml】 文件内容
apiVersion: v1
kind: Service
metadata:
name: nginx-test-1
labels:
test: cluster
spec:
type: ClusterIP
ports:
- port: 80 #service的端口,暴露给k8s集群内部服务访问
protocol: TCP
targetPort: 80 #pod容器中定义的端口
selector:
test: cluster #选择拥有test=cluster标签的pod
kubectl apply -f service_test_1.yaml
kubectl get svc -l test=cluster
在k8s控制节点(master节点)访问service的IP+端口,就可以把请求代理到后端pod
curl 10.111.10.207:80
查看service详细信息
kubectl describe svc nginx-test-1
观察转发情况
ipvsadm -Ln
查看endpoint
kubectl get ep nginx-test-1
service可以对外提供统一固定的ip地址,并将请求重定向至集群中的pod。其中“将请求重定向至集群中的pod”就是通过endpoint与selector协同工作实现。selector是用于选择pod,由selector选择出来的pod的ip地址和端口号,将会被记录在endpoint中。endpoint便记录了所有pod的ip地址和端口号。当一个请求访问到service的ip地址时,就会从endpoint中选择出一个ip地址和端口号,然后将请求重定向至pod中。具体把请求代理到哪个pod,需要的就是kube-proxy的轮询实现的。service不会直接到pod,service是直接到endpoint资源,就是地址加端口,再由endpoint再关联到pod。