Showing content from https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/merge_requests/714.diff below:
diff --git a/doc/gitlab_managed_clusters.md b/doc/gitlab_managed_clusters.md new file mode 100644 index 0000000000000000000000000000000000000000..5fc8a13a755b4131d91574108f17367ec487a64e --- /dev/null +++ b/doc/gitlab_managed_clusters.md @@ -0,0 +1,213 @@ +# GitLab-managed clusters using the agent + +## Problem to solve + +Leverage the agent to replicate and improve upon certificate based +[GitLab-managed clusters](https://docs.gitlab.com/ee/user/project/clusters/gitlab_managed_clusters.html). + +### Features to replicate + +A GitLab-managed cluster provided the following features: + +- **Namespace creation** Before a deployment job starts, a namespace is created specifically for the + environment the job is deploying to. This was done by gitlab-rails, as the credentials passed to the + job would not have permission to create a namespace. + [Issue](https://gitlab.com/gitlab-org/gitlab/-/issues/297004) +- **Cross-namespace access restriction:** Credentials passed to a deployment job only had permission + to modify resources in the namespace that had been created for it. + [Issue](https://gitlab.com/gitlab-org/gitlab/-/issues/343885) + +### Improvements + +There are two limitations of the certificate integration that the new solution should address: + +- **Naming flexibility for environments within a project:** It was previously not possible to choose the + namespace for some environments but not others; a namespace was always created for every deployed + environment. A common example of where this flexibility would be beneficial is production and staging + having their own dedicated namespaces, while all review apps share a single namespace. +- **Predictable truncation behaviour:** The namespace name was previously derived from the project and + environment names. However, namespace names have a length limit of 63 characters, which was easily + exceeded and required truncation of the original name (a digest was added as a suffix to guarantee + uniqueness). This led to namespaces with very similar names (the only difference being the digest), + and it was difficult to determine which namespace an environment was deployed to. +- **Automated cleanup:** When using dynamic environments (for example, a review app for each feature + branch), clusters would previously end up with a large number of namespaces that had to be cleaned + up manually. If an environment is marked as ephemeral and removed, the namespace should also be removed. + +## Proposal + +When configuring CI access for a project or group, a user can optionally specify a list of rules +that determine both the namespace that will be created, and the branch(es) and environments that +are permitted to use the connection. + +Rules can be defined in the same way as [`rules`](https://docs.gitlab.com/ee/ci/yaml/#rulesif) used +by GitLab CI/CD. They can include references to CI/CD variables which are then expanded in the context +of the running job. + +Rules can include the following keywords: + +- `if`: Logic that is evaluated to determine if the rule is matched. If no condition is provided, +the rule is matched in all cases. +- `namespace`: The namespace to create if the rule is matched. +- `roles`: +- **TBC** Method of specifying RBAC configuration to apply if the rule is matched (complements +impersonation configuration in `access_as`). + +Values for all keys support variable expansion. + +As with GitLab CI/CD, rules are evaluated _in order_ until the first match. Exactly zero or one rules can +match for a given job. + +### Prior art + +The proposal makes use of two existing concepts: + +- **CI/CD job prerequisites:** This is the mechanism the certificate-based integration used to provision +namespaces and create service accounts (the credentials for which were then passed to the job). It provides +a way to execute actions after a CI job is created, but before it starts. Prerequisite actions are asynchronous, +which enables communication with external services (ie a Kubernetes cluster). +- **`rules` keyword and evaluation:** See the documentation for [CI/CD rules](https://docs.gitlab.com/ee/ci/yaml/#rules) +**TBC** Determine how much evaluation logic can be reused. + +### Addressing improvements + +The proposal fixes the certificate-based limitations described above: + +- **Naming flexibility**: With the ability to provide any number of rules using CI/CD variables, +namespace names are now fully customisable. +- **Truncation behaviour**: The namespace name must still be within the required limit, however now that +namespaces can be customised individually the user is able to fix this themselves. **TBC 1** By default, +GitLab could either abort the job or truncate the name. **TBC 2** This also could be configured via an +additional option, either globally or per-rule. + +### Agent exclusion **[TBC]** + +There are two options for specifying when an agent should **not** be authorised. Examples of each are +described in the next section. + +#### Option A: Exclude if no rules are matched + +If one or more rules are specified and none are matched, authorisation is denied. This may be a source +of confusion because there is a difference in behaviour when no rules are specified, and when rules are +specified but none match. The former is allowed (and must continue to be allowed to maintain backwards +compatibility), while the latter is not. + +#### Option B: Support `when: never` in rule definitions + +If one or more rules are specified and none are matched, authorisation is allowed. Access must be +explicitly denied using a keyword such as `when: never`. This is consistent with how rules behave +in CI, but would be a special case here as there are no other uses for the keyword. + +## Examples + +The following examples are per-project, however the functionality will also be available for groups. + +### Namespace management + +```yaml +# .gitlab/agents/my-agent/config.yaml +ci_access: + projects: + # Single namespace for all environments + - id: group/project1 + rules: + - namespace: gitlab-deploy + + # All environments use a seperate namespace + - id: group/project2 + rules: + - namespace: $CI_ENVIRONMENT_SLUG + + # Create production namespace only + - id: group/project3 + rules: + - if: $CI_ENVIRONMENT_SLUG == "production" + namespace: myapp-production + + # Review apps share a namespace, all others use separate namespaces + - id: group/project4 + rules: + - if: $CI_ENVIRONMENT_SLUG =~ /^review/ + namespace: review-apps + - namespace: myapp-$CI_ENVIRONMENT_SLUG +``` + +### Branch/environment restriction - OPTION A + +```yaml +# .gitlab/agents/my-agent/config.yaml +ci_access: + projects: + # Any job on the default branch + - id: group/project5 + rules: + - if: $CI_COMMIT_BRANCH == CI_DEFAULT_BRANCH + + # Any job deploying to staging or production + - id: group/project6 + rules: + - if: $CI_ENVIRONMENT_SLUG == "production" || $CI_ENVIRONMENT_SLUG == "staging" + + # Any job on the default branch that is deploying to an environment + - id: group/project7 + rules: + - if: $CI_ENVIRONMENT_SLUG && $CI_COMMIT_BRANCH == CI_DEFAULT_BRANCH +``` + +### Branch/environment restriction - OPTION B + +```yaml +# .gitlab/agents/my-agent/config.yaml +ci_access: + projects: + # Any job on the default branch + - id: group/project6 + rules: + - if: $CI_COMMIT_BRANCH == CI_DEFAULT_BRANCH + - when: never + + # Any job deploying to staging or production + - id: group/project7 + rules: + - if: $CI_ENVIRONMENT_SLUG == "production" || $CI_ENVIRONMENT_SLUG == "staging" + - when: never + + # Any job on the default branch that is deploying to an environment + - id: group/project7 + rules: + - if: $CI_ENVIRONMENT_SLUG && $CI_COMMIT_BRANCH == CI_DEFAULT_BRANCH + - when: never +``` + +## Implementation + +### Configuration flow + +The configuration flow is unchanged. When a configuration file is updated, the content is sent to +the `/api/v4/internal/kubernetes/agent_configuration` internal API endpoint and persisted to the +database. For more information, see +[Access to Kubernetes from CI](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/kubernetes_ci_access.md). + +### Execution flow + +Steps marked with an asterisk [*] are to be implemented. All others are existing. + +1. When a pipeline is created, agent authorisation configuration entries are fetched from the database +to populate the `KUBECONFIG` CI/CD variable for each job. +1. [*] While iterating through each potential agent, evaluate the `rules` section of the configuration. +If evaluation determines that the agent is not available to this job, no associated context is included +in the `KUBECONFIG`. +1. [*] When the job is triggered, determine if any interaction with the Kubernetes cluster is required +prior to the job starting (for example, creating a namespace), and trigger an +[Unmet Prerequisite](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/build/prerequisite/factory.rb) +if so. **TBC** This decision may be made on the fly, or persisted in the previous step to reduce computation. +1. The job enters the `preparing` state, and executes logic to meet any prerequisites. If these complete +successfully, the job is started. If not successful (for example, the cluster is unreachable), the job is +aborted. If there are none to complete, this step is skipped. +1. The job interacts with the cluster(s) via KAS. KAS calls the +[`/api/v4/job/allowed_agents`](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/kubernetes_ci_access.md#apiv4joballowed_agents-api) +API to determine if the requested agent is allowed. +1. [*] Agents are included/excluded in the response based on their `rules` configuration. **TBC** Again, this +information may have been persisted in a previous step. +1. Job execution continues. +
RetroSearch is an open source project built by @garambo
| Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4