【K8s】之 10. Pod基本用法

文章目录

    • 一、简介
      • (1)`Node` 与 `Pod`
    • 二、操作`Pod`
    • 三、标签`label`
      • (1)操作
    • 四、标签选择器
      • (1)操作
      • (2)约束 `pod` 调度
    • 五、命名空间 `namespace`
      • (1)操作
    • 六、如果工作节点`Node`挂掉了,`Pod`如何处理?
      • (1)副本集(RS)
        • 1)操作
      • (2)后台支撑服务集(`DaemonSet`)
        • 1)在每个节点上运行一个
        • 2)在特定的节点上运行一个
      • (3)任务(`Job`)
        • (1)模拟

一、简介


一个 PodKubernetes 最基本的构建单元,也是最小、最简单的构建单元。Pod 也是扩缩容的基本单位,Kubernetes 的扩容和缩容都是直接对 Pod 进行操作的,直接增加 Pod 或是减少 Pod

一个 Pod 包含一个应用容器(有的时候有多个)、存储资源、唯一的网络 IP、以及其它容器运行所必须的资源。

PodKubernetes 集群中主要有两种使用方式:

  • 运行一个单独的容器:这是最常用的方式;在这种情况下,可以认为一个 Pod 封装了一个单独的容器,Kubernetes 是对 pod 进行管理,而不是直接对容器进行管理。

  • 运行耦合度高的多个容器:Pod 也可能包含多个容器,这些容器之间关联紧密需要共享资源。将多个容器添加到单个 Pod 的主要原因是应用可能由一个主进程和一个或多个辅助进程组成。在实践中,把一个进程放到一个容器中运行是最好的。

如图:

【K8s】之 10. Pod基本用法_第1张图片



(1)NodePod

Pod 是运行在 Node 上的。一个 NodeKubernetes 上的工作节点,它可能是虚拟出来的节点或者是物理节点,这取决于集群的部署方式。

每个 Node 节点都被 Master 节点所管理,一个 Node 节点可以运行多个 Pod,在集群中,Kubernetes Master 节点通过 Node 节点自动管理 Pods

每个 Nodes 运行至少需要两个组件:

  • Kubelet:负责 MasterNode 之间的通信,用于管理节点上的 Pod
  • Docker:负责从仓库拉取容器镜像,运行应用等。

如图:

【K8s】之 10. Pod基本用法_第2张图片



二、操作Pod


Pod 和其他 Kubernetes 资源通过向 Kubernetes REST API 提供 JSONYAML 描述文件来创建

编写YAML有4个重要组成部分:

  • apiVersionYAML描述文件所使用的Kubernetes API版本
  • kindKubernetes对象/资源类型
  • metadataPod元数据(名称、命名空间、标签、注解等)
  • specPod规格/内容(容器列表、存储卷等)
  1. 查看pods有哪些属性
    kubectl explain pods

  2. 编写 nginx.yaml文件

此文件定义了一个名为 nginxPod,默认监听在 80 端口

apiVersion: v1
kind: Pod
metadata:
  name: nginx-manual
spec:
  containers:
    - image: registry.cn-hangzhou.aliyuncs.com/chenshi-kubernetes/nginx:1.9.1
      name: nginx
      ports:
        - containerPort: 80
          protocol: TCP
  1. 执行创建 pod
    kubectl create -f nginx.yaml

  2. Pod 列表查看新创建的 Pod
    kubectl get pods

Pod 在整个生命周期中存在各种状态,常见的状态如下图:

【K8s】之 10. Pod基本用法_第3张图片

另外 Pod 的重启策略(RestartPolicy)有 3 种,分别为:

  • Always:默认策略,当容器失效时,kubelet 会自动重启该容器

  • OnFailure:当容器终止运行且退出码不为 0 时,kubelet 会自动重启该容器

  • Never:不论容器运行状态如何,kubelet 都不重启该容器

  1. 查看日志
# pod 上只有一个容器
kubectl logs nginx

# pod 上有多个容器,需要指定参数 -c 容器名 进行查询
kubectl logs nginx -c nginx
  1. 测试pod端口是否可用
# 执行端口转发,将本地 8080 端口转发到 nginx 80端口
kubectl port-forward nginx 8080:80

# 另起一个窗口,访问
curl http://localhost:8080
  1. 删除 Pod
    kubectl delete pod nginx

使用标签选择器删除pod
kubectl delete pod -l creation_method=manual

通过删除整个命名空间的方式来删除pod
kubectl delete ns test1-namespace



三、标签label


可以通过标签来组织 Pod 和所有其他 Kubernetes 资源对象。

通过标签划分组,这样就可以对属于某个组的所有 Pod 进行操作,而不需要单独为某个 Pod 执行操作。

  • 标签是可以附加在 Kubernetes 资源对象的任意键值对,通过标签选择器可以选择具有该确切标签的资源。

  • 标签的 key 是唯一的,一个资源可以拥有多个标签。

  • 创建资源时可以将标签附加在资源上,也可以在现有的资源上添加标签或修改标签值。


(1)操作

  1. yaml文件
apiVersion: v1
kind: Pod
metadata:
  name: nginx-manual-v2
  # 标签
  labels:
    creation_method: manual
    rel: beta
spec:
  containers:
    - image: registry.cn-hangzhou.aliyuncs.com/chenshi-kubernetes/nginx:1.9.1
      name: nginx
      ports:
        - containerPort: 80
          protocol: TCP
  1. 创建pod
    kubectl create -f nginx-manual-with-labels.yaml

  2. 查看 pod 标签
    kubectl get pod --show-labels

  3. 查看某个具体的标签 -L
    kubectl get pod -L creation_method,rel

  4. 修改标签

# 向 nginx-manual 这个 pod 添加一个标签
$ kubectl label pod nginx-manual creation_method=manual
pod/nginx-manual labeled

# 将 nginx-manual-v2 这个 pod 上 rel=beat 修改为 rel=stable
# 需要添加 --overwrite 选项
$ kubectl label pod nginx-manual-v2 rel=stable --overwrite
pod/nginx-manual-v2 labeled


四、标签选择器


标签通常与标签选择器结合在一起使用,标签选择器可以选择标记有特定标签的 Pod 子集,并对这些 Pod 执行操作。

标签选择器对于标签的使用一般有如下 3 种方式:

  • 包含或是不包含使用特定键的标签
  • 包含具有特定键和值的标签
  • 包含有特定键,值可以为任意值的标签

(1)操作

  1. 想要筛选出所有手动创建的 Pod
    kubectl get pod -l creation_method=manual

  2. 列出含有 rel 标签的所有pod
    kubectl get pod -l rel

  3. 列出不含 rel 标签的所有 pod
    kubectl get pod -l '!rel'

  4. 其他的使用方式

# 列出含有 creation_method 标签,但是其值不能为 manual 的 Pod
$ kubectl get pod -l 'creation_method!=manual'
# 列出含有 rel 标签,且其值为 beta 或是 stable 的 Pod
$ kubectl get pod -l 'rel in (beta,stable)'
# 列出含有 rel 标签,且其值不为 beta 和 stable 的 Pod
$ kubectl get pod -l 'rel notin (beta,stable)'
# 列出含有标签 creation_method=manual 和 rel=stable 的 Pod
$ kubectl get pod -l creation_method=manual,rel=stable

(2)约束 pod 调度

Pod 通常都是随机调度到工作节点上。

如果想要将 Pod 调度到 GPU 的工作节点上,可以对相应的节点打上标签,然后在编写 yaml 文件时使用 nodeSelector 指定对应的节点标签。

  1. 查看环境中节点情况
    kubectl get nodes

  2. 选择一个几点打上标签
    kubectl label node kube-node-1 gpu=true

  3. 查看是否打上标签
    kubectl get nodes -l gpu=true

  4. 新建名为 nginx-gpupod

apiVersion: v1
kind: Pod
metadata:
  name: nginx-gpu
spec:
  # 标签选择器
  nodeSelector:
    gpu: "true"
  containers:
    - image: registry.cn-hangzhou.aliyuncs.com/chenshi-kubernetes/nginx:1.9.1
      name: nginx
      ports:
        - containerPort: 80
          protocol: TCP
  1. 创建
$ kubectl create -f nginx-gpu.yaml
pod/nginx-gpu created



五、命名空间 namespace


由于标签和 Pod 是多对多的关系,使用标签可以将众多的 Pod 进行分组,这些组中的 Pod 有交叉重复的可能

使用 命名空间 就可以将对象分隔成完全独立且不重叠的组。

Kubernetes 的命名空间为对象名称提供了一个作用域。

对象名称只需要在一个命名空间内保持唯一,不同的命名空间可以包含同名的对象。


(1)操作

  1. 查看集群中所有的命名空间
    kubectl get namespaces

  2. 查看 kube-system 命名空间下的 Pod

这里的pod都是和 Kubernetes 系统相关的。

$kubectl get pod -n kube-system                       
NAME                                    READY   STATUS    RESTARTS   AGE
coredns-5c98db65d4-zssrt                1/1     Running   0          64m
etcd-kube-master                        1/1     Running   7          272d
kube-apiserver-kube-master              1/1     Running   7          272d
kube-controller-manager-kube-master     1/1     Running   7          64m
kube-proxy-2ddnw                        1/1     Running   0          64m
kube-proxy-fjnhx                        1/1     Running   0          64m
kube-proxy-wldhn                        1/1     Running   0          64m
kube-scheduler-kube-master              1/1     Running   7          272d
kubernetes-dashboard-5ff478f859-d5b2g   1/1     Running   0          64m
  1. 创建新的命名空间
apiVersion: v1
kind: Namespace
metadata:
  name: test1-namespace
  1. 执行创建
    kubectl create -f test1-namespace.yaml

或者直接使用命令
kubectl create namespace test2-namespace

  1. 在新的命名空间中创建 Pod
  • yaml 文件的 metadata 字段中添加 namespace: test1-namespace 属性
  • 创建 Pod 时在命令中使用参数 -n 指定命名空间

比如创建 pod 时候指定

$ kubectl create -f nginx-manual.yaml -n test1-namespace
pod/nginx-manual created



六、如果工作节点Node挂掉了,Pod如何处理?


使用副本集 ReplicaSet 或部署 Deployment 来创建并管理 Pod

这样部署可以自动运行、保持健康、工作节点挂掉之后 Pod 会自动迁移到新的节点,所以几乎不会手动创建 Pod


(1)副本集(RS)

副本集 ReplicaSet 是一种 Kubernetes 资源对象,它可以保证 Pod 始终处于运行状态。

如果 Pod 因任何原因消失,ReplicaSet 会注意到缺少了 Pod 并创建新的 Pod 进行替代。

ReplicaSet 主要用于创建和管理一个 Pod 的多个副本(replicas),核心标准是确保 Pod 的数量始终与其标签选择器匹配,它会持续监控正在运行的 Pod 列表,并保证带有对应标签的 Pod 数量与期望相符,如果运行的 Pod 太少会根据 Pod 模板创建新的副本;如果运行的 Pod 太多就会删除多余的副本。

ReplicaSet 由 3 个部分组成:

  • 标签选择器(label selector): 确定 ReplicaSet 作用域中有哪些 Pod
  • 副本个数(replica count): 指定应运行的 Pod 数量
  • Pod 模板(pod template): 用于创建新的 Pod 副本

上述的 3 个部分都可以随时修改,只有副本个数的变更会影响到现有的 Pod,更改标签选择器和 Pod 模板对现有的 Pod 没有影响。

如果更改标签选择器会使现有的 Pod 脱离 ReplicaSet 的范围,ReplicaSet 会停止关注它们;如果更改模板,只会对新创建的 Pod 应用新的模板,并不会影响现在存在的 Pod

使用 ReplicaSet 有以下 3 大好处:

  • 保证 Pod 持续运行,如果现有 Pod 数量不符合预期将会自动调整 Pod 的数量;
  • 当集群节点发生故障时,在故障节点受 ReplicaSet 控制的所有 Pod 会被创建新的替代副本;
  • 可以轻松实现 Pod 的水平伸缩。

注意, 这里的标签选择器可以匹配如下的标签:

  • 具有某个特定标签名和值的 Pod
  • 缺少某个标签的 Pod
  • 包含特定标签名,不管其值为多少的 Pod
  • 匹配多个标签,只要符合其中一个标签就认为是符合标准的

1)操作

创建一个 ReplicaSet

  1. nginx-replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: registry.cn-hangzhou.aliyuncs.com/chenshi-kubernetes/nginx:1.9.1
  1. 执行创建
    kubectl create -f nginx-replicaset.yaml

  2. 查看创建的 podreplicaSet

$ kubectl get pods
$ kubectl get rs
  1. 查看详细描述
    kubectl describe rs

  2. 删除定义的ReplicaSet

删除 ReplicaSet同时,会删除对应匹配的所有 Pod

kubectl delete rs nginx


(2)后台支撑服务集(DaemonSet

ReplicaSet 用于在 Kubernetes 集群上运行部署特定数量的 Pod,如果你希望在集群的每个 Node 上都运行某个 Pod,这个时候就需要使用到 DaemonSet 了,当有节点加入集群时,会为它们新增一个 Pod

当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。

DaemonSet 的使用情况分为两种:

  • 在每个节点上运行一个 Pod
  • 在特定的节点上运行一个 Pod

1)在每个节点上运行一个

  1. 创建yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: mysql-ds
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "123456"
  1. 执行创建
$ docker pull mysql:5.7
$ kubectl create -f mysql-ds.yaml
  1. 观察 Pod 是否分布到了每个节点上
$ kubectl get nodes
$ kubectl get pods -o wide

2)在特定的节点上运行一个

只需要在模板中的nodeSelector属性中指明即可。

  1. 先给节点打个标签
$ kubectl label node kube-node-1 disk1=ssd1
node/kube-node-1 labeled
  1. 创建yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: tomcat-ssd
spec:
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      nodeSelector:
        disk1: ssd1
      containers:
        - name: tomcat
          image: kubeguide/tomcat-app:v1
  1. 执行创建
$ kubectl create -f tomcat-ssd.yaml
daemonset.apps/tomcat-ssd created
  1. 更改标签,观察 DaemonSet 创建的 Pod是否还存在?
$ kubectl label node kube-node-1 disk1=hdd --overwrite
node/kube-node-1 labeled
  1. 查看节点上的 pod
    kubectl get pod

pod已经终止了。


(3)任务(Job

ReplicaSetDaemonSet 监控管理的 Pod 会持续不断的运行任务,这样的任务是没有完成态的,如果其中的进程退出了 Pod 会重新启动。

如果想要执行一个可完成的任务,当进程终止后 Pod 不再重新启动,那么就需要使用任务 (Job)。

当节点发生故障的时候,该节点上由 Job 管理的 Pod 会按照 ReplicaSetPod 的方式,重新安排到其它节点;如果进程异常退出,可以将 Job 配置为重新启动容器。


(1)模拟

模拟一个任务,有一个构建在 busybox 上的容器,该容器会调用 sleep 命令休息两分钟,然后就正常退出。

  1. 创建yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: batch-job
spec:
  template:
    metadata:
      labels:
        app: batch-job
    spec:
      # 当容器中的进程运行结束时,kubernetes会如何做
      restartPolicy: OnFailure
      containers:
        - name: main
          image: luksa/batch-job
  1. 执行创建
$ kubectl create -f sleep.yaml
job.batch/batch-job created
  1. 查看 JobPod
$ kubectl get jobs
$ kubectl get po

如果想让一项任务按顺序一次执行 10 次,可以使用 completions属性

spec:
  completions: 10
  template: ...

如果想要一项任务总共运行 10 次,每次可以并行执行 3个 Pod,可以使用 parallelism属性

spec:
  completions: 10
  parallelism: 3
  template: ...

你可能感兴趣的:(【K8s】)