Skip to content

Available client-go credential (exec) plugin, no Cloud Provider CLI required.

License

Notifications You must be signed in to change notification settings

seal-io/kubecia

Repository files navigation

Kubernetes Cloud Identify Authenticator(KubeCIA)

tl;dr: Available client-go credential (exec) plugin, no Cloud Provider CLI required.

This tool is maintained by Seal.

Background

Since Kubernetes v1.22, we can use external credential plugins to authenticate with Kubernetes clusters. However, using external credential plugins requires the Cloud Provider CLI to be installed, for some scenarios, such as CI/CD, it is overkill and not friendly to automation task preparation.

$ docker images --format "{{.Repository}}:{{.Tag}}\t{{.Size}}" | grep cli

gcr.io/google.com/cloudsdktool/google-cloud-cli:latest	2.82GB
public.ecr.aws/aws-cli/aws-cli:latest	415MB
mcr.microsoft.com/azure-cli:latest	722MB

KubeCIA, which is a lightweight and easy-to-use credential plugin for Kubernetes, is born to reduce the dependency of Cloud Provider CLI.

Usage

KubeCIA can call the Cloud Provider API to get the credential and consume the local filesystem as caching. The following example shows how to use KubeCIA to get credentials for EKS cluster.

apiVersion: v1
kind: Config
users:
  - name: eks-user
    user:
      exec:
        # -- KubeCIA only supports `client.authentication.k8s.io/v1` API version.
        apiVersion: "client.authentication.k8s.io/v1"
        # -- API version `client.authentication.k8s.io/v1` needs configuring `interactiveMode`.
        interactiveMode: Never
        command: "kubecia"
        args:
          - "aws"
        env:
          # -- KubeCIA can retrieve the environment variables prefixed with `KUBECIA_`,
          # -- second segment must be the upper case of the sub command.
          - name: KUBECIA_AWS_ACCESS_KEY_ID
            value: <REPLACE_WITH_YOUR_AWS_ACCESS_KEY_ID>
          - name: KUBECIA_AWS_SECRET_ACCESS_KEY
            # -- For sensitive value, KubeCIA will try to expand from the environment variable.
            value: "$AWS_SECRET_ACCESS_KEY"
          - name: KUBECIA_AWS_REGION
            value: <REPLACE_WITH_YOUR_AWS_REGION>
          - name: KUBECIA_AWS_CLUSTER
            value: <REPLACE_WITH_YOUR_EKS_CLUSTER_ID_OR_NAME>
          - name: KUBECIA_AWS_ASSUME_ROLE_ARN
            value: <REPLACE_WITH_YOUR_EKS_ASSUME_ROLE_ARN>
clusters:
  - name: eks-cluster
    cluster:
      server: <REPLACE_WITH_YOUR_EKS_ENDPOINT>
      certificate-authority: <REPLACE_WITH_YOUR_EKS_CA_PEM_PATH>
contexts:
  - name: eks-cluster
    context:
      cluster: eks-cluster
      user: eks-user
current-context: eks-cluster

Centralized Service Mode

KubeCIA can be set up as a centralized service by kubecia serve command.

$ kubecia serve --socket /var/run/kubecia.sock

Under this mode, the above configuration can also work.

When acting as a sidecar, main containers can use any Unix socket tool to call centralized KubeCIA service, the following example shows how to use cURL(7.40.0+) to get.

apiVersion: v1
kind: Config
users:
  - name: eks-user
    user:
      exec:
        apiVersion: "client.authentication.k8s.io/v1"
        command: "curl"
        args:
          - "--silent"
          - "--output"
          - "-"
          - "--location"
          - "--unix-socket"
          # -- KubeCIA service will listen on this Unix socket at default, change it by `--socket` flag.
          - "/var/run/kubecia.sock"
          - "--user"
          # -- The service principal credentials, e.g. the AWS access_key_id and secret_access_key, the Azure client_id and client_secret,
          # -- are required to be provided via `Authentication` header.
          - "<REPLACE_WITH_YOUR_AWS_ACCESS_KEY_ID>:<REPLACE_WITH_YOUR_AWS_SECRET_ACCESS_KEY>"
          - "http:/./aws/<REPLACE_WITH_YOUR_AWS_REGION>/<REPLACE_WITH_YOUR_EKS_CLUSTER_ID_OR_NAME>/<REPLACE_WITH_YOUR_EKS_ROLE_ARN>"
        interactiveMode: Never
clusters:
  - name: eks-cluster
    cluster:
      server: <REPLACE_WITH_YOUR_EKS_ENDPOINT>
      certificate-authority: <REPLACE_WITH_YOUR_EKS_CA_PEM_PATH>
contexts:
  - name: eks-cluster
    context:
      cluster: eks-cluster
      user: eks-user
current-context: eks-cluster

But describing the sensitive credentials in the configuration file is not recommended, it is recommended to use the shell injection as below.

apiVersion: v1
kind: Config
users:
  - name: eks-user
    user:
      exec:
        apiVersion: "client.authentication.k8s.io/v1"
        command: "/bin/bash"
        args:
          - "-c"
          - "curl --silent --output - --location --unix-socket /var/run/kubecia.sock --user ${AWS_ACCESS_KEY_ID}:${AWS_SECRET_ACCESS_KEY} http:/./aws/${AWS_REGION}/${EKS_CLUSTER}/${EKS_ROLE_ARN}"
        env:
          ##
          ## AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are optional present at here,
          ## there can be provided by environment variables.
          ##
          # - name: AWS_ACCESS_KEY_ID
          #  value: <REPLACE_WITH_YOUR_AWS_ACCESS_KEY_ID>
          # - name: AWS_SECRET_ACCESS_KEY
          #  value: <REPLACE_WITH_YOUR_AWS_SECRET_ACCESS_KEY>
          - name: AWS_REGION
            value: <REPLACE_WITH_YOUR_AWS_REGION>
          - name: EKS_CLUSTER
            value: <REPLACE_WITH_YOUR_EKS_CLUSTER_ID_OR_NAME>
          - name: EKS_ROLE_ARN
            value: <REPLACE_WITH_YOUR_EKS_ROLE_ARN>
        interactiveMode: Never
clusters:
  - name: eks-cluster
    cluster:
      server: <REPLACE_WITH_YOUR_EKS_ENDPOINT>
      certificate-authority: <REPLACE_WITH_YOUR_EKS_CA_PEM_PATH>
contexts:
  - name: eks-cluster
    context:
      cluster: eks-cluster
      user: eks-user
current-context: eks-cluster

Notice

KubeCIA only response result with apiVersion: "client.authentication.k8s.io/v1", please update the kubectl if not supported.

KubeCIA focuses on obtaining the token for accessing the Kubernetes cluster based on the user's service principal credential, to other features or modes, please review the below links.

KubeCIA establishes on Unix socket, to expose the service to the network, please use the socket proxy, like ncat.

$ ncat --verbose --listen --keep-open --source-port 80 --sh-exec "ncat --unixsock /var/run/kubecia.sock"

License

Copyright (c) 2024 Seal, Inc.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at LICENSE file for details.

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.