はじめに
GitLabではマージリクエストのdiffやGitLab CIジョブのログなどのデータをS3といったオブジェクトストレージに保存することができます。
ファイルサイズが大きい際レスポンスが遅い問題に直面したのでS3からMinioへの移行を検証しました。MinioにはEFSを使用して可用性を確保しています。
環境
EKS 1.16
Helm 3.4.0
Helmfile 0.122.0
GitLab Helm Chart 4.8.4
kube2iam Helm Chart 2.5.0
ALB Ingress Controller Helm Chart 0.1.11
NGINX Ingress Controller Helm Chart 1.39.0
手順
EKSクラスタやS3バケットは構築済みであることを前提とします。
以下の流れで実施します。
- S3使用のGitLabでバックアップ
- Minio用意
- Minio使用のGitLabでリストア
0. 前準備
Kubernetesリソースをデプロイしていきます。
まずはGitLabがS3を使用できるようにSecretをデプロイします。
provider: AWS
use_iam_profile: true
region: ap-northeast-1
$ kubectl create secret generic gitlab-rails-storage \
--from-file=connection=rails-storage.yaml
[default]
bucket_location = ap-northeast-1
$ kubectl create secret generic storage-config \
--from-file=config=storage.config
GitLab Helm Chartに同梱されているNGINX Ingress Controllerは使用しないため、templateのIngressを編集する必要があります。
metadata:
annotations:
- kubernetes.io/ingress.class: "{{ template "gitlab.ingressclass" $ }}"
Helmfileでkube2iam、ALB Ingress Controller、NGINX Ingress Controller、GitLabをデプロイします。
<ALB_INGRESS_CONTROLLER_IAM_ROLE_ARN>
、<S3_IAM_ROLE_ARN>
にはkube2iamで使用可能なIAM RoleのARNに置き換えてください。
repositories:
- name: stable
url: https://charts.helm.sh/stable
- name: incubator
url: https://charts.helm.sh/incubator
releases:
- name: kube2iam
namespace: kube-system
chart: stable/kube2iam
version: 2.5.0
values:
- host:
iptables: true
interface: "eni+"
extraArgs:
auto-discover-base-arn: ""
rbac:
create: true
- name: aws-alb-ingress-controller
namespace: kube-system
chart: incubator/aws-alb-ingress-controller
version: 0.1.11
values:
- clusterName: <EKS_CLUSTER_NAME>
autoDiscoverAwsRegion: true
autoDiscoverAwsVpcID: true
podAnnotations:
iam.amazonaws.com/role: <ALB_INGRESS_CONTROLLER_IAM_ROLE_ARN>
- name: nginx-ingress
namespace: kube-system
chart: stable/nginx-ingress
version: 1.39.0
values:
- controller:
service:
type: NodePort
- name: test-gitlab
namespace: default
chart: ./gitlab
values:
- global:
edition: ce
hosts:
https: false
gitlab:
name: gitlab.sample.com
https: false
minio:
enabled: false
ingress:
configureCertmanager: false
enabled: false
tls:
enabled: false
appConfig:
lfs:
bucket: test-gitlab-lfs
connection:
secret: gitlab-rails-storage
key: connection
artifacts:
bucket: test-gitlab-artifacts
connection:
secret: gitlab-rails-storage
key: connection
uploads:
bucket: test-gitlab-uploads
connection:
secret: gitlab-rails-storage
key: connection
packages:
bucket: test-gitlab-packages
connection:
secret: gitlab-rails-storage
key: connection
externalDiffs:
enabled: true
bucket: test-gitlab-mr-diffs
connection:
secret: gitlab-rails-storage
key: connection
pseudonymizer:
configMap:
bucket: test-gitlab-pseudo
connection:
secret: gitlab-rails-storage
key: connection
backups:
bucket: test-gitlab-backups
tmpBucket: test-gitlab-tmp
upgradeCheck:
enabled: false
certmanager:
install: false
nginx-ingress:
enabled: false
prometheus:
install: false
registry:
enabled: false
gitlab-runner:
install: false
gitlab:
gitlab-exporter:
enabled: false
gitlab-shell:
enabled: false
sidekiq:
annotations:
iam.amazonaws.com/role: <S3_IAM_ROLE_ARN>
registry:
enabled: false
task-runner:
enabled: true
annotations:
iam.amazonaws.com/role: <S3_IAM_ROLE_ARN>
registry:
enabled: false
backups:
objectStorage:
config:
secret: storage-config
key: config
webservice:
annotations:
iam.amazonaws.com/role: <S3_IAM_ROLE_ARN>
registry:
enabled: false
ingress:
enabled: true
minReplicas: 1
$ helmfile apply -f helmfile.yaml
ALB→NGINX Ingress Controllerへのルーティング設定のためのIngressをデプロイします。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
kubernetes.io/ingress.class: alb
name: alb-ingress
namespace: kube-system
spec:
rules:
- http:
paths:
- backend:
serviceName: test-gitlab-nginx-ingress-controller
servicePort: 80
$ kubectl apply -f alb-ingress.yaml
1. バックアップ
Task Runner Podからデータのバックアップを取ります。データはS3バケットに保存されます。
$ kubectl exec <TASK_RUNNER_POD> -it backup-utility
2. Minioの用意
EFSアクセスポイントの設定値は下表になります。
Key | Value |
---|---|
名前 | minio |
パス | /minio |
POSIXユーザー | 1000:1000 |
作成情報 | 1000:1000(0777) |
EKSでEFSを使用できるようEFS CSIドライバーをデプロイします。
$ kubectl apply -k "github.com/kubernetes-sigs/aws-efs-csi-driver/deploy/kubernetes/overlays/stable/ecr/?ref=release-1.0"
StorageClassも新規作成が必要になります。
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
$ kubectl apply -f efs-sc.yaml
MinioのPersistentVolumeでEFSが使用できるようtemplateにファイルを新規追加します。
+ {{- if and .Values.global.minio.enabled .Values.persistence.enabled }}
+ kind: PersistentVolume
+ apiVersion: v1
+ metadata:
+ name: {{ template "minio.fullname" . }}
+ namespace: {{ $.Release.Namespace }}
+ labels:
+ {{ include "gitlab.standardLabels" . | indent 4 }}
+ spec:
+ volumeMode: Filesystem
+ persistentVolumeReclaimPolicy: Retain
+ accessModes:
+ - {{ .Values.persistence.accessMode | quote }}
+ capacity:
+ storage: {{ .Values.persistence.size | quote }}
+ {{- if .Values.persistence.csi }}
+ csi:
+ {{ toYaml .Values.persistence.csi | indent 4 }}
+ {{- end -}}
+ {{- if .Values.persistence.storageClass }}
+ {{- if (eq "-" .Values.persistence.storageClass) }}
+ storageClassName: ""
+ {{- else }}
+ storageClassName: "{{ .Values.persistence.storageClass }}"
+ {{- end -}}
+ {{- end }}
+ {{- end }}
webservice同様、GitLab同梱のNGINX Ingress Controllerを使用しないため修正します。
metadata:
annotations:
- kubernetes.io/ingress.class: "{{ template "minio.ingressclass" . }}"
Minioを使用できるように、HelmfileのマニフェストファイルでGitLabのvaluesを修正します。
<EFS_FILESYSTEM_ID>
、<EFS_ACCESSPOINT_ID>
にはそれぞれEFSファイルシステムのID、EFSアクセスポイントのIDに置き換えてください。
repositories:
- name: stable
url: https://charts.helm.sh/stable
- name: incubator
url: https://charts.helm.sh/incubator
releases:
- name: kube2iam
namespace: kube-system
chart: stable/kube2iam
version: 2.5.0
values:
- host:
iptables: true
interface: "eni+"
extraArgs:
auto-discover-base-arn: ""
rbac:
create: true
- name: aws-alb-ingress-controller
namespace: kube-system
chart: incubator/aws-alb-ingress-controller
version: 0.1.11
values:
- clusterName: <EKS_CLUSTER_NAME>
autoDiscoverAwsRegion: true
autoDiscoverAwsVpcID: true
podAnnotations:
iam.amazonaws.com/role: <ALB_INGRESS_CONTROLLER_IAM_ROLE_ARN>
- name: nginx-ingress
namespace: kube-system
chart: stable/nginx-ingress
version: 1.39.0
values:
- controller:
service:
type: NodePort
- name: test-gitlab
namespace: default
chart: ./gitlab
values:
- global:
edition: ce
hosts:
https: false
gitlab:
name: gitlab.sample.com
https: false
+ minio:
+ name: minio.sample.com
+ https: false
minio:
- enabled: false
+ enabled: true
ingress:
configureCertmanager: false
enabled: false
tls:
enabled: false
appConfig:
- lfs:
- bucket: test-gitlab-lfs
- connection:
- secret: gitlab-rails-storage
- key: connection
- artifacts:
- bucket: test-gitlab-artifacts
- connection:
- secret: gitlab-rails-storage
- key: connection
- uploads:
- bucket: test-gitlab-uploads
- connection:
- secret: gitlab-rails-storage
- key: connection
- packages:
- bucket: test-gitlab-packages
- connection:
- secret: gitlab-rails-storage
- key: connection
externalDiffs:
enabled: true
- bucket: test-gitlab-mr-diffs
- connection:
- secret: gitlab-rails-storage
- key: connection
- pseudonymizer:
- configMap:
- bucket: test-gitlab-pseudo
- connection:
- secret: gitlab-rails-storage
- key: connection
- backups:
- bucket: test-gitlab-backups
- tmpBucket: test-gitlab-tmp
upgradeCheck:
enabled: false
certmanager:
install: false
nginx-ingress:
enabled: false
prometheus:
install: false
registry:
enabled: false
gitlab-runner:
install: false
gitlab:
gitlab-exporter:
enabled: false
gitlab-shell:
enabled: false
sidekiq:
- annotations:
- iam.amazonaws.com/role: <S3_IAM_ROLE_ARN>
registry:
enabled: false
task-runner:
enabled: true
- annotations:
- iam.amazonaws.com/role: <S3_IAM_ROLE_ARN>
registry:
enabled: false
- backups:
- objectStorage:
- config:
- secret: storage-config
- key: config
webservice:
- annotations:
- iam.amazonaws.com/role: <S3_IAM_ROLE_ARN>
registry:
enabled: false
ingress:
enabled: true
minReplicas: 1
+ minio:
+ ingress:
+ enabled: true
+ persistence:
+ storageClass: efs-sc
+ accessMode: ReadWriteMany
+ csi:
+ driver: efs.csi.aws.com
+ volumeHandle: <EFS_FILESYSTEM_ID>::<EFS_ACCESSPOINT_ID>
$ helmfile apply -f helmfile.yaml
3. リストア
Minio Podが立ち上がったら、Task Runner Podでリストア実行します。
バックアップファイルはS3バケット上に存在しているので以下のコマンドで事前に取得する必要があります。
$ aws s3 cp s3://test-gitlab-backups/<BACKUP_FILE_TAR>
$ kubectl cp <BACKUP_FILE_TAR> <TASK_RUNNER_POD>:/tmp
$ kubectl exec <TASK_RUNNER_POD> -it -- backup-utility --restore -f file:///tmp/<BACKUP_FILE_TAR>
まとめ
GitLabで使用するオブジェクトストレージをS3からMinioに変更する手順を説明しました。
MinioでEFSを使用するための設定もしていますが、それほど複雑ではないことが分かると思います。
S3と比べてレスポンス速度は変わりますが、可用性の観点では劣るので要件に応じて方式を考える必要があります。