云端漫步
type: channel
link: https://blog.lazytoki.cn/
description: 他们都去了很远的地方冒险 ，那是有一片片由钢筋水泥筑成，同时又掺入了梦想的丛林 。
items: Kubernetes PDB资源状态解释
items: 随感
items: 拥抱云原生! 使用Kubernetes部署Minecraft服务器吧
items: Loki和grafana集成问题
items: pod所在节点的dns解析有问题
items: Ingress认证
items: k8s自动申请证书
items: k8s securityContext笔记
items: Nginx Ingress 4层代理笔记
items: 通过Kubernetes集群部署Minecraft服服务器

Kubernetes PDB资源状态解释
type: item
date: 2025-03-03T03:31:00+00:00
description: 1. 什么是自愿中断？在 Kubernetes 中，中断分为两种：自愿中断（Voluntary Disruptions）：由用户或管理员主动触发的操作，例如：升级或维护节点（Node Drain）。手动删除 Pod。更新 Deployment 或 StatefulSet 的 Pod 模板（触发滚动更新）。非自愿中断（Involuntary Disruptions）：由系统故障或意外事件引起的，例如：节点硬件故障。网络分区。内核崩溃。PDB 主要用于管理自愿中断，确保在中断过程中应用的高可用性。2. PDB 的作用PDB 的核心作用是：限制同时中断的 Pod 数量，确保在自愿中断期间，应用仍然能够保持一定数量的可用 Pod。防止因中断操作导致的服务不可用或性能下降。例如：如果你有一个包含 10 个 Pod 的 Deployment，设置 PDB 可以确保在节点升级时，最多只有 2 个 Pod 被终止，剩下的 8 个 Pod 仍然可以提供服务。3. PDB 的关键参数PDB 有两个关键参数，用于定义中断的容忍度：minAvailable：指定在中断期间，必须保持的最小可用 Pod 数量。例如：minAvailable: 3 表示在任何时候，至少有 3 个 Pod 必须是可用的。maxUnavailable：指定在中断期间，最多允许多少个 Pod 不可用。例如：maxUnavailable: 1 表示在任何时候，最多只能有 1 个 Pod 不可用。注意：minAvailable 和 maxUnavailable 是互斥的，只能设置其中一个。4. PDB 的工作原理当 Kubernetes 进行自愿中断操作时（例如节点 Drain 或滚动更新），它会检查相关的 PDB 规则：如果中断操作会导致 Pod 数量低于 minAvailable 或超过 maxUnavailable，则中断操作会被阻止。只有当中断操作符合 PDB 规则时，才会继续执行。例如：假设你有一个 Deployment，包含 5 个 Pod，并且设置了 maxUnavailable: 1。当你触发滚动更新时，Kubernetes 会确保在任何时候，最多只有 1 个 Pod 被终止，剩下的 4 个 Pod 仍然可以提供服务。5. PDB 的适用场景PDB 特别适用于以下场景：有状态服务：例如数据库（如 MySQL、PostgreSQL）或消息队列（如 Kafka、RabbitMQ），需要确保在中断期间仍然有足够的副本提供服务。高可用服务：例如 Web 服务或 API 服务，需要确保在中断期间不会导致服务不可用。滚动更新：在更新应用时，确保服务的可用性不受影响。6. PDB 的示例以下是一个 PDB 的 YAML 示例：apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: my-app-pdb namespace: default spec: minAvailable: 2 # 确保至少有 2 个 Pod 可用 selector: matchLabels: app: my-app # 选择需要保护的 Pod 或者使用 maxUnavailable：apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: my-app-pdb namespace: default spec: maxUnavailable: 1 # 最多允许 1 个 Pod 不可用 selector: matchLabels: app: my-app # 选择需要保护的 Pod 7. PDB 的注意事项仅对自愿中断有效：PDB 只能管理自愿中断（如节点 Drain、滚动更新），无法防止非自愿中断（如节点故障）。需要合理设置参数：如果 minAvailable 或 maxUnavailable 设置过于严格，可能会导致中断操作无法执行。与 HPA 结合使用：如果应用使用了 Horizontal Pod Autoscaler（HPA），需要确保 PDB 的设置与 HPA 的伸缩策略兼容。8. PDB 的实际应用假设你有一个包含 3 个 Pod 的 Deployment，并且希望确保在节点升级时，至少有两个 Pod 可用。你可以创建一个 PDB：apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: my-app-pdb namespace: default spec: minAvailable: 2 selector: matchLabels: app: my-app 当管理员执行节点 Drain 操…

随感
type: item
date: 2024-07-02T14:55:00+00:00
description: 害怕失去，害怕得不到，不敢向前走，永远在焦虑，永远止步不前，像一只仓鼠一样囤积自己所见的一切，仿佛把一切都抓在自己身边，那么周围事物就会围绕着我一直不变...

拥抱云原生! 使用Kubernetes部署Minecraft服务器吧
type: item
date: 2024-05-05T07:52:00+00:00
description: 前言随着docker的爆火，万物皆可容器化，当然Minecraft游戏服务端也不例外，早在docker刚出现的时候，itzg大佬在github的便推出了Minecraft running on docker的项目，支持各类服务端的运行。但是随着笔者接触到云原生之后，便热衷于用k8s去部署各种支持容器化的项目，幸运的是itzg大佬也写了可以使用k8s的helm部署的chart包，这样我们就可以一键梭哈部署我们的Minecraft服务器啦！准备工作环境需求8G以上的内存,100G以上硬盘正常运行的Kubernetes 集群，版本1.4以上提前预定义好存储卷PV provisioner 或者使用动态存储卷Helm版本v3.x以上可选环境部署Nginx ingress (Kubernetes ingress流量解决方案)使用OpenEBS动态制备本地存储卷 (Kubernetes存储解决方案)使用Cert-manager实现服务端域名https自动证书申请准备部署当以上环境条件满足后，我们就可以开始愉快部署了：在终端输入以下命令后，于是我们的部署就完成啦 ，happy helming :)helm install minecraft \ --set minecraftServer.eula=true itzg/minecraft很显然我们不可能稀里糊涂的就这么部署了，我们既没有指定使用哪种服务端，也没有指定对应java版本等等，这不是我们所期望的结果。所以在开始前，我们先得获取作者提供的Helm chart包，在ArtifactHub这个网站就可以获取到我们所需的Minecraft chart包。然后我们将下载好的包解压之后，会得到如下文件：minecraft ├── Chart.yaml ├── README.md ├── ci │ └── test-values.yaml ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── backupdir-pvc.yaml │ ├── datadir-pvc.yaml │ ├── deployment.yaml │ ├── extra-list.yaml │ ├── extraports-ing.yaml │ ├── extraports-svc.yaml │ ├── minecraft-svc.yaml │ ├── rclone-secret.yaml │ ├── rcon-svc.yaml │ └── secrets.yaml ├── values.schema.json └── values.yaml首先我们新建一份yaml格式的空白文件，命名为customized-values.yaml,后面我们会用这份文件自定义配置，达到我们期望部署的Minecraft服务端。然后我们打开values.yaml，我们会看到许多配置参数，令人眼花缭乱，但是我们只看对我们部署关键的参数，然后把这些参数按照yaml语法格式复制到我们新建的values文件里，可以参考如下我在新的values文件里定义的参数。images tag这里可以参考作者给的文档详细展示了容器镜像tag和java版本的对应关系，这样可以找到适合运行Minecraft服务端的java版本。#指定容器的镜像地址，以及镜像tag使用哪个版本的java # ref: https://hub.docker.com/r/itzg/minecraft-server/ image: repository: itzg/minecraft-server tag: java11-jdk pullPolicy: IfNotPresent pullSecret: ""CPU/Memory资源限制个人建议可以把resource设置上，以免容器内存或者CPU过高把节点搞崩。resources: requests: memory: 4096Mi cpu: 1000m limits: cpu: 5500m memory: 8192Mi工作节点选择(可跳过不设置)如果你是多个工作节点的话，可以忽略scheduler的调度算法，指定pod到哪个节点上去部署nodeSelector: kubernetes.io/hostname: home-local-worker07探活设置#这里我把initialDelaySeconds调成了300s,视个人网络情况而定，以便给服务端足够的启动时间，防止服务端没能在探活周期正常运行，导致被强制kill掉。 livenessProbe: command: - mc-health initialDelaySeconds: 300 periodSeconds: 5 failureThr…

Loki和grafana集成问题
type: item
date: 2024-04-04T13:50:22+00:00
description: 问题描述在使用helm部署loki-stack的时候，遇到连接loki的数据源出现失败的情况loki-stack 版本 2.10.2查看log发现如下报错logger=tsdb.loki endpoint=CheckHealth t=2024-04-04T11:56:44.985411573Z level=error msg="Loki health check failed" error="error from loki: parse error at line 1, col 1: syntax error: unexpected IDENTIFIER" logger=context userId=1 orgId=1 uname=admin t=2024-04-04T11:56:44.985485641Z level=info msg="Request Completed" method=GET path=/api/datasources/uid/ddhj6qxw5g7pcc/health status=400 remote_addr=116.3.95.227 time_ms=53 duration=53.253649ms size=106 referer=https://grafana.lazytoki.cn/connections/datasources/edit/ddhj6qxw5g7pcc handler=/api/datasources/uid/:uid/health status_source=server logger=tsdb.loki endpoint=checkHealth pluginId=loki dsName=loki dsUID=ddhj6qxw5g7pcc uname=admin fromAlert=false t=2024-04-04T11:56:44.985183092Z level=error msg="Error received from Loki" duration=51.467899ms stage=databaseRequest statusCode=400 contentLength=65 start=1970-01-01T00:00:01Z end=1970-01-01T00:00:04Z step=1s query=vector(1)+vector(1) queryType=instant direction=backward maxLines=0 supportingQueryType=none lokiHost=loki.loki:3100 lokiPath=/loki/api/v1/query status=error error="parse error at line 1, col 1: syntax error: unexpected IDENTIFIER" statusSource=downstream level=warn ts=2024-04-02T15:27:53.199405593Z caller=client.go:419 component=client host=loki:3100 msg="error sending batch, will retry" status=-1 tenant= error="Post \"http://loki:3100/loki/api/v1/push\": dial tcp 10.96.0.245:3100: connect: connection refused" level=warn ts=2024-04-02T15:27:53.931125608Z caller=client.go:419 component=client host=loki:3100 msg="error sending batch, will retry" status=-1 tenant= error="Post \"http://loki:3100/loki/api/v1/push\": dial tcp 10.96.0.245:3100: connect: connection refused" level=warn ts=2024-04-02T15:27:54.990545589Z caller=client.go:419 component=client host=loki:3100 msg="error sending batch, will retry" status=-1 tenant= error="Post \"http://loki:3100/loki/api/v1/push\": dial tcp 10.96.…

pod所在节点的dns解析有问题
type: item
date: 2024-03-31T14:20:00+00:00
description: 问题现象在某个节点上的pod在进行外部通信的时候报错，具体错误是:ERROR: [generic] Unable to download webpage: <urlopen error [Errno -3] Temporary failure in name resolution> (caused by URLError(gaierror(-3, 'Temporary failure in name resolution')))意思是在进行dns解析的时候出现错误。排查在问题节点上启动busybox尝试ping其他节点上无头服务，发现无法ping通，初步断定是当前节点的dns解析出现了问题root@tencent-beijing-master:~# kubectl exec -it busybox-vj29p -- sh / # ping postgresql-hl.cloud ping: bad address 'postgresql-hl.cloud' / # ping mysql-primary-headless ^C / # ping mysql-primary-headless.cloud ping: bad address 'mysql-primary-headless.cloud' / # exit / ping mysql-primary-headless.cloud ^C / ping baidu.com ^C / # 在其他节点上ping却可以ping通root@tencent-beijing-master:~# kubectl exec -it busybox-4zp7g -- sh / # ping postgresql-hl.cloud PING postgresql-hl.cloud (100.93.145.75): 56 data bytes 64 bytes from 100.93.145.75: seq=0 ttl=62 time=3.333 ms 64 bytes from 100.93.145.75: seq=1 ttl=62 time=3.185 ms 64 bytes from 100.93.145.75: seq=2 ttl=62 time=3.247 ms 64 bytes from 100.93.145.75: seq=3 ttl=62 time=3.247 ms ^C --- postgresql-hl.cloud ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 3.185/3.253/3.333 ms / # / # ping baidu.com PING baidu.com (110.242.68.66): 56 data bytes 64 bytes from 110.242.68.66: seq=0 ttl=250 time=12.091 ms 64 bytes from 110.242.68.66: seq=1 ttl=250 time=12.163 ms 64 bytes from 110.242.68.66: seq=2 ttl=250 time=12.187 ms 64 bytes from 110.242.68.66: seq=3 ttl=250 time=12.153 ms ^C --- baidu.com ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 12.091/12.148/12.187 ms / # 发现也无法ping集群内部pod iproot@tencent-beijing-master:~# kubectl exec -it busybox-vj29p -- sh / # ping 100.96.12.201 PING 100.96.12.201 (100.96.12.201): 56 data bytes ^C --- 100.96.12.201 ping statistics --- 3 packets transmitted, 0 packets received, 100% packet loss / # exit command terminated with exit code 1 root@tencent-beijing-master:~# 其他节点的却可以ping通root@tencent-beijing-maste…

Ingress认证
type: item
date: 2024-03-31T13:43:45+00:00
description: Basic Authentication¶This example shows how to add authentication in a Ingress rule using a secret that contains a file generated with htpasswd. It's important the file generated is named auth (actually - that the secret has a key data.auth), otherwise the ingress-controller returns a 503.Create htpasswd file¶$ htpasswd -c auth foo New password: <bar> New password: Re-type new password: Adding password for user fooConvert htpasswd into a secret¶$ kubectl create secret -n generic basic-auth --from-file=auth secret "basic-auth" createdExamine secret¶$ kubectl get secret basic-auth -o yaml apiVersion: v1 data: auth: Zm9vOiRhcHIxJE9GRzNYeWJwJGNrTDBGSERBa29YWUlsSDkuY3lzVDAK kind: Secret metadata: name: basic-auth namespace: default type: Opaque

k8s自动申请证书
type: item
date: 2024-03-31T13:39:25+00:00
description: Automated Certificate Management with cert-managercert-manager automatically requests missing or expired certificates from a range of supported issuers (including Let's Encrypt) by monitoring ingress resources.To set up cert-manager you should take a look at this full example.To enable it for an ingress resource you have to deploy cert-manager, configure a certificate issuer update the manifest:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-demo annotations: cert-manager.io/issuer: "letsencrypt-staging" # Replace this with a production issuer once you've tested it [..] spec: tls: - hosts: - ingress-demo.example.com secretName: ingress-demo-tls [...]

k8s securityContext笔记
type: item
date: 2023-12-30T16:29:00+00:00
description: podSecurityContext 和 securityContext 是两个相关但用途不同的配置选项，用于 Kubernetes 中的容器和 Pod 安全性。podSecurityContext：podSecurityContext 是用于配置整个 Pod 的安全上下文的选项。它通常包括 Pod 层面的配置，例如指定运行 Pod 的用户和组、Seccomp 配置、AppArmor 配置等。podSecurityContext 中的设置将应用于 Pod 内的所有容器，除非在容器级别明确覆盖。示例：apiVersion: v1 kind: Pod metadata: name: my-pod spec: securityContext: runAsUser: 1000 containers: - name: my-container image: my-imagesecurityContext：securityContext 是用于配置单个容器的安全上下文的选项。它通常包括容器级别的配置，例如指定容器运行时的用户和组、特权模式、Linux 内核功能、Seccomp 配置、AppArmor 配置等。securityContext 中的设置将应用于特定容器，允许在同一 Pod 内的不同容器中使用不同的安全配置。示例：apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: container-1 image: image-1 securityContext: runAsUser: 1000 - name: container-2 image: image-2 securityContext: runAsUser: 2000总之，podSecurityContext 用于配置整个 Pod 的安全性，而 securityContext 用于配置单个容器的安全性。你可以根据需要在 Pod 和容器级别分别配置它们，以满足特定的安全需求。podSecurityContext 是 Kubernetes 中用于定义 Pod 安全上下文的配置选项。这允许你为特定的 Pod 配置安全属性，以确保其行为与安全性符合你的需求。Pod 安全上下文通常用于控制以下方面的安全性：Linux 用户和组的权限：你可以通过 runAsUser 和 runAsGroup 字段设置 Pod 中容器的运行用户和组。这有助于限制容器的权限，防止恶意进程访问主机上的资源。Linux 特权模式：你可以使用 privileged 字段来指定是否容器应该以特权模式运行，这将影响容器的访问权限，包括主机上的文件系统。Seccomp 和 AppArmor 配置：通过 seccompProfile 和 apparmorProfile 字段，你可以配置容器的 Seccomp 和 AppArmor 配置，以限制容器中进程的系统调用和访问权限。sysctl 参数：使用 sysctls 字段，你可以配置容器的内核参数，以增强容器的安全性。Linux 安全上下文标签：你可以使用 securityContext 字段配置 Linux 安全上下文标签，以限制容器的访问权限。资源限制：虽然资源限制通常与 Pod 的 resources 字段相关，但它们也与安全性有关。通过限制 CPU 和内存资源，你可以避免容器使用过多的资源，从而确保其他 Pod 仍然能够正常工作。示例：apiVersion: v1 kind: Pod metadata: name: my-pod spec: securityContext: runAsUser: 1000 runAsGroup: 3000 seccompProfile: type: RuntimeDefault containers: - name: my-container image: my-image在这个示例中，securityContext 设置了运行容器的用户和组，以及 Seccomp 配置。这有助于确保容器以指定的用户和组运行，并且受到 Seccomp 配置的限制。这是一个简化的示例，实际配置可能会更复杂，根据安全需求来定制。securityContext 在 Kubernetes 中是用于定义 Pod 或容器的安全上下文的配置选项。这些配置允许你控制容器运行时的安全性特性。以下是一些常见的 securityContext 字段及其作用：runAsUser 和 runAsGroup： 用于指定容器运行时的用户和用户组。这有助于限制容器内进程的权限，确保它们以指定的用户和用户组身份运行。securityContext: runAsUser: 1000 runAsGr…

Nginx Ingress 4层代理笔记
type: item
date: 2023-12-30T16:23:00+00:00
description: Nginx Ingress Controller 在 Kubernetes 中充当了一个代理和负载均衡器的角色，它可以根据 Ingress 资源的规则将外部的 HTTP/HTTPS 流量转发到集群内部的服务。然而，对于非 HTTP/HTTPS 的流量，例如 TCP/UDP，Nginx Ingress Controller 也提供了代理的功能，但它并不是通过 Ingress 资源来配置，而是需要通过 ConfigMap 进行配置。以下是 Nginx Ingress 的 TCP 代理的工作原理：集群外部的 TCP 连接请求：当有一个来自集群外部的 TCP 连接请求到达 Nginx Ingress Controller 时，Nginx 会根据这个请求的目标端口来决定如何处理这个请求。ConfigMap 配置：Nginx Ingress Controller 会读取一个特定的 ConfigMap（通常名为 tcp-services 或 udp-services），在这个 ConfigMap 中，你可以定义一个端口到服务的映射。这个映射告诉 Nginx Ingress Controller，对于到达特定端口的 TCP 请求，应该将其转发到哪个服务。TCP 请求转发：根据 ConfigMap 的配置，Nginx Ingress Controller 会将 TCP 请求转发到对应的服务。这个服务可以是集群内的任何服务，不论它是运行在哪个 Namespace 中，或者是使用哪种协议。服务响应：当服务处理完请求并返回响应时，Nginx Ingress Controller 会将这个响应返回给原始的 TCP 客户端。值得注意的是，Nginx Ingress 的 TCP/UDP 代理比 HTTP/HTTPS 代理少了很多功能，例如基于路径的路由、SSL 终止、主机名路由等。因为 TCP 和 UDP 是传输层协议，它们并不像 HTTP/HTTPS 那样提供丰富的应用层信息，所以 Nginx Ingress Controller 只能根据 TCP/UDP 请求的目标端口来决定如何转发请求。Nginx Ingress Controller 提供了 TCP 服务的代理功能，但是它并不支持基于路径或主机名的路由，这是因为 TCP 是一种传输层协议，它并不包含这些应用层信息。所以，如果你想要代理 TCP 服务到集群内部的多个服务，你需要为每个服务指定一个唯一的端口。你可以在一个名为 tcp-services 或 udp-services 的 ConfigMap 中定义端口到服务的映射。例如：apiVersion: v1 kind: ConfigMap metadata: name: tcp-services namespace: ingress-nginx data: 9000: "default/my-service-1:9000" 9001: "default/my-service-2:9001"在这个例子中，所有发送到端口 9000 的 TCP 请求将被转发到名为 my-service-1 的服务的端口 9000，所有发送到端口 9001 的 TCP 请求将被转发到名为 my-service-2 的服务的端口 9001。请注意，你需要在 Nginx Ingress Controller 的部署配置中添加一个参数，指定这个 ConfigMap 的名称。例如：args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/tcp-services这样，Nginx Ingress Controller 就会加载这个 ConfigMap，并根据它的配置来代理 TCP 请求。最后，你需要在 Nginx Ingress Controller 的 Service 中公开这些端口，以便外部的 TCP 客户端可以连接到它们。例如：apiVersion: v1 kind: Service metadata: name: ingress-nginx namespace: ingress-nginx spec: ports: - name: http port: 80 targetPort: http - name: https port: 443 targetPort: https - name: tcp-9000 port: 9000 targetPort: 9000 - name: tcp-9001 port: 9001 targetPort: 9001 selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: in…

通过Kubernetes集群部署Minecraft服服务器
type: item
date: 2023-12-30T16:18:00+00:00
description: 1.准备工作需要以下基础Kubernetes基础概念Kubernetes集群(当前集群版本 version 1.23.4)#当前环境版本 Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.4", GitCommit:"e6c093d87ea4cbb530a7b2ae91e54c0842d8308a", GitTreeState:"clean", BuildDate:"2022-02-16T12:38:05Z", GoVersion:"go1.17.7", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.4", GitCommit:"e6c093d87ea4cbb530a7b2ae91e54c0842d8308a", GitTreeState:"clean", BuildDate:"2022-02-16T12:32:02Z", GoVersion:"go1.17.7", Compiler:"gc", Platform:"linux/amd64"}helm服务#当前环境版本 version.BuildInfo{Version:"v3.8.1", GitCommit:"5cb9af4b1b271d11d7a97a71df3ac337dd94ad37", GitTreeState:"clean", GoVersion:"go1.17.5"}Minecraft helm chart包在Artifact hub下载并解压对应的Minecraft chart包到当前目录 (chart version 4.3.0)2.配置基础Values文件先把服务端跑起来,体验一把由于values文件内容较多，我们只需要修改如下地方就可以把服务端跑起来.修改如下地方,在values文件中搜索即可找到: 服务端版本类型以及服务端属性文件的地方 minecraftServer: #同意EULA，搭建过mc服务器的童鞋应该都知道这个地方 This must be overridden, since we can't accept this for the user. eula: "TRUE" # 服务端的版本,例如填入版本1.12.2或者1.16.5... One of: LATEST, SNAPSHOT, or a specific version (ie: "1.7.9"). version: "1.12.2" # 服务端类型,默认是原版VANILLA，也就是官方服务端 This can be one of "VANILLA", "FORGE", "SPIGOT", "BUKKIT", "PAPER", "FTBA", "SPONGEVANILLA", "CURSEFORGE" type: "VANILLA" # 服务端内存限制 If you adjust this, you may need to adjust resources.requests above to match. memory: 1024M # 如果需要离线登录，请关闭online mode Check accounts against Minecraft account service. onlineMode: false 这个地方是选择k8s集群的存储驱动，我这里使用的是nfs的动态provisioner，大家可以自寻选择自己合适的CSI插件作为自己的Minecraft后端存储 注意层级关系，value中有两处persistence的配置地方，选择最外层的persistence进行配置 persistence: annotations: {} ## minecraft data Persistent Volume Storage Class ## If defined, storageClassName: <storageClass> ## If set to "-", storageClassName: "", which disables dynamic provisioning ## If undefined (the default) or set to null, no storageClassName spec is ## set, choosing the default provisioner. (gp2 on AWS, standard on ## GKE, AWS & OpenStack) ## storage…