7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

EC2 インスタンスで運用している GitLab を、 GKE に移行してみた。(Kubernetes Engine + Cloud SQL + Cloud Filestore)

Last updated at Posted at 2018-08-27

はじめに

EC2 インスタンスで運用中の GitLab(Omnibus パッケージ)を GKE 上に移行させました。
本投稿はその際メモしていた移行手順に、イメージ図や簡単なコメントを追記したものとなります。

また移行に際し、次の GitHub プロジェクトを参考にさせてもらいました。
https://github.com/sameersbn/docker-gitlab



ちなみにプロジェクト主である sameersbn さんですが、ご尊顔も公開されていました。

・・・この方は、いったい何者なんでしょ?

前提条件

  • GKE に リージョン クラスタ を作成済み
  • AWS VPC と GCP VPC 間は VPN で接続済み(以前の記事参照
  • 作業用のローカルマシン(CentOS7)は Docker(docker-ce-18.03.1) が稼働済み
  • 作業用のローカルマシンには、Google Cloud SDK(v212.0.0)、kubectl(v1.11.2) をインストール、初期設定済みであり、GKE クラスタに接続済み
  • 移行元の GitLab バージョンは、移行先のバージョン(v11.1.4)と同一になるよう、移行作業前にアップグレード
  • 下表の情報を想定して環境を構築
項目 備考
プロジェクトID my-project
リージョン asia-northeast1 東京リージョン
VPC aws-internal-connect AWS VPC間でVPN接続済み
Cloud SQL インスタンスID gitlab-pgsql
Cloud SQL データベース名 gitlabhq_production
Cloud SQL データベースバージョン POSTGRES_9_6
Cloud SQL ユーザーID gitlab
Cloud SQL Proxy デプロイ名 cloudsqlproxy
Cloud SQL Proxy サービス名 sqlproxy-gitlab
Cloud Filestore インスタンスID nfs-server
Cloud Filestore リージョン asia-east1 東京リージョンでは未提供の為
Cloud Filestore 共有名 NFSvol
GitLab デプロイ名、サービス名 gitlab
Redis デプロイ名、サービス名 redis
Active Directory IPアドレス 10.0.1.123 AWSで稼働中のAD

実装イメージ

topology.png

移行元 GitLab のバージョンアップ

EC2上で稼働中のGitLab(Omnibusパッケージ)のバージョンを、この辺りの情報を参考にアップグレードする。
※9.5 ⇒ 11.1.4(2018.08現在の最新版)

Cloud SQL に PostgreSQL インスタンス作成

GitLab が利用するデータベースには、Cloud SQL (データベースエンジン=PostgreSQL 9.6)を利用する。

スクリプト作成

create-cloudsql-pgsql.sh
#!/bin/bash

INSTANCE_ID=gitlab-pgsql        #インスタンスID
REGION=asia-northeast1          #インスタンスを作成するリージョン
DATABASE_VERSION=POSTGRES_9_6   #データベースバージョン
NUMBER_CPUS=1                   #割当てvCPU数
MEMORY_SIZE=3840MiB             #割当てメモリ容量
STORAGE_TYPE=SSD                #ストレージの種類(HDD|SSD)
STORAGE_SIZE=10GB               #ストレージの容量(GB単位)

gcloud beta sql instances create $INSTANCE_ID \
    --region=$REGION \
    --database-version=$DATABASE_VERSION \
    --cpu=$NUMBER_CPUS \
    --memory=$MEMORY_SIZE \
    --storage-type=$STORAGE_TYPE \
    --storage-size=$STORAGE_SIZE \
    --storage-auto-increase

スクリプト実行、確認

$ sh create-cloudsql-pgsql.sh

$ gcloud beta sql instances list
NAME          DATABASE_VERSION  LOCATION           TIER              ADDRESS         STATUS
gitlab-pgsql  POSTGRES_9_6      asia-northeast1-b  db-custom-1-3840  35.XXX.XXX.XXX  RUNNABLE

デフォルトユーザー(postgres)にパスワード設定

インスタンスを作成すると、postgres ユーザーがデフォルトで登録されるため、そのパスワードを設定する。

スクリプト作成

set-passwd.sh
#!/bin/bash

INSTANCE_ID=gitlab-pgsql      #インスタンスID
PASSWORD=<PASSWORD>           #'postgres' ユーザーのパスワード


gcloud sql users set-password postgres no-host \
    --instance=$INSTANCE_ID \
    --password=$PASSWORD

スクリプト実行

$ sh set-passwd.sh

インスタンスにデータベース作成

GitLab が利用するデータベース gitlabhq_production を作成する。

スクリプト作成

add_sql_database.sh
#!/bin/bash

DATABASE_NAME=gitlabhq_production       #データベース名
INSTANCE_ID=gitlab-pgsql                #インスタンスID

gcloud sql databases create $DATABASE_NAME \
    --instance=$INSTANCE_ID

スクリプト実行、確認

$ sh add_sql_database.sh

$ gcloud sql databases list --instance=gitlab-pgsql
NAME                 CHARSET  COLLATION
postgres             UTF8     en_US.UTF8
gitlabhq_production  UTF8     en_US.UTF8

ユーザー作成

データベース接続ユーザー gitlab を作成する。

ちなみにこの gitlab ユーザーは、管理者権限を持つユーザー(cloudsqlsuperuser)として作成される。

スクリプト作成

add_sql_user.sh
#!/bin/bash

USER_NAME=gitlab              #ユーザーID
HOST=%                        #アクセス許可ホスト
INSTANCE_ID=gitlab-pgsql      #インスタンスID
PASSWORD=<PASSWORD>           #ユーザーパスワード

gcloud sql users create $USER_NAME \
    --host=$HOST \
    --instance=$INSTANCE_ID \
    --password=$PASSWORD

スクリプト実行、確認

$ sh add_sql_user.sh

$ gcloud sql users list --instance=gitlab-pgsql
NAME      HOST
gitlab
postgres

Cloud SQL Proxy の Pod、Service の作成

Cloud SQL のデータベースを Pod から直接接続して利用することも可能だが、接続管理(ホワイトリスト、SSL等)が煩雑になる。
Cloud SQL Proxy を利用することで、安全、簡単に接続できるようになる。

尚、独立した Pod として実装する方法は、ここの情報を参考にした。

サービスアカウントの作成

Cloud SQL クライアントの役割を持つサービスアカントを作成し、サービスアカウントキーをローカルにダウンロードする。

スクリプト作成

create-service-account.sh
#!/bin/bash

KEYFILE_NAME=$HOME/credentials.json #サービスアカウントの秘密鍵ファイルパス
PROJECT_ID=my-project               #プロジェクトID
ACCOUNT_NAME=cloudsql               #サービスアカウント名

#サービスアカウントの作成
gcloud iam service-accounts create $ACCOUNT_NAME \
    --display-name="$ACCOUNT_NAME"

#サービスアカウントへ役割(Cloud SQL クライアント)付与
gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member="serviceAccount:$ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
    --role="roles/cloudsql.client"

#サービスアカウントキーの作成
gcloud iam service-accounts keys create $KEYFILE_NAME \
    --iam-account $ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com

スクリプト実行

$ sh create-service-account.sh

秘密鍵を GKE に登録

ダウンロードしたサービスアカウントキー(秘密鍵)を GKE の Secret に登録する。
GKE に登録することで、Pod(Cloud SQL Proxy)から参照できるようになる。

スクリプト作成

create-secret.sh
#!/bin/bash

KEYFILE_NAME=$HOME/credentials.json     #秘密鍵ファイルパス

kubectl create secret generic service-account-token \
    --from-file=credentials.json=$KEYFILE_NAME

スクリプト実行、確認

$ sh create-secret.sh

$ kubectl get secret
NAME                    TYPE      DATA      AGE
service-account-token   Opaque    1         4m

Cloud SQL Proxy のデプロイ

今回 Cloud SQL Proxy は独立した Pod として運用するため、デプロイする必要がある。

デプロイ定義ファイル作成

deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: cloudsqlproxy
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: cloudsqlproxy
    spec:
      containers:
       # Make sure to specify image tag in production
       # Check out the newest version in release page
       # https://github.com/GoogleCloudPlatform/cloudsql-proxy/releases
      - image: b.gcr.io/cloudsql-docker/gce-proxy:latest
       # 'Always' if imageTag is 'latest', else set to 'IfNotPresent'
        imagePullPolicy: Always
        name: cloudsqlproxy
        command:
        - /cloud_sql_proxy
        - -dir=/cloudsql
        - -instances=my-project:asia-northeast1:gitlab-pgsql=tcp:0.0.0.0:5432,my-project:asia-northeast1:app-mysql=tcp:0.0.0.0:3306
        - -credential_file=/credentials/credentials.json
        ports:
        - name: port-app-mysql
          containerPort: 3306
        - name: port-gitlab-pgsql
          containerPort: 5432
        volumeMounts:
        - mountPath: /cloudsql
          name: cloudsql
        - mountPath: /credentials
          name: service-account-token
      volumes:
      - name: cloudsql
        emptyDir:
      - name: service-account-token
        secret:
          secretName: service-account-token

volumeMounts には秘密鍵をマウントする定義があり、command で Cloud SQL のインスタンスへの接続が定義されていることが判る。

尚、上記 YAML ファイルでは gitlab-pgsql インスタンス以外に、今回は利用しない app-mysql インスタンスへの接続も定義している。
このように Cloud SQL Proxy は、Cloud SQL の複数インスタンスに対しプロキシすることもできる。

また必要が無ければ、app-mysql の接続に関する定義は削除しても構わない。

デプロイ実行、確認

$ kubectl create -f deployment.sh

$ kubectl get pod
NAME                             READY     STATUS    RESTARTS   AGE
cloudsqlproxy-XXXXXXXXXX-XXXXX   1/1       Running   0          4m

Cloud SQL Proxy の Service 作成

サービス定義ファイル作成

今回の定義情報には、前述のプロキシ定義にある app-mysql への定義も記載している。
参考程度に記載しているだけなので、必要が無ければ削除しても構わない。

service.yaml
apiVersion: v1
kind: Service
metadata:
  name: sqlproxy-app
spec:
  ports:
  - port: 3306
    targetPort: port-app-mysql
  selector:
    app: cloudsqlproxy
---
apiVersion: v1
kind: Service
metadata:
  name: sqlproxy-gitlab
spec:
  ports:
  - port: 5432
    targetPort: port-gitlab-pgsql
  selector:
    app: cloudsqlproxy

サービス作成、確認

$ kubectl apply -f service.yaml

$ kubectl get svc
NAME                TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                     AGE
sqlproxy-app        ClusterIP      10.1.163.153   <none>        3306/TCP                    4m
sqlproxy-gitlab     ClusterIP      10.1.160.34    <none>        5432/TCP                    4m

永続ディスクの準備

GKE の ゾーン クラスタ は単一のゾーン内にノードが作成される為、永続ディスクに GCE ディスクを用いても特に問題は起きない。(ネット上の情報は、この方法で解説されている場合が多い。)

今回実装に用いるリージョン クラスタでは、ノードがリージョン内の複数のゾーン(例えば asia-northeast1-aasia-northeast1-basia-northeast1-c)に作成されるため、ゾーンを跨いでマウントすることが出来ない GCE ディスクを利用すると問題が生じてしまう。

そこで今回の永続ディスクには Cloud Filestore を利用することにする。

尚、投稿時点で東京リージョンでは提供されていないため、距離的に近い台湾リージョン(asia-east1)に Filestore インスタンスを作成する。

Cloud Filestore インスタンス作成

スクリプト作成

create-instance.sh
#!/bin/bash

INSTANCE_ID=nfs-server            #インスタンスID
PROJECT_ID=my-project             #プロジェクトID
LOCATION=asia-east1-a             #ロケーション(≒ゾーン)
TIER=STANDARD                     #サービス層(種別) (STANDARD|PREMIUM)
SHARE_NAME=NFSvol                 #共有名
CAPACITY=1TB                      #割当て容量
VPC=aws-internal-connect          #VPC

gcloud beta filestore instances create $INSTANCE_ID \
    --project=$PROJECT_ID \
    --location=$LOCATION \
    --tier=$TIER \
    --file-share=name="$SHARE_NAME",capacity=$CAPACITY \
    --network=name="$VPC"

スクリプト実行、確認

$ sh create-instance.sh

$ gcloud beta filestore instances list
INSTANCE_NAME  LOCATION      TIER      CAPACITY_GB  FILE_SHARE_NAME  IP_ADDRESS     STATE  CREATE_TIME
nfs-server     asia-east1-a  STANDARD  1024         NFSvol           10.32.XXX.XXX  READY  2018-08-21T02:56:54

インスタンス内にディレクトリ作成

GCP上の適当なVMインスタンスへログイン後、共有ボリュームをマウントし、予め gitlabredis ディレクトリを作成しておく。
ここで作成したディレクトリを、Pod の永続ディスクとして利用する。

#共有ボリュームマウント
$ sudo mount 10.32.XXX.XXX:/NFSvol /mnt

#gitlab, redis ディレクトリ作成
$ sudo mkdir /mnt/gitlab /mnt/redis

#ディレクトリ確認
$ ls /mnt
gitlab  lost+found  redis

#共有ボリュームのアンマウント
$ sudo umount /mnt

Persistent Volume 作成

共有ボリュームに、2つの Persistent Volume(PV)を作成する。
(GitLabが利用する PV と、Redis が利用する PV)

PV定義ファイル作成

pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-gitlab
  labels:
    app: pv-gitlab
  annotations:
    volume.beta.kubernetes.io/storage-class: "nfs"
spec:
  capacity:
    storage: 30Gi
  accessModes:
  - ReadWriteMany
  nfs:
    path: /NFSvol/gitlab
    server: 10.32.XXX.XXX
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-redis
  labels:
    app: pv-redis
  annotations:
    volume.beta.kubernetes.io/storage-class: "nfs"
spec:
  capacity:
    storage: 30Gi
  accessModes:
  - ReadWriteMany
  nfs:
    path: /NFSvol/redis
    server: 10.32.XXX.XXX

PV作成、確認

$ kubectl create -f pv.yaml

$ kubectl get pv
NAME        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                STORAGECLASS   REASON    AGE
pv-gitlab   30Gi       RWX            Retain           Bound     default/pvc-gitlab   nfs                      3m
pv-redis    30Gi       RWX            Retain           Bound     default/pvc-redis    nfs                      3m

Persistent Volume Claim の作成

Pod のPV要求(Persistent Volume Claim:PVC)を2つ作成する。
selectorを定義し、要求するPVを限定している。

PVC定義ファイル作成

pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-gitlab
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: "nfs"
  resources:
    requests:
      storage: 30Gi
  selector:
    matchLabels:
      app: pv-gitlab
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-redis
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: "nfs"
  resources:
    requests:
      storage: 30Gi
  selector:
    matchLabels:
      app: pv-redis

PVC 作成、確認

$ kubectl create -f pvc.yaml

$ kubectl get pvc
NAME         STATUS    VOLUME      CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-gitlab   Bound     pv-gitlab   30Gi       RWX            nfs            3m
pvc-redis    Bound     pv-redis    30Gi       RWX            nfs            3m

Docker イメージのアップロード

Redis、GitLab の Docker イメージをローカルにダウンロード、タグ付けし、Container Registry にアップロードする。

Redis イメージのアップロード

Docker イメージ の Pull

$ docker pull sameersbn/redis:4.0.9-1

イメージにタグ付け

$ docker tag sameersbn/redis:4.0.9-1 asia.gcr.io/my-project/redis:4.0.9-1

イメージのアップロード、確認

$ gcloud docker -- push asia.gcr.io/my-project/redis:4.0.9-1

$ gcloud container images list-tags asia.gcr.io/my-project/redis
DIGEST        TAGS     TIMESTAMP
94872deed848  4.0.9-1  2018-07-28T23:45:25

GitLab イメージのアップロード

Docker イメージ の Pull

$ docker pull sameersbn/gitlab:11.1.4

イメージにタグ付け

$ docker tag sameersbn/gitlab:11.1.4 asia.gcr.io/my-project/gitlab:11.1.4

イメージのアップロード、確認

$ gcloud docker -- push asia.gcr.io/my-project/gitlab:11.1.4

$ gcloud container images list-tags asia.gcr.io/my-project/gitlab
DIGEST        TAGS    TIMESTAMP
9886c6781e11  11.1.4  2018-08-02T07:03:26

Redis の準備

Redis のデプロイ

デプロイ定義ファイル作成

前述で作成した PVC pvc-redisvolumes に定義し、volumeMounts でマウント情報を定義する。

deploy-redis.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  generation: 1
  labels:
    run: redis
  name: redis
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      run: redis
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        run: redis
    spec:
      containers:
      - image: asia.gcr.io/my-project/redis:4.0.9-1
        imagePullPolicy: Always
        name: redis
        env:
        - name: TZ
          value: "Asia/Tokyo"
        ports:
        - containerPort: 6379
          protocol: TCP
        volumeMounts:
        - name: redis-data
          mountPath: "/var/lib/redis"
        resources:
          requests:
            cpu: 100m
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      volumes:
        - name: redis-data
          persistentVolumeClaim:
            claimName: "pvc-redis"
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

デプロイの作成、確認

$ kubectl create -f deploy-redis.yaml

$ kubectl get pod
NAME                     READY     STATUS    RESTARTS   AGE
redis-XXXXXXXXXX-XXXXX   1/1       Running   0          1m

Redis サービスの作成

サービス定義ファイルの作成

service-redis.yaml
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: default
  annotations:
    cloud.google.com/load-balancer-type: "internal"
  labels:
    run: redis
spec:
  type: LoadBalancer
  #loadBalancerIP: [IP-ADDRESS]
  ports:
  - port: 6379
    protocol: TCP
    targetPort: 6379
  selector:
    run: redis

サービスの作成、確認

$ kubectl create -f service-redis.yaml

$ kubectl get svc
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
redis     LoadBalancer   10.1.163.115   10.1.1.4      6379:31570/TCP   1m

GitLab の準備

環境変数の設定

今回利用する GitLab イメージは、Podに環境変数を渡すことにより初期設定を行うことができる。
それら環境変数を ConfigMapSecret に分けて設定しておく。

ConfigMap 定義ファイル作成

設定できる環境変数の一覧はこちらのページに記載されている。

gitlab-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: gitlab-configmap
data:
  DEBUG: "false"
  DB_ADAPTER: postgresql
  DB_HOST: sqlproxy-service-gitlab-pgsql
  DB_PORT: "5432"
  DB_NAME: gitlabhq_production
  REDIS_HOST: redis
  REDIS_PORT: "6379"
  TZ: Asia/Tokyo
  GITLAB_TIMEZONE: Tokyo
  GITLAB_HTTPS: "false"
  SSL_SELF_SIGNED: "false"
  GITLAB_HOST: gitlab
  GITLAB_PORT: "80"
  GITLAB_SSH_PORT: "22"
  GITLAB_SECRETS_DB_KEY_BASE: long-and-random-alphanumeric-string
  GITLAB_SECRETS_SECRET_KEY_BASE: long-and-random-alphanumeric-string
  GITLAB_SECRETS_OTP_KEY_BASE: long-and-random-alphanumeric-string
  GITLAB_NOTIFY_ON_BROKEN_BUILDS: "true"
  GITLAB_NOTIFY_PUSHER: "false"
  GITLAB_EMAIL: gitlab@example.co.jp
  GITLAB_EMAIL_REPLY_TO: noreply@example.co.jp
  GITLAB_BACKUP_SCHEDULE: daily
  GITLAB_BACKUP_TIME: 01:00
  SMTP_ENABLED: "true"
  SMTP_DOMAIN: example.co.jp
  SMTP_HOST: smtp.gmail.com
  SMTP_PORT: "587"
  SMTP_STARTTLS: "true"
  SMTP_AUTHENTICATION: login
  OAUTH_ENABLED: "false"
  OAUTH_BLOCK_AUTO_CREATED_USERS: "true"
  OAUTH_AUTO_LINK_LDAP_USER: "false"
  OAUTH_AUTO_LINK_SAML_USER: "false"
  OAUTH_CAS3_LABEL: cas3
  OAUTH_CAS3_DISABLE_SSL_VERIFICATION: "false"
  OAUTH_CAS3_LOGIN_URL: /cas/login
  OAUTH_CAS3_VALIDATE_URL: /cas/p3/serviceValidate
  OAUTH_CAS3_LOGOUT_URL: /cas/logout
  OAUTH_SAML_LABEL: Our SAML Provider
  OAUTH_SAML_NAME_IDENTIFIER_FORMAT: urn:oasis:names:tc:SAML:2.0:nameid-format:transient
  LDAP_ENABLED: "true"
  LDAP_LABEL: example.local
  LDAP_HOST: 10.0.1.123
  LDAP_PORT: "389"
  LDAP_UID: sAMAccountName
  LDAP_METHOD: plain
  LDAP_ACTIVE_DIRECTORY: "true"
  LDAP_BASE: DC=example,DC=local

ConfigMap 作成、確認

$ kubectl create -f gitlab-configmap.yaml

$ kubectl get configmap gitlab-configmap -o yaml
apiVersion: v1
data:
  DB_ADAPTER: postgresql
  DB_HOST: sqlproxy-service-gitlab-pgsql
  DB_NAME: gitlabhq_production
  DB_PORT: "5432"

  ・・・

  SMTP_STARTTLS: "true"
  SMTP_AUTHENTICATION: login
  SSL_SELF_SIGNED: "false"
  TZ: Asia/Tokyo
kind: ConfigMap
metadata:
  creationTimestamp: 2018-08-21T01:31:59Z
  name: gitlab-configmap
  namespace: default
  resourceVersion: "3616639"
  selfLink: /api/v1/namespaces/default/configmaps/gitlab-configmap
  uid: ff9dbd94-a4e1-11e8-aadc-42010a920042

シークレット定義ファイル作成

環境変数は、全て上記 ConfigMap に記載することが可能だが、アカウントやパスワード、トークン等、セキュリティ上プレーンテキストで設定したくない情報は、Secret 定義に環境変数の値を BASE64 エンコードして記述することができる。

今回は Cloud SQL 、SMTPサーバ(Gmail)、ADサーバ(AWS側)の接続アカウント情報を、BASE64 エンコードして記載した。

gitlab-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: gitlab-secret
data:
  DB_USER: Z2l0bGFi                       #echo -n "gitlab" | base64
  DB_PASS: MWx4THhrRDg=                   #echo -n "<PASSWORD>" | base64
  SMTP_USER: aG9nZUBleGFtcGxlLmNvLmpw     #echo -n "hoge@example.co.jp" | base64
  SMTP_PASS: VDhkbTNuc0s=                 #echo -n "<PASSWORD>" | base64
  LDAP_BIND_DN: Q049QWRtaW5pc3RyYXRvcixDTj1Vc2VycyxEQz1leGFtcGxlLERDPWxvY2Fs #echo -n "CN=Administrator,CN=Users,DC=example,DC=local" | base64
  LDAP_PASS: TUczNHBkYw==                 #echo -n "<PASSWORD> | base64

シークレット作成、確認

$ kubectl create -f gitlab-secret.yaml

$ kubectl get secret gitlab-secret -o yaml
apiVersion: v1
data:
  DB_PASS: MWx4THhrRDg=
  DB_USER: Z2l0bGFi
  LDAP_BIND_DN: Q049QWRtaW5pc3RyYXRvcixDTj1Vc2VycyxEQz1leGFtcGxlLERDPWxvY2Fs
  LDAP_PASS: TUczNHBkYw==
  SMTP_USER: aG9nZUBleGFtcGxlLmNvLmpw
  SMTP_PASS: VDhkbTNuc0s=
kind: Secret
metadata:
  creationTimestamp: 2018-08-21T01:30:02Z
  name: gitlab-secret
  namespace: default
  resourceVersion: "3616376"
  selfLink: /api/v1/namespaces/default/secrets/gitlab-secret
  uid: b9ffbc3e-a4e1-11e8-a346-42010a920024
type: Opaque

GitLabのデプロイ

デプロイ定義ファイル作成

前述で作成した PVC pvc-gitlabvolumes に定義し、volumeMounts でマウント情報を定義する。

また今回の GitLab は Internal からのみアクセス可能なサービスとして設定する為、コンテナポート 443(SSL)の定義は省略する。

deploy-gitlab.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  generation: 1
  labels:
    run: gitlab
  name: gitlab
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      run: gitlab
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        run: gitlab
    spec:
      containers:
      - image: asia.gcr.io/my-project/gitlab:11.1.4
        imagePullPolicy: Always
        name: gitlab
        envFrom:
        - configMapRef:
            name: gitlab-configmap
        - secretRef:
            name: gitlab-secret
        ports:
        - containerPort: 80
          protocol: TCP
        - containerPort: 22
          protocol: TCP
        volumeMounts:
        - name: gitlab-data
          mountPath: "/home/git/data"
        resources:
          requests:
            cpu: 100m
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      volumes:
        - name: gitlab-data
          persistentVolumeClaim:
            claimName: "pvc-gitlab"
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

尚、今回はリソース要求(resources: requests:)、制限(resources: limits:)は GKE のデフォルト値である cpu: 100m のみ設定している。

※GKE では リソース要求は cpu のみ設定されており、制限は特に設定されていない。

Example
$ kubectl get LimitRange -o yaml
apiVersion: v1
items:
- apiVersion: v1
  kind: LimitRange
  metadata:

    ・・・

  spec:
    limits:
    - defaultRequest:
        cpu: 100m
      type: Container
kind: List

  ・・・

この辺りは利用ユーザー数やリソース消費状況(kubectl top nodekubectl describe node)を確認しつつ、適切にプランニングしたほうが良いだろう。

Example
・・・
        resources:
          requests:
            cpu: 100m
            memory: 1Gi
          limits:
            cpu: 1000m
            memory: 2Gi
・・・

デプロイ実行、確認

$ kubectl create -f deploy-gitlab.yaml

$ kubectl get pod
NAME                     READY     STATUS    RESTARTS   AGE
gitlab-XXXXXXXXX-XXXXX   1/1       Running   0          5m

GitLab サービスの作成

サービス定義ファイル作成

service-gitlab.yaml
apiVersion: v1
kind: Service
metadata:
  name: gitlab
  namespace: default
  annotations:
    cloud.google.com/load-balancer-type: "internal"
  labels:
    run: gitlab
spec:
  type: LoadBalancer
  ports:
  - port: 80
    name: gitlab-http
    protocol: TCP
    targetPort: 80
  - port: 22
    name: gitlab-ssh
    protocol: TCP
    targetPort: 22
  selector:
    run: gitlab

サービス作成、確認

$ kubectl create -f service-gitlab.yaml

$ kubectl get svc
NAME      TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)                     AGE
gitlab    LoadBalancer   10.1.163.88   10.1.1.11     80:30488/TCP,22:30118/TCP   5m

GitLab 起動確認

DNS に GitLab を登録

GitLab サービスに割り当てられた IP アドレス(今回の例では EXTERNAL-IP に割り当てられた 10.1.1.11)が名前解決できるよう、内部向け DNS サーバにホスト gitlab.example.local を登録する。

尚、内部向け DNS サーバへの登録方法は割愛。

サーバにアクセス

ブラウザから http://gitlab/ (または http://gitlab.example.local/) にアクセスして、下図のページが表示されることを確認する。

screencapture-gitlab-users-password-edit-2018-08-22-15_32_57.png

尚、開いたページは管理者(root)パスワードを変更するよう促しているが、後述のデータ移行により移行元サーバから管理者アカウント情報も移行される為、そのままページを閉じて構わない。

データ移行

移行元データをバックアップ

移行元の GitLab サーバにログインし、次のコマンドでデータをバックアップする。

$ sudo gitlab-rake gitlab:backup:create

デフォルトでは /var/opt/gitlab/backups 下に XXXXXXXXXX_YYYY_MM_DD_11.1.4_gitlab_backup.tar というファイル名で保存される。

移行先にデータ転送

上記バックアップファイルをGKE上のGitLab Pod の /home/git/data/backups(Cloud Filesore 上の /<Mount Point>/gitlab/backups)下に転送する。

※VMインスタンスに Cloud Filestore を NFS マウントして scp する等、力業で転送すること

移行先でリストア

BACKUP パラメータに、ファイル名から _gitlab_backup.tar を除いた文字列を指定する点に注意すること。

$ kubectl exec -it gitlab-XXXXXXXXXX-XXXXX /bin/bash

/home/git/gitlab# sudo -u git -H bundle exec rake RAILS_ENV=production gitlab:backup:restore BACKUP=XXXXXXXXXX_YYYY_MM_DD_11.1.4

リストア後、ブラウザから http://gitlab/ を開いてログインし、移行元から全プロジェクトが移行されていることを確認する。

エンドユーザー側での作業

GitLab の移行が完了すれば利用者からもアクセスできるようになるが、エンドユーザー側のローカルリポジトリには移行元のリモートリポジトリが設定されたままだ。
このままでは移行元に対し git pullgit push してしまう恐れがあるので、リモートリポジトリに設定されている URI を、次の手順で変更してもらう。

リモートリポジトリの確認
> cd <ローカルプロジェクトのフォルダパス>
> git remote -v
origin  git@<移行元ホスト名>:foo/bar.git (fetch)
origin  git@<移行元ホスト名>:foo/bar.git (push)


リモートリポジトリの URI 変更
> git remote set-url origin git@gitlab:foo/bar.git


リモートリポジトリの変更確認
> git remote -v
origin  git@gitlab:foo/bar.git (fetch)
origin  git@gitlab:foo/bar.git (push)


fetch 実行
> git fetch origin
The authenticity of host 'gitlab (10.1.1.11)' can't be established.
ECDSA key fingerprint is SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
ECDSA key fingerprint is MD5:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX.
Are you sure you want to continue connecting (yes/no)? yes    ←'yes' 入力
7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?