我正在使用持久卷声明将数据存储在容器中
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-pvc
labels:
type: amazonEBS
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
规范中的声明:
spec:
volumes:
- name: test-data-vol
persistentVolumeClaim:
claimName: test-pvc
containers:
- name: test
image: my.docker.registry/test:1.0
volumeMounts:
- mountPath: /var/data
name: test-data-vol
首次启动时,该卷已正确安装。但是,当我尝试更新容器映像时:
- image: my.docker.registry/test:1.0
+ image: my.docker.registry/test:1.1
此卷无法装入新的pod:
# kubectl get pods
test-7655b79cb6-cgn5r 0/1 ContainerCreating 0 3m
test-bf6498559-42vvb 1/1 Running 0 11m
# kubectl describe test-7655b79cb6-cgn5r
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3m5s default-scheduler Successfully assigned test-7655b79cb6-cgn5r to ip-*-*-*-*.us-west-2.compute.internal
Warning FailedAttachVolume 3m5s attachdetach-controller Multi-Attach error for volume "pvc-2312eb4c-c270-11e8-8d4e-065333a7774e" Volume is already exclusively attached to one node and can't be attached to another
Normal SuccessfulMountVolume 3m4s kubelet, ip-*-*-*-*.us-west-2.compute.internal MountVolume.SetUp succeeded for volume "default-token-x82km"
Warning FailedMount 62s kubelet, ip-*-*-*-*.us-west-2.compute.internal Unable to mount volumes for pod "test-7655b79cb6-cgn5r(fab0862c-d1cf-11e8-8d4e-065333a7774e)": timeout expired waiting for volumes to attach/mount for pod "test-7655b79cb6-cgn5r". list of unattached/unmounted volumes=[test-data-vol]
Kubernetes似乎无法将该卷从一个容器重新连接到另一个容器。如何正确处理?当旧版本停止时,我需要此卷上的数据以供新版本的部署使用。
答案 0 :(得分:1)
这里的问题是EBS卷是ReadWriteOnce
,只能安装到单个Pod,因此,当您滚动更新时,旧Pod会容纳该卷。为此,您要么必须使用StatefulSet
,要么可以使用任何ReadWriteMany
PV类型。
Kubernetes Deployment有时更适合用于无状态吊舱。
您始终可以使用蛮力方法,这种方法会强制删除保存该卷的容器。确保将Reclaim Policy
设置为Retain
。
答案 1 :(得分:0)
不确定,RollingUpdate
是否可以解决问题。根据{{3}},由于“滚动更新”是更新容器图像的安全方法。我想,K8也可以处理PV / PVC。
答案 2 :(得分:0)
根据您在问题中提供的上下文,我无法确定您的意图是运行单个实例有状态应用程序,还是运行集群有状态应用程序。 / p>
我最近在this section in the docs遇到了这个问题,这是解决该问题的方法...
如果您正在运行单个实例的有状态应用程序:
spec.replicas
,请保持Deployment
的默认值为1。spec.strategy.type
中将Recreate
设置为Deployment
示例Deployment
(来自docs):
# application/mysql/mysql-deployment.yaml apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 kind: Deployment metadata: name: mysql spec: selector: matchLabels: app: mysql strategy: type: Recreate template: metadata: labels: app: mysql spec: containers: - image: mysql:5.6 name: mysql env: # Use secret in real usage - name: MYSQL_ROOT_PASSWORD value: password ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pv-claim
示例PersistentVolume
和PersistentVolumeClaim
(来自docs):
# application/mysql/mysql-pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: mysql-pv-volume labels: type: local spec: storageClassName: manual capacity: storage: 20Gi accessModes: - ReadWriteOnce hostPath: path: "/mnt/data" --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pv-claim spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests: storage: 20Gi
这里显而易见的基本问题是,滚动更新将不起作用,因为在任何时候最多只能运行一个pod。将spec.strategy.type
设置为Recreate
会告诉Kubernetes在部署新Pod之前先停止正在运行的Pod,因此即使有最少的停机时间,也可能会有一些停机时间。
如果您需要群集的有状态应用程序,则可以使用已经提到的StatefulSet
作为控制器类型或将ReadWriteMany
作为存储类型。