k8s企业级应用系列(二):对象管理及Pod原理

这篇具有很好参考价值的文章主要介绍了k8s企业级应用系列(二):对象管理及Pod原理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

对象管理

本节介绍对象的相关概念和管理机制。只有了解了这些机制,我们才能轻松的对k8s资源进行编排。


1 对象 Object

k8s对象即是对应用程序、工作负载、存储、网络等资源的抽象表示,如image、pod、node、volume、service等。集群中每个对象都有一个名称来标识其在同类资源中唯一性,同时拥有一个UID来标识其在整个集群中唯一性

由于许多资源类型需要用作DNS子域名的名称,所以,对象命名需遵守RFC 1035定义的DNS标签标准。

对象命名规范

  • 最多 63 个字符。
  • 只能包含小写字母、数字、‘-’。有些资源名称也可以使用'.'
  • 必须以字母开头。
  • 必须以字母数字结尾。

2 命名空间 namespace

通过命名空间,将资源分组,分组间相互隔离。同一命名空间中的资源名称需要唯一。k8s会为所有命名空间设置一个不可变的标签kubernetes.io/metadata.name: "<namespace_name>",标签值是命名空间的名称,可使用标签运算符快速定位到命名空间<namespace_name>

绝大多数的k8s对象都属于某一命名空间,但是也有一些资源(如:命名空间本身,节点,持久化卷)不属于任何命名空间。

2.1 查看命名空间中的资源

# 查看 位于命名空间中的资源
kubectl api-resources --namespaced=true

# 查看 不在命名空间中的资源
kubectl api-resources --namespaced=false

2.2 创建命名空间

# Source: /myworkdir/myns.yaml
apiVersion: v1
kind: NameSpace
metadata:
  name: myns
# 通过资源描述文件创建命名空间
kubectl create -f /myworkdir/myns.yaml

# 通过命令创建命名空间
kubectl create namespace myns

# 查看/删除命名空间
kubectl get ns
kubectl delete namespace myns

2.3 设置当前默认的命名空间

kubectl config set-context --current --namespace=<名字空间名称>
# 验证
kubectl config view --minify | grep namespace:

2.4 DNS解析

当创建一个Service时,k8s会创建一条DNS记录,格式为<服务名称>.<名字空间名称>.svc.cluster.local

  • 如果容器只使用<服务名称>访问Service,它会被解析到本地命名空间中的Service。
  • 如果你想跨命名空间访问Service,则需要使用完全限定域名(FQDN)。
  • 命名空间名称必须满足RFC 1123 DNS名称规范。

3 标签 labels

标签labels,顾名思义就是给k8s对象做个标记,它是附加到k8s对象(如pod)上的键值对,用来标识对象属性。标签可以在创建时附加到对象上,也可以在创建后随时添加和修改。k8s中的对象标签名称UID不同,不具有唯一性,主要用来分组和筛选。

3.1 标签键:
前缀+名称两段组成,用斜杠/分割,前缀是可选的,名称是必需的。如kubernetes.io/master

前缀段的使用规范:

  • 如果指定前缀,则必须是DNS子域,由’.'和一系列DNS标签组成,最多253个字符。
    前缀kubernetes.io/k8s.io/是为k8s核心组件保留的。
  • 如果省略前缀,则认为标签键是用户私有的。

名称段的命名规范:

  • 最多 63 个字符。
  • 只能包含字母、数字,破折号’-‘、下划线’_‘、点’.'。
  • 以字母数字字符([a-z0-9A-Z])开头和结尾。

3.2 标签值:

  • 可以为空。最多 63 个字符。
  • 以字母数字字符([a-z0-9A-Z])开头和结尾。
  • 只能包含字母、数字,破折号’-‘、下划线’_‘、点’.'。

3.3 标签语法

# json格式
"metadata": {
  "labels": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

# yaml格式
metadata: 
  labels:
    key1: value1
    key2: value2

3.4 示例:

apiVersion: v1
kind: Pod  # 资源类型
metadata:
  name: label-demo  # 定义资源名称,在同类资源中唯一。
  labels:
    environment: production  # 定义私有标签environment:production
    app: nginx  # 定义私有标签app:nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2  # 引用镜像版本。
    ports:
    - containerPort: 80

4 标签选择器 selector

一般我们会给一批资源对象打上相同的标签,然后通过标签选择器进行匹配,选择满足匹配条件的一组资源对象。
标签选择器的匹配方式可分为基于等值基于集合两种方式。这两种方式既可以在REST客户端 kubeclt 中使用,也可以在k8s对象中引用。

4.1 在REST客户端 kubeclt 中使用

# 基于等值:支持'='、'=='和'!='
kubectl get pods -l environment=production,tier=frontend  # 查找标签为environment=production,tier=frontend的pod。
kubectl get pods -l environment!=production,tier==frontend

# 基于集合:支持'in' 'notin'
kubectl get pods -l 'environment in (production),tier in (frontend)'
kubectl get pods -l 'environment in (production, qa)'  # 查看标签environment的值在(production, qa)中的pod。
kubectl get pods -l 'environment,environment notin (frontend)'

# 混合使用
kubectl get pods -l 'partition in (customerA, customerB),environment!=qa'

4.2 在k8s对象中引用

# 基于等值  
---
"selector": {  # json格式
  "component" : "redis",
  "type": "Cluster"
}

selector:  # yaml格式
  component: redis
  type: Cluster

nodeSelector:   # 节点选择器  spec.nodeSelector
  accelerator: nvidia-tesla-p100  # 选择带有该标签的节点。

# 基于集合
---
selector:
  # 集合形式,由{key,value}对组成的映射。类似于matchExpressions的In操作。
  matchLabels: 
    component: redis
  # 列表形式,支持运算符:In NotIn Exists DoesNotExist。
  matchExpressions: 
    - { key: tier, operator: In, values: [cache] }
    - { key: environment, operator: NotIn, values: [dev] }

4.3 根据标签查找

# 使用-L key查看所有具有key标签的pod。
$ kubectl get pods -Lapp -Ltier -Lrole
NAME                           READY  STATUS    RESTARTS   AGE   APP         TIER       ROLE
guestbook-fe-4nlpb             1/1    Running   0          1m    guestbook   frontend   <none>
guestbook-redis-master-5pg3b   1/1    Running   0          1m    guestbook   backend    master
guestbook-redis-replica-2q2yf  1/1    Running   0          1m    guestbook   backend    replica
guestbook-redis-replica-qgazl  1/1    Running   0          1m    guestbook   backend    replica
my-nginx-divi2                 1/1    Running   0          29m   nginx       <none>     <none>
# 指定标签键值
$ kubectl get pods -lapp=guestbook,role=replica
NAME                           READY  STATUS   RESTARTS  AGE
guestbook-redis-replica-2q2yf  1/1    Running  0         3m
guestbook-redis-replica-qgazl  1/1    Running  0         3m

4.4 更新标签

# 根据"app=nginx"过滤所有的Pod,然后用打上"tier=fe"标签
$ kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
# 查看刚设置了标签的Pod
$ kubectl get pods -l app=nginx -L tier # -L 表示查看所有键为tier的pod。
NAME                        READY     STATUS    RESTARTS   AGE       TIER
my-nginx-2035384211-j5fhi   1/1       Running   0          23m       fe
my-nginx-2035384211-u2c7e   1/1       Running   0          23m       fe

5 注解 annotations
标签注解都是为k8s对象附加元数据。但是,标签可以用来选择对象查找满足某些条件的对象集合。注解附加的是非标识元数据,不用于标识选择对象。

5.1 注解语法

注解标签一样,也是键/值对

  • 注解的键也由前缀+名称两段组成,用斜杠/分割,前缀是可选的,名称是必需的。键的命名规范同标签的键。
  • 注解的值大小没有限制,结构没有规定,能够包含标签不允许的字符,客户端程序(例如工具和库)能够获取这些元数据信息,然后进行加工和处理。
# json格式
"metadata": {
  "annotations": {
    "key1" : "value1",
    "key2" : "value2"
  }
  
# yaml格式
metadata: 
  annotations: 
    key1: value1
    key2: value2

5.2 示例

apiVersion: v1
kind: Pod
metadata:
  name: annotations-demo
  annotations:
    imageregistry: "https://hub.docker.com/"  # 定义注解内容
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

6 字段选择器

字段选择器常用在REST客户端中,根据字段值筛选k8s对象。支持的字段有metadata.name、metadata.namespace、status.phase等,使用不被支持的字段时选择器会报错。

# 筛选出status.phase字段值为Running的所有Pod
$ kubectl get pods --field-selector status.phase=Running

# 使用不支持的字段,选择器报错
$ kubectl get ingress --field-selector foo.bar=baz
Error from server (BadRequest): Unable to find "ingresses" that match label selector "", field selector "foo.bar=baz": "foo.bar" is not a known field selector: only "metadata.name", "metadata.namespace"

# 支持'='、'=='和'!='
$ kubectl get services --all-namespaces --field-selector metadata.namespace!=default # 筛选非defualt命名空间的svc

# 链式选择器,同标签选择器一样,可以使用逗号分隔的列表组成一个选择链。
kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always

# 查看多种资源类型
kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default

7 属主与附属机制
7.1 基本概念

一些对象其他对象属主,称为属主对象。具有属主对象属主对象附属,简称附属对象。例如,ReplicaSet是一组Pod属主PodReplicaSet附属

7.2 属主引用

附属对象有一个metadata.ownerReferences字段,用来引用属主对象,这种引用方式就称为属主引用属主引用定义了对象间的附属关系k8s对象大多都是通过属主引用链接到彼此的。metadata.ownerReferences字段中,包含在同一个命名空间下的属主对象名称属主对象UID。通常,k8s会自动附属对象设置属主引用值,这些对象包含ReplicaSet、DaemonSet、Deployment、Job、CronJob、ReplicationController等。当然,也可以手动修改该字段的值。

7.3 垃圾回收

k8s会检查并删除不再拥有属主引用附属对象。例如,属主对象ReplicaSet被删除之后留下来的附属对象Pod,将会被k8s自动清理。

7.4 级联删除

附属对象还有一个ownerReferences.blockOwnerDeletion字段(布尔值),用来控制附属对象是否阻止属主对象被回收删除。k8s会自动将该字段设置为true,也可手动更改。当删除一个附属对象时,k8s将根据该字段的值判断是否删除该对象的属主对象,默认情况下,该字段为true,表示不删除属主对象。比如,默认情况下,删除附属对象Pod时,属主对象ReplicaSet不会被删除。

7.5 与标签选择器不同

属主引用定义了对象间的附属关系,而标签选择器只是定义了对象间的调用关系,这种调用关系松耦合的属主引用则是对象间的强绑定关系。例如,Service会通过标签选择器选择满足条件的EndpointSlice对象,同时,每个EndpointSlice对象都有一个属主引用属性,指定了其附属于哪些Service。



Pod原理


  1. 工作负载Pod

概述:Pod是 k8s 系统中可以创建和管理的最小单元,k8s 不会直接处理容器,而是通过Pod管理容器,通过控制器管理Pod,这些控制器ReplicaSet、Job、CronJob、Deployment、StatefulSet、DaemonSet等

1.1 Pod结构

Pod中都包含一个Infra容器,至少一个应用容器,以及零或多个init容器sidecar容器,除init容器外,它们共享存储网络资源

k8s企业级应用系列(二):对象管理及Pod原理,微服务&amp;&amp;云原生,kubernetes,容器,云原生,运维,k8s

1.2 Infra/Pause容器

基础设施容器Infra容器创建完成后就会进入Pause状态,所以也叫做Pause容器。它是Pod的根容器,Pod中其他的容器都会被加入到Pause容器中,成为它的子容器。

容器技术参见我的另一篇文章:《Docker企业级应用(架构原理+工作流)》

容器之间是通过命名空间进行隔离的,为了让Pod中的容器共享资源,就需要打破命名空间的隔离。所以,在Pod初始化时会首先创建一个Infra容器,然后再将创建的应用容器加入到Infra容器中,这样它们就共享同一套资源了。

容器运行时可以通过创建父子容器的方式,控制容器组间共享级别。即先创建一个父容器Infra,然后在创建子容器myapp时,指定需要加入的父容器Infra,如docker run -d --name myapp --pip=container:InfraId --net=container:InfraId --ipc=container:InfraId myImage

1.2 应用容器及回调

用户的应用程序就运行在这些应用容器中。此外,我们可以为应用容器设置回调函数,在容器启动和终止时操作。通过spec.containers.lifecycle字段定义回调函数PostStart和PreStop。回调函数的作用:

  • PostStart
    在容器被创建之后立即被执行。但是,不能保证回调会在容器入口点(ENTRYPOINT)之前执行。 没有参数传递给处理程序。
  • PreStop
    在容器因 API 请求或者管理事件(诸如存活态探针、启动探针失败、资源抢占、资源竞争等) 而被终止之前,此回调会被调用。 如果容器已经处于已终止或者已完成状态,则对 preStop回调的调用将失败。停止容器的 TERM 信号被发出之前,回调必须执行结束。Pod 的终止宽限周期在 PreStop 回调被执行之前即开始计数, 所以无论回调函数的执行结果如何,容器最终都会在 Pod 的终止宽限期内被终止。 没有参数会被传递给处理程序。
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  dnsPolicy: Default
  containers:
  - name: myapp-container
    image: busybox:1.28
    lifecycle:
      postStart:
        exec:
          # command: ["/bin/sh", "-c", "do_postStart.sh"]
          command: ["/bin/sh", "-c", "echo Hello postStart> /usr/share/message"]
      preStop:
        exec:
          # command: ["/bin/sh", "-c", "do_preStop.sh"]
          command: ["/bin/sh","-c","while killall -0 myapp; do sleep 1; done"]

1.3 Init容器

Pod中可以有多个init容器init容器会在应用容器启动之前,依次逐个运行,每个init容器运行成功后才能执行下一个init容器。当所有的init容器都运行成功后,才会初始化应用容器。当init容器运行完成后,它的生命周期也就结束了,然后被k8s回收。

  • 与普通容器不同:
    Init容器不支持lifecycle、livenessProbe、readinessProbe或者startupProbe字段,Init容器必须在Pod准备就绪之前完成启动。Init 容器与应用容器共享资源(CPU、内存、网络),但不直接与主应用容器进行交互。不过这些容器可以使用共享卷进行数据交换。
  • 用途:
    1.init容器拥有独立的文件系统视图,可以访问应用容器不能访问的Secret。
    2.init容器在应用容器启动之前运行完成,所以可以使用init容器完成一些先决条件,等到前置条件满足才会运行应用容器。
    3.方便运行应用程序中不能有的工具,如编译工具、sed、awk等。
# Source: /myworkdir/mypod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app.kubernetes.io/name: MyApp
spec:
  # 应用容器定义
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  # init容器定义
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  # init容器定义
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]

1.4 Sidecar容器

Sidecar容器是与应用容器在同一个 Pod 中运行的辅助容器。这些容器通过提供额外的服务或功能(如日志记录、监控、安全性或数据同步)来增强或扩展应用容器的功能, 而无需直接修改主应用代码

  • 与常规容器不同:
    1.Sidecar容器具有独立的生命周期。它们可以独立于应用容器启动、停止和重启。 这意味着你可以更新、扩展或维护Sidecar容器,而不影响主应用。
    2.可以直接与主应用容器进行交互,共享相同的网络命名空间、文件系统和环境变量。
  • 与Init容器不同:
    1.init容器运行完成后就是被k8s回收,而Sidecar容器有独立的生命周期。
    2.sidecar容器支持lifecycle、livenessProbe、readinessProbe或者startupProbe字段。
apiVersion: apps/v1
kind: Pod
metadata:
  name: myapp
  labels:
    app: myapp
  spec:
    # 应用容器定义
    containers:
      - name: myapp
        image: alpine:latest
        command: ['sh', '-c', 'echo "logging" > /opt/logs.txt']
        volumeMounts:
          - name: data
            mountPath: /opt
    # 通过initContainers字段定义Sidecar容器
    initContainers:
      - name: logshipper
        image: alpine:latest
        restartPolicy: Always  # Pod整个生命周期
        command: ['sh', '-c', 'tail /opt/logs.txt']  # tail命令保持进程不退出。
        volumeMounts:
          - name: data
            mountPath: /data
	volumes:
	  - name: data
	    emptyDir: {}

1.5 Pod生命周期

Pod在其生命周期内只能被调度一次,一旦Pod被调度到某个节点上,将一直运行到被终止。每个Pod都有一个唯一的UID值。Pod自身不具备自愈能力,如果Pod所在节点出现故障,Pod会被删除。所以,k8s使用控制器来管理这些相对临时性的Pod。

k8s企业级应用系列(二):对象管理及Pod原理,微服务&amp;&amp;云原生,kubernetes,容器,云原生,运维,k8s

Pod在其生命周期中所处的状态:

Pod状态值 描述
Pending Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。
ContainerCreating Pod 已经绑定到了某个节点。正在创建容器。
Running Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。
Succeeded Pod 中的所有容器都已成功终止,并且不会再重启。
Failed Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。
Unknown 因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。

1.6 外部访问Pod容器的应用程序文章来源地址https://www.toymoban.com/news/detail-851132.html

curl -ivh -k https://${POD_IP}:${CONTAINER_PORT}/path -w %{http_code}

到了这里,关于k8s企业级应用系列(二):对象管理及Pod原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 企业级docker应用注意事项

    现在很多企业使用容器化技术部署应用,绕不开的docker技术,在生产环境docker常用操作总结。参考:https://juejin.cn/post/7259275893796651069 在docker hub 官方 使用后面带有 DOCKER OFFICIAL IMAGE 标签的镜像,有更好的安全性保障。 默认使用 latest 标签,拉取最新镜像,镜像稳定性以及兼容

    2024年02月15日
    浏览(36)
  • 低代码企业级PMO项目管理系统,360度全景透视企业管理视角

    在一个崇高的目标支持下,不停地工作,即使慢,也一定会获得成功。   爱因斯坦 企业级PMO项目管理业务是行业里相对成熟和规范的业务,拥有众多商业套件和标准产品。 然而随着企业数字化建设进入深水区,站在甲方角度进行项目管理的业务视角、精细化管控、标准化管

    2024年02月03日
    浏览(42)
  • Microsoft Bitlocker企业级管理部署方案

    目录 一、前言 二、BitLocker部署前的准备工作 三、BitLocker的部署方式

    2024年02月05日
    浏览(27)
  • 【AIGC调研系列】AIGC企业级模型Command-R介绍

    Command-R与其他大语言模型的主要区别在于其专为企业级应用设计,特别是在检索增强生成(RAG)和工具使用方面。Command-R是一个350亿参数的高性能生成模型,具有开放式权重,能够支持多种用例,包括推理、摘要和问答[2]。它特别针对大规模生产工作负载进行了优化,属于可

    2024年04月26日
    浏览(32)
  • Kafka在企业级应用中的实践

    前面说了很多Kafka的性能优点,有些童鞋要说了,这Kafka在企业开发或者企业级应用中要怎么用呢?今天咱们就来简单探究一下。 Kafka 提供了一个可靠的消息传递机制,使得企业能够将不同组件之间的通信解耦,实现高效的异步处理。在企业级应用中,可以通过以下步骤来使

    2024年02月11日
    浏览(34)
  • Mysql 数据库开发及企业级应用

    1.1、为什么要使用数据库 ​ 程序员 Jack 还是在在校学习期间, 就听高年级的大哥忠告, “ 小伙子, 搞编程, 想要成为最牛逼的程序员, 一定要学好 C/C++语言和数据结构及算法” , Jack 谨记了这句忠告, 因为这位高年级的哥们还没毕业就已经被 BAT 公司预定, 在学校那是

    2024年02月16日
    浏览(38)
  • Stable Diffusion 从入门到企业级应用010

    本文是《Stable Diffusion 从入门到企业级应用实战》系列的第四部分能力进阶篇《Stable Diffusion ControlNet v1.1 图像精准控制》的第0414篇 利用Stable Diffusion ControlNet 法线贴图模型精准控制图像生成。本部分内容,位于整个Stable Diffusion生态体系的位置如下图黄色部分所示:        

    2024年02月10日
    浏览(25)
  • 【分布式应用】ELK企业级日志分析系统

    目录 一、ELK 简介 1.1 ELK各组件介绍 ElasticSearch: Kiabana: Logstash: 1.2 可以添加的其它组件: Filebeat: 缓存/消息队列(redis、kafka、RabbitMQ等): Fluentd: 1.3 ELK、ELFK、EFLKL 二、为什么要使用 ELK 三、完整日志系统基本特征 四、ELK 的工作原理 五、ELK集群部署 实验环境: 实验步

    2024年02月14日
    浏览(33)
  • 分布式应用:ELK企业级日志分析系统

    目录 一、理论 1.ELK  2.ELK场景  3.完整日志系统基本特征 4.ELK 的工作原理          5.ELK集群准备 6.Elasticsearch部署(在Node1、Node2节点上操作) 7.Logstash 部署(在 Apache 节点上操作) 8.Kiabana 部署(在 Node1 节点上操作) 二、实验          1.Elasticsearch部署(在Node1、Node2节点上

    2024年02月14日
    浏览(30)
  • 云表|低代码开发崛起:重新定义企业级应用开发

    nbsp; nbsp; nbsp; nbsp;低代码开发这个概念在近年来越来越受到人们的关注,市场对于低代码的需求也日益增长。据Gartner预测,到2025年,75%的大型企业将使用至少四种低代码/无代码开发工具,用于IT应用开发和公民开发计划。 nbsp; nbsp; nbsp; nbsp;那么,为什么低代码开发如此受到

    2024年02月08日
    浏览(35)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包