github.com/GoogleContainerTools/skaffold/v2@v2.13.2/docs-v2/design_proposals/configurable-kubecontext.md (about)

     1  # Configurable kubecontext
     2  
     3  * Author(s): Cornelius Weig (@corneliusweig)
     4  * Design Shepherd: Balint Pato (@balopat)
     5  * Date: 29 June 2019
     6  * Status: On hold
     7  
     8  > **Note** :exclamation: As the global config option adds considerable complexity, that part of this design proposal has been put on hold to await more evidence.
     9  Ideally, the CLI and `skaffold.yaml` options are already enough for the great majority of Skaffold users.
    10  
    11  ## Background
    12  
    13  So far, Skaffold always uses the currently active kubecontext when interacting with a Kubernetes cluster.
    14  This is problematic when users want to deploy multiple projects with different kubecontexts, because the user needs to manually switch the context before starting Skaffold.
    15  In particular when working on multiple such projects in parallel, the current behavior is limiting.
    16  
    17  Open issues concerning this problem are
    18  
    19  - Allow option to specify the kubectl context ([#511](https://github.com/GoogleContainerTools/skaffold/issues/511))
    20  - Support kube.config and kube.context for specifying alternative Kubernetes config file or context ([#2325](https://github.com/GoogleContainerTools/skaffold/issues/2325))
    21  - Feature: Support regex in profile activation via kubeContext ([#1677](https://github.com/GoogleContainerTools/skaffold/issues/1677))
    22  - Skaffold.yaml files are not portable ([#480](https://github.com/GoogleContainerTools/skaffold/issues/480))
    23  - Support forcing a context and a namespace for a profile/command ([#2426](https://github.com/GoogleContainerTools/skaffold/issues/2426))
    24  
    25  There also was an attempt to add a configuration option to `skaffold.yaml` (Support for overriding kubectl context during deployment [#1540](https://github.com/GoogleContainerTools/skaffold/pull/1540)).
    26  
    27  The goal of this document is to create an agreement on what options should be supported and identify edge cases.
    28  
    29  ### Recommended use-cases
    30  
    31  ##### As Skaffold user, I want to define the kubecontext for a single skaffold run.
    32  Use CLI flag or environment variable.
    33  
    34  ##### As enterprise user, I want to define a default kubecontext for a project to be used across different machines.
    35  Use the kubecontext configuration in `skaffold.yaml`.
    36  Think twice before using this approach in open source projects, as the setting will not be portable.
    37  
    38  ##### As individual user, I want to define a default kubecontext for a project.
    39  Use kubecontext setting in the global Skaffold config (via `skaffold config set ...`).
    40  
    41  ##### As Skaffold user with multiple profiles, I want to use different kubecontexts for different profiles.
    42  Use the kubecontext configuration in `skaffold.yaml`.
    43  
    44  
    45  ## Design
    46  
    47  There are four places where kubecontext activation can be added:
    48  <table>
    49      <thead>
    50          <th>Precedence</th> <th>Kind</th> <th>Details</th>
    51      </thead>
    52      <tbody>
    53          <tr>
    54              <td>1. (highest)</td>
    55              <td>CLI option</td>
    56              <td>
    57                The Kubernetes standard to set the kubecontext is <code>--context</code>.
    58                However, in Skaffold this term is so overloaded that it should more precisely be named <code>--kube-context</code>.
    59                This flag is necessary for IDE integration.
    60              </td>
    61          </tr>
    62          <tr>
    63              <td>2.</td>
    64              <td>Env variable</td>
    65              <td>
    66                <code>SKAFFOLD_KUBE_CONTEXT</code>, similar to other Skaffold flags.
    67              </td>
    68          </tr>
    69          <tr>
    70              <td>3.</td>
    71              <td><code>skaffold.yaml</code></td>
    72              <td>
    73                Json-path <code>deploy.kubeContext</code>.
    74                This option is shareable, and requires some error handling for profile activation by kubecontext (see below).
    75              </td>
    76          </tr>
    77          <tr>
    78              <td>4. (lowest)</td>
    79              <td>Global Skaffold config</td>
    80              <td>
    81                This should give users the possibility to define a default context globally or per project.
    82                This variant is not shareable.
    83              </td>
    84          </tr>
    85      </tbody>
    86  </table>
    87  
    88  ---
    89  
    90  Beside the kubecontext, also the namespace needs to be specified.
    91  Ideally, the namespace should also offer the same override variants as kubecontext.
    92  This is out of scope for this design proposal.
    93  As long as this is not implemented, there is always the workaround, to duplicate a kubecontext and set the default namespace for this kubecontext to the desired value.
    94  Then this kubecontext/namespace pair can be activated with the kubecontext activation machinery detailed in this design proposal.
    95  
    96  ### Detailed discussion
    97  #### Option in `skaffold.yaml`
    98  A configuration option in `skaffold.yaml` has the advantage of being most discoverable:
    99  it is in the place where users configure all aspects of their pipeline.
   100  In addition, it allows to define the kubecontext per Skaffold profile.
   101  
   102  A natural place for the config in `skaffold.yaml` is in `latest.DeployConfig`, resulting in a json path `deploy.kubeContext`.
   103  
   104  Profiles have a double role, because they may override the kubecontext to a different value as before, but they may also be activated by a kubecontext.
   105  To catch unexpected behavior, the profile activation will perform the following logic:
   106  
   107  1. All profiles are checked if they become active with the _original_ kubecontext.
   108  2. If any profile was activated by the current kubecontext, the effective kubecontext may not change.
   109     In other words, the effective kubecontext _after_ profile activation must match the kubecontext _before_ profile activation.
   110     - If the context has changed, return an error.
   111     - If the context has not changed, continue.
   112  
   113  It is therefore possible that subsequent profiles repeatedly switch the kubecontext, in which case the last one wins.
   114  
   115  For example, the following sequence will result in an error:
   116  
   117  - The current context is `minikube` and activates some profile.
   118  - Some profile also overrides the kubecontext and deploys to kubecontext `gke_abc_123`.
   119  - Thus the `minikube`-specific profile would be deployed to `gke_abc_123`, and this will be forbidden.
   120  
   121  **Note**: `skaffold.yaml` is meant to be shared, but kubecontext names vary across users.
   122  Sharing therefore makes only sense in a corporate setting where context names are the same across different machines.
   123  
   124  #### Option in global Skaffold config
   125  Specifying a default kubecontext globally is straightforward. For example, via new config option
   126  ```yaml
   127  global:
   128    default-context: docker-for-desktop
   129  ```
   130  
   131  On the other hand, building a relation between projects and kubecontext needs to solve two questions:
   132  
   133  1. How to identify projects
   134  2. How to save the project/kubecontext relation
   135  
   136  ##### How to identify projects
   137  
   138  There are at least three possibilities:
   139  
   140  - Identify projects by their absolute host path.
   141    This is guaranteed to be unique, but may break if a user moves his project to another location.
   142  - Identify projects by a new `metadata.name` entry in `skaffold.yaml` (see also [#2200](https://github.com/GoogleContainerTools/skaffold/issues/2200)).
   143    This has the drawback of being potentially not unique, so that users accidentally pin the kubecontext for more projects than intended.
   144    On the other hand, this is the standard approach taken by Kubernetes resources.
   145  - Identify project by their initial commit.
   146    This variant is stable against relocations.
   147    It is also unique unless a user forks a project and wants to define different kubecontexts for each fork.
   148    Compared to the other alternatives, it is rather slow.
   149  
   150  **\<What option has the best tradeoffs?\>**
   151  
   152  Resolution: We will go ahead with the `metadata.name` approach. As the name may not be unique, this requires special documentation.
   153  
   154  
   155  ##### How to save project/kubecontext relations
   156  
   157  Currently, the Skaffold config uses the kubecontext as identifier.
   158  
   159  There are two possibilities to add the relation:
   160  
   161  1. Reverse the mapping project/kubecontext and save as list under `kube-context` entries:
   162     ```yaml
   163     kubecontexts:
   164     - kube-context: my-context
   165       skaffoldConfigs:
   166       - config-name
   167     ```
   168     The drawback here is that the data structure does not forbid conflicting entries, such as:
   169     ```yaml
   170     kubecontexts:
   171     - kube-context: context1
   172       skaffoldConfigs:
   173       - my-project
   174     - kube-context: context2
   175       skaffoldConfigs:
   176       - my-project
   177     ```
   178  2. Add a new top-level entry in Skaffold config:
   179     ```yaml
   180     global: {}
   181     kubecontexts: []
   182     skaffoldConfigs:
   183       my-project: my-context
   184       my-other-project: my-other-context
   185       '*': default-context
   186     ```
   187     This option will be more complex to implement wrt `skaffold config`.
   188  
   189  ### Open Issues/Questions
   190  
   191  **\<What Skaffold config structure has the best tradeoffs?\>**
   192  
   193  Resolution: The top-level entry (option 2) overall has the better trade-offs.
   194  
   195  ## Implementation plan
   196  1. Implement the CLI flag and env var variant first. This should also be the most important for the IDE integration. [#2447](https://github.com/GoogleContainerTools/skaffold/pull/2447)
   197  2. Implement `skaffold.yaml` variant. [#2510](https://github.com/GoogleContainerTools/skaffold/pull/2510)
   198  3. ~~Implement the global Skaffold config variant to override a kubecontext for a skaffold config (`skaffoldConfigs`).~~ [#2558](https://github.com/GoogleContainerTools/skaffold/pull/2558)
   199  4. ~~Implement the global Skaffold config variant to set a default kubecontext (`skaffoldConfigs['*']`).~~ [#2558](https://github.com/GoogleContainerTools/skaffold/pull/2558)
   200  5. ~~Implement the namespace functionality.~~ (out of scope)
   201  
   202  ## Integration test plan
   203  
   204  A single test covers the overall kubecontext override functionality sufficiently (part of [#2447](https://github.com/GoogleContainerTools/skaffold/pull/2447)).
   205  Other test-cases such as precedence of the different variants and error cases should be covered by unit tests.