2019.08.09
tel 一般

Windowsでk8sを使って開発をしてみた

すっかり暑くなってしまいましたね(季節の挨拶)

前回ものは試しということで、自分のWindows10Pro上でDocker for Windows をインストールし、k8sを有効化して、apacheのコンテナを起動させてみました。

あれから半年以上の時間が経ち、とりあえずやっつけ部分もありつつもWEBアプリの開発環境を自分のPC内のk8s環境に構築をしたので、それについて今回は書いていこうと思います。

環境を作ったWEBアプリのざっくりした仕様

今回、ローカルk8s上に構築した開発環境で作成しているWEBアプリは、以下の機能を持っています。

  • ApacheでPHPのアプリが動いている
  • データはMySQLで管理している
  • 別のサーバとして、RESTアクセスによってファイル生成をするサーバが存在している
  • WEBページとは別にPHPのバッチ処理が動いている
  • バッチ処理ではFTPでファイルの転送を行っている
  • ファイル転送先のFTPサーバは複数あり、ファイルを置くまでがお仕事

物理的なサーバで考えると、

  • WEB + バッチ + DBサーバ
  • コンテンツ生成サーバ
  • FTP転送先サーバがN台

というくらいの規模です。

Service、Podなどの構成

構成は

  • LoadBarancer + WEB用Pod
  • LoadBarancer + DB用Pod
  • LoadBarancer + FTP用Pod
  • DB接続パスワード用Secret
  • Job用Pod

の単純な構成です。

それぞれのYAMLは大体こんな感じにしています。

WEB

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-web
  template:
    metadata:
      labels:
        app: app-web
    spec:
      containers:
        - name: apache-container
          image: local/apache-php72
          imagePullPolicy: Never
          volumeMounts:
            - mountPath: /var/www/html
              name: host-html
            - mountPath: /var/log/apache2
              name: host-log
            - mountPath: /etc/apache2/sites-available
              name: host-conf
          ports:
          - containerPort: 80
          env:
            - name: TZ
              value: Asia/Tokyo
            - name: DB_NAME
              value: hogehoge
            - name: DB_USER
              valueFrom:
                secretKeyRef:
                  name: secret-db
                  key: username
            - name: DB_PASS
              valueFrom:
                secretKeyRef:
                  name: secret-db
                  key: password
          resources:
            limits:
              cpu: 200m
              memory: 256Mi
      volumes:
        - name: host-html
          hostPath:
            path: /C/src
            type: Directory
        - name: host-log
          hostPath:
            path: /C/mount/var/log/apache2
            type: Directory
        - name: host-conf
          hostPath:
            path: /C/mount/etc/apache2/sites-available
            type: Directory
---
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-web
spec:
  type: LoadBalancer
  ports:
    - name: "http-port"
      protocol: "TCP"
      port: 80
      targetPort: 80
  selector:
    app: app-web

DB

apiVersion: apps/v1
kind: Deployment
metadata:
  name: db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-db
  template:
    metadata:
      labels:
        app: app-db
    spec:
      containers:
        - name: db-container
          image: local/mysql57-nosqlmode:latest
          imagePullPolicy: Never
          volumeMounts:
            - mountPath: /var/lib/mysql
              name: host-db
          ports:
          - containerPort: 3306
          env:
            - name: TZ
              value: Asia/Tokyo
            - name: MYSQL_DATABASE
              value: hogehoge
            - name: MYSQL_USER
              valueFrom:
                secretKeyRef:
                  name: secret-db
                  key: username
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: secret-db
                  key: password
          resources:
            limits:
              cpu: 200m
              memory: 256Mi
      volumes:
        - name: host-db
          hostPath:
            path: /C/mount/var/lib/mysql
            type: Directory
---
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-database
spec:
  type: LoadBalancer
  ports:
    - name: "mysql-port"
      protocol: "TCP"
      port: 3306
      targetPort: 3306
  selector:
    app: app-db

FTP

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ftp-data
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-ftp-data
  template:
    metadata:
      labels:
        app: app-ftp-data
    spec:
      containers:
        - name: ftp-data-container
          image: local/ftp:latest
          imagePullPolicy: Never
          volumeMounts:
            - mountPath: /home/ftp_user/
              name: hostpass
          ports:
          - containerPort: 21
          resources:
            limits:
              cpu: 200m
              memory: 256Mi
      volumes:
        - name: hostpass
          hostPath:
            path: /C/mount/home/ftp_user/data
            type: Directory
---
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-ftp
spec:
  type: LoadBalancer
  ports:
    - name: "ftp-port"
      protocol: "TCP"
      port: 21
      targetPort: 21
  selector:
    app: app-ftp-data

バッチ用のJOB

apiVersion: batch/v1
kind: Job
metadata:
  name: job-cast
spec:
  backoffLimit: 0
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: job-cast
        image: local/php72
        command: ["/usr/local/bin/php", "/var/www/html/src/batch.php", "-v"]
        volumeMounts:
        - mountPath: /var/www/html
          name: host-html
      volumes:
        - name: host-html
          hostPath:
            path: /C/src
            type: Directory

設定の上でのチェックポイントとしては

  • imagePullPolicy: Never により、起動対象のイメージをローカルにあるものだけ利用するように
  • secretKeyRef: の部分でパスワードをsecretから読み取るように
  • volumeMounts と hostPath の設定で、ソースファイルやDBのディレクトリをWindows側からマウントするようにして、ディスクの永続化としている

といったあたりかなと思います。

今後の開発環境について

今回はとりあえず上記のような構成で設定していますが、今後は以下のような構成にトライしてみたいなぁと考えています。

  • nginx, php-fpm, fluentd あたりのコンテナでPodを構成してみる
  • memcached, redisあたりの利用
  • DBのレプリケーション構成
  • ローリングアップデート構成
  • そもそも、本番環境がコンテナでないのであれば、構築スクリプトはDockerfileにあるよりもオーケストレーションツールのレシピであるほうが使いまわしは効くので、オーケストレーションツールを使ってデプロイ出来るエコサイクルを構築したほうが最終的に楽かも??

将来像についてはいつ実施できるのか今の所なにも目処は経っていないのですが、やはり構築環境をコード化しておくと自分のPCの入れ替え時に再構築が早い、といった便利なことも多く、また環境の切り替えも楽なのでミドルウェアアップデートとかの動作確認もやりやすいなぁという印象です。
初期コストはかなり高いですが、慣れるといろいろと楽ができるので余裕がある方は是非チャレンジしてみてほしいなぁと思います。

tel

一覧に戻る