21
11

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.

おうちkubernetesでデータを永続化する

Last updated at Posted at 2017-12-23

目的

おうちでKubernetes運用していますか?
私はVPSを借りてKubernetesを運用しています。

しかし、kubernetesを運用していくなかで、なんどもOSを入れ直したり、インスタンスを作り直したりしたいが、アプリケーションのデータを失いたくない。そんなことはありませんか?

解決策

Google Driveに定期的に保存することを検討します。

Rclone

ローカルファイルをありとあらゆるSaaSに同期できるツール
これをサイドカーに入れて、定期的にデータをバックアップすることを考えます。

Secret作成

Rcloneは、同期先の情報をconfigファイルとして与えることができます。
この中には認証情報なども含まれるためKubernetesのSecretリソースとして用意するのが良さそうです。

rclone config コマンドで対話形式でコンフィグファイルを作ることができます。
手元のマシンにrcloneをインストールしても良いのですが、今回はdockerでやってみました。

$ mkdir config
$ docker run --rm -v `pwd`/config:/config -t -i tynor88/rclone:latest rclone config --config=/config/.rclone.conf

[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[s6-init] ensuring user provided files have correct perms...exited 0.
[fix-attrs.d] applying ownership & permissions fixes...
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts...
[cont-init.d] 10-adduser: executing...

GID/UID
-------------------------------------
User uid:    911
User gid:    911
-------------------------------------

[cont-init.d] 10-adduser: exited 0.
[cont-init.d] 40-config: executing...
crontab => 0 * * * * /app/rclone.sh
chmod: /config/Rclone.sh: No such file or directory
[cont-init.d] 40-config: exited 0.
[cont-init.d] done.
[services.d] starting services
crond[199]: crond (busybox 1.24.2) started, log level 0
crond[199]: user:root entry:*/15	*	*	*	*	run-parts /etc/periodic/15min
crond[199]: user:root entry:0	*	*	*	*	run-parts /etc/periodic/hourly
crond[199]: user:root entry:0	2	*	*	*	run-parts /etc/periodic/daily
crond[199]: user:root entry:0	3	*	*	6	run-parts /etc/periodic/weekly
crond[199]: user:root entry:0	5	1	*	*	run-parts /etc/periodic/monthly
crond[199]: user:abc entry:0 * * * * /app/rclone.sh
[services.d] done.
No remotes found - make a new one
n) New remote
s) Set configuration password
q) Quit config
n/s/q> n
name> hoge
Type of storage to configure.
Choose a number from below, or type in your own value
 1 / Amazon Drive
   \ "amazon cloud drive"
 2 / Amazon S3 (also Dreamhost, Ceph, Minio)
   \ "s3"
 3 / Backblaze B2
   \ "b2"
 4 / Dropbox
   \ "dropbox"
 5 / Encrypt/Decrypt a remote
   \ "crypt"
 6 / Google Cloud Storage (this is not Google Drive)
   \ "google cloud storage"
 7 / Google Drive
   \ "drive"
 8 / Hubic
   \ "hubic"
 9 / Local Disk
   \ "local"
10 / Microsoft OneDrive
   \ "onedrive"
11 / Openstack Swift (Rackspace Cloud Files, Memset Memstore, OVH)
   \ "swift"
12 / Yandex Disk
   \ "yandex"
Storage> 7
Google Application Client Id - leave blank normally.
client_id>
Google Application Client Secret - leave blank normally.
client_secret>
Remote config
Use auto config?
 * Say Y if not sure
 * Say N if you are working on a remote or headless machine or Y didn't work
y) Yes
n) No
y/n> N

config/.rclone.conf が出来上がるので、kubernetesにsecretとしてデプロイします。

$ kubectl create secret generic rclone-config --from-file=./config/.rclone.conf

Rclone定期実行

rcloneを定期実行するDockerイメージがあります。今回はこれを使います。
https://hub.docker.com/r/tynor88/rclone/

デプロイ

今回は例として、gollum(gitをバックエンドとするwiki) をデプロイし、そのデータをGoogleDriveに同期してみます。

初回起動時は以前保存していたものを復元するために GoogleDrive -> Pod で同期を行います。
これはpod.spec.initContainersで実現しています。 ( https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ )

起動中はgollumとは別にrcloneのコンテナを動作させて、定期的に Pod -> GoogleDrive で同期を行います。

図にするとこんな感じ。

以下がmanifest上記を実現するmanifestです。

gollum-with-rclone.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    run: gollum
  name: gollum
  namespace: default
spec:
  selector:
    matchLabels:
      run: gollum
  template:
    metadata:
      labels:
        run: gollum
    spec:
      initContainers:  # gollumのために、git initを初めにしておく
      - name: init
        image: golang:latest # gitがあればなんでも良い
        command:
        - sh
        - -c
        - cd /root/wikidata && git init
        volumeMounts:
        - mountPath: /root/wikidata
          name: data
      - name: first-rclone
        image: tynor88/rclone:latest
        command:  # rclone初回実行 (GoogleDrive -> Pod)
        - sh
        - -c
        - /usr/bin/with-contenv sh /app/rclone.sh
        env:
        - name: SYNC_COMMAND
          value: rclone sync GoogleDrive:/gollum /data
        volumeMounts:
        - mountPath: /data
          name: data
        - mountPath: /root
          name: config
      containers:
      - name: gollum
        image: suttang/gollum:latest # 本命のgollumイメージ
        volumeMounts:
        - mountPath: /root/wikidata
          name: data
      - name: rclone
        image: tynor88/rclone:latest # 同期用のrclone (Pod -> GoogleDrive)
        imagePullPolicy: Always
        env:
        - name: SYNC_DESTINATION
          value: GoogleDrive
        - name: SYNC_DESTINATION_SUBPATH
          value: gollum
        - name: CRON_SCHEDULE
          value: 0 * * * *
        volumeMounts:
        - mountPath: /data
          name: data
        - mountPath: /config
          name: config
      volumes:
      - name: data  # wikiのデータを入れる
        emptyDir: {}
      - name: config # secretからConfigを読み出す
        secret:
          defaultMode: 511 # 雑に0777
          secretName: rclone-config

クラスタにデプロイするためには下記を実行します。

$ kubectl apply -f gollum-with-rclone.yaml

できたー!

注意

  • 定期実行によるバックアップなので、その隙間の変更はバックアップされない。
    • preStopなどでもバックアップするとより良いと考えられる
      • それでも突然死などはカバーしきれないので注意が必要
  • replicaを1以上にすることは想定していません(おうちなので)
    • その場合はアプリケーションとデータを分離して、データのバックアップをGoogleDriveにSyncするなどさらなる工夫が必要そうです。

まとめ

おうちでKubernetesクラスタを構築する際に問題となるデータの永続化について、Rcloneを用いた、GoogleDriveへの定期バックアップスクリプトを紹介しました。
ファイルであればなんでも同期できるため、どんなデータでも永続化できることが特徴です。

Kubernetesは変化が早いため、常に最新のKubernetesの環境が手元にあるのは非常に良い勉強になるため、おうちKubernetesクラスタ、おすすめです。

(Raspberry piを使ったKubernetesの構築方法も紹介していますので、こちらも参考にしてみてください https://qiita.com/hatotaka/items/48a88ecb190e1f5e03c3 )

このエントリは、Z Lab のメンバーによる Z Lab Advent Calendar 2017 として業務時間中に書きました。

21
11
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
21
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?