@kubernetes(k8s)label标签的使用及service代理模式

label

一、label的介绍

1、label的概述

1>Label 是 Kubernetes 系统中另外一个核心概念。一个 Label 是一个 key=value 的键值对,其中 key 与 vaue 由用 户自己指定。
2>Label 可以附加到各种资源对象上,例如 Node、Pod、Service、RC 等,一个资源对象可以定义任意 数量的 Label,
3>同一个 Label 也可以被添加到任意数量的资源对象上去,Label 通常在资源对象定义时确定,也可 以在对象创建后动态添加或者删除

2、label的分类

我们可以通过指定的资源对象捆绑一个或多个不同的 Label 来实现多维度的资源分组管理功能,以便于灵活、 方便地进行资源分配、调度、配置、部署等管理工作
例如:部署不同版本的应用到不同的环境中;或者监控和 分析应用(日志记录、监控、告警)等

在这里插入图片描述

#常见的lable
   1)版本标签:"release" : "stable" , "release" : "canary" 
   2)环境标签:"environment" : "dev" , "environment" : "production" 
   3)架构标签:"tier" : "frontend" , "tier" : "backend" , "tier" : "middleware" 
   4)分区标签:"partition" : "customerA" , "partition" : "customerB" 
   5)质量管控标签:"track" : "daily" , "track" : "weekly





ps :Label 相当于我们熟悉的“标签”,給某个资源对象定义一个 Label,就相当于給它打了一个标签,随后可以 通过 Label Selector(标签选择器)查询和筛选拥有某些 Label 的资源对象,Kubernetes 通过这种方式实现了类似 SQL 的简单又通用的对象查询机制

二、label的使用

#编写配置清单
[root@m01 /mnt]# cat deployment-nginx.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx
  labels:
    app: nginx
spec:
  replicas: 2   
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80




#创建pod
[root@m01 /mnt]# kubectl create -f deployment-nginx.yaml 
deployment.apps/deployment-nginx created     
[root@m01 /mnt]# kubectl get pods --show-labels -n hzl     #根据标签查询pod
NAME                               READY   STATUS    RESTARTS   AGE     LABELS
deployment-nginx-585449566-9z226   1/1     Running   0          6m27s   app=nginx,pod-template-hash=585449566
deployment-nginx-585449566-d9z8l   1/1     Running   0          6m27s   app=nginx,pod-template-hash=585449566

1、增加标签

#设置标签
[root@m01 /mnt]# kubectl label pod -n hzl deployment-nginx-585449566-9z226 nginx=nginx001
pod/deployment-nginx-585449566-9z226 labeled
[root@m01 /mnt]# kubectl get pods --show-labels -n hzl       #查看标签
NAME                               READY   STATUS    RESTARTS   AGE     LABELS
deployment-nginx-585449566-9z226   1/1     Running   0          8m40s   app=nginx,nginx=nginx001,pod-template-hash=585449566
deployment-nginx-585449566-d9z8l   1/1     Running   0          8m40s   app=nginx,pod-template-hash=585449566




#给所有的pod设置所有标签
[root@m01 /mnt]# kubectl label pods --all test=test
pod/deployment-nginx-585449566-9z226 labeled
pod/deployment-nginx-585449566-cvftk labeled
pod/deployment-nginx-585449566-d9z8l labeled
[root@m01 /mnt]# kubectl get pod --show-labels   #查看
NAME                               READY   STATUS    RESTARTS   AGE    LABELS
deployment-nginx-585449566-9z226   1/1     Running   0          3h1m   app=hzl-nginx,pod-template-hash=585449566,test=test
deployment-nginx-585449566-cvftk   1/1     Running   0          15m    app=nginx,pod-template-hash=585449566,test=test
deployment-nginx-585449566-d9z8l   1/1     Running   0          3h1m   app=nginx,pod-template-hash=585449566,test=test

在这里插入图片描述

2、更改(更新)标签label

#更新标签
[root@m01 /mnt]# kubectl label pods deployment-nginx-585449566-9z226  app=hzl-nginx --overwrite
pod/deployment-nginx-585449566-9z226 labeled
[root@m01 /mnt]# kubectl get pod --show-labels 
NAME                               READY   STATUS    RESTARTS   AGE    LABELS
deployment-nginx-585449566-9z226   1/1     Running   0          165m   app=hzl-nginx,pod-template-hash=585449566
deployment-nginx-585449566-cvftk   1/1     Running   0          8s     app=nginx,pod-template-hash=585449566
deployment-nginx-585449566-d9z8l   1/1     Running   0          165m   app=nginx,pod-template-hash=585449566

3、删除标签lael

#删除标签label
root@m01 /mnt]# kubectl label pod  -n hzl deployment-nginx-585449566-9z226 nginx-
pod/deployment-nginx-585449566-9z226 labeled
[root@m01 /mnt]# kubectl get pod -n hzl --show-labels    #查看已经删除
NAME                               READY   STATUS    RESTARTS   AGE   LABELS
deployment-nginx-585449566-9z226   1/1     Running   0          27m   app=nginx,pod-template-hash=585449566
deployment-nginx-585449566-d9z8l   1/1     Running   0          27m   app=nginx,pod-template-hash=585449566

设置权重
在这里插入图片描述

4、查看标签label

#查看标签
[root@m01 /mnt]# kubectl get pod --show-labels 
NAME                               READY   STATUS    RESTARTS   AGE    LABELS
deployment-nginx-585449566-9z226   1/1     Running   0          157m   app=nginx,pod-template-hash=585449566
deployment-nginx-585449566-d9z8l   1/1     Running   0          157m   app=nginx,pod-template-hash=585449566


#查看匹配标签条件的node
格式:
kubectl get nodes -l 标签key=标签values

[root@m01 /mnt]# kubectl get nodes -L  app=nginx
NAME    STATUS   ROLES                  AGE    VERSION   APP=NGINX
m01     Ready    control-plane,master   5d7h   v1.21.3   
nod01   Ready    <none>                 5d7h   v1.21.3   
nod02   Ready    <none>                 5d7h   v1.21.3   


5、标签格式以列显示

[root@m01 /mnt]# kubectl get pods -L app -n hzl 
NAME                               READY   STATUS    RESTARTS   AGE   APP
deployment-nginx-585449566-9z226   1/1     Running   0          30m   nginx
deployment-nginx-585449566-d9z8l   1/1     Running   0          30m   nginx

service 资源

一、service介绍

service 是 k8s 中的一个重要概念,主要是提供负载均衡和服务自动发现。它是 k8s 中最核心的资源之一,每 一个 Service 就是我们平常所说的一个“微服务

在这里插入图片描述

1、service的概述:

#为什么使用service
   在非 k8s 世界中,管理员可以通过在配置文件中指定 IP 地址 或主机名,容许客户端访问,
   但在 k8s 中这种方式是行不通的。因为 Pod 是有生命周期的,它们可以被创建或 销毁。虽然通过控制器能够动态地创建 Pod,但当 Pod 被分配到某个节点时,K8s 都会为其分配一个 IP 地址,而 该 IP 地址不总是稳定可依赖的。
   因此,在 Kubernetes 集群中,如果一组 Pod(称为 backend)为其它 Pod (称 为 frontend)提供服务,那么那些 frontend(前端) 该如何发现,并连接到这组(后端) backend 的 Pod 

2、service存在的意义

1#防止Pod失联(服务发现):Service通过label-selector关联Pod

2#定义一组Pod的访问策略(4层负载均衡)

3、使用测试工具查看svc代理名称(别名)

#查看svc(负载均衡代理名称)
[root@m01 /hzl]# kubectl get svc     
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   25m
test-svc     ClusterIP   10.107.80.105   <none>        80/TCP    14m




#使用网络管理工具测试查看
[root@m01 /hzl]# kubectl run test --rm -it --image=busybox:1.28
If you don't see a command prompt, try pressing enter.
/ # nslookup test-svc      #查看svc的代理
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      test-svc
Address 1: 10.107.80.105 test-svc.default.svc.cluster.local

/ # nslookup kubernetes   
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
/ # 

二、service代理模式

1》Userspace(用户模式)
2》Iptables 代理模式
3》Ipvs 代理模式

【service官方文档】

Service 的工作方式:
在 Kubernetes 迭代过程中,给 Service 设置里三种工作方式,分别是:Userspace 方式、Iptables 以及 Ipvs, 这三种方式到现在为止,官方推荐使用 IPVS, 当集群不支持 IPVS 的时候,集群会降级到 Iptables

【service资源清单定义】

kind: Service 
apiVersion: v1 
metadata:
  name: test-service 
  namespace: default
  labels: 
    app: test-service
spec: 
  type: ClusterIP 
  selector:
    app: test-service
  ports:
    - port: 80 
      targetPort: 80

1、Userspace代理模式

Client Pod 要访问 Server Pod 时,它先将请求发给本机内核空间中的 service 规则, 由它再将请求,转给监听在指 定套接字上的 kube-proxy,kube-proxy 处理完请求,并分发请求到指定 Server Pod 后,再将请求递交给内核空间中 的 service,由 service 将请求转给指定的 Server Pod, 由于其需要来回在用户空间和内核空间交互通信,因此效率很差

在这里插入图片描述

#Userspace概述:
  这种模式,kube-proxy 会监视 Kubernetes 控制平面对 Service 对象和 Endpoints 对象的添加和移除操作。 
  对每个 Service,它会在本地 Node 上打开一个端口(随机选择)
  任何连接到“代理端口”的请求,都会被代理到 Service 的后端 Pods 中的某个上面(如 Endpoints 所报告的一样)。 
  使用哪个后端 Pod,是 kube-proxy 基于 SessionAffinity 来确定的
  最后,它配置 iptables 规则,捕获到达该 Service 的 clusterIP(是虚拟 IP) 和 Port 的请求,并重定向到代理端口,代理端口再代理请求到后端Pod


ps : 默认情况下,用户空间模式下的 kube-proxy 通过轮转算法选择后端

2、iptables代理模式

直接由内核中的 iptables 规则,接受 Client Pod 的请求,并处理完成后,直接转发给指定 ServerPod。这种方 式不再将请求转发给 kube-proxy,性能提升很多

在这里插入图片描述

# iptables 代理模式的概述:
  这种模式,kube-proxy 会监视 Kubernetes 控制节点对 Service 对象和 Endpoints 对象的添加和移除。 
  对每个 Service,它会配置 iptables 规则,从而捕获到达该 Service 的 clusterIP 和端口的请求,进而将请求重 定向到 Service 的一组后端中的某个 Pod 上面。
  对于每个 Endpoints 对象,它也会配置 iptables 规则,这个规则会选择一个后端组合

ps :默认的策略是,kube-proxy 在 iptables 模式下随机选择一个后端

3、IPVS 代理模式

IPVS代理模式基于类似于 iptables 模式的 netfilter 挂钩函数, 但是使用哈希表作为基础数据结构,并且在内核空间中工作。 这意味着,与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通信的延迟要短,并且在同步代理规则时具有更好的性能,与其他代理模式相比,IPVS 模式还支持更高的网络流量吞吐量

在这里插入图片描述

# IPVS概述
   在 ipvs 模式下,kube-proxy 监视 Kubernetes 服务和端点,调用 netlink 接口相应地创建 IPVS 规则, 并定期将 IPVS 规则与 Kubernetes 服务和端点同步。 
   该控制循环可确保IPVS 状态与所需状态匹配。访问服务时,IPVS 将流量定向到后端Pod之一

   



#IPVS 提供了更多选项来平衡后端 Pod 的流量,这些是:
    rr: 轮替(Round-Robin)
    lc: 最少链接(Least Connection),即打开链接数量最少者优先
    dh: 目标地址哈希(Destination Hashing)
    sh: 源地址哈希(Source Hashing)
    sed:最短预期延迟(Shortest Expected Delay)
    nq: 从不排队(Never Queue)




ps : 要在 IPVS 模式下运行 kube-proxy,必须在启动 kube-proxy 之前使 IPVS 在节点上可用。
      当 kube-proxy 以 IPVS 代理模式启动时,它将验证 IPVS 内核模块是否可用。 
      如果未检测到 IPVS 内核模块,则 kube-proxy 将退回到以 iptables 代理模式运行

【ipvs的使用】

#修改代理模式为ipvs
[root@m01 /mnt]# kubectl edit configmaps kube-proxy -nkube-system

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
  config.conf: |-
    apiVersion: kubeproxy.config.k8s.io/v1alpha1
    bindAddress: 0.0.0.0
    bindAddressHardFail: false
    clientConnection:
............
.......


#删除kube-proxy的Pod,使配置文件生效
[root@m01 /mnt]# kubectl delete pod kube-proxy-9lvgh -nkube-system



#查看规则
[root@m01 /mnt]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

设置ipvs
在这里插入图片描述

【总述】

以上不论哪种,kube-proxy 都通过 watch 的方式监控着 kube-APIServer 写入 etcd 中关于 Pod 的最新状态信息, 它一旦检查到一个 Pod 资源被删除了 或 新建,它将立即将这些变化,反应再 iptables 或 ipvs 规则中,以便 iptables 和 ipvs 在调度 Clinet Pod 请求到 Server Pod 时,不会出现 Server Pod 不存在的情况。
自 k8s1.1 以后,service 默认使用 ipvs 规则,若 ipvs 没有被激活,则降级使用 iptables 规则. 但在 1.1 以前,service 使用的模式默认为 userspace

#Iptables VS IPVS

1)Iptables灵活,功能强大;规则遍历匹配和更新,呈线性时延

2)IPVS工作在内核态,有更好的性能;调度算法丰富:rr,wrr,lc,wlc,ip hash

三、service四种类型

在这里插入图片描述

1、service常见的三种类型

1》ClusterIP(集群内部使用)

默认方式,分配一个稳定的IP地址,即VIP,只能在集群内部访问

2》NodePort(对外暴露应用)

在每个节点启用一个端口来暴露服务,可以在集群外部访问,通过NodeIP:NodePort访问
默认的端口范围:30000~32767

3》LoadBalancer(对外暴露应用,适用于公有云)

与NodePort类似,在每个节点启用一个端口来暴露服务。除此之外,K8s请求底层云平台的负载均衡器,把每个[Node IP]:[NodePort]作为后端添加进去

2、ClusterIP

kubernetes 默认就是这种方式,是集群内部访问的方式,外部是无法访问的。其主要用于为集群内 Pod 访 问时,提供的固定访问地址,默认是自动分配地址,可使用 ClusterIP 关键字指定固定 IP

类型为ClusterIP的service,这个service有一个Cluster-IP,其实就一个VIP。具体实现原理依靠kubeproxy组件,通过iptables或是ipvs实现,这种类型的service 只能在集群内访问

在这里插入图片描述

【ClusterIP使用】

创建资源清单ClusterIP:clusterip.yaml

#编写资源清单
[[root@m01 /hzl]# cat clusterip.yaml 
---
kind: Pod
apiVersion: v1
metadata:
  name: nginx
  labels:
    app: hzl
spec:
  containers:
    - name: clusterip-nginx
      image: nginx

---
apiVersion: v1
kind: Service
metadata:
  name: svc-nginx 
spec:
  type: ClusterIP
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx




#创建svc
[root@m01 /hzl]# kubectl apply -f clusterip.yaml 
pod/nginx created
service/svc-nginx created




#查看svc状态
[root@m01 /hzl]# kubectl get svc,pod
NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   8m20s
service/svc-nginx    ClusterIP   10.100.136.166   <none>        80/TCP    53s

NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx                    1/1     Running   0          54s
pod/nginx-6799fc88d8-5z58m   1/1     Running   0          49m



#使用内部ip访问测试:(内部ip)
[root@m01 /hzl]# curl  10.100.136.166 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
.....
....


#使用外部访问:(外部ip)
[root@m01 /hzl]# curl 192.168.15.55
curl: (7) Failed connect to 192.168.15.55:80; 拒绝连接
######################################################################################

案列二
#编写clueterip资源清单
[root@m01 /mnt]# cat clusterip-service.yaml 
kind: Service
apiVersion: v1
metadata: 
  name: my-svc
spec:
  type: ClusterIP
  selector: 
    app: nginx
  ports:
    - port: 80
      targetPort: 80



#创建svc
[root@m01 /mnt]# kubectl apply -f clusterip-service.yaml 
service/my-svc created

[root@m01 /mnt]# kubectl get svc     #查看svc
NAME     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
my-svc   ClusterIP   10.104.124.174   <none>        80/TCP    2m14s



#访问同上

3、NodePort

在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过: NodePort来访问该服务
对于端口的使用,有的场景不只是在集群内部访问,还有在集群外部的,那么ClusterIP就满足不了了,因为他只支持在集群内部访问,对于集群外部的访问,NodePort当然是其中的一种实现方案,如下所示

在这里插入图片描述

【NodePort】

#编写配置清单
[root@m01 /hzl]# cat nodeport.yaml 
---
kind: Pod
apiVersion: v1
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
    - name: nodeport-nginx
      image: nginx

---
apiVersion: v1
kind: Service
metadata:
  name: service-nginx
spec:
  type: NodePort
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30443
  selector:
    app: nginx




#创建svc
[root@m01 /hzl]# kubectl apply -f nodeport.yaml 
pod/nginx created




#查看svc已创建
[root@m01 /hzl]# kubectl get pod,svc
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx                    1/1     Running   0          21s
pod/nginx-6799fc88d8-h2d7z   1/1     Running   0          3m56s

NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP        3m23s
service/service-nginx   NodePort    10.99.159.216   <none>        80:30443/TCP   21s




#测试访问(外部ip)
[root@m01 /hzl]# curl 192.168.15.55:30443
<!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>
..........
......

4、LoadBalancer

LoadBalancer 类型的 service 是可以实现集群外部访问服务的另外一种解决方案。不过并不是所有的 k8s 集 群都会支持,大多是在公有云托管集群中会支持该类型。负载均衡器是异步创建的,关于被提供的负载均衡器的 信息将会通过 Service 的 status.loadBalancer 字段被发布出去

在NodePort的基础上,借助Cloud Provider创建一个外部负载均衡器,并将请求转发到NodePort

在这里插入图片描述

【LoadBalancer使用】

#编写资源清单
[root@m01 /hzl]# cat LoadBalancer.yaml 
---
kind: Pod
apiVersion: v1
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
    - name: loadbalancer-nginx
      image: nginx


---
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx






#创建pod及svc
[root@m01 /hzl]# kubectl apply -f LoadBalancer.yaml 
pod/nginx unchanged
service/loadbalancer-nginx created



#查看pod及svc
[root@m01 /hzl]# kubectl get pod,svc
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx                    1/1     Running   0          51s
pod/nginx-6799fc88d8-wx7x5   1/1     Running   0          18m

NAME                         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
service/kubernetes           ClusterIP      10.96.0.1      <none>        443/TCP        18m
service/loadbalancer-nginx   LoadBalancer   10.111.92.24   <pending>     80:30400/TCP   21s




#测试访问:

5、ExternalName

ExternalName Service 是 Service 的一个特例,它没有选择器,也没有定义任何端口或 Endpoints。它的作用是 返回集群外 Service 的外部别名。它将外部地址经过集群内部的再一次封装(实际上就是集群 DNS 服务器将 CNAME 解析到了外部地址上),实现了集群内部访问即可。例如你们公司的镜像仓库,最开始是用 ip 访问,等到后面域 名下来了再使用域名访问。你不可能去修改每处的引用。但是可以创建一个 ExternalName,首先指向到 ip,等后 面再指向到域名

把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有 Kubernetes 1.7或更高版本的kube-dns才支持

【 ExternalName使用】

#编写资源清单
[root@m01 /hzl]# cat ExternalName.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: externalname
spec:
  type: ExternalName
  externalName: www.baidu.com



#创建svc
[root@m01 /hzl]# kubectl apply -f ExternalName.yaml 
service/externalname created




#查看svc
NAME           TYPE           CLUSTER-IP   EXTERNAL-IP     PORT(S)   AGE
externalname   ExternalName   <none>       www.baidu.com   <none>    28s





#测试:
[root@m01 /hzl]# kubectl run -it test  --rm --image=busybox:1.28.3
If you don't see a command prompt, try pressing enter.
/ # nslookup  externalname    #常看 externalname 相关的网络
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      externalname
Address 1: 112.80.248.75
Address 2: 112.80.248.76
/ # wget  externalname     #在容器内部访问 externalname ,则请求已转发
Connecting to externalname (112.80.248.75:80)
wget: server returned error: HTTP/1.1 403 Forbidden
/ # 



#访问测试的ip
[root@m01 /hzl]# curl 112.80.248.75:80      #访问转发到到百度
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <bod
posted @ 2021-08-06 21:44  ଲ一笑奈&何  阅读(355)  评论(0编辑  收藏  举报