diff --git a/examples/nfs/README.md b/examples/nfs/README.md index 9eb0f7b8968..a1fa2a84556 100644 --- a/examples/nfs/README.md +++ b/examples/nfs/README.md @@ -32,9 +32,51 @@ Documentation for other releases can be found at -# Example of NFS volume +# Outline -See [nfs-web-rc.yaml](nfs-web-rc.yaml) for a quick example of how to use an NFS +This example describes how to create Web frontend server, an auto-provisioned persistent volume on GCE, and an NFS-backed persistent claim. + +Demonstrated Kubernetes Concepts: + +* [Persistent Volumes](http://kubernetes.io/docs/user-guide/persistent-volumes/) to + define persistent disks (disk lifecycle not tied to the Pods). +* [Services](http://kubernetes.io/docs/user-guide/services/) to enable Pods to + locate one another. + +![alt text][nfs pv example] + +As illustrated above, two persistent volumes are used in this example: + +- Web frontend Pod uses a persistent volume based on NFS server, and +- NFS server uses an auto provisioned [persistent volume](http://kubernetes.io/docs/user-guide/persistent-volumes/) from GCE PD or AWS EBS. + +Note, this example uses an NFS container that doesn't support NFSv4. + +[nfs pv example]: nfs-pv.png + + +## tl;dr Quickstart + +```console +$ kubectl create -f examples/nfs/provisioner/nfs-server-gce-pv.yaml +$ kubectl create -f examples/nfs/nfs-server-rc.yaml +$ kubectl create -f examples/nfs/nfs-server-service.yaml +# get the cluster IP of the server using the following command +$ kubectl describe services nfs-server +# use the NFS server IP to update nfs-pv.yaml and execute the following +$ kubectl create -f examples/nfs/nfs-pv.yaml +$ kubectl create -f examples/nfs/nfs-pvc.yaml +# run a fake backend +$ kubectl create -f examples/nfs/nfs-busybox-rc.yaml +# get pod name from this command +$ kubectl get pod -l name=nfs-busybox +# use the pod name to check the test file +$ kubectl exec nfs-busybox-jdhf3 -- cat /mnt/index.html +``` + +## Example of NFS based persistent volume + +See [NFS Service and Replication Controller](nfs-web-rc.yaml) for a quick example of how to use an NFS volume claim in a replication controller. It relies on the [NFS persistent volume](nfs-pv.yaml) and [NFS persistent volume claim](nfs-pvc.yaml) in this example as well. @@ -46,19 +88,24 @@ controller and import it into two replication controllers. ### NFS server part -Define [NFS server controller](nfs-server-rc.yaml) and +Define [the NFS Service and Replication Controller](nfs-server-rc.yaml) and [NFS service](nfs-server-service.yaml): +The NFS server exports an an auto-provisioned persistent volume backed by GCE PD: + +```console +$ kubectl create -f examples/nfs/provisioner/nfs-server-gce-pv.yaml +``` + ```console $ kubectl create -f examples/nfs/nfs-server-rc.yaml $ kubectl create -f examples/nfs/nfs-server-service.yaml ``` -The server exports `/mnt/data` directory as `/` (fsid=0). The -directory contains dummy `index.html`. Wait until the pod is running -by checking `kubectl get pods -lrole=nfs-server`. +The directory contains dummy `index.html`. Wait until the pod is running +by checking `kubectl get pods -l role=nfs-server`. -### Create the NFS claim +### Create the NFS based persistent volume claim The [NFS busybox controller](nfs-busybox-rc.yaml) uses a simple script to generate data written to the NFS server we just started. First, you'll need to @@ -95,7 +142,7 @@ Conveniently, it's also a `busybox` pod, so we can get an early check that our mounts are working now. Find a busybox pod and exec: ```console -$ kubectl get pod -lname=nfs-busybox +$ kubectl get pod -l name=nfs-busybox NAME READY STATUS RESTARTS AGE nfs-busybox-jdhf3 1/1 Running 0 25m nfs-busybox-w3s4t 1/1 Running 0 25m @@ -132,7 +179,7 @@ We can then use the busybox container we launched before to check that `nginx` is serving the data appropriately: ```console -$ kubectl get pod -lname=nfs-busybox +$ kubectl get pod -l name=nfs-busybox NAME READY STATUS RESTARTS AGE nfs-busybox-jdhf3 1/1 Running 0 1h nfs-busybox-w3s4t 1/1 Running 0 1h @@ -145,6 +192,13 @@ nfs-busybox-w3s4t ``` + + + + + + + [![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/examples/nfs/README.md?pixel)]() diff --git a/examples/nfs/nfs-data/Dockerfile b/examples/nfs/nfs-data/Dockerfile index 77735a1ed1a..6a9c689120f 100644 --- a/examples/nfs/nfs-data/Dockerfile +++ b/examples/nfs/nfs-data/Dockerfile @@ -12,8 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM jsafrane/nfsexporter -MAINTAINER Jan Safranek -ADD index.html /mnt/data/index.html +FROM centos +MAINTAINER Jan Safranek, jsafrane@redhat.com; Huamin Chen, hchen@redhat.com +RUN yum -y install /usr/bin/ps nfs-utils && yum clean all +RUN mkdir -p /exports +ADD run_nfs.sh /usr/local/bin/ +ADD index.html /tmp/index.html +RUN chmod 644 /tmp/index.html -ENTRYPOINT ["/usr/local/bin/run_nfs", "/mnt/data"] +# expose mountd 20048/tcp and nfsd 2049/tcp and rpcbind 111/tcp +EXPOSE 2049/tcp 20048/tcp 111/tcp 111/udp + +ENTRYPOINT ["/usr/local/bin/run_nfs.sh", "/exports"] diff --git a/examples/nfs/nfs-data/README.md b/examples/nfs/nfs-data/README.md index 9384b531349..a2ee9092513 100644 --- a/examples/nfs/nfs-data/README.md +++ b/examples/nfs/nfs-data/README.md @@ -34,11 +34,12 @@ Documentation for other releases can be found at # NFS-exporter container with a file -This container exports /mnt/data with index.html in it via NFSv4. Based on -../exporter. +This container exports /exports with index.html in it via NFS. Based on +../exports. Since some Linux kernels have issues running NFSv4 daemons in containers, +only NFSv3 is opened in this container. + +Available as `gcr.io/google-samples/nfs-server` -Available in dockerhub as -[jsafrane/nfs-data](https://registry.hub.docker.com/u/jsafrane/nfs-data/). diff --git a/examples/nfs/nfs-data/run_nfs.sh b/examples/nfs/nfs-data/run_nfs.sh new file mode 100755 index 00000000000..1714d352597 --- /dev/null +++ b/examples/nfs/nfs-data/run_nfs.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +# Copyright 2015 The Kubernetes Authors All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +function start() +{ + + # prepare /etc/exports + for i in "$@"; do + # fsid=0: needed for NFSv4 + echo "$i *(rw,fsid=0,insecure,no_root_squash)" >> /etc/exports + # move index.html to here + /bin/cp /tmp/index.html $i/ + chmod 644 $i/index.html + echo "Serving $i" + done + + # start rpcbind if it is not started yet + /usr/sbin/rpcinfo 127.0.0.1 > /dev/null; s=$? + if [ $s -ne 0 ]; then + echo "Starting rpcbind" + /usr/sbin/rpcbind -w + fi + + mount -t nfsd nfds /proc/fs/nfsd + + # -N 4.x: disable NFSv4 + # -V 3: enable NFSv3 + /usr/sbin/rpc.mountd -N 2 -V 3 -N 4 -N 4.1 + + /usr/sbin/exportfs -r + # -G 10 to reduce grace time to 10 seconds (the lowest allowed) + /usr/sbin/rpc.nfsd -G 10 -N 2 -V 3 -N 4 -N 4.1 2 + /usr/sbin/rpc.statd --no-notify + echo "NFS started" +} + +function stop() +{ + echo "Stopping NFS" + + /usr/sbin/rpc.nfsd 0 + /usr/sbin/exportfs -au + /usr/sbin/exportfs -f + + kill $( pidof rpc.mountd ) + umount /proc/fs/nfsd + echo > /etc/exports + exit 0 +} + + +trap stop TERM + +start "$@" + +# Ugly hack to do nothing and wait for SIGTERM +while true; do + sleep 5 +done diff --git a/examples/nfs/nfs-pv.png b/examples/nfs/nfs-pv.png new file mode 100644 index 00000000000..1ac5fc0d1ac Binary files /dev/null and b/examples/nfs/nfs-pv.png differ diff --git a/examples/nfs/nfs-pv.yaml b/examples/nfs/nfs-pv.yaml index 1bc043f905f..258f4d4c9d4 100644 --- a/examples/nfs/nfs-pv.yaml +++ b/examples/nfs/nfs-pv.yaml @@ -9,5 +9,5 @@ spec: - ReadWriteMany nfs: # FIXME: use the right IP - server: 10.999.999.999 - path: "/" + server: 10.244.1.4 + path: "/exports" diff --git a/examples/nfs/nfs-server-rc.yaml b/examples/nfs/nfs-server-rc.yaml index 15c40140802..c83ed1db876 100644 --- a/examples/nfs/nfs-server-rc.yaml +++ b/examples/nfs/nfs-server-rc.yaml @@ -13,9 +13,20 @@ spec: spec: containers: - name: nfs-server - image: gcr.io/google_containers/volume-nfs + image: gcr.io/google-samples/nfs-server:1.1 ports: - name: nfs containerPort: 2049 + - name: mountd + containerPort: 20048 + - name: rpcbind + containerPort: 111 securityContext: privileged: true + volumeMounts: + - mountPath: /exports + name: mypvc + volumes: + - name: mypvc + persistentVolumeClaim: + claimName: nfs-pv-provisioning-demo diff --git a/examples/nfs/nfs-server-service.yaml b/examples/nfs/nfs-server-service.yaml index a9966c3fce1..9654d158384 100644 --- a/examples/nfs/nfs-server-service.yaml +++ b/examples/nfs/nfs-server-service.yaml @@ -4,6 +4,11 @@ metadata: name: nfs-server spec: ports: - - port: 2049 + - name: nfs + port: 2049 + - name: mountd + port: 20048 + - name: rpcbind + port: 111 selector: role: nfs-server diff --git a/examples/nfs/provisioner/nfs-server-gce-pv.yaml b/examples/nfs/provisioner/nfs-server-gce-pv.yaml new file mode 100644 index 00000000000..92f9f573584 --- /dev/null +++ b/examples/nfs/provisioner/nfs-server-gce-pv.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: nfs-pv-provisioning-demo + labels: + demo: nfs-pv-provisioning + annotations: + volume.alpha.kubernetes.io/storage-class: any +spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 200Gi