kubernetes核心概念 service
一、 service作用
使用kubernetes集群运行工作负载时,由于pod经常处于用后即焚状态,pod经常被重新生成,因此pod对应的ip地址也会经常变化,导致无法直接访问pod提供的服务,kubernetes中使用了service来解决这一问题,即在pod前面使用service对pod进行代理,无论pod怎样变化 ,只要有label,就可以让service能够联系上pod,把podip地址添加到service对应的端点列表(endpoints)实现对pod ip跟踪,进而实现通过service访问pod目的。
svc 特点:
服务发现,防止阴滚动升级等因素导致 pod ip 发生改变而失联,找到提供同一个服务的 pod。
负载均衡,定义一组 pod 的访问策略。
svc 与 pod 关系:
pod 在创建时,与资源没有明确关联,通过 service 标签和 pod 标签相匹配来以此关联。
可以通过 endpoints 来查看关联的 pod。
二、kube-proxy三种代理模式
- kube-proxy三种代理模式:userspace模式、iptables模式、ipvs模式
2.1 userspace模式
userspace 模式是 kube-proxy 使用的第一代模式,该模式在 kubernetes v1.0 版本开始支持使用。
kube-proxy 会为每个 service 随机监听一个端口(proxy port),并增加一条 iptables 规则。所以通过 clusterip:port 访问 service 的报文都 redirect 到 proxy port,kube-proxy 从它监听的 proxy port 收到报文以后,走 round robin(默认) 或是 session affinity(会话亲和力,即同一 client ip 都走同一链路给同一 pod 服务),分发给对应的 pod。
由于 userspace 模式会造成所有报文都走一遍用户态(也就是 service 请求会先从用户空间进入内核 iptables,然后再回到用户空间,由 kube-proxy 完成后端 endpoints 的选择和代理工作),需要在内核空间和用户空间转换,流量从用户空间进出内核会带来性能损耗,所以这种模式效率低、性能不高,不推荐使用
2.2 iptables模式
iptables 模式是 kube-proxy 使用的第二代模式,该模式在 kubernetes v1.1 版本开始支持,从 v1.2 版本开始成为 kube-proxy 的默认模式。
iptables 模式是 kube-proxy 的改进版,相比 userspace 模式有显著的性能提升。其工作原理如下:
(1).kube-proxy 同样监听 kubernetes api 服务器中 service 和 endpoint 的变化。
不同的是,kube-proxy 使用 iptables 来设置网络规则。这些规则会直接在内核空间进行处理,而不是通过用户空间。
(2).当有新的 service 创建时,kube-proxy 会生成相应的 iptables 规则,定义从 service ip 和端口到后端 pod 的 nat 转发规则。
(3).数据包在内核空间直接被转发到相应的后端 pod,减少了上下文切换,提高了转发性能。
iptables 模式的优点是性能更好,但在处理大量规则时,规则管理和更新可能会变得复杂。
2.3 ipvs模式
ipvs 模式被 kube-proxy 采纳为第三代模式,模式在 kubernetes v1.8 版本开始引入,在 v1.9 版本中处于 beta 阶段,在 v1.11 版本中正式开始使用。
ipvs 模式是 kube-proxy 的最新实现方式,使用 linux 内核中的 ip virtual server (ipvs) 技术。其工作原理如下:
(1).kube-proxy 监听 kubernetes api 服务器中 service 和 endpoint 的变化
(2).kube-proxy 使用 ipvs 来创建和维护负载均衡规则。ipvs 是内核中的一个模块,专门用于负载均衡,支持多种调度算法。
(3).当有新的 service 创建时,kube-proxy 会使用 ipvs 创建相应的负载均衡规则,定义从 service ip 和端口到后端 pod 的转发规则。
(4).数据包在内核空间通过 ipvs 直接转发,性能更高,同时支持更多的负载均衡算法(如轮询、最小连接数、最短延迟等)。
(5).ipvs 模式的优点是性能最佳,支持更多的负载均衡算法和更复杂的网络规则,但需要内核支持 ipvs 模块。
三、 service类型
service类型决定了访问service的方法
3.1 service类型
-
clusterip
clusterip:这是 kubernetes 的默认方式。这其中根据是否会生成 clusterip 又分为普通 service 和 headless service。 -普通 service:创建的 service 会分配一个集群内部可访问的固定虚拟 ip,这是最常使用的方式。 -headless service:创建的 service 不会分配固定的虚拟 ip,同样也不会通过 kube-proxy 做反向代理和负载均衡,主要通过 dns 提供稳定的网络 id 进行访问,通常用于 statefulset 中。 -
nodeport
nodeport:使用 clusterip,并且将 service 的 port 端口映射到集群中每个 node 节点的相同端口 port,这样在集群外部访问服务可以直接使用 nodeip:nodeport 进行访问。 -
loadbalancer
loadbalancer:在 nodeport 的基础上(也就是拥有 clusterip 和 nodeport),还会向所处的公有云申请负载均衡器 lb(负载均衡器的后端直接映射到各 node 节点的 nodeport 上),这样就实现了通过外部的负载均衡器访问服务。 -
externalname
externalname:这是 service 的一种特例形式。主要用于解决运行在集群外部的服务问题,这种方式下会返回外部服务的别名来为集群内部提供服务。上述提到的 3 种模式主要依赖于 kube-proxy,而这种模式依赖于kube-dns的层级。
四、 service创建
4.1 clusterip类型
clusterip根据是否生成clusterip又可分为普通service和headless service
service两类:
- 普通service:
为kubernetes的service分配一个集群内部可访问的固定虚拟ip(cluster ip), 实现集群内的访问。
- headless service:
该服务不会分配cluster ip, 也不通过kube-proxy做反向代理和负载均衡。而是通过dns提供稳定的网络id来访问,dns会将headless service的后端直接解析为pod ip列表。
4.1.1 普通clusterip service创建
4.1.1.1 通过资源清单文件创建service
[root@master01 ~]# cat service.yml
apiversion: apps/v1
kind: deployment
metadata:
name: nginx-server
spec:
replicas: 3
selector:
matchlabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-1
image: nginx:1.19.6
imagepullpolicy: ifnotpresent
ports:
- containerport: 80
---
apiversion: v1
kind: service
metadata:
name: nginx-svc
spec:
type: clusterip
ports:
- protocol: tcp
port: 80
targetport: 80
selector:
app: nginx
~~~powershell
[root@k8s-master01 pod]# kubectl apply -f service.yml
deploymen
t.apps/nginx-server created
- 验证
查看service
[root@k8s-master01 pod]# kubectl get svc
name type cluster-ip external-ip port(s) age
kubernetes clusterip 10.96.0.1 443/tcp 15d
nginx-svc clusterip 10.102.204.179 80/tcp 65s
查看endpoints
[root@k8s-master01 pod]# kubectl get endpoints
name endpoints age
kubernetes 192.168.71.120:6443 15d
nginx-svc 192.168.32.163:80,192.168.69.237:80,192.168.79.119:80 88s
查看pod
[root@k8s-master01 pod]# kubectl get pods
name ready status restarts age
nginx-server-55679bfd89-9l6pv 1/1 running 0 3m
nginx-server-55679bfd89-c4hq9 1/1 running 0 3m
nginx-server-55679bfd89-x89zt 1/1 running 0 3m
4.1.1.3 访问
[root@k8s-master01 pod]# curl http://10.102.204.179:80
<!doctype html>
<html>
<head>
<title>welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: tahoma, verdana, arial, sans-serif;
}
</style>
</head>
<body>
<h1>welcome to nginx!</h1>
<p>if you see this page, the nginx web server is successfully installed and
working. further configuration is required.</p>
<p>for online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>thank you for using nginx.</em></p>
</body>
</html>
4.1.2.1 编写用于创建deployment控制器类型的资源清单文件
[root@master01 ~]# vim service.yml
apiversion: apps/v1
kind: deployment
metadata:
name: nginx-server
spec:
replicas: 3
selector:
matchlabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-1
image: nginx:1.19.6
imagepullpolicy: ifnotpresent
ports:
- containerport: 80
---
apiversion: v1
kind: service
metadata:
name: headless-service
spec:
type: clusterip
clusterip: none # none就代表是无头service
ports:
- protocol: tcp
port: 80
targetport: 80
selector:
app: nginx
```
#### 4.1.2.3 应用资源清单文件创建headless service
命令
[root@k8s-master01 pod]# kubectl apply -f service.yml
deployment.apps/nginx-server created
service/headless-service created
``
#### 4.1.2.4 查看已创建的headless service
命令
[root@k8s-master01 pod]# kubectl get svc
name type cluster-ip external-ip port(s) age
headless-service clusterip none <none> 80/tcp 10s
kubernetes clusterip 10.96.0.1 <none> 443/tcp 15d
可以看到headless-service没有cluster-ip,用none表示
4.2 nodeport类型
1.这种类型建立在clusterip类型之上,其在每个node节点的ip地址的某静态端口(nodeport)暴露服务,因此,它依然会为service分配集群ip地址,并将此作为nodeport的路由目标。
2.nodeport类型就是在工作节点的ip地址上选择一个端口用于将集群外部的用户请求转发至目标service的clusterip和port,因此,这种类型的service既可如clusterip一样受到集群内部客户端pod的访问,会受到集群外部客户端通过套接字:进行的请求。
暴漏端口+所在节点ip地址访问
- 创建资源清单文件
[root@master01 ~]# cat node.yml
apiversion: apps/v1
kind: deployment
metadata:
name: nginx-node
labels:
app: nginx-node
spec:
replicas: 2
selector:
matchlabels:
app: nginx-node
template:
metadata:
labels:
app: nginx-node
spec:
containers:
- name: c1
image: nginx:1.19.6
imagepullpolicy: ifnotpresent
ports:
- containerport: 80
---
apiversion: v1
kind: service
metadata:
name: nginx-nodeserver
spec:
type: nodeport
selector:
app: nginx-node
ports:
- protocol: tcp
nodeport: 31110
port: 8070
targetport: 80
- 应用资源清单文件
[root@k8s-master01 pod]# kubectl apply -f node.yml
deployment.apps/nginx-node created
service/nginx-nodeserver created
- 验证service创建
[root@k8s-master01 pod]# kubectl get deployment -o wide
name ready up-to-date available age containers images selector
nginx-node 2/2 2 2 56s c1 nginx:1.19.6 app=nginx-node
[root@master01 ~]# kubectl get svc
[root@k8s-master01 pod]# kubectl get svc -o wide
name type cluster-ip external-ip port(s) age selector
kubernetes clusterip 10.96.0.1 443/tcp 15d
nginx-nodeserver nodeport 10.98.125.252 8070:31110/tcp 81s app=nginx-node
[root@k8s-master01 pod]# kubectl get endpoints
name endpoints age
kubernetes 192.168.71.120:6443 15d
nginx-nodeserver 192.168.32.169:80,192.168.69.242:80 101s
[root@k8s-master01 pod]# kubectl get pods -o wide
name ready status restarts age ip node nominated node readiness gates
nginx-node-ffcd559b-vpdvm 1/1 running 0 2m20s 192.168.69.242 k8s-worker02
nginx-node-ffcd559b-zmz2r 1/1 running 0 2m20s 192.168.32.169 k8s-master01
4.3 loadbalancer
生成和node 同网段ip地址,暴漏ip地址加端口访问
1.什么是负载均衡
lb,既负载均衡(load balancer),是高并发、高可用系统必不可少的关键组件,其目标是尽力将网络流量平均分发到多个服务器上,以提高系统整体的响应速度和可用性。
负载均衡的主要作用
高并发:负载均衡通过算法调整负载,尽力均匀的分配应用集群中的各结点的工作量。从而提升整个应用集群处理并发的能力(吞吐量)
伸缩性:添加或减少服务器数量,然后由负载均衡分发控制。使集群具备伸缩性。
高可用:负载均衡器可以监控候选服务器,当服务器不可用时,自动跳转,将请求分发给可用的服务器。使服务集群具有高可用特性。
安全防护:负载均衡软件或硬件提供了安全性功能;如防护墙,黑名单、防攻击。
loadbalancer和nodeport非常相似,目的都是向外暴露一个端口,区别在于loadbalancer会在集群外部再做一个负载均衡设备,而这个设备需要外部环境的支持,外部服务发送到这个设备上的请求,会被设备负载后转发到集群中
loadbalancer其实就是使用外部的一个负载均衡来负载k8s中的pod
在私有云环境下的k8s想使用loadbalancer需要部署metallb组件
想在私网环境下测试loadbalancer,必须要创建一个metallb,metallb相当于一个负载均衡器的角色
loadbalancer原理:请求首先被转发到外部lb负载设备,在通过匹配规则,转发到k8s集群任意node节点上,在通过service资源找到对应的pod,最终提供服务
部署metallb组件
metallb组件也是以pod形式运行
metallb部署在k8s中,为k8s集群提供了网络负载均衡器, 它主要提供两个功能:地址分配和外部通知
在公有云环境下,当购买或指定一个负载均衡器时,云平台将为用户分配一个ip地址,通过这个ip地址就能实现loadbalancer,而在私有云集群中,metallb将负责ip地址的分配。
metallb无法凭空创建ip地址,因此需要在配置过程中为metallb指定一个ip地址池,当服务创建或者删除时,metallb负责从ip地址池中分配或者销毁服务对应的ip地址。
metallb可以为kubernetes集群中的service提供网络负载均衡功能。
metallb两大功能为:
- 地址分配,类似于dhcp
- 外部通告,一旦metallb为服务分配了外部ip地址,它就需要使群集之外的网络意识到该ip在群集中“存在”。metallb使用标准路由协议来实现此目的:arp,ndp或bgp
资源清单文件下载:
4.3.2.2 应用资源清单文件
资源清单文件下载:
# kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
# kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml
4.3.2.3 准备metallb配置文件
[root@nginx metallb]# cat metallb-conf.yaml
apiversion: v1
kind: configmap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 192.168.71.240-192.168.71.250
192.168.71.240-192.168.71.250是集群节点服务器ip同一段。
2.发布service类型为loadbalancer的deployment控制器类型应用
创建deployment控制器类型应用nginx-metallb及service,service类型为loadbalancer
[root@master01 ~]# vim loadbalancer.yml
apiversion: apps/v1
kind: deployment
metadata:
name: nginx-node
labels:
app: nginx-node
spec:
selector:
matchlabels:
app: nginx-node
template:
metadata:
labels:
app: nginx-node
spec:
containers:
- name: c1
image: nginx:1.19.6
imagepullpolicy: ifnotpresent
ports: - containerport: 80
apiversion: v1
kind: service
metadata:
name: nginx-load
spec:
type: loadbalancer
selector:
app: nginx-node
ports:
- protocol: tcp
port: 8070
targetport: 80
[root@k8s-master01 pod]# kubectl apply -f loadbalancer.yml
deployment.apps/nginx-node created
service/nginx-load created
[root@k8s-master01 pod]# kubectl get pods -o wide
name ready status restarts age ip node nominated node readiness gates
nginx-node-ffcd559b-hm96q 1/1 running 0 34s 192.168.32.178 k8s-master01
[root@k8s-master01 pod]# kubectl get svc -o wide
name type cluster-ip external-ip port(s) age selector
kubernetes clusterip 10.96.0.1 443/tcp 15d
nginx-load loadbalancer 10.107.254.39 192.168.71.241 8070:32481/tcp 57s app=nginx-node
loadbalancer 作用是将svc 映射为和node 同网段的ip地址
发表评论