K8s Service四层代理
Service概念
- Pod重启后IP地址很有可能会发生变化,与其有关联的服务找不到Pod。kubernetes 定义了service资源对象,Services定义了一个服务访问入口,客户端通过这个入口可访问背后的应用集群实例, 通过Label Selector实现的。
- Service 是一个固定接入层,客户端通过访问service的ip 和 端口访问到service关联的后端pod, 这个service工作依赖于kubernetes集群之上的一个附件,也就是kubernetes的DNS服务
- kubernetes要想给客户端提供网络功能,需依赖第三方的网络插件
- 每个K8s节点上都有一个组件kube-proxy, 始终监视着apiserver中有关service资源的变动信息,需要跟master之上的apiserver交互,随时连接到apiserver上获取任何一个与service资源相关的资源变动状态,这种是通过kubernetes固有的一种请求方法watch来实现,一旦有service资源内容发生变动,kube-proxy都会将它转化为当前节点之上的能够实现service资源调度
Service实现方法
k8s创建Service时,会根据标签选择器selector(label selector) 来查找Pod,据此创建与Service同名的endpoint对象,当Pod地址发生变化,endpoint也会随之发生变化。 Service接收前端Client请求时,会通过endpoint,找到Pod地址 (具体哪个Pod,根据kube-proxy负责均衡实现)
Service涉及IP类型
- Node Network : 物理机IP
- Pod Network : Pod 节点IP
- Cluster Network : 集群IP,也就是service network,没有配置在某个接口,只是在service规则里
端口
- nodePort: 物理机映射的端口
- port: service 端口,k8s集群内部可访问端口
- targetPort: pod端口
ClusterIP Yaml
- 导出相关镜像
[root@k8snode4 ~]# ctr -n=k8s.io images import busybox.tar.gz
[root@k8snode4 ~]# ctr -n=k8s.io images import nginx.tar.gz
- 查看pod标签
[root@k8smaster4 ~]# kubectl get pods --show-labels
- 查看指定标签Pod
[root@k8smaster4 ~]# kubectl get pods -l run=my-nginx
- 查看endpoint
[root@k8smaster4 svc]# kubectl get ep
- 查看ipvsadm
[root@k8smaster4 svc]# ipvsadm
[root@k8smaster4 svc]# ipvsadm -Ln
- Service 默认域名
SVC_NAME.NS_NAME.DOMAIN.LTD
服务名.命名空间.域名后缀
my-nginx.default.svc.cluster.local
- 查看端口占用指令
[root@k8snode5 ~]# netstat -tunlp
- 编写 ClusterIP Ymal
[root@k8smaster4 svc]# cat pod_test.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
type: ClusterIP
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: docker.io/library/nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
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: /
- 编写 NodePort Yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx-nodeport
labels:
run: my-nginx-nodeport
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: 80
nodePort: 30380
selector:
run: my-nginx-nodeport
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx-nodeport
spec:
selector:
matchLabels:
run: my-nginx-nodeport
replicas: 2
template:
metadata:
labels:
run: my-nginx-nodeport
spec:
containers:
- name: my-nginx-nodeport-container
image: docker.io/library/nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- ExternalName 跨名称空间访问
目标服务 Yaml
[root@k8smaster4 svc]# cat server_nginx.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
namespace: nginx-ns
spec:
selector:
app: nginx
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: nginx-ns
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: docker.io/library/nginx
imagePullPolicy: IfNotPresent
本地 Yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: nginx-ns
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: docker.io/library/nginx
imagePullPolicy: IfNotPresent
软连接service Yaml(只服务软连接)
[root@k8smaster4 svc]# cat client.yaml
apiVersion: v1
kind: Service
metadata:
name: client-svc
spec:
type: ExternalName
externalName: nginx-svc.nginx-ns.svc.cluster.local
ports:
- name: http
port: 80
targetPort: 80
访问效果
[root@k8smaster4 svc]# kubectl exec -it client-6976cc8697-fmkk6 -- /bin/sh
/ # wget -q -O - client-svc # 同一名称空间
/ # wget -q -O - nginx-svc.nginx-ns.svc.cluster.local #非同一名称空间