当前位置: 代码网 > 科技>人工智能>数据分析 > kubernetes核心概念 service(上)

kubernetes核心概念 service(上)

2024年08月06日 数据分析 我要评论
使用kubernetes集群运行工作负载时,由于Pod经常处于用后即焚状态,Pod经常被重新生成,因此Pod对应的IP地址也会经常变化,导致无法直接访问Pod提供的服务,Kubernetes中使用了Service来解决这一问题,即在Pod前面使用Service对Pod进行代理,无论Pod怎样变化 ,只要有Label,就可以让Service能够联系上Pod,把PodIP地址添加到Service对应的端点列表(Endpoints)实现对Pod IP跟踪,进而实现通过Service访问Pod目的。

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地址

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com