学习笔记
分享学习经验,记录生活点滴

pod : 运行于Kubernetes中的容器

pod

一、pod介绍

​ 一个pod是一组紧密相关的容器,它们总是一起运行在同一个工作节点上,以及同一个Linux命名空间中。每个pod就像一个独立的逻辑机器,拥有自己的IP、主机名、进程等,运行一个独立的应用程序。应用程序可以是单个进程,运行在单个容器中,也可以是一个主应用进程或者其他支持进程,每个进程都在自己的容器中运行。、

一个pod绝不会跨越多个工作节点

​ 一个pod的所有容器都运行在同一个逻辑机器上,而其他pod中的容器,即使运行在同一个工作节点上,也会出现在不同的节点上。

多个容器比单个容器中包含多个进程要好

​ 容器被设计为每个容器只运行一个进程(除非进程本身产生子进程)。如果在单个容器中运行多个不相关的进程,那么保持所有进程运行、管理它们的日志等将很困难。

​ 由于不能将多个进程聚集在一个单独的容器中,所以需要另一种更高级的结构来将容器绑定在一起,并将它们作为一个单元进行管理,这就是pod背后的根本原理。

​ 在包含容器的pod下,我们可以同时运行一些密切相关的进程,并为它们提供(几乎)相同的环境,此时这些进程就好像全部运行于单个容器中一样,同时又保持着一定的隔离。这样一来,我们便能全面地利用容器所提供的特性,同时对这些进程来说它们就像运行在一起一样,实现两全其美。

同一pod中容器之间的部分隔离

​ 期望隔离容器组,而不是单个容器,并让每个容器组内的容器共享一些资源,而不是全部(换句话说,没有完全隔离)。Kubernetes通过配置Docker来让一个pod内的所有容器共享相同的Linux命名空间,而不是每个容器都有自己的一组命名空间。

容器如何共享相同的IP和端口空间

​ 由于一个pod中的容器运行于相同的Network命名空间中,因此它们共享相同的IP地址和端口空间。这意味着在同一pod中的容器运行的多个进程需要注意不能绑定到相同的端口号,否则会导致端口冲突,但这只涉及同一pod中的容器。由于每个pod都有独立的端口空间,对于不同pod中的容器来说则永远不会遇到端口冲突。

将多层应用分散到多个pod中

​ 不应该将应用程序都放到单一pod中的原因就是扩缩容。pod也是扩缩容的基本单位,对于Kubernetes来说,它不能横向扩缩单个容器,只能扩缩整个pod。

何时在pod中使用多个容器

​ 将多个容器添加到单个pod的主要原因是应用可能由一个主进程和一个或多个辅助进程组成。

总结:pod是逻辑主机,其行为与非容器世界中的物理主机或虚拟机非常相似。此外,运行在同一个pod中的进程与运行在同一物理机或虚拟机上的进程相似,只是每个进程都封装在一个容器之中。

二、以YAML或JSON描述文件创建pod

​ pod和其他Kubernetes资源通常是通过向Kubernetes RESTAPI提供JSON或YAML描述文件来创建的。此外还有其他更简单的创建资源的方法,比如使用kubect1 run命令,但这些方法通常只允许配置一组有限的属性。另外,通过YAML文件定义所有的Kubernetes对象之后,还可以将它们存储在版本控制系统中,充分利用版本控制所带来的便利性。

检查现有pod的YAML描述文件

$ kubect1 get po kubia-zxzij -o yaml

为pod创建一个简单的YAML描述文件

apiVersion:v1  #描述文件遵循v1版本的Kubernetes API
kind:pod       #说明在描述一个pod
metadata:
    name:kubia-manual-v2  #pod的名称
spec:
    containers:
    -image:luksa/kubia  #创建容器所用的镜像
    name:kubia          #容器的名称
    ports:
    -containerPort:8080 #应用监听的端口
        protocol:TCP

使用kubectl create来创建 pod

​ 使用kubectl create命令从YAML文件创建pod:

$ kubectl create -f kubia-manual.yaml

kubect1 create -f命令用于从YAML或JSON文件创建任何资源(不只是pod)。

得到运行中pod的完整定义

$ kubect1 get po kubia-manual -o yaml

也可以让kubect1返回JSON格式而不是YAML格式(即使使用YAML创建pod,同样也可以获取JSON格式的描述文件)

$ kubect1 get po kubia-manual -o json

在pod列表中查看新创建的pod

$ kubectl get pods

查看应用程序日志

使用ssh命令登录到pod正在运行的节点,并使用docker logs命令查看其日志。(有点麻烦)

$ docker logs <container id>

Kubernetes提供了一种更为简单的方法。

$ kubectl logs kubia-manual

获取多容器pod的日志时指定容器名称

$ kubectl logs kubia-manual -c kubia

向pod发送请求

将本地网络端口转发到pod中的端口

如果想要在不通过service的情况下与某个特定的pod进行通信(出于调试或其他原因),Kubernetes将允许我们配置端口转发到该pod。可以通过kubect1 port-forward命令完成上述操作。例如以下命令会将机器的本地端口8888转发到我们的kubia-manual pod的端口8080:

$ kubectl port-forward kubia-manual 8888:8080

此时端口转发正在运行,可以通过本地端口连接到我们的pod。

通过端口转发连接到pod

在另一个终端中,通过运行在localhost:8888上的kubectl port-forward代理,可以使用cur1命令向pod发送一个HTTP请求:

$ curl localhost:8888

三、使用标签组织pod

标签是可以附加到资源的任意键值对,用以选择具有该确切标签的资源(这是通过标签选择器完成的)。只要标签的key在资源内是唯一的,一个资源便可以拥有多个标签。

创建一个名为kubia-manual-with-labels.yaml的新文件。

apiVersion:v1  #描述文件遵循v1版本的Kubernetes API
kind:pod       #说明在描述一个pod
metadata:
    name:kubia-manual  #pod的名称
    labels:
        creation_method:manual  #两个标签被附加到pod上
        env:prod
spec:
    containers:
    -image:luksa/kubia  #创建容器所用的镜像
    name:kubia          #容器的名称
    ports:
    -containerPort:8080 #应用监听的端口
        protocol:TCP

kubect1 get pods命令默认不会列出任何标签,但我们可以使用--show-labels选项来查看:

$ kubectl get po --show-labels

如果只对某些标签感兴趣,可以使用-L选项指定它们并将它们分别显示在自己的列中,而不是列出所有标签。

$ kubectl get po -L creation_method,env

修改现有pod的标签

标签也可以在现有pod上进行添加和修改。由于pod kubia-manual也是手动创建的,所以为其添加creation_method=manual标签:

$ kubectl label po kubia-manual creation_method=manual

更改现有标签时,需要使用--overwrite选项。

$ kubectl label po kubia-manual-v2 env=debug --overwrite

四、通过标签选择器列出pod子集

使用标签选择器列出pod:

$ kubectl get po -l creation method=manual

列出包含env标签的所有pod,无论其值如何:

$ kubectl get po -l env

列出没有env标签的pod:

$ kubectl get po -l '!env'

五、使用标签和选择器来约束pod调度

使用标签分类工作节点

假设集群中的一个节点刚添加完成,它包含一个用于通用GPU计算的GPU。希望向节点添加标签来展示这个功能特性,可以通过将标签gpu=true添加到其中一个节点来实现(只需从kubect1 get nodes返回的列表中选择一个):
$ kubectl label node gke-kubia-85f6-node-0rrx gpu=true

将pod调度到特定节点

假设我们想部署一个需要GPU来执行其工作的新pod。为了让调度器只在提供适当GPU的节点中进行选择,我们需要在pod的YAML文件中添加一个节点选择器。使用以下代码清单中的内容创建一个名为kubia-gpu.yaml的文件,然后使用kubect1 create -f kubia-gpu.yaml命令创建该pod。

apiVersion:v1
kind:Pod
metadata:
    name:kubia-gpu
spec:
    nodeSelector:
        gpu:"true"  #节点选择器要求Kubernetes只将pod部署到包含标签gpu=true的节点上
    containers:
    -image:luksa/kubia
    name:kubia

六、注解pod

添加和修改注解

$ kubectl annotate pod kubia-manual mycompany.com/someannotation="foo bar"

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

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

$ kubectl get ns

使用kubect1命令指定命名空间来列出只属于该命名空间的pod:

$ kubectl get po --namespace kube-system

可以使用-n来代替--namespace

创建一个命名空间

从YAML文件创建命名空间

apiVersion:v1
kind:Namespace
metadata:
    name:custom-namespace #这是命名空间的名称

使用kubect1将文件提交到Kubernetes API服务器:

$ kubectl create -f custom-namespace.yaml

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

$ kubectl create namespace custom-namespace

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

如果想要在刚创建的命名空间中创建资源,可以选择在metadata字段中添加一个namespace:custom-namespace属性,也可以在使用kubectl create命令创建资源时指定命名空间:

$ kubectl create -f kubia-manual.yaml -n custom-namespace

八、停止和移除pod

按名称删除pod

$ kubectl delete po kubia-gpu

还可以通过指定多个空格分隔的名称来删除多个pod

使用标签选择器删除 pod

$ kubectl delete po -l creation_method=manual

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

$ kubectl delete ns custom-namespace

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

$ kubectl delete po --all

会保留一些备份---ReplicationCcontroller

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

通过使用单个命令删除当前命名空间中的所有资源,可以删除ReplicationCcontroller和pod,以及我们创建的所有service:

$ kubectl delete all --al1

命令中的第一个all指定正在删除所有资源类型,而--a11选项指定将删除所有资源实例,而不是按名称指定它们。

赞(6) 打赏
未经允许不得转载:ABCLearning » pod : 运行于Kubernetes中的容器
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

阿里云限时红包 助力一步上云

了解详情领取红包

觉得文章有用就打赏一下文章作者

微信扫一扫打赏