概述

Pod是Kubernetes的最小单元,也是最重要和最基本的概念。每一个Pod包含一个或多个容器,Pod的容器会作为
一个整体被Master调度到一个Node上运行。
Kubenetes为每个Pod都分配了唯一的IP地址,称为PodIP,一个Pod里的多个容器共享PodIP地址。在Kubernetes里,一个Pod里的容器与另外主机上的Pod容器能够直接通信。
应用在每个Node上运行的其实是一个Pod。Pod也只能运行在Node上。一个pod的所有容器都运行在同一个节点上;一个pod绝不跨越两个节点,如下图:

Kubernetes——Pod - 图2

image.png

Pod容器组是一个k8s中一个抽象的概念,用于存放一组 container(可包含一个或多个 container 容器,即图上正方体),以及这些 container (容器)的一些共享资源。这些资源包括:

  • 共享存储,称为卷(Volumes),即图上紫色圆柱
  • 网络,每个 Pod(容器组)在集群中有个唯一的 IP,pod(容器组)中的 container(容器)共享该IP地址
  • container(容器)的基本信息,例如容器的镜像版本,对外暴露的端口等

POD 资源配置清单

pod一级字段查看 kubectl explain pods

  1. $ kubectl explain pods
  2. KIND: Pod
  3. VERSION: v1
  4. DESCRIPTION:
  5. Pod is a collection of containers that can run on a host. This resource is
  6. created by clients and scheduled onto hosts.
  7. FIELDS:
  8. apiVersion <string>
  9. APIVersion defines the versioned schema of this representation of an
  10. object. Servers should convert recognized schemas to the latest internal
  11. value, and may reject unrecognized values. More info:
  12. https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
  13. kind <string>
  14. Kind is a string value representing the REST resource this object
  15. represents. Servers may infer this from the endpoint the client submits
  16. requests to. Cannot be updated. In CamelCase. More info:
  17. https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
  18. metadata <Object>
  19. Standard object's metadata. More info:
  20. https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
  21. spec <Object>
  22. Specification of the desired behavior of the pod. More info:
  23. https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
  24. status <Object>
  25. Most recently observed status of the pod. This data may not be up to date.
  26. Populated by the system. Read-only. More info:
  27. https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

pod具体配置文件

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: string
  5. namaspace: string
  6. labels:
  7. - name: string
  8. annotations:
  9. - name: string
  10. spec:
  11. containers:
  12. - name: string
  13. images: string
  14. imagePullPolice: [Always | Never | IfNotPresent]
  15. command: [string]
  16. args: [string]
  17. workingDir: string
  18. volumeMounts:
  19. - name: string
  20. mountPath: string
  21. readOnly: boolean
  22. ports:
  23. - name: string
  24. containerPort: int
  25. hostPort: int
  26. protocol: string
  27. env:
  28. - name: string
  29. value: string
  30. resources:
  31. limits:
  32. cpu: string
  33. memory: string
  34. requests:
  35. cpu: string
  36. memory: string
  37. livenessProbe:
  38. exec:
  39. command: [string]
  40. httpGet:
  41. path: string
  42. port: int
  43. host: string
  44. scheme: string
  45. httpHeaders:
  46. - name: string
  47. value: string
  48. tcpSocket:
  49. port: number
  50. initialDelaySeconds: 0
  51. timeoutSeconds: 0
  52. periodSeconds: 0
  53. successThreshold: 0
  54. failureThreshold: 0
  55. securityContext:
  56. privileged: false
  57. restartPolicy: [Always | Never | OnFailure]
  58. nodeSelector: object
  59. imagePullSecrets:
  60. - name: string
  61. hostNetwork: false
  62. volumes:
  63. - name: string
  64. emptyDir: {}
  65. hostPath:
  66. path: string
  67. secret:
  68. secretName: string
  69. items:
  70. - key: string
  71. path: string
  72. configMap:
  73. name: string
  74. items:
  75. - key: string
  76. 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 文件

  1. apiVersion: v1 # 定义版本(资源类型不同,其版本可能不同)
  2. kind: Pod #(定义资源类型)
  3. metadata: #(定义元数据)
  4. name: demo-nginx #(定义pod名称)
  5. namespace: default #(定义pod隶属的名称空间)
  6. spec:
  7. containers:
  8. - name: demo-nginx #(定义容器名称,一个POD中可包含多个容器)
  9. image: nginx:1.14 #(定义容器镜像名称)
  10. ports: #(定义容器暴露端口)
  11. - name: http #(暴露端口名称)
  12. containerPort: 80 #(暴露端口)
  13. - name: demo-tomcat
  14. image: tomcat:8.5.35
  15. ports:
  16. - name: tomcat
  17. containerPort: 8080

2 构建

  1. kubectl apply -f demo.yaml

查看结果

  1. $ kubectl get pods -o wide
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. niginx-pod 2/2 Running 0 4h39m 10.1.0.147 docker-desktop <none> <none>

创建POD

  1. #[root@master all]# cat nginx.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: nginx1
  6. namespace: web1
  7. spec:
  8. containers:
  9. - name: nginx-web
  10. image: nginx:1.14
  11. ports:
  12. - name: http
  13. containerPort: 80

运行pod

  1. kubectl apply -f nginx.yaml

查看pod

  1. #[root@master all]# kubectl get pods -n web1
  2. NAME READY STATUS RESTARTS AGE
  3. nginx1 1/1 Running 0 8s

指定输出格式

  1. [root@master all]# kubectl get pods -n web1 -o yaml
  2. [root@master all]# kubectl get pods -n web1 -o json

更新pod

对于活动对象,并非每个属性值都支持修改,如pod资源的metadata.name字段不支持修改,处分先delete删除后重新创建。
更新

  1. kubectl get pods -n web1 -o yaml > nginx.yaml

修改重新部署

  1. kubectl replace -f nginx.yaml --force

删除POD

  1. kubectl delete -f nginx.yaml

查看

  1. [root@master all]# kubectl get pods -n web1
  2. No resources found.

更新

  1. [root@master all]# cat nginx.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: nginx1
  6. namespace: web1
  7. spec:
  8. containers:
  9. - name: nginx-web
  10. image: nginx:1.12
  11. ports:
  12. - name: http
  13. containerPort: 80
  14. [root@master all]# kubectl apply -f nginx.yaml
  15. pod/nginx1 configured
  16. [root@master all]# kubectl get pods -n web1
  17. NAME READY STATUS RESTARTS AGE
  18. nginx1 1/1 Running 1 19s

日志

kubectl logs nginx-pod

  1. $ kubectl logs nginx-pod
  2. /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
  3. /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
  4. /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
  5. 10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
  6. 10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
  7. /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
  8. /docker-entrypoint.sh: Configuration complete; ready for start up

如果 Pod 上包含多个容器,在查询具体容器的日志时,需要指定参数 -c 容器名 进行查询

删除 pod

  1. $ kubectl delete pod nginx-pod
  2. pod "nginx-pod" deleted

imagePullPolicy

各工作节点负责运行POD对象,而POD的核心功能用在运行容器,因此工作节点上必须配置运行引擎,如docker,启动容器时,容器引擎将自动拉取镜像。拉取镜像的方式

  1. [root@master all]# kubectl explain pods.spec.containers.imagePullPolicy
  2. KIND: Pod
  3. VERSION: v1
  4. FIELD: imagePullPolicy <string>
  5. DESCRIPTION:
  6. Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always
  7. if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
  8. More info:
  9. https://kubernetes.io/docs/concepts/containers/images#updating-images

Always: 镜像标签为”latest”或镜像不存在时总是从指定仓库获取镜像
IfNotPresent: 仅当本地镜像缺失时才从目标仓库下载镜像
Never: 禁止从仓库下载,仅使用本地镜像
注:对于镜像标签为latest的镜像,其默认策略为”Always”,而对于其他标签,其默认策略为”IfNotPresent”,如果使用私有仓库需要认证,则可通过imagePullSecretes 字段调用此认证信息完成。
**
图片.png

端口

  1. kubectl explain pods.spec.containers.ports
  2. FIELDS:
  3. containerPort <integer> -required- #必选字段,指定在POD对象的IP地址上暴露的容器端口,其有效范围是(0,65536),使用时,应该总是指定容器应用正常监听者的端口
  4. Number of port to expose on the pod's IP address. This must be a valid port
  5. number, 0 < x < 65536.
  6. hostIP <string>#
  7. What host IP to bind the external port to.
  8. hostPort <integer> # 主机端口,他将接受到的请求通过NAT机制转发至由containerPort字段指定的容器端口
  9. Number of port to expose on the host. If specified, this must be a valid
  10. port number, 0 < x < 65536. If HostNetwork is specified, this must match
  11. ContainerPort. Most containers do not need this.
  12. name <string> # 当前端口的名称,必须符合IANA_SVC_NAME规范且在当前POD内必须是唯一的,此端口名可被service资源调用
  13. If specified, this must be an IANA_SVC_NAME and unique within the pod. Each
  14. named port in a pod must have a unique name. Name for the port that can be
  15. referred to by services.
  16. protocol <string> # 端口相关协议,其值仅可为TCP或UDP,默认是TCP
  17. Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP".

通过端口转发使用 kubectl port-forward 命令来执行端口转发,将本地的 8080 端口转发到 nginx-manual 的 80 端口

  1. $ kubectl port-forward nginx-pod 8000:80

自定义运行容器化应用

容器的command字段能够指定不同于镜像默认运行的应用程序,并且可以同时为使用args字段进行参数传递,它们将覆盖镜像中默认定义,如果仅为容器定义了args字段,那么他将作为参数传递给镜像中默认指定运行的应用程序,如果仅指定了command字段,那么他将覆盖镜像中定义的程序及参数,并以无参数方式运行应用程序。

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: demo
  5. spec:
  6. containers:
  7. - name: demo
  8. image: alpine:latest
  9. command: ["/bin/sh"]
  10. args: ["-c","while true; do sleep 30; done"]

环境变量/env

非容器化的传统管理方式中,复杂的应用程序的配置信息多数由配置文件进行指定,用户可借助文本完成配置,对于容器隔离出的环境中的应用程序,用户就需要穿透容器边界在容器内进行配置编辑并进行重载,这种方式复杂,环境变量的方式传递便成为一种潮流。 这种方式依赖于应用程序支持通过环境表示变量进行配置的能力,否则,用户在制作docker镜像时需要通过entrypoint脚本完成变量到程序配置文件的同步。

需要在容器配置端中嵌套使用env字段,他的值是一个由环境变
量构成的列表,通常包含name和value字段构成

  1. [root@master1 ~]# kubectl explain pod.spec.containers.env
  2. KIND: Pod
  3. VERSION: v1
  4. RESOURCE: env <[]Object>
  5. DESCRIPTION:
  6. List of environment variables to set in the container. Cannot be updated.
  7. EnvVar represents an environment variable present in a Container.
  8. FIELDS:
  9. name <string> -required- #环境变量名称,必选字段
  10. Name of the environment variable. Must be a C_IDENTIFIER.
  11. value <string> #传递给环境变量的值,通过$(VAR_NAME)引用,逃逸格式为"$$(VAR_NAME)",默认为空
  12. Variable references $(VAR_NAME) are expanded using the previous defined
  13. environment variables in the container and any service environment
  14. variables. If a variable cannot be resolved, the reference in the input
  15. string will be unchanged. The $(VAR_NAME) syntax can be escaped with a
  16. double $$, ie: $$(VAR_NAME). Escaped references will never be expanded,
  17. regardless of whether the variable exists or not. Defaults to "".
  18. valueFrom <Object>
  19. Source for the environment variable's value. Cannot be used if value is not
  20. empty.

实例

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: demo-env
  5. spec:
  6. containers:
  7. - name: demo-env
  8. image: ikubernetes/filebeat:5.6.5-alpine
  9. env:
  10. - name: REDIS_HOST
  11. value: redis.com
  12. - name: LOG_LEVEL
  13. value: info

此处传递主机名称和日志级别
查看,通过printenv即可获取环境变量和列表及其对应的值
Kubernetes——Pod - 图5

共享节点的网络名称空间

kubectl explain pods.spec.hostNetwork 同一个POD对象的各个容器均运行在一个独立的、隔离的Network名称空间中,共享同一个网络协议栈及相关的网络设备,也有一些特殊的POD对象需要运行与所在节点的名称空间中,执行系统级的管理任务,如查看和操作节点的网络资源甚至是网络设备等,事实上,仅需要设置HostNetwork的属性位true即可创建共享节点网络名称空间的Pod对象

如下
配置配置结果

  1. #[root@master1 all]# cat demohostnet.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: demo-hostnet
  6. spec:
  7. containers:
  8. - name: demo-hostnet
  9. image: nginx:1.14
  10. hostNetwork: true

验证结果
Kubernetes——Pod - 图6
查看运行节点
Kubernetes——Pod - 图7
node1节点结果:
Kubernetes——Pod - 图8

Pod对象的安全上下文

pod 对象的安全上下文用于设定Pod或容器的权限和访问控制功能,其支持的常用属性有: 1 基于用户ID和组ID访问控制对象时的权限 2 以特权或非特权的方式运行 3 通过Linux capabities为其提供部分特权 4 基于seccomp过滤进程的系统调用 5 基于SELinux的安全标签 6 是否能够进行权限升级

POD 对象的安全上下文定义在spec.securityContext字段中,而容器的安全上下文则定义在spec.containers.securityContext字段中,且二者可嵌套使用的字段有所不同,

  1. [root@master1 all]# cat demosecu.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: demo-sec
  6. spec:
  7. containers:
  8. - name: demo-sec
  9. image: busybox
  10. command: ["/bin/sh","-c","sleep 86400"]
  11. securityContext:
  12. runAsNonRoot: true # 非特权模式运行
  13. runAsUser: 1000 #设置其运行的UID为1000的可以访问
  14. allowPrivilegeEscalation: false #设置其权限升级不允许

查看验证
Kubernetes——Pod - 图9

注意

在生产环境中,很少会单独启动一个Pod直接使用,经常会用Deployment、DaemonSet、StatefulSet等方式调度并管理Pod,定义Pod的参数同时适应于Deployment、DaemonSet、StatefulSet等方式。

参考文章

https://blog.51cto.com/11233559/2367822