MySQL
php-fpm
kubernetes

kubernetes上にnginx+php-fpm+mysqlでpersistent volume上のデータを表示させる

前提条件

kubernetesがインストール済み
※まだの方はここここなどを参考にインストールしてください

環境と構成

構成情報

  • CentOS 7.3.1611
  • Kubernetes 1.5.2
  • flannel 0.7.0
  • docker 1.12.6

環境情報

  • Master IPアドレス 192.168.122.100
  • Node IPアドレス 192.168.122.101

nfs serverのインストール(Masterで作業)

persistent volumeをNodeからマウントできるように今回はMasterにnfs-serverをインストールしたいと思います。
※今回は/mnt/nfsを見せるように設定します。(適当に変更してください)

root@master yum -y install nfs-utils rpcbind
root@master mkdir -p /mnt/nfs
root@master vi /etc/exports
  /mnt/nfs *(rw,async,no_root_squash)
root@master systemctl start rpcbind nfs-server
root@master systemctl enable rpcbind nfs-server

docker private registryのインストール(Masterで作業)

自作したコンテナを格納するプライベートレジストリを立てたいと思います。
今回はこれもMaster上に立てます。

root@master yum install docker-distribution
root@master systemctl start docker-distribution
root@master systemctl enable docker-distribution

コンテナの作成(Nodeで作業)

  • 前準備

MySQLコンテナでnfsサーバからマウントするため、MySQLコンテナが配備されるNode側にnfsをマウントできるようにしておきます。
Master上のnfsサーバがマウントできればok.
エラーがなければアンマウント

root@node yum install -y nfs-utils
root@node mount -t nfs 192.168.226.138:/mnt/nfs /mnt
root@node umount /mnt

また、今回はMaster上のdocker private registryにはHTTPでアクセスするためdockerの設定ファイルにinsecure registryを追加します。

root@node vi /etc/sysconfig/docker
  INSECURE_REGISTRY='--insecure-registry=192.168.226.138:5000'
root@node systemctl restart docker
  • MySQLのデータベースとテーブルをpersistent volume上に作成

persistent volume上に今回のWebページで使うためのデータベースとテーブルを作成しておきます。

board.sql
DROP DATABASE IF EXISTS board;
CREATE DATABASE board;
USE board;

DROP TABLE IF EXISTS `data`;
CREATE TABLE `data` (
  `name` CHAR(20) NOT NULL DEFAULT 'no name',
  `value` TEXT
);
root@node yum install -y mariadb
root@node mount -t nfs 192.168.226.138:/mnt/nfs /mnt
root@node docker run -d --name mysql -v /mnt:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=password -p 3306:3306 mysql
root@node mysql -h 192.168.226.139 -u root -ppassword < board.sql
root@node docker stop mysql
root@node docker rm mysql
root@node umount /mnt
  • nginxコンテナの作成

デフォルトのnginxイメージから設定ファイルだけを修正してプライベートレジストリにアップロードします。

server.conf
server {
 listen 80 default;
 server_name _;
 root /var/www/html;
 index index.php index.html index.htm;
 charset utf-8;

 access_log off;
 error_log off;

 location / {
   try_files $uri $uri/ /index.php$is_args$args;
 }

 location ~ \.php$ {
   fastcgi_pass localhost:9000;
   fastcgi_index index.php;
   fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
   include       fastcgi_params;
 }
}

root@node docker run --name nginx -d nginx
root@node docker cp server.conf nginx:/etc/nginx/conf.d/server.conf
root@node docker stop nginx
root@node docker commit -m "first version" nginx 192.168.122.100:5000/my_nginx:1.0
root@node docker push 192.168.122.100:5000/my_nginx:1.0
root@node docker rm nginx

  • php-fpmコンテナの作成

メインとなるindex.phpを配備したphp-fpmコンテナを作成し、nginxと同様にプライベートレジストリにアップロードします。

index.php
<?php
  $messages="";
  $host=$_ENV["MYSQL_ADDR"];
  $user="root";
  $passwd="password";

  $pdo=new PDO("mysql:host=".$host.";dbname=board",$user,$passwd);

  if(isset($_POST["send"])){
    $query="insert into data (name,value) values ('".$_POST["name"]."','".$_POST["message"]."')";
    $pdo->query($query);
  }

  $sql = $pdo->query("select * from data");
  foreach ($sql as $row) {
    $messages.=$row['name']." : ".$row['value']."<br>";
  }

?>
<html>
  <head>
    <title>Webテスト</title>
  </head>
  <body>
    <form action="#" method="post">
      名前: <input type="text" value="名無し" name="name"><br>
      メッセージ: <input type="text" value="メッセージ" name="message"><br>
      <input type="submit" value="送信" name="send">
    </form>

    <?php echo $messages; ?>
  </body>
</html>

↓php-fpmのDockerfile

FROM php:7-fpm

RUN apt-get update \
  && apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng12-dev libmcrypt-dev \
  && docker-php-ext-install pdo_mysql mysqli mbstring gd iconv mcrypt

COPY index.php /var/www/html/

docker build -t 192.168.122.100:5000/my_php-fpm:1.0 .
docker push 192.168.122.100:5000/my_php-fpm:1.0

デプロイとアクセス

まずdeployのためのyamlファイルです。

mysql.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs
  labels:
    type: nfs
    app: nfs-volume
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /mnt/nfs
    server: 192.168.122.100
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-claim
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mysql-deployment
  labels:
    app: mysql-server
spec:
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql-server
    spec:
      containers:
      - image: mysql
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-claim
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
  labels:
    app: mysql
spec:
  ports:
  - port: 3306
    targetPort: 3306
  selector:
    app: mysql-server

web.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: web-deployment
  labels:
    app: web-server
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: web-server
    spec:
      containers:
      - name: nginx
        image: 192.168.122.100:5000/my_nginx:1.0
        ports:
          - containerPort: 80
      - name: php-fpm
        image: 192.168.122.100:5000/my_php-fpm:1.0
        env:
        - name: MYSQL_ADDR
          value: mysql-service.default.svc.cluster.local
          # or value: (mysql-serviveのIPアドレス)
          # mysql-serviceのIPアドレスの取得方法
          # kubectl get svc mysql-service
        ports:
          - containerPort: 9000
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
  labels:
    app: web-server
spec:
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30000
  type: NodePort
  selector:
    app: web-server

それぞれのyamlファイルをkubectlコマンドでdeployしていきます。

kubectl create -f mysql.yaml
kubectl create -f web.yaml

pod起動後、ブラウザからNodeの30000番ポート( http://192.168.122.101:30000 )にアクセスできればok.
めでたし、めでたし

※参考: http://takaya030.hatenablog.com/entry/2016/06/18/005057