Repository: falcosecurity/driverkit
Pull request #197 (2022-08-16 15:19:01)

feat(kebernetes-incluster): Adding kubernetes in cluster subcommand
**What type of PR is this?**

/kind feature

**Any specific area of the project related to this PR?**

> Uncomment one (or more) `/area <>` lines:

/area cmd

/area pkg

**What this PR does / why we need it**:

* Adding a sub-command to use Kubernetes feature inside a kube pods with the appropriate service token/account.
* Adding configs/flags options to handle non root execution and pull secrets when using custom builder image.
* Fixing Kubenertes execution and probe module extraction. (Now extract module and probe properly, than delete the configmap and the pod)


~~To make non root execution works, I had to make a sub docker image builder with this owner change:~~
```
FROM falcosecurity/driverkit-builder

RUN chown -R nobody /usr/bin
```
~~I have to do this because driverkit's generated build script run a `ln -sf /usr/bin/gcc ...`, requiring root right/access.~~
~~Can you see another workaround ? Except to rewrite the builder Dockerfile and scripts to make them non-root executable.~~


**Which issue(s) this PR fixes**:

None

```release-note
* New sub-command `kubernetes-in-cluster` or `k8s-ic`
* New Kubernetes flags: 
  * namespace: Namespace where to execute the builder pod
  * run-as-user: User Id of the pod
  * imagePullSecret: Pull secret for custom builder image
```


poiana: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/falcosecurity/driverkit/pull/197#" title="Author self-approved">Lowaiz</a>*
**Once this PR has been reviewed and has the lgtm label**, please assign dwindsor for approval by writing `/assign @dwindsor` in a comment. For more information see:[The Kubernetes Code Review Process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process).

The full list of commands accepted by this bot can be found [here](https://prow.falco.org/command-help?repo=falcosecurity%2Fdriverkit).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/falcosecurity/driverkit/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["dwindsor"]} -->
FedeDP: Hi @Lowaiz ! Thanks for this great PR!

> I have to do this because driverkit's generated build script run a ln -sf /usr/bin/gcc ..., requiring root right/access.
Can you see another workaround ? Except to rewrite the builder Dockerfile and scripts to make them non-root executable.

Mmmh perhaps we could override CC env variable?
For reference, the ubuntu one would become:
```
{{ if .BuildModule }}
# Build the module
cd {{ .DriverBuildDir }}
make CC=/usr/bin/gcc-{{ .GCCVersion }} KERNELDIR=$sourcedir
mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }}
strip -g {{ .ModuleFullPath }}
# Print results
modinfo {{ .ModuleFullPath }}
{{ end }}
```

This is what we already do for clang btw, eg (taken from same ubuntu script):
```
{{ if .BuildProbe }}
# Build the eBPF probe
cd {{ .DriverBuildDir }}/bpf
if [[ -x /usr/bin/llc ]]; then
	LLC_BIN=/usr/bin/llc
else
	LLC_BIN=/usr/bin/llc-7
fi

if [[ -x /usr/bin/clang ]]; then
	CLANG_BIN=/usr/bin/clang
else
	CLANG_BIN=/usr/bin/clang-7
fi

make LLC=$LLC_BIN CLANG=$CLANG_BIN CC=/usr/bin/gcc-8 KERNELDIR=$sourcedir
```

Lowaiz: Hi @FedeDP,

> I think this would be a valuable improvement that perhaps could go in a different PR, wdyt?

This enhancement make usable the non-root security context, so I guess we should put them together. 

I already pushed the changes, but I can move them elsewhere if needed 
FedeDP: > This enhancement make usable the non-root security context, so I guess we should put them together.

Yep, no problem on my side :) 
poiana: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/falcosecurity/driverkit/pull/197#pullrequestreview-1080737342" title="Approved">FedeDP</a>*, *<a href="https://github.com/falcosecurity/driverkit/pull/197#" title="Author self-approved">Lowaiz</a>*

The full list of commands accepted by this bot can be found [here](https://prow.falco.org/command-help?repo=falcosecurity%2Fdriverkit).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/falcosecurity/driverkit/blob/master/OWNERS)~~ [FedeDP]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
poiana: LGTM label has been added.  <details>Git tree hash: 6909a3694c978790a47bb7e4f0e83f5afe8871b0</details>

Patch:
diff --git a/cmd/config_options.go b/cmd/config_options.go
index 818bda3..f8d4951 100644
--- a/cmd/config_options.go
+++ b/cmd/config_options.go
@@ -9,8 +9,8 @@ import (
 	logger "github.com/sirupsen/logrus"
 )
 
-var validProcessors = []string{"docker", "kubernetes"}
-var aliasProcessors = []string{"docker", "k8s"}
+var validProcessors = []string{"docker", "kubernetes", "kubernetes-in-cluster"}
+var aliasProcessors = []string{"docker", "k8s", "k8s-ic"}
 var configOptions *ConfigOptions
 
 // ConfigOptions represent the persistent configuration flags of driverkit.
diff --git a/cmd/kubernetes.go b/cmd/kubernetes.go
index 42a1f20..bd1e3ce 100644
--- a/cmd/kubernetes.go
+++ b/cmd/kubernetes.go
@@ -34,6 +34,10 @@ func NewKubernetesCmd(rootOpts *RootOptions, rootFlags *pflag.FlagSet) *cobra.Co
 		f.Usage = upperAfterPointRegexp.ReplaceAllString(f.Usage, ", ${1}")
 		f.Usage = upperAfterCommaRegexp.ReplaceAllStringFunc(f.Usage, strings.ToLower)
 	})
+	// Add Kubernetes pods options flags
+	flags := kubernetesCmd.Flags()
+	addKubernetesFlags(flags)
+	kubernetesCmd.PersistentFlags().AddFlagSet(flags)
 	// Add root flags
 	kubernetesCmd.PersistentFlags().AddFlagSet(rootFlags)
 
@@ -75,7 +79,6 @@ func kubernetesRun(cmd *cobra.Command, args []string, kubefactory factory.Factor
 		return err
 	}
 
-	buildProcessor := driverbuilder.NewKubernetesBuildProcessor(kc.CoreV1(), clientConfig, namespaceStr, viper.GetInt("timeout"), viper.GetString("proxy"))
-
+	buildProcessor := driverbuilder.NewKubernetesBuildProcessor(kc.CoreV1(), clientConfig, kubernetesOptions.RunAsUser, kubernetesOptions.Namespace, kubernetesOptions.ImagePullSecret, viper.GetInt("timeout"), viper.GetString("proxy"))
 	return buildProcessor.Start(b)
 }
diff --git a/cmd/kubernetes_in_cluster.go b/cmd/kubernetes_in_cluster.go
new file mode 100644
index 0000000..5a7d843
--- /dev/null
+++ b/cmd/kubernetes_in_cluster.go
@@ -0,0 +1,59 @@
+package cmd
+
+import (
+	"github.com/falcosecurity/driverkit/pkg/driverbuilder"
+	"github.com/falcosecurity/driverkit/pkg/kubernetes/factory"
+	logger "github.com/sirupsen/logrus"
+	"github.com/spf13/cobra"
+	"github.com/spf13/pflag"
+	"github.com/spf13/viper"
+	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/rest"
+)
+
+// NewKubernetesInClusterCmd creates the `driverkit kubernetes` command.
+func NewKubernetesInClusterCmd(rootOpts *RootOptions, rootFlags *pflag.FlagSet) *cobra.Command {
+	kubernetesInClusterCmd := &cobra.Command{
+		Use:     "kubernetes-in-cluster",
+		Short:   "Build Falco kernel modules and eBPF probes against a Kubernetes cluster inside a Kubernetes cluster.",
+		Aliases: []string{"k8s-ic"},
+	}
+
+	// Add Kubernetes pods options flags
+	flags := kubernetesInClusterCmd.Flags()
+	addKubernetesFlags(flags)
+	kubernetesInClusterCmd.PersistentFlags().AddFlagSet(flags)
+	// Add root flags
+	kubernetesInClusterCmd.PersistentFlags().AddFlagSet(rootFlags)
+
+	kubernetesInClusterCmd.Run = func(cmd *cobra.Command, args []string) {
+		logger.WithField("processor", cmd.Name()).Info("driver building, it will take a few seconds")
+		if !configOptions.DryRun {
+			config, err := rest.InClusterConfig()
+			if err != nil {
+				logger.WithError(err).Fatal("exiting")
+			}
+			if err = factory.SetKubernetesDefaults(config); err != nil {
+				logger.WithError(err).Fatal("exiting")
+			}
+			if err = kubernetesInClusterRun(cmd, args, config, rootOpts); err != nil {
+				logger.WithError(err).Fatal("exiting")
+			}
+		}
+	}
+
+	return kubernetesInClusterCmd
+}
+
+func kubernetesInClusterRun(_ *cobra.Command, _ []string, kubeConfig *rest.Config, rootOpts *RootOptions) error {
+	b := rootOpts.toBuild()
+
+	kc, err := kubernetes.NewForConfig(kubeConfig)
+	if err != nil {
+		return err
+	}
+
+	buildProcessor := driverbuilder.NewKubernetesBuildProcessor(kc.CoreV1(), kubeConfig, kubernetesOptions.RunAsUser, kubernetesOptions.Namespace, kubernetesOptions.ImagePullSecret, viper.GetInt("timeout"), viper.GetString("proxy"))
+
+	return buildProcessor.Start(b)
+}
diff --git a/cmd/kubernetes_options.go b/cmd/kubernetes_options.go
new file mode 100644
index 0000000..829fdb9
--- /dev/null
+++ b/cmd/kubernetes_options.go
@@ -0,0 +1,17 @@
+package cmd
+
+import flag "github.com/spf13/pflag"
+
+var kubernetesOptions = &KubeOptions{}
+
+type KubeOptions struct {
+	RunAsUser       int64  `json:"runAsUser,omitempty" protobuf:"varint,2,opt,name=runAsUser" default:"0"`
+	Namespace       string `validate:"required" name:"namespace" default:"default"`
+	ImagePullSecret string `validate:"omitempty" name:"image-pull-secret" default:""`
+}
+
+func addKubernetesFlags(flags *flag.FlagSet) {
+	flags.StringVarP(&kubernetesOptions.Namespace, "namespace", "n", "default", "If present, the namespace scope for the pods and its config ")
+	flags.Int64Var(&kubernetesOptions.RunAsUser, "run-as-user", 0, "Pods runner user")
+	flags.StringVar(&kubernetesOptions.ImagePullSecret, "image-pull-secret", "", "ImagePullSecret")
+}
diff --git a/cmd/root.go b/cmd/root.go
index 6327c32..a7b5a78 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -154,6 +154,7 @@ func NewRootCmd() *RootCmd {
 
 	// Subcommands
 	rootCmd.AddCommand(NewKubernetesCmd(rootOpts, flags))
+	rootCmd.AddCommand(NewKubernetesInClusterCmd(rootOpts, flags))
 	rootCmd.AddCommand(NewDockerCmd(rootOpts, flags))
 	rootCmd.AddCommand(NewCompletionCmd())
 
diff --git a/docs/driverkit.md b/docs/driverkit.md
index fd9ebe9..6a2530c 100644
--- a/docs/driverkit.md
+++ b/docs/driverkit.md
@@ -2,10 +2,6 @@
 
 A command line tool to build Falco kernel modules and eBPF probes.
 
-### Synopsis
-
-A command line tool to build Falco kernel modules and eBPF probes.
-
 ```
 driverkit
 ```
@@ -13,22 +9,23 @@ driverkit
 ### Options
 
 ```
-      --architecture string       target architecture for the built driver (default "$runtime.GOARCH")
+      --architecture string       target architecture for the built driver, one of [amd64,arm64] (default "amd64")
+      --builderimage string       docker image to be used to build the kernel module and eBPF probe. If not provided, the default image will be used. (default "falcosecurity/driverkit-builder:latest")
   -c, --config string             config file path (default $HOME/.driverkit.yaml if exists)
       --driverversion string      driver version as a git commit hash or as a git tag (default "master")
       --dryrun                    do not actually perform the action
   -h, --help                      help for driverkit
       --kernelconfigdata string   base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc
       --kernelrelease string      kernel release to build the module for, it can be found by executing 'uname -v'
-      --kernelurls []string       list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>")
-      --kernelversion uint16      kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default 1)
+      --kernelurls strings        list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>")
+      --kernelversion string      kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1")
   -l, --loglevel string           log level (default "info")
       --moduledevicename string   kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco")
       --moduledrivername string   kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco")
       --output-module string      filepath where to save the resulting kernel module
       --output-probe string       filepath where to save the resulting eBPF probe
       --proxy string              the proxy to use to download data
-  -t, --target string             the system to target the build for
+  -t, --target string             the system to target the build for, one of [amazonlinux,amazonlinux2,amazonlinux2022,archlinux,centos,debian,flatcar,minikube,photon,redhat,rocky,ubuntu,ubuntu-aws,ubuntu-generic,vanilla]
       --timeout int               timeout in seconds (default 120)
 ```
 
@@ -37,4 +34,5 @@ driverkit
 * [driverkit completion](driverkit_completion.md)	 - Generates completion scripts.
 * [driverkit docker](driverkit_docker.md)	 - Build Falco kernel modules and eBPF probes against a docker daemon.
 * [driverkit kubernetes](driverkit_kubernetes.md)	 - Build Falco kernel modules and eBPF probes against a Kubernetes cluster.
+* [driverkit kubernetes-in-cluster](driverkit_kubernetes-in-cluster.md)	 - Build Falco kernel modules and eBPF probes against a Kubernetes cluster inside a Kubernetes cluster.
 
diff --git a/docs/driverkit_docker.md b/docs/driverkit_docker.md
index 266b24e..205a36f 100644
--- a/docs/driverkit_docker.md
+++ b/docs/driverkit_docker.md
@@ -2,10 +2,6 @@
 
 Build Falco kernel modules and eBPF probes against a docker daemon.
 
-### Synopsis
-
-Build Falco kernel modules and eBPF probes against a docker daemon.
-
 ```
 driverkit docker [flags]
 ```
@@ -13,7 +9,7 @@ driverkit docker [flags]
 ### Options
 
 ```
-      --architecture string       target architecture for the built driver (default "$runtime.GOARCH")
+      --architecture string       target architecture for the built driver, one of [amd64,arm64] (default "amd64")
       --builderimage string       docker image to be used to build the kernel module and eBPF probe. If not provided, the default image will be used. (default "falcosecurity/driverkit-builder:latest")
   -c, --config string             config file path (default $HOME/.driverkit.yaml if exists)
       --driverversion string      driver version as a git commit hash or as a git tag (default "master")
@@ -21,15 +17,15 @@ driverkit docker [flags]
   -h, --help                      help for docker
       --kernelconfigdata string   base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc
       --kernelrelease string      kernel release to build the module for, it can be found by executing 'uname -v'
-      --kernelurls []string       list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>")
-      --kernelversion uint16      kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default 1)
+      --kernelurls strings        list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>")
+      --kernelversion string      kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1")
   -l, --loglevel string           log level (default "info")
       --moduledevicename string   kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco")
       --moduledrivername string   kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco")
       --output-module string      filepath where to save the resulting kernel module
       --output-probe string       filepath where to save the resulting eBPF probe
       --proxy string              the proxy to use to download data
-  -t, --target string             the system to target the build for
+  -t, --target string             the system to target the build for, one of [amazonlinux,amazonlinux2,amazonlinux2022,archlinux,centos,debian,flatcar,minikube,photon,redhat,rocky,ubuntu,ubuntu-aws,ubuntu-generic,vanilla]
       --timeout int               timeout in seconds (default 120)
 ```
 
diff --git a/docs/driverkit_kubernetes-in-cluster.md b/docs/driverkit_kubernetes-in-cluster.md
new file mode 100644
index 0000000..4a8b968
--- /dev/null
+++ b/docs/driverkit_kubernetes-in-cluster.md
@@ -0,0 +1,38 @@
+## driverkit kubernetes-in-cluster
+
+Build Falco kernel modules and eBPF probes against a Kubernetes cluster inside a Kubernetes cluster.
+
+```
+driverkit kubernetes-in-cluster [flags]
+```
+
+### Options
+
+```
+      --architecture string        target architecture for the built driver, one of [amd64,arm64] (default "amd64")
+      --builderimage string        docker image to be used to build the kernel module and eBPF probe. If not provided, the default image will be used. (default "falcosecurity/driverkit-builder:latest")
+  -c, --config string              config file path (default $HOME/.driverkit.yaml if exists)
+      --driverversion string       driver version as a git commit hash or as a git tag (default "master")
+      --dryrun                     do not actually perform the action
+  -h, --help                       help for kubernetes-in-cluster
+      --image-pull-secret string   ImagePullSecret
+      --kernelconfigdata string    base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc
+      --kernelrelease string       kernel release to build the module for, it can be found by executing 'uname -v'
+      --kernelurls strings         list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>")
+      --kernelversion string       kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1")
+  -l, --loglevel string            log level (default "info")
+      --moduledevicename string    kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco")
+      --moduledrivername string    kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco")
+  -n, --namespace string           If present, the namespace scope for the pods and its config  (default "default")
+      --output-module string       filepath where to save the resulting kernel module
+      --output-probe string        filepath where to save the resulting eBPF probe
+      --proxy string               the proxy to use to download data
+      --run-as-user int            Pods runner user
+  -t, --target string              the system to target the build for, one of [amazonlinux,amazonlinux2,amazonlinux2022,archlinux,centos,debian,flatcar,minikube,photon,redhat,rocky,ubuntu,ubuntu-aws,ubuntu-generic,vanilla]
+      --timeout int                timeout in seconds (default 120)
+```
+
+### SEE ALSO
+
+* [driverkit](driverkit.md)	 - A command line tool to build Falco kernel modules and eBPF probes.
+
diff --git a/docs/driverkit_kubernetes.md b/docs/driverkit_kubernetes.md
index 958b598..1992af5 100644
--- a/docs/driverkit_kubernetes.md
+++ b/docs/driverkit_kubernetes.md
@@ -2,10 +2,6 @@
 
 Build Falco kernel modules and eBPF probes against a Kubernetes cluster.
 
-### Synopsis
-
-Build Falco kernel modules and eBPF probes against a Kubernetes cluster.
-
 ```
 driverkit kubernetes [flags]
 ```
@@ -13,10 +9,12 @@ driverkit kubernetes [flags]
 ### Options
 
 ```
-      --architecture string            target architecture for the built driver (default "$runtime.GOARCH")
-      --as string                      username to impersonate for the operation
+      --architecture string            target architecture for the built driver, one of [amd64,arm64] (default "amd64")
+      --as string                      username to impersonate for the operation, user could be a regular user or a service account in a namespace
       --as-group stringArray           group to impersonate for the operation, this flag can be repeated to specify multiple groups
-      --cache-dir string               default HTTP cache directory (default "$HOME/.kube/http-cache")
+      --as-uid string                  uID to impersonate for the operation
+      --builderimage string            docker image to be used to build the kernel module and eBPF probe. If not provided, the default image will be used. (default "falcosecurity/driverkit-builder:latest")
+      --cache-dir string               default cache directory (default "$HOME/.kube/cache")
       --certificate-authority string   path to a cert file for the certificate authority
       --client-certificate string      path to a client certificate file for TLS
       --client-key string              path to a client key file for TLS
@@ -26,23 +24,26 @@ driverkit kubernetes [flags]
       --driverversion string           driver version as a git commit hash or as a git tag (default "master")
       --dryrun                         do not actually perform the action
   -h, --help                           help for kubernetes
+      --image-pull-secret string       ImagePullSecret
       --insecure-skip-tls-verify       if true, the server's certificate will not be checked for validity, this will make your HTTPS connections insecure
       --kernelconfigdata string        base64 encoded kernel config data: in some systems it can be found under the /boot directory, in other it is gzip compressed under /proc
       --kernelrelease string           kernel release to build the module for, it can be found by executing 'uname -v'
-      --kernelurls []string            list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>")
-      --kernelversion uint16           kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default 1)
+      --kernelurls strings             list of kernel header urls (e.g. --kernelurls <URL1> --kernelurls <URL2> --kernelurls "<URL3>,<URL4>")
+      --kernelversion string           kernel version to build the module for, it's the numeric value after the hash when you execute 'uname -v' (default "1")
       --kubeconfig string              path to the kubeconfig file to use for CLI requests
   -l, --loglevel string                log level (default "info")
       --moduledevicename string        kernel module device name (the default is falco, so the device will be under /dev/falco*) (default "falco")
       --moduledrivername string        kernel module driver name, i.e. the name you see when you check installed modules via lsmod (default "falco")
-  -n, --namespace string               if present, the namespace scope for this CLI request
+  -n, --namespace string               If present, the namespace scope for the pods and its config  (default "default")
       --output-module string           filepath where to save the resulting kernel module
       --output-probe string            filepath where to save the resulting eBPF probe
       --proxy string                   the proxy to use to download data
       --request-timeout string         the length of time to wait before giving up on a single server request, non-zero values should contain a corresponding time unit (e.g, 1s, 2m, 3h), a value of zero means don't timeout requests (default "0")
+      --run-as-user int                Pods runner user
   -s, --server string                  the address and port of the Kubernetes API server
-  -t, --target string                  the system to target the build for
+  -t, --target string                  the system to target the build for, one of [amazonlinux,amazonlinux2,amazonlinux2022,archlinux,centos,debian,flatcar,minikube,photon,redhat,rocky,ubuntu,ubuntu-aws,ubuntu-generic,vanilla]
       --timeout int                    timeout in seconds (default 120)
+      --tls-server-name string         server name to use for server certificate validation, if it is not provided, the hostname used to contact the server is used
       --token string                   bearer token for authentication to the API server
       --user string                    the name of the kubeconfig user to use
 ```
diff --git a/pkg/driverbuilder/builder/templates/amazonlinux.sh b/pkg/driverbuilder/builder/templates/amazonlinux.sh
index 0a545f8..7c1a24a 100644
--- a/pkg/driverbuilder/builder/templates/amazonlinux.sh
+++ b/pkg/driverbuilder/builder/templates/amazonlinux.sh
@@ -37,6 +37,6 @@ modinfo {{ .ModuleFullPath }}
 {{ if .BuildProbe }}
 # Build the eBPF probe
 cd {{ .DriverBuildDir }}/bpf
-make LLC=/usr/bin/llc-{{ .LLVMVersion }} CLANG=/usr/bin/clang-{{ .LLVMVersion }} CC=/usr/bin/gcc KERNELDIR=/tmp/kernel
+make LLC=/usr/bin/llc-{{ .LLVMVersion }} CLANG=/usr/bin/clang-{{ .LLVMVersion }} KERNELDIR=/tmp/kernel
 ls -l probe.o
 {{ end }}
\ No newline at end of file
diff --git a/pkg/driverbuilder/builder/templates/archlinux.sh b/pkg/driverbuilder/builder/templates/archlinux.sh
index 0a3196c..b0795e8 100644
--- a/pkg/driverbuilder/builder/templates/archlinux.sh
+++ b/pkg/driverbuilder/builder/templates/archlinux.sh
@@ -21,13 +21,10 @@ rm -Rf /tmp/kernel
 mkdir -p /tmp/kernel
 mv usr/lib/modules/*/build/* /tmp/kernel
 
-# Change current gcc
-ln -sf /usr/bin/gcc-{{ .GCCVersion }} /usr/bin/gcc
-
 {{ if .BuildModule }}
 # Build the module
 cd {{ .DriverBuildDir }}
-make KERNELDIR=/tmp/kernel
+make CC=/usr/bin/gcc-{{ .GCCVersion }} KERNELDIR=/tmp/kernel
 mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }}
 strip -g {{ .ModuleFullPath }}
 # Print results
@@ -37,6 +34,6 @@ modinfo {{ .ModuleFullPath }}
 {{ if .BuildProbe }}
 # Build the eBPF probe
 cd {{ .DriverBuildDir }}/bpf
-make LLC=/usr/bin/llc-7 CLANG=/usr/bin/clang-7 CC=/usr/bin/gcc KERNELDIR=/tmp/kernel
+make LLC=/usr/bin/llc-7 CLANG=/usr/bin/clang-7 KERNELDIR=/tmp/kernel
 ls -l probe.o
 {{ end }}
\ No newline at end of file
diff --git a/pkg/driverbuilder/builder/templates/centos.sh b/pkg/driverbuilder/builder/templates/centos.sh
index 500e94f..9bf6fcf 100644
--- a/pkg/driverbuilder/builder/templates/centos.sh
+++ b/pkg/driverbuilder/builder/templates/centos.sh
@@ -21,13 +21,10 @@ rm -Rf /tmp/kernel
 mkdir -p /tmp/kernel
 mv usr/src/kernels/*/* /tmp/kernel
 
-# Change current gcc
-ln -sf /usr/bin/gcc-{{ .GCCVersion }} /usr/bin/gcc
-
 {{ if .BuildModule }}
 # Build the module
 cd {{ .DriverBuildDir }}
-make KERNELDIR=/tmp/kernel
+make CC=/usr/bin/gcc-{{ .GCCVersion }} KERNELDIR=/tmp/kernel
 mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }}
 strip -g {{ .ModuleFullPath }}
 # Print results
@@ -37,6 +34,6 @@ modinfo {{ .ModuleFullPath }}
 {{ if .BuildProbe }}
 # Build the eBPF probe
 cd {{ .DriverBuildDir }}/bpf
-make LLC=/usr/bin/llc-7 CLANG=/usr/bin/clang-7 CC=/usr/bin/gcc KERNELDIR=/tmp/kernel
+make LLC=/usr/bin/llc-7 CLANG=/usr/bin/clang-7 KERNELDIR=/tmp/kernel
 ls -l probe.o
 {{ end }}
\ No newline at end of file
diff --git a/pkg/driverbuilder/builder/templates/debian.sh b/pkg/driverbuilder/builder/templates/debian.sh
index 87ea014..7f9302c 100644
--- a/pkg/driverbuilder/builder/templates/debian.sh
+++ b/pkg/driverbuilder/builder/templates/debian.sh
@@ -42,6 +42,6 @@ modinfo {{ .ModuleFullPath }}
 {{ if .BuildProbe }}
 # Build the eBPF probe
 cd {{ .DriverBuildDir }}/bpf
-make LLC=/usr/bin/llc-{{ .LLVMVersion }} CLANG=/usr/bin/clang-{{ .LLVMVersion }} CC=/usr/bin/gcc-8 KERNELDIR=$sourcedir
+make LLC=/usr/bin/llc-{{ .LLVMVersion }} CLANG=/usr/bin/clang-{{ .LLVMVersion }} KERNELDIR=$sourcedir
 ls -l probe.o
 {{ end }}
\ No newline at end of file
diff --git a/pkg/driverbuilder/builder/templates/flatcar.sh b/pkg/driverbuilder/builder/templates/flatcar.sh
index 74c2280..614d772 100644
--- a/pkg/driverbuilder/builder/templates/flatcar.sh
+++ b/pkg/driverbuilder/builder/templates/flatcar.sh
@@ -20,9 +20,6 @@ rm -Rf /tmp/kernel
 mkdir -p /tmp/kernel
 mv /tmp/kernel-download/*/* /tmp/kernel
 
-# Change current gcc
-ln -sf /usr/bin/gcc-{{ .GCCVersion }} /usr/bin/gcc
-
 curl --silent -o /tmp/kernel.config -SL {{ .KernelConfigURL }}
 
 cd /tmp/kernel
@@ -33,7 +30,7 @@ make KCONFIG_CONFIG=/tmp/kernel.config modules_prepare
 {{ if .BuildModule }}
 # Build the module
 cd {{ .DriverBuildDir }}
-make KERNELDIR=/tmp/kernel
+make CC=/usr/bin/gcc-{{ .GCCVersion }} KERNELDIR=/tmp/kernel
 mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }}
 strip -g {{ .ModuleFullPath }}
 # Print results
@@ -43,6 +40,6 @@ modinfo {{ .ModuleFullPath }}
 {{ if .BuildProbe }}
 # Build the eBPF probe
 cd {{ .DriverBuildDir }}/bpf
-make LLC=/usr/bin/llc-12 CLANG=/usr/bin/clang-12 CC=/usr/bin/gcc KERNELDIR=/tmp/kernel
+make LLC=/usr/bin/llc-12 CLANG=/usr/bin/clang-12 KERNELDIR=/tmp/kernel
 ls -l probe.o
 {{ end }}
\ No newline at end of file
diff --git a/pkg/driverbuilder/builder/templates/photonos.sh b/pkg/driverbuilder/builder/templates/photonos.sh
index c7be687..d973461 100644
--- a/pkg/driverbuilder/builder/templates/photonos.sh
+++ b/pkg/driverbuilder/builder/templates/photonos.sh
@@ -21,13 +21,11 @@ rm -Rf /tmp/kernel
 mkdir -p /tmp/kernel
 mv usr/src/linux-headers-*/* /tmp/kernel
 
-# Change current gcc
-ln -sf /usr/bin/gcc-{{ .GCCVersion }} /usr/bin/gcc
 {{ if .BuildModule }}
 
 # Build the module
 cd {{ .DriverBuildDir }}
-make KERNELDIR=/tmp/kernel
+make CC=/usr/bin/gcc-{{ .GCCVersion }} KERNELDIR=/tmp/kernel
 mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }}
 strip -g {{ .ModuleFullPath }}
 
@@ -38,6 +36,6 @@ modinfo {{ .ModuleFullPath }}
 
 # Build the eBPF probe
 cd {{ .DriverBuildDir }}/bpf
-make LLC=/usr/bin/llc-7 CLANG=/usr/bin/clang-7 CC=/usr/bin/gcc KERNELDIR=/tmp/kernel
+make LLC=/usr/bin/llc-7 CLANG=/usr/bin/clang-7 KERNELDIR=/tmp/kernel
 ls -l probe.o
 {{ end }}
\ No newline at end of file
diff --git a/pkg/driverbuilder/builder/templates/redhat.sh b/pkg/driverbuilder/builder/templates/redhat.sh
index 1ca0f05..c0dc5e2 100644
--- a/pkg/driverbuilder/builder/templates/redhat.sh
+++ b/pkg/driverbuilder/builder/templates/redhat.sh
@@ -36,6 +36,6 @@ modinfo {{ .ModuleFullPath }}
 {{ if .BuildProbe }}
 # Build the eBPF probe
 cd {{ .DriverBuildDir }}/bpf
-make LLC=/usr/bin/llc CLANG=/usr/bin/clang CC=/usr/bin/gcc KERNELDIR=/tmp/kernel
+make LLC=/usr/bin/llc CLANG=/usr/bin/clang KERNELDIR=/tmp/kernel
 ls -l probe.o
 {{ end }}
\ No newline at end of file
diff --git a/pkg/driverbuilder/builder/templates/rocky.sh b/pkg/driverbuilder/builder/templates/rocky.sh
index 500e94f..9bf6fcf 100644
--- a/pkg/driverbuilder/builder/templates/rocky.sh
+++ b/pkg/driverbuilder/builder/templates/rocky.sh
@@ -21,13 +21,10 @@ rm -Rf /tmp/kernel
 mkdir -p /tmp/kernel
 mv usr/src/kernels/*/* /tmp/kernel
 
-# Change current gcc
-ln -sf /usr/bin/gcc-{{ .GCCVersion }} /usr/bin/gcc
-
 {{ if .BuildModule }}
 # Build the module
 cd {{ .DriverBuildDir }}
-make KERNELDIR=/tmp/kernel
+make CC=/usr/bin/gcc-{{ .GCCVersion }} KERNELDIR=/tmp/kernel
 mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }}
 strip -g {{ .ModuleFullPath }}
 # Print results
@@ -37,6 +34,6 @@ modinfo {{ .ModuleFullPath }}
 {{ if .BuildProbe }}
 # Build the eBPF probe
 cd {{ .DriverBuildDir }}/bpf
-make LLC=/usr/bin/llc-7 CLANG=/usr/bin/clang-7 CC=/usr/bin/gcc KERNELDIR=/tmp/kernel
+make LLC=/usr/bin/llc-7 CLANG=/usr/bin/clang-7 KERNELDIR=/tmp/kernel
 ls -l probe.o
 {{ end }}
\ No newline at end of file
diff --git a/pkg/driverbuilder/builder/templates/ubuntu.sh b/pkg/driverbuilder/builder/templates/ubuntu.sh
index 0d2db91..370761f 100644
--- a/pkg/driverbuilder/builder/templates/ubuntu.sh
+++ b/pkg/driverbuilder/builder/templates/ubuntu.sh
@@ -24,13 +24,10 @@ tar -xf data.tar.*
 cd /tmp/kernel-download/usr/src/
 sourcedir=$(find . -type d -name "{{ .KernelHeadersPattern }}" | head -n 1 | xargs readlink -f)
 
-# Change current gcc
-ln -sf /usr/bin/gcc-{{ .GCCVersion }} /usr/bin/gcc
-
 {{ if .BuildModule }}
 # Build the module
 cd {{ .DriverBuildDir }}
-make KERNELDIR=$sourcedir
+make CC=/usr/bin/gcc-{{ .GCCVersion }} KERNELDIR=$sourcedir
 mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }}
 strip -g {{ .ModuleFullPath }}
 # Print results
@@ -52,6 +49,6 @@ else
 	CLANG_BIN=/usr/bin/clang-7
 fi
 
-make LLC=$LLC_BIN CLANG=$CLANG_BIN CC=/usr/bin/gcc-8 KERNELDIR=$sourcedir
+make LLC=$LLC_BIN CLANG=$CLANG_BIN KERNELDIR=$sourcedir
 ls -l probe.o
 {{ end }}
\ No newline at end of file
diff --git a/pkg/driverbuilder/builder/templates/vanilla.sh b/pkg/driverbuilder/builder/templates/vanilla.sh
index b21b47a..647bd13 100644
--- a/pkg/driverbuilder/builder/templates/vanilla.sh
+++ b/pkg/driverbuilder/builder/templates/vanilla.sh
@@ -45,6 +45,6 @@ modinfo {{ .ModuleFullPath }}
 {{ if .BuildProbe }}
 # Build the eBPF probe
 cd {{ .DriverBuildDir }}/bpf
-make LLC=/usr/bin/llc-7 CLANG=/usr/bin/clang-7 CC=/usr/bin/gcc-8 KERNELDIR=/tmp/kernel
+make LLC=/usr/bin/llc-7 CLANG=/usr/bin/clang-7 KERNELDIR=/tmp/kernel
 ls -l probe.o
 {{ end }}
\ No newline at end of file
diff --git a/pkg/driverbuilder/kubernetes.go b/pkg/driverbuilder/kubernetes.go
index cb3293a..7767e4b 100644
--- a/pkg/driverbuilder/kubernetes.go
+++ b/pkg/driverbuilder/kubernetes.go
@@ -30,24 +30,28 @@ const KubernetesBuildProcessorName = "kubernetes"
 const falcoBuilderUIDLabel = "org.falcosecurity/driverkit-uid"
 
 type KubernetesBuildProcessor struct {
-	coreV1Client v1.CoreV1Interface
-	clientConfig *restclient.Config
-	namespace    string
-	timeout      int
-	proxy        string
+	coreV1Client    v1.CoreV1Interface
+	clientConfig    *restclient.Config
+	runAsUser       int64
+	namespace       string
+	imagePullSecret string
+	timeout         int
+	proxy           string
 }
 
 // NewKubernetesBuildProcessor constructs a KubernetesBuildProcessor
 // starting from a kubernetes.Clientset. bufferSize represents the length of the
 // channel we use to do the builds. A bigger bufferSize will mean that we can save more Builds
 // for processing, however setting this to a big value will have impacts
-func NewKubernetesBuildProcessor(corev1Client v1.CoreV1Interface, clientConfig *restclient.Config, namespace string, timeout int, proxy string) *KubernetesBuildProcessor {
+func NewKubernetesBuildProcessor(corev1Client v1.CoreV1Interface, clientConfig *restclient.Config, runAsUser int64, namespace string, imagePullSecret string, timeout int, proxy string) *KubernetesBuildProcessor {
 	return &KubernetesBuildProcessor{
-		coreV1Client: corev1Client,
-		clientConfig: clientConfig,
-		namespace:    namespace,
-		timeout:      timeout,
-		proxy:        proxy,
+		coreV1Client:    corev1Client,
+		clientConfig:    clientConfig,
+		runAsUser:       runAsUser,
+		namespace:       namespace,
+		imagePullSecret: imagePullSecret,
+		timeout:         timeout,
+		proxy:           proxy,
 	}
 }
 
@@ -91,7 +95,7 @@ func (bp *KubernetesBuildProcessor) buildModule(build *builder.Build) error {
 
 	// Append a script to the entrypoint to wait
 	// for the module to be ready before exiting PID 1
-	res = fmt.Sprintf("%s\n%s", res, waitForModuleScript)
+	res = fmt.Sprintf("%s\n%s", res, waitForLockScript)
 
 	buildCmd := []string{
 		"/bin/bash",
@@ -132,7 +136,7 @@ func (bp *KubernetesBuildProcessor) buildModule(build *builder.Build) error {
 			"kernel.config":         string(configDecoded),
 			"module-Makefile":       bufMakefile.String(),
 			"fill-driver-config.sh": bufFillDriverConfig.String(),
-			"module-downloader.sh":  waitForModuleAndCat,
+			"downloader.sh":         waitForFileAndCat,
 		},
 	}
 	// Construct environment variable array of corev1.EnvVar
@@ -156,11 +160,16 @@ func (bp *KubernetesBuildProcessor) buildModule(build *builder.Build) error {
 		builderImage = build.CustomBuilderImage
 	}
 
+	secuContext := corev1.PodSecurityContext{
+		RunAsUser: &bp.runAsUser,
+	}
 	pod := &corev1.Pod{
 		ObjectMeta: commonMeta,
 		Spec: corev1.PodSpec{
 			ActiveDeadlineSeconds: pointer.Int64Ptr(deadline),
 			RestartPolicy:         corev1.RestartPolicyNever,
+			SecurityContext:       &secuContext,
+			ImagePullSecrets:      []corev1.LocalObjectReference{{Name: bp.imagePullSecret}},
 			Containers: []corev1.Container{
 				{
 					Name:            name,
@@ -209,22 +218,30 @@ func (bp *KubernetesBuildProcessor) buildModule(build *builder.Build) error {
 	if err != nil {
 		return err
 	}
+	defer configClient.Delete(ctx, cm.Name, metav1.DeleteOptions{})
 	_, err = podClient.Create(ctx, pod, metav1.CreateOptions{})
 	if err != nil {
 		return err
 	}
+	defer podClient.Delete(ctx, pod.Name, metav1.DeleteOptions{})
 
-	out, err := os.Create(build.ModuleFilePath)
+	outModule, err := os.Create(build.ModuleFilePath)
+	if err != nil {
+		return err
+	}
+	defer outModule.Close()
+
+	outProbe, err := os.Create(build.ProbeFilePath)
 
 	if err != nil {
 		return err
 	}
-	defer out.Close()
+	defer outProbe.Close()
 
-	return bp.copyModuleFromPodWithUID(ctx, out, namespace, string(uid))
+	return bp.copyModuleAndProbeFromPodWithUID(ctx, outModule, outProbe, namespace, string(uid))
 }
 
-func (bp *KubernetesBuildProcessor) copyModuleFromPodWithUID(ctx context.Context, out io.Writer, namespace string, falcoBuilderUID string) error {
+func (bp *KubernetesBuildProcessor) copyModuleAndProbeFromPodWithUID(ctx context.Context, outModule io.Writer, outProbe io.Writer, namespace string, falcoBuilderUID string) error {
 	namespacedClient := bp.coreV1Client.Pods(namespace)
 	watch, err := namespacedClient.Watch(ctx, metav1.ListOptions{
 		LabelSelector: fmt.Sprintf("%s=%s", falcoBuilderUIDLabel, falcoBuilderUID),
@@ -251,20 +268,53 @@ func (bp *KubernetesBuildProcessor) copyModuleFromPodWithUID(ctx context.Context
 				continue
 			}
 			if p.Status.Phase == corev1.PodRunning {
-				logger.WithField(falcoBuilderUIDLabel, falcoBuilderUID).Info("start downloading module from pod")
-				err = copySingleFileFromPod(out, bp.coreV1Client, bp.clientConfig, p.Namespace, p.Name)
+				logger.WithField(falcoBuilderUIDLabel, falcoBuilderUID).Info("start downloading module and probe from pod")
+				if builder.ModuleFullPath != "" {
+					err = copySingleFileFromPod(outModule, bp.coreV1Client, bp.clientConfig, p.Namespace, p.Name, builder.ModuleFullPath)
+					if err != nil {
+						return err
+					}
+				}
+				if builder.ProbeFullPath != "" {
+					err = copySingleFileFromPod(outProbe, bp.coreV1Client, bp.clientConfig, p.Namespace, p.Name, builder.ProbeFullPath)
+					if err != nil {
+						return err
+					}
+				}
+				err = unlockPod(bp.coreV1Client, bp.clientConfig, p)
 				if err != nil {
 					return err
 				}
-				logger.WithField(falcoBuilderUIDLabel, falcoBuilderUID).Info("completed downloading module from pod")
+				logger.WithField(falcoBuilderUIDLabel, falcoBuilderUID).Info("completed downloading from pod")
 			}
 			return nil
 		}
+	}
+}
 
+func unlockPod(podClient v1.PodsGetter, clientConfig *restclient.Config, pod *corev1.Pod) error {
+	options := &exec.ExecOptions{
+		PodClient: podClient,
+		Config:    clientConfig,
+		Pod:       pod,
+		Command: []string{
+			"rm",
+			"/tmp/download.lock",
+		},
+		Executor: &exec.DefaultRemoteExecutor{},
+	}
+
+	if err := options.Validate(); err != nil {
+		return err
 	}
+	if err := options.Run(); err != nil {
+		return err
+	}
+
+	return nil
 }
 
-func copySingleFileFromPod(out io.Writer, podClient v1.PodsGetter, clientConfig *restclient.Config, namespace, podName string) error {
+func copySingleFileFromPod(out io.Writer, podClient v1.PodsGetter, clientConfig *restclient.Config, namespace string, podName string, fileNameToCopy string) error {
 	if len(namespace) == 0 {
 		return errors.New("need a namespace to copy from pod")
 	}
@@ -281,15 +331,15 @@ func copySingleFileFromPod(out io.Writer, podClient v1.PodsGetter, clientConfig
 				Out:    out,
 				ErrOut: bytes.NewBuffer([]byte{}), //TODO(fntlnz): necessary to deal with errors here?
 			},
-			Stdin: false,
-
+			Stdin:     false,
 			Namespace: namespace,
 			PodName:   podName,
 		},
 
 		Command: []string{
 			"/bin/bash",
-			"/driverkit/module-downloader.sh",
+			"/driverkit/downloader.sh",
+			fileNameToCopy,
 		},
 		Executor: &exec.DefaultRemoteExecutor{},
 	}
diff --git a/pkg/driverbuilder/templates.go b/pkg/driverbuilder/templates.go
index 9ebe6e9..0b4a7a9 100644
--- a/pkg/driverbuilder/templates.go
+++ b/pkg/driverbuilder/templates.go
@@ -3,20 +3,12 @@ package driverbuilder
 import (
 	"io"
 	"text/template"
-
-	"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
 )
 
-var waitForModuleScript = `
+var waitForLockScript = `
 touch /tmp/module-download.lock
 while true; do
-  if [ ! -f ` + builder.ModuleFullPath + ` ]; then
-    echo "Falco module not found - waiting for 10 seconds"
-	sleep 10
-	continue
-  fi
-  echo "module found, wait for the download lock to be released"
-  if [ -f /tmp/module-download.lock ]; then
+  if [ -f /tmp/download.lock ]; then
     echo "Lock not released yet - waiting for 5 seconds"
     sleep 5
     continue
@@ -26,18 +18,17 @@ while true; do
 done
 `
 
-// waitForModuleAndCat MUST only output the file, any other output will break
+// waitForFileAndCat MUST only output the file, any other output will break
 // the download file itself because it goes trough stdout
-var waitForModuleAndCat = `
+var waitForFileAndCat = `
 while true; do
-  if [ ! -f ` + builder.ModuleFullPath + ` ]; then
+  if [ ! -f "$1" ]; then
 	sleep 10 1>&/dev/null
 	continue
   fi
   break
 done
-cat ` + builder.ModuleFullPath + `
-rm /tmp/module-download.lock 1>&/dev/null
+cat "$1"
 `
 
 type makefileData struct {


Test patch:
diff --git a/cmd/testdata/autohelp.txt b/cmd/testdata/autohelp.txt
index 0dc8e05..23c34b7 100644
--- a/cmd/testdata/autohelp.txt
+++ b/cmd/testdata/autohelp.txt
@@ -1,4 +1,4 @@
-INFO specify a valid processor                     processors="[docker kubernetes]"
+INFO specify a valid processor                     processors="[docker kubernetes kubernetes-in-cluster]"
 {{ .Desc }}
 
 {{ .Usage }}
diff --git a/cmd/testdata/templates/commands.txt b/cmd/testdata/templates/commands.txt
index 7889e23..4c624b2 100644
--- a/cmd/testdata/templates/commands.txt
+++ b/cmd/testdata/templates/commands.txt
@@ -1,5 +1,6 @@
 Available Commands:
-  completion  Generates completion scripts.
-  docker      Build Falco kernel modules and eBPF probes against a docker daemon.
-  help        Help about any command
-  kubernetes  Build Falco kernel modules and eBPF probes against a Kubernetes cluster.
\ No newline at end of file
+  completion            Generates completion scripts.
+  docker                Build Falco kernel modules and eBPF probes against a docker daemon.
+  help                  Help about any command
+  kubernetes            Build Falco kernel modules and eBPF probes against a Kubernetes cluster.
+  kubernetes-in-cluster Build Falco kernel modules and eBPF probes against a Kubernetes cluster inside a Kubernetes cluster.
\ No newline at end of file