管理持久卷

一些包含的服务需要持久存储,通过持久卷配置,指定您的集群可以访问哪些磁盘。 有关安装此 chart 所需的存储配置的文档,可以查看存储指南

安装后的存储更改需要由集群管理员手动处理。 GitLab chart 不处理安装后这些卷的自动管理。

初始安装后未自动管理的更改示例包括:

  • 将不同的卷挂载到 Pod
  • 更改有效访问模式或 Storage Class
  • 扩展卷的存储大小*1

1 在 Kubernetes 1.11 中,如果您在 Storage Class 中将 allowVolumeExpansion 配置为 true,支持扩展卷的存储大小

由于以下原因,自动化这些更改很复杂:

  1. Kubernetes 不允许更改现有 PersistentVolumeClaim 中的大多数字段
  2. 除非手动配置PVC 是唯一动态配置的 PersistentVolumes
  3. Delete 是动态配置的 PersistentVolumes 默认的 reclaimPolicy

这意味着为了进行更改,我们需要删除 PersistentVolumeClaim 并使用我们的更改创建一个新的。但是由于默认reclaimPolicy,删除了PersistentVolumeClaim 可能会删除 PersistentVolumes 和底层磁盘。除非配置了适当的 volumeNames 和/或 labelSelectors,否则 chart 不知道要附加到的卷。

我们将继续研究如何简化此过程,但目前需要遵循手动过程来更改您的存储。

找到 GitLab 卷

查找正在使用的 volumes/claims:

kubectl --namespace <namespace> get PersistentVolumeClaims -l release=<chart release name> -ojsonpath='{range .items[*]}{.spec.volumeName}{"\t"}{.metadata.labels.app}{"\n"}{end}'
  • <namespace> 应该替换为您安装 GitLab chart 的命名空间。
  • <chart release name> 应替换为您用于安装 GitLab chart 的名称。

该命令打印卷名称列表,后面是它们所针对的服务的名称。

例如:

$ kubectl --namespace helm-charts-win get PersistentVolumeClaims -l release=review-update-app-h8qogp -ojsonpath='{range .items[*]}{.spec.volumeName}{"\t"}{.metadata.labels.app}{"\n"}{end}'
pvc-6247502b-8c2d-11e8-8267-42010a9a0113  gitaly
pvc-61bbc05e-8c2d-11e8-8267-42010a9a0113  minio
pvc-61bc6069-8c2d-11e8-8267-42010a9a0113  postgresql
pvc-61bcd6d2-8c2d-11e8-8267-42010a9a0113  prometheus
pvc-61bdf136-8c2d-11e8-8267-42010a9a0113  redis

在进行存储更改之前

进行更改的人员需要对集群具有管理员访问权限,并对所使用的存储解决方案具有适当的访问权限。通常首先需要在存储解决方案中应用更改,然后需要在 Kubernetes 中更新结果。

在进行更改之前,您应该确保您的 PersistentVolumes 正在使用 Retain reclaimPolicy,这样它们就不会在您进行更改时被删除。

首先,找到正在使用的卷/声明

接下来,编辑每个卷并将 spec 字段下 persistentVolumeReclaimPolicy 的值更改为 Retain 而不是 Delete

例如:

kubectl --namespace helm-charts-win edit PersistentVolume pvc-6247502b-8c2d-11e8-8267-42010a9a0113

编辑输出:

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    kubernetes.io/createdby: gce-pd-dynamic-provisioner
    pv.kubernetes.io/bound-by-controller: "yes"
    pv.kubernetes.io/provisioned-by: kubernetes.io/gce-pd
  creationTimestamp: 2018-07-20T14:58:43Z
  labels:
    failure-domain.beta.kubernetes.io/region: europe-west2
    failure-domain.beta.kubernetes.io/zone: europe-west2-b
  name: pvc-6247502b-8c2d-11e8-8267-42010a9a0113
  resourceVersion: "48362431"
  selfLink: /api/v1/persistentvolumes/pvc-6247502b-8c2d-11e8-8267-42010a9a0113
  uid: 650bd649-8c2d-11e8-8267-42010a9a0113
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 50Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: repo-data-review-update-app-h8qogp-gitaly-0
    namespace: helm-charts-win
    resourceVersion: "48362307"
    uid: 6247502b-8c2d-11e8-8267-42010a9a0113
  gcePersistentDisk:
    fsType: ext4
    pdName: gke-cloud-native-81a17-pvc-6247502b-8c2d-11e8-8267-42010a9a0113
# Changed the following line
  persistentVolumeReclaimPolicy: Retain
  storageClassName: standard
status:
  phase: Bound

进行存储更改

首先,对集群外的磁盘进行所需的更改。(在 GKE 中调整磁盘大小,或从快照或克隆等创建新磁盘)。

您如何做到这一点,以及是否可以在不停机的情况下实时完成,取决于您使用的存储解决方案,本文档无法涵盖。

接下来,评估您是否需要将这些更改反映在 Kubernetes 对象中。例如:随着磁盘存储容量的扩大,PersistentVolumeClaim 中的存储容量设置只会在有新的卷资源时使用。 因此,如果您打算扩展更多磁盘(用于额外的 Gitaly Pod),则只需增加 PersistentVolumeClaim 中的值。

如果您确实需要在 Kubernetes 中反映更改,请确保已按照 在进行存储更改之前 部分中所述更新了卷的回收策略。

我们记录的存储更改路径是:

对现有卷的更改

首先找到您要更改的 GitLab 卷

使用 kubectl edit 对卷进行所需的配置更改。(这些更改应该只是更新反映附加磁盘的真实状态)

例如:

kubectl --namespace helm-charts-win edit PersistentVolume pvc-6247502b-8c2d-11e8-8267-42010a9a0113

编辑输出:

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    kubernetes.io/createdby: gce-pd-dynamic-provisioner
    pv.kubernetes.io/bound-by-controller: "yes"
    pv.kubernetes.io/provisioned-by: kubernetes.io/gce-pd
  creationTimestamp: 2018-07-20T14:58:43Z
  labels:
    failure-domain.beta.kubernetes.io/region: europe-west2
    failure-domain.beta.kubernetes.io/zone: europe-west2-b
  name: pvc-6247502b-8c2d-11e8-8267-42010a9a0113
  resourceVersion: "48362431"
  selfLink: /api/v1/persistentvolumes/pvc-6247502b-8c2d-11e8-8267-42010a9a0113
  uid: 650bd649-8c2d-11e8-8267-42010a9a0113
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    # Updated the storage size
    storage: 100Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: repo-data-review-update-app-h8qogp-gitaly-0
    namespace: helm-charts-win
    resourceVersion: "48362307"
    uid: 6247502b-8c2d-11e8-8267-42010a9a0113
  gcePersistentDisk:
    fsType: ext4
    pdName: gke-cloud-native-81a17-pvc-6247502b-8c2d-11e8-8267-42010a9a0113
  persistentVolumeReclaimPolicy: Retain
  storageClassName: standard
status:
  phase: Bound

现在更改已反映在 volume 中,我们需要更新 claim

按照对 PersistentVolumeClaim 进行更改部分中的说明进行操作。

更新要绑定到声明的卷

在单独的终端中,开始观察 claim 的状态何时变为 bound,然后进行下一步,使卷可用于新声明。

kubectl --namespace <namespace> get --watch PersistentVolumeClaim <claim name>

编辑卷以使其可用于新声明。 删除 .spec.claimRef 部分。

kubectl --namespace <namespace> edit PersistentVolume <volume name>

编辑输出:

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    kubernetes.io/createdby: gce-pd-dynamic-provisioner
    pv.kubernetes.io/bound-by-controller: "yes"
    pv.kubernetes.io/provisioned-by: kubernetes.io/gce-pd
  creationTimestamp: 2018-07-20T14:58:43Z
  labels:
    failure-domain.beta.kubernetes.io/region: europe-west2
    failure-domain.beta.kubernetes.io/zone: europe-west2-b
  name: pvc-6247502b-8c2d-11e8-8267-42010a9a0113
  resourceVersion: "48362431"
  selfLink: /api/v1/persistentvolumes/pvc-6247502b-8c2d-11e8-8267-42010a9a0113
  uid: 650bd649-8c2d-11e8-8267-42010a9a0113
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 100Gi
  gcePersistentDisk:
    fsType: ext4
    pdName: gke-cloud-native-81a17-pvc-6247502b-8c2d-11e8-8267-42010a9a0113
  persistentVolumeReclaimPolicy: Retain
  storageClassName: standard
status:
  phase: Released

在对 Volume 进行更改后不久,观察声明状态的终端应该显示 Bound

最后,将更改应用到 GitLab chart

切换到不同的卷

如果要切换到使用新卷,使用具有旧卷中相应数据副本的磁盘,则首先需要在 Kubernetes 中创建新的 Persistent Volume

要为您的磁盘创建一个 Persistent Volume,您需要为您的存储类型找到驱动程序特定文档。 您可能希望使用相同 Storage Class 的现有持久卷作为起点:

kubectl --namespace <namespace> get PersistentVolume <volume name> -o yaml > <volume name>.bak.yaml

在遵循驱动程序文档时,需要记住以下几点:

  • 您需要使用驱动程序来创建 Persistent Volume,而不是许多文档中显示的带有卷的 Pod 对象。
  • 不会想为新卷创建 PersistentVolumeClaim,我们将改为编辑现有声明。

驱动程序文档通常包括在 Pod 中使用驱动程序的示例,例如:

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    # This GCE PD must already exist.
    gcePersistentDisk:
      pdName: my-data-disk
      fsType: ext4

您真正想要的是创建一个 Persistent Volume,如下所示:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: test-volume
spec:
  capacity:
    storage: 400Gi
  accessModes:
  - ReadWriteOnce
  gcePersistentDisk:
    pdName: my-data-disk
    fsType: ext4

您通常使用 PersistentVolume 信息创建一个本地 yaml 文件,然后向 Kubernetes 发出 create 命令以创建使用该文件的对象。

kubectl --namespace <your namespace> create -f <local-pv-file>.yaml

创建卷后,您可以继续对 PersistentVolumeClaim 进行更改

对 PersistentVolumeClaim 进行更改

找到您要更改的 PersistentVolumeClaim

kubectl --namespace <namespace> get PersistentVolumeClaims -l release=<chart release name> -ojsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.app}{"\n"}{end}'
  • <namespace> 应该替换为您安装 GitLab chart 的命名空间。
  • <chart release name> 应替换为您用于安装 GitLab chart 的名称。

该命令将打印 PersistentVolumeClaim 名称的列表,后面是它们所针对的服务的名称。

然后将 claim 的副本保存到本地文件系统:

kubectl --namespace <namespace> get PersistentVolumeClaim <claim name> -o yaml > <claim name>.bak.yaml

输出示例:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  annotations:
    pv.kubernetes.io/bind-completed: "yes"
    pv.kubernetes.io/bound-by-controller: "yes"
    volume.beta.kubernetes.io/storage-provisioner: kubernetes.io/gce-pd
  creationTimestamp: 2018-07-20T14:58:38Z
  labels:
    app: gitaly
    release: review-update-app-h8qogp
  name: repo-data-review-update-app-h8qogp-gitaly-0
  namespace: helm-charts-win
  resourceVersion: "48362433"
  selfLink: /api/v1/namespaces/helm-charts-win/persistentvolumeclaims/repo-data-review-update-app-h8qogp-gitaly-0
  uid: 6247502b-8c2d-11e8-8267-42010a9a0113
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 50Gi
  storageClassName: standard
  volumeName: pvc-6247502b-8c2d-11e8-8267-42010a9a0113
status:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 50Gi
  phase: Bound

为新的 PVC 对象创建一个新的 YAML 文件。 让它使用相同的 metadata.namemetadata.labelsmetadata.namespacespec 字段。(应用您的更新),并删除其它设置:

示例:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  labels:
    app: gitaly
    release: review-update-app-h8qogp
  name: repo-data-review-update-app-h8qogp-gitaly-0
  namespace: helm-charts-win
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      # This is our updated field
      storage: 100Gi
  storageClassName: standard
  volumeName: pvc-6247502b-8c2d-11e8-8267-42010a9a0113

现在删除旧的 claim

kubectl --namespace <namespace> delete PersistentVolumeClaim <claim name>

您可能需要清除 finalizers,允许删除完成:

kubectl --namespace <namespace> patch PersistentVolumeClaim <claim name> -p '{"metadata":{"finalizers":null}}'

创建新的 claim:

kubectl --namespace <namespace> create PersistentVolumeClaim -f <new claim yaml file>

如果您绑定到之前绑定到声明的同一个 PersistentVolume,则继续更新要绑定到声明的卷

否则,如果您已将声明绑定到新卷,请转到将更改应用于 GitLab chart

将更改应用到 GitLab chart

PersistentVolumesPersistentVolumeClaims 进行更改后,您还需要发布 Helm 更新,并将更改应用于 chart 设置。

有关选项,请参阅安装存储指南

注意: 如果您对 Gitaly volume claim 进行了更改,则需要删除 Gitaly StatefulSet,然后才能发布 Helm 更新。这是因为 StatefulSet 的 Volume Template 是不可变的,无法更改。

您可以在不删除 Gitaly Pod 的情况下删除 StatefulSet:kubectl --namespace <namespace> delete --cascade=false StatefulSet <release-name>-gitaly Helm update 命令将重新创建 StatefulSet,它将采用和更新 Gitaly pod。

更新 chart,并包含更新的配置:

示例:

helm upgrade --install review-update-app-h8qogp gitlab-jh/gitlab \
  --set gitlab.gitaly.persistence.size=100Gi \
  <your other config settings>