在编写 YAML 文件时,常用的技巧和最佳实践
- 缩进和对齐:使用正确的缩进和对齐格式,以提高文件的可读性。建议使用两个空格或四个空格作为缩进,注意不要按tab键。以确保在相同层级的键值对或列表项目之间保持一致的对齐。
- 使用注释:在 YAML 文件中使用注释可以提供额外的说明和文档,使其他人更容易理解和阅读你的配置。使用 # 符号来添加单行注释,或使用 | 或 > 标记来添加多行注释。
- 大小写敏感
下面以pod入门yaml编写技巧为例,慢慢过度到namespace,deployment,statefulset等编写
通过kubectl explain查看定义资源包含哪些字段
只看常用字段
查看pod字段定义
[root@pengfei-master1 pod]# kubectl explain pod
KIND: Pod
VERSION: v1
DESCRIPTION:
Pod is a collection of containers that can run on a host. This resource is
created by clients and scheduled onto hosts.
#Pod是可以在主机上运行的容器的集合。此资源是由客户端创建并调度到主机上
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
#APIVersion定义了对象,代表了一个版本,VERSION已经给出了具体版本,可以直接使用
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
#Kind是字符串类型的值,代表了要创建的资源。服务器可以从客户端提交的请求推断出这个资源
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
#metadata是对象,定义元数据属性信息的
spec <Object>
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
#spec定义Pod的规格,里面包含容器的信息
status <Object>
Most recently observed status of the pod. This data may not be up to date.
Populated by the system. Read-only. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
#status表示状态,这个不可以修改,定义pod的时候也不需要定义这个字段
字段注释:
apiVersion定义了对象,代表了一个版本,VERSION已经给出了具体版本,可以直接使用
Kind是字符串类型的值,代表了要创建的资源。服务器可以从客户端提交的请求推断出这个资源
metadata是对象,定义元数据属性信息的 spec定义Pod的规格,里面包含容器的信息
status表示状态,这个不可以修改,定义pod的时候也不需要定义这个字段
查看pod.metadata字段定义
[root@pengfei-master1 pod]# kubectl explain pod.metadata
KIND: Pod
VERSION: v1
RESOURCE: metadata <Object>
# metadata是对象<Object>,下面可以有多个字段
DESCRIPTION:
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md
ObjectMeta is metadata that all persisted resources must have, which
includes all objects users must create.
FIELDS:
annotations <map[string]string>
Annotations is an unstructured key value map stored with a resource that
may be set by external tools to store and retrieve arbitrary metadata. They
are not queryable and should be preserved when modifying objects. More
info: http://kubernetes.io/docs/user-guide/annotations
#annotations是注解,map类型表示对应的值是key-value键值对,<string,string>表示 key和value都是String类型的
......
labels <map[string]string> #创建的资源具有的标签
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
#labels是标签,labels是map类型,map类型表示对应的值是key-value键值对,<string,string>表示 key和value都是String类型的
......
name <string> #创建的资源的名字
Name must be unique within a namespace. Is required when creating
resources, although some resources may allow a client to request the
generation of an appropriate name automatically. Name is primarily intended
for creation idempotence and configuration definition. Cannot be updated.
More info: http://kubernetes.io/docs/user-guide/identifiers#names
......
namespace <string> #创建的资源所属的名称空间,namespaces划分了一个空间,在同一个namesace下的资源名字是唯一的,默认的名称空间是default
Namespace defines the space within which each name must be unique. An empty
namespace is equivalent to the "default" namespace, but "default" is the
canonical representation. Not all objects are required to be scoped to a
namespace - the value of this field for those objects will be empty.
Must be a DNS_LABEL. Cannot be updated. More info:
http://kubernetes.io/docs/user-guide/namespaces
字段注释:
annotations是注解,map类型表示对应的值是key-value键值对,<string,string>表示 key和value都是String类型的
labels创建的资源具有的标签,labels是map类型,map类型表示对应的值是key-value键值对,<string,string>表示 key和value都是String类型的
name创建的资源的名字
namespace创建的资源所属的名称空间,namespaces划分了一个空间,在同一个namesace下的资源名字是唯一的,默认的名称空间是default
pod.spec字段定义
[root@pengfei-master1 pod]# kubectl explain pod.spec
KIND: Pod
VERSION: v1
RESOURCE: spec <Object>
DESCRIPTION:
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
PodSpec is a description of a pod.#Pod的spec字段是用来描述Pod的
FIELDS:
affinity <Object>#定义亲和性的
automountServiceAccountToken <boolean>
containers <[]Object> -required-#是对象列表,用来定义容器的,是必须字段。表示下面有很多对象,对象列表下面的内容用 - 连接。
字段注释:
affinity定义pod亲和性的
containers是对象列表,用来定义容器的,是必须字段。表示下面有很多对象,对象列表下面的内容用 - 连接。
pod.spec.containers字段定义
[root@pengfei-master1 pod]# kubectl explain pod.spec.containers
KIND: Pod
VERSION: 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.
#container是定义在pod里面的,一个pod至少要有一个容器
FIELDS:
......
env <[]Object>
List of environment variables to set in the container. Cannot be updated.
image <string> #image是用来指定容器需要的镜像的
Container image name. More info:
https://kubernetes.io/docs/concepts/containers/images This field is
optional to allow higher level config management to default or override
container images in workload controllers like Deployments and StatefulSets.
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
#镜像拉取策略,pod是要调度到node节点的,那pod启动需要镜像,可以根据这个字段设置镜像拉取策略,支持如下三种:
#Always:不管本地是否存在镜像,都要重新拉取镜像
#Never: 从不拉取镜像
#IfNotPresent:如果本地存在,使用本地的镜像,本地不存在,从官方拉取镜像
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
......
name <string> -required- #name是必须字段,用来指定容器名字的
Name of the container specified as a DNS_LABEL. Each container in a pod
must have a unique name (DNS_LABEL). Cannot be updated.
ports <[]Object> #port是端口,属于对象列表
List of ports to expose from the container. Not specifying a port here DOES
NOT prevent that port from being exposed. Any port which is listening on
the default "0.0.0.0" address inside a container will be accessible from
the network. Modifying this array with strategic merge patch may corrupt
the data. For more information See
https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated.
字段注释:
container是定义在pod里面的,一个pod至少要有一个容器
image是用来指定容器需要的镜像的
imagePullPolicy镜像拉取策略,pod是要调度到node节点的,那pod启动需要镜像,可以根据这个字段设置镜像拉取策略,支持三种:Always:不管本地是否存在镜像,都要重新拉取镜像 ;Never: 从不拉取镜像 IfNotPresent:如果本地存在,使用本地的镜像,本地不存在,从官方拉取镜像
pod.spec.container.ports字段定义
KIND: Pod
VERSION: v1
RESOURCE: ports <[]Object> #对象列表下面的内容用 - 连接
DESCRIPTION:
List of ports to expose from the container. Not specifying a port here DOES
NOT prevent that port from being exposed. Any port which is listening on
the default "0.0.0.0" address inside a container will be accessible from
the network. Modifying this array with strategic merge patch may corrupt
the data. For more information See
https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated.
ContainerPort represents a network port in a single container.
FIELDS:
containerPort <integer> -required- #containerPort是必须字段, pod中的容器需要暴露的端口
Number of port to expose on the pod's IP address. This must be a valid port
number, 0 < x < 65536.
hostIP <string>#将容器中的服务暴露到宿主机的端口上时,可以指定绑定的宿主机 IP。
What host IP to bind the external port to.
hostPort <integer> #容器中的服务在宿主机上映射的端口
Number of port to expose on the host. If specified, this must be a valid
port number, 0 < x < 65536. If HostNetwork is specified, this must match
ContainerPort. Most containers do not need this.
name <string> #端口的名字
If specified, this must be an IANA_SVC_NAME and unique within the pod. Each
named port in a pod must have a unique name. Name for the port that can be
referred to by services.
protocol <string> #端口协议,默认TCP
Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP".
Possible enum values:
- `"SCTP"` is the SCTP protocol.
- `"TCP"` is the TCP protocol.
- `"UDP"` is the UDP protocol.
字段注释:
ports对象列表下面的内容用 - 连接
containerPort是必须字段, pod中的容器需要暴露的端口
hostIP将容器中的服务暴露到宿主机的端口上时,可以指定绑定的宿主机 IP。
hostPort容器中的服务在宿主机上映射的端口 name#端口的名字
protocol端口协议,默认TCP
案例1:
创建一个nginx pod
打开两个终端,一个编写yaml文件,另一个使用kubectl explain查看帮助,注意缩进和对其,我这里空2个格
apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx
name: nginx-test
spec:
containers:
- name: nginx #注意-后面空了1个
image: nginx #没有指定nginx版本,将拉取最新版
imagePullPolicy: IfNotPresent #自动拉取策略
ports:
- containerPort: 80 #字段容器端口,注意-后面空了1个
创建pod
[root@pengfei-master1 pod]# kubectl apply -f pod_frist.yaml
pod/nginx-test created
查看创建的pod
[root@pengfei-master1 pod]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-test 1/1 Running 0 43s
获取指定 Pod 的详细信息
[root@pengfei-master1 pod]# kubectl describe pod nginx-test
Name: nginx-test
Namespace: default #默认名称空间
Priority: 0
Service Account: default
Node: pengfei-node2/192.168.5.134 #pod被调度到了node2节点
Start Time: Thu, 06 Jul 2023 10:57:22 +0800
Labels: app=nginx #pod具有的标签
Annotations: cni.projectcalico.org/containerID: 3588b4476bb5ce118f9e6346b5672a1952cd912419ba8b67f1313e4b3b54fd45
cni.projectcalico.org/podIP: 10.244.225.123/32
cni.projectcalico.org/podIPs: 10.244.225.123/32
Status: Running #pod的状态
IP: 10.244.225.123 #calico网络插件分配的pod ip
IPs:
IP: 10.244.225.123
Containers: #容器信息
nginx:
Container ID: containerd://75f6deabbedfd2bcf54e5d014b88754b15ac1698fecf02b8a9fdb0d8312eae9c
Image: nginx
Image ID: docker.io/library/nginx@sha256:b8f2383a95879e1ae064940d9a200f67a6c79e710ed82ac42263397367e7cc4e
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Thu, 06 Jul 2023 10:57:32 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-rtb86 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-rtb86:
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 3m16s default-scheduler Successfully assigned default/nginx-test to pengfei-node2#调度成功
Normal Pulled 3m6s kubelet Container image "nginx" already present on machine#镜像本地存在
Normal Created 3m6s kubelet Created container nginx #容器创建成功
Normal Started 3m5s kubelet Started container nginx#容器启动成功
查看pod日志
[root@pengfei-master1 pod]# kubectl logs -f nginx-test
编辑切换为居中
kubectl get
更新pod
修改镜像image: nginx:1.14.2
[root@pengfei-master1 pod]# kubectl apply -f pod_frist.yaml
[root@pengfei-master1 pod]# kubectl describe pod nginx-test
编辑切换为居中
添加图片注释,不超过 140 字(可选)
删除pod
[root@pengfei-master1 pod]# kubectl delete -f pod_frist.yaml
其他资源
[root@pengfei-master1 pod]# kubectl explain deployment
[root@pengfei-master1 pod]# kubectl explain namespace
#查看方式同pod