当前位置:   article > 正文

K8S Pod配置详解(spec)_k8s spec

k8s spec

Pod 是 Kubernetes 中最基本的资源对象之一,代表一组容器的单位。

以下是几个重要的 Pod 字段的含义和用法:

  1. metadata:包含了 Pod 的元数据,例如名称、标签、命名空间等。

  1. spec:定义了 Pod 的行为和构建,例如容器镜像、资源限制、环境变量等。

  1. status:存储了 Pod 的运行状态,例如 Pod IP 地址、容器状态、节点名称等。

  1. containers:定义了 Pod 中包含的容器,包括容器名称、镜像、端口映射等。

  1. restartPolicy:定义了在容器停止时的重启策略,可以设置为 "Always"、"OnFailure" 或 "Never"。

  1. dnsPolicy:定义了 Pod 的 DNS 策略,例如使用 Cluster DNS 还是自定义 DNS。

  1. nodeSelector:指定 Pod 运行在哪个节点上,可以根据节点标签进行选择。

这些字段结合起来,可以帮助我们灵活地配置和管理 Pod。

示例

下面是一个简单的 Pod 配置文件示例:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: my-pod
  5. labels:
  6. app: my-app
  7. spec:
  8. containers:
  9. - name: my-container
  10. image: nginx:latest
  11. ports:
  12. - containerPort: 80
  13. restartPolicy: Always
  14. dnsPolicy: ClusterFirst
  15. nodeSelector:
  16. kubernetes.io/os: linux

注释:

  1. apiVersion:指定使用的 Kubernetes API 的版本,在这个例子中是 v1。

  1. kind:指定资源对象的类型,在这个例子中是 Pod。

  1. metadata:定义了 Pod 的元数据。在这个例子中,Pod 名称为 "my-pod",并且具有一个 "app" 标签,值为 "my-app"。

  1. spec:定义了 Pod 的行为和构建。在这个例子中,Pod 包含一个容器 "my-container",使用 nginx 镜像,暴露了 80 端口;重启策略为 "Always";DNS 策略为 "ClusterFirst";运行在具有 "kubernetes.io/os: linux" 标签的节点上。

这是一个简单的例子,实际的配置文件可能更加复杂和丰富。不过,这个示例可以让您了解 Pod 配置文件的基本结构和内容。

hostAliases

hostAliases 字段可以用于 Pod 配置文件。hostAliases 字段用于指定 Pod 中容器的主机别名,它是一个数组,每个数组项定义了一个主机别名。

下面是一个使用 hostAliases 字段的示例:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: my-pod
  5. labels:
  6. app: my-app
  7. spec:
  8. hostAliases:
  9. - ip: "10.0.0.1"
  10. hostnames:
  11. - "example.com"
  12. - "www.example.com"
  13. containers:
  14. - name: my-container
  15. image: nginx:latest
  16. ports:
  17. - containerPort: 80
  18. restartPolicy: Always
  19. dnsPolicy: ClusterFirst
  20. nodeSelector:
  21. kubernetes.io/os: linux

在这个示例中,我们定义了一个 hostAliases,它将 IP 地址 "10.0.0.1" 映射到两个主机名 "example.com" 和 "[www.example.com"。这样,在Pod 中的容器将能够访问这两个域名,而不会受到 Kubernetes 集群的网络隔离的限制。

NodeName

Pod 配置文件中还有一个 nodeName 字段。nodeName 字段指定了 Pod 应该运行在哪个节点上,它是一个字符串,表示节点的名称。

如果您想要明确控制 Pod 运行的节点,可以在配置文件中使用 nodeName 字段。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: my-pod
  5. spec:
  6. nodeName: node1
  7. containers:
  8. - name: my-container
  9. image: nginx:latest
  10. ports:
  11. - containerPort: 80
  12. restartPolicy: Mas
  13. dnsPolicy: ClusterFirst

在这个例子中,我们指定了 nodeName 为 "node1",这意味着 Pod 将运行在名为 "node1" 的节点上。

请注意,使用 nodeName 字段进行固定分配节点是一项高级功能,应在必要时才使用,因为它将打破 Kubernetes 集群的自动调度和再平衡功能。

shareProcessNamespace

Pod 配置文件中还有一个 shareProcessNamespace 字段。shareProcessNamespace 字段用于控制 Pod 中容器是否共享进程空间。

如果设置为 true,则所有容器在该 Pod 中将共享同一个进程空间,意味着可以使用 pid 命名空间共享进程。这可以使得容器在同一 Pod 中直接通信,并共享共同的进程空间。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: my-pod
  5. spec:
  6. shareProcessNamespace: true
  7. containers:
  8. - name: my-container1
  9. image: nginx:latest
  10. ports:
  11. - containerPort: 80
  12. - name: my-container2
  13. image: nginx:latest
  14. ports:
  15. - containerPort: 80
  16. restartPolicy: Mas
  17. dnsPolicy: ClusterFirst

在这个例子中,我们指定了 shareProcessNamespace 为 true,因此两个容器将共享同一个进程空间。


以下字段均是spec字段的PodSpec 部分的内容,go原码:https://pkg.go.dev/k8s.io/api/core/v1#PodSpec

DNSpolicy

Pod 配置文件中还有一个 dnsPolicy 字段。dnsPolicy 字段指定了 Pod 使用哪种 DNS 解析策略。

Kubernetes 支持以下几种 DNS 解析策略:

  • ClusterFirst:首先使用 Kubernetes 集群中的 DNS 解析器,如果解析失败,再使用容器操作系统的 DNS 解析器。

  • ClusterFirstWithHostNet:与 ClusterFirst 类似,但在容器操作系统中首先使用主机的 DNS 解析器。

  • Default:直接使用容器操作系统的 DNS 解析器。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: my-pod
  5. spec:
  6. dnsPolicy: ClusterFirst
  7. containers:
  8. - name: my-container
  9. image: nginx:latest
  10. ports:
  11. - containerPort: 80
  12. restartPolicy: Mas
  13. dnsPolicy: ClusterFirst

在这个例子中,我们指定了 dnsPolicy 为 ClusterFirst,这意味着 Pod 将首先使用集群中的 DNS 解析器进行解析,如果失败则使用容器操作系统的 DNS 解析器。

ServiceAccountName

Pod 配置文件中还有一个 serviceAccountName 字段。serviceAccountName 字段指定了为 Pod 分配的服务帐户名称。

服务帐户是 Kubernetes 中的概念,用于表示一个特定的操作者,可以访问集群中的资源。为 Pod 分配的服务帐户可以控制 Pod 中的容器访问集群中的资源的权限。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: my-pod
  5. spec:
  6. serviceAccountName: my-service-account
  7. containers:
  8. - name: my-container
  9. image: nginx:latest
  10. ports:
  11. - containerPort: 80
  12. restartPolicy: Mas
  13. dnsPolicy: ClusterFirst

在这个例子中,我们指定了 serviceAccountName 为 my-service-account,这意味着为 Pod 分配了名为 my-service-account 的服务帐户。

HostNetwork

HostNetwork 是一个布尔类型的字段,用于指定 Pod 是否使用主机的网络配置。如果 HostNetwork 的值为 true,则 Pod 中的容器将使用主机的网络配置,并与主机共享同一个网络命名空间。

这意味着,如果一个 Pod 中的容器使用主机的网络配置,它将可以直接使用主机上的 IP 地址、端口等。同时,如果主机上的端口被占用,Pod 中的容器也无法使用该端口。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: my-pod
  5. spec:
  6. hostNetwork: true
  7. containers:
  8. - name: my-container
  9. image: nginx:latest
  10. ports:
  11. - containerPort: 80
  12. restartPolicy: Always
  13. dnsPolicy: ClusterFirst

在这个例子中,我们指定了 hostNetwork 的值为 true,这意味着 Pod 中的容器将使用主机的网络配置。

如果 hostNetwork 的值为 false,则 Pod 中的容器将使用独立的网络配置,不共享主机的网络命名空间。这是 Kubernetes 默认的配置。

在这种情况下,Pod 中的容器将拥有独立的 IP 地址,并通过 Kubernetes 的网络服务进行通信。这样可以保证 Pod 中的容器的网络隔离,同时也方便容器间的通信。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: my-pod
  5. spec:
  6. hostNetwork: false
  7. containers:
  8. - name: my-container
  9. image: nginx:latest
  10. ports:
  11. - containerPort: 80
  12. restartPolicy: Always
  13. dnsPolicy: ClusterFirst

在这个例子中,我们指定了 hostNetwork 的值为 false,这意味着 Pod 中的容器将使用独立的网络配置,不共享主机的网络命名空间。

问题:一个 Pod 难道不是只有一个 IP 地址吗,里面的容器可以有多个ip吗?

答:是的,一个 Pod 是只有一个 IP 地址的,但是它中的容器是可以有多个 IP 地址的。

在 Kubernetes 中,容器与容器之间是隔离的,但是它们共享同一个网络命名空间。这意味着容器可以通过相对地址进行通信,不需要使用 IP 地址。

但是,在某些特殊情况下,容器可能需要使用 IP 地址进行通信,此时容器可以获取自己的 IP 地址。这些 IP 地址是由容器所在的 Pod 分配的。

因此,在一个 Pod 中,容器可以有多个 IP 地址,但是它们共享同一个 Pod 的 IP 地址。

SecurityContext

SecurityContext 是一个重要的字段,用于定义 Pod 中容器的安全性配置。它包含了许多子字段,可以用来控制容器的安全特性,例如用户、组、Capabilities 等。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: my-pod
  5. spec:
  6. hostNetwork: false
  7. containers:
  8. - name: my-container
  9. image: nginx:latest
  10. ports:
  11. - containerPort: 80
  12. securityContext:
  13. runAsUser: 1000
  14. runAsGroup: 3000
  15. capabilities:
  16. add:
  17. - NET_BIND_SERVICE
  18. restartPolicy: Never
  19. dnsPolicy: ClusterFirst

在这个例子中,我们为容器指定了 runAsUser 和 runAsGroup,分别用于指定容器运行时使用的用户和组。此外,我们还为容器添加了 NET_BIND_SERVICE Capabilities,以允许容器绑定到小于 1024 的端口。

1000 和 3000 在上面的例子中分别代表了容器运行时使用的用户 ID 和组 ID。

在 Unix-like 操作系统中,每个用户和组都有一个唯一的用户 ID (UID) 和组 ID (GID)。通过指定 runAsUser 和 runAsGroup,可以控制容器的行为和权限,以确保它们的安全性。

例如,如果一个容器指定了一个特殊的用户 ID 和组 ID,它只能访问该用户和组具有的文件和资源,并且无法对其他文件和资源进行更改。

总之,通过指定 runAsUser 和 runAsGroup,可以确保容器在运行时具有合适的权限和访问控制。

总之,使用 SecurityContext 可以对容器的安全性进行细致的配置,以确保 Pod 中的容器具有安全的运行环境。

ImagePullSecrets

ImagePullSecrets 是一个在 Kubernetes 中用于授权拉取私有镜像的字段。它是一个列表,包含一个或多个令牌,用于认证访问私有镜像仓库。

例如,如果你有一个私有镜像仓库,并希望在 Kubernetes 中使用这个镜像,则可以使用 ImagePullSecrets 字段。你需要在本地创建一个 Docker 认证文件,并使用它在 Kubernetes 中创建一个 secret,然后在 ImagePullSecrets 字段中指定这个 secret。这样,当你的 pod 运行时需要拉取镜像时,Kubernetes 就会使用这个令牌进行认证,以确保能够成功拉取私有镜像。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: mypod
  5. spec:
  6. containers:
  7. - name: mycontainer
  8. image: myprivaterepo/myimage:1.0
  9. imagePullSecrets:
  10. - name: myregistrykey

在这个例子中,mypod 定义了一个名为 mycontainer 的容器,使用了从 myprivaterepo 仓库中拉取的名为 myimage 的镜像。imagePullSecrets 字段指定了一个 secret,名为 myregistrykey,用于授权拉取私有镜像。

Affinity

Affinity 是 Kubernetes 中用于控制 pod 在集群中的分布方式的一个字段。它允许你指定 pod 应该在哪些节点上运行,以及它们与其他 pod 的相对位置。这对于在应用程序中使用多个容器时特别有用,因为它允许你控制这些容器的相对位置。

例如,如果你的应用程序包含两个容器,一个是数据库,另一个是 Web 应用程序,你可以使用 Affinity 字段指定数据库容器始终运行在同一个节点上,而 Web 应用程序容器可以在其他节点上运行。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: mypod
  5. spec:
  6. containers:
  7. - name: mycontainer
  8. image: myimage:1.0
  9. affinity:
  10. nodeAffinity:
  11. requiredDuringSchedulingIgnoredDuringExecution:
  12. nodeSelectorTerms:
  13. - matchExpressions:
  14. - key: kubernetes.io/hostname
  15. operator: In
  16. values:
  17. - node1

在这个例子中,mypod 定义了一个名为 mycontainer 的容器,使用了名为 myimage 的镜像。Affinity 字段指定了 nodeAffinity,要求该 pod 在具有标签 kubernetes.io/hostname=node1 的节点上运行。这意味着,如果没有符合条件的节点,该 pod 将不会被调度。

Tolerations

Tolerations 是 Kubernetes 中的一个字段,用于控制 pod 可以在哪些节点上运行。它允许您指定 pod 可以容忍的节点标签。如果您定义了 Affinity 字段,并且不存在符合条件的节点,那么 pod 可以在指定的标签不存在的节点上运行,只要它们被容忍了。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: mypod
  5. spec:
  6. containers:
  7. - name: mycontainer
  8. image: myimage:1.0
  9. tolerations:
  10. - key: "key1"
  11. operator: "Exists"
  12. effect: "NoExecute"

在这个例子中,mypod 定义了一个名为 mycontainer 的容器,使用了名为 myimage 的镜像。Tolerations 字段指定了一个名为 key1 的标签,如果存在该标签,pod 可以在其上运行,即使该标签不匹配 Affinity 中的任何条件。

PriorityClassName和priority

PriorityClassName 和 priority 是 Kubernetes 中的两个字段,用于控制 Pod 的优先级。

  • PriorityClassName 是一个指向 PriorityClass 对象的引用,该对象定义了 Pod 的优先级。

  • priority 是一个整数,表示 Pod 的优先级。

在 Pod 中,如果同时定义了 PriorityClassName 和 priority,那么 PriorityClassName 将被忽略,而 priority 将生效。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: mypod
  5. spec:
  6. priorityClassName: high-priority
  7. containers:
  8. - name: mycontainer
  9. image: myimage:1.0

在这个例子中,mypod 定义了一个名为 mycontainer 的容器,使用了名为 myimage 的镜像。同时,PriorityClassName 字段指定了优先级为 high-priority。

注意:在系统中,必须先定义相应的 PriorityClass 对象,然后才能使用 PriorityClassName 字段。

DNSConfig

DNSConfig 字段用于定义 Pod 中的 DNS 配置。

该字段包含以下字段:

  • nameservers:一个字符串数组,用于指定查询 DNS 服务器的地址。

  • searches:一个字符串数组,用于指定搜索的域名。

  • options:一个字符串数组,用于指定 DNS 解析选项。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: mypod
  5. spec:
  6. dnsConfig:
  7. nameservers:
  8. - 8.8.8.8
  9. - 8.8.4.4
  10. searches:
  11. - mydomain.com
  12. options:
  13. - name: ndots
  14. value: "2"
  15. containers:
  16. - name: mycontainer
  17. image: myimage:1.0

在这个例子中,mypod 定义了一个名为 mycontainer 的容器,使用了名为 myimage 的镜像。同时,DNSConfig 字段指定了查询 DNS 服务器地址为 8.8.8.8 和 8.8.4.4,搜索的域名为 mydomain.com,以及选项 ndots 的值为 2。

ReadinessGates

ReadinessGates 字段用于定义 Pod 在部署时的准备状态。它是一个对象数组,每个对象都包含一个 ConditionType 字段和一个状态字段。当所有条件都满足时,Pod 就是准备就绪的。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: mypod
  5. spec:
  6. readinessGates:
  7. - conditionType: PodScheduled
  8. containers:
  9. - name: mycontainer
  10. image: myimage:1.0

在这个例子中,mypod 定义了一个名为 mycontainer 的容器,使用了名为 myimage 的镜像。同时,readinessGates 字段指定了一个类型为 PodScheduled 的准备条件。这意味着,当 Pod 被调度到一个节点上之后,它才是准备就绪的。

RuntimeClassName

RuntimeClassName 字段用于指定一个 Pod 的运行时环境。在 Kubernetes 中,不同的运行时环境可以具有不同的特性,例如资源限制和存储卷配置。

通过使用 RuntimeClassName 字段,可以指定一个特定的运行时环境,以确保 Pod 运行在符合预期的环境中。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: mypod
  5. spec:
  6. runtimeClassName: myruntime
  7. containers:
  8. - name: mycontainer
  9. image: myimage:1.0

在这个例子中,mypod 定义了一个名为 mycontainer 的容器,使用了名为 myimage 的镜像。同时,RuntimeClassName 字段指定了一个名为 myruntime 的运行时环境。

PreemptionPolicy

PreemptionPolicy 字段用于指定在一个 Node 上预占用 Pod 的策略。当一个新的 Pod 被调度到一个已经被占用的 Node 上时,PreemptionPolicy 将决定如何处理已经在这个 Node 上运行的 Pod。

有三种可能的策略:

  1. Never:表示不会强制占用一个正在运行的 Pod。

  1. Always:表示总是允许预占用正在运行的 Pod。

  1. LeastRequested:表示只会预占用资源请求量最少的 Pod。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: mypod
  5. spec:
  6. preemptionPolicy: Never
  7. containers:
  8. - name: mycontainer
  9. image: myimage:1.0

在这个例子中,mypod 定义了一个名为 mycontainer 的容器,使用了名为 myimage 的镜像。同时,PreemptionPolicy 字段设置为 Never,表示这个 Pod 在任何情况下都不会被占用。

Overhead

Overhead 字段指定了在运行 Pod 时需要额外分配的资源。它是一个选项字段,可以用来为容器分配额外的内存或者 CPU。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: mypod
  5. spec:
  6. overhead:
  7. cpu: 100m
  8. memory: 500Mi
  9. containers:
  10. - name: mycontainer
  11. image: myimage:1.0

在这个例子中,mypod 定义了一个名为 mycontainer 的容器,使用了名为 myimage 的镜像。同时,Overhead 字段指定额外分配了 100m 的 CPU 和 500Mi 的内存。这意味着在运行这个 Pod 的时候,需要额外保证有足够的 CPU 和内存资源。

TopologySpreadConstraints

TopologySpreadConstraints 字段是 Kubernetes 1.19 版本中新增的。它用于控制 Pod 调度的策略。可以帮助保证 Pod 被分配到集群中的不同节点上,从而实现高可用性。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: mypod
  5. spec:
  6. topologySpreadConstraints:
  7. - maxSkew: 1
  8. topologyKey: "kubernetes.io/hostname"
  9. whenUnsatisfiable: DoNotSchedule
  10. containers:
  11. - name: mycontainer
  12. image: myimage:1.0

在这个例子中,mypod 定义了一个名为 mycontainer 的容器,使用了名为 myimage 的镜像。同时,TopologySpreadConstraints 字段指定了对于 Pod 的调度策略。当前指定的规则是:使用节点的 kubernetes.io/hostname 作为调度的依据,每个节点上的 Pod 数量不能差距超过 1,如果规则不满足时不调度这个 Pod。这样可以保证 Pod 在集群中被均匀地分配,并且每个节点上的 Pod 数量差距不会过大,从而保证集群的高可用性。

SetHostnameAsFQDN

SetHostnameAsFQDN 字段是 Kubernetes 1.19 版本中新增的。它用于指定容器的主机名是否被设置为容器的全称域名(FQDN)。默认情况下,容器的主机名将被设置为容器的名称。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: mypod
  5. spec:
  6. hostname: mycontainer
  7. subdomain: mynamespace
  8. setHostnameAsFQDN: true
  9. containers:
  10. - name: mycontainer
  11. image: myimage:1.0

在这个例子中,mypod 定义了一个名为 mycontainer 的容器,使用了名为 myimage 的镜像。同时,setHostnameAsFQDN 字段设置为 true,指示将容器的主机名设置为容器的全称域名,在本例中即为 mycontainer.mynamespace。这可以在容器中提供更多关于容器身份的信息,方便容器内部的程序对容器进行身份识别。

OS

OS 字段指定了运行容器的操作系统。在 Kubernetes 中,可以通过 Docker 镜像运行容器,这些镜像通常是在特定操作系统(如 Linux 或 Windows)上创建的。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: mypod
  5. spec:
  6. containers:
  7. - name: mycontainer
  8. image: myimage:1.0
  9. imagePullPolicy: IfNotPresent
  10. securityContext:
  11. runAsUser: 1000
  12. runAsGroup: 3000
  13. env:
  14. - name: MY_ENV
  15. value: "test"
  16. os: Linux

在这个例子中,mypod 定义了一个名为 mycontainer 的容器,使用了名为 myimage 的镜像。os 字段设置为 Linux,指示该容器将在 Linux 操作系统上运行。

SchedulingGates

SchedulingGates 字段是一个可选字段,用于定义 Pod 的调度策略。该字段允许您定义一组调度策略,以确定是否应该调度 Pod 到特定的节点上。

例如:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: mypod
  5. spec:
  6. containers:
  7. - name: mycontainer
  8. image: myimage:1.0
  9. imagePullPolicy: IfNotPresent
  10. env:
  11. - name: MY_ENV
  12. value: "test"
  13. schedulingGates:
  14. - condition: Exists
  15. matchExpressions:
  16. - key: topology.kubernetes.io/zone
  17. operator: In
  18. values:
  19. - us-west-2a

在这个例子中,mypod 定义了一个名为 mycontainer 的容器,使用了名为 myimage 的镜像。同时,schedulingGates 字段定义了一组调度策略,该策略将仅在匹配特定节点上的 topology.kubernetes.io/zone 关键字为 us-west-2a 的情况下调度 Pod。这意味着,Pod 只会在满足调度策略的节点上调度,否则将不会被调度。

HostUsers

HostUsers 字段控制 Pod 的用户命名空间是否与宿主机共享。如果该字段设置为 true 或没有设置,则 Pod 将在宿主机用户命名空间中运行,这对于 Pod 需要只能从宿主机用户命名空间访问的功能很有用,例如使用 CAP_SYS_MODULE 加载内核模块。如果该字段设置为 false,则为该 Pod 创建一个新的用户命名空间。将其设置为 false 对于防止容器破坏漏洞很有用,并允许用户以 root 身份在宿主机上运行容器,而不需要实际具有宿主机的 root 权限。该字段是 alpha 级别,仅受支持 UserNamespacesSupport 功能的服务器接受。

注意:该字段只适用于支持 UserNamespacesSupport 功能的服务器。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/162218
推荐阅读
相关标签
  

闽ICP备14008679号