第 39 节 关于 Kubernetes 的一些疑问 4


❤️💕💕新时代拥抱云原生,云原生具有环境统一、按需付费、即开即用、稳定性强特点。Myblog:http://nsddd.topopen in new window


[TOC]

Pod API 字段

Pod 是 Kubernetes 中最小的部署单位,它代表一个运行中的容器。Pod API 字段主要包括:

  • apiVersion:Pod API 的版本。
  • kind:对象类型,这里是 Pod。
  • metadata:元数据,包括名称、命名空间、标签等。
  • spec:Pod 规范,描述了 Pod 应如何运行。
  • status:Pod 状态,包括 IP 地址、容器状态等。

下面是一个示例 Pod API 对象:

codeapiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  namespace: default
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
status:
  phase: Running
  conditions:
    - type: Ready
      status: "True"

Kubernetes源码的哪个位置

在 Kubernetes 源码中,Pod 的定义位于 pkg/api/v1/pod.go 文件中,它是由一个名为 Pod 的结构体表示的。这个结构体定义了 Pod 的所有字段,包括 apiVersionkindmetadataspec 等。

下面是 Pod 结构体的定义:

codetype Pod struct {
        // Standard object's metadata.
        // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
        // +optional
        metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`

        // Specification of the desired behavior of the pod.
        // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        // +optional
        Spec PodSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`

        // Most recently observed status of the pod.
        // This data may not be up to date.
        // Populated by the system.
        // Read-only.
        // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
        // +optional
        Status PodStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}

DeamonSet

DaemonSet 是 Kubernetes 中的一种调度器,它能保证每个节点上运行一个指定的 Pod。这对于一些全局服务(如日志收集、监控等)很有用。

当节点加入或离开集群时,DaemonSet 会自动在新节点上创建或销毁 Pod。此外,如果某个节点中的 Pod 因故障而退役,DaemonSet 也会在该节点上重新创建一个新的 Pod。

使用 DaemonSet 可以确保集群中的所有节点上都运行着指定的 Pod,这对于提供全局服务很有帮助。

示例 DaemonSet API 对象:

codeapiVersion: apps/v1
kind: DaemonSet
metadata:
  name: myapp-daemonset
  namespace: default
  labels:
    app: myapp
spec:
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp-container
        image: busybox
        command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']

DaemonSet API 对象包含以下几个主要字段:

  • apiVersion:API 的版本。
  • kind:对象类型,这里是 DaemonSet。
  • metadata:元数据,包括名称、命名空间、标签等。
  • spec:DaemonSet 规范,描述了 DaemonSet 应如何运行。它包括了两个字段:
    • selector:选择器,描述了哪些节点应该运行 DaemonSet 中的 Pod。
    • template:Pod 模板,描述了 DaemonSet 中的 Pod 应该如何运行。

声明式 API

在 Kubernetes 中,我们可以使用声明式 API 来描述我们希望集群中运行什么。我们可以使用 YAML 或 JSON 格式来声明我们希望运行的应用程序、服务、部署、调度器等。

例如,我们可以使用以下声明式 API 对象来创建一个 Deployment:

codeapiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  namespace: default
  labels:
    app: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp-container
        image: busybox
        command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']

然后,我们可以使用 kubectl 命令来将这个声明式 API 对象发送到 Kubernetes 集群,如下所示:

Copy code
kubectl apply -f deployment.yaml

这样,Kubernetes 就会根据声明式 API 对象中的描述创建 Deployment 和相应的 Pod。

在 Deployment 中,我们可以使用 kubectl rollout 命令来进行版本控制。这个命令可以帮助我们轻松地实现滚动升级或回滚。

例如,我们可以使用以下命令来升级 Deployment 中的应用程序:

Copy code
kubectl set image deployment/myapp-deployment myapp-container=myapp:v2

这条命令会将 Deployment 中的所有 Pod 的镜像更新为 myapp:v2。Kubernetes 会自动在新的 Pod 启动并就绪之前停止旧的 Pod,从而实现滚动升级。

如果我们希望回滚到之前的版本,可以使用以下命令:

Copy code
kubectl rollout undo deployment/myapp-deployment

这条命令会将 Deployment 滚动回上一个版本。

在背后,Kubernetes 使用了一个名为 ControllerRevision 的资源来跟踪 Deployment 的每个版本。每当我们使用 kubectl rollout 命令进行版本控制时,Kubernetes 都会创建一个新的 ControllerRevision 记录,从而使我们能够轻松地回滚到之前的版本。

kubectl create 和 kubectl apply 命令有什么区别

kubectl createkubectl apply 命令都可以用来在 Kubernetes 集群中创建资源。但是,这两个命令的行为略有不同。

  • kubectl create 命令是用来新建资源的。如果在执行该命令时,集群中已经存在同名的资源,则会报错。
  • kubectl apply 命令是用来更新资源的。如果在执行该命令时,集群中已经存在同名的资源,则会更新资源的配置。如果不存在同名的资源,则会新建资源。

所以,如果我们希望新建资源,则可以使用 kubectl create

如果我们希望新建资源,则可以使用 kubectl create 命令。例如,我们可以使用以下命令来新建 Deployment 资源:

kubectl create -f deployment.yaml

此命令会从 deployment.yaml 文件中读取 Deployment 配置,并在集群中新建 Deployment。

如果我们希望更新已存在的资源,则可以使用 kubectl apply 命令。例如,我们可以使用以下命令来更新 Deployment 资源:

kubectl apply -f deployment.yaml

此命令会从 deployment.yaml 文件中读取 Deployment 配置,如果集群中已经存在同名的 Deployment,则会更新 Deployment 的配置;如果不存在,则会新建 Deployment。

从底层来看,kubectl createkubectl apply 命令的实现方式略有不同。

  • kubectl create 命令是通过向 Kubernetes API 服务发送 HTTP POST 请求来创建资源的。在发送请求时,会将资源的配置以 JSON 或 YAML 格式发送给 API 服务。API 服务收到请求后,会解析请求中包含的资源配置,然后在集群中新建资源。
  • kubectl apply 命令也是通过向 Kubernetes API 服务发送 HTTP POST 请求来创建或更新资源的。但是,它的实现方式略有不同。在发送请求时,会将资源的配置以 JSON 或 YAML 格式发送给 API 服务。API 服务收到请求后,会解析请求中包含的资源配置,然后检查集群中是否已经存在同名的资源。如果存在,则会更新资源的配置;如果不存在,则会在集群中新建资源。

patch操作

⚠️ 注意,patch 操作是声明式 API 的关键,Kubectl apply 可以理解为是执行了一个对原有API 对象的 PATCH cao'zuo

在 Kubernetes 中,patch 操作是用来更新资源的配置的。它可以让我们只修改资源的部分字段,而不是整个资源的配置。

例如,我们可以使用 patch 操作来修改 Deployment 的副本数量,而不需要修改整个 Deployment 的配置。这样做可以节省时间,并且也可以减少网络流量。

我们可以使用 kubectl patch 命令来执行 patch 操作。例如,我们可以使用以下命令来修改 Deployment 的副本数量:

kubectl patch deployment myapp-deployment -p '{"spec":{"replicas": 3}}'

此命令会将 Deployment 的副本数量修改为 3。

需要注意的是,patch 操作不会清除资源的字段。也就是说,如果我们使用 patch 操作修改资源的某个字段,而不指定该字段的值,则该字段的值不会被清除。

例如,如果我们使用以下命令来修改 Deployment 的副本数量:

kubectl patch deployment myapp-deployment -p '{"spec":{"replicas": null}}'

此命令会尝试将 Deployment 的副本数量设置为 null,但是由于 Deployment 的副本数量是必填字段,所以这条命令会失败。

如果我们希望清除资源的某个字段,则可以使用 kubectl edit 命令。

kubectl edit 命令会打开资源的编辑界面,让我们可以直接修改资源的配置。我们可以将要清除的字段设置为 null,然后保存即可。

例如,我们可以使用以下命令来清除 Deployment 的副本数量字段:

kubectl edit deployment myapp-deployment

这条命令会打开 Deployment 的编辑界面,我们可以将副本数量字段设置为 null,然后保存即可。

声明式 API 的一些工作原理

在Kubernetes中,API对象存储在etcd数据库中。在etcd中,每个API对象都有一个唯一的路径,用于标识对象所在的位置。这个路径通常包含几个部分:

  • 命名空间:API对象所属的命名空间。
  • 资源类型:API对象的类型,例如Pod、Service、Deployment等。
  • 资源名称:API对象的名称。

例如,如果要描述一个名为"my-pod"的Pod对象,它位于名为"default"的命名空间中,那么它在etcd中的完整路径可能如下所示:

/registry/pods/default/my-pod

这个路径中的各个部分分别表示命名空间(default)、资源类型(pods)和资源名称(my-pod)。

END 链接