概述
Pod是Kubernetes的最小单元,也是最重要和最基本的概念。每一个Pod包含一个或多个容器,Pod的容器会作为
一个整体被Master调度到一个Node上运行。
Kubenetes为每个Pod都分配了唯一的IP地址,称为PodIP,一个Pod里的多个容器共享PodIP地址。在Kubernetes里,一个Pod里的容器与另外主机上的Pod容器能够直接通信。
应用在每个Node上运行的其实是一个Pod。Pod也只能运行在Node上。一个pod的所有容器都运行在同一个节点上;一个pod绝不跨越两个节点,如下图:
Pod容器组是一个k8s中一个抽象的概念,用于存放一组 container(可包含一个或多个 container 容器,即图上正方体),以及这些 container (容器)的一些共享资源。这些资源包括:
- 共享存储,称为卷(Volumes),即图上紫色圆柱
- 网络,每个 Pod(容器组)在集群中有个唯一的 IP,pod(容器组)中的 container(容器)共享该IP地址
- container(容器)的基本信息,例如容器的镜像版本,对外暴露的端口等
POD 资源配置清单
pod一级字段查看 kubectl explain pods
$ kubectl explain pods
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/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/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
spec <Object>
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
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/api-conventions.md#spec-and-status
pod具体配置文件
apiVersion: v1
kind: Pod
metadata:
name: string
namaspace: string
labels:
- name: string
annotations:
- name: string
spec:
containers:
- name: string
images: string
imagePullPolice: [Always | Never | IfNotPresent]
command: [string]
args: [string]
workingDir: string
volumeMounts:
- name: string
mountPath: string
readOnly: boolean
ports:
- name: string
containerPort: int
hostPort: int
protocol: string
env:
- name: string
value: string
resources:
limits:
cpu: string
memory: string
requests:
cpu: string
memory: string
livenessProbe:
exec:
command: [string]
httpGet:
path: string
port: int
host: string
scheme: string
httpHeaders:
- name: string
value: string
tcpSocket:
port: number
initialDelaySeconds: 0
timeoutSeconds: 0
periodSeconds: 0
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
restartPolicy: [Always | Never | OnFailure]
nodeSelector: object
imagePullSecrets:
- name: string
hostNetwork: false
volumes:
- name: string
emptyDir: {}
hostPath:
path: string
secret:
secretName: string
items:
- key: string
path: string
configMap:
name: string
items:
- key: string
path: string
含义如下
属性名称 | 取值类型 | 取值说明 |
---|---|---|
apiVersion | String | 版本号,例如v1,版本号必须可以用 kubectl api-versions 查询到 |
kind | String | Pod |
metadata | Object | 元数据 |
metadata.name | String | Pod名称,需符合RFC 1035规范 |
metadata.namespace | String | Pod所属的命名空间,默认为”default” |
metadata.labels[] | List | 自定义标签 |
metadata.annotations[] | List | 自定义注释列表 |
spec: | Object | Pod中容器的详细定义 |
containers: | List | Pod中容器列表 |
- name: string | String | 容器名称,需符合RFC 1035规范 |
image: string | String | 容器的镜像名称 |
imagePullPolicy: [ Always|Never|IfNotPresent ] | String | 获取镜像的策略,默认值为Alawys,Alawys表示每次都尝试下载镜像,IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像 |
command: [string] | List | 容器的启动命令列表,如不指定,使用打包时使用的启动命令 |
args: [string] | List | 容器的启动命令参数列表 |
workingDir: string | String | 容器的工作目录 |
volumeMounts: | List | 挂载到容器内部的存储卷配置 |
- name: string | String | 引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名 |
mountPath: string | String | 存储卷在容器内mount的绝对路径,应少于512字符 |
readOnly: boolean | Boolean | 是否为只读模式,默认为读写模式 |
ports: | List | 需要暴露的端口库号列表 |
- name: string | String | 端口的名称 |
containerPort: int | Int | 容器需要监听的端口号 |
hostPort: int | Int | 容器所在主机需要监听的端口号,默认与Container相同 |
protocol: string | String | 端口协议,支持TCP和UDP,默认TCP |
env: | List | 容器运行前需设置的环境变量列表 |
- name: string | String | 环境变量名称 |
value: string | String | 环境变量的值 |
resources: | Object | 资源限制和请求的设置 |
limits: | Object | 资源限制的设置 |
cpu: string | String | CPU的限制,单位为core数,将用于docker run —cpu-shares参数 |
memory: string | String | 内存限制,单位可以为Mib/Gib,将用于docker run —memory参数 |
requests: | Object | 资源限制的设置 |
cpu: string | String | CPU请求,容器启动的初始可用数量 |
memory: string | String | 内存请求,容器启动的初始可用数量 |
livenessProbe: | Object | 对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器,可设置的方法包括exec、httpGet和tcpSocket,对一个容器仅需设置其中一种健康检查方法 |
exec: | Object | 对Pod容器内检查方式设置为exec方式 |
command: [string] | String | exec方式需要制定的命令或脚本 |
httpGet: | Object | 对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port |
path: string | ||
port: number | ||
host: string | ||
scheme: string | ||
HttpHeaders: | ||
- name: string | ||
value: string | ||
tcpSocket: | Object | 对Pod内个容器健康检查方式设置为tcpSocket方式 |
port: number | ||
initialDelaySeconds: 0 | Number | 容器启动完成后首次探测的时间,单位为秒 |
timeoutSeconds: 0 | Number | 对容器健康检查探测等待响应的超时时间,单位秒,默认1秒,若超过该超时时间设置,则认为该容器不健康,会重启该容器 |
periodSeconds: 0 | Number | 对容器监控检查的定期探测时间设置,单位秒,默认10秒一次 |
successThreshold: 0 | ||
failureThreshold: 0 | ||
securityContext: | ||
privileged: false | ||
restartPolicy: [Always | Never | OnFailure] | String | Pod的重启策略,(1)Always表示一旦不管以何种方式终止运行,kubelet都将重启它,(2)OnFailure表示只有Pod以非0退出码退出才重启,如果容器正常结束(退出码为0)kubelet将不会重启它,(3)Nerver:Pod终止后,kubelet将退出码报告给Master,不会再重启该Pod。 |
nodeSelector: obeject | Object | 设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定 |
imagePullSecrets: | Object | Pull镜像时使用的secret名称,以name:secretkey格式指定 |
- name: string | ||
hostNetwork: false | Boolean | 是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络,不再使用Docker网桥,该Pod将无法在同一宿主机上启动第2哥副本 |
volumes: | List | 在该pod上定义共享存储卷列表 |
- name: string | String | 共享存储卷名称 ,在一个Pod中每个存储卷定义一个名称,应符合RFC 1035规范。容器定义部分的containers[].volumeMounts[].name将引用该共享存储卷的名称。 Volume的类型包括:emptyDir、hostPath、gcePersistentDisk、awsElasticBlockStore、gitRepo、secret、nfs、iscsi、glusterfs、persistentVolumeClaim、rbd、flexVolume、cinder、cephfs、flocker、downwardAPI、fc、azureFile、configMap、vsphereVolume,可以定义多个Volume,每个Volume的name保持唯一。 |
emptyDir: {} | Object | 类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值 |
hostPath: string | Object | 类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录 |
path: string | String | Pod所在宿主机的目录,将被用于同期中mount的目录 |
secret: | Object | 类型为secret的存储卷,挂载集群与定义的secre对象到容器内部 |
scretname: string | ||
items: | ||
- key: string | ||
path: string | ||
configMap: | Object | 类型为configMap的存储卷,挂载预定义的configMap对象到容器内部 |
name: string | ||
items: | ||
- key: string | ||
path: string |
HelloWorld
创建 nginx-pod.yaml 文件
apiVersion: v1 # 定义版本(资源类型不同,其版本可能不同)
kind: Pod #(定义资源类型)
metadata: #(定义元数据)
name: demo-nginx #(定义pod名称)
namespace: default #(定义pod隶属的名称空间)
spec:
containers:
- name: demo-nginx #(定义容器名称,一个POD中可包含多个容器)
image: nginx:1.14 #(定义容器镜像名称)
ports: #(定义容器暴露端口)
- name: http #(暴露端口名称)
containerPort: 80 #(暴露端口)
- name: demo-tomcat
image: tomcat:8.5.35
ports:
- name: tomcat
containerPort: 8080
2 构建
kubectl apply -f demo.yaml
查看结果
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
niginx-pod 2/2 Running 0 4h39m 10.1.0.147 docker-desktop <none> <none>
创建POD
#[root@master all]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx1
namespace: web1
spec:
containers:
- name: nginx-web
image: nginx:1.14
ports:
- name: http
containerPort: 80
运行pod
kubectl apply -f nginx.yaml
查看pod
#[root@master all]# kubectl get pods -n web1
NAME READY STATUS RESTARTS AGE
nginx1 1/1 Running 0 8s
指定输出格式
[root@master all]# kubectl get pods -n web1 -o yaml
[root@master all]# kubectl get pods -n web1 -o json
更新pod
对于活动对象,并非每个属性值都支持修改,如pod资源的metadata.name字段不支持修改,处分先delete删除后重新创建。
更新
kubectl get pods -n web1 -o yaml > nginx.yaml
修改重新部署
kubectl replace -f nginx.yaml --force
删除POD
kubectl delete -f nginx.yaml
查看
[root@master all]# kubectl get pods -n web1
No resources found.
更新
[root@master all]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx1
namespace: web1
spec:
containers:
- name: nginx-web
image: nginx:1.12
ports:
- name: http
containerPort: 80
[root@master all]# kubectl apply -f nginx.yaml
pod/nginx1 configured
[root@master all]# kubectl get pods -n web1
NAME READY STATUS RESTARTS AGE
nginx1 1/1 Running 1 19s
日志
kubectl logs nginx-pod
$ kubectl logs nginx-pod
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
如果 Pod 上包含多个容器,在查询具体容器的日志时,需要指定参数 -c 容器名
进行查询
删除 pod
$ kubectl delete pod nginx-pod
pod "nginx-pod" deleted
imagePullPolicy
各工作节点负责运行POD对象,而POD的核心功能用在运行容器,因此工作节点上必须配置运行引擎,如docker,启动容器时,容器引擎将自动拉取镜像。拉取镜像的方式
[root@master all]# kubectl explain pods.spec.containers.imagePullPolicy
KIND: Pod
VERSION: v1
FIELD: imagePullPolicy <string>
DESCRIPTION:
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
Always: 镜像标签为”latest”或镜像不存在时总是从指定仓库获取镜像
IfNotPresent: 仅当本地镜像缺失时才从目标仓库下载镜像
Never: 禁止从仓库下载,仅使用本地镜像
注:对于镜像标签为latest的镜像,其默认策略为”Always”,而对于其他标签,其默认策略为”IfNotPresent”,如果使用私有仓库需要认证,则可通过imagePullSecretes 字段调用此认证信息完成。
**
端口
kubectl explain pods.spec.containers.ports
FIELDS:
containerPort <integer> -required- #必选字段,指定在POD对象的IP地址上暴露的容器端口,其有效范围是(0,65536),使用时,应该总是指定容器应用正常监听者的端口
Number of port to expose on the pod's IP address. This must be a valid port
number, 0 < x < 65536.
hostIP <string>#
What host IP to bind the external port to.
hostPort <integer> # 主机端口,他将接受到的请求通过NAT机制转发至由containerPort字段指定的容器端口
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> # 当前端口的名称,必须符合IANA_SVC_NAME规范且在当前POD内必须是唯一的,此端口名可被service资源调用
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或UDP,默认是TCP
Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP".
通过端口转发使用 kubectl port-forward
命令来执行端口转发,将本地的 8080 端口转发到 nginx-manual 的 80 端口
$ kubectl port-forward nginx-pod 8000:80
自定义运行容器化应用
容器的command字段能够指定不同于镜像默认运行的应用程序,并且可以同时为使用args字段进行参数传递,它们将覆盖镜像中默认定义,如果仅为容器定义了args字段,那么他将作为参数传递给镜像中默认指定运行的应用程序,如果仅指定了command字段,那么他将覆盖镜像中定义的程序及参数,并以无参数方式运行应用程序。
apiVersion: v1
kind: Pod
metadata:
name: demo
spec:
containers:
- name: demo
image: alpine:latest
command: ["/bin/sh"]
args: ["-c","while true; do sleep 30; done"]
环境变量/env
非容器化的传统管理方式中,复杂的应用程序的配置信息多数由配置文件进行指定,用户可借助文本完成配置,对于容器隔离出的环境中的应用程序,用户就需要穿透容器边界在容器内进行配置编辑并进行重载,这种方式复杂,环境变量的方式传递便成为一种潮流。 这种方式依赖于应用程序支持通过环境表示变量进行配置的能力,否则,用户在制作docker镜像时需要通过entrypoint脚本完成变量到程序配置文件的同步。
需要在容器配置端中嵌套使用env字段,他的值是一个由环境变
量构成的列表,通常包含name和value字段构成
[root@master1 ~]# kubectl explain pod.spec.containers.env
KIND: Pod
VERSION: v1
RESOURCE: env <[]Object>
DESCRIPTION:
List of environment variables to set in the container. Cannot be updated.
EnvVar represents an environment variable present in a Container.
FIELDS:
name <string> -required- #环境变量名称,必选字段
Name of the environment variable. Must be a C_IDENTIFIER.
value <string> #传递给环境变量的值,通过$(VAR_NAME)引用,逃逸格式为"$$(VAR_NAME)",默认为空
Variable references $(VAR_NAME) are expanded using the previous defined
environment variables in the container and any service environment
variables. If a variable cannot be resolved, the reference in the input
string will be unchanged. The $(VAR_NAME) syntax can be escaped with a
double $$, ie: $$(VAR_NAME). Escaped references will never be expanded,
regardless of whether the variable exists or not. Defaults to "".
valueFrom <Object>
Source for the environment variable's value. Cannot be used if value is not
empty.
实例
apiVersion: v1
kind: Pod
metadata:
name: demo-env
spec:
containers:
- name: demo-env
image: ikubernetes/filebeat:5.6.5-alpine
env:
- name: REDIS_HOST
value: redis.com
- name: LOG_LEVEL
value: info
此处传递主机名称和日志级别
查看,通过printenv即可获取环境变量和列表及其对应的值
共享节点的网络名称空间
kubectl explain pods.spec.hostNetwork 同一个POD对象的各个容器均运行在一个独立的、隔离的Network名称空间中,共享同一个网络协议栈及相关的网络设备,也有一些特殊的POD对象需要运行与所在节点的名称空间中,执行系统级的管理任务,如查看和操作节点的网络资源甚至是网络设备等,事实上,仅需要设置HostNetwork的属性位true即可创建共享节点网络名称空间的Pod对象
如下
配置配置结果
#[root@master1 all]# cat demohostnet.yaml
apiVersion: v1
kind: Pod
metadata:
name: demo-hostnet
spec:
containers:
- name: demo-hostnet
image: nginx:1.14
hostNetwork: true
Pod对象的安全上下文
pod 对象的安全上下文用于设定Pod或容器的权限和访问控制功能,其支持的常用属性有: 1 基于用户ID和组ID访问控制对象时的权限 2 以特权或非特权的方式运行 3 通过Linux capabities为其提供部分特权 4 基于seccomp过滤进程的系统调用 5 基于SELinux的安全标签 6 是否能够进行权限升级
POD 对象的安全上下文定义在spec.securityContext字段中,而容器的安全上下文则定义在spec.containers.securityContext字段中,且二者可嵌套使用的字段有所不同,
[root@master1 all]# cat demosecu.yaml
apiVersion: v1
kind: Pod
metadata:
name: demo-sec
spec:
containers:
- name: demo-sec
image: busybox
command: ["/bin/sh","-c","sleep 86400"]
securityContext:
runAsNonRoot: true # 非特权模式运行
runAsUser: 1000 #设置其运行的UID为1000的可以访问
allowPrivilegeEscalation: false #设置其权限升级不允许
注意
在生产环境中,很少会单独启动一个Pod直接使用,经常会用Deployment、DaemonSet、StatefulSet等方式调度并管理Pod,定义Pod的参数同时适应于Deployment、DaemonSet、StatefulSet等方式。