K8S四层代理Service-01
- 概念、原理解读
-
- [1、 为什么要有Service?](#1、 为什么要有Service?)
- [2、 Service概述](#2、 Service概述)
- [3、 Service工作原理](#3、 Service工作原理)
- [4 、kubernetes集群中有三类IP地址](#4 、kubernetes集群中有三类IP地址)
- 认识Service资源
- 创建Service
概念、原理解读
1、 为什么要有Service?
- pod的IP经常变化,service是pod的代理,客户端访问只需要访问service,就会把请求代理到Pod
- pod的IP在k8s集群之外无法访问,所以需要创建service,这个service可以在k8s集群外访问的。
2、 Service概述
- service是一个固定接入层,客户端可以通过访问service的IP和端口进而访问到service关联的一组后端pod。
- service的名称解析依赖于在kubernetes集群之上部署的一个附件,kubernetes的dns服务(1.11之前的版本使用的是kubedns,较新的版本使用的是coredns),因此在部署完k8s之后需要再部署dns附件。
- kubernetes要想给客户端提供网络功能 ,需要依赖第三方的网络插件(flannel,calico 等)。每个K8s节点上都有一个组件叫做kube-proxy ,这个组件将始终监视着apiserver中有关service资源的变动信息,通过kubernetes中固有的一种请求方法watch来实现监视,一旦有service资源的内容发生变动(如创建,删除),kube-proxy都会将它转化成当前节点之上的能够实现service资源调度,把我们请求调度到后端特定的pod资源之上的规则,这个规则可能是iptables,也可能是ipvs,取决于service的实现方式。
3、 Service工作原理
k8s在创建Service时,会根据标签选择器selector(lable selector)来查找Pod,并创建endpoint对象来存储pod集合的IP+端口信息,当Pod 地址发生变化时,endpoint也会随之发生变化,service接收前端client请求的时候,就会通过endpoint,找到转发到哪个Pod进行访问的地址。(至于转发到哪个节点的Pod,由负载均衡kube-proxy决定)
如图:
4 、kubernetes集群中有三类IP地址
1、Node Network(节点网络):物理节点或者虚拟节点的网络,如ens33接口上的网路地址
2、Pod network(pod 网络),创建的Pod具有的IP地址
bash
kubectl get pods -o wide
Node Network和Pod network这两种网络地址是配置的,其中节点网络地址是配置在节点接口之上,而pod网络地址是配置在pod资源之上的,因此这些地址都是配置在某些设备之上的,这些设备可能是硬件,也可能是软件模拟的
3、Cluster Network(也称为service network,表示集群地址),这个地址是虚拟的地址(virtual ip),没有配置在某个接口上,只是出现在service的规则当中。
bash
kubectl get svc
认识Service资源
查看定义Service资源需要的字段有哪些?
bash
kubectl explain service
其中
bash
FIELDS:
apiVersion <string> #service资源使用的api组
kind <string> #创建的资源类型
metadata <Object> #定义元数据
spec <Object>
bash
kubectl explain service.spec
bash
其中
FIELDS:
type <string> #定义service的类型
ports <[]Object> #定义service端口,用来和后端pod建立联系
Service的四种类型
查看定义Service.spec.type有哪些类型?
bash
kubectl explain service.spec.type
Service的端口
查看service的spec.ports字段如何定义?
bash
kubectl explain service.spec.ports
bash
其中
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上,最后进入容器。
创建Service
创建Pod
bash
mkdir pods
vim pod_test_1.yaml
【pod_test_1.yaml】 文件内容
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: /
更新资源清单文件
bash
kubectl apply -f pod_test_1.yaml
查看刚才创建的Pod ip地址
bash
kubectl get pods -owide -l test=cluster
创建service
bash
vim service_test_1.yaml
【service_test_1.yaml】 文件内容
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
bash
kubectl apply -f service_test_1.yaml
kubectl get svc -l test=cluster
在k8s控制节点(master节点)访问service的IP+端口,就可以把请求代理到后端pod
bash
curl 10.111.10.207:80
查看service详细信息
bash
kubectl describe svc nginx-test-1
观察转发情况
bash
ipvsadm -Ln
查看endpoint
bash
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。