まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:iks

Docker Desktop ショックがあって以来、なるべく少ない制約の下で docker を動かせる環境を色々調べています。そんな中で見つけた1つの方法が Docker in Docker(以下、DinD)です。

DinD はその名前の通りで、コンテナクラスタ(親)の中で動くコンテナ(子)として Docker サーバー&クライアントを動かす、というものです。多くの場合、「親コンテナ=Kubernetes」となることが多いので、正確には "Docker in Kubernetes" と表現すべきかもしれませんが、広い意味(?)での "Docker in Docker" ということだと思います。

単なる運用環境の観点だと「Kubernetes が使えるなら Docker は要らないのでは?」と思うかもしれませんが、特に開発段階だとコマンドとしての docker CLI を使いたいことがあったり、プロダクション環境とは別の小さな開発環境を Docker で作っておけると便利なことも多くあります。そういった意味で Kubernetes があってもそれとは別に Docker 環境が欲しくなることがあるのでした。


IBM Cloud からも IKS(IBM Kubernetes Services)ROKS(Redhat Openshift Kubernetes Services) が提供されていて、これらの環境でも DinD を使うことができます。特に今回は IKS の 30 日無料版を使って DinD 環境を作って使う手順を紹介します。なお、IKS 30 日無料版の制約事項や環境準備手順についてはこちらの過去記事を参照ください:
http://dotnsf.blog.jp/archives/1079287640.html


↑この記事最後の "$ kubectl get all" コマンドが成功するまでになれば準備完了です。なお Kubernetes クラスタに対して "$ kubectl get all" コマンドが実行できるようになっていれば IKS 以外の他の Kubernetes クラスタ環境でも以下同様にして DinD 環境を作ることができると思います。


【(IKS に) DinD の Pod を作る】
では早速 DinD 環境を作ります。DinD 環境といっても大それたものではなく、コンテナ的に言えば「DinD の Pod を1つ作る」ことになります。そしてその1つの Pod の中に「Docker デーモンのコンテナ」と「Docker クライアントのコンテナ」を1つずつ作ります(つまり1つの Pod の中で2つのコンテナを動かします)。

実際の作成に関しても、以下の内容のマニフェストファイルを用意するだけです(この内容を dind.yml という名前で保存してください):
apiVersion: v1
kind: Pod
metadata:
  name: dind
spec:
  containers:
    - name: docker
      image: docker:19.03
      command: ["docker", "run", "nginx:latest"]
      env:
        - name: DOCKER_HOST
          value: tcp://localhost:2375
    - name: dind-daemon
      image: docker:19.03-dind
      env:
        - name: DOCKER_TLS_CERTDIR
          value: ""
      resources:
        requests:
          cpu: 20m
          memory: 512Mi
      securityContext:
        privileged: true

そして、kubectl コマンドで以下を実行してマニフェストを適用します:
$ kubectl apply -f dind.yml

※または dind.yml を用意しなくても、このコマンドでも同じ結果になります:
$ kubectl apply -f https://raw.githubusercontent.com/dotnsf/dind_iks/main/dind.yml


初回のみイメージのダウンロードで少し時間がかかりますが、しばらく待つと dind という名前の Pod が1つ(コンテナは docker dind-daemon の2つ)起動します:
$ kubectl get pods

NAME READY STATUS RESTARTS AGE dind 2/2 Running 2 101m $ kubectl describe pod dind Name: dind Namespace: default Priority: 0 Node: 10.144.222.147/10.144.222.147 Start Time: Sun, 20 Feb 2022 21:52:46 +0900 Labels: Annotations: cni.projectcalico.org/containerID: 0c110243107d25c9e27b82202871504047d9ac691ad294d8f89bb1a9b114ca5e cni.projectcalico.org/podIP: 172.30.216.78/32 cni.projectcalico.org/podIPs: 172.30.216.78/32 kubernetes.io/psp: ibm-privileged-psp Status: Running IP: 172.30.216.78 IPs: IP: 172.30.216.78 Containers: docker: Container ID: containerd://0dbd05bc4171f96caaa7601a10e1b2f853511b4ed7087ab3958c016024c65f1c Image: docker:19.03 Image ID: docker.io/library/docker@sha256:ea1f0761c92b600417ad14bc9b2b3a30abf8e96e94895fee6cbb5353316f30b0 Port: Host Port: Command: docker run nginx:latest State: Running Started: Sun, 20 Feb 2022 22:53:02 +0900 Last State: Terminated Reason: Completed Exit Code: 0 Started: Sun, 20 Feb 2022 21:53:08 +0900 Finished: Sun, 20 Feb 2022 22:53:01 +0900 Ready: True Restart Count: 2 Environment: DOCKER_HOST: tcp://localhost:2375 Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-gz5fb (ro) dind-daemon: Container ID: containerd://5a6a15eefa9ebdf8a0dcc825f1c87fa4a5a37daab005a1d83e5df8f9a33ff7bb Image: docker:19.03-dind Image ID: docker.io/library/docker@sha256:c85365ad08c7f6e02ac962a8759c4a5b8512ea5c294d3bb9ed25fca52e9e22e5 Port: Host Port: State: Running Started: Sun, 20 Feb 2022 21:53:07 +0900 Ready: True Restart Count: 0 Requests: cpu: 20m memory: 512Mi Environment: DOCKER_TLS_CERTDIR: Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-gz5fb (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: kube-api-access-gz5fb: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: DownwardAPI: true QoS Class: Burstable Node-Selectors: Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 600s node.kubernetes.io/unreachable:NoExecute op=Exists for 600s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Created 43m (x3 over 103m) kubelet Created container docker Normal Started 43m (x3 over 103m) kubelet Started container docker Normal Pulled 43m (x2 over 103m) kubelet Container image "docker:19.03" already present on machine d


DinD 環境はあっけなく完成しました。


【(IKS の) DinD 内の docker を操作する】
次に完成した DinD 環境を実際に CLI で使ってみます。そのためにまずは Docker クライアントが使える環境のシェルにアタッチする必要があります。Docker クライアントは docker という名前のコンテナで動いていることが分かっているので、以下のコマンドを実行します:
$ kubectl exec -it dind -c docker -- /bin/sh

/ #

プロンプトが "/ #" という記号に変わればアタッチ成功です。ここからは docker CLI コマンドが実行できます。試しに "docker version" コマンドを実行するとクライアント&サーバー双方の docker バージョン情報(下の例ではどちらも "19.03.15")を確認できます:
/ # docker version

Client: Docker Engine - Community
 Version:           19.03.15
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        99e3ed8
 Built:             Sat Jan 30 03:11:43 2021
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.15
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       99e3ed8
  Built:            Sat Jan 30 03:18:13 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.3.9
  GitCommit:        ea765aba0d05254012b0b9e595e995c09186427f
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683


実際にサーバーイメージをデプロイして動作確認してみましょう。というわけで、まずは nginx イメージを 8000 番ポートでデプロイしてみます:
/ # docker run -d --name ningx -p 8000:80 nginx

成功したら早速アクセスして動作確認を・・・と思ったのですが、この docker コンテナには HTTP クライアントが curl 含めてインストールされていないようでした。というわけで動作確認用のコマンドもインストールしておきます。とりあえず curl と w3m あたりでいいですかね。。:
/ # apk add --update curl

/ # apk add --update w3m

インストールが成功したら、まずは curl で http://localhost:8000/ にアクセスしてみます:
/ # curl http://localhost:8000/

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

うぉっ、と。少なくとも HTTP サーバーとして動いているらしいことは確認できたのですが、これだとちょっと見にくいですね。というわけで、先程一緒にインストールした w3m で確認してみます:
/ # w3m http://localhost:8000/

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

2022022101


かろうじて Nginx のトップ画面らしきものが確認できました。というわけで一応動いていると思います。


【まとめ】
というわけで DinD が IBM Cloud の 30 日無料版 Kubernetes クラスタ環境でも動かせることが確認できました。

とはいえ、もともとは Docker Desktop の代替になるような Docker 環境を探していたことに立ち返ると、この(クライアント側のような) CLI だけの Docker 環境はどうしても使い道が限られてしまうように感じます。ある程度、Docker を理解している人向けに、CLI だけで完結する使いみちであればなんとか、といったところでしょうか。


本当はここで作った Pod を外部に EXPOSE できるといいんですが、自分で試行錯誤している限りではまだうまく行ってません。もし方法をご存じの方がいらっしゃったら是非教えてください。


(2022/02/21 追記ここから)
試行錯誤の中で外部公開する方法がわかりました。

上述の "$ kubectl apply -f ..." コマンドを実行する箇所の内容を以下のように変更してください:
$ kubectl apply -f https://raw.githubusercontent.com/dotnsf/dind_iks/main/dind_expose.yml

なお、ここで指定している dind_expose.yml の内容は以下のようなものです。Pod を Deployment に書き換えた上で Service オブジェクトを追加して、8000 番ポートでの待受けを 30800 番ポートから転送するように(この後の作業で 8000 番ポートで待ち受けるアプリケーションをデプロイする想定で)あらかじめ公開しています:
apiVersion: v1
kind: Service
metadata:
  name: dind
spec:
  selector:
    app: dind
  ports:
  - port: 8000
    name: port8000
    protocol: TCP
    targetPort: 8000
    nodePort: 30800
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dind
spec:
  selector:
    matchLabels:
      app: dind
  replicas: 1
  template:
    metadata:
      labels:
        app: dind
    spec:
      containers:
        - name: docker
          image: docker:19.03
          command: ["docker", "run", "nginx:latest"]
          env:
            - name: DOCKER_HOST
              value: tcp://localhost:2375
        - name: dind-daemon
          image: docker:19.03-dind
          env:
            - name: DOCKER_TLS_CERTDIR
              value: ""
          resources:
            requests:
              cpu: 20m
              memory: 512Mi
          securityContext:
            privileged: true

このコマンドの後、"$ kubectl get all" を実行すると以下のような結果になります:
$ kubectl get all
NAME READY STATUS RESTARTS AGE pod/dind-7d8546bc8-fxbhw 2/2 Running 1 19s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/dind NodePort 172.21.8.233 8000:30800/TCP 21s service/kubernetes ClusterIP 172.21.0.1 443/TCP 3d10h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/dind 1/1 1 1 20s NAME DESIRED CURRENT READY AGE replicaset.apps/dind-7d8546bc8 1 1 1 21s

以前の方法では Pod 名は "dind" 固定だったのですが、ここでは "dind-" に続けてランダムな文字列が付与されています(上例では "dind-7d8546bc8-fxbhw" となっています)。この Pod 名を指定して以下を実行して docker コンテナのシェルに接続します:
$ kubectl exec -it dind-7d8546bc8-fxbhw -c docker -- /bin/sh

/ #

この後は以前の方法と同様にして docker コンテナ内で NGINX を 8000 番ポートで起動します:
/ # docker run -d --name ningx -p 8000:80 nginx

これで以前と同様に k8s のワーカーノード内で(NodePort サービスを使って) NGINX が 8000 番ポートで起動します。ただ今回は Service オブジェクトで 8000 番リクエストを 30800 番ポートで外部公開しているので、 http://(ワーカーノードのパブリックIPアドレス):30800/ にアクセスすればクラスタ外部からでもこの NGINX に接続できるようになっています。


ワーカーノードのパブリック IP アドレスは IBM Cloud の IKS 環境であれば、IBM Cloud ダッシュボード画面から確認することができます(この例では "169.51.206.71" となっています):
2022022102


というわけで、改めてウェブブラウザで http://169.51.206.71:30800/ にアクセスしてみると、、、期待通りの画面が表示されました! IBM Cloud の30日無料版 Kubernetes クラスタ環境で構築した DinD のコンテナを外部に公開することができることが確認できました:
2022022100


というわけで、30 日間無料の IBM Cloud Kubernetes 環境を使って、Docker および Kubernetes クラスタの実行環境を構築することができました。

(2022/02/21 追記ここまで)
 

昨年、ブログを使ってこのような夏休み企画(休んでないけど)を実施しました:
「30 日後に死ぬ k8s」


IBM Cloud から提供されている k8s 環境は(ワーカーノード1つなどの条件の下で)30 日間無料で使えます。この環境を使って 30 日間で毎日1つずつ、計 30 種類のコンテナをデプロイして動かす、というものでした。後に追加で動作確認できたり、動作確認はできなかったがデプロイできてるっぽいものもあったのですが、その際も IBM Db2 は公式イメージを docker で動かすことはできたのですが、この k8s 環境ではうまくデプロイできずにいました。

が、最近になって改めて挑戦し、今度は同環境で IBM Db2 コンテナを動かすことができました。Db2 クライアントからの接続も確認できました。以前できなくて今回できた理由ははっきりとはわかっていませんが、自分の腕が上がったのか、イメージ側の更新と関係があるのか、あるいはその両方か・・・ ともあれ、遅ればせながら IBM Db2 コンテナイメージを IBM Cloud の 30 日間無料 k8s クラスタにデプロイして動かす方法を紹介します。


【30 日間無料の k8s クラスタを用意】
こちらの記事を参照して、IBM Cloud の 30 日間無料 k8s クラスタをセットアップしてください。また具体的な操作をする際に必要な ibmcloud CLI や kubectl CLI といったコマンドツール類のインストール手順も含まれています(リンク先最後の "$ kubectl get all" コマンドが正しく実行できる状態にしてください):
http://dotnsf.blog.jp/archives/1079287640.html


なおリンク先でも触れられていますが、この k8s クラスタ環境はシングルワーカーノードです。イメージをデプロイした後に "type = NodePort" を指定することでサービスを公開できます(Ingress などが提供されていないため、他の方法でサービス公開はできません)。


【IBM Db2 コンテナイメージ】
公式な IBM Db2 コミュニティ版のコンテナイメージはこちらから無料で提供されています:
https://hub.docker.com/r/ibmcom/db2


同ページ内の説明文によると、この無料コミュニティ版コンテナイメージを動かす前提条件として、「CPU: 4コア以下、メモリ: 16GB 以下」が挙げられています:
2022011801


一方で IBM Cloud の 30 日間無料 k8s クラスタのワーカーノードは「CPU: 2 コア、メモリ: 4GB」であることがわかっています:
2022011802


一応、条件を満たした環境で使う、ということになります。なおコンテナイメージのリンク先情報によると、2022/01/18 時点で特にバージョンを指定せずにこのコンテナを利用しようとすると、最新版である v11.5.7.0 が使われるようです(以下の内容はこのバージョンで動作確認しています):
2022011803



【IBM Db2 を k8s にデプロイするための yaml ファイル】
色々試行錯誤してできあがった IBM Cloud の 30 日間無料 k8s クラスタにデプロイできるよう調整した yaml ファイルはこちらです:
https://github.com/dotnsf/yamls_for_iks/blob/main/db2_deployment_nodeport.yaml

このファイルを指定して、
$ kubectl apply -f https://raw.githubusercontent.com/dotnsf/yamls_for_iks/main/db2_deployment_nodeport.yaml

とすることでデプロイできます(その場合は db2inst1 ユーザーのパスワードは db2inst1 、サンプル(SAMPLE)データベースは作成、それとは別に db2inst1 ユーザーから使える mydb という空のデータベースも作成する、というオプションが初期設定されています)。

あるいは以下のように一度 wget コマンドでローカルにダウンロードしてから内容をカスタマイズして、その後に改めて kubectl コマンドでデプロイすることも可能です:
$ wget https://raw.githubusercontent.com/dotnsf/yamls_for_iks/main/db2_deployment_nodeport.yaml

(ダウンロードした db2_deployment_nodeport.yaml ファイルをカスタマイズ)

$ kubectl apply db2_deployment_nodeport.yaml


例えば db2inst1 ユーザーのパスワードを変えたい場合は 38 行目を変更、サンプルデータベースを作る必要がなければ 39, 40 行目を削除、mydb データベースもこの時点で作る必要がなければ 41, 42 行目を削除、といった具合です。

なお後者のカスタマイズをする場合に指定可能なオプション内容については公式ページ内"Advanced Configuration Options" 欄を参考に編集してください。

"kubectl get all" コマンドでデプロイ後のクラスタの様子を確認してみます:
$ kubectl get all

NAME                            READY   STATUS    RESTARTS   AGE
pod/db2-54ff649944-w7d24        1/1     Running   0          2d14h
pod/hostname-7b4f76fd59-c8b2l   1/1     Running   0          8d

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE
service/db2          NodePort    172.21.54.211           50000:30500/TCP   2d14h
service/hostname     NodePort    172.21.105.49           8080:30080/TCP    8d
service/kubernetes   ClusterIP   172.21.0.1              443/TCP           8d

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/db2        1/1     1            1           2d14h
deployment.apps/hostname   1/1     1            1           8d

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/db2-54ff649944        1         1         1       2d14h
replicaset.apps/hostname-7b4f76fd59   1         1         1       8d

↑のように Db2 関連の pod, service, deployment, replicaset が1つずつ追加されていればコマンドは成功しています。 また service を見ると 50000 番ポート(Db2 の標準動作ポート)が 30500 番で公開されていることも確認できます。つまり Db2 は
 (ワーカーノードのIPアドレス※):30500
で公開されて動いていることがわかります(※ワーカーノードの IP アドレス確認方法はこちらを参照してください)。


【動作確認】
では実際に Db2 サーバーが正しく動作していることを動作確認してます。。。 と、実はここが大きな問題でした。Db2 サーバーは正しくデプロイされて動作しているのですが、Db2 サーバーに接続試験を行おうとすると、その環境準備がちょっと面倒だったりするのです。

Db2 サーバーに CLI でアクセスしようとすると Db2 クライアントライブラリのダウンロード&インストールが必要です。Node.js などのプログラムから接続するにもクライアントライブラリが必要になります。この Db2 クライアントライブラリをインストールするには、無料版の Db2 Community Edition をダウンロードしてインストールする必要があり、ここで急にハードルが上がってしまいます。

そこでこれらの手間を省くために別の動作確認方法を考えました。それは「Db2 のコンテナインスタンスをもう1つ作って、そこからリモートサーバーにアクセスする」という方法です。マネージドサービスと異なり、Db2 サーバーのコンテナイメージからはライブラリセットアップ済みの CLI も使えるのです。そのための Db2 コンテナをもう1つ追加で作ってクライアントとして使うことで(手間という意味では)比較的容易に動作確認用クライアント環境が用意できると思いました。

というわけで、先程の yaml ファイルを少し変更(サンプルDB 作らず、mydb DBも作らず、ポート番号は 30501 に変更、コンテナの名称も db2 から db2cli に変更)した yaml ファイルを使って、(機能的にはサーバー機能もインストール済みですが)新しい Db2 クライアントコンテナを作成します:
$ kubectl apply -f https://raw.githubusercontent.com/dotnsf/yamls_for_iks/main/db2cli_deployment_nodeport.yaml

作成後にクラスタ内の様子を kubectl コマンドで確認すると、新しい db2cli インスタンスが起動しているはずです:
$ kubectl get all
NAME                            READY   STATUS    RESTARTS   AGE
pod/db2-54ff649944-w7d24        1/1     Running   0          2d14h
pod/db2cli-86d476659d-m7c6d     1/1     Running   0          9s
pod/hostname-7b4f76fd59-c8b2l   1/1     Running   0          8d

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE
service/db2          NodePort    172.21.54.211           50000:30500/TCP   2d14h
service/db2cli       NodePort    172.21.112.13           50000:30501/TCP   11s
service/hostname     NodePort    172.21.105.49           8080:30080/TCP    8d
service/kubernetes   ClusterIP   172.21.0.1              443/TCP           8d

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/db2        1/1     1            1           2d14h
deployment.apps/db2cli     1/1     1            1           11s
deployment.apps/hostname   1/1     1            1           8d

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/db2-54ff649944        1         1         1       2d14h
replicaset.apps/db2cli-86d476659d     1         1         1       11s
replicaset.apps/hostname-7b4f76fd59   1         1         1       8d

ここからは db2cli コンテナからの作業となります。まずは db2cli コンテナ上のシェルにログインする必要があります。まずは IBM Cloud の k8s サービスからダッシュボードにアクセスします:
2022011801


ダッシュボード画面左メニューから「ポッド」を選び、ポッド一覧から "db2cli" で始まる名前のポッドを探し、画面右のメニューから「実行」を選択します:
2022011802


これで該当 Pod のシェルをブラウザからリモート操作できるようになります:
2022011803


以下の手順で(最初に作った方の)Db2 サーバーに接続して SQL を実行する、という動作確認をします。

まずは Db2 を利用可能なユーザー(db2inst1)にスイッチします(プロンプトが # から $ へ切り替わります):
# su - db2inst1
$

次に Db2 コマンドをインタラクティブに実行できるシェルに切り替えます(プロンプトが $ から db2 => に切り替わります):
$ db2
db2 =>

この状態から Db2 サーバーに接続したり、ログインしたり、SQL を実行したりできます。まずは Db2 サーバーへの接続が必要です。Db2 ではリモートサーバーやデータベースを「カタログ」という単位で管理するので、まず最初にリモート Db21 サーバーを db2onk8s という名前でカタログに登録します。以下のコマンドを実行します(1.2.3.4 部分はワーカーノードの IP アドレスに置き換えてください):
db2 => catalog tcpip node db2onk8s remote 1.2.3.4 server 30500

次にこのサーバー上の SAMPLE データベースをカタログに登録します:
db2 => catalog database sample at node db2onk8s

これで Db2 クライアントから Db2 サーバー上の SAMPLE データベースに接続するためのカタログができました。

ではこのデータベースカタログを使って Db2 サーバー上の SAMPLE データベースに接続します。このコマンドを入力した後に db2inst1 ユーザーのパスワードを聞かれるので、Db2 サーバーのコンテナを作成した時に指定した db2inst1 ユーザーのパスワード(変更していない場合は db2inst1)を入力してください:
db2 => connect to sample user db2inst1
Enter current password for db2inst1:


正しいパスワードを入力すると目的のデータベースに接続します。この状態で Db2 クライアントから Db2 サーバーに接続しています:
db2 => connect to sample user db2inst1
Enter current password for db2inst1:

   Database Connection Information

 Database server        = DB2/LINUXX8664 11.5.7.0
 SQL authorization ID   = DB2INST1
 Local database alias   = SAMPLE

db2 => 

SQL を使って Db2 サーバーの SAMPLE データベースのテーブルからレコードを取り出したり、追加・変更・削除といった操作が可能です:
db2 => select * from employee;

EMPNO  FIRSTNME     MIDINIT LASTNAME        WORKDEPT PHONENO HIREDATE   JOB      EDLEVEL SEX BIRTHDATE  SALARY      BONUS       COMM       
------ ------------ ------- --------------- -------- ------- ---------- -------- ------- --- ---------- ----------- ----------- -----------
000010 CHRISTINE    I       HAAS            A00      3978    01/01/1995 PRES          18 F   08/24/1963   152750.00     1000.00     4220.00
000020 MICHAEL      L       THOMPSON        B01      3476    10/10/2003 MANAGER       18 M   02/02/1978    94250.00      800.00     3300.00
000030 SALLY        A       KWAN            C01      4738    04/05/2005 MANAGER       20 F   05/11/1971    98250.00      800.00     3060.00
000050 JOHN         B       GEYER           E01      6789    08/17/1979 MANAGER       16 M   09/15/1955    80175.00      800.00     3214.00
000060 IRVING       F       STERN           D11      6423    09/14/2003 MANAGER       16 M   07/07/1975    72250.00      500.00     2580.00
000070 EVA          D       PULASKI         D21      7831    09/30/2005 MANAGER       16 F   05/26/2003    96170.00      700.00     2893.00
000090 EILEEN       W       HENDERSON       E11      5498    08/15/2000 MANAGER       16 F   05/15/1971    89750.00      600.00     2380.00
000100 THEODORE     Q       SPENSER         E21      0972    06/19/2000 MANAGER       14 M   12/18/1980    86150.00      500.00     2092.00
000110 VINCENZO     G       LUCCHESSI       A00      3490    05/16/1988 SALESREP      19 M   11/05/1959    66500.00      900.00     3720.00
000120 SEAN                 O'CONNELL       A00      2167    12/05/1993 CLERK         14 M   10/18/1972    49250.00      600.00     2340.00
000130 DELORES      M       QUINTANA        C01      4578    07/28/2001 ANALYST       16 F   09/15/1955    73800.00      500.00     1904.00
000140 HEATHER      A       NICHOLLS        C01      1793    12/15/2006 ANALYST       18 F   01/19/1976    68420.00      600.00     2274.00
000150 BRUCE                ADAMSON         D11      4510    02/12/2002 DESIGNER      16 M   05/17/1977    55280.00      500.00     2022.00
000160 ELIZABETH    R       PIANKA          D11      3782    10/11/2006 DESIGNER      17 F   04/12/1980    62250.00      400.00     1780.00
000170 MASATOSHI    J       YOSHIMURA       D11      2890    09/15/1999 DESIGNER      16 M   01/05/1981    44680.00      500.00     1974.00
000180 MARILYN      S       SCOUTTEN        D11      1682    07/07/2003 DESIGNER      17 F   02/21/1979    51340.00      500.00     1707.00
000190 JAMES        H       WALKER          D11      2986    07/26/2004 DESIGNER      16 M   06/25/1982    50450.00      400.00     1636.00
000200 DAVID                BROWN           D11      4501    03/03/2002 DESIGNER      16 M   05/29/1971    57740.00      600.00     2217.00
000210 WILLIAM      T       JONES           D11      0942    04/11/1998 DESIGNER      17 M   02/23/2003    68270.00      400.00     1462.00
000220 JENNIFER     K       LUTZ            D11      0672    08/29/1998 DESIGNER      18 F   03/19/1978    49840.00      600.00     2387.00
000230 JAMES        J       JEFFERSON       D21      2094    11/21/1996 CLERK         14 M   05/30/1980    42180.00      400.00     1774.00
000240 SALVATORE    M       MARINO          D21      3780    12/05/2004 CLERK         17 M   03/31/2002    48760.00      600.00     2301.00
000250 DANIEL       S       SMITH           D21      0961    10/30/1999 CLERK         15 M   11/12/1969    49180.00      400.00     1534.00
000260 SYBIL        P       JOHNSON         D21      8953    09/11/2005 CLERK         16 F   10/05/1976    47250.00      300.00     1380.00
000270 MARIA        L       PEREZ           D21      9001    09/30/2006 CLERK         15 F   05/26/2003    37380.00      500.00     2190.00
000280 ETHEL        R       SCHNEIDER       E11      8997    03/24/1997 OPERATOR      17 F   03/28/1976    36250.00      500.00     2100.00
000290 JOHN         R       PARKER          E11      4502    05/30/2006 OPERATOR      12 M   07/09/1985    35340.00      300.00     1227.00
000300 PHILIP       X       SMITH           E11      2095    06/19/2002 OPERATOR      14 M   10/27/1976    37750.00      400.00     1420.00
000310 MAUDE        F       SETRIGHT        E11      3332    09/12/1994 OPERATOR      12 F   04/21/1961    35900.00      300.00     1272.00
000320 RAMLAL       V       MEHTA           E21      9990    07/07/1995 FIELDREP      16 M   08/11/1962    39950.00      400.00     1596.00
000330 WING                 LEE             E21      2103    02/23/2006 FIELDREP      14 M   07/18/1971    45370.00      500.00     2030.00
000340 JASON        R       GOUNOT          E21      5698    05/05/1977 FIELDREP      16 M   05/17/1956    43840.00      500.00     1907.00
200010 DIAN         J       HEMMINGER       A00      3978    01/01/1995 SALESREP      18 F   08/14/1973    46500.00     1000.00     4220.00
200120 GREG                 ORLANDO         A00      2167    05/05/2002 CLERK         14 M   10/18/1972    39250.00      600.00     2340.00
200140 KIM          N       NATZ            C01      1793    12/15/2006 ANALYST       18 F   01/19/1976    68420.00      600.00     2274.00
200170 KIYOSHI              YAMAMOTO        D11      2890    09/15/2005 DESIGNER      16 M   01/05/1981    64680.00      500.00     1974.00
200220 REBA         K       JOHN            D11      0672    08/29/2005 DESIGNER      18 F   03/19/1978    69840.00      600.00     2387.00
200240 ROBERT       M       MONTEVERDE      D21      3780    12/05/2004 CLERK         17 M   03/31/1984    37760.00      600.00     2301.00
200280 EILEEN       R       SCHWARTZ        E11      8997    03/24/1997 OPERATOR      17 F   03/28/1966    46250.00      500.00     2100.00
200310 MICHELLE     F       SPRINGER        E11      3332    09/12/1994 OPERATOR      12 F   04/21/1961    35900.00      300.00     1272.00
200330 HELENA               WONG            E21      2103    02/23/2006 FIELDREP      14 F   07/18/1971    35370.00      500.00     2030.00
200340 ROY          R       ALONZO          E21      5698    07/05/1997 FIELDREP      16 M   05/17/1956    31840.00      500.00     1907.00

  42 record(s) selected.


この時点で k8s ダッシュボード画面はこのようになっています。必要に応じて続けてコマンドを実行することもできます:
2022011800


操作を終了して接続を切るには quit コマンドを実行します:
db2 => quit

$ exit

# 


改めて k8s 上にデプロイした Db2 サーバーコンテナ(とクライアントコンテナ)が期待通りに動いていることが確認できました。


IBM Cloud から提供されている 30 日間無料 Kubernetes サービスIBM Kubernetes Service 、以下 "IKS")環境を使って利用することのできるコンテナイメージを1日に1個ずつ 30 日間連続で紹介してきました。

最終日というかおまけとして、31 日目は実際にこれらのイメージをデプロイしてきたの感想を含めたあとがきを記していきます。


【率直な感想】
改めてこの 30 日間を振り返ります。これだけの環境を作ってきました:

Dayカテゴリーデプロイ内容
0準備準備作業
1ウェブサーバーhostname
2Apache HTTP
3Nginx
4Tomcat
5Websphere Liberty
6データベースMySQL
7phpMyAdmin
8PostgreSQL
9pgAdmin4
10MongoDB
11Mongo-Express
12Redis
13RedisCommander
14ElasticSearch
15Kibana
16CouchDB
17CouchBase
18HATOYA
19プログラミングNode-RED
20Scratch
21Eclipse Orion
22Swagger Editor
23R Studio
24Jenkins
25アプリケーションFX
262048
27DOS Box
28VNC Server(Lubuntu)
29Drupal
30WordPress



自分はプログラマーなので、プログラマー視点というか開発者視点で客観的にこの表を見てまず思うのは、自分が開発環境として使いそうなデータベースやツール、ミドルウェア類は一通り揃っているという事実です。もちろん自分の PC にこの環境を用意することはできるし、ローカルだけで開発環境が整うのはそれはそれでメリットもあるわけですが、一方で無料のリモート環境にこれだけのツール類を揃えて使うことができるというのは充分すぎるというか、「使う予定はないかもしれないけど、この環境を使うならおまけに R Studio も入れちゃおうかな」とか、「念の為 IaaS 的な環境も」とか、「ちょっと気分転換にゲームを」とか余裕で考えるくらいの環境が用意できる、そんな太っ腹な無料サービスだと改めて感じました。

また単なる開発環境である以上に、コンテナや k8s の運用を勉強するための環境としてもかなり使えると感じています。Day 1 で紹介したようなレプリカセットを変更した上で挙動の変化を確認したり、Day 24 では k8s の管理ダッシュボードを使ってポッドの中でシェルを動かしたり、Day 29Day 30 では複数のコンテナを通信させて動く環境を作る、といったことも体験できました。普段データベースは使っているけど、データの解析はしたことがない人でも解析環境まで入手できるようになる、このような、実際に外部から利用可能な形で公開して体験できる形の環境が無料で提供されているという点を改めて素晴らしいと感じています。


【この環境の制約事項について】
もちろん制約事項を感じることもありました。この契約では k8s の Ingress が使えないためサービスは NodePort 公開しかできない(ワーカーノードの IP アドレスでしか公開できない)、そのためコンテナ側に SSL を使った公開方法が考慮されていてもこの環境では使えない、、といった制約を何度か経験することになりました。まあここは開発環境と割り切って使う中ではあまり気にならないとも言えますけど、外部連携時に SSL 接続を前提としているケースがあったり、(IP アドレスではなく)ドメイン名やホスト名を使う前提のサービスと連携するケースがあったりすると、そこで制約を受けることになる点が注意が必要だと思いました。

加えて、今回は 30 日間で紹介するサービスを上述の 30 種類にしていますが、実はこの中に含めたくて諦めたサービスもいくつかあります。それらの多くはこの無料環境でデプロイして使うのは難しい※と判断したものばかりでした。

※自分の誤解に基づくものや、うまく回避する方法を知らなかっただけというものも含まれているかもしれません。ただ今回の企画の時間的な意味も含めた制約の中では「難しい」と諦めざるを得なかった、という意味です。

理由としてもったいなかったのは「デプロイはできたようだが、確認する方法(専用クライアント)がない」というケースでした。超軽量データベースである Apache Derby などはその例で、IKS へのデプロイ自体は成功していたように見えているのですが、動作を確認するにはアプリケーションを作る必要があって、そこまで作業するのが時間制約的に困難だったというケースです。curl やウェブブラウザで動作確認ができず、動作確認用クライアントを作る必要がある、というパターンのは今回は諦めました。

この動作確認用クライアントが存在しない以外の理由が原因となったケースもあります。その1つを紹介すると IBM Db2 コンテナがあります。本環境で IBM Db2 コンテナを使うのが難しそうだと判断した理由は少し特殊な環境設定にありました。

IBM Db2 はデフォルトで 50000 番ポートを使って通信します。ポート番号自体はコンテナ公開時にポートフォワーディングで変更することもできるのですが、IBM Db2 の場合は /etc/services ファイル内にこのポート番号を指定するための設定を加える必要がありました。コンテナで動かす場合は、コンテナイメージ内のこの設定を変更して(かつこの変更が消えないようにして)再起動するか、設定を変更せず 50000 番ポートで公開するか、いずれかの方法が必要となります。

コンテナの紹介ページでは docker コマンドによるデプロイ方法が紹介されていました。docker であれば EXPOSE するポート番号を自由に指定できるのですが、今回は NodePort を使った公開しかできない k8s 環境、という制約があります。また今回は無料の範囲内で(ボリュームを使わずに)紹介するという目的もありました。この制約の中で色々な方法を試したのですが、結局うまく公開することができず、今回は 30 個の中から除外する、という判断をするに至った、という背景を記載しておきます。

ここに記載するのもどうかと思ったのですが、もしかすると詳しい人が引き継いでくれることを期待して、自分が(ちょっと)試してみた限りでは難しそうだと判断して諦めたコンテナイメージのリストを掲載しておきます。本当はこれらを 30 個に加えたかったのだけど、そもそも自分が普段使っているわけではないものもあったりして、設定そのものにあまり詳しくなかったりするものが大半です。もし 30 日無料版 IKS 環境で動かすことができたら教えてください(笑):

コンテナイメージあきらめた理由
Cassandra デプロイはできたが、稼働中にポッドが Pending 状態になる
CockroachDB デプロイ時に CrashLoopBackOff エラー
Apache Derby デプロイはできているっぽいが、動作確認ができていない
GitLab デプロイはできたが、稼働中にポッドが Pending 状態になる(HTTPS 必須で HTTP 接続不可?)
IBM Db2 50000 番ポートでのサービス公開が NodePort の範囲外だった
MediaWiki デプロイはできたが、稼働中に大量の deprecated メッセージ
Memcached デプロイはできたように見えたが、接続時にエラー
Minix デプロイはできたが、Minix のシェルにログインできない・・・と思っていたが、後から方法がわかりました(k8s のポッドにコンソールログインしてから "# ssh localhost")。これを 30 個に含めてもよかったかも。
Mosquitto デプロイはできているっぽいが、動作確認ができていない
phpMoAdmin デプロイはできているっぽいが、MongoDB に接続できない(docker 環境でしか動かないコンテナイメージ?)
Container Registry デプロイはできているっぽいが、動作確認ができていない(HTTPS 必須で HTTP 接続不可?)
SAMBA デプロイはできたように見えたが、接続時にエラー
Ubuntu デプロイ時に CrashLoopBackOff エラー


Minix イメージについては幻の 31 日目のイメージとして加えさせていただきます(笑)。


上述の IBM Db2 もそうだったのですが、コンテナ内のファイルを編集して再起動、を前提とするようなコンテナイメージや、そもそも動作に必要なスペックが高すぎるものは諦めました。自分の場合はあくまで開発環境という意味での「とりあえず動いて外部から利用できることが重要」という視点で見ていたので、上記 30 個のリストの中にもしかすると使っているうちに別の制約を受けることになる可能性は否定できません。


【最後に】
改めて書きますが、これだけの開発環境が連続して 30 日間無料で使えるというのはやはり魅力です。自分が業務や個人で作っているアプリケーションを作る際の環境と比較しても、ほぼ支障を感じることがありませんし、制約事項で挙げたサービスについても他の方法で無料で入手することができるものばかりと考えると、アプリケーション開発者にとっては無料で勉強も利用もできる環境がかなり広くなったと改めて感慨にふけることができるようになりました。

余談ですが、IBM Cloud にはこの 30 日無料版 k8s クラスタ環境以外にも、無料枠内で(期間制限なしで)使える多くのサービスが用意されています。この k8s 環境を通じて、興味が湧いたらぜひこちらも試していただきたいです。これは私自身の感想ですが、マネージドサービスで使えるデータベースは本当に便利です。

本 k8s 環境をできるだけ多くの人に知ってもらって、使ってみていただければと思っています。


最後に 30 日間の利用環境が残り1時間になった時の記念写真。1か月ありがとうございました。
mycluster1

mycluster2




IBM Cloud から提供されている 30 日間無料 Kubernetes サービスIBM Kubernetes Service 、以下 "IKS")環境を使って利用することのできるコンテナイメージを1日に1個ずつ 30 日間連続で紹介していきます。

環境のセットアップや制約事項については Day0 のこちらの記事を参照してください。

Day 25 からはアプリケーション系コンテナとその GUI ツールを中心に紹介してます。最終日である Day 30 は集大成として世の中の大半のウェブコンテンツを管理していると思われる WordPress イメージをデプロイする例を紹介します。
wp0


【イメージの概要】
ブログなどのウェブコンテンツを管理・編集・公開するシステムです。

個人的にも WordPress には思い入れがあります。業務とは関係のないところで WordPress を知って、勉強して、そこから自分のキャリアが変わるきっかけにもなりました。今の自分が今の立場でいるのは WordPress との関わりがあったからだと思っています。そんな背景もあって 30 日間連続ブログの最終日に紹介するコンテンツとさせていただきました。

WordPress の動作時にはデータベースが必要なのですが、今回は MySQL を使う方法を紹介します。MySQL 単体のデプロイについては Day 6 でも紹介しているので、必要に応じて参照してください。


【イメージのデプロイ】
まずはこれら2つのファイルを自分の PC にダウンロードしてください:
https://raw.githubusercontent.com/dotnsf/yamls_for_iks/main/mysql.yaml
https://raw.githubusercontent.com/dotnsf/yamls_for_iks/main/wordpress.yaml

前者が MySQL 用、後者が WordPress 用のデプロイファイルです(両方使います)。
前者の MySQL 用デプロイファイルは Day 6 で行ったものと同様の編集が必要です。mysql.yaml ファイルをテキストエディタで開いて、 "MYSQL_" で始まる4箇所の env.name の value 値を変更してください。それぞれの具体的な意味は以下の通りです(初期値として指定されている値のまま動かすことも可能ですが、安全のためなるべく変更してください):
・MYSQL_ROOT_PASSWORD : 管理者パスワード(初期値 P@ssw0rd)
・MYSQL_DATABASE : デプロイと同時に作成するデータベースの名前(初期値 mydb)
・MYSQL_USER : デプロイと同時に作成するデータベースを利用するユーザー名(初期値 user1)
・MYSQL_PASSWORD : デプロイと同時に作成するデータベースを利用するパスワード(初期値 password1)

また後者の WordPress 用デプロイファイルには4箇所の変種が必要です。wordpress.yaml ファイルをテキストエディタで開いて、 "WORDPRESS_" で始まる4箇所の env.name の value 値を変更してください。それぞれの具体的な意味は以下の通りです。特に WORDPRESS_DB_HOST の値は後述する IP アドレスと上述の MySQL に設定した値を両方参照して入力する必要がある点に注意ください:
・WORDPRESS_DB_HOST : MySQL のホスト名とポート番号(初期値 xxx.xxx.xxx.xxx:30306)
・WORDPRESS_DB_USER : MySQL に接続するユーザー名(初期値 user1)
・WORDPRESS_DB_PASSWORD : MySQL に接続するパスワード(初期値 password1)
・WORDPRESS_DB_NAME : MySQL の DB 名(初期値 mydb)

ではこのダウンロード&編集した2つの yaml ファイルを指定してデプロイします。以下のコマンドを実行する前に Day 0 の内容を参照して ibmcloud CLI ツールで IBM Cloud にログインし、クラスタに接続するまでを済ませておいてください。

そして以下のコマンドを実行します:
$ kubectl apply -f mysql.yaml

$ kubectl apply -f wordpress.yaml

以下のコマンドで MySQL 関連の Deployment, Service, Pod, Replicaset が1つずつ生成されたことと、サービスが 30306 番ポートで公開されていること、そして WordPress 関連も同様に Deployment, Service, Pod, Replicaset が1つずつ生成され、サービスが 30080 番ポートで公開されていることを確認します:
$ kubectl get all

NAME                            READY   STATUS    RESTARTS   AGE
pod/mysql-5bd77967b-z9lcl       1/1     Running   0          104s
pod/wordpress-67848cd6b-296kh   1/1     Running   0          62s

NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/kubernetes    ClusterIP   172.21.0.1       <none>        443/TCP          27d
service/mysqlserver   NodePort    172.21.89.71     <none>        3306:30306/TCP   105s
service/wordpress     NodePort    172.21.140.192   <none>        80:30080/TCP     63s

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mysql       1/1     1            1           106s
deployment.apps/wordpress   1/1     1            1           64s

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/mysql-5bd77967b       1         1         1       106s
replicaset.apps/wordpress-67848cd6b   1         1         1       64s

この後に実際にサービスを利用するため、以下のコマンドでワーカーノードのパブリック IP アドレスを確認します(以下の例であれば 161.51.204.190):
$ ibmcloud ks worker ls --cluster=mycluster-free
OK
ID                                                       パブリック IP    プライベート IP   フレーバー   状態     状況    ゾーン   バージョン
kube-c3biujbf074rs3rl76t0-myclusterfr-default-000000df   169.51.204.190   10.144.185.144    free         normal   Ready   mil01    1.20.7_1543*

つまりこの時点で(上述の結果であれば)アプリケーションは http://169.51.204.190:30080/ で稼働している、ということになります。ウェブブラウザを使って、アプリケーションの URL(上述の方法で確認した URL)にアクセスしてみます:
wp1


WordPress をインストールしたことがある人にはお馴染みの初期セットアップ画面が表示されます。とりあえず無事に IKS 内で WordPress が稼働できているようです。

Drupal の時とは異なり、データベース接続情報などはデプロイ時に既に指定しているので、サイトの情報を入力するだけで使えるようになります:
wp2


セットアップが無事に成功しました。あとはセットアップ時に指定したユーザー&パスワードでログインすれば管理画面にアクセスできるようになります:
wp3


WordPress のコンテンツ管理画面にアクセスできました。IKS 内で WordPress を起動できました:
wp4


 Drupal の時と同様ですが、コンテンツフォルダを共有していないので、インスタンス数を2以上に増やして使うことはできませんが、とりあえず WordPress が動く環境を作ることができました。


【YAML ファイルの解説】
WordPress の YAML ファイルはこちらを使っています(MySQL の YAML ファイルについては Day 6 参照):
apiVersion: v1
kind: Service
metadata:
  name: wordpress
spec:
  selector:
    app: wordpress
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30080
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
      - name: wordpress
        image: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: "xxx.xxx.xxx.xxx:30306"
        - name: WORDPRESS_DB_USER
          value: "user1"
        - name: WORDPRESS_DB_PASSWORD
          value: "password1"
        - name: WORDPRESS_DB_NAME
          value: "mydb"
        ports:
        - containerPort: 80

Deployment 1つと、Service 1つ、環境変数の指定も不要で本シリーズで紹介する 30 個の中でも指折りにシンプルな YAML ファイルです。一応解説を加えておきます。アプリケーションそのものは 80 番ポートで動作するように作られているため、NodePort 30080 番を指定して、外部からは 30080 番ポートでアクセスできるようにしています(NodePort として指定可能な番号の範囲は 30000 ~ 32767 です、指定しない場合は空いている番号がランダムに割り振られます)。また ReplicaSet は1つだけで作りました。


デプロイしたコンテナイメージを削除する場合はデプロイ時に使った YAML ファイルを再度使って、以下のコマンドを実行します。不要であれば削除しておきましょう:
$ kubectl delete -f wordpress.yaml

$ kubectl delete -f mysql.yaml


【紹介したイメージ】
https://hub.docker.com/_/wordpress


【紹介記録】
ついに 30 日間 30 イメージ紹介を達成しました!

Dayカテゴリーデプロイ内容
0準備準備作業
1ウェブサーバーhostname
2Apache HTTP
3Nginx
4Tomcat
5Websphere Liberty
6データベースMySQL
7phpMyAdmin
8PostgreSQL
9pgAdmin4
10MongoDB
11Mongo-Express
12Redis
13RedisCommander
14ElasticSearch
15Kibana
16CouchDB
17CouchBase
18HATOYA
19プログラミングNode-RED
20Scratch
21Eclipse Orion
22Swagger Editor
23R Studio
24Jenkins
25アプリケーションFX
262048
27DOS Box
28VNC Server(Lubuntu)
29Drupal
30WordPress

IBM Cloud から提供されている 30 日間無料 Kubernetes サービスIBM Kubernetes Service 、以下 "IKS")環境を使って利用することのできるコンテナイメージを1日に1個ずつ 30 日間連続で紹介していきます。

環境のセットアップや制約事項については Day0 のこちらの記事を参照してください。

Day 25 からはアプリケーション系コンテナとその GUI ツールを中心に紹介してます。残り2日となった Day 29 はウェブコンテンツ管理システムの1つ Drupal イメージをデプロイする例を紹介します。


【イメージの概要】
ブログなどのウェブコンテンツを管理・編集・公開するシステムです。

Drupal の動作時にはデータベースが必要なのですが、今回は MySQL を使う方法を紹介します。MySQL 単体のデプロイについては Day 6 でも紹介しているので、必要に応じて参照してください。


【イメージのデプロイ】
まずはこれら2つのファイルを自分の PC にダウンロードしてください:
https://raw.githubusercontent.com/dotnsf/yamls_for_iks/main/mysql.yaml
https://raw.githubusercontent.com/dotnsf/yamls_for_iks/main/drupal.yaml

前者が MySQL 用、後者が Drupal 用のデプロイファイルです(両方使います)。後者の Drupal 用デプロイファイルは編集不要ですが、前者の MySQL 用デプロイファイルは Day 6 で行ったものと同様の編集が必要です。mysql.yaml ファイルをテキストエディタで開いて、 "MYSQL_" で始まる4箇所の env.name の value 値を変更してください。それぞれの具体的な意味は以下の通りです(初期値として指定されている値のまま動かすことも可能ですが、安全のためなるべく変更してください):
・MYSQL_ROOT_PASSWORD : 管理者パスワード(初期値 P@ssw0rd)
・MYSQL_DATABASE : デプロイと同時に作成するデータベースの名前(初期値 mydb)
・MYSQL_USER : デプロイと同時に作成するデータベースを利用するユーザー名(初期値 user1)
・MYSQL_PASSWORD : デプロイと同時に作成するデータベースを利用するパスワード(初期値 password1)

ではこのダウンロード&編集した2つの yaml ファイルを指定してデプロイします。以下のコマンドを実行する前に Day 0 の内容を参照して ibmcloud CLI ツールで IBM Cloud にログインし、クラスタに接続するまでを済ませておいてください。

そして以下のコマンドを実行します:
$ kubectl apply -f mysql.yaml

$ kubectl apply -f drupal.yaml

以下のコマンドで MySQL 関連の Deployment, Service, Pod, Replicaset が1つずつ生成されたことと、サービスが 30306 番ポートで公開されていること、そして Drupal 関連も同様に Deployment, Service, Pod, Replicaset が1つずつ生成され、サービスが 30080 番ポートで公開されていることを確認します:
$ kubectl get all

NAME                          READY   STATUS    RESTARTS   AGE
pod/drupal-5dcb945df7-rwqxc   1/1     Running   0          57s
pod/mysql-5bd77967b-2mhxl     1/1     Running   0          74s

NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/drupal        NodePort    172.21.92.228   <none>        80:30080/TCP     58s
service/kubernetes    ClusterIP   172.21.0.1      <none>        443/TCP          27d
service/mysqlserver   NodePort    172.21.111.48   <none>        3306:30306/TCP   75s

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/drupal   1/1     1            1           59s
deployment.apps/mysql    1/1     1            1           76s

NAME                                DESIRED   CURRENT   READY   AGE
replicaset.apps/drupal-5dcb945df7   1         1         1       59s
replicaset.apps/mysql-5bd77967b     1         1         1       76s

この後に実際にサービスを利用するため、以下のコマンドでワーカーノードのパブリック IP アドレスを確認します(以下の例であれば 161.51.204.190):
$ ibmcloud ks worker ls --cluster=mycluster-free
OK
ID                                                       パブリック IP    プライベート IP   フレーバー   状態     状況    ゾーン   バージョン
kube-c3biujbf074rs3rl76t0-myclusterfr-default-000000df   169.51.204.190   10.144.185.144    free         normal   Ready   mil01    1.20.7_1543*

つまりこの時点で(上述の結果であれば)アプリケーションは http://169.51.204.190:30080/ で稼働している、ということになります。ウェブブラウザを使って、アプリケーションの URL(上述の方法で確認した URL)にアクセスしてみます:
drupal1


無事に Drupal の初期設定画面が表示されました。とりあえず IKS 上で(MySQL と)Drupal が起動できているようです。あとは今回の環境向けの設定をするだけです。

基本は普通に進めていけばいいのですが注意点はデータベース構成部分です。今回の環境用に用意した MySQL に接続するので mysql.yaml で設定した内容を入力する必要がある点に注意してください。高度なオプションを有効にして、ポート番号も 30306 を指定する必要があります:
drupal2


あとはそのまま進めていって・・・
drupal3


最後にサイトの環境情報を入力して保存すれば準備完了です:
drupal4


無事に IKS 内に MySQL + Drupal 環境を作ることができました:
drupal5


コンテンツフォルダを共有していないので、インスタンス数を2以上に増やして使うことはできませんが、とりあえず Drupal が動く環境を作ることができました。

【YAML ファイルの解説】
Drupal の YAML ファイルはこちらを使っています(MySQL の YAML ファイルについては Day 6 参照):
apiVersion: v1
kind: Service
metadata:
  name: drupal
spec:
  selector:
    app: drupal
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30080
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: drupal
spec:
  replicas: 1
  selector:
    matchLabels:
      app: drupal
  template:
    metadata:
      labels:
        app: drupal
    spec:
      containers:
      - name: drupal
        image: drupal
        ports:
        - containerPort: 80

Deployment 1つと、Service 1つのシンプルな YAML ファイルです。一応解説を加えておきます。アプリケーションそのものは 80 番ポートで動作するように作られているため、NodePort 30080 番を指定して、外部からは 30080 番ポートでアクセスできるようにしています(NodePort として指定可能な番号の範囲は 30000 ~ 32767 です、指定しない場合は空いている番号がランダムに割り振られます)。また ReplicaSet は1つだけで作りました。


デプロイしたコンテナイメージを削除する場合はデプロイ時に使った YAML ファイルを再度使って、以下のコマンドを実行します。不要であれば削除しておきましょう:
$ kubectl delete -f drupal.yaml

$ kubectl delete -f mysql.yaml


【紹介したイメージ】
https://hub.docker.com/_/drupal


【紹介記録】

Dayカテゴリーデプロイ内容
0準備準備作業
1ウェブサーバーhostname
2Apache HTTP
3Nginx
4Tomcat
5Websphere Liberty
6データベースMySQL
7phpMyAdmin
8PostgreSQL
9pgAdmin4
10MongoDB
11Mongo-Express
12Redis
13RedisCommander
14ElasticSearch
15Kibana
16CouchDB
17CouchBase
18HATOYA
19プログラミングNode-RED
20Scratch
21Eclipse Orion
22Swagger Editor
23R Studio
24Jenkins
25アプリケーションFX
262048
27DOS Box
28VNC Server(Lubuntu)
29Drupal
30WordPress

このページのトップヘ