kubernetes核心概念 service(上)

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创建

Service的创建在工作中有两种方式,一是命令行创建,二是通过资源清单文件YAML文件创建。

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

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值