K8s Pod和namespace

什么是Pod

Pod是Kubernetes中可以创建和部署的最小单位。

Pod为一个或多个container的组合,K8s为了便于管理container,将他们封装为pod。

Pod的特点

Pod的特点:

  • Pod包含1到多个container
  • 同一Pod中的container只会运行在同一个节点中。不可能跨节点。

每个container只运行一个应用进程。如果应用包含多个进程,需要使用多个container。Pod将这些相关的container组合到一起。

一个Pod中的所有container:

  • 使用同一个namespace
  • 共享同一个hostname和网络接口
  • 文件系统完全隔离,不共享

同一pod的container如果绑定同一个端口会存在端口冲突。但不同的pod中的container不会存在此问题。

pod是kubernetes管理的最小单位。pod当然也是应用水平扩展(运行多个实例)时的最小单位。

多层应用需要拆分到多个pod。

同一个pod包含的container用途需要紧密相关。

pod没有自愈能力,也没有横向扩展能力。因此生产中pod需要和controller配合使用。

在K8s中,pod被认为是一种临时的对象。

数据卷(volume)和pod具有相同的生命周期,如果pod删除后重新创建,这个pod关联的数据卷也会删除并重建。

网络

每一个pod分配一个独立的IP地址。同一个pod使用同一个网络namespace。位于同一个pod内的所有container都是用相同的网络namespace,包括IP地址和端口号。这些container可以通过localhost的方式访问其他的container。

存储

可以为pod指定一个或多个共享的数据卷(volume)。pod内的所有container都可以访问这个数据卷。

Pod终止过程

以pod的删除过程为例说明下pod是终止过程。

  1. 用户发出删除pod指令,默认pod删除宽限时间为30秒。
  2. API server中该pod的状态被更新。Pod在宽限时间之后会被认为dead。
  3. Pod进入Terminating状态。
  4. 和步骤3同时进行。当kubelet发现API server中Pod被标记为terminating,开始终止pod的过程。如果pod定义了preStop hook,调用preStop hook的逻辑。如果preStop过程在宽限时间到之后仍在运行,kubelet会请求额外的2秒宽限时间。接下来发送TERM信号到container。
  5. 和步骤3同时进行。pod从endpoint中移除。service不会再转发流量到这个pod。并且controller不再认为这个pod处于运行状态。
  6. 当宽限时间到达之时,发送SIGKILL指令到pod中所有进程。
  7. Kubelet完成删除pod过程,告诉API server设置宽限时间为0,意味着立即删除。Pod消失,再也不会被客户端查询到。

可以使用

kubectl delete pod ... --grace-period=<seconds>

覆盖默认的宽限时间。

可以使用如下命令强制删除pod

kubectl delete pod ... --grace-period=0 --force

Pod描述文件模板

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
apiVersion: v1
kind: Pod
metadata:
    name: kubia-manual
spec:
    containers:
        - image: luksa/kubia
          name: kubia
          ports:
          - containerPort: 8080
            protocol: TCP

注意:修改pod template不会对已经创建出的pod生效。

Pod Phase

PodStatus(pod 状态)具有一个phase字段。

PodPhase的可能值和解释:

描述
Pending k8s已接收到,但是container没有被创建。pod被调度或者在下载镜像的时候也是Pending状态
Running pod被分配到某个node,pod中所有container都被创建。至少一个container在运行中,或者处于启动中,重启中状态
Succeeded pod中所有的container以succeeded状态结束,不会再重启
Failed 所有的container已终止运行,其中至少一个container以failed状态结束
Unknown 无法获取pod状态,典型的情况为和pod所在主机通信异常

Pod Condition

PodStatus有一个PodConditions字段。该字段是一个数组,有如下6个部分:

  • lastProbeTime: 上一次更新pod情况的时间。
  • lastTransitionTime: 上一次pod状态变更的时间。
  • message: 状态变更的详细描述。
  • reason: 一个驼峰命名的单词描述上次状态变更的原因。
  • status: True False或Unknown。
  • type: 有如下值
    • PodScheduled: pod被调度到了node
    • Ready: pod可以接受请求。归service的负责均衡管理。
    • Initialized: 所有的init container启动成功。
    • Unschedulable: pod无法被调度,比如说资源不足或其他原因。
    • ContainersReady: 所有的container启动成功。

Container probes

Probe是kubelet针对container周期性触发的诊断操作。Kubelet调用container的handler进行诊断操作。Handler有如下三种类型:

  • ExecAction: 在container执行特定命令。命令的退出状态码为0会被认为诊断无异常。
  • TCPSocketAction: 发送TCP请求。如果目标端口开放则诊断无异常。
  • HTTPGetAction: 发送HTTP GET请求。返回200到400之间(包括200)的状态码表示诊断无异常。

Probe有3种:

  • livenessProbe: 检查container是否在运行。如果liveness probe失败,kubelet会kill掉container。接下来container会根据restartPolicy确定是否重启。如果没配置livenessProbe,默认状态是Success。
  • readinessProbe: 检查pod是否已就绪对外提供服务。如果fail,endpoint会移除该pod的IP地址。在initial delay之前,此probe的默认值为Failure。如果没配置readinessProbe,默认状态为Success。
  • startupProbe: 检查pod是否已启动。如果配置了startupProbe,其他的probe会被禁用,直到startupProbe状态为Success才会启用其他的probe。如果startupProbe失败,kubelet会kill掉container。接下来container会根据restartPolicy确定是否重启。如果没有配置startupProbe,默认状态为Success。

livenessProbe的例子

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - args:
    - /server
    image: k8s.gcr.io/liveness
    livenessProbe:
      httpGet:
        # when "host" is not defined, "PodIP" will be used
        # host: my-host
        # when "scheme" is not defined, "HTTP" scheme will be used. Only "HTTP" and "HTTPS" are allowed
        # scheme: HTTPS
        path: /healthz
        port: 8080
        httpHeaders:
        - name: X-Custom-Header
          value: Awesome
      initialDelaySeconds: 15
      timeoutSeconds: 1
    name: liveness

Container States

可以使用

kubectl describe pod [POD_NAME]

来查看container state。

Container state有如下值:

  • Waiting: container state默认值。如果container既没有运行又没有终止,它处于waiting状态。
  • Running: container在运行,没遇到任何问题。
  • Terminated: container运行完毕,已经终止。运行完毕成功退出或者运行失败都是Terminated状态。

Restart Policy

具有三个值:

  • Always
  • OnFailure
  • Never

RestartPolicy位于PodSpec配置中,对pod内所有的container生效。

Container的重启延迟时间会指数级增长(最多为5分钟),启动成功10分钟之后,重启延迟时间重置。

Init Container

Init Container在应用程序container之前运行。

一个pod可以具有一个或多个init container。

Init container具有如下特点:

  • 总是会运行完毕退出。
  • 每个init container依次运行,一个运行成功再运行下一个。

如果init container运行失败,kubenetes会反复重启pod直到运行成功。如果RestartPolicy配置为Never,pod不会被重启。

Init Container和应用Container的不同之处

  1. 资源限制不同,详情参见https://kubernetes.io/docs/concepts/workloads/pods/init-containers/#resources
  2. 不支持ReadinessProbe

Init Container使用例子

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']

Init Container的行为

如果pod的RestartPolicy为Always,它所有init container的RestartPolicy为OnFailure。

如果pod重启,pod的init container必须要重新执行。

使用activeDeadlineSeconds或livenessProbe避免init container永无休止的fail。

Pod重启的原因

  • pod参数更新导致init container的image改变。
  • pod基础container重启。这种情况不常见。
  • pod的所有container都已停止,同时RestartPolicy设置为Always

Pod的操作

获取pod信息

kubectl get po pod_name -o yaml

创建pod

kubectl create -f kubia-manual.yaml

其中kubia-manual.yaml为pod描述文件。

获取所有pod

kubectl get pods

查看更详细的pod信息列表

kubectl get pods -o wide

获取pod的日志

kubectl logs pod_name

如果pod内存在多个container,可以使用如下命令获取某一个特定container内的日志

kubectl logs pod_name -c container_name

删除pod

kubectl delete po kubia-gpu

向pod发送请求

绑定宿主机和pod端口的方式:

  • 使用k8s service(推荐)
  • 使用port forwarding

Port forwarding方式

kubectl port-forward kubia-manual 8888:8080

Label(标签)

label是key/value pair。可以对k8s中的资源对象(pod,controller,service等)进行分类和标记,供其他资源对象的相关selector进行操作。

label相关操作

创建带有label的pod

yaml

apiVersion: v1
kind: Pod
metadata:
    name: kubia-manual-v2
    labels:
        creation_method: manual
        env: prod
spec:
    containers:
    - image: luksa/kubia
      name: kubia
      ports:
      - containerPort: 8080
        protocol: TCP

查看pod的label信息

kubectl get po --show-labels

将指定label分列显示

kubectl get po -L creation_method,env

新增标签

kubectl label po kubia-manual creation_method=manual

修改标签

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

使用label selector列出pod信息

精确匹配

kubectl get po -l creation_method=manual

列出包含env标签的pod

kubectl get po -l env

列出不包含env标签的pod

kubectl get po -l '!env'

使用label selector删除pod

kubectl delete po -l creation_method=manual

label selector的运算符

  • creation_method!=manual 否定
  • env in (prod,devel) 范围
  • env notin (prod,devel) 范围否定
  • app=pc,rel=beta 使用多个selector

节点标签配置

可以为集群中的节点增加标签,这样就可以使用pod spec中的nodeSelector人工干预pod的schedule过程,控制pod可运行到哪些节点上。

节点操作

节点增加标签

kubectl label node gke-kubia-85f6-node-0rrx gpu=true

使用label selector列出节点

kubectl get nodes -l gpu=true

创建node时使用node selector。(以下pod中的container仅会在label为gpu=true的节点下运行)

apiVersion: v1
kind: Pod
metadata:
    name: kubia-gpu
spec:
    nodeSelector:
        gpu: "true"
    containers:
      - image: luksa/kubia
      name: kubia

查看pod描述

kubectl describe pod kubia-manual

Annotation

Annotation通常来说不会被k8s直接使用,主要为了便于集群维护者查看。

有一个例外是对于一些alpha或者beta的API,它们会从annotation中读取一些配置。

Annotation相关操作

增加annotation

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

删除kubia-manual这个pod上key为description的annotation

kubectl annotate pods kubia-manual description-

Namespace

Namespace用于对k8s中资源对象的分组。namespace之间没有嵌套或层级关系。一个资源对象只能属于一个namespace。不同组之间的对象是隔离的,互相不可见。

Namespace 适合用于隔离不同用户创建的资源。

注意:namespace无法保证网络的隔离性,比如说service可以跨namespace访问。

默认来说Kubernetes具有如下3个namespace:

  • default: k8s默认的namespace,如果操作如果不指明namespace,默认会操作名为default的namespace。
  • kube-system: k8s系统自己运行所需的资源对象所在的namespace。
  • kube-public: k8s自动创建的namespace,对所有用户可见。适合放置集群范围都可见的服务。

namespace相关操作

列出所有的namespace

kubectl get ns

获取指定namespace下的所有pod

kubectl get po --namespace kube-system
# 或
kubectl get po -n kube-system

创建namespace

custom-namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
    name: custom-namespace
kubectl create -f custom-namespace.yaml

或者使用

kubectl create namespace custom-namespace

在指定namespace下创建资源

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

k8s快速切换namespace

alias kcd='kubectl config set-context $(kubectl config currentcontext) --namespace '

kcd some-namespace

执行如下命令验证

kubectl config view --minify | grep namespace:

删除整个namespace,这样namespace下的所有pod都会被删除

kubectl delete ns custom-namespace

删除整个namespace下的所有pod,但不删除namespace

kubectl delete po --all

删除namespace中所有的资源

kubectl delete all --all
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容

  • 在实践之前,必须先学习k8s的几个重要概念,它们是组成k8s集群的基石。 1. Cluster Cluster是计...
    wangfs阅读 830评论 0 0
  • 1.Pod Pod是k8s的最基本的操作单元,包含一个或多个紧密相关的容器,类似于豌豆荚的概念。一个Pod可以被一...
    jony456123阅读 7,383评论 0 5
  • 排错指南 - Pod 本文档介绍 Pod 的异常状态,可能原因和解决办法。 排查 Pod 异常的常用命令如下: 查...
    小孩子的童话2014阅读 6,941评论 0 2
  • 为什么 K8S 的节点上的资源会被 pod 和系统进程所使用,如果默认什么都不配置,那么节点上的全部资源都是可以分...
    徐亚松_v阅读 10,321评论 1 6
  • 玉温娴柳含嫶柔,黛螺縠波泛徐舟。 渚石润染苔琉绿,清流随澹阔屏悠。 稚子啕啕酡颜绶,鹣鲽脉脉海棠绸。 丽日逐兴通古...
    青石过客阅读 153评论 0 0