繁体   English   中英

如何将卷附加到 kube.netes pod 容器,如 docker?

[英]How to attache a volume to kubernetes pod container like in docker?

我是 Kube.netes 的新手,但熟悉 docker。

Docker 用例

通常,当我想保留数据时,我只是创建一个带有名称的卷,然后将其附加到容器中,即使我停止它然后启动另一个具有相同图像的卷,我也可以看到数据持久化。 所以这就是我以前在 docker 中所做的

docker volume create nginx-storage
run -it --rm -v nginx-storage:/usr/share/nginx/html -p 80:80 nginx:1.14.2

然后我:

  1. 在 /usr/share/nginx/html 新建一个 html 文件
  2. 停止容器
  3. 再次运行相同的 docker 运行命令(将创建另一个具有相同卷的容器)
  4. html 文件存在(这意味着数据保存在该卷中)

Kube.netes 用例

通常,当我使用 Kube.netes 卷时,我使用 hostPath 指定 PVC (PersistentVolumeClaim) 和 PV (PersistentVolume),这会将装载目录或文件从主机绑定到容器。

我想要做的是重现上一个示例( Docker 用例)中指定的相同行为,那么我该怎么做呢? Kube.netes 创建卷的过程是否与 Docker 不同? 如果可能的话,提供 YAML 文件会帮助我理解。

我设法通过创建 PVC 来做到这一点,这就是我的做法(使用 Nginx 图像):

nginx-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-data
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Mi

nginx-deployment.yaml

# Deployment 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template: # template for the pods
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.14.2
          volumeMounts:
            - mountPath: /usr/share/nginx/html
              name: nginx-data
      volumes:
        - name: nginx-data
          persistentVolumeClaim:
            claimName: nginx-data  
      restartPolicy: Always       
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: nginx
  ports:
    - name: http
      port: 80
      nodePort: 30080
  type: NodePort

一旦我在 PVC 上运行 kubectl apply 然后在部署到localhost:30080将显示 404 not found 页面意味着一旦容器启动, /usr/share/nginx/html中的所有数据都被删除,这是因为它是绑定安装从 k8s 集群节点到该容器的目录作为卷:

/usr/share/nginx/html <-- dir in volume
/var/lib/k8s-pvs/nginx2-data/pvc-9ba811b0-e6b6-4564-b6c9-4a32d04b974f <-- dir from node (was automatically created)
  • 我尝试将新文件作为新的 index.html 文件添加到 html 目录中的该容器中,然后删除该容器,pod 创建了一个新容器并检查 localhost:30080 是否与新创建的主页一起使用

  • 我尝试删除部署并重新应用它(不删除 PVC)检查了 localhost:30080 并且一切仍然存在。

评论中指定的替代解决方案kube.netes.io/docs/tasks/configure-pod-container/… by larsks

初步估计,您不能(可移植地)这样做。 而是将您的内容构建到图像中。

有两个大的实际问题,特别是如果您在云托管的 Kube.netes 上运行面向生产的系统:

  1. 如果您查看PersistentVolume 类型列表,其中很少有可以在 ReadWriteMany 模式下使用。 很容易获得一次只能在一个节点上使用的 AWSElasticBlockStore 卷,类似这样的东西可能是默认的集群设置。 这意味着您将无法运行为相同(静态)数据提供服务的多个 pod 副本。

  2. 一旦你得到一个卷,就很难编辑它的内容。 考虑前面提到的 EBS 卷:如果不登录到安装它的节点就无法编辑它,这意味着找到该节点,让您的安全团队相信您可以对整个集群进行根访问,启用远程登录,然后编辑文件。 在大多数非开发人员 Kube.netes 设置中,这实际上是不可能的。

相反,您应该做的是将 static 内容构建到自定义图像中。 运行 Kube.netes 几乎需要某种图像注册表,您可以将此 static 内容服务器推送到与您的应用程序代码相同的注册表中。

FROM nginx:1.14.2
COPY . /usr/share/nginx/html
# Base image has a working CMD, no need to repeat it

然后在您的部署规范中,设置image: registry.example.com/nginx-frontend:20220209或您选择命名此图像构建的任何名称,并且根本不使用卷。 您可以像部署应用程序的其他部分一样部署它; 您可以使用 Helm 或 Kustomize 来简化更新过程。

相应地,在普通 Docker 的情况下,我会避免这里的卷。 您不讨论文件如何进入nginx-storage命名卷; 如果您使用docker cp类的命令式命令或docker exec类的调试工具,这些方法很难编写脚本,并且本质上是它们运行的系统的本地方法。 将一个 Docker 卷从一个地方复制到另一个地方并不容易。 不过,可以通过注册表推送和拉取图像。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM