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

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

More than 1 year has passed since last update.

目的

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

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

解決策

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

Rclone

https://rclone.org/

ローカルファイルをありとあらゆる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 として業務時間中に書きました。

inajob
電子工作、JavaScript、Kubernetes 興味があることは何でも! https://twitter.com/ina_ani
http://d.hatena.ne.jp/inajob/
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
ユーザーは見つかりませんでした