diff --git a/README.md b/README.md
index 5e048d19900ae4e4cdec0dd41e8ac16195bc615a..69cf297a7cc2ee90457751d7dae416a0176e3261 100644
--- a/README.md
+++ b/README.md
@@ -188,6 +188,25 @@ To uninstall, execute:
 kubectl delete -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
 ```
 
+## Debug
+> it providers a out-of-cluster debug env for deverlopers
+### debug
+```Bash
+git clone https://github.com/rancher/local-path-provisioner.git
+cd local-path-provisioner
+go build
+kubectl apply -f debug/config.yaml
+./local-path-provisioner --debug start --namespace=local-path-storage
+```
+
+### example
+[Usage](#usage)
+
+### clear
+```
+kubectl delete -f debug/config.yaml
+```
+
 ## License
 
 Copyright (c) 2014-2020  [Rancher Labs, Inc.](http://rancher.com/)
diff --git a/debug/config.yaml b/debug/config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b1c096122ef10147f66ceb2bac9af5b24dddf1bf
--- /dev/null
+++ b/debug/config.yaml
@@ -0,0 +1,48 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: local-path-storage
+---
+
+apiVersion: storage.k8s.io/v1
+kind: StorageClass
+metadata:
+  name: local-path
+provisioner: rancher.io/local-path
+volumeBindingMode: WaitForFirstConsumer
+reclaimPolicy: Delete
+
+---
+
+kind: ConfigMap
+apiVersion: v1
+metadata:
+  name: local-path-config
+  namespace: local-path-storage
+data:
+  config.json: |-
+        {
+                "nodePathMap":[
+                {
+                        "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES",
+                        "paths":["/opt/local-path-provisioner"]
+                },
+                {
+                        "node":"yasker-lp-dev1",
+                        "paths":["/opt/local-path-provisioner", "/data1"]
+                },
+                {
+                        "node":"yasker-lp-dev3",
+                        "paths":[]
+                }
+                ]
+        }
+  setup: |-
+        #!/bin/sh
+        path=$1
+        mkdir -m 0777 -p ${path}
+  teardown: |-
+        #!/bin/sh
+        path=$1
+        rm -rf ${path}
+
diff --git a/main.go b/main.go
index 4f15bea71f26cca197c9b1fd648c2bf6449c8f3a..fd4792f9fcbf998c6ec0966a1e46a5e17ff59a9b 100644
--- a/main.go
+++ b/main.go
@@ -4,30 +4,37 @@ import (
 	"fmt"
 	"os"
 	"os/signal"
+	"path/filepath"
 	"syscall"
 
 	"github.com/Sirupsen/logrus"
 	"github.com/pkg/errors"
 	"github.com/urfave/cli"
 
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	clientset "k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/rest"
+	"k8s.io/client-go/tools/clientcmd"
 	pvController "sigs.k8s.io/sig-storage-lib-external-provisioner/controller"
 )
 
 var (
 	VERSION = "0.0.1"
 
-	FlagConfigFile         = "config"
-	FlagProvisionerName    = "provisioner-name"
-	EnvProvisionerName     = "PROVISIONER_NAME"
-	DefaultProvisionerName = "rancher.io/local-path"
-	FlagNamespace          = "namespace"
-	EnvNamespace           = "POD_NAMESPACE"
-	DefaultNamespace       = "local-path-storage"
-	FlagHelperImage        = "helper-image"
-	EnvHelperImage         = "HELPER_IMAGE"
-	DefaultHelperImage     = "busybox"
+	FlagConfigFile            = "config"
+	FlagProvisionerName       = "provisioner-name"
+	EnvProvisionerName        = "PROVISIONER_NAME"
+	DefaultProvisionerName    = "rancher.io/local-path"
+	FlagNamespace             = "namespace"
+	EnvNamespace              = "POD_NAMESPACE"
+	DefaultNamespace          = "local-path-storage"
+	FlagHelperImage           = "helper-image"
+	EnvHelperImage            = "HELPER_IMAGE"
+	DefaultHelperImage        = "busybox"
+	FlagKubeconfig            = "kubeconfig"
+	DefaultKubeConfigFilePath = ".kube/config"
+	DefaultConfigFileKey      = "config.json"
+	DefaultConfigMapName      = "local-path-config"
 )
 
 func cmdNotFound(c *cli.Context, command string) {
@@ -75,6 +82,11 @@ func StartCmd() cli.Command {
 				EnvVar: EnvHelperImage,
 				Value:  DefaultHelperImage,
 			},
+			cli.StringFlag{
+				Name:  FlagKubeconfig,
+				Usage: "Paths to a kubeconfig. Only required when it is out-of-cluster.",
+				Value: "",
+			},
 		},
 		Action: func(c *cli.Context) {
 			if err := startDaemon(c); err != nil {
@@ -84,11 +96,45 @@ func StartCmd() cli.Command {
 	}
 }
 
+func homeDir() string {
+	if h := os.Getenv("HOME"); h != "" {
+		return h
+	}
+	return os.Getenv("USERPROFILE") // windows
+}
+
+func loadConfig(kubeconfig string) (*rest.Config, error) {
+	if c, err := rest.InClusterConfig(); err == nil {
+		return c, nil
+	}
+	home := homeDir()
+	if kubeconfig == "" && home != "" {
+		kubeconfig = filepath.Join(home, DefaultKubeConfigFilePath)
+	}
+	_, err := os.Stat(kubeconfig)
+	if err != nil {
+		return nil, err
+	}
+	return clientcmd.BuildConfigFromFlags("", kubeconfig)
+}
+
+func findConfigFileFromConfigMap(kubeClient clientset.Interface, namespace string) (string, error) {
+	cm, err := kubeClient.CoreV1().ConfigMaps(namespace).Get(DefaultConfigMapName, metav1.GetOptions{})
+	if err != nil {
+		return "", err
+	}
+	configFile, ok := cm.Data[DefaultConfigFileKey]
+	if !ok {
+		return "", fmt.Errorf("%v is not exist in local-path-config ConfigMap", DefaultConfigFileKey)
+	}
+	return configFile, nil
+}
+
 func startDaemon(c *cli.Context) error {
 	stopCh := make(chan struct{})
 	RegisterShutdownChannel(stopCh)
 
-	config, err := rest.InClusterConfig()
+	config, err := loadConfig(c.String(FlagKubeconfig))
 	if err != nil {
 		return errors.Wrap(err, "unable to get client config")
 	}
@@ -103,10 +149,6 @@ func startDaemon(c *cli.Context) error {
 		return errors.Wrap(err, "Cannot start Provisioner: failed to get Kubernetes server version")
 	}
 
-	configFile := c.String(FlagConfigFile)
-	if configFile == "" {
-		return fmt.Errorf("invalid empty flag %v", FlagConfigFile)
-	}
 	provisionerName := c.String(FlagProvisionerName)
 	if provisionerName == "" {
 		return fmt.Errorf("invalid empty flag %v", FlagProvisionerName)
@@ -115,6 +157,13 @@ func startDaemon(c *cli.Context) error {
 	if namespace == "" {
 		return fmt.Errorf("invalid empty flag %v", FlagNamespace)
 	}
+	configFile := c.String(FlagConfigFile)
+	if configFile == "" {
+		configFile, err = findConfigFileFromConfigMap(kubeClient, namespace)
+		if err != nil {
+			return fmt.Errorf("invalid empty flag %v and it also does not exist at ConfigMap %v/%v", FlagConfigFile, namespace, DefaultConfigMapName)
+		}
+	}
 	helperImage := c.String(FlagHelperImage)
 	if helperImage == "" {
 		return fmt.Errorf("invalid empty flag %v", FlagHelperImage)
diff --git a/provisioner.go b/provisioner.go
index 4a2ea1706b82f50c885cab97f6f4af474678c83f..e80e8cc8210ff85a4b3a755dbaa1f576604321bf 100644
--- a/provisioner.go
+++ b/provisioner.go
@@ -418,10 +418,27 @@ func (p *LocalPathProvisioner) createHelperPod(action ActionType, cmdsForPath []
 	return nil
 }
 
+func isJSONFile(configFile string) bool {
+	return strings.HasSuffix(configFile, ".json")
+}
+
+func unmarshalFromString(configFile string) (*ConfigData, error) {
+	var data ConfigData
+	if err := json.Unmarshal([]byte(configFile), &data); err != nil {
+		return nil, err
+	}
+	return &data, nil
+}
+
 func loadConfigFile(configFile string) (cfgData *ConfigData, err error) {
 	defer func() {
 		err = errors.Wrapf(err, "fail to load config file %v", configFile)
 	}()
+
+	if !isJSONFile(configFile) {
+		return unmarshalFromString(configFile)
+	}
+
 	f, err := os.Open(configFile)
 	if err != nil {
 		return nil, err