Pod
什么是Pod
Pod可简单地理解为是一组、一个或多个容器,具有共享存储/网络及如何运行容器的规范。Pad包含
一个或多个相对紧密耦合的应用程序容器,处于同一个Pod中的容器共享同样的存储空间(Volume,卷
或存储卷)、IP地址和Port端口,容器之间使用localhost:port相互访问。根据Docker的构造,Pod可被
建模为一组具有共享命令空间、卷、IP地址和Port端口的Docker容器。Pod包含的容器最好是一个容器
只运行一个进程。每个Pod包含一个pause容器,pause容器是Pod的父容器,它主要负责僵尸进程的回
收管理。
Kubernetes为每个Pod都分配一个唯一的IP地址,这样就可以保证应用程序使用同一端口,避免了发生
冲突的问题。
k8s最终都是围绕着pod来的,因为pod里面运行的是容器(container),我们最终是为了跑我们的应用程序,所以Pod运行的是container,而容器可以有一个或者多个,一个pod里面可以运行多个容器!
正常情况下pod外面还有一层控制器,这个控制器称为pod控制器,之前讲master组件里面contaroller-manager就是其中一个,pod可以裸着,也可以基于pod控制器来创建,还有一些控制器如:service(服务发现)/volume(卷组)/PVC,还有PHA,以后还会讲很多控制器,事实上都是围绕着pod来去实现的,这些控制器最终都是为了给pod服务的,因为我们最终是为了运行应用,应用运行在container(容器)里面容器跑在pod里面.
pod可以理解为一个container(容器)或者多个容器的集合,一个pod跑多个容器,具有共享存储/网络及如何运行容器的规范,就是一个pod如果运行着多个容器,那他们是共享存储的共享网络的,事实上多个容器他们的ip是一样的,主机名一样的.对应的网络端口号也是一样的,所以不能在一个pod里面运行两个相同的容器,会冲突.pod包含一个或者多个相对紧密耦合的应用程序,之前是建议一个容器里面只运行一个进程,而pod是比如LNMP,可以将nginx,php,mysql都运行在一个pod里面,比如运行一个nginx容器再运行一个php容器再运行一个mysql容器,也可以,但是数据库类的不建议跑在pod容器里面,可以将多个容器运行在一个pod里面,同一个pod多个容器之间ip 端口号 主机名 都是一样的,一个pod里面多个容器可以通过127.0.0.1本地回环地址直接进行通信,这种方式给我们后面比如日志收集,监控提供了一个很好的机制,我们可以每个pod里面运行一个主容器,然后运行一个日志收集的容器,再运行一个监控客户端的容器,这些怎么完成一个pod多个容器,他们共享网络机制怎么实现的呢?就是前面下载的pause镜像这个镜像启动的容器给我们提供一个pod多个容器能实现各种名称空间共享的一个工具,所以我们每个pod里面都要包含一个基础容器,这个基础容器就是pause容器,这个pause给我们提供名称空间共享.
apiVersion: v1 # 必选,API的版本号
kind: Pod # 必选,类型Pod
metadata: # 必选,元数据
name: nginx # 必选,符合RFC 1035规范的Pod名称,不写名称默认defalut
namespace: web-testing # 可选,不指定默认为default,Pod所在的命名空间
labels: # 可选,标签选择器,一般用于Selector
- app: nginx
annotations: # 可选,注释列表
- app: nginx
spec: # 必选,用于定义容器的详细信息或者是说定义容器的期望状态值
containers: # 必选,容器列表
- name: nginx # 必选,符合RFC 1035规范的容器名称
image: nginx: v1 # 必选,容器所用的镜像的地址
imagePullPolicy: Always # 可选,镜像拉取策略
command:
- nginx # 可选,容器启动执行的命令
- -g
- "daemon off;"
workingDir: /usr/share/nginx/html # 可选,容器的工作目录
volumeMounts: # 可选,存储卷配置
- name: webroot # 存储卷名称
mountPath: /usr/share/nginx/html # 挂载目录
readOnly: true # 只读
ports: # 可选,容器需要暴露的端口号列表
- name: http # 端口名称
containerPort: 80 # 端口号
protocol: TCP # 端口协议,默认TCP
env: # 可选,环境变量配置
- name: TZ # 变量名
value: Asia/Shanghai
- name: LANG
value: en_US.utf8
resources: # 可选,资源限制和资源请求限制
limits: # 最大限制设置
cpu: 1000m
memory: 1024MiB
requests: # 启动所需的资源
cpu: 100m
memory: 512MiB
readinessProbe: # 可选,容器状态检查
httpGet: # 检测方式
path: / # 检查路径
port: 80 # 监控端口
timeoutSeconds: 2 # 超时时间
initialDelaySeconds: 60 # 初始化时间
livenessProbe: # 可选,监控状态检查
exec: # 检测方式
command:
- cat
- /health
httpGet: # 检测方式
path: /_health
port: 8080
httpHeaders:
- name: end-user
value: jason
tcpSocket: # 检测方式
port: 80
initialDelaySeconds: 60 # 初始化时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 2 # 检查成功为2次表示就绪
failureThreshold: 1 # 检测失败1次表示未就绪
securityContext: # 可选,限制容器不可信的行为
provoleged: false
restartPolicy: Always # 可选,默认为Always
nodeSelector: # 可选,指定Node节点
region: subnet7
imagePullSecrets: # 可选,拉取镜像使用的secret
- name: default-dockercfg-86258
hostNetwork: false # 可选,是否为主机模式,如是,会占用主机端口
volumes: # 共享存储卷列表
- name: webroot # 名称,与上述对应
emptyDir: {} # 共享卷类型,空
hostPath: # 共享卷类型,本机目录
path: /etc/hosts
secret: # 共享卷类型,secret模式,一般用于密码
secretName: default-token-tf2jp # 名称
defaultMode: 420 # 权限
configMap: # 一般用于配置文件
name: nginx-conf
defaultMode: 420
创建一个Pod
用命令行创建的pod这种方式叫命令式命令
#命令行方式创建pod
kubectl run nginx-1 --image=nginx:1.22.1
配置清单创建pod,把我们要创建的pod配置写到一个yml文件里面,通过命令执行这个文件,这种方式叫声明式对象
查看怎么写
[root@k8s-master1 ~]# 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.
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> #这个也是(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>#(对象) 对象意味着值可以有多个,同时比上面(string)字符串低一个级别,低一个级别就是要空两个空格
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 pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
上面每个查询出来的都可以继续查询
[root@k8s-master1 ~]# kubectl explain pod.apiVersion
KIND: Pod
VERSION: v1 #版本v1 写v1就行
FIELD: apiVersion <string> #格式
DESCRIPTION:
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
[root@k8s-master1 ~]# kubectl explain pod.kind
KIND: Pod
VERSION: v1
FIELD: kind <string>
DESCRIPTION:
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
查一下pod.metadata
[root@k8s-master1 ~]# kubectl explain pod.metadata
#metadata可以跟很多很多字段
KIND: Pod
VERSION: v1
RESOURCE: metadata <Object>
DESCRIPTION:
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
• 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
creationTimestamp <string>
#创建字符串时间戳,不需要我们定义,会自动生成,也可以定义
CreationTimestamp is a timestamp representing the server time when this
object was created. It is not guaranteed to be set in happens-before order
across separate operations. Clients may not set this value. It is
represented in RFC3339 form and is in UTC.
• Populated by the system. Read-only. Null for lists. More info:
• https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
deletionGracePeriodSeconds <integer>
#删除限制时间 删除宽限期秒,不需要我们定义,会自动生成,也可以定义
Number of seconds allowed for this object to gracefully terminate before it
will be removed from the system. Only set when deletionTimestamp is also
set. May only be shortened. Read-only.
deletionTimestamp <string>
#删除时间戳 ,不需要我们定义,会自动生成,也可以定义
DeletionTimestamp is RFC 3339 date and time at which this resource will be
deleted. This field is set by the server when a graceful deletion is
requested by the user, and is not directly settable by a client. The
resource is expected to be deleted (no longer visible from resource lists,
and not reachable by name) after the time in this field, once the
finalizers list is empty. As long as the finalizers list contains items,
deletion is blocked. Once the deletionTimestamp is set, this value may not
be unset or be set further into the future, although it may be shortened or
the resource may be deleted prior to this time. For example, a user may
request that a pod is deleted in 30 seconds. The Kubelet will react by
sending a graceful termination signal to the containers in the pod. After
that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL)
to the container and after cleanup, remove the pod from the API. In the
presence of network partitions, this object may still exist after this
timestamp, until an administrator or automated process can determine the
resource is fully terminated. If not set, graceful deletion of the object
has not been requested.
• Populated by the system when a graceful deletion is requested. Read-only.
• More info:
• https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
labels <map[string]string> #映射,映射就理解为ansible理解的字典模式 key value 名:值
#用的比较多的,
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
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>
#用的比较多
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
#不常用的暂时删掉
通过上面查询得到了metadata需要写的是name名字,namespace名称空间,lables标签(这个是映射关系就是key value)
然后到了第四个字段spec,这里面字段非常多
[root@k8s-master1 ~]# 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.
FIELDS:
activeDeadlineSeconds <integer>
Optional duration in seconds the pod may be active on the node relative to
StartTime before the system will actively try to mark it failed and kill
associated containers. Value must be a positive integer.
affinity <Object>
If specified, the pod's scheduling constraints
automountServiceAccountToken <boolean>
AutomountServiceAccountToken indicates whether a service account token
should be automatically mounted.
containers <[]Object> -required- #必选字段 是个列表
#spec里面最重要的就是containers(容器)
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.
hostNetwork <boolean>
#网络,直接使用主机网络的方式
Host networking requested for this pod. Use the host's network namespace.
If this option is set, the ports that will be used must be specified.
Default to false.
hostPID <boolean>
#id
Use the host's pid namespace. Optional: Default to false.
hostUsers <boolean>
#用户
Use the host's user namespace. Optional: Default to true. If set to true or
not present, the pod will be run in the host user namespace, useful for
when the pod needs a feature only available to the host user namespace,
such as loading a kernel module with CAP_SYS_MODULE. When set to false, a
new userns is created for the pod. Setting false is useful for mitigating
container breakout vulnerabilities even allowing users to run their
containers as root without actually having root privileges on the host.
This field is alpha-level and is only honored by servers that enable the
UserNamespacesSupport feature.
hostname <string>
#主机名
Specifies the hostname of the Pod If not specified, the pod's hostname will
be set to a system-defined value.
imagePullSecrets <[]Object>
#镜像的下载策略
ImagePullSecrets is an optional list of references to secrets in the same
namespace to use for pulling any of the images used by this PodSpec. If
specified, these secrets will be passed to individual puller
implementations for them to use. More info:
https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod
initContainers <[]Object>
#初始化容器
List of initialization containers belonging to the pod. Init containers are
executed in order prior to containers being started. If any init container
fails, the pod is considered to have failed and is handled according to its
restartPolicy. The name for an init container or normal container must be
unique among all containers. Init containers may not have Lifecycle
actions, Readiness probes, Liveness probes, or Startup probes. The
resourceRequirements of an init container are taken into account during
scheduling by finding the highest request/limit for each resource type, and
then using the max of of that value or the sum of the normal containers.
Limits are applied to init containers in a similar fashion. Init containers
cannot currently be added or removed. Cannot be updated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
nodeName <string>
#后面会讲的,选择节点的
NodeName is a request to schedule this pod onto a specific node. If it is
non-empty, the scheduler simply schedules this pod onto that node, assuming
that it fits resource requirements.
nodeSelector <map[string]string>
#也是选择节点的
NodeSelector is a selector which must be true for the pod to fit on a node.
Selector which must match a node's labels for the pod to be scheduled on
that node. More info:
https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
#不重要,或暂时用不到的先不显示
经过查询得到了spec最重要的字段是containers(容器)我们进行查询containers得到进一步的详细内容
[root@k8s-master1 ~]# 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.
FIELDS:
args <[]string>
Arguments to the entrypoint. The container image's CMD is used if this is
not provided. Variable references $(VAR_NAME) are expanded using the
container's environment. If a variable cannot be resolved, the reference in
the input string will be unchanged. Double $$ are reduced to a single $,
which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will
produce the string literal "$(VAR_NAME)". Escaped references will never be
expanded, regardless of whether the variable exists or not. Cannot be
updated. More info:
https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
command <[]string>
Entrypoint array. Not executed within a shell. The container image's
ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME)
are expanded using the container's environment. If a variable cannot be
resolved, the reference in the input string will be unchanged. Double $$
are reduced to a single $, which allows for escaping the $(VAR_NAME)
syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
Escaped references will never be expanded, regardless of whether the
variable exists or not. Cannot be updated. More info:
https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
env <[]Object>
List of environment variables to set in the container. Cannot be updated.
envFrom <[]Object>
List of sources to populate environment variables in the container. The
keys defined within a source must be a C_IDENTIFIER. All invalid keys will
be reported as an event when the container is starting. When a key exists
in multiple sources, the value associated with the last source will take
precedence. Values defined by an Env with a duplicate key will take
precedence. Cannot be updated.
image <string>
#镜像
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
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
lifecycle <Object>
Actions that the management system should take in response to container
lifecycle events. Cannot be updated.
livenessProbe <Object>
Periodic probe of container liveness. Container will be restarted if the
probe fails. Cannot be updated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
name <string> -required- #必选字段
#名字,要给容器起个名字
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> #列表
#端口号
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.
#我们查询一下端口号怎么写
[root@k8s-master1 ~]# kubectl explain pod.spec.containers.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- #必选字段
#容器port是谁
Number of port to expose on the pod's IP address. This must be a valid port
number, 0 < x < 65536.
hostIP <string>
#hostip 默认就是主机ip
What host IP to bind the external port to.
hostPort <integer>
#在主机上的端口号是谁 这就相当于docker run 里面的-p 端口映射
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>
#协议 有sctp tcp udp
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.
经过上面查询containers字段里面要写image镜像,容器名字name,port端口号
然后又查询了端口号字段的格式,port下需要写containersPort端口号容器的端口号,其他的也也可以写比如hostPort映射到主机的端口号是谁,包括端口号使用的协议protocol
vim nginx-pods.yml
通常情况下资源对象,如果是单个单词的话,首字母大写,如果是多个单词组成的话,通常是驼峰式的,第一个单词首字母首字母小写,第二个单词首字母大写,第三个单词首字母小写,第四个单词首字母大写,凹凸凹凸和骆驼似的驼峰式的.
apiVersion: v1 #版本v1
kind: Pod #类型pod
metadata: #元数据
name: nginx-3 #pod名称
namespace: default #不写默认default
labels: #列表s 是个复数
app: nginx #自定义的
env: dev #自定义的字段
spec: #规格
containers: #容器
- name: nginx #容器名称
image: nginx:1.22.1 #镜像地址
ports: #端口号
- containerPort: 80 #镜像端口号
然后有两种命令可以创建
第一种
kubectl create -f nginx-port.yml
#这种也是命令式的方式对pod进行创建
kubectl delete -f nginx-port.yml
#删除
第二种
kubectl apply -f nginx-port.yml
#声明式的方式
命令式方式和声明式方式的区别
命令式:我明确告诉系统要如何完成如何做也要告诉系统.
声明式:不明确告诉系统要如何完成,根据需求配置来完成创建
如果用create命令行基于文件创建,未来想更新,对这个文件进行更新,他是无法更新的,如果用apply这种声明式的方式创建资源对象后期资源配置文件修改了,可以再执行这个命令对这个资源进行更新,只是说pod目前不支持更新,后面提到pod控制器的时候用这种方式更新
这是一个通过资源配置清单来创建一个简单的pod