目录
一、创建Kubernetes对象YAML文件必备字段
在Kubernetes创建对象,我们通常是通过一个声明式的清单来创建。Kubernetes 对象是持久化的实体。是一种“意向表达”(Record of Intent)。一旦创建该对象, Kubernetes 系统将不断工作以确保该对象存在。
我们在Kubernetes中创建对象,本质上是在通知 Kubernetes 系统,我们想要的集群工作负载状态看起来应该是什么样子的, 也就是 Kubernetes 集群所谓的期望状态(Desired State)。
1.apiVersion
创建该对象所使用的 Kubernetes API 的版本,比如 apps/v1,networking.k8s.io/v1等。
2.kind
想要创建的对象的类别,比如 Deployment,DaemonSet等。
3.metadata
帮助唯一标识对象的一些数据,包括一个 name 字符串(必需字段)、UID(自动生成) 和可选的 namespace。
4.spec
我们所期望的该对象的状态,对每个 Kubernetes 对象而言,其 spec都不同
具体的可以参考官方文档:https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/
apiVersion: v1 # Kubernetes API 的版本,对于 Pod 来说,通常是 v1
kind: Pod # 要创建的对象的类别,这里是 Pod
metadata:
name: my-pod # 对象的名称,在命名空间中必须是唯一的
namespace: default # 命名空间,如果省略,则默认为 default
# UID 是由 Kubernetes 系统自动生成的,不需要在清单文件中指定
spec:
containers: # Pod 规格中定义了容器的列表
- name: my-container # 容器的名称
image: nginx:1.19.2 # 容器使用的镜像及其标签
# 其他容器配置,如端口、环境变量等...
二、YAML格式基本规范
YAML(YAML Ain't Markup Language)是一种用于数据序列化的格式,常用于配置文件、数据交换等场景。YAML的目标是易于阅读和书写,同时也易于与编程语言交互。YAML文件通常以.yaml或.yml作为文件扩展名。
1.结构表示
- 使用缩进表示层级关系,通常使用两个或四个空格的缩进,但必须在同一文档中保持一致。
- 不使用制表符(Tab)进行缩进。
2.键值对
- 使用冒号加空格: 来分隔键和值。
- 键是唯一的,通常是字符串。
3.列表(数组)
- 使用短横线加空格- 来表示列表项。
- 列表项通常会缩进,表示属于上一级的列表。
4.字典(映射)
- 字典是一组键值对的集合。
- 字典的每个键值对都会缩进,表示属于上一级的字典。
5.数据类型
- 支持字符串、布尔值、整数、浮点数、null、时间、日期等数据类型。
- 字符串通常不需要引号,但如果包含特殊字符,则需要用单引号或双引号括起来。
- 使用true/false表示布尔值。
- 使用null表示空值。
6.注释
使用井号 # 开头表示注释,注释内容不会被解析。
7.多文档支持
使用三个短横线---来分隔文件中的多个文档。
8.复杂结构
字典和列表可以嵌套使用,形成复杂的结构。
9.示例
# 这是一个注释
person: # 字典的开始
name: John Doe # 字符串
age: 30 # 整数
married: true # 布尔值
children: # 列表的开始
- name: Jane Doe
age: 10
- name: Doe Junior
age: 5
三、YAML文件编写
YAML文件通常用于配置管理系统、部署工具、持续集成和持续部署(CI/CD)等场景,它们易于阅读和编辑。在Kubernetes中,YAML文件被广泛用于定义资源对象,如Deployments、Services、Pods等。
1.YAML文件的组成
YAML文件由apiVersion、kind、metadata、spec、status五部分组成,前四部分较常用。
kubectl explain deployment
KIND: Deployment
VERSION: apps/v1
DESCRIPTION:
Deployment enables declarative updates for Pods and ReplicaSets.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Specification of the desired behavior of the Deployment.
status <Object>
Most recently observed status of the Deployment.
2.生成YAML文件框架
2.1--dry-run命令
kubectl create deployment jumpoint-web --image=nginx:latest --port=80 --replicas=2 --namespace=jumpoint-ns --dry-run=client --output=yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: jumpoint-web
name: jumpoint-web
namespace: jumpoint-ns
spec:
replicas: 2
selector:
matchLabels:
app: jumpoint-web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: jumpoint-web
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
resources: {}
status: {}
若要定义Pod等资源对象,生成YAML文件的方法类似。
2.2通过explain获取YAML文件字段的含义
#若要查看metadata.labels字段的含义
kubectl explain deployment.metadata.labels
KIND: Deployment
VERSION: apps/v1
FIELD: labels <map[string]string>
DESCRIPTION:
Map of string keys and values that can be used to organize and categorize
(scope and select) objects. May match selectors of replication controllers
and services. More info: http://kubernetes.io/docs/user-guide/labels
#若要查看spec.selector.matchLabels字段的含义(其它字段含义查询方式类似)
kubectl explain deployment.spec.selector.matchLabels
KIND: Deployment
VERSION: apps/v1
FIELD: matchLabels <map[string]string>
DESCRIPTION:
matchLabels is a map of {key,value} pairs. A single {key,value} in the
matchLabels map is equivalent to an element of matchExpressions, whose key
field is "key", the operator is "In", and the values array contains only
"value". The requirements are ANDed.
#若要查看deployment.spec.template.spec.containers字段下还有哪些字段可用,有时可能要根据实际需求添加一些字段(上边生成的YAML文件略简单)
kubectl explain deployment.spec.template.spec.containers
KIND: Deployment
VERSION: apps/v1
RESOURCE: containers <[]Object>
DESCRIPTION:
List of containers belonging to the pod. Containers cannot currently be
added or removed. There must be at least one container in a Pod. Cannot be
updated.
A single application container that you want to run within a pod.
FIELDS:
...
imagePullPolicy <string>
Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always
if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
More info:
https://kubernetes.io/docs/concepts/containers/images#updating-images
Possible enum values:
- `"Always"` means that kubelet always attempts to pull the latest image.
Container will fail If the pull fails.
- `"IfNotPresent"` means that kubelet pulls if the image isn't present on
disk. Container will fail if the image isn't present and the pull fails.
- `"Never"` means that kubelet never pulls an image, but only uses a local
image. Container will fail if the image isn't present
...
3.调整YAML文件内容
精简不用的字段、修改字段的内容、添加镜像的拉取策略等,将其保存到nginx-deployment.yaml文件中。
3.1Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: jumpoint-web-deployment-label
name: jumpoint-web
namespace: jumpoint-ns
spec:
replicas: 2
selector:
matchLabels:
app: jumpoint-web-pod-label
template:
metadata:
labels:
app: jumpoint-web-pod-label
spec:
containers:
- image: nginx:latest
name: jumpoint-web-container-name
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
name: http
#使用nginx-deployment.yaml文件创建Deployment资源对象。
kubectl create namespace jumpoint-ns
kubectl apply -f nginx-deployment.yaml
kubectl get deployments -n jumpoint-ns
kubectl get pods -n jumpoint-ns -o wide
kubectl describe deployment -n jumpoint-ns jumpoint-web
注意:YAML文件中spec.selector.matchLabels必须与spec.template.metadata.labels一致,若不一致,如spec.selector.matchLabels=jumpoint-web-pod-selector,spec.template.metadata.labels=jumpoint-web-pod-label,会遇到如下报错:
kubectl apply -f nginx-deployment.yaml
The Deployment "jumpoint-web" is invalid: spec.template.metadata.labels: Invalid value: map[string]string{"app":"jumpoint-web-pod-label"}: `selector` does not match template `labels`
上述报错的原因也比较好理解,在Kubernetes中,Deployment标签、Pod选择器,和Pod标签之间的关系是为了确保Deployment能够正确地管理其下属的Pod。以下是这三个标签作用的说明
- Deployment标签(metadata.labels)
这些标签是附加在Deployment资源本身上的,用于识别和组织资源,但并不直接影响Deployment如何选择和管理Pod。通常,这些标签用于帮助用户通过标签选择器(如kubectl get deployments -l app=jumpoint-web-deployment-label)找到特定的Deployment。
- Pod选择器 (spec.selector.matchLabels)
这个选择器定义了Deployment如何找到它应该管理的Pod。Deployment会监视并管理所有与这个选择器匹配的Pod。因此,该选择器需要与创建的Pod的标签相匹配,以便Deployment可以“认领”并管理这些Pod。
- Pod标签 (spec.template.metadata.labels)
这些标签是在Pod模板中定义的,将被附加到由Deployment创建的每个Pod实例上。该标签必须与Deployment的Pod选择器匹配,其会告诉Deployment哪些Pod属于它。如果这些标签不匹配,Deployment将无法找到(也就是无法选择)它应该管理的Pod,导致它不会执行任何更新或回滚操作。
简而言之,spec.selector.matchLabels必须与spec.template.metadata.labels一致,因为这样设置后,Deployment才能正确地识别出它应该管理的Pod。而metadata.labels在Deployment上的标签主要是为了方便用户对Deployment进行分类和查询,并不直接参与Pod的选择过程。
3.2Service
cat nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-web-service-label
name: nginx-web-service
namespace: jumpoint-ns
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
nodePort: 30001
selector:
app: jumpoint-web-pod-label
Service的spec.selector,会匹配Pod的spec.template.metadata.labels,并将网络流量路由到匹配到的Pod上。
4.Deployment Workload部署
下面开始部署一个完整的Deployment工作负载(创建NameSpace---->部署Deployment---->创建Service)
cat nginx-deployment-v2.yaml
apiVersion: v1
kind: Namespace
metadata:
name: jumpoint-ns-v2
labels:
app: jumpoint-ns-v2-namespace-label
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: jumpoint-web-deployment-label
name: jumpoint-web
namespace: jumpoint-ns-v2
spec:
replicas: 2
selector:
matchLabels:
app: jumpoint-web-pod-label
template:
metadata:
labels:
app: jumpoint-web-pod-label
spec:
containers:
- image: nginx:latest
name: jumpoint-web-container-name
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
name: http
---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-web-service-label
name: nginx-web-service
namespace: jumpoint-ns-v2
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
nodePort: 30004
selector:
app: jumpoint-web-pod-label
kubectl apply -f nginx-deployment-v2.yaml
5.Kubectl命令行使用
kubectl get deployment -n jumpoint-ns-v2
kubectl get pods -n jumpoint-ns-v2 -o wide
kubectl get svc -n jumpoint-ns-v2
kubectl get ep -n jumpoint-ns-v2