# kubeconfig

* [step by step](#step-by-step)
  * [defining clusters](#defining-clusters)
  * [defining users](#defining-users)
  * [defining contexts](#defining-contexts)
  * [setup default namespace](#setup-default-namespace)
  * [use contexts](#use-contexts)
* [OpenID Connect ( OIDC )](#openid-connect--oidc-)
* [Configure Access to Multiple Clusters](#configure-access-to-multiple-clusters)
  * [Create a second configuration file](#create-a-second-configuration-file)
  * [Clean up](#clean-up)
  * [with Proxy](#with-proxy)
* [get info](#get-info)
  * [basic view](#basic-view)
  * [server IP](#server-ip)
  * [get user](#get-user)
  * [get password](#get-password)
  * [get key](#get-key)
* [kubeadm-cfg.yml](#kubeadm-cfgyml)
* [have fun](#have-fun)

{% hint style="info" %}

> * references:
>   * [\* 创建 kubeconfig 文件](https://jimmysong.io/kubernetes-handbook/practice/create-kubeconfig.html)
>   * [创建k8s context](https://www.cnblogs.com/tiny1987/p/12018080.html)
>   * [Configure Access to Multiple Clusters](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)
>   * [Organizing Cluster Access Using kubeconfig Files](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/)
>   * [kubectl config](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#config)
>   * [Kubectl Config Set-Context | Tutorial and Best Practices](https://www.containiq.com/post/kubectl-config-set-context-tutorial-and-best-practices)
>   * [Checklist: pros and cons of using multiple Kubernetes clusters, and how to distribute workloads between them](http://vadimeisenberg.blogspot.com/2019/03/multicluster-pros-and-cons.html)
>   * [kubectl config view](https://jamesdefabia.github.io/docs/user-guide/kubectl/kubectl_config_view/)
> * others:
>   * [Introducing kubectl](https://kubebyexample.com/learning-paths/application-development-kubernetes/lesson-1-running-containerized-applications)
> * more usage:
>   * [imarslo : kubectl config view](https://github.com/marslo/ibook/blob/marslo/docs/virtualization/kubernetes/certificates.html#basic-environment)
>     {% endhint %}

### step by step

#### defining clusters

```bash
$ kubectl config set-cluster k8s-cluster --server=127.0.0.1:8087
```

[**modify server**](https://jamesdefabia.github.io/docs/user-guide/kubectl/kubectl_config_set-cluster/)

```bash
$ kubectl config set-cluster NAME --server=https://10.69.114.92:6443

# or
$ kubectl config set-cluster $(kubectl config current-context) --server=https://10.69.114.92:6443
```

#### defining users

* using token

  ```bash
  $ kubectl config set-credentials my-user --token=Py93bt12mT
  ```
* using basic authentication

  ```bash
  $ kubectl config set-credentials my-user --username=redhat-username --password=redhat-password
  ```
* using certificates

  ```bash
  $ kubectl config set-credentials my-user --client-certificate=redhat-certificate.crt --client-key=redhat-key.key
  ```

#### defining contexts

```bash
$ kubectl config set-context --cluster=k8s-cluster --user=my-user
```

* by namespace

  ```bash
  $ kubectl config set-context my-context --cluster=k8s-cluster --user=my-user --namespace=redhat-dev
  ```

#### [setup default namespace](https://www.cloudytuts.com/tutorials/kubernetes/how-to-set-default-kubernetes-namespace/)

```bash
$ kubectl config set-context --current --namespace=<my_namespace>
```

#### use contexts

```bash
$ kubectl config use-context my-context
```

* verify

  ```bash
  $ kubectl config get-contexts
  CURRENT   NAME            CLUSTER           AUTHINFO      NAMESPACE
  *         my-context      172.0.7.2:6443    my-user       redhat-dev
            my-context-2    172.1.8.0:6443    my-user-2

  $ kubectl config current-context
  my-context
  ```

### OpenID Connect ( OIDC )

> \[!NOTE|label:references:]
>
> * [Option 1 - OIDC Authenticator](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#option-1-oidc-authenticator)
>
>   ```bash
>   $ kubectl config set-credentials USER_NAME \
>             --auth-provider=oidc \
>             --auth-provider-arg=idp-issuer-url=( issuer url ) \
>             --auth-provider-arg=client-id=( your client id ) \
>             --auth-provider-arg=client-secret=( your client secret ) \
>             --auth-provider-arg=refresh-token=( your refresh token ) \
>             --auth-provider-arg=idp-certificate-authority=( path to your ca certificate ) \
>             --auth-provider-arg=id-token=( your id_token )
>   ```

```bash
echo "-----BEGIN CERTIFICATE-----
....
-----END CERTIFICATE-----
" \ > ca-kubernetes-staging.pem

## set cluster
kubectl config set-cluster kubernetes-staging \
               --server=https://127.0.7.2:6443 \
               --certificate-authority=ca-kubernetes-staging.pem \
               --embed-certs

## set credential
kubectl config set-credentials marslo@kubernetes-staging  \
               --auth-provider=oidc  \
               --auth-provider-arg='idp-issuer-url=https://dex-k8s.domain.com/'  \
               --auth-provider-arg='client-id=dex-k8s-authenticator'  \
               --auth-provider-arg='client-secret=Z**********************0' \
               --auth-provider-arg='refresh-token=C**********************************************************************n' \
               --auth-provider-arg='id-token=e**********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************A'

## set context
kubectl config set-context kubernetes-staging --cluster=kubernetes-staging --user=marslo@kubernetes-staging

## use context
kubectl config use-context kubernetes-staging
```

* verify

  ```bash
  # get id-token
  $ kubectl config view -o jsonpath='{.users[?(@.name == "marslo@kubernetes-staging")].user.auth-provider.config.id-token}'

  # get the password for the `e2e` user
  $ kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}'
  ```

### [Configure Access to Multiple Clusters](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)

> \[!TIP] a configuration file describes `clusters`, `users`, and `contexts`

* set clusters

  ```bash
  # cluster development
  $ kubectl config --kubeconfig=config-demo \
                   set-cluster development \
                   --server=https://1.2.3.4 \
                   --certificate-authority=fake-ca-file

  # cluster test
  $ kubectl config --kubeconfig=config-demo \
                   set-cluster test \
                   --server=https://5.6.7.8 \
                   --insecure-skip-tls-verify
  ```
* set user

  > \[!NOTE]
  >
  > * To delete a user you can run `kubectl --kubeconfig=config-demo config unset users.<name>`
  > * To remove a cluster, you can run `kubectl --kubeconfig=config-demo config unset clusters.<name>`
  > * To remove a context, you can run `kubectl --kubeconfig=config-demo config unset contexts.<name>`

  ```bash
  # with CA
  $ kubectl config --kubeconfig=config-demo \
                   set-credentials developer \
                   --client-certificate=fake-cert-file \
                   --client-key=fake-key-seefile

  # with basic authentication
  $ kubectl config --kubeconfig=config-demo \
                   set-credentials experimenter \
                   --username=exp \
                   --password=some-password
  ```
* add context

  ```bash
  # user developer namespace frontend
  $ kubectl config --kubeconfig=config-demo \
                   set-context dev-frontend \
                   --cluster=development \
                   --namespace=frontend \
                   --user=developer

  # user developer namespace storage
  $ kubectl config --kubeconfig=config-demo \
                   set-context dev-storage \
                   --cluster=development \
                   --namespace=storage \
                   --user=developer

  # user experimenter
  $ kubectl config --kubeconfig=config-demo \
                   set-context exp-test \
                   --cluster=test \
                   --namespace=default \
                   --user=experimenter
  ```
* result

  ```bash
  $ kubectl config --kubeconfig=config-demo get-contexts
  CURRENT   NAME           CLUSTER       AUTHINFO       NAMESPACE
            dev-frontend   development   developer      frontend
            dev-storage    development   developer      storage
            exp-test       test          experimenter   default

  $ kubectl config --kubeconfig=config-demo view
  apiVersion: v1
  clusters:
  - cluster:
      certificate-authority: fake-ca-file
      server: https://1.2.3.4
    name: development
  - cluster:
      insecure-skip-tls-verify: true
      server: https://5.6.7.8
    name: test
  contexts:
  - context:
      cluster: development
      namespace: frontend
      user: developer
    name: dev-frontend
  - context:
      cluster: development
      namespace: storage
      user: developer
    name: dev-storage
  - context:
      cluster: test
      namespace: default
      user: experimenter
    name: exp-test
  current-context: ""
  kind: Config
  preferences: {}
  users:
  - name: developer
    user:
      client-certificate: fake-cert-file
      client-key: fake-key-seefile
  - name: experimenter
    user:
      password: some-password
      username: exp
  ```
* use context

  ```bash
  $ kubectl config --kubeconfig=config-demo use-context dev-frontend
  Switched to context "dev-frontend".

  $ kubectl config --kubeconfig=config-demo get-contexts
  CURRENT   NAME           CLUSTER       AUTHINFO       NAMESPACE
  *         dev-frontend   development   developer      frontend
            dev-storage    development   developer      storage
            exp-test       test          experimenter   default

  $ kubectl config --kubeconfig=config-demo view --minify
  apiVersion: v1
  clusters:
  - cluster:
      certificate-authority: fake-ca-file
      server: https://1.2.3.4
    name: development
  contexts:
  - context:
      cluster: development
      namespace: frontend
      user: developer
    name: dev-frontend
  current-context: dev-frontend
  kind: Config
  preferences: {}
  users:
  - name: developer
    user:
      client-certificate: fake-cert-file
      client-key: fake-key-seefile
  ```

#### [Create a second configuration file](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/#create-a-second-configuration-file)

* `KUBECONFIG` environment variable
  * linux

    ```bash
    $ export KUBECONFIG_SAVED="$KUBECONFIG"
    ```
  * windows

    ```powershell
    > $Env:KUBECONFIG_SAVED=$ENV:KUBECONFIG
    ```
* temporarily append two paths to your kubeconfig environment variable
  * linux

    ```bash
    $ export KUBECONFIG="${KUBECONFIG}:config-demo:config-demo-2"
    ```
  * windows

    ```powershell
    > $Env:KUBECONFIG=("config-demo;config-demo-2")
    ```
* [Append $HOME/.kube/config to your KUBECONFIG environment variable](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/#append-home-kube-config-to-your-kubeconfig-environment-variable)
  * linux

    ```bash
    $ export KUBECONFIG="${KUBECONFIG}:${HOME}/.kube/config"
    ```
  * windows

    ```powershell
    > $Env:KUBECONFIG="$Env:KUBECONFIG;$HOME\.kube\config"
    ```

#### [Clean up](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/#clean-up)

* linux

  ```bash
  $ export KUBECONFIG="$KUBECONFIG_SAVED"
  ```
* windows

  ```powershell
  > $Env:KUBECONFIG=$ENV:KUBECONFIG_SAVED
  ```

#### [with Proxy](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#proxy)

> \[!NOTE] references:
>
> * [cheatsheet : Kubectl context and configuration](https://kubernetes.io/docs/reference/kubectl/cheatsheet/#kubectl-context-and-configuration)

```bash
$ kubectl config set-cluster <k8s-cluster-name> --proxy-url=<my-proxy-url>

# i.e.
$ kubectl config set-cluster development --proxy-url=http://sample.proxy.com:3128
```

* result

  ```bash
  apiVersion: v1
  kind: Config

  clusters:
  - cluster:
      proxy-url: http://proxy.example.org:3128
      server: https://k8s.example.org/k8s/clusters/c-xxyyzz
    name: development

  users:
  - name: developer

  contexts:
  - context:
    name: development
  ```

### get info

> \[!INFO|label:references:]
>
> * [\* imarslo : jsonpath](https://github.com/marslo/ibook/blob/marslo/docs/virtualization/kubernetes/pod.html#jsonpath)
> * [jsonpath support](https://kubernetes.io/docs/reference/kubectl/jsonpath/)
> * [JSONPath 支持](https://kubernetes.io/zh-cn/docs/reference/kubectl/jsonpath/)

#### basic view

* get contexts list

  ```bash
  $ kubectl config --kubeconfig=config-demo get-contexts
  CURRENT   NAME           CLUSTER       AUTHINFO       NAMESPACE
  *         dev-frontend   development   developer      frontend
            dev-storage    development   developer      storage
            exp-test       test          experimenter   default
  ```
* get current context

  ```bash
  $ kubectl config --kubeconfig=config-demo current-context
  dev-frontend
  ```
* get clusters

  ```bash
  $ kubectl config --kubeconfig=config-demo get-clusters
  NAME
  development
  test
  ```
* get users

  ```bash
  $ kubectl config --kubeconfig=config-demo get-users
  NAME
  developer
  experimenter
  ```

#### server IP

**by cluster name**

```bash
# get all cluster name
$ kubectl config --kubeconfig=config-demo view -o jsonpath="{.clusters[*].name}"
development test

$ kubectl config --kubeconfig=config-demo view \
                 -o jsonpath='{.clusters[?(@.name == "development")].cluster.server}'
https://1.2.3.4
```

**current in-use via `--minify`**

> \[!NOTE]
>
> ```bash
> --minify=false:
>          Remove all information not used by current-context from the output
> ```

```bash
$ kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}'
https://1.2.3.4
# or
$ kubectl config view --minify -o jsonpath="{.clusters[].cluster.server}"
https://1.2.3.4

# more info
$ kubectl config view --minify -o jsonpath="{.clusters[*].name}"
development
# or
$ kubectl config view --minify -o jsonpath="{.clusters[].name}"
development
```

**current in-use via `current-context`**

```bash
# or get current cluster IP
$ kubectl config --kubeconfig=config-demo current-context
development
$ kubectl config --kubeconfig=config-demo view \
                 -o jsonpath="{.clusters[?(@.name == \"$(kubectl config --kubeconfig=config-demo current-context)\")].cluster.server}"
```

#### get user

```bash
$ kubectl config --kubeconfig=config-demo view -o jsonpath='{.users[*].name}'
developer experimenter
```

#### get password

```bash
$ kubectl config --kubeconfig=config-demo view -o jsonpath='{.users[?(@.name == "experimenter")]}'
{"name":"experimenter","user":{"password":"some-password","username":"exp"}}

$ kubectl config --kubeconfig=config-demo view -o jsonpath='{.users[?(@.name == "experimenter")].user.password}'
some-password
```

#### get key

```bash
$ kubectl config --kubeconfig=config-demo view -o jsonpath='{.users[?(@.name == "developer")]}'
{"name":"developer","user":{"client-certificate":"fake-cert-file","client-key":"fake-key-seefile"}}
# or via base64 decoding
$ kubectl config --kubeconfig=config-demo view -o jsonpath='{.users[?(@.name == "developer")]}' | base64 -d
    --minify=false:
  Remove all information not used by current-context from the output
$ kubectl config --kubeconfig=config-demo view -o jsonpath='{.users[?(@.name == "developer")].user.client-key}'
fake-key-seefile
# or via base64 decoding
$ kubectl config --kubeconfig=config-demo view -o jsonpath='{.users[?(@.name == "developer")].user.client-key}' | base64 -d
```

### kubeadm-cfg.yml

> \[!NOTE|label:references:]
>
> * [Certificate Management with kubeadm](https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#kubeconfig-additional-users)

```bash
$ kubectl get cm kubeadm-config -n kube-system -o=jsonpath="{.data.ClusterConfiguration}"
```

### have fun

* [view config details](https://stackoverflow.com/a/53403859/2940319)

  ```bash
  exec >/tmp/output &&
  CONTEXT_NAME=kubernetes-admin@kubernetes \
  CONTEXT_CLUSTER=$(kubectl config view -o=jsonpath="{.contexts[?(@.name==\"${CONTEXT_NAME}\")].context.cluster}") \
  CONTEXT_USER=$(kubectl config view -o=jsonpath="{.contexts[?(@.name==\"${CONTEXT_NAME}\")].context.user}") && \
  echo "[" && \
  kubectl config view -o=json | jq -j --arg CONTEXT_NAME "$CONTEXT_NAME" '.contexts[] | select(.name==$CONTEXT_NAME)' && \
  echo "," && \
  kubectl config view -o=json | jq -j --arg CONTEXT_CLUSTER "$CONTEXT_CLUSTER" '.clusters[] | select(.name==$CONTEXT_CLUSTER)' && \
  echo "," && \
  kubectl config view -o=json | jq -j --arg CONTEXT_USER "$CONTEXT_USER" '.users[] | select(.name==$CONTEXT_USER)' && \
  echo -e "\n]\n" && \
  exec >/dev/tty && \
  cat /tmp/output | jq && \
  rm -rf /tmp/output
  ```

  * [or](https://stackoverflow.com/a/53403319/2940319)

    ```bash
    $ kubectl config view -o json |
      jq '. as $o
            | ."current-context" as $current_context_name
            | $o.contexts[] | select(.name == $current_context_name) as $context
            | $o.clusters[] | select(.name == $context.context.cluster) as $cluster
            | $o.users[] | select(.name == $context.context.user) as $user
            | {"current-context-name": $current_context_name, context: $context, cluster: $cluster, user: $user}'
    ```
