diff --git a/deploy/example-configmap.yaml b/deploy/example-configmap.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..aae6b64031a677924f6551baa0436cbd71f76f23
--- /dev/null
+++ b/deploy/example-configmap.yaml
@@ -0,0 +1,24 @@
+kind: ConfigMap
+apiVersion: v1
+metadata:
+  name: local-path-config
+  namespace: default
+data:
+  config.json: |-
+        {
+                "nodePathMap":[
+                {
+                        "node":"yasker-lp-dev1",
+                        "paths":["/opt", "/data1"]
+                },
+                {
+                        "node":"yasker-lp-dev2",
+                        "paths":["/opt"]
+                },
+                {
+                        "node":"yasker-lp-dev3",
+                        "paths":["/data3"]
+                }
+                ]
+        }
+
diff --git a/deploy/provisioner.yaml b/deploy/provisioner.yaml
index bbe34b0dcdb59f6e5f6f16d5cd01979bb388fd39..7e37cc0c5b110949dde6a383a448d810750cd0c5 100644
--- a/deploy/provisioner.yaml
+++ b/deploy/provisioner.yaml
@@ -52,6 +52,7 @@ spec:
       labels:
         app: local-path-provisioner
     spec:
+      serviceAccountName: local-path-provisioner-service-account
       containers:
         - name: local-path-provisioner
           image: yasker/local-path-provisioner:63df7c1
@@ -60,4 +61,12 @@ spec:
           - local-path-provisioner
           - --debug
           - start
-      serviceAccountName: local-path-provisioner-service-account
+          - --config
+          - /etc/config/config.json
+          volumeMounts:
+          - name: config-volume
+            mountPath: /etc/config/
+      volumes:
+        - name: config-volume
+          configMap:
+            name: local-path-config
diff --git a/main.go b/main.go
index dfa7b05414b97fe3aaaf0e264c5ac0400e766c1f..31a0024429855359669d26167dae7f0b3f468886 100644
--- a/main.go
+++ b/main.go
@@ -22,6 +22,7 @@ var (
 
 	FlagProvisionerName = "provisioner-name"
 	EnvProvisionerName  = "PROVISIONER_NAME"
+	FlagConfigFile      = "config"
 )
 
 func cmdNotFound(c *cli.Context, command string) {
@@ -48,10 +49,15 @@ func StartCmd() cli.Command {
 		Flags: []cli.Flag{
 			cli.StringFlag{
 				Name:   FlagProvisionerName,
-				Usage:  "Specify provisioner name",
+				Usage:  "Optional. Specify provisioner name.",
 				EnvVar: EnvProvisionerName,
 				Value:  DefaultProvisionerName,
 			},
+			cli.StringFlag{
+				Name:  FlagConfigFile,
+				Usage: "Required. Provisioner configuration file.",
+				Value: "",
+			},
 		},
 		Action: func(c *cli.Context) {
 			if err := startDaemon(c); err != nil {
@@ -84,7 +90,11 @@ func startDaemon(c *cli.Context) error {
 	if provisionerName == "" {
 		return fmt.Errorf("invalid empty provisioner name")
 	}
-	provisioner := NewProvisioner(kubeClient)
+	configFile := c.String(FlagConfigFile)
+	provisioner, err := NewProvisioner(kubeClient, configFile)
+	if err != nil {
+		return err
+	}
 	pc := pvController.NewProvisionController(
 		kubeClient,
 		provisionerName,
diff --git a/provisioner.go b/provisioner.go
index 144e3a1b83a1e215ad602c0319f18ca67481a1d8..910bff91b8243adcf66e450d2944785be5ae0ecf 100644
--- a/provisioner.go
+++ b/provisioner.go
@@ -1,7 +1,9 @@
 package main
 
 import (
+	"encoding/json"
 	"fmt"
+	"os"
 	"path/filepath"
 	"time"
 
@@ -19,18 +21,55 @@ const (
 )
 
 var (
-	DefaultPath   = "/opt"
-	CleanupCounts = 120
+	CleanupTimeoutCounts = 120
 )
 
 type LocalPathProvisioner struct {
 	kubeClient *clientset.Clientset
+	configFile string
 }
 
-func NewProvisioner(kubeClient *clientset.Clientset) *LocalPathProvisioner {
+type NodePathMapData struct {
+	Node  string   `json:"node,omitempty"`
+	Paths []string `json:"paths,omitempty"`
+}
+
+type ConfigData struct {
+	NodePathMap []*NodePathMapData `json:"nodePathMap,omitempty"`
+}
+
+type NodePathMap struct {
+	Paths map[string]struct{}
+}
+
+type Config struct {
+	NodePathMap map[string]*NodePathMap
+}
+
+func (c *Config) getRandomPathOnNode(node string) (string, error) {
+	npMap := c.NodePathMap[node]
+	if npMap == nil {
+		return "", fmt.Errorf("config doesn't contain node %v", node)
+	}
+	paths := npMap.Paths
+	if len(paths) == 0 {
+		return "", fmt.Errorf("no local path available on node %v", node)
+	}
+	path := ""
+	for path = range paths {
+		break
+	}
+	return path, nil
+}
+
+func NewProvisioner(kubeClient *clientset.Clientset, configFile string) (*LocalPathProvisioner, error) {
+	if _, err := getConfig(configFile); err != nil {
+		return nil, errors.Wrapf(err, "invalidate config file %v", configFile)
+	}
 	return &LocalPathProvisioner{
 		kubeClient: kubeClient,
-	}
+		configFile: configFile,
+	}, nil
 }
 
 func (p *LocalPathProvisioner) Provision(opts pvController.VolumeOptions) (*v1.PersistentVolume, error) {
@@ -47,10 +86,20 @@ func (p *LocalPathProvisioner) Provision(opts pvController.VolumeOptions) (*v1.P
 	if opts.SelectedNode == nil {
 		return nil, fmt.Errorf("configuration error, no node was specified")
 	}
+
+	cfg, err := getConfig(p.configFile)
+	if err != nil {
+		return nil, err
+	}
+
+	basePath, err := cfg.getRandomPathOnNode(node.Name)
+	if err != nil {
+		return nil, err
+	}
 	name := opts.PVName
-	path := filepath.Join(DefaultPath, name)
+	path := filepath.Join(basePath, name)
 
-	logrus.Infof("Created volume %v", name)
+	logrus.Infof("Created volume %v at %v:%v", name, node.Name, path)
 	fs := v1.PersistentVolumeFilesystem
 	hostPathType := v1.HostPathDirectoryOrCreate
 
@@ -159,9 +208,12 @@ func (p *LocalPathProvisioner) cleanupVolume(name, path, node string) (err error
 	if name == "" || path == "" || node == "" {
 		return fmt.Errorf("invalid empty name or path or node")
 	}
-	//TODO match up with node prefixes, make sure it's one of them (and not `/`)
-	if filepath.Clean(path) == "/" {
-		return fmt.Errorf("not sure why you want to DESTROY the root directory")
+	path, err = filepath.Abs(path)
+	if err != nil {
+		return err
+	}
+	if path == "/" {
+		return fmt.Errorf("not sure why you want to DESTROY THE ROOT DIRECTORY")
 	}
 	hostPathType := v1.HostPathDirectoryOrCreate
 	cleanupPod := &v1.Pod{
@@ -170,6 +222,7 @@ func (p *LocalPathProvisioner) cleanupVolume(name, path, node string) (err error
 		},
 		Spec: v1.PodSpec{
 			RestartPolicy: v1.RestartPolicyNever,
+			NodeName:      node,
 			Containers: []v1.Container{
 				{
 					Name:    "local-path-cleanup",
@@ -213,7 +266,7 @@ func (p *LocalPathProvisioner) cleanupVolume(name, path, node string) (err error
 	}()
 
 	completed := false
-	for i := 0; i < CleanupCounts; i++ {
+	for i := 0; i < CleanupTimeoutCounts; i++ {
 		if pod, err := p.kubeClient.CoreV1().Pods(namespace).Get(pod.Name, metav1.GetOptions{}); err != nil {
 			return err
 		} else if pod.Status.Phase == v1.PodSucceeded {
@@ -223,9 +276,59 @@ func (p *LocalPathProvisioner) cleanupVolume(name, path, node string) (err error
 		time.Sleep(1 * time.Second)
 	}
 	if !completed {
-		return fmt.Errorf("cleanup process timeout after %v seconds", CleanupCounts)
+		return fmt.Errorf("cleanup process timeout after %v seconds", CleanupTimeoutCounts)
 	}
 
-	logrus.Infof("Volume %v has been cleaned up", name)
+	logrus.Infof("Volume %v has been cleaned up from %v:%v", name, node, path)
 	return nil
 }
+
+func getConfig(configFile string) (cfg *Config, err error) {
+	defer func() {
+		err = errors.Wrapf(err, "fail to load config file %v", configFile)
+	}()
+	f, err := os.Open(configFile)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+
+	var data ConfigData
+	if err := json.NewDecoder(f).Decode(&data); err != nil {
+		return nil, err
+	}
+	cfg, err = canonicalizeConfig(&data)
+	if err != nil {
+		return nil, err
+	}
+	return cfg, nil
+}
+
+func canonicalizeConfig(data *ConfigData) (cfg *Config, err error) {
+	defer func() {
+		err = errors.Wrapf(err, "config canonicalization failed")
+	}()
+	cfg = &Config{}
+	cfg.NodePathMap = map[string]*NodePathMap{}
+	for _, n := range data.NodePathMap {
+		if cfg.NodePathMap[n.Node] != nil {
+			return nil, fmt.Errorf("duplicate node %v", n.Node)
+		}
+		npMap := &NodePathMap{Paths: map[string]struct{}{}}
+		cfg.NodePathMap[n.Node] = npMap
+		for _, p := range n.Paths {
+			if p[0] != '/' {
+				return nil, fmt.Errorf("path must start with / for path %v on node %v", p, n.Node)
+			}
+			path, err := filepath.Abs(p)
+			if err != nil {
+				return nil, err
+			}
+			if _, ok := npMap.Paths[path]; ok {
+				return nil, fmt.Errorf("duplicate path %v on node %v", p, n.Node)
+			}
+			npMap.Paths[path] = struct{}{}
+		}
+	}
+	return cfg, nil
+}