別の記事で永続ディスク(Persistent Disk)設定方法を紹介しましたが、永続ディスクの制限は複数ノードからマウントして同時に読み書きできない。
本記事では、NFS(Network File System)を利用して、その制限を解決する方法を紹介致します。
ワークフォルダの構成
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
デプロイ後の確認
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
定義実施後確認
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
ビルドイメージの確認
デプロイジョブはGKEの中に確認
2つのジョブはNFSを共有利用できることを稼働ログで確認できます。
本記事の利用ソースコードはこちら
https://github.com/itdevsamurai/gke/tree/master/persistentvolume
最後まで読んで頂き、どうも有難う御座います!
DevSamurai 橋本