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

Commit

Permalink
877 allow controller to use token (#885)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
jamding authored and andresmgot committed Aug 17, 2018
1 parent 89b32fd commit c67245d
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 6 deletions.
3 changes: 1 addition & 2 deletions cmd/function-controller/function-controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"github.com/kubeless/kubeless/pkg/version"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"k8s.io/client-go/rest"
)

const (
Expand All @@ -53,7 +52,7 @@ var rootCmd = &cobra.Command{
FunctionClient: kubelessClient,
}

restCfg, err := rest.InClusterConfig()
restCfg, err := utils.GetInClusterConfig()
if err != nil {
logrus.Fatalf("Cannot get REST client: %v", err)
}
Expand Down
33 changes: 32 additions & 1 deletion docs/function-controller-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,35 @@ It is possible to configure the different images that Kubeless uses for deploy a
- (Optional) Image Pull Secrets: Secret required to pull the image in case the repository is private.
- 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.
- 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.


## Authenticate Kubeless Function Controller using OAuth Bearer Token

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.

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.

For example, if the bearer token is mounted at /mnt/secrets/bearer-token, this k8s spec can use it:

```yaml
# Kubeless core controller
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: kubeless-controller-manager
namespace: kubeless
labels:
kubeless: controller
spec:
template:
metadata:
labels:
kubeless: controller
spec:
containers:
- env:
- name: KUBELESS_TOKEN_FILE_PATH
value: /mnt/secrets/bearer-token
... # The rest of the Deployment has been omitted
```

8 changes: 5 additions & 3 deletions pkg/utils/k8sutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const (

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

// GetAPIExtensionsClientInCluster returns a k8s clientset to access APIExtensions from inside of cluster
func GetAPIExtensionsClientInCluster() clientsetAPIExtensions.Interface {
config, err := rest.InClusterConfig()
config, err := GetInClusterConfig()

if err != nil {
logrus.Fatalf("Can not get kubernetes config: %v", err)
}
Expand All @@ -136,10 +137,11 @@ func GetAPIExtensionsClientInCluster() clientsetAPIExtensions.Interface {

// GetFunctionClientInCluster returns function clientset to the request from inside of cluster
func GetFunctionClientInCluster() (versioned.Interface, error) {
config, err := rest.InClusterConfig()
config, err := GetInClusterConfig()
if err != nil {
return nil, err
}

kubelessClient, err := versioned.NewForConfig(config)
if err != nil {
return nil, err
Expand Down
19 changes: 19 additions & 0 deletions pkg/utils/kubelessutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
kubelessApi "github.com/kubeless/kubeless/pkg/apis/kubeless/v1beta1"
"github.com/kubeless/kubeless/pkg/langruntime"
"github.com/sirupsen/logrus"
"io/ioutil"
batchv1 "k8s.io/api/batch/v1"
"k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
Expand All @@ -40,6 +41,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)

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

// GetInClusterConfig returns necessary Config object to authenticate k8s clients if env variable is set
func GetInClusterConfig() (*rest.Config, error) {
config, err := rest.InClusterConfig()

tokenFile := os.Getenv("KUBELESS_TOKEN_FILE_PATH")
if len(tokenFile) == 0 {
return config, err
}
tokenBytes, err := ioutil.ReadFile(tokenFile)
if err != nil {
return nil, fmt.Errorf("unable to read file containing oauth token: %s", err)
}
config.BearerToken = string(tokenBytes)

return config, nil
}

func getConfigLocation(apiExtensionsClientset clientsetAPIExtensions.Interface) (ConfigLocation, error) {
configLocation := ConfigLocation{}
controllerNamespace := os.Getenv("KUBELESS_NAMESPACE")
Expand Down

0 comments on commit c67245d

Please sign in to comment.