LoginSignup
11
9

More than 3 years have passed since last update.

GKE上にNFSを構築する方法

Last updated at Posted at 2019-12-03

別の記事で永続ディスク(Persistent Disk)設定方法を紹介しましたが、永続ディスクの制限は複数ノードからマウントして同時に読み書きできない。
本記事では、NFS(Network File System)を利用して、その制限を解決する方法を紹介致します。

実施手順

  • Persistent Disk作成
  • Persistent Diskフォーマット
  • Persistent Diskを使って、NFSサーバ立ち上げ
  • NFSを使って、GKE中にストレージを作成
  • GKEのストレージマウントのPod作成

最初の2つのステップ(Persistent Disk作成、とPersistent Diskフォーマット)は別の記事で紹介したため、それらの記事を参照してください。

※本手順はGCPとgcloudコマンドの利用経験があることが望ましいです。

ワークフォルダの構成

nfs_on_gke
├── README.md
├── cloudbuild.dummyjob.yaml
├── deployment
│   ├── dummy_job_01.deployment.yaml
│   └── dummy_job_02.deployment.yaml
├── dummyjob.Dockerfile
├── job
│   └── dummyjob.go
├── nfs-container.deployment.yaml
├── nfs-service.deployment.yaml
└── nfs-volume.yaml

1. Persistent Diskを使って、NFSサーバ立ち上げ

nfs-container.deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nfs-server
spec:
  replicas: 1
  selector:
    matchLabels:
      role: nfs-server
  template:
    metadata:
      labels:
        role: nfs-server
    spec:
      containers:
      - name: nfs-server
        image: gcr.io/google_containers/volume-nfs:latest
        ports:
          - name: nfs
            containerPort: 2049
          - name: mountd
            containerPort: 20048
          - name: rpcbind
            containerPort: 111
        securityContext:
          privileged: true
        volumeMounts:
          - mountPath: /exports
            name: mypvc
      volumes:
        - name: mypvc
          gcePersistentDisk:
            pdName: gce-nfs-disk
            fsType: ext4
nfs-service.deployment.yaml
apiVersion: v1
kind: Service
metadata:
  name: nfs-server
spec:
  ports:
    - name: nfs
      port: 2049
    - name: mountd
      port: 20048
    - name: rpcbind
      port: 111
  selector:
    role: nfs-server
  type: LoadBalancer

GKEにデプロイ

# クラスタ作成
gcloud container clusters create ds-gke-small-cluster \
    --project ds-project \
    --zone asia-northeast1-b \
    --machine-type n1-standard-1 \
    --num-nodes 1 \
    --enable-stackdriver-kubernetes

# k8sコントロールツールをインストール
gcloud components install kubectl
kubectl version

# GKEのクラスタにアクセスするため、credentialsを設定
gcloud container clusters get-credentials --zone asia-northeast1-b ds-gke-small-cluster

# デプロイ NFSサーバ
kubectl apply -f nfs-container.deployment.yaml

# 外からアクセスするため、NFSサービスをデプロイ。クラスタ内でアクセスしかない場合、このステップをスキップ
kubectl apply -f nfs-service.deployment.yaml

デプロイ後の確認
gcp_gke_kubernetes_nfs_devsamurai_001.png
gcp_gke_kubernetes_nfs_devsamurai_002.png

2. NFSを使って、GKE中にストレージを作成

nfs-volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-data-volume
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: "xx.xx.xx.xx"
    path: "/exports"
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nfs-data-volume
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 10Gi

ボリューム定義実施

# PersistentVolumeとPersistentVolumeClaimを作成。複数接続で読み書きできるaccessModes(ReadWriteMany)
kubectl apply -f nfs-volume.yaml

定義実施後確認
gcp_gke_kubernetes_nfs_devsamurai_003.png

3. GKEのストレージマウントのPod作成

golangで簡単なジョブを作成する。
ジョブ処理はoutput-pathにサンプル10ファイルを作成する。予定は複数ジョブを稼働して、共有用のNFSにファイルを作成する。

dummyjob.go
package main

import (
    "flag"
    "fmt"
    "io/ioutil"
    "log"
    "os"
    "time"
)

var jobName = flag.String("job-name", "", "specify job name")
var outputPath = flag.String("output-path", "", "specify output path for job")

func main() {

    flag.Parse()

    outlog("Dummy Job start ...")

    for i := 0; i < 10; i++ {
        unixtime := time.Now().Unix()
        fileName := fmt.Sprint(*jobName, "_", unixtime, ".txt")

        // make a file
        file, err := os.Create(*outputPath + "/" + fileName)
        if err != nil {
            log.Fatal(err)
        }
        outlog("created a file: ", fileName)

        // out some
        file.WriteString("hello from " + *jobName)
        file.Close()

        // sleep to delay process
        time.Sleep(2 * time.Second)
    }

    // list all file in path
    outlog("List all files:")
    files, err := ioutil.ReadDir(*outputPath)
    if err != nil {
        log.Fatal(err)
    }

    for _, file := range files {
        outlog(file.Name())
    }

    outlog("Dummy Job finished.")

}

func outlog(args ...string) {
    log.Println(*jobName+":", args)
}
dummyjob.Dockerfile
FROM alpine:latest
WORKDIR /app
COPY ./dummyjob /app
cloudbuild.dummyjob.yaml
steps:
# go build
- name: golang:1.12
  dir: .
  args: ['go', 'build', '-o', 'dummyjob', 'job/dummyjob.go']
  env: ["CGO_ENABLED=0"]

# docker build
- name: 'gcr.io/cloud-builders/docker'
  dir: .
  args: [
         'build',
         '-t', '${_GCR_REGION}/${_GCR_PROJECT}/${_GCR_IMAGE_NAME}:${_GCR_TAG}',
         '-f', 'dummyjob.Dockerfile',
         '--cache-from', '${_GCR_REGION}/${_GCR_PROJECT}/${_GCR_IMAGE_NAME}:${_GCR_TAG}',
         '.'
        ]

# push image to Container Registry
- name: 'gcr.io/cloud-builders/docker'
  args: ["push", '${_GCR_REGION}/${_GCR_PROJECT}/${_GCR_IMAGE_NAME}']

substitutions:
  # # GCR region name to push image
  _GCR_REGION: asia.gcr.io
  # # Project ID
  _GCR_PROJECT: project-abc123
  # # Image name
  _GCR_IMAGE_NAME: dummy-job
  # # Image tag
  _GCR_TAG: latest

イメージをビルドして、2つのジョブをデプロイする

# build dummy-job image on Container Registry
gcloud builds submit --config cloudbuild.dummyjob.yaml

# deploy job
kubectl apply -f deployment/dummy_job_01.deployment.yaml
kubectl apply -f deployment/dummy_job_02.deployment.yaml

ビルドイメージの確認
gcp_gke_kubernetes_nfs_devsamurai_004.png

デプロイジョブはGKEの中に確認
gcp_gke_kubernetes_nfs_devsamurai_005.png

2つのジョブはNFSを共有利用できることを稼働ログで確認できます。
gcp_gke_kubernetes_nfs_devsamurai_006.png

NFSを共有して読み書きできることを確認できました。

本記事で利用したソースコードはこちら

https://github.com/itdevsamurai/gke/tree/master/nfs

最後まで読んで頂き、どうも有難う御座います!

DevSamurai 橋本

関連記事:GKEの中で永続ディスク(Persistent Disk)の利用方法

11
9
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
9