Help us understand the problem. What is going on with this article?

GKEとCloud SQLを使ってhelmでRedmineを建ててみる

この記事は:calendar:GMOアドマーケティング Advent Calendar 2019の18日目の記事です。

自己紹介

GMOアドマーケティングでインフラ開発に携わっています、@sandatsです。
最近はGCPに触れる機会が多く、今回は勉強も含めてGKE + Cloud SQL + helmでRedmineを建ててみました。

登場人物の紹介

GKE(Google Kubernetes Engine)

GCPのインフラを利用して構成されるKubernetes

Cloud SQL

GCPが提供するマネージドDBサービス
MySQL/Postgre SQL/SQL Serverが使える

Helm

Kubernetesのパッケージ管理ツール
今回はHelm 3を利用

Redmine

タスク/チケット/進捗などなど管理ツール
お世話になってます:pray:

前提

  • helmがインストールされている
  • GCPでKubernetesクラスタが起動している
  • GCPでCloud SQLが起動し、プライベート IPが有効になっている
  • KubernetesとCloud SQLのVPCが同じVPCネットワークを使っている

参考したドキュメントやリンク

Helm Quickstart
https://helm.sh/docs/intro/quickstart/

Helm charts Redmine
https://github.com/helm/charts/tree/master/stable/redmine

環境

helm : v3.0.1
Kubernetes : v1.13.11-gke.14

 ~  helm version
version.BuildInfo{Version:"v3.0.1", GitCommit:"7c22ef9ce89e0ebeb7125ba2ebf7d421f3e82ffa", GitTreeState:"clean", GoVersion:"go1.13.4"}

 ~  kubectl version
Client Version: version.Info{Major:"1", Minor:"13+", GitVersion:"v1.13.11-dispatcher", GitCommit:"2e298c7e992f83f47af60cf4830b11c7370f6668", GitTreeState:"clean", BuildDate:"2019-09-19T22:26:40Z", GoVersion:"go1.11.13", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"13+", GitVersion:"v1.13.11-gke.14", GitCommit:"56d89863d1033f9668ddd6e1c1aea81cd846ef88", GitTreeState:"clean", BuildDate:"2019-11-07T19:12:22Z", GoVersion:"go1.12.11b4", Compiler:"gc", Platform:"linux/amd64"}

helmからRedmineをインストール

helmからRedmineをinstall

 ~  helm install infra-redmine stable/redmine
NAME: infra-redmine
LAST DEPLOYED: Mon Dec 16 18:27:27 2019
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the Redmine URL:

  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        Watch the status with: 'kubectl get svc --namespace default -w infra-redmine'


  export SERVICE_IP=$(kubectl get svc --namespace default infra-redmine --template "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}")
  echo "Redmine URL: http://$SERVICE_IP/"

2. Login with the following credentials

  echo Username: user
  echo Password: $(kubectl get secret --namespace default infra-redmine -o jsonpath="{.data.redmine-password}" | base64 --decode)

helm ls でインストールしたRedmineの情報が確認できる

 ~  helm ls
NAME            NAMESPACE   REVISION    UPDATED                                 STATUS      CHART           APP VERSION
infra-redmine   default     1           2019-12-18 15:23:23.329367 +0900 JST    deployed    redmine-14.0.1  4.0.5

しばらくすると、2つのpodsがREADY 1/1になる

 ~  kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
infra-redmine-5799684fc8-r4h25   1/1     Running   1          16m
infra-redmine-mariadb-0          1/1     Running   0          15m

kubectl get serviceでEXTERNAL-IPをメモします

 ~  kubectl get service
NAME                    TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
infra-redmine           LoadBalancer   10.109.4.121   35.243.123.53   80:31675/TCP   26m
infra-redmine-mariadb   ClusterIP      10.109.6.209   <none>          3306/TCP       26m
kubernetes              ClusterIP      10.109.0.1     <none>          443/TCP        126m

EXTERNAL-IPに適当なブラウザからアクセスするとRedmineが表示されます
スクリーンショット 2019-12-16 18.56.01.png

Redmineの削除

helm uninstallを実行するとRedmineのdeployments、pods、serviceが削除されます。早い。

 ~  helm uninstall infra-redmine
release "infra-redmine" uninstalled
 ~  helm ls
NAME    NAMESPACE   REVISION    UPDATED STATUS  CHART   APP VERSION

 ~  kubectl get service
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.109.0.1   <none>        443/TCP   142m
 ~  kubectl get pods
No resources found.

ここまでのまとめ

素の状態でインストールするとRedmineとMariaDBのpodsが起動する

Redmine on k8s.png

serviceが作成され、LoadBalancer経由でRedmineを閲覧できる

Redmine on k8s with GCLB.png

つづいて、Redmineのpodsはそのままにして、MariaDBのpodsを起動させずにCloud SQLへ接続する設定に変更します。

DBの作成

CloudSQLのWeb UIからRedmineに使うDBを先に作成しておく。
cloudsql_redmine.png

チャートのカスタマイズ

Helmではchart毎にカスタマイズ可能なパラメータが存在する。
https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing

helm show values チャート名でカスタマイズ可能な値が表示される。

 ~  helm show values stable/redmine
## Global Docker image parameters
## Please, note that this will override the image parameters, including dependencies, configured to use the global value
## Current available global Docker image parameters: imageRegistry and imagePullSecrets
##
# global:
#   imageRegistry: myRegistryName
#   imagePullSecrets:
#     - myRegistryKeySecretName
#   storageClass: myStorageClass

## Bitnami Redmine image version
## ref: https://hub.docker.com/r/bitnami/redmine/tags/
##
image:
  registry: docker.io
  repository: bitnami/redmine
  tag: 4.0.5-debian-9-r28
  ## Specify a imagePullPolicy
  ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent'
  ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images
  ##
  pullPolicy: IfNotPresent
# ...

パラメータを編集して、RedmineをCloud SQLに接続しつつ、DB用のPodsを起動しないようにします。

チャートのカスタマイズ

チャートのカスタマイズパラメータをファイルに書き出す。

 ~  helm show values stable/redmine > helm_redmine.yaml

書き出したファイルを開き、mariadbのenabledをtrueからfalseにする。

mariadb:
  ## Whether to deploy a mariadb server to satisfy the applications database requirements. To use an external database set this to false and configure the externalDatabase parameters
  enabled: false
  ## Disable MariaDB replication
  replication:
    enabled: false

同様にexternalDatabaseでCloud SQLへ接続するための情報を記述。(host、name、user、passwordを変更)

externalDatabase:
  ## Database host
  host: 10.153.16.3

  ## Database name
  name: redmine

  ## Database User
  user: root

  ## Database Password
  password: hogehoge

  ## Database port number (use 5432 when using PostgreSQL)
  port: 3306

修正したファイルを指定して、helm installを実行。

 ~  helm install infra-redmine stable/redmine -f helm_redmine.yaml
NAME: infra-redmine
LAST DEPLOYED: Wed Dec 18 15:32:35 2019
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the Redmine URL:

  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        Watch the status with: 'kubectl get svc --namespace default -w infra-redmine'


  export SERVICE_IP=$(kubectl get svc --namespace default infra-redmine --template "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}")
  echo "Redmine URL: http://$SERVICE_IP/"

2. Login with the following credentials

  echo Username: user
  echo Password: $(kubectl get secret --namespace default infra-redmine -o jsonpath="{.data.redmine-password}" | base64 --decode)

前回とは異なり、今回はRedmineのpodsのみ起動する。

 ~  kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
infra-redmine-7b76bbb49f-zjd6v   1/1     Running   0          23m

この状態で、kubectl get svcに表示されるEXTERNAL-IPにアクセスすると同様にRedmineのトップページが表示されます。

 ~  kubectl get svc
NAME            TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
infra-redmine   LoadBalancer   10.203.9.231   35.230.106.77   80:31731/TCP   8m38s
kubernetes      ClusterIP      10.203.0.1     <none>          443/TCP        21m

チャートのパラメータをカスタマイズして、Cloud SQLを使ってRedmineを建てる事ができました。
Redmine on k8s with CloudSQL.png

DBの中身を確認

RedmineがCloud SQLを使っているのか確かめる為、RedmineコンテナからmysqlコマンドでCloud SQLに接続します。

 ~  kubectl exec -it infra-redmine-7b76bbb49f-zjd6v /bin/sh
# which mysql
/opt/bitnami/mysql/bin/mysql
# mysql -h 10.153.16.3 redmine -p
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 2909
Server version: 5.7.14-google (Google)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [redmine]> show tables;
+-------------------------------------+
| Tables_in_redmine                   |
+-------------------------------------+
| ar_internal_metadata                |
| attachments                         |
| auth_sources                        |
| boards                              |
| changes                             |
| changeset_parents                   |
| changesets                          |
| changesets_issues                   |
| comments                            |
| custom_field_enumerations           |
| custom_fields                       |
| custom_fields_projects              |
| custom_fields_roles                 |
| custom_fields_trackers              |
| custom_values                       |
| documents                           |
| email_addresses                     |
| enabled_modules                     |
| enumerations                        |
| groups_users                        |
| import_items                        |
| imports                             |
| issue_categories                    |
| issue_relations                     |
| issue_statuses                      |
| issues                              |
| journal_details                     |
| journals                            |
| member_roles                        |
| members                             |
| messages                            |
| news                                |
| open_id_authentication_associations |
| open_id_authentication_nonces       |
| projects                            |
| projects_trackers                   |
| queries                             |
| queries_roles                       |
| repositories                        |
| roles                               |
| roles_managed_roles                 |
| schema_migrations                   |
| settings                            |
| time_entries                        |
| tokens                              |
| trackers                            |
| user_preferences                    |
| users                               |
| versions                            |
| watchers                            |
| wiki_content_versions               |
| wiki_contents                       |
| wiki_pages                          |
| wiki_redirects                      |
| wikis                               |
| workflows                           |
+-------------------------------------+
56 rows in set (0.001 sec)

コンテナ内からCloudSQLのプライベートIPでDBに接続できました。
Redmineのテーブルも存在する事が確認できました。

まとめ

  • 1コマンドでHelmからRedmineを起動できる(yaml書かなくて良い:thumbsup:)
  • Kubernetes podsからCloud SQLへプライベートIPで接続できる(同一VPCを利用する)
  • chartにはカスタマイズ用のパラメータが存在する。

今後について

インフラで使っていくツールをk8sに乗せかえていきたいです:muscle:

明日は、@mSpringさんによる「TensorFlowにおけるクリッピングと正規化」です!

引き続き、:calendar:GMOアドマーケティング Advent Calendar 2019 をお楽しみください:relaxed:

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした