k8s资源的基本操作
一、Namespace
1、概述
命名空间(namespace)是Kubernetes中的一种资源对象,用于将集群中的资源进行逻辑分组和隔离。它可以看作为一个虚拟集群,将物理集群划分为多个逻辑部分,每个部分都有自己的一组资源(如Pod、Service、ConfigMap等)。
每一个添加到Kubernetes集群的工作负载必须放在一个命名空间中。命名空间为集群中的对象名称赋予作用域。虽然在命名空间中名称必须是唯一的,但是相同的名称可以在不同的命名空间中使用。
2、预定义的k8s命名空间
2.1、default
当创建资源时如果没有明确指定 Namespace,默认就会被创建在这个命名空间中。在创建替代的命名空间之前,该命名空间会充当用户新添加资源的主要目的地,无法删除。
2.2、kube-public
所有的用户(包括未经身份验证的用户)都可以读取该命名空间。 该命名空间主要预留为集群使用,以便某些资源需要在整个集群中可见可读。
2.3、kube-system
kube-system
命名空间专门用于托管Kubernetes系统组件:DNS(如 CoreDNS)、网络插件(如 Flannel 或 Calico)、API 服务器代理、监控系统(如 Prometheus operator)以及其他管理和运维相关的组件。
一般规则是,避免向该命名空间添加普通的工作负载。它一般由系统直接管理,因此具有相对宽松的策略。
2.4、kube-node-lease
v1.13开始引入
用于存储节点租约(Node Lease)对象。节点租约是节点用来向控制面证明自身活跃状态的一种机制。节点租约允许 kubelet 发送心跳, 由此控制面能够检测到节点故障。
3、命名空间基本操作
3.1、查看
3.1.1、查看所有的命名空间
kubectl get ns
3.1.2、查看指定的命名空间
kubectl get ns ns名称
3.1.3、指定输出格式
kubectl get ns ns名称 -o 格式参数
kubernetes支持的格式有很多,比较常见的是
wide
、json
、yaml
yaml格式 |
---|
![]() |
json格式 |
![]() |
wide格式 |
![]() |
3.1.4、查看ns详情
kubectl describe ns ns名称
#查看命名空间default详情
[root@k8s-master ~]# kubectl describe ns default
Name: default
Labels: kubernetes.io/metadata.name=default
Annotations: <none>
Status: Active #Active 命名空间正在使用中 Terminating 正在删除命名空间
No resource quota. #ResourceQuota:针对namespace做的资源限制
No LimitRange resource. #LimitRange:针对namespace中的每个组件做的资源限制
3.2、创建
3.2.1、命令行创建
kubectl create ns dev1
3.2.2、通过yaml资源清单创建
- 编写dev2.yaml资源配置文件
cat dev2.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: dev2
- 通过apply进行创建
kubectl apply -f dev2.yaml
- 通过create进行创建
- 简单修改yaml资源配置文件
cat dev3.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: dev3
kubectl create -f dev3.yaml
- 查看命名空间
kubectl get ns dev1
kubectl get ns dev2
kubectl get ns dev3
3.3、删除
3.3.1、命令式对象配置删除
kubectl delete -f dev3.yaml
3.3.2、命令式对象管理删除
kubectl delete ns dev1 dev2
3.4、资源限额
可以通过Resource Quota来限制Namespace中资源的使用,资源配额是一种控制机制,可以限制Namespace中资源使用量,包括CPU、内存、存储等。
资源限制可以针对Namespace中所有Pod进行限制,也可以针对单个Pod进行限制
3.4.1、配置资源含义
资源名称 | 描述 |
---|---|
limits.cpu |
所有非终止状态的 Pod,其 CPU 限额总量不能超过该值。 |
limits.memory |
所有非终止状态的 Pod,其内存限额总量不能超过该值。 |
requests.cpu |
所有非终止状态的 Pod,其 CPU 需求总量不能超过该值。 |
requests.memory |
所有非终止状态的 Pod,其内存需求总量不能超过该值。 |
hugepages-<size> |
对于所有非终止状态的 Pod,针对指定尺寸的巨页请求总数不能超过此值。 |
cpu |
与 requests.cpu 相同。 |
memory |
与 requests.memory 相同。 |
关于Namespace的资源限额演示将结合下面的Pod来示例
二、Pod
1、概述
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。
Pod(就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。
Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。 Pod 所建模的是特定于应用的 "逻辑主机",其中包含一个或多个应用容器, 这些容器相对紧密地耦合在一起。
除了应用容器,Pod 还可以包含在 Pod 启动期间运行的 Init 容器。 也可以注入临时性容器来调试正在运行的 Pod。
其他的资源对象都是用来支撑或者扩展Pod 对象功能的,比如:
控制器对象是用来管控Pod 对象的
Service 或者Ingress 资源对象是用来暴露Pod 引用对象的
PersistentVolume 资源对象是用来为Pod提供存储
2、Pod结构
依据Pod结构可以看出pod内部可以包含一个或者多个容器,容器类型分为两部分
- 用户容器:用户以容器形式运行的程序,数量可以多可以少
- Pause:Pod根容器,每个pod都会拥有
- 命名空间共享:Pause容器负责初始化并管理Pod级别的Linux命名空间(如网络namespace、PID namespace等)。这意味着Pod内的所有容器都共享相同的网络接口、IP地址、端口范围、主机名以及进程ID命名空间。这样,Pod内部的容器可以通过localhost互相通信,对外则表现为一个统一的服务实体。
- 网络栈和存储卷共享:Pause容器创建了网络栈,其他容器通过加入Pause容器的网络命名空间来共享网络配置,包括IP地址和端口。同时,它也提供了存储卷挂载点,使得Pod内的所有容器可以访问相同的存储卷资源。
- Pod基础设施容器:Pause容器可以被视为Pod的基础设施容器或基础容器,它是Pod的第一个被创建的容器,作为其他容器的“父容器”。由于 Pause 容器的存在,Pod 中的其他容器可以无需直接管理网络和存储资源,而将这部分职责委托给Pause容器。
- 资源隔离与管理:虽然Pod内的容器共享某些资源,但它们在其他资源如CPU、内存上仍然是隔离的。Pause容器帮助实现了这种资源使用的逻辑边界。
- 健康检查代理:由于Pause容器通常是Pod中始终存在的部分,它的状态可以被用来间接判断Pod的整体运行状况。如果Pause容器终止,那么整个Pod会被视为失败。
3、Pod的资源清单
apiVersion: v1 #必选,版本号,例如v1
kind: Pod #必选,资源类型,例如 Pod
metadata: #必选,元数据
name: string #必选,Pod名称
namespace: string #Pod所属的命名空间,默认为"default"
labels: #自定义标签列表
- name: string
spec: #必选,Pod中容器的详细定义
containers: #必选,Pod中容器列表
- name: string #必选,容器名称
image: string #必选,容器的镜像名称
imagePullPolicy: [ Always|Never|IfNotPresent ] #获取镜像的策略
command: [string] #容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] #容器的启动命令参数列表
workingDir: string #容器的工作目录
volumeMounts: #挂载到容器内部的存储卷配置
- name: string #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean #是否为只读模式
ports: #需要暴露的端口库号列表
- name: string #端口的名称
containerPort: int #容器需要监听的端口号
hostPort: int #容器所在主机需要监听的端口号,默认与Container相同
protocol: string #端口协议,支持TCP和UDP,默认TCP
env: #容器运行前需设置的环境变量列表
- name: string #环境变量名称
value: string #环境变量的值
resources: #资源限制和请求的设置
limits: #资源限制的设置
cpu: string #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
memory: string #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
requests: #资源请求的设置
cpu: string #Cpu请求,容器启动的初始可用数量
memory: string #内存请求,容器启动的初始可用数量
lifecycle: #生命周期钩子
postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
livenessProbe: #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器
exec: #对Pod容器内检查方式设置为exec方式
command: [string] #exec方式需要制定的命令或脚本
httpGet: #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
initialDelaySeconds: 0 #容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 0 #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 0 #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
restartPolicy: [Always | Never | OnFailure] #Pod的重启策略
nodeName: <string> #设置NodeName表示将该Pod调度到指定到名称的node节点上
nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上
imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定
- name: string
hostNetwork: false #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
volumes: #在该pod上定义共享存储卷列表
- name: string #共享存储卷名称 (volumes类型有很多种)
emptyDir: {} #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
hostPath: string #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: string #Pod所在宿主机的目录,将被用于同期中mount的目录
secret: #类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
scretname: string
items:
- key: string
path: string
configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string
4、Pod基本操作
4.1、查看
4.1.1、查看k8s集群中系统运行的pod
kubectl get pods -n kube-system
4.1.2、查看指定命名空间下所有的Pod、Services以及Deployments
kubectl get pod,svc,deploy -n <namespcae>
4.1.3、查看某种资源可以配置的一级属性
kubectl explain pod
4.1.4、查看属性的子属性
kubectl explain pod.spec.containers
4.2、创建
4.2.1、命令方式启动
# 命令格式: kubectl create deploy (pod控制器名称) [参数]
[root@k8s-master ~]# kubectl create deploy nginx --image=nginx --port=8081 -n dev1
deployment.apps/nginx created
--image 指定Pod的镜像
--port 指定端口
--namespace 指定namespace
4.2.2、创建yaml配置文件启动
cat nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
namespace: dev2
labels:
chapter: first-app
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name : nginx
image: nginx
ports:
- containerPort: 8081
[root@k8s-master ~]# kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deploy created
4.2.3、直接创建pod(通过yaml资源清单)
cat pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
spec:
containers:
- image: nginx:latest
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
[root@k8s-master ~]# kubectl create -f pod-nginx.yaml
pod/nginx created
4.2.4、直接创建(kubectl run)
kubectl run pod-nginx --image=nginx
4.3、查看创建的pod信息
4.3.1、查看Pod基本信息
kubectl get pods -n dev1
kubectl get pods -n dev2
4.3.2、查看Pod的详细信息
[root@k8s-master ~]# kubectl get pods -n dev1
NAME READY STATUS RESTARTS AGE
nginx-66b77cb96d-bsxg8 1/1 Running 0 12m
[root@k8s-master ~]# kubectl get pods -n dev2
NAME READY STATUS RESTARTS AGE
nginx-deploy-66b77cb96d-v2m9x 1/1 Running 0 108s
[root@k8s-master ~]# kubectl describe pod nginx-66b77cb96d-bsxg8 -n dev1
Name: nginx-66b77cb96d-bsxg8
Namespace: dev1
Priority: 0
Node: k8s-node1/192.168.112.50
Start Time: Mon, 17 Jun 2024 11:38:05 +0800
Labels: app=nginx
pod-template-hash=66b77cb96d
Annotations: <none>
Status: Running
IP: 10.244.1.11
IPs:
IP: 10.244.1.11
Controlled By: ReplicaSet/nginx-66b77cb96d
Containers:
nginx:
Container ID: docker://35405e89a4c95504f24dd51fe4e89d6441f80780d3b54ab9b6c8cefba9a7fd04
Image: nginx
Image ID: docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Port: 8081/TCP
Host Port: 0/TCP
State: Running
Started: Mon, 17 Jun 2024 11:39:04 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-vvb7w (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-vvb7w:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 13m default-scheduler Successfully assigned dev1/nginx-66b77cb96d-bsxg8 to k8s-node1
Normal Pulling 13m kubelet Pulling image "nginx"
Normal Pulled 12m kubelet Successfully pulled image "nginx" in 57.688637974s
Normal Created 12m kubelet Created container nginx
Normal Started 12m kubelet Started container nginx
[root@k8s-master ~]# kubectl describe pod nginx-deploy-66b77cb96d-v2m9x -n dev2
Name: nginx-deploy-66b77cb96d-v2m9x
Namespace: dev2
Priority: 0
Node: k8s-node2/192.168.112.60
Start Time: Mon, 17 Jun 2024 11:48:21 +0800
Labels: app=nginx
pod-template-hash=66b77cb96d
Annotations: <none>
Status: Running
IP: 10.244.2.11
IPs:
IP: 10.244.2.11
Controlled By: ReplicaSet/nginx-deploy-66b77cb96d
Containers:
nginx:
Container ID: docker://d08cd3e2d16ab031c7421d7c484342d8f0381309368e1a8c0a34ccbbec5f61b5
Image: nginx
Image ID: docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Port: 8081/TCP
Host Port: 0/TCP
State: Running
Started: Mon, 17 Jun 2024 11:48:37 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-2hvg8 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-2hvg8:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 4m1s default-scheduler Successfully assigned dev2/nginx-deploy-66b77cb96d-v2m9x to k8s-node2
Normal Pulling 4m1s kubelet Pulling image "nginx"
Normal Pulled 3m46s kubelet Successfully pulled image "nginx" in 15.384979508s
Normal Created 3m46s kubelet Created container nginx
Normal Started 3m46s kubelet Started container nginx
4.4、访问
4.4.1、获取Pod的IP
kubectl get pods -n dev1 -o wide
4.4.2、访问Pod
[root@k8s-master ~]# curl 10.244.1.11
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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.5、删除
4.5.1、直接删除Pod
#命令格式: kubectl delete pod pod名称 -n 名称空间
[root@k8s-master ~]# kubectl delete pod nginx -n dev3
pod "nginx" deleted
4.5.2、删除通过控制器创建的pod
#删除指定Pod
[root@k8s-master ~]# kubectl delete pod nginx-66b77cb96d-ggmsm -n dev1
pod "nginx-66b77cb96d-ggmsm" deleted
#虽然显示删除Pod成功,但是再次查看时发现又创建了一个
[root@k8s-master ~]# kubectl get pods -n dev1
NAME READY STATUS RESTARTS AGE
nginx-66b77cb96d-zpvgn 1/1 Running 0 48s
# 这是因为当前Pod是由Pod控制器创建的,控制器会监控Pod状况,一旦发现Pod死亡,会立即重建。此时要想删除Pod,必须删除Pod控制器
#先查询dev1命名空间下的Pod控制器
[root@k8s-master ~]# kubectl get deploy -n dev1
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 175m
#接下来删除对应的Pod控制器
[root@k8s-master ~]# kubectl delete deploy nginx -n dev1
deployment.apps "nginx" deleted
#稍等片刻,再次查询Pod发现被删除
[root@k8s-master ~]# kubectl get pods -n dev1
No resources found in dev1 namespace.
4.6、资源限制
4.6.1、创建命名空间
[root@k8s-master ~]# kubectl create ns quota-mem-cpu
namespace/quota-mem-cpu created
#查看命名空间
[root@k8s-master ~]# kubectl get ns
4.6.2、创建资源配额对象
cat quota-mem-cpu.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: mem-cpu-demo
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
- apiversion,声明apiserver的版本为v1
- kind,对象,创建资源配额对象
- metadata,版本数据,指定名称
- hard,硬件限制
- requests.cpu: "1",申请一个cpu
- limits.cpu: "2",最大可以使用2个cpu
4.6.3、将命名空间和资源配额对象绑定
kubectl apply -f quota-mem-cpu.yaml --namespace=quota-mem-cpu
4.6.4、查看命名空间对应的资源配额对象信息
kubectl get resourcequota mem-cpu-demo -n quota-mem-cpu -o yaml
ResourceQuota 在 quota-mem-cpu-example 命名空间中设置了如下要求:
- 在该命名空间中所有 Pod 的内存请求总和不能超过 1 GiB。
- 在该命名空间中所有 Pod 的内存限制总和不能超过 2 GiB。
- 在该命名空间中所有 Pod 的 CPU 请求总和不能超过 1 cpu。
- 在该命名空间中所有 Pod 的 CPU 限制总和不能超过 2 cpu。
4.6.5、编写yaml配置文件,创建pod
cat quota-mem-cpu-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: quota-mem-cpu-demo
spec:
containers:
- name: quota-mem-cpu-demo-test
image: nginx
resources:
limits:
memory: "800Mi"
cpu: "800m"
requests:
memory: "600Mi"
cpu: "400m"
kubectl apply -f quota-mem-cpu-pod.yaml -n quota-mem-cpu
- 查看创建在指定命名空间的pod
kubectl get pod -n quota-mem-cpu
4.6.6、再次查看资源配额对象
kubectl get resourcequota mem-cpu-demo -n quota-mem-cpu -o yaml
4.6.7、尝试创建第二个pod
- 编写yaml配置文件
cat quota-mem-cpu-pod-2.yaml
apiVersion: v1
kind: Pod
metadata:
name: quota-mem-cpu-demo-2
spec:
containers:
- name: quota-mem-cpu-demo-test-2
image: redis
resources:
limits:
memory: "1Gi"
cpu: "800m"
requests:
memory: "700Mi"
cpu: "400m"
- 创建pod
kubectl apply -f quota-mem-cpu-pod2.yaml -n quota-mem-cpu
在Error信息中,
requested: requests.memory=700Mi, used: requests.memory=600Mi, limited: requests.memory=1Gi
代表新的内存请求与已经使用的内存请求之和超过了内存请求的配额:
600 MiB + 700 MiB > 1 GiB
三、Label
1、概述
Label是标签的意思,一对 key/value ,被关联到对象上,k8s中的资源对象大都可以打上标签,如Node、Pod、Service 等
一个资源可以绑定任意多个label,k8s 通过 Label 可实现多维度的资源分组管理,后续可通过 Label Selector 查询和筛选拥有某些 Label 的资源对象。同一个资源对象的labels属性的key必须唯一
1.1、示例
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
2、设计目的
标签使用户能够以松散耦合的方式将他们自己的组织结构映射到系统对象,而无需客户端存储这些映射。
服务部署和批处理流水线通常是多维实体(例如,多个分区或部署、多个发行序列、多个层,每层多个微服务)。 管理通常需要交叉操作,这打破了严格的层次表示的封装,特别是由基础设施而不是用户确定的严格的层次结构。
3、常见的标签示例
"release" : "stable"
,"release" : "canary"
"environment" : "dev"
,"environment" : "qa"
,"environment" : "production"
"tier" : "frontend"
,"tier" : "backend"
,"tier" : "cache"
"partition" : "customerA"
,"partition" : "customerB"
"track" : "daily"
,"track" : "weekly"
4、标签的语法
4.1、前缀
- 前缀是可选的;
- 如果指定,前缀必须是 DNS 子域:由点(
.
)分隔的一系列 DNS 标签,总共不超过 253 个字符, 后跟斜杠(/
)。 - 如果省略前缀,则假定标签键对用户是私有的。 向最终用户对象添加标签的自动系统组件(例如
kube-scheduler
、kube-controller-manager
、kube-apiserver
、kubectl
或其他第三方自动化工具)必须指定前缀。
4.2、名称
- 名称段是必需的
- 必须小于等于 63 个字符,以字母数字字符(
[a-z0-9A-Z]
)开头和结尾, 带有破折号(-
),下划线(_
),点(.
)和之间的字母数字。
4.3、有效的标签值
- 必须为 63 个字符或更少(可以为空)
- 除非标签值为空,必须以字母数字字符(
[a-z0-9A-Z]
)开头和结尾 - 包含破折号(
-
)、下划线(_
)、点(.
)和字母或数字
4.3、示例
4.3.1、有 environment: production
和 app: nginx
两个标签的Pod资源清单
apiVersion: v1
kind: Pod
metadata:
name: label-demo
labels:
environment: production
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
5、Label selector(标签选择器)
标签定义完毕之后,还要考虑到标签的选择,这就要使用到Label Selector
,即:
Label用于给某个资源对象定义标识
Label Selector用于查询和筛选拥有某些标签的资源对象
5.1、基于等式的Label selector
允许按标签键和值进行过滤。 匹配对象必须满足所有指定的标签约束,尽管它们也可能具有其他标签。 可接受的运算符有 =
、==
和 !=
三种。 前两个表示相等(并且是同义词),而后者表示不相等。
5.1.1、示例
environment = production
tier != frontend
选择所有包含Label中key="environment"且value="production"的对象
选择所有包括Label中的key="tier"且value不等于"frontend"的对象
apiVersion: v1
kind: Pod
metadata:
name: cuda-test
spec:
containers:
- name: cuda-test
image: "registry.k8s.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1
nodeSelector:
accelerator: nvidia-tesla-p100
Pod 选择带有标签 "
accelerator=nvidia-tesla-p100
"
5.2、基于集合的Label selector
基于集合的标签需求允许你通过一组值来过滤键。 支持三种操作符:
in
、notin
和exists
(只可以用在键标识符上)。
5.2.1、示例
environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
- 第一个示例选择了所有键等于
environment
并且值等于production
或者qa
的资源。 - 第二个示例选择了所有键等于
tier
并且值不等于frontend
或者backend
的资源,以及所有没有tier
键标签的资源。 - 第三个示例选择了所有包含了有
partition
标签的资源;没有校验它的值。 - 第四个示例选择了所有没有
partition
标签的资源;没有校验它的值。
5.3、注意事项
- 对于某些 API 类别(例如 ReplicaSet)而言,两个实例的标签选择算符不得在命名空间内重叠, 否则它们的控制器将互相冲突,无法确定应该存在的副本个数。
- 对于基于等值的和基于集合的条件而言,不存在逻辑或(
||
)操作符。 你要确保你的过滤语句按合适的方式组织。 - 基于等式的Label selector和基于集合的Label selector可以混合使用:
partition in (customerA, customerB),environment!=qa
。
6、基本操作
6.1、使用帮助
kubectl label --help
6.2、为Pod资源打标签
kubectl label pod pod-nginx1 version=1.0 -n dev1
6.3、为Pod资源更新标签
kubectl label pod pod-nginx1 version=2.0 -n dev1 --overwrite
6.4、查看标签
kubectl get pod pod-nginx1 -n dev1 --show-labels
6.5、筛选标签
kubectl get pod -n dev1 -l version=2.0 --show-labels
kubectl get pod -n dev1 -l version!=2.0 --show-labels
6.6、删除标签
kubectl label pod pod-nginx1 version- -n dev1
6.7、配置
6.7.1、创建yaml资源清单
cat label-nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev1
labels:
version: "3.0"
env: "test"
spec:
containers:
- image: nginx:latest
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
kubectl create -f label-nginx-pod.yaml
6.7.2、删除
kubectl delete -f label-nginx-pod.yaml
四、Deployment
1、概述
Deployment 是 Kubernetes 中用于管理 Pod 副本集的控制器,Deployment自动管理关联的ReplicaSet,从而间接控制Pod的数量和状态。它可以控制一组 Pod 的创建、扩缩容和更新等操作。Deployment 支持滚动更新和回滚等功能,可以实现无缝的应用程序版本升级。
2、基本操作
2.1、命令格式
kubectl create deployment NAME --image=image -- [COMMAND] [args...] [options]
- NAME: 要创建的Deployment名称。
- --image=image: 指定容器使用的镜像名称。
- [COMMAND] [args...]: (可选)启动时执行的命令及参数。
- [options]: 创建部署时可配置的额外选项。
2.2、使用帮助
kubectl create deployment --help
2.3、查看deployment信息
kubectl create deploy nginx-deploy --image=nginx --port=8082 --replicas=3 -n dev1
#查看创建的pod
[root@k8s-master ~]# kubectl get pods -n dev1
NAME READY STATUS RESTARTS AGE
nginx-deploy-794c9c67dc-gf9bf 1/1 Running 0 37m
nginx-deploy-794c9c67dc-m2dq5 1/1 Running 0 37m
nginx-deploy-794c9c67dc-xnbnp 1/1 Running 0 37m
#查看deployment信息
[root@k8s-master ~]# kubectl get deploy -n dev1
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deploy 3/3 3 3 43m
# UP-TO-DATE:成功升级的副本数量
# AVAILABLE:可用副本的数量
[root@k8s-master ~]# kubectl get deploy -n dev1 -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deploy 3/3 3 3 58m nginx nginx app=nginx-deploy
2.4、查看deployment的详细信息
[root@k8s-master ~]# kubectl describe deploy nginx-deploy -n dev1
Name: nginx-deploy
Namespace: dev1
CreationTimestamp: Tue, 18 Jun 2024 15:32:30 +0800
Labels: app=nginx-deploy
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=nginx-deploy
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx-deploy
Containers:
nginx:
Image: nginx
Port: 8082/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deploy-794c9c67dc (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 60m deployment-controller Scaled up replica set nginx-deploy-794c9c67dc to 3
2.5、删除
kubectl delete deploy nginx-deploy -n dev1
2.6、配置
2.6.1、创建yaml资源清单
cat deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: dev1
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
protocol: TCP
2.6.2、创建
kubectl create -f deploy-nginx.yaml
2.6.3、删除
kubectl delete -f deploy-nginx.yaml
2.7、扩缩容(增加减少pod副本数)
2.7.1、通过yaml资源清单修改副本数
cat deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: dev1
spec:
replicas: 5
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
protocol: TCP
#apply命令执行yaml文件,create执行一次,再执行就会报错复
[root@k8s-master ~]# kubectl apply -f deploy-nginx.yaml
deployment.apps/nginx created
#查看pod个数
[root@k8s-master ~]# kubectl get pods -n dev1
#查看deployment控制器详细信息
kubectl describe deploy nginx -n dev1
#缩容对应的修改资源清单里的replicas个数然后kubectl apply -f xxx.yaml即可
2.7.2、edit deployment实现在线更新
[root@k8s-master ~]# kubectl edit deploy nginx -n dev1
deployment.apps/nginx edited
2.7.3、scale deployment实现扩缩容
命令格式
kubectl scale deploy deploy名称 --replicas=pod数量 -n 命名空间
#变更pod数量为5个
kubectl scale deploy nginx --replicas=5 -n dev1
#查看pod数量
kubectl get pods -n dev1
五、Service
1、概述
在kubernetes中,pod是应用程序的载体,我们可以通过pod的ip来访问应用程序。但是却存在以下两个问题:
- Pod IP 会随着Pod的重建产生变化
- Pod IP 仅仅是集群内可见的虚拟IP,外部无法访问
为了解决这个问题,kubernetes提供了Service资源,Service会对提供同一个服务的多个pod进行聚合,并且提供一个统一的入口地址。通过访问Service的入口地址就能访问到后面的pod服务。
Service可以看作是一组同类Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。
2、基本操作
2.1、创建集群内部可以访问的Service
#暴露Service
[root@k8s-master ~]# kubectl expose deploy nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev1
service/svc-nginx1 exposed
#查看service
[root@k8s-master ~]# kubectl get svc svc-nginx1 -n dev1 -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx1 ClusterIP 172.16.32.152 <none> 80/TCP 72s app=nginx
# 这里产生了一个CLUSTER-IP,这就是service的IP,在Service的生命周期中,这个地址是不会变动的
# 可以通过这个IP访问当前service对应的POD
[root@k8s-master ~]# curl 172.16.32.152
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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>
2.2、创建集群外部也可以访问的Service
# 上面创建的Service的type类型为ClusterIP,这个ip地址只用集群内部可访问
# 如果需要创建外部也可以访问的Service,需要修改type为NodePort
[root@k8s-master ~]# kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 -n dev1
service/svc-nginx2 exposed
# 此时查看,会发现出现了NodePort类型的Service,而且有一对Port(80:30571/TCP)
[root@k8s-master ~]# kubectl get svc svc-nginx2 -n dev1 -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx2 NodePort 172.16.140.61 <none> 80:30571/TCP 2m57s app=nginx
#接下来就可以通过集群外的主机访问 节点ip:30571访问服务了
例:http://192.168.112.40:30571
2.3、删除Service
[root@k8s-master ~]# kubectl delete svc svc-nginx1 -n dev1
service "svc-nginx1" deleted
2.4、配置
2.4.1、创建yaml资源清单
#ClusterIP类型的
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: dev1
spec:
clusterIP: 172.16.100.100 #固定svc的内网ip
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: ClusterIP
#NodePort类型的
apiVersion: v1
kind: Service
metadata:
name: svc-nginx1
namespace: dev1
spec:
clusterIP: 172.16.200.200 #固定svc的内网ip
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: nginx
type: NodePort
2.4.2、创建
kubectl apply -f svc-nginx.yaml
kubectl apply -f svc-nginx2.yaml
2.4.3、删除
kubectl delete -f svc-nginx.yaml
kubectl delete -f svc-nginx2.yaml
至此本篇完成,仅涉及最常见的k8s资源的基本操作
更加深入的我会继续学习