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 的工作方式:
在 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