github.com/SamarSidharth/kpt@v0.0.0-20231122062228-c7d747ae3ace/site/guides/tenant-onboarding.md (about)

     1  # Tenant onboarding
     2  
     3  We have seen that in large organizations using kubernetes, there is a platform
     4  team (or infrastructure team) that is responsible for managing the kubernetes
     5  clusters. Typically a kubernetes cluster is shared by multiple teams to run
     6  different types of workloads. One of the common use-cases platform teams have
     7  is onboarding a new tenant on the kubernetes cluster. In this guide, you will
     8  learn - how you can use kpt to address the tenant use-case. Though this guide
     9  focuses on the tenant use-case, the pattern for package workflow discussed here
    10  can be applied to other use cases as well.
    11  
    12  **Note:** This guide is inspired by the [kube-common-setup](https://github.com/nghnam/kube-common-setup)
    13  helm chart.
    14  
    15  ## Terminology
    16  
    17  Before we jump into the tutorial, let’s go over some terminologies that are
    18  used throughout this guide.
    19  
    20  ### Tenant
    21  
    22  A tenant represents a collection of related infra/app resources and needs to be
    23  isolated from other resources, for example, a microservice, a workload, a team
    24  (group of developers) sharing common infra resources.
    25  
    26  ### Platform team
    27  
    28  Central infra team responsible for managing the Kubernetes cluster. Members of
    29  the platform teams typically have administrative privileges on the Kubernetes cluster.
    30  
    31  ### App developer team
    32  
    33  The team responsible for operating the tenant. Once the tenant is provisioned,
    34  this team will typically deploy resources (workload, services etc) in the tenant.
    35  
    36  ## Package organization
    37  
    38  There are many ways to organize the tenant package and its variants. In this guide,
    39  we will explore one of the patterns where we keep the packages and their variants
    40  in different repos as shown in the figure below.
    41  
    42  ![drawing](/static/images/tenant-onboarding.svg)
    43  
    44  Package catalog repo contains kpt packages that will be used to create variants
    45  of the packages. Platform repo contains the variants of the packages and there
    46  is one-to-many relationship between packages in catalog to platform repo. This
    47  organization has many benefits such as:
    48  
    49  * It is easy to discover the packages and its variants.
    50  * It makes it easy to enforce different constraints/invariants on package and
    51    package variants.
    52  * It allows flexibility in roles/permissions for package publishing/consumption.
    53  * Platform repo also serves as the deployment repository.
    54  
    55  ```shell
    56  # A sample layout for package catalog repo
    57  # that contains the tenant pkg
    58  pkg-catalog $ tree .
    59  .
    60  ├── LICENSE
    61  ├── README.md
    62  └── tenant
    63      ├── Kptfile
    64      ├── README.md
    65      ├── namespace.yaml
    66      ├── ns-invariant.yaml
    67      ├── quota.yaml
    68      ├── role-binding.yaml
    69      └── service-account.yaml
    70      # other packages will come here
    71  ```
    72  
    73  ```shell
    74  # An sample layout for platform repo
    75  platform $ tree .
    76  .
    77  ├── LICENSE
    78  ├── README.md
    79  └── tenants
    80      ├── tenant-a
    81      │   ├── Kptfile
    82      │   ├── README.md
    83      │   ├── namespace.yaml
    84      │   ├── ns-invariant.yaml
    85      │   ├── quota.yaml
    86      │   ├── role-binding.yaml
    87      │   └── service-account.yaml
    88      └── tenant-b
    89          ├── Kptfile
    90          ├── README.md
    91          ├── namespace.yaml
    92          ├── ns-invariant.yaml
    93          ├── quota.yaml
    94          ├── role-binding.yaml
    95          └── service-account.yaml
    96  ```
    97  
    98  ## Tenant package
    99  
   100  The tenant package should have a good set of defaults configuration so that it
   101  can work as a good starting point for most of the tenants. Application developer
   102  teams can customize the tenant package over time as their need evolves.
   103  
   104  The tenant package should include invariants (guardrails) that prevent
   105  mis-configuration. For example, each tenant package shouldn’t have more than
   106  one namespace, resource quota shouldn’t exceed limits etc.
   107  
   108  One of the key principles to keep in mind is that the tenant package shouldn’t
   109  try to offer all the possible customization options. The tenant package should
   110  offer a reasonable set of defaults with required constraints. Downstream users
   111  of the tenant package can directly edit, add/delete resources as per their needs.
   112  
   113  Here is an example of a [basic tenant package](https://github.com/GoogleContainerTools/kpt/tree/main/package-examples/tenant).
   114  
   115  ```shell
   116  
   117  $ export PKG_CATALOG_DIR=<path/to/pkg/catalog/dir>
   118  $ cd $PKG_CATALOG_DIR
   119  pkg-catalog $ kpt pkg tree tenant
   120  Package "tenant"
   121  ├── [Kptfile]  Kptfile tenant
   122  ├── [namespace.yaml]  Namespace tenant-name
   123  ├── [ns-invariant.yaml]  StarlarkRun ns-invariant
   124  ├── [quota.yaml]  ResourceQuota tenant-name/quota
   125  ├── [role-binding.yaml]  RoleBinding tenant-name/sa-admin
   126  └── [service-account.yaml]  ServiceAccount tenant-name/sa
   127  
   128  ```
   129  
   130  The tenant package’s Kptfile offers basic customization and enforces single
   131  namespace constraint.
   132  
   133  ```shell
   134  
   135  $ cd $PKG_CATALOG_DIR
   136  pkg-catalog $ cat tenant/Kptfile
   137  apiVersion: kpt.dev/v1
   138  kind: Kptfile
   139  metadata:
   140    name: tenant
   141  info:
   142    description: Base tenant package
   143  pipeline:
   144    mutators:
   145      - image: set-namespace:v0.1
   146        configMap:
   147          namespace: tenant-name # ←- will be customized for pkg variant
   148    validators:
   149      - image: gcr.io/kpt-fn/starlark:v0.3
   150        configPath: ns-invariant.yaml
   151  
   152  ```
   153  
   154  ### Publishing tenant package
   155  
   156  So once you are happy with the tenant package, you can publish the tenant
   157  package by tagging the version as shown below:
   158  
   159  ```shell
   160  # Assuming you are in the pkg catalog repo where tenant package exists
   161  $ cd $PKG_CATALOG_DIR
   162  
   163  # Please remove the inventory information from the Kptfile before publishing
   164  
   165  # create new tag
   166  $ git tag tenant/v0.1 main
   167  
   168  # push the tag to the upstream
   169  $ git push origin tenant/v0.1
   170  
   171  ```
   172  
   173  ## Tenant onboarding workflow
   174  
   175  Now, let’s take a look at how tenant onboarding will work. Steps described below
   176  can be done by a member of the platform team or application developer team. The
   177  good thing is that it enables self-service workflow for application teams where
   178  they can request for new tenants by simply issuing a PR against the platform repo.
   179  
   180  ```shell
   181  
   182  # assuming you have a fork of the platform repo residing locally at pointed by
   183  # by PLATFORM_DIR env variable locally. 
   184  $ cd $PLATFORM_DIR
   185  
   186  # create a new branch to onboard new tenant
   187  $ git checkout -b onboarding-tenant-a
   188  
   189  $ cd tenants
   190  
   191  # create an instance `tenant-a` of the upstream tenant package using `kpt pkg get`
   192  # Ensure PKG_CATALOG_REPO env variable points to the pkg catalog repo.
   193  $ kpt pkg get $PKG_CATALOG_REPO/tenant@v0.1 tenant-a
   194  
   195  # tenant customizations:
   196  # change the namespace to tenant-a in the tenant-a/Kptfile
   197  # configure the quota.yaml by directly editing if needed
   198  # configure resources by directly editing them
   199  # Add functions to the pipeline in Kptfile
   200  
   201  # render the package to ensure all customizations are applied
   202  # and validations are run.
   203  $ kpt fn render tenant-a
   204  
   205  # if all invariants passed, then we are all set.
   206  
   207  $ git commit -am "added tenant-a"
   208  $ git push origin onboarding-tenant-a
   209  
   210  # make a pull request for platform team to merge
   211  # TODO (link to an example PR will be great here)
   212  ```
   213  
   214  ## Day 2 use-cases
   215  
   216  Platform team can evolve the tenant package over time for example, introducing
   217  additional invariants to be enforced, updating the defaults for quota etc. So
   218  assuming a new version of the tenant package `tenant/v0.2` has been published.
   219  Let’s go through the steps needed to update the tenant package.
   220  
   221  ```shell
   222  
   223  # assuming you have a fork of the platform repo residing locally at pointed by
   224  # by PLATFORM_DIR env variable locally. 
   225  $ cd $PLATFORM_DIR
   226  
   227  # create a new branch to update tenant
   228  $ git checkout -b update-tenant-a
   229  
   230  $ kpt pkg update tenant-a@tenants/v0.2
   231  
   232  $ kpt fn render tenant-a
   233  
   234  # if all invariants passed, then we are all set.
   235  
   236  $ git commit -am "updated tenant-a to newer version"
   237  $ git push origin update-tenant-a
   238  
   239  # make a pull request for platform team to merge
   240  ```
   241  
   242  ## Summary
   243  
   244  So, in this guide, how platform teams can enable self service workflow for
   245  application teams to onboard a new tenant. In the next guide, we will explore
   246  how platform teams can do it at a scale when there are hundreds of tenants
   247  provisioned on a kubernetes cluster. Next guides will explore package lifecycle
   248  (pkg diff/update) use cases at large scale.