05-K8S Basic-Pod资源管理(Pod网络、Labels)
一、Pod资源管理
1.1、什么是pod
- 在一个pod中通常只能运行主容器,其他容器是为了辅助主容器的任何而设定。通常辅助容器称之为边车(side car)。
- 多个容器在同一pod中使用IPC pod相互通讯
- 一个pod中运行的多个容器可以通过localhost彼此找到
- 每个容器都继承了pod的名称
- 每个pod在平面共享网络空间中都有一个ip地址
- 在一个pod中,容器共享卷
1.2、k8s网络
- Node Network : 真正与外界网络通讯的接口
- Service Network : 进会出现在iptable或ipv4规则中,都不会被配置到网络接口中,因此没有办法ping,仅用于规则当中用于路径和接受调度请求转发给service请求流量
- Pod Network : 内部网络,pod地址也是被动态分配的网络地址,各个pod之间无论运行在哪个node节点上,pod之间可以直接通讯的,但是pod是动态的,随之有可能被pod控制器所重建,也有可能被用户误删除而重建节点,地址会发生变化,所以pod和pod之前通过ip地址通讯不是理想的状态,应该借助于service地址进行通讯。
- 当资源运行在k8s上,并响应用户固定地址的请求时,必须将地址映射到service上,哪怕只有一个pod,service主要表现为iptables和ipvs规则,所以客户端访问这组资源时要先到service,service调度或反带给后端pod,但是每一次请求都要经service进行动态转发,这是没办法避免的资源消耗,必须有一个机制帮助我们实现服务注册和服务发现机制,service就是帮助我们将服务注册到k8s之上的服务总线,dns服务,动态注册和更新的dns服务即CoreDNS
# 问题思考:运行一个pods,地址在10.244.0.0/16网络中,如何让集群外部进行访问?
1、Service : NodePort类型的Service, 通过集群中各个主机节点都打开同一个端口,把用户的请求映射给Pods,使其任何节点的这个端口都可以访问到此Pods,端口是随机的一般在30000~32767范围。(kube-proxy生成对应的iptable及Lvs规则实现的,这些都是四层的调度,四层是不能卸载https协议的。)。
由于被映射到宿主机的端口是随机的,所以不得不再在外面使用一个负载均衡器。如haproxy、nginx,将用户的请求反代至每一个物理节点上的Service映射的随机端口上,再到后端pods。
思考一个问题:我们怎么知道Service映射到节点的端口是什么呢?随机的范围30000~32767
因此,就得思考在k8s集群之外的负载均衡器上按需创建,以触发器触发的方式按需检测自动创建调度规则呢?
此时就得上云计算环境了,LBaaS负载均衡级服务,软件的方式。自动检测生成负载均衡的调度功能、调度规则,当检测Service消亡时也会联动被删除,以实现用户访问的一直都是标准的端口。
2、hostPort : Pods一定是运行在集群中的某一个节点上的,所以,Pods运行在哪个节点上,就使用哪个节点的端口访问,其它未运行Pods的节点不可以访问,即单一端口映射。
3、hostNetwork : pod资源的地址就时node节点的地址即监听宿主机的名称空间,Pods直接使用节点的网络,仅通过此运行Pods的节点进行访问其Pods监听的端口,其它未运行Pods的节点不可以访问。
Service → NodePort
二、标签Label
2.1、标签介绍
-
需求:Pods是动态的,必要时都会将Pod进行重建,所以我们引入了Service来固定接入用户的请求,同时又使用Pod Controller以便在Pod出现故障时得以重建,所以需求就是Service、Pod Controller是如何识别、过滤哪些Pod是当前Service、Pod Controller所管理的Pod,所以就引入了 Label标签、Label Selector标签选择器。
-
补充:同一资源类型下,不允许同一资源进行同名。如果想在k8s上跑一台测试的LNMP及生产的LNMP就需要运行在不同的名称空间下,Pod是名称空间级别的资源,所以可以将同名称的Pod创建在不同的NameSpace下。
-
标签就是“键值”类型的对象,它们可用于资源创建时直接指定,也可以随时按需添加活动对象,而后即可由标签选择器进行匹配度检查从而完成资源挑选。
- 一个对象可拥有不止一个标签,而同一个标签也可被添加至多个资源上
- 实践中,可以为资源附加多个不同维度的标签以实现灵活的资源分组管理功能
- 例如版本标签、环境标签、分层标签等,用于交叉标识同一资源所属的不同版本,环境及架构层级等
- 标签中的键值名称通常由前缀和键名组成,其中键前缀可选,其格式如“KEY_PREFIX/KEY_NAME”
- 键名至多使用63个字符,可使用字母、数字、连接号(-),下划线(_),点号(.)等字符,且只能以字母或数字开头
- 键前缀必须为DNS子域名格式,且不能超过253个字符。省略键前缀时,键将被视为用户的私有资源,不过k8s系统组件或第三方组件会自动为用户资源添加的键必须使用键前缀,而“kubernetes.io/”前缀于kubernetes的核心组件使用
- 标签中的键值必须不能多余63个字符,它要么为空,要么是以字母或数字开头及结尾,且中间仅使用了字母、数字、连接号(-)、下划线(_)、或点好(.)、等字符的数据
2.2、标签示图
三、标签选择器(Label Selector)
3.1、标签选择器介绍
- 标签选择器用于表达式标签的查询条件或选择标准,kubernetesAPI目前支持两种选择器
- 基于等值关系(equuality-based)
- 操作符有=、==、!=三种,其中前两个意义相同,都表示"等值"关系,最后一个表示”不等“关系
- 基于集合关系(set-based)
- KEY in (value1,value2)
- KEY not in (VALUE1,VALUE2,...)
- KEY : 所有存在键名标签的资源
- !KEY : 所有不存在此键名标签的资源
- 基于等值关系(equuality-based)
- 使用标签选择器时还将遵循以下逻辑
- 同时指定的多个选择器之间的逻辑关系为 ”与“ 操作
- 使用空值的标签选择器意味着每个资源对象都将被选中
- 空的标签选择器将无法选出任何资源
3.2、定义标签选择器的方式
- kubernetes的诸多资源对象必须以标签选择器的方式关联到pod资源对象,例如Service、Deployment和ReplicaSet类型的资源等,它们在apec字段中嵌套使用嵌套"selector"字段,通过“matchlables” 来指定标签选择器,有的甚至还支持使用“matchExperssions” 构造父爱的标签选择机制。
matchLables
: 通过直接给定键值对指定标签选择器matchxperssions
: 基本表达式指定的标签选择器列表,每个选择器形如 “key:KEY_NAME, operator:OPERATOR, values: [VALUE1, BALUE2,.....]” 选择器列表间为“逻辑与”关系- 使用in 或 Not in 操作符时,其values非必须为飞控字符串列表,而使用Exists 或 DoseNotExist时,其value必须为空
四、简单的标签及标签选择器使用
4.1、声明式apply常见pod指定pod的标签
1、查看已运行的pod的标签信息
~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
app="对应的控制器名称" pod-template-hash(pod模块的hash值)= pod模板的哈希指纹信息
myapp-5c6976696c-8kpqh 1/1 Running 0 45h app=myapp,pod-template-hash=5c6976696c
myapp-5c6976696c-sxt79 1/1 Running 0 45h app=myapp,pod-template-hash=5c6976696c
nginx-dep-b4c55647f-nf7pt 1/1 Running 0 47h app=nginx-dep,pod-template-hash=b4c55647f
nginx-deplo-57c48cb848-ppgnf 1/1 Running 0 2d app=nginx-deplo,pod-template-hash=57c48cb848
nginx-deplo1-69dbc7b5bc-dzr5s 1/1 Running 0 47h app=nginx-deplo1,pod-template-hash=69dbc7b5bc
nginx-deploy-66ff98548d-gjnn8 1/1 Running 0 2d3h pod-template-hash=66ff98548d,run=nginx-deploy
ngx-dep-d554574bd-mg7jg 1/1 Running 0 46h app=ngx-dep,pod-template-hash=d554574bd
# 查看之前再prod名称空间下创建的pod资源标签
basic]# kubectl get pods -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 1 26h <none>
2、定义一个YAML pod资源配置并将其定义标签
~]# cat mainfests/basic/pod-demo-2.yaml
#pod所属的群组
apiVersion: v1
#资源类型为pod
kind: Pod
#元数据
metadata:
#pod名称
name: pod-demo
#pod所属的名称空间,如果不指定可在apply时使用-n选项
namespace: prod
#定义pod的标签
labels:
app: pod-demo
rel: stable
#定义pod的属性
spec:
#容器
containers:
#第一个容器的名称
- name: myapp
#这个容器使用的镜像文件
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
#第二个容器的名称
- name: bbox
image: busybox:latest
imagePullPolicy: IfNotPresent
#定义这个容器启动运行的命令
command: ["/bin/sh","-c","sleep 86400"]
3、删除指定名称空间下的pod
~]# kubectl get pods -n prod
NAME READY STATUS RESTARTS AGE
pod-demo 2/2 Running 0 16h
~]# kubectl delete pods -n prod pod-demo
pod "pod-demo" deleted
4、使用声明式apply指定资源文件创建pod
basic]# kubectl apply -f pod-demo-2.yaml
pod/pod-demo created
5、查看创建pod的标签
basic]# kubectl get pods -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 0 88s app=pod-demo,rel=stable
4.2、kubctl label专门管理标签以及指定标签显示
1、查看kubectl label 命令的帮助文档
~]# kubectl label -h
Usage: #向哪个资源上打什么标签
kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]
Examples:
# Update pod 'foo' with the label 'unhealthy' and the value 'true'.
kubectl label pods foo unhealthy=true
# Update pod 'foo' with the label 'status' and the value 'unhealthy', overwriting any existing value.
kubectl label --overwrite pods foo status=unhealthy
# Update all pods in the namespace
kubectl label pods --all status=unhealthy
# Update a pod identified by the type and name in "pod.json"
kubectl label -f pod.json status=unhealthy
# Update pod 'foo' only if the resource is unchanged from version 1.
kubectl label pods foo status=unhealthy --resource-version=1
# Update pod 'foo' by removing a label named 'bar' if it exists.
# Does not require the --overwrite flag.
kubectl label pods foo bar-
2、将之前创建的pod资源上添加标签
~]# kubectl get pods -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 0 6m57s app=pod-demo,rel=stable
~]# kubectl label pods pod-demo -n prod tier=frontend
pod/pod-demo labeled
~]# kubectl get pods -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 0 8m9s app=pod-demo,rel=stable,tier=frontend
3、在已经有的标签key上直接打标签会报错
~]# kubectl label pods pod-demo -n prod app=frontend
error: 'app' already has a value (pod-demo), and --overwrite is false
4、覆盖之前已有的标签(必须使用--overwrite=true即允许覆盖之前已经存在的标签)
~]# kubectl label pods pod-demo -n prod --overwrite=true app=myapp
pod/pod-demo labeled
~]# kubectl get pods -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 0 10m app=myapp,rel=stable,tier=frontend
5、删除已有的表标签
~]# kubectl label pods pod-demo -n prod rel- #使用标签key + -号意思为删除此标签
pod/pod-demo labeled
~]# kubectl get pods -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-demo 2/2 Running 0 11m app=myapp,tier=frontend
6、kubectl get 选项指定根据标签显示资源
-L : 只显示这个资源上指定的标签
-l : 选择器可是使用等值或不等值选择式的标签 '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)
#等值的标签选择器
~]# kubectl get pods --show-labels -l app=myapp
NAME READY STATUS RESTARTS AGE LABELS
myapp-5c6976696c-8kpqh 1/1 Running 0 46h app=myapp,pod-template-hash=5c6976696c
myapp-5c6976696c-sxt79 1/1 Running 0 46h app=myapp,pod-template-hash=5c6976696c
#不等值选择器
~]# kubectl get pods --show-labels -l app!=myapp
NAME READY STATUS RESTARTS AGE LABELS
nginx-dep-b4c55647f-nf7pt 1/1 Running 0 2d1h app=nginx-dep,pod-template-hash=b4c55647f
nginx-deplo-57c48cb848-ppgnf 1/1 Running 0 2d1h app=nginx-deplo,pod-template-hash=57c48cb848
nginx-deplo1-69dbc7b5bc-dzr5s 1/1 Running 0 2d1h app=nginx-deplo1,pod-template-hash=69dbc7b5bc
nginx-deploy-66ff98548d-gjnn8 1/1 Running 0 2d4h pod-template-hash=66ff98548d,run=nginx-deploy
ngx-dep-d554574bd-mg7jg 1/1 Running 0 47h app=ngx-dep,pod-template-hash=d554574bd
#列表选择器
~]# kubectl get pods --show-labels -l "app in (myapp,ngx-dep)"
NAME READY STATUS RESTARTS AGE LABELS
myapp-5c6976696c-8kpqh 1/1 Running 0 47h app=myapp,pod-template-hash=5c6976696c
myapp-5c6976696c-sxt79 1/1 Running 0 47h app=myapp,pod-template-hash=5c6976696c
ngx-dep-d554574bd-mg7jg 1/1 Running 0 47h app=ngx-dep,pod-template-hash=d554574bd
~]# kubectl get pods -l "app in (myapp,ngx-dep)" -L app
NAME READY STATUS RESTARTS AGE APP
myapp-5c6976696c-8kpqh 1/1 Running 0 47h myapp
myapp-5c6976696c-sxt79 1/1 Running 0 47h myapp
ngx-dep-d554574bd-mg7jg 1/1 Running 0 47h ngx-dep
~]# kubectl get pods -l "app notin (myapp,ngx-dep)" -L app
NAME READY STATUS RESTARTS AGE APP
nginx-dep-b4c55647f-nf7pt 1/1 Running 0 2d1h nginx-dep
nginx-deplo-57c48cb848-ppgnf 1/1 Running 0 2d1h nginx-deplo
~]# kubectl get pods -l "app" -L app
~]# kubectl get pods -l '!app' -L app
五、资源注解(annotation)
5.1、资源注解介绍
- 注解也是"键值"类型的数据,不过它不能用于标签及挑选kubernetes对象,仅用于为资源提供”元数据信息“
- 注解中的元数据不受字符数量的限制,它可大可小,可以为结构化或非结构化形式,也支持使用标签中禁止使用的其他字符
- 在kubernetes的新版中(Alpha或Beta阶段)为某资源引入新字段时,常以注解方式以避免其增删等变动给用户带去的困扰,一旦确定支持使用它们,这些新增字段再引入到资源中淘汰相关的注解
5.2、kubectl annotate管理资源的注解
1、查看命令的帮助
basic]# kubectl explain pods.metadata.annotations
~]# kubectl annotate -h
Usage:
kubectl annotate [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]
3、将之前创建的pod资源上添加资源注解
~]# kubectl get pods -n prod
~]# kubectl delete -f mainfests/basic/pod-demo-2.yaml
pod "pod-demo" deleted
4、重新构建资源并指定资源注解
basic]# cat pod-demo-2.yaml
#pod所属的群组
apiVersion: v1
#资源类型为pod
kind: Pod
#元数据
metadata:
#pod名称
name: pod-demo
#pod所属的名称空间,如果不指定可在apply时使用-n选项
namespace: prod
#定义pod的标签
labels:
app: pod-demo
rel: stable
#定义资源注解
annotations:
zhe.dai/project: hellow world
#定义pod的属性
spec:
#容器
containers:
#第一个容器的名称
- name: myapp
#这个容器使用的镜像文件
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
#第二个容器的名称
- name: bbox
image: busybox:latest
imagePullPolicy: IfNotPresent
#定义这个容器启动运行的命令
command: ["/bin/sh","-c","sleep 86400"]
5、创建pod
basic]# kubectl apply -f pod-demo-2.yaml
pod/pod-demo created
6、查看pod的资源注解信息
basic]# kubectl describe pods pod-demo -n prod
Name: pod-demo
Namespace: prod
Priority: 0
Node: 192.168.1.185/192.168.1.185
Start Time: Wed, 19 Feb 2020 17:14:38 +0800
Labels: app=pod-demo
rel=stable
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"zhe.dai/project":"hellow world"},"labels":{"app":"pod-demo","rel":"stable"},"n...
zhe.dai/project: hellow world
Status: Running
IP: 192.168.1.221
# 理解 : 为什么当使用声明时apply方式创建资源后,对其yaml文件继续修改后,还会重新读取新的配置,其实本质上是将配置信息存放在参数注解中,当yaml更新时就会做一个对比,当发生改变时重新apply一次,类似于补丁机制。
向往的地方很远,喜欢的东西很贵,这就是我努力的目标。