K8s-Pod

Pod介绍

概念:Pod是kubernetes中最小的资源管理组件,Pod也是最小化运行容器化应用的资源对象。一个Pod代表着集群中运行的一个进程。kubernetes中其他大多数组件都是围绕着Pod来进行支撑和扩展Pod功能的,例如,用于管理Pod运行的rcc和Deployment等控制器对象。

当一个 pod 包含多个容器时,这些容器总是运行于同一个工作节点上——一个 pod 绝不会跨越多个工作节点;一个Pod的所有容器都运行在同一个节点上。

image.png

why Pod

①多个容器比单个容器有多个进程要好:https://www.cnblogs.com/yzgblogs/p/16068352.html

②多个提供密切相关进程的容器绑定在一起,可以共享存储(Volumes)、网络(IP)。K8s通过配置Docker,使得一个 pod 内的所有容器共享相同的 Linux 命名空间(共享Network 和UTS 命名空间)。在默认情况下,每个容器的文件系统与其他容器完全隔离。但我们可以使用名为 Volumes的 Kubernetes 资源来共享文件目录。

  • 同一个Pod中的容器不能绑定相同的端口

  • 同一个Pod内的容器可以通过localhost与其他容器进行通信

  • 每个Pod都有独立的端口空间,不同Pod的容器不会出现端口冲突的情况

Pod间的扁平化网络:

Kubernetes 集群中的所有 pod 都在同一个共享网络地址空间中,每个 pod 都可以通过其他 pod 的 IP 地址来实现相互访问,即这些 pod 之间没有 NAT (网络地址转换)网关。当两个 pod 彼此之间发送网络数据包时,它们都会将对方的实际 IP 地址看作数据包中的源 IP。

image.png

通过Pod管理容器

K8s不能扩缩一个Pod内的单个容器,只能扩缩整个Pod。

将多层应用分散到多个Pod中断,例如:web服务器和数据库可以分开在不同的Pod,提高对KK8s集群资源的利用

紧密耦合到容器组可以添加到同一个 pod 中:通常为一个主容器和若干个支持容器。例如:主容器是一个仅仅服务于某个目录中的文件的WEB服务器,而辅容器为从定期下载内容并存储在web服务器目录中,日志收集器、数据处理器、通讯适配器等。

多个容器是否可以在一个Pod中的判断标准:

  • 它们需要一起运行还是可以在不同的主机上运行?

  • 它们代表的是一个整体还是相互独立的组件?

  • 它们必须一起进行扩缩容还是可以分别进行?

    image.png

通过YAML/json描述文件创建pod

pod或其他K8s资源通常通过调用k8s的rest api + ymal/json文件来创建的  。通过 YAML 文件定义所有的 Kubernetes 对象之后,还可以将它们存储在版本控制系统中,充分利用版本控制所带来的便利性。

检查现有 pod 的 YAML 描述文件

命令可以查看指定 pod 的完整 YAML 定义

kubectl get pod -o yaml <pod-name>

介绍 pod 定义的主要部分 

  • YAML 中使用的 Kubernetes API 版本和YAML 描述的资源类型

  • metadata: 包括名称、命名空间、标签和关于该容器的其他信息

  • spec: 包含 pod 内容的实际说明,例如 pod 的容器、卷和其他数据

  • status: 包含运行中的 pod 的当前信息,例如 pod 所处的条件、每个容器的描述和状态,以及内部 IP 和其他基本信息

                status 包含只读的运行时数据,该数据展示了给定时刻的资源状态。在创建新的 pod 时, status 部分不需要提供

apiVersion: v1                   -----# 遵循 v1 版本的 Kubernetes API
kind: Pod                        -----# 资源类型为 Pod
metadata:
  name: kubia-manual             -----# pod 的名称 
spec:
  containers:
  # 创建容器所使用的镜像
  - image: idealism/kubia
    # 容器的名称
    name: kubia
    ports:
    # 应用监听的端口
    - containerPort: 8080
      protocol: TCP

使用 kubectl explain 发现可用的 API 对象字段, kubectl explain pod 可以查看 pod 的 各个属性,然后通过选择对应的属性 (kubectl explain pod.spec) 深入了解每个属性的更多信息

使用 kubectl create 来创建 pod 

可以通过kubectl create -f 命令用来给yaml、json文件创建任何资源(不只是pod资源)

kubectl create -f <yaml_file_name>

使用kubectl get pods 可以获得默认命名空间内的所有Pod名称与状态。若要查看特定命名空间的Pod名称,可以使用命令 kubectl get pods -n <namespace_name>

kubectl get pods -n ranoss

使用kubectl get pod <pod_name> -n <namespace_name> -o yaml命令可以查看指定租户下,指定pod的yaml文件信息。

查看应用程序的日志

容器化的应用程序通常会将日志记录到标准输出和标准错误流,而不是写入文件,这就允许用户可以通过简单、标准的方式查看不同应用程序的日志。 

docker logs <container>   允许我们查看主机上指定容器的日志

kubectl logs  -n <namespace_name> <pod_name> -c <container> 允许我们查看指定 pod 中指定容器的日志,如果该 pod 只包含一个容器,那么 -c <container> 可以省略

当一个 pod 被删除时,它的日志也会被删除。如果希望在 pod 删除之后仍然可以获取其日志,我们需要设置中心化的、集群范围的日志系统,将所有日志存储到中央存储中

标签组织Pod

通过标签来组织Pod和所有其他K8s对象。标签是附加在资源的任意键值对,用以选择具有该标签的资源(通过标签选择器完成)。只要标签在资源内是唯一的,一个资源就可以拥有多个标签。

可以在创建资源的时候将标签附加到资源上,也可以在资源已经创建的前提下,添加其他标签或者修改现有标签的值。

app: 基于应用的横向纬度,指定 pod 属于哪一个应用、组件或微服务

rel: 基于版本的纵向纬度,显示在 pod 中运行的应用程序版本 (stable----稳定的版本, beta----测试版本, canary----体验版本)

image.png

在创建资源时附加标签,可以在yaml文件中的metadata.labels 定义。例如:

# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 资源类型为 Pod
kind: Pod
metadata:
  # pod 的名称
  name: kubia-manual-v2
  # pod 的标签
  labels:
    creation_method: manual
    env: prod
spec:
  containers:
    # 创建容器所使用的镜像
    - image: idealism/kubia
      # 容器的名称
      name: kubia
      ports:
        # 应用监听的端口
        - containerPort: 8080
          protocol: TCP

在如上的yaml文件中,定义Pod名称为kubia-manual-v2的所属标签为 creation_method: manual,env: prod。

使用 --show-labels 参数,可以查看资源的标签信息。若只想查看某个标签,可以使用 参数  -L 进行筛选

标签可以在现有资源上进行添加或修改。 

 使用  kubectl label pod <pod_name> <label_key=label_value>  可以对pod新增标签。

使用  kubectl label pod <pod_name> <label_key=label_value> --overwrite  可以对pod已有标签进行修改。

标签选择器

标签选择器允许我们选择标记有特定标签的 pod 子集,并对这些 pod 执行操作,它可以根据资源的以下条件来选择资源: 

  • 包含(或不包含)使用特定键的标签

  • 包含具有特定键和值的标签

  • 包含具有特定键的标签,但其值与我们指定但不同

使用标签选择器列出 

kubectl get pods -l creation_method=manual       : 列出包含 creation_method=manual 标签的所有 pod

kubectl get pods -l env       : 列出有 env 标签的所有 pod ,无论其值为如何

kubectl get pods -l '!env'    : 列出没有 env 标签的所有 pod

kubectl get pods -l creation_method!=manual       : 列出有 creation_method 标签但其值不等于 manual 的所有 pod

kubectl get pods -l 'env in (debug, prod)'           : 列出有 env 标签并且其值为 debug 或 prod 的所有 pod

kubectl get pods -l 'env notin (debug, prod)'        : 列出没有 env 标签,或者有 env 标签并且其值不为 debug 和 prod 的所有 pod

另外,在包含多个逗号分割的情况下,可以在标签选择器中同时使用多个条件,此时资源只有全部匹配才算成功。

使用标签选择器和标签调度Pod

某些情况下,我们希望对将 pod 调度到何处持有一定发言权,例如:硬件基础设施不同质。 

  • 某些工作节点使用机械硬盘,其他节点使用固态硬盘。可能想将一些 pod 调度到一组节点,同时将其他 pod 调度到另一组节点

  • 将执行 GPU 密集型运算的 pod 调度到实际提供 GPU 加速到节点上

K8s希望屏蔽应用程序和基础架构耦合,但是又想保持对Pod调度到哪个节点拥有发言权,这种情况下,我们应该用某种方式描述对节点的需求,使 Kubernetes 选择一个符合这些需求的节点,这恰好可以通过节点标签和节点标签选择器完成。

使用标签分类工作节点

通过附加标签来对节点进行分类,这些标签指定节点提供对硬件类型,或者任何调度 pod 时能提供便利对其他信息。例如,若某个节点包含了用于GPU计算的GPU,可以给这个节点打上标签gpu=true

#列出所有节点
kubectl get nodes

#给节点打上标签   kubectl label node <node_name> <label_key=label_value>
kubectl label node 21.5.10.101 gpu=true

##展示节点的所有标签
kubectl get nodes  --show-labels

#展示包含某个标签的节点     kubectl get nodes -l <label_key=label_value>
kubectl get nodes -l gpu=true

将 pod 调度到特定节点

基于 kubia-manual-gpu.yaml 创建一个新的描述文件 kubia-manual-gpu.yaml ,并添加 spec.nodeSelector 属性,指定选择的标签为 gpu=true 。这样当我们创建该 pod 时,调度器将只在包含标签 gpu=true 的节点中选择。 

# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 资源类型为 Pod
kind: Pod
metadata:
  # pod 的名称
  name: kubia-manual-gpu
  # pod 的标签
  labels:
    creation_method: manual
    env: prod
spec:
  # 节点选择器
  nodeSelector:
    # 选择的标签
    gpu: "true"

我们也可以将 pod 调度到某个确定的节点,由于每个节点都有一个唯一标签 kubernetes.io/hostname ,值为该节点的实际主机名,因此我们也可以将 pod 调度到某个确定的节点。但如果节点处于离线状态,那么可能会导致 pod 不可调度。我们绝不应该考虑单个节点,而是应该通过标签选择器考虑符合特定标准但逻辑节点组。

使用命名空间对资源进行分组

Kubernetes 命名空间简单地为对象名称提供了一个作用域。此时我们并不会将所有资源都放在同一个命名空间中,而是将它们组织到多个命名空间中,这样可以允许我们多次使用相同的资源名称(跨不同的命名空间)。 

了解对命名空间的需求

在使用多个命名空间的前提下,我们可以将包含大量组件的复杂系统拆分成更小的不同组,这些不同组也可以用于在多租户环境中分配资源,将资源分配为生产、开发和 QA 环境,或者以其他任何需要的方式分配资源。资源名称只需要在命名空间内保持唯一即可,因此两个不同的命名空间可以包含同名的资源。 

大多数类型的资源都与命名空间相关,但仍有一些与它们无关,其中之一便是全局且未被约束于单一命名空间但节点资源。

发现其他命名空间及其 pod

kubectl get namespaces: 列出集群中的所有命名空间

kubectl get pods -n kube-system: 列出 kube-system 命名空间下的所有 pod

命名空间的优点

可以隔离资源,将不属于一组的资源分到不重叠的组中,避免无意中修改或删除其他用户的资源,也无须关心名称冲突

可用于仅允许某些用户访问某些特定的资源,甚至限制单个用户可用的计算资源数量

创建一个命名空间

命名空间是一种和其他资源一样的 Kubernetes 资源,因此可以通过 YAML 文件提交到 Kubernetes API 服务器来创建该资源。

从 YAML 文件创建命名空间 

# 遵循 v1 版本的 Kubernetes API
apiVersion: v1
# 资源类型为 Namespace
kind: Namespace
metadata:
  # 命名空间的名称
  name: custom-namespace

kubectl create -f custom-namespace.yaml 可以通过 YAML 文件创建命名空间。

Kubernetes 中的所有内容都是一个 API 对象,可以通过向 API 服务器提交 YAML 文件来实现创建、读取、更新和删除。

使用 kubectl create namespace 命令创建命名空间

kubectl create namespace <namespace-name>: 创建一个指定名称的命名空间

管理其他命名空间中的对象 

kubectl create -n custom-namespace -f kubia-manual.yaml: 在 kubia-manual 命名空间中通过指定的 YAML 文件创建一个资源。

如果不指定命名空间, kubectl 将在当前上下文中配置的默认命名空间中执行操作。而当前上下文的命名空间和当前上下文本身都可以通过 kubectl config 命令进行更改。

命名空间提供的隔离 

尽管命名空间将对象分隔到不同更多组,只允许你对属于特定命名空间的对象进行操作,但实际上命名空间之间并不提供对正在运行对对象对任何隔离。例如,若K8s集群中的网络解决方案中不提供网络隔离时,不同命名空间间仍然可以通过pod的IP进行通信。

停止和移除 pod

按名称删除 pod 

kubectl delete pod -n <namespace-name> <pod-name-1> [<pod-name-2> ...]: 删除指定命名空间下的指定 pod 。

在删除 pod 的过程中,实际上我们在指示 Kubernetes 终止该 pod 中的所有容器。 Kubernetes 向进程发送一个 SIGTERM 信号并等待一定的秒数(默认为 30 秒),使其正常关闭,如果它没有即使关闭,则通过 SIGKILL 终止该进程。因此,为了确保你的进程总是正常关闭,进程需要正确处理 SIGTERM 信号。 

使用标签选择器删除 pod 

kubectl delete pod -n <namespace-name> -l <label-key>=<label-value>: 删除指定命名空间下含有指定标签的所有 pod 。 

在微服务示例中,通过指定 rel=canary 标签选择器,可以一次删除所有金丝雀 pod 。

image.png

通过删除整个命名空间来删除 pod

kubectl delete namespace custom-namespace: 删除整个 custom-namespace 命名空间( pod 将会随命名空间自动删除)

删除命名空间中的所有 pod ,但保留命名空间

kubectl delete pod -n <namespace-name> --all: 删除指定命名空间中的所有 pod 。

若在该命名空间内,使用kubectl run命令创建了pod。则可能出现执行上面删除命名空间的所有pod后,仍然在该命名空间中出现pod的情况,这个是因为当删除了由ReplicationCcontroller(kubectl run命令不会直接创建pod,而是创建一个ReplicationCcontroller,再由ReplicationCcontroller创建一个pod)创建的pod后,他会重新创建一个新的pod。

删除命名空间中的(几乎)所有资源

kubectl delete all -n <namespace-name> --all: 删除指定命名空间中的所有资源。 all 指定删除所有资源类型, --all 选项指定删除所有资源实例。

注意:使用 all 关键字并不会真的完全删除所有内容。一些资源会被保留下来,并且需要被明确指定删除。如:Secret

注意:该命令也会删除名为 kubernetes 的 Service ,但它会在几分钟后自动重新创建。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值