Commit 17fd5f25 authored by Zach Loafman's avatar Zach Loafman

NFS: Revamp example, add nfs-common to debian saltbase

This ensures nfs-common is installed on GCE, and provides a more functional explanation/example. I launched two replication controllers so that there were busybox pods to poke around at the NFS volume, and so that the later wget actually works (the original example would have to work on the node, or need some other access to the container network). After switching to two controllers, it actually makes more sense to use PV claims, and it's probably a configuration that makes more sense for indirection for NFS anyways.
parent b7916424
...@@ -10,6 +10,7 @@ pkg-core: ...@@ -10,6 +10,7 @@ pkg-core:
- apt-transport-https - apt-transport-https
- python-apt - python-apt
- glusterfs-client - glusterfs-client
- nfs-common
- socat - socat
{% endif %} {% endif %}
# Ubuntu installs netcat-openbsd by default, but on GCE/Debian netcat-traditional is installed. # Ubuntu installs netcat-openbsd by default, but on GCE/Debian netcat-traditional is installed.
......
...@@ -291,15 +291,6 @@ before you can use it__ ...@@ -291,15 +291,6 @@ before you can use it__
See the [NFS example](../../examples/nfs/) for more details. See the [NFS example](../../examples/nfs/) for more details.
For example, [this file](../../examples/nfs/nfs-web-pod.yaml) demonstrates how to
specify the usage of an NFS volume within a pod.
In this example one can see that a `volumeMount` called `nfs` is being mounted
onto `/usr/share/nginx/html` in the container `web`. The volume "nfs" is defined as
type `nfs`, with the NFS server serving from `nfs-server.default.kube.local`
and exporting directory `/` as the share. The mount being created in this
example is writeable.
### iscsi ### iscsi
An `iscsi` volume allows an existing iSCSI (SCSI over IP) volume to be mounted An `iscsi` volume allows an existing iSCSI (SCSI over IP) volume to be mounted
......
...@@ -306,9 +306,13 @@ func TestExampleObjectSchemas(t *testing.T) { ...@@ -306,9 +306,13 @@ func TestExampleObjectSchemas(t *testing.T) {
"wordpress": &api.Pod{}, "wordpress": &api.Pod{},
}, },
"../examples/nfs": { "../examples/nfs": {
"nfs-server-pod": &api.Pod{}, "nfs-busybox-rc": &api.ReplicationController{},
"nfs-server-rc": &api.ReplicationController{},
"nfs-server-service": &api.Service{}, "nfs-server-service": &api.Service{},
"nfs-web-pod": &api.Pod{}, "nfs-pv": &api.PersistentVolume{},
"nfs-pvc": &api.PersistentVolumeClaim{},
"nfs-web-rc": &api.ReplicationController{},
"nfs-web-service": &api.Service{},
}, },
"../docs/user-guide/node-selection": { "../docs/user-guide/node-selection": {
"pod": &api.Pod{}, "pod": &api.Pod{},
......
...@@ -33,57 +33,115 @@ Documentation for other releases can be found at ...@@ -33,57 +33,115 @@ Documentation for other releases can be found at
# Example of NFS volume # Example of NFS volume
See [nfs-web-pod.yaml](nfs-web-pod.yaml) for a quick example, how to use NFS volume See [nfs-web-rc.yaml](nfs-web-rc.yaml) for a quick example of how to use an NFS
in a pod. 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.
## Complete setup ## Complete setup
The example below shows how to export a NFS share from a pod and imports it The example below shows how to export a NFS share from a single pod replication
into another one. controller and import it into two replication controllers.
### Prerequisites ### NFS server part
Define [NFS server controller](nfs-server-rc.yaml) and
[NFS service](nfs-server-service.yaml):
```console
$ kubectl create -f examples/nfs/nfs-server-rc.yaml
$ kubectl create -f examples/nfs/nfs-server-service.yaml
```
The nfs server pod creates a privileged container, so if you are using a Salt based KUBERNETES_PROVIDER (**gce**, **vagrant**, **aws**), you have to enable the ability to create privileged containers by API. 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`.
```sh ### Create the NFS claim
# At the root of Kubernetes source code
$ vi cluster/saltbase/pillar/privilege.sls
# If true, allow privileged containers to be created by API The [NFS busybox controller](nfs-busybox-rc.yaml) uses a simple script to
allow_privileged: true generate data written to the NFS server we just started. First, you'll need to
find the cluster IP of the server:
```console
$ kubectl describe services nfs-server
``` ```
For other non-salt based provider, you can set `--allow-privileged=true` for both api-server and kubelet, and then restart these components. Replace the invalid IP in the [nfs PV](nfs-pv.yaml). (In the future,
we'll be able to tie these together using the service names, but for
now, you have to hardcode the IP.)
Rebuild the Kubernetes and spin up a cluster using your preferred KUBERNETES_PROVIDER. Create the the [persistent volume](../../docs/user-guide/persistent-volumes.md)
and the persistent volume claim for your NFS server. The persistent volume and
claim gives us an indirection that allow multiple pods to refer to the NFS
server using a symbolic name rather than the hardcoded server address.
### NFS server part ```console
$ kubectl create -f examples/nfs/nfs-pv.yaml
$ kubectl create -f examples/nfs/nfs-pvc.yaml
```
Define [NFS server pod](nfs-server-pod.yaml) and ## Setup the fake backend
[NFS service](nfs-server-service.yaml):
$ kubectl create -f nfs-server-pod.yaml The [NFS busybox controller](nfs-busybox-rc.yaml) updates `index.html` on the
$ kubectl create -f nfs-server-service.yaml NFS server every 10 seconds. Let's start that now:
The server exports `/mnt/data` directory as `/` (fsid=0). The directory contains ```console
dummy `index.html`. Wait until the pod is running! $ kubectl create -f examples/nfs/nfs-busybox-rc.yaml
```
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
NAME READY STATUS RESTARTS AGE
nfs-busybox-jdhf3 1/1 Running 0 25m
nfs-busybox-w3s4t 1/1 Running 0 25m
$ kubectl exec nfs-busybox-jdhf3 -- cat /mnt/index.html
Thu Oct 22 19:20:18 UTC 2015
nfs-busybox-w3s4t
```
You should see output similar to the above if everything is working well. If
it's not, make sure you changed the invalid IP in the [NFS PV](nfs-pv.yaml) file
and make sure the `describe services` command above had endpoints listed
(indicating the service was associated with a running pod).
### NFS client ### Setup the web server
[WEB server pod](nfs-web-pod.yaml) uses the NFS share exported above as a NFS The [web server controller](nfs-web-rc.yaml) is an another simple replication
volume and runs simple web server on it. The pod assumes your DNS is configured controller demonstrates reading from the NFS share exported above as a NFS
and the NFS service is reachable as `nfs-server.default.kube.local`. Edit the volume and runs a simple web server on it.
yaml file to supply another name or directly its IP address (use
`kubectl get services` to get it).
Define the pod: Define the pod:
$ kubectl create -f nfs-web-pod.yaml ```console
$ kubectl create -f examples/nfs/nfs-web-rc.yaml
```
This creates two pods, each of which serve the `index.html` from above. We can
then use a simple service to front it:
Now the pod serves `index.html` from the NFS server: ```console
kubectl create -f examples/nfs/nfs-web-service.yaml
```
$ curl http://<the container IP address>/ We can then use the busybox container we launched before to check that `nginx`
Hello World! is serving the data appropriately:
```console
$ kubectl get pod -lname=nfs-busybox
NAME READY STATUS RESTARTS AGE
nfs-busybox-jdhf3 1/1 Running 0 1h
nfs-busybox-w3s4t 1/1 Running 0 1h
$ kubectl get services nfs-web
NAME LABELS SELECTOR IP(S) PORT(S)
nfs-web <none> role=web-frontend 10.0.68.37 80/TCP
$ kubectl exec nfs-busybox-jdhf3 -- wget -qO- http://10.0.68.37
Thu Oct 22 19:28:55 UTC 2015
nfs-busybox-w3s4t
```
<!-- BEGIN MUNGE: GENERATED_ANALYTICS --> <!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
......
# This mounts the nfs volume claim into /mnt and continuously
# overwrites /mnt/index.html with the time and hostname of the pod.
apiVersion: v1
kind: ReplicationController
metadata:
name: nfs-busybox
spec:
replicas: 2
selector:
name: nfs-busybox
template:
metadata:
labels:
name: nfs-busybox
spec:
containers:
- image: busybox
command:
- sh
- -c
- 'while true; do date > /mnt/index.html; hostname >> /mnt/index.html; sleep $(($RANDOM % 5 + 5)); done'
imagePullPolicy: IfNotPresent
name: busybox
volumeMounts:
# name must match the volume name below
- name: nfs
mountPath: "/mnt"
volumes:
- name: nfs
persistentVolumeClaim:
claimName: nfs
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs
spec:
capacity:
storage: 1Mi
accessModes:
- ReadWriteMany
nfs:
# FIXME: use the right IP
server: 10.999.999.999
path: "/"
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nfs
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Mi
apiVersion: v1 apiVersion: v1
kind: Pod kind: ReplicationController
metadata: metadata:
name: nfs-server name: nfs-server
labels:
role: nfs-server
spec: spec:
containers: replicas: 1
- name: nfs-server selector:
image: jsafrane/nfs-data role: nfs-server
ports: template:
- name: nfs metadata:
containerPort: 2049 labels:
securityContext: role: nfs-server
privileged: true spec:
containers:
- name: nfs-server
# TODO(zmerlynn): change to gcr.io/google_containers/volume-nfs
image: jsafrane/nfs-data
ports:
- name: nfs
containerPort: 2049
securityContext:
privileged: true
# # This pod mounts the nfs volume claim into /usr/share/nginx/html and
# This pod imports nfs-server.default.kube.local:/ into /usr/share/nginx/html # serves a simple web page.
#
apiVersion: v1 apiVersion: v1
kind: Pod kind: ReplicationController
metadata: metadata:
name: nfs-web name: nfs-web
spec: spec:
containers: replicas: 2
- name: web selector:
image: nginx role: web-frontend
ports: template:
- name: web metadata:
containerPort: 80 labels:
volumeMounts: role: web-frontend
# name must match the volume name below spec:
- name: nfs containers:
mountPath: "/usr/share/nginx/html" - name: web
volumes: image: nginx
- name: nfs ports:
nfs: - name: web
# FIXME: use the right hostname containerPort: 80
server: nfs-server.default.kube.local volumeMounts:
path: "/" # name must match the volume name below
- name: nfs
mountPath: "/usr/share/nginx/html"
volumes:
- name: nfs
persistentVolumeClaim:
claimName: nfs
kind: Service
apiVersion: v1
metadata:
name: nfs-web
spec:
ports:
- port: 80
selector:
role: web-frontend
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment