Kubernetes(7)-管理Pod对象

Pod 是 Kubernetes 系统的基础单元,是资源对象中可由用户创建或者部署的最小组件,也是
在 Kubernetes 系统上运行容器化应用的资源对象。其他的大多数资源对象都是用于支撑和
扩展 Pod 对象的功能的,例如,用于管控 Pod 运行的 StatefulSet 和 Deployment 等控制
器对象,用于暴露 Pod 应用的 Service 和 Ingress 对象,为 Pod 提供持久存储的
PersistentVolume 存储资源对象等。

Pod 中可以运行多个容器,这些容器共享 Network、UTS 和 IPC 名称空间,具有相同的域名、
主机名和网络接口,并可以通过 IPC 直接通讯。为一个 Pod 对象中的各个容器提供网络名称
空间等共享机制的是底层的基础容器 pause。也就是说在 Pod 中运行的多个容器之间共享
Network、UTS 和 IPC 名称空间,但是分别拥有各自的 MNT、USR 和 PID 名称空间。

尽管 Pod 可以类比为 VM 或者物理机,可以允许多个容器,但是一个 Pod 内通常仅运行一
个应用,除非多个容器之间有密切关系。在实际生产中也是将多个应用分别构建到多个 Pod,
另外,Pod 也是 K8s 进行系统规模伸缩和调度的基础单元,分别运行于多个 Pod 的多个应用
可以独立按需要进行规模变动,增强系统架构灵活性。

不过,分布式应用场景必须要求 Pod 中同时运行多个容器。分布式系统设计常常包含以下几种
模型:

  1. Sidecar pattern(边车模型):Pod 中运行一个主容器和一个辅助容器。如,将主容器中的日志
    使用 agent 收集至日志服务器,可以将 agent 运行为辅助应用容器,及 sidecar。又如,主
    容器为 database server,辅助容器为 redis 作为数据库本地缓存。
  2. Ambassador pattern(大使模型):Pod 中运行一个主容器,辅助容器为代理容器。将主容器中
    的访问请求转发到远程服务器,如访问一主多从的 redis 集群时,若 redis 集群发生变动,
    则只需更改 Ambassador 容器,无需更改主容器应用。
  3. Adapter pattern(适配器模型):此种模型主要用于将主容器的内容进行标准输出,如日志或
    指标数据的输出,便于调用者同意接收数据的接口。

一. 管理 Pod 对象的容器

Pod 对象中至少要运行一个容器,因此 containers 字段是定义 Pod 时的一级字段 spec 下的必须
字段。另外,还要使用 name 字段定义容器名称,image 字段定义镜像等。

1.1 镜像及其获取策略

首先获取 pod 资源的配置资源的所有可配置字段,其中 status 字段不用管:

root@kube-master1:~# kubectl explain pod. | grep -E "^ {3}[a-z]"  # pod资源有5个一级字段,status为k8s自己维护
   apiVersion	<string>  # 接受字符串类型的值,没有子字段
   kind	<string>          # 接受字符串类型的值,没有子字段
   metadata	<Object>      # 接受对象类型,有子字段
   spec	<Object>          # 接受对象类型,有子字段
   status	<Object>      # 接受对象类型,有子字段

# metadata字段的子字段
root@kube-master1:~# kubectl explain pod.metadata | grep -E "^ {3}[a-z]"
   annotations	<map[string]string>
   clusterName	<string>
   creationTimestamp	<string>
   deletionGracePeriodSeconds	<integer>
   deletionTimestamp	<string>
   finalizers	<[]string>
   generateName	<string>
   generation	<integer>
   labels	<map[string]string>
   managedFields	<[]Object>
   name	<string>
   namespace	<string>
   ownerReferences	<[]Object>
   resourceVersion	<string>
   selfLink	<string>
   uid	<string>

# spec字段的子字段
root@kube-master1:~# kubectl explain pod.spec | grep -E "^ {3}[a-z]"
   activeDeadlineSeconds	<integer>
   affinity	<Object>
   automountServiceAccountToken	<boolean>
   containers	<[]Object> -required-    # 必须字段
   dnsConfig	<Object>
   dnsPolicy	<string>
   enableServiceLinks	<boolean>
   ephemeralContainers	<[]Object>
   hostAliases	<[]Object>
   hostIPC	<boolean>
   hostNetwork	<boolean>
   hostPID	<boolean>
   hostname	<string>
   imagePullSecrets	<[]Object>
   initContainers	<[]Object>
   nodeName	<string>
   nodeSelector	<map[string]string>
   overhead	<map[string]string>
   preemptionPolicy	<string>
   priority	<integer>
   priorityClassName	<string>
   readinessGates	<[]Object>
   restartPolicy	<string>
   runtimeClassName	<string>
   schedulerName	<string>
   securityContext	<Object>
   serviceAccount	<string>
   serviceAccountName	<string>
   shareProcessNamespace	<boolean>
   subdomain	<string>
   terminationGracePeriodSeconds	<integer>
   tolerations	<[]Object>
   topologySpreadConstraints	<[]Object>
   volumes	<[]Object>

# spec.containers字段下的子字段
root@kube-master1:~# kubectl explain pod.spec.containers | grep -E "^ {3}[a-z]"
   args	<[]string>
   command	<[]string>
   env	<[]Object>
   envFrom	<[]Object>
   image	<string>
   imagePullPolicy	<string>
   lifecycle	<Object>
   livenessProbe	<Object>
   name	<string> -required-  # 必须字段
   ports	<[]Object>
   readinessProbe	<Object>
   resources	<Object>
   securityContext	<Object>
   startupProbe	<Object>
   stdin	<boolean>
   stdinOnce	<boolean>
   terminationMessagePath	<string>
   terminationMessagePolicy	<string>
   tty	<boolean>
   volumeDevices	<[]Object>
   volumeMounts	<[]Object>
   workingDir	<string>

# 镜像获取策略
root@kube-master1:~# kubectl explain pod.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
kubectl explain 输出的字段取值表示 取值类型
<string> 字符串类型
<[]string> 字符串列表
<Obeject> 对象,子字段(在 yaml 文件用缩进表示)
<[]Object> 子字段列表(在 yaml 文件中用"-"及其同级缩进的块表示)
<map[string]string> 键值对
<boolean> 布尔值(true/false)
<integer> 整型

使用上面的kubectl explain命令就可以得到某资源的所有配置字段和其接受的数据类型,
pod 中容器的imagePullPolicy字段用于指明镜像获取策略,其接受如下几个值:

  • Always: 当镜像标签为lastest或镜像不存在时总是从指定的仓库中 pull 镜像。
  • IfNotPresent: 仅仅当本地镜像缺失时才从目标仓库 pull 镜像。
  • Never: 禁止从仓库下载镜像,仅从本地下载。

下面的资源清单指明,使用 nginx 最新的镜像创建 pod,镜像获取策略为 Always。

apiVersion: v1
kind: Pod
metadata:
  name: pod-nginx
spec:
  containers:
    - name: nginx
      image: nginx:latest
      imagePullPolicy: Always

需要注意的是,对于 lastest 标签的镜像,默认的拉取策略就是 Always。不是 latest 标签的
镜像则是 IfNotPresent 策略。使用私有的仓库时,拉取镜像需要 Registry 服务器认证完成才
可以。认证过程需要在运行容器的节点上使用docker login命令进行,或者将认证信息定义为
专有的 Secret 资源,并配置 Pod 通过"imagePullSecretes"字段调用此信息完成认证。

root@kube-master1:~# kubectl explain pod.spec.imagePullSecrets | grep -E "^ {,3}[a-z]"
   name	<string>
root@kube-master1:~# kubectl explain pod.spec.imagePullSecrets
KIND:     Pod
VERSION:  v1

RESOURCE: imagePullSecrets <[]Object>

DESCRIPTION:
     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. For example, in the case of docker, only
     DockerConfig type secrets are honored. More info:
     https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod

     LocalObjectReference contains enough information to let you locate the
     referenced object inside the same namespace.

FIELDS:
   name	<string>
     Name of the referent. More info:
     https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

1.2 暴露端口

root@kube-master1:/opt/k8s-data/yaml# kubectl explain Pod.spec.containers.ports | grep -E "^ {3}[a-z]"
   containerPort	<integer> -required-  # 必选字段,指定Pod对象上的IP地址上暴露的容器端口
   hostIP	<string>
   hostPort	<integer>
   name	<string>
   protocol	<string>
字段 说明
containerPort <integer> 必选字段,指定 Pod 对象上的 IP 地址上暴露的容器端口,端口有效范围为 0-65535,应结合容器应用来指定端口。
hostIP 主机端口要绑定的主机 IP,默认为 0.0.0.0 即主机上所有可用的 IP。考虑到 Pod 对象是由调度器调度运行的,工作节点的 IP 地址难以明确指定,因此该字段通常使用默认值。
hostPort 主机端口,它将接受到的请求通过 NAT 机制转发至由 containerPort 字段指定的容器端口。
name 当前端口的名称,在当前 Pod 内必须唯一,该端口名可以被 Service 调用。
protocol 端口相关的协议,取值为 TCP 或 UDP,默认为 TCP。
root@kube-master1:/opt/k8s-data/yaml# cat pod-example.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-example
spec:
  containers:
  - name: mynginx
    image: nginx:1.18.1
    ports:
    - name: http
      containerPort: 80
      protocol: TCP

主要注意的是,Pod 资源的 hostPort 与 Service 之一的 NodePort 暴露端口的方式不一样,NodePort
是通过所有节点暴露容器服务,而 hostPort 则是经由 Pod 对象所在的节点 IP 地址来进行的。

root@kube-master1:/opt/k8s-data/yaml# kubectl explain Service.spec.ports | grep -E "^ {3}[a-z]"
   name	<string>
   nodePort	<integer>  # Service中的端口暴露字段
   port	<integer> -required-
   protocol	<string>
   targetPort	<string>

1.3 自定义运行的容器化应用

Docker 镜像启动容器时运行的应用程序在对应的 Dockerfile 中由 ENTRYPOINT 指令定义,
而传递给容器程序的参数则通过 CMD 命令指定。ENTRYPOINT 指令不存在时,CMD 可用于同
时指定容器启动要默认运行的程序及其参数。例如,在工作节点使用docker inspect命令
可以得到镜像中定义的 CMD 和 ENTRYPOINT 值:

root@node1:~# docker inspect nginx:1.16.1 -f {
   {.Config.Cmd}}
[nginx -g daemon off;]
root@node1:~# docker inspect nginx:1.16.1 -f {
   {.Config.Entrypoint}}
[]

同样,在 K8s 的 Pod 资源的嵌套字段中,command 字段可以用来指定不同于镜像默认的运行
程序,并且可以同时使用 args 字段进行参数传递。这样指定后会覆盖镜像默认的定义,只指
定 args,则作为默认的程序的运行参数,只指定 command,则使用指定程序和无参数运行。

root@kube-master1:/opt/k8s-data/yaml# kubectl explain Pod.spec.containers.command
KIND:     Pod
VERSION:  v1
FIELD:    command <[]string>
DESCRIPTION:
     Entrypoint array. Not executed within a shell. The docker 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. 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. Cannot be updated. More info:
     https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

root@kube-master1:/opt/k8s-data/yaml# kubectl explain Pod.spec.containers.args
KIND:     Pod
VERSION:  v1
FIELD:    args <[]string>
DESCRIPTION:
     Arguments to the entrypoint. The docker 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. 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. Cannot be
     updated. More info:
     https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

例如,下面的资源清单将镜像 nginx:1.16.1 的默认应用程序改为/bin/bash,传递的应用
参数为-c while true ; do sleep 5; done:

root@kube-master1:/opt/k8s-data/yaml# cat pod-example.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-example-cus-cmd
spec:
  containers:
  - name: mynginx
    image: nginx:1.16.1
    command: ["/bin/bash"]
    args: ["-c", "while true; do sleep 5 30; done"]

1.4 环境变量

向 Pod 中的容器环境变量传递数据的方式有两种:env 和 envFrom,其中 envFrom 结合
ConfiMap 和 Secret 资源使用:

root@kube-master1:/opt/k8s-data/yaml# kubectl explain Pod.spec.containers.env | egrep "^ {3}[a-z]"
   name	<string> -required-
   value	<string>
   valueFrom	<Object>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值