kubernetes(kind)上でdjango/mysqlを実行する方法

Shuji Ohira
inet-lab
Published in
10 min readMar 29, 2021

こちらの記事は,研究室で開発/運用しているdjangoベースのWebアプリをkubernetes in docker (kind) に移行する際の備忘録となっています.また,本記事ではmysqlとdjangoベースのWeb Serverの両方をkubernetes上のpodとしてデプロイする方法が説明されています.

以下のような環境で実行することを前提としています.(また,Dockerはインストール及び起動されているものとします)
実験環境
OS : Ubuntu 18.04
Docker : v20.10.5

0. 準備

まず,kindとkubectlをインストールします.kindはその名の通りdocker内でkubernetesを実行するためのテスト環境で,ローカル環境でkubernetesを実行することが可能になります.似たような種類のものでMinikubeというツールもありますが,こちらは複数のノードのデプロイに対応していないため,この点においてはkindに優位性があるようです.

kubectlはkubernetes用のコマンドラインツールで,このコマンドを使うことでkubernetes cluster/pod等の作成・削除が可能になります.また,contextと呼ばれるパラメータを切り替えることで,操作対象をkindからGoole Kubernetes Engine (GKE)等のpublic cloudに変更することも可能です.
以下がkindとkubectlをインストールする手順です.(※最新のビルド方法は公式サイトを参照してください)

//kindのinstall
$ curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.10.0/kind-linux-amd64
$ chmod +x ./kind
# mv ./kind /usr/local/bin/kind
$ kind --version
//kubectlのinstall
$ curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
$ chmod +x ./kubectl
# mv ./kubectl /usr/local/bin/kubectl
$ kubectl version --client

次に,pollsと呼ばれるテスト用のdjango projectが含まれたpython-docs-samplesリポジトリとkubernetes用のyamlファイルが保存されたリポジトリをcloneします.また,django v2.2 LTSで動作させるために,予め準備されているpatchファイルをpython-docs-samplesリポジトリに適用します.

//python-docs-samplesとdjango_on_kubernetesをまとめてclone
$ git clone --recursive https://github.com/shuji-oh/django_on_kubernetes
//django v2.2 LTSで動かすために,patchを適用
$ cd django_on_kubernetes/python-docs-samples
$ git apply ../diff_python-docs-samples.patch
// 1.以降のコマンドはdjango_on_kubernetes/の上で行うので一つ戻る
$ cd ..

これで,下準備は完了です.

1. kubernetes cluster/podの作成

ここからはkubernetes clusterやpodの作成を行っていきます.kubernetes clusterはmasterとworkerから構成されており,ざっくり説明するとworker側でcontainerが動作していて,master側でそのworkerの管理をします.今回は,master1台・worker3台のclusterを作成してみます.また,kubernetesにおけるpodは1つ以上のcontainerが起動している最小単位のオブジェクトのことです.今回はpodとしてmysqlやdjangoベースのWebアプリを起動していきます.
以下でclusterの作成を行います.

//clusterを作成
$ kind create cluster --config kind.yaml --name django
Creating cluster "kind-django" ...
//kind-djangoが選択されているか確認 (*がついとけばok)
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO
* kind-django kind-django kind-django
//clusterの確認
$ kubectl get nodes

DBの作成

先ほど作成したクラスタにmysqlのpodを作成していきます.DBを作成する前に,パスワード等の公開できない情報をyamlファイルに埋め込むためのtoolであるsecretを作成しておきます.

//mysql_deployment.yaml用のsecretの設定
$ cat env-secret.txt ※ env-secret.txtはvim等のエディタで作成してください
username=root
password=password
//env-secret.txtを元に, secretの作成
$ kubectl create secret generic --save-config mysql-secret --from-env-file ./env-secret.txt
//secretの確認
$ kubectl get secret mysql-secret
NAME TYPE DATA AGE
mysql-secret Opaque 2 5h53m

これでやっと,mysqlのpodが作成できます.

//mysqlのpodの作成
$ kubectl apply -f mysql_pv.yaml
$ kubectl apply -f mysql_deployment.yaml
//podの確認
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-6f95b985b5-655dv 1/1 Running 0 5h56m

Web Serverの作成

次にWeb Serverのpodを作成していきます.まず,Web ServerがDBに接続するためのパスワード等の情報を隠蔽するために,pipenv用の環境変数を定義します.

//django用の環境変数の設定 (先ほどのenv-secret.txtと内容は同じにすること!)
$ cat .env ※ .envはvim等のエディタで作成してください
DATABASE_USER=root
DATABASE_PASSWORD=password

次に,kubernetesから参照するdocker imageを作成します.作成したimageをkindに取り込み,その後Web Serverのpodを作成します.

//先ほど作成した.envファイルを指定しつつ, docker imageを作成
$ docker build -t mysite/django:v1 --build-arg ENV='.env' .
//docker imageをkindでロード
$ kind load docker-image mysite/django:v1 --name django
//Web Serverのpodを作成, podの確認
$ kubectl apply -f python_server_deployment.yaml
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
django-f4c97786d-2w5m4 1/1 Running 0 4h51m
django-f4c97786d-nvbt5 1/1 Running 0 4h51m
django-f4c97786d-zp64k 1/1 Running 0 4h51m
mysql-6f95b985b5-655dv 1/1 Running 0 5h56m

2. djangoのmanage.pyによるDB migration

現状DB内はデフォルトの状態でdjangoに関するtable等が存在しない状態です.なので,DBやdjangoが動いているpodに直接アクセスしてそれらを作成します.

//DBの作成
$ kubectl run -it --rm --image=mysql:5.7 --restart=Never mysql-client -- mysql -u root -h mysql-clusterip -ppassword -P 13306
mysql> create database polls;
mysql> exit;
//djangoのmanage.pyを使ってtableの作成
$ kubectl exec -it django-f4c97786d-2w5m4 -- /bin/bash
# pipenv run python manage.py makemigrations
# pipenv run python manage.py migrate

3. podへのポートフォワーディング, ブラウザで接続

ここまでの手順でほとんど終わりですが,最後にブラウザからアクセスするためにpodへポートフォワーディングします.

$ kubectl port-forward django-f4c97786d-2w5m4 8888:8000

上記のポートフォワーディングを行うコマンドを行いつつ,ブラウザでhttp://127.0.0.1:8888にアクセスすると,`Hello, world. You’re at the polls`が出てきます.http://127.0.0.1:8888/adminにもアクセスできれば,ビルド成功です.

4. 終わりに

余談ですが,`kubectl`は毎回打つのめんどくさいので`k`などのエイリアスを作成しておくと良いと随所で書かれています.

$ k get pods
NAME READY STATUS RESTARTS AGE
django-f4c97786d-2w5m4 1/1 Running 0 4h51m
django-f4c97786d-nvbt5 1/1 Running 0 4h51m
django-f4c97786d-zp64k 1/1 Running 0 4h51m
mysql-6f95b985b5-655dv 1/1 Running 0 5h56m

参考文献

  1. “DjangoをlocalのKubernetesで動かす,” https://solist.work/blog/posts/django-local-kubernetes/
  2. “kubernetesでMysqlを動かしてみる,” https://qiita.com/witchy/items/3a39b674097b86a44546
  3. 青山真也, “Kubernetes完全ガイド 第二版”

--

--