EKSにデプロイしたGitLabのバージョンを12から13にアップデートする

# はじめに
[GitLab 13.0.0](https://about.gitlab.com/releases/2020/05/22/gitlab-13-0-released/)が2020/05/22にリリースされました。
そこで今回はEKSにHelmでデプロイしたGitLab 12.3.5を13.0.0にバージョンアップデートする方法を説明します。

まずはGitLab Helm Chartのアプリバージョンとのマッピングを見てみましょう。
詳細は[こちらのページ](https://docs.gitlab.com/charts/installation/version_mappings.html)にあります。

| Chart Version       |       GitLab Version |
|:-----------------|:------------------|
| 2.3.7             |              12.3.5 |
| 2.6.9 (2系の最新)           |            12.6.8 |
|      3.0.0       |              12.7.0 |
| 3.3.5 (3系の最新)              |                12.10.6 |
|4.0.0|13.0.0|

表から分かるように**アプリのメジャーバージョンが変わる前にChartのメジャーバージョンが変わっている**ので少し変則的にバージョンを上げていく必要があります。
Chartのメジャーアップデートを2回行うため、**2.3.7 → 2.6.9 → 3.0.0 → 3.3.5 → 4.0.0**と段階的にバージョンを上げていきます。

# 環境情報
macOS Mojabe 10.14.6
Helm 3.2.1
EKS 1.13
RDS PostgreSQL 9.6.15
ALB Ingress Controller Helm Chart 0.1.11
kube2iam Helm Chart 2.0.1
GitLab Helm Chart 2.3.7, 2.6.9, 3.0.0, 3.3.5, 4.0.0

# 前準備
ALBを使用するために`ALB Ingress Controller`、IAM RoleをPodに付与するために`kube2iam`をデプロイしておきます。

GitLabがS3を使うためにはS3バケット情報をSecretとして作る必要があります。
[こちらの記事](https://qiita.com/samskeyti/items/17d9be432eda750559ad)に詳しく書いてあるので参考にしてください。
今回は`gitlab-rails-storage`、`storage-config`、`registry-storage`の名前で3つのSecretを作成します。

RDSへのアクセス情報のSecretは次のコマンドで作成します。namespaceは`update-test`にします。

```console
$ kubectl create secret generic gitlab-postgresql \
   --from-literal password=<PASSWORD> \
   --namespace update-test 
```

`my-values.yaml`を作成してHelmコマンドでGitLabをデプロイします。
`s3-full-access-role`はPodがS3にアクセスするためのものです。

```yaml:my-values.yaml
global:
  edition: ce
  hosts:
    https: false
    gitlab:
      name: 1ec885a2-updatetest-albing-6622-1089076412.ap-northeast-1.elb.amazonaws.com
      https: false
  ingress:
    configureCertmanager: false
    enabled: false
    tls:
      enabled: false
  psql:
    password: 
      secret: gitlab-postgresql
      key: password
    host: update-test-gitlab.crdjlj5j7v3p.ap-northeast-1.rds.amazonaws.com
    port: 5432
    username: gitlab
    database: gitlabhq_production
  minio:
    enabled: false
  appConfig:
    lfs:
      bucket: update-test-gitlab-lfs
      connection:
        secret: gitlab-rails-storage
        key: connection
    artifacts:
      bucket: update-test-gitlab-artifacts
      connection:
        secret: gitlab-rails-storage
        key: connection
    uploads:
      bucket: update-test-gitlab-uploads
      connection:
        secret: gitlab-rails-storage
        key: connection
    packages:
      bucket: update-test-gitlab-packages
      connection:
        secret: gitlab-rails-storage
        key: connection
    externalDiffs:
      enabled: true
      bucket: update-test-gitlab-mr-diffs
      connection:
        secret: gitlab-rails-storage
        key: connection
    pseudonymizer:
      configMap:
      bucket: update-test-gitlab-pseudo
      connection:
        secret: gitlab-rails-storage
        key: connection
    backups:
      bucket: update-test-gitlab-backups
      tmpBucket: update-test-gitlab-tmp
  time_zone: Tokyo
upgradeCheck:
  enabled: false
certmanager:
  install: false
nginx-ingress:
  enabled: false
prometheus:
  install: false
postgresql:
  install: false
gitlab-runner:
  install: false
registry:
  minReplicas: 1
  storage:
    secret: registry-storage
    key: config
  annotations:
    iam.amazonaws.com/role: s3-full-access-role
  ingress:
    enabled: false
gitlab:
  gitlab-shell:
    enabled: false
  gitlab-exporter:
    enabled: false
  unicorn:
    annotations:
      iam.amazonaws.com/role: s3-full-access-role
    ingress:
      enabled: false
    service:
      type: NodePort
  sidekiq:
    annotations:
      iam.amazonaws.com/role: s3-full-access-role
  task-runner:
    annotations:
      iam.amazonaws.com/role: s3-full-access-role
    backups:
      objectStorage:
        config:
          secret: storage-config
          key: config
```

```console
$ helm install \
   --namespace update-test \
   --values my-values.yaml \
   --version 2.3.7 \
   update-test-gitlab \
   gitlab/gitlab 
```

ALBはIngressをデプロイすることで自動で作成されます。
**GitLab Helm Chartに同梱されているIngressはNGINX Ingress Controller用**のため、template内のIngressのannotationsを編集することになります。

Helm Chartの**templateはできる限り編集しないほうが良い**です。
`values.yaml`のようにバージョン跨ぎで再利用できないためバージョンアップのたびに作業が増えるからです。

そこで今回は自分でIngressを作成してデプロイします。
`spec.rules[].host`はALBのDNS名を入れます。

```yaml:alb-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    kubernetes.io/ingress.class: alb
  name: alb-ingress
  namespace: update-test
spec:
  rules:
  - host: 1ec885a2-updatetest-albing-6622-1089076412.ap-northeast-1.elb.amazonaws.com
    http:
      paths:
      - backend:
          serviceName: update-test-gitlab-unicorn
          servicePort: 8181
      - backend:
          serviceName: update-test-gitlab-unicorn
          servicePort: 8080
        path: /admin/sidekiq
```

```console
$ kubectl apply -f alb-ingress.yaml
```

以上で検証環境構築は完了です。

# バージョンアップ手順

## 2.3.7 → 2.6.9

GitLab Helm Chart 2系の最新である2.6.9にアップデートします。
`my-values.yaml`に変更点はありません。

```console
$ helm upgrade \
   --namespace update-test \
   --values my-values.yaml \
   --version 2.6.9 \
   update-test-gitlab \
   gitlab/gitlab 
```

## 2.6.9 → 3.0.0

GitLab Helm Chart 3.0.0にアップデートします。
ここでも`my-values.yaml`に変更点はありません。

```console
$ helm upgrade \
   --namespace update-test \
   --values my-values.yaml \
   --version 3.0.0 \
   update-test-gitlab \
   gitlab/gitlab
```

## 3.0.0 → 3.3.5

GitLab Helm Chart 3系の最新である3.3.5にアップデートします。
ここでも`my-values.yaml`に変更点はありません。

```console
$ helm upgrade \
   --namespace update-test \
   --values my-values.yaml \
   --version 3.3.5 \
   update-test-gitlab \
   gitlab/gitlab
```

## 3.3.5 → 4.0.0

GitLab Helm Chart 4.0.0からwebサーバに**unicornだけでなくpumaを使用できる**ようになっています。(デフォルトではpumaを使用)
それに伴い、今までHelm Chart内のコードは**unicornがwebserviceという名前に変わっています**。

`my-values.yaml`の中身を変更してからアップデートします。

```console
$ sed -i -e "s/unicorn/webservice/g" my-values.yaml
```

```console
$ helm upgrade \
   --namespace update-test \
   --values my-values.yaml \
   --version 4.0.0 \
   update-test-gitlab \
   gitlab/gitlab
```

アクセスしてみると502画面になってしまいます。

<img width="1440" alt="スクリーンショット 2020-05-24 23.06.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307853/af2587d7-4412-0edc-45eb-50f0f1ad0387.png">

アクセスできない原因はIngressです。Helm Chartのtemplateに含めなかったことの弊害がここで現れました。
宛先のService名を変更して再デプロイします。

```console
$ sed -i -e "s/unicorn/webservice/g" alb-ingress.yaml
```
```console
$ kubectl apply -f alb-ingress.yaml
```

アクセスできるようになり、アプリバージョンも13.0.0になっています。
ただ、PostgreSQL 9.6が古いと怒られています。

<img width="1440" alt="スクリーンショット 2020-05-24 23.08.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307853/33ac6a79-f552-4200-88d1-532e803c6fa0.png">

PostgreSQLコンテナを使っていると色々と面倒な作業が生じますが、今回はRDSを使用しているのでAWSコンソールからさっとPostgreSQL 11にアップデートします。

<img width="788" alt="スクリーンショット 2020-05-24 23.11.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307853/72dc7a0e-c653-4cf7-523a-fc7256157313.png">

PostgreSQLアップデートは15分ほどで終わりました。
次にDBマイグレーション処理を行うために`helm upgrade`します。

```console
$ helm upgrade \
   --namespace update-test \
   --values my-values.yaml \
   --version 4.0.0 \
   update-test-gitlab \
   gitlab/gitlab
```

adminページに警告が現れることがなくなりました。
<img width="1440" alt="スクリーンショット 2020-05-24 23.39.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307853/118550bc-a5bf-8e95-0887-9696b50e8856.png">

バージョンアップ前のコミットなどを見てデータの整合性を確認しましょう。
問題はなさそうです。
<img width="1440" alt="スクリーンショット 2020-05-24 23.45.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307853/4635fc19-6175-4bc1-5915-b8b13b39e4a0.png">


# おわりに
EKSにデプロイしたGitLabを12から13にメジャーアップデートする方法を説明しました。
今回はHelm 3.2.1を使用しましたが、Helm 2.14.3でも同様に成功することを確認済みです。
ですが今後のことを考えるとHelm 3の方が良いと思います。