Skip to content
This repository was archived by the owner on Dec 15, 2021. It is now read-only.

Commit c67245d

Browse files
jamdingandresmgot
authored andcommitted
877 allow controller to use token (#885)
* adding readme * Support setting env variable for bearer token * Revert "adding readme" This reverts commit 6ed2ef2. * formatting * Delete glide.yaml Now Gopkg.toml is used instead * Remove description for CRDs (#887) * Remove description for CRDs * Update docs * Adapt kafka manifest * Renaming GetOverriddenClientConfig to GetInClusterConfig, removing redundant error handler for getting config * adding readme * Support setting env variable for bearer token * Revert "adding readme" This reverts commit 6ed2ef2. * formatting * Renaming GetOverriddenClientConfig to GetInClusterConfig, removing redundant error handler for getting config * Adding docs for KUBELESS_TOKEN_FILE_PATH * Fix format
1 parent 89b32fd commit c67245d

File tree

4 files changed

+57
-6
lines changed

4 files changed

+57
-6
lines changed

cmd/function-controller/function-controller.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import (
3131
"github.com/kubeless/kubeless/pkg/version"
3232
"github.com/sirupsen/logrus"
3333
"github.com/spf13/cobra"
34-
"k8s.io/client-go/rest"
3534
)
3635

3736
const (
@@ -53,7 +52,7 @@ var rootCmd = &cobra.Command{
5352
FunctionClient: kubelessClient,
5453
}
5554

56-
restCfg, err := rest.InClusterConfig()
55+
restCfg, err := utils.GetInClusterConfig()
5756
if err != nil {
5857
logrus.Fatalf("Cannot get REST client: %v", err)
5958
}

docs/function-controller-configuration.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,4 +228,35 @@ It is possible to configure the different images that Kubeless uses for deploy a
228228
- (Optional) Image Pull Secrets: Secret required to pull the image in case the repository is private.
229229
- The image used to populate the base image with the function. This is called `provision-image`. This image should have at least `unzip` and `curl`. It is also possible to specify `provision-image-secret` to specify a secret to pull that image from a private registry.
230230
- The image used to build function images. This is called `builder-image`. This image is optional since its usage can be disabled with the property `enable-build-step`. A Dockerfile to build this image can be found [here](https://github.com/kubeless/kubeless/tree/master/docker/function-image-builder). It is also possible to specify `builder-image-secret` to specify a secret to pull that image from a private registry.
231-
231+
232+
## Authenticate Kubeless Function Controller using OAuth Bearer Token
233+
234+
In some non-RBAC k8s deployments using webhook authorization, service accounts may have insufficient privileges to perform all k8s operations that the Kubeless Function Controller requires for interacting with the cluster. It's possible to override the default behavior of the Kubeless Function Controller using a k8s serviceaccount for authentication with the cluster and instead use a provided OAuth Bearer token for all k8s operations.
235+
236+
This can be done by creating a k8s secret and mounting that secret as a volume on controller pods, then setting the environmental variable `KUBELESS_TOKEN_FILE_PATH` to the filepath of that secret. Be sure to set this environmental variable on the controller template spec or to every pod created in the deployment.
237+
238+
For example, if the bearer token is mounted at /mnt/secrets/bearer-token, this k8s spec can use it:
239+
240+
```yaml
241+
# Kubeless core controller
242+
---
243+
apiVersion: apps/v1beta1
244+
kind: Deployment
245+
metadata:
246+
name: kubeless-controller-manager
247+
namespace: kubeless
248+
labels:
249+
kubeless: controller
250+
spec:
251+
template:
252+
metadata:
253+
labels:
254+
kubeless: controller
255+
spec:
256+
containers:
257+
- env:
258+
- name: KUBELESS_TOKEN_FILE_PATH
259+
value: /mnt/secrets/bearer-token
260+
... # The rest of the Deployment has been omitted
261+
```
262+

pkg/utils/k8sutil.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const (
5656

5757
// GetClient returns a k8s clientset to the request from inside of cluster
5858
func GetClient() kubernetes.Interface {
59-
config, err := rest.InClusterConfig()
59+
config, err := GetInClusterConfig()
6060
if err != nil {
6161
logrus.Fatalf("Can not get kubernetes config: %v", err)
6262
}
@@ -123,7 +123,8 @@ func GetAPIExtensionsClientOutOfCluster() clientsetAPIExtensions.Interface {
123123

124124
// GetAPIExtensionsClientInCluster returns a k8s clientset to access APIExtensions from inside of cluster
125125
func GetAPIExtensionsClientInCluster() clientsetAPIExtensions.Interface {
126-
config, err := rest.InClusterConfig()
126+
config, err := GetInClusterConfig()
127+
127128
if err != nil {
128129
logrus.Fatalf("Can not get kubernetes config: %v", err)
129130
}
@@ -136,10 +137,11 @@ func GetAPIExtensionsClientInCluster() clientsetAPIExtensions.Interface {
136137

137138
// GetFunctionClientInCluster returns function clientset to the request from inside of cluster
138139
func GetFunctionClientInCluster() (versioned.Interface, error) {
139-
config, err := rest.InClusterConfig()
140+
config, err := GetInClusterConfig()
140141
if err != nil {
141142
return nil, err
142143
}
144+
143145
kubelessClient, err := versioned.NewForConfig(config)
144146
if err != nil {
145147
return nil, err

pkg/utils/kubelessutil.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
kubelessApi "github.com/kubeless/kubeless/pkg/apis/kubeless/v1beta1"
3232
"github.com/kubeless/kubeless/pkg/langruntime"
3333
"github.com/sirupsen/logrus"
34+
"io/ioutil"
3435
batchv1 "k8s.io/api/batch/v1"
3536
"k8s.io/api/core/v1"
3637
"k8s.io/api/extensions/v1beta1"
@@ -40,6 +41,7 @@ import (
4041
"k8s.io/apimachinery/pkg/types"
4142
"k8s.io/apimachinery/pkg/util/intstr"
4243
"k8s.io/client-go/kubernetes"
44+
"k8s.io/client-go/rest"
4345
)
4446

4547
// GetFunctionPort returns the port for a function service
@@ -760,6 +762,23 @@ func GetOwnerReference(kind, apiVersion, name string, uid types.UID) ([]metav1.O
760762
}, nil
761763
}
762764

765+
// GetInClusterConfig returns necessary Config object to authenticate k8s clients if env variable is set
766+
func GetInClusterConfig() (*rest.Config, error) {
767+
config, err := rest.InClusterConfig()
768+
769+
tokenFile := os.Getenv("KUBELESS_TOKEN_FILE_PATH")
770+
if len(tokenFile) == 0 {
771+
return config, err
772+
}
773+
tokenBytes, err := ioutil.ReadFile(tokenFile)
774+
if err != nil {
775+
return nil, fmt.Errorf("unable to read file containing oauth token: %s", err)
776+
}
777+
config.BearerToken = string(tokenBytes)
778+
779+
return config, nil
780+
}
781+
763782
func getConfigLocation(apiExtensionsClientset clientsetAPIExtensions.Interface) (ConfigLocation, error) {
764783
configLocation := ConfigLocation{}
765784
controllerNamespace := os.Getenv("KUBELESS_NAMESPACE")

0 commit comments

Comments
 (0)