diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-07 09:08:04 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-07 09:08:04 +0300 |
commit | 95a6825e19809cae0cee779c0ca3667b233a58f4 (patch) | |
tree | e5cb19ea02021cf67be33cfc30a5c4f59ccf10d5 /doc | |
parent | fcfafe81d1f1aa442c5a5c93cd27b5f5b798cb90 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'doc')
-rw-r--r-- | doc/api/graphql/reference/index.md | 17 | ||||
-rw-r--r-- | doc/architecture/blueprints/gitlab_agent_deployments/index.md | 403 | ||||
-rw-r--r-- | doc/ci/yaml/index.md | 2 |
3 files changed, 413 insertions, 9 deletions
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index a4a74c171d9..0b5d73afacd 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -10928,7 +10928,7 @@ four standard [pagination arguments](#connection-pagination-arguments): | <a id="boardepicancestorsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. | | <a id="boardepicancestorsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. | | <a id="boardepicancestorsnot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. | -| <a id="boardepicancestorsor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. | +| <a id="boardepicancestorsor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. | | <a id="boardepicancestorssearch"></a>`search` | [`String`](#string) | Search query for title or description. | | <a id="boardepicancestorssort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. | | <a id="boardepicancestorsstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. | @@ -10967,7 +10967,7 @@ four standard [pagination arguments](#connection-pagination-arguments): | <a id="boardepicchildrenmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. | | <a id="boardepicchildrenmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. | | <a id="boardepicchildrennot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. | -| <a id="boardepicchildrenor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. | +| <a id="boardepicchildrenor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. | | <a id="boardepicchildrensearch"></a>`search` | [`String`](#string) | Search query for title or description. | | <a id="boardepicchildrensort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. | | <a id="boardepicchildrenstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. | @@ -13018,7 +13018,7 @@ four standard [pagination arguments](#connection-pagination-arguments): | <a id="epicancestorsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. | | <a id="epicancestorsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. | | <a id="epicancestorsnot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. | -| <a id="epicancestorsor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. | +| <a id="epicancestorsor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. | | <a id="epicancestorssearch"></a>`search` | [`String`](#string) | Search query for title or description. | | <a id="epicancestorssort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. | | <a id="epicancestorsstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. | @@ -13057,7 +13057,7 @@ four standard [pagination arguments](#connection-pagination-arguments): | <a id="epicchildrenmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. | | <a id="epicchildrenmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. | | <a id="epicchildrennot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. | -| <a id="epicchildrenor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. | +| <a id="epicchildrenor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. | | <a id="epicchildrensearch"></a>`search` | [`String`](#string) | Search query for title or description. | | <a id="epicchildrensort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. | | <a id="epicchildrenstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. | @@ -14077,7 +14077,7 @@ Returns [`Epic`](#epic). | <a id="groupepicmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. | | <a id="groupepicmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. | | <a id="groupepicnot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. | -| <a id="groupepicor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. | +| <a id="groupepicor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. | | <a id="groupepicsearch"></a>`search` | [`String`](#string) | Search query for title or description. | | <a id="groupepicsort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. | | <a id="groupepicstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. | @@ -14128,7 +14128,7 @@ four standard [pagination arguments](#connection-pagination-arguments): | <a id="groupepicsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. | | <a id="groupepicsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. | | <a id="groupepicsnot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. | -| <a id="groupepicsor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. | +| <a id="groupepicsor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. | | <a id="groupepicssearch"></a>`search` | [`String`](#string) | Search query for title or description. | | <a id="groupepicssort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. | | <a id="groupepicsstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. | @@ -25289,7 +25289,7 @@ Values for ordering deployments by a specific field. | <a id="epicfilterslabelname"></a>`labelName` | [`[String]`](#string) | Filter by label name. | | <a id="epicfiltersmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. | | <a id="epicfiltersnot"></a>`not` | [`NegatedEpicBoardIssueInput`](#negatedepicboardissueinput) | Negated epic arguments. | -| <a id="epicfiltersor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. | +| <a id="epicfiltersor"></a>`or` | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. | | <a id="epicfilterssearch"></a>`search` | [`String`](#string) | Search query for epic title or description. | ### `EpicTreeNodeFieldsInputType` @@ -25570,7 +25570,8 @@ A time-frame defined as a closed inclusive range of two dates. | Name | Type | Description | | ---- | ---- | ----------- | -| <a id="unionedepicfilterinputlabelname"></a>`labelName` | [`[String!]`](#string) | Filters epics that have at least one of the given labels. Ignored unless `or_issuable_queries` flag is enabled. | +| <a id="unionedepicfilterinputauthorusername"></a>`authorUsername` | [`[String!]`](#string) | Filters epics that are authored by one of the given users. | +| <a id="unionedepicfilterinputlabelname"></a>`labelName` | [`[String!]`](#string) | Filters epics that have at least one of the given labels. | ### `UnionedIssueFilterInput` diff --git a/doc/architecture/blueprints/gitlab_agent_deployments/index.md b/doc/architecture/blueprints/gitlab_agent_deployments/index.md new file mode 100644 index 00000000000..96e361d7531 --- /dev/null +++ b/doc/architecture/blueprints/gitlab_agent_deployments/index.md @@ -0,0 +1,403 @@ +--- +status: proposed +creation-date: "2022-11-23" +authors: [ "@shinya.maeda" ] +coach: "@DylanGriffith" +approvers: [ "@nagyv-gitlab", "@cbalane", "@hustewart", "@hfyngvason" ] +owning-stage: "~devops::release" +participating-stages: [Configure, Release] +--- + +# View and manage resources deployed by GitLab Agent For Kuberenetes + +## Summary + +As part of the [GitLab Kubernetes Dashboard](https://gitlab.com/groups/gitlab-org/-/epics/2493) epic, +users want to view and manage their resources deployed by GitLab Agent For Kuberenetes. +Users should be able to interact with the resources through GitLab UI, such as Environment Index/Details page. + +This blueprint describes how the association is established and how these domain models interact with each other. + +## Motivation + +### Goals + +- The proposed architecture can be used in [GitLab Kubernetes Dashboard](https://gitlab.com/groups/gitlab-org/-/epics/2493). +- The proposed architecture can be used in [Organization-level Environment dashboard](https://gitlab.com/gitlab-org/gitlab/-/issues/241506). +- The cluster resources and events can be visualized per [GitLab Environment](../../../ci/environments/index.md). + An environment-specific view scoped to the resources managed either directly or indirectly by a deployment commit. +- Support both [GitOps mode](../../../user/clusters/agent/gitops.md#gitops-configuration-reference) and [CI Access mode](../../../user/clusters/agent/ci_cd_workflow.md#authorize-the-agent). + - NOTE: At the moment, we focus on the solution for CI Access mode. GitOps mode will have significant architectural changes _outside of_ this blueprint, + such as [Flux switching](https://gitlab.com/gitlab-org/gitlab/-/issues/357947) and [Manifest projects outside of the Agent configuration project](https://gitlab.com/groups/gitlab-org/-/epics/7704). In order to derisk potential rework, we'll revisit the GitOps mode after these upstream changes have been settled. + +### Non-Goals + +- The design details of [GitLab Kubernetes Dashboard](https://gitlab.com/groups/gitlab-org/-/epics/2493) and [Organization-level Environment dashboard](https://gitlab.com/gitlab-org/gitlab/-/issues/241506). +- Support Environment/Deployment features that rely on GitLab CI/CD pipelines, such as [Protected Environments](../../../ci/environments/protected_environments.md), [Deployment Approvals](../../../ci/environments/deployment_approvals.md), [Deployment safety](../../../ci/environments/deployment_safety.md), and [Environment rollback](../../../ci/environments/index.md#environment-rollback). These features are already available in CI Access mode, however, it's not available in GitOps mode. + +## Proposal + +### Overview + +- GitLab Environment and Agent-managed Resource Group have 1-to-1 relationship. +- Agent-managed Resource Group tracks all resources produced by the connected [agent](../../../user/clusters/agent/index.md). This includes not only resources written in manifest files but also subsequently generated resources (e.g. `Pod`s created by `Deployment` manifest file). +- Agent-managed Resource Group renders dependency graph, such as `Deployment` => `ReplicaSet` => `Pod`. This is for providing ArgoCD-style resource view. +- Agent-managed Resource Group has the Resource Health status that represents a summary of resource statuses, such as `Healthy`, `Progressing` or `Degraded`. + +```mermaid +flowchart LR + subgraph Kubernetes["Kubernetes"] + subgraph ResourceGroupProduction["ResourceGroup"] + direction LR + ResourceGroupProductionService(["Service"]) + ResourceGroupProductionDeployment(["Deployment"]) + ResourceGroupProductionPod1(["Pod1"]) + ResourceGroupProductionPod2(["Pod2"]) + end + subgraph ResourceGroupStaging["ResourceGroup"] + direction LR + ResourceGroupStagingService(["Service"]) + ResourceGroupStagingDeployment(["Deployment"]) + ResourceGroupStagingPod1(["Pod1"]) + ResourceGroupStagingPod2(["Pod2"]) + end + end + + subgraph GitLab + subgraph Organization + subgraph Project + environment1["production environment"] + environment2["staging environment"] + end + end + end + + environment1 --- ResourceGroupProduction + environment2 --- ResourceGroupStaging + ResourceGroupProductionService -.- ResourceGroupProductionDeployment + ResourceGroupProductionDeployment -.- ResourceGroupProductionPod1 + ResourceGroupProductionDeployment -.- ResourceGroupProductionPod2 + ResourceGroupStagingService -.- ResourceGroupStagingDeployment + ResourceGroupStagingDeployment -.- ResourceGroupStagingPod1 + ResourceGroupStagingDeployment -.- ResourceGroupStagingPod2 +``` + +### Existing components and relationships + +- [GitLab Project](../../../user/project/working_with_projects.md) and GitLab Environment have 1-to-many relationship. +- GitLab Project and Agent have 1-to-many _direct_ relationship. Only one project can own a specific agent. +- [GitOps mode](../../../user/clusters/agent/gitops.md#gitops-configuration-reference) + - GitLab Project and Agent do _NOT_ have many-to-many _indirect_ relationship yet. This will be supported in [Manifest projects outside of the Agent configuration project](https://gitlab.com/groups/gitlab-org/-/epics/7704). + - Agent and Agent-managed Resource Group have 1-to-1 relationship. Inventory IDs are used to group Kubernetes resources. This might be changed in [Flux switching](https://gitlab.com/gitlab-org/gitlab/-/issues/357947). +- [CI Access mode](../../../user/clusters/agent/ci_cd_workflow.md#authorize-the-agent) + - GitLab Project and Agent have many-to-many _indirect_ relationship. The project owning the agent can [share the access with the other proejcts](../../../user/clusters/agent/ci_cd_workflow.md#authorize-the-agent-to-access-projects-in-your-groups). (NOTE: Technically, only running jobs inside the project are allowed to access the cluster due to job-token authentication.) + - Agent and Agent-managed Resource Group do _NOT_ have relationships yet. + +### Issues + +- Agent-managed Resource Group should have environment ID as the foreign key, which must be unique across resource groups. +- Agent-managed Resource Group should have parameters how to group resources in the associated cluster, for example, `namespace`, `lable` and `inventory-id` (GitOps mode only) can passed as parameters. +- Agent-managed Resource Group should be able to fetch all relevant resources, including both default resource kinds and other [Custom Resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/). +- Agent-managed Resource Group should be aware of dependency graph. +- Agent-managed Resource Group should be able to compute Resource Health status from the associated resources. + +### Example: Pull-based deployment (GitOps mode) + +NOTE: +At the moment, we focus on the solution for CI Access mode. GitOps mode will have significant architectural changes _outside of_ this blueprint, +such as [Flux switching](https://gitlab.com/gitlab-org/gitlab/-/issues/357947) and [Manifest projects outside of the Agent configuration project](https://gitlab.com/groups/gitlab-org/-/epics/7704). In order to derisk potential rework, we'll revisit the GitOps mode after these upstream changes have been settled. + +### Example: Push-based deployment (CI access mode) + +This is an example of how the architecture works in push-based deployment. +The feature is documented [here](../../../user/clusters/agent/ci_cd_workflow.md) as CI access mode. + +```mermaid +flowchart LR + subgraph ProductionKubernetes["Production Kubernetes"] + subgraph ResourceGroupProductionFrontend["ResourceGroup"] + direction LR + ResourceGroupProductionFrontendService(["Service"]) + ResourceGroupProductionFrontendDeployment(["Deployment"]) + ResourceGroupProductionFrontendPod1(["Pod1"]) + ResourceGroupProductionFrontendPod2(["Pod2"]) + end + subgraph ResourceGroupProductionBackend["ResourceGroup"] + direction LR + ResourceGroupProductionBackendService(["Service"]) + ResourceGroupProductionBackendDeployment(["Deployment"]) + ResourceGroupProductionBackendPod1(["Pod1"]) + ResourceGroupProductionBackendPod2(["Pod2"]) + end + subgraph ResourceGroupProductionPrometheus["ResourceGroup"] + direction LR + ResourceGroupProductionPrometheusService(["Service"]) + ResourceGroupProductionPrometheusDeployment(["Deployment"]) + ResourceGroupProductionPrometheusPod1(["Pod1"]) + ResourceGroupProductionPrometheusPod2(["Pod2"]) + end + end + + subgraph GitLab + subgraph Organization + subgraph OperationGroup + subgraph AgentManagementProject + AgentManagementAgentProduction["Production agent"] + AgentManagementManifestFiles["Kubernetes Manifest Files"] + AgentManagementEnvironmentProductionPrometheus["production prometheus environment"] + AgentManagementPipelines["CI/CD pipelines"] + end + end + subgraph DevelopmentGroup + subgraph FrontendAppProject + FrontendAppCode["VueJS"] + FrontendDockerfile["Dockerfile"] + end + subgraph BackendAppProject + BackendAppCode["Golang"] + BackendDockerfile["Dockerfile"] + end + subgraph DeploymentProject + DeploymentManifestFiles["Kubernetes Manifest Files"] + DeploymentPipelines["CI/CD pipelines"] + DeploymentEnvironmentProductionFrontend["production frontend environment"] + DeploymentEnvironmentProductionBackend["production backend environment"] + end + end + end + end + + DeploymentEnvironmentProductionFrontend --- ResourceGroupProductionFrontend + DeploymentEnvironmentProductionBackend --- ResourceGroupProductionBackend + AgentManagementEnvironmentProductionPrometheus --- ResourceGroupProductionPrometheus + ResourceGroupProductionFrontendService -.- ResourceGroupProductionFrontendDeployment + ResourceGroupProductionFrontendDeployment -.- ResourceGroupProductionFrontendPod1 + ResourceGroupProductionFrontendDeployment -.- ResourceGroupProductionFrontendPod2 + ResourceGroupProductionBackendService -.- ResourceGroupProductionBackendDeployment + ResourceGroupProductionBackendDeployment -.- ResourceGroupProductionBackendPod1 + ResourceGroupProductionBackendDeployment -.- ResourceGroupProductionBackendPod2 + ResourceGroupProductionPrometheusService -.- ResourceGroupProductionPrometheusDeployment + ResourceGroupProductionPrometheusDeployment -.- ResourceGroupProductionPrometheusPod1 + ResourceGroupProductionPrometheusDeployment -.- ResourceGroupProductionPrometheusPod2 + AgentManagementAgentProduction -- Shared with --- DeploymentProject + DeploymentPipelines -- "Deploy" --> ResourceGroupProductionFrontend + DeploymentPipelines -- "Deploy" --> ResourceGroupProductionBackend + AgentManagementPipelines -- "Deploy" --> ResourceGroupProductionPrometheus +``` + +### Further details + +#### Multi-Project Deployment Pipelines + +The microservice project setup can be improved by [Multi-Project Deployment Pipelines](https://gitlab.com/groups/gitlab-org/-/epics/8483): + +- Deployment Project can behave as the shared deployment engine for any upstream application projects and environments. +- Environments can be created within the application projects. It gives more visibility of environments for developers. +- Deployment Project can be managed under Operator group. More segregation of duties. +- Users don't need to setup [RBAC to restrict CI/CD jobs](../../../user/clusters/agent/ci_cd_workflow.md#restrict-project-and-group-access-by-using-impersonation). +- This is especitially helpful for [dynamic environments](../../../ci/environments/index.md#create-a-dynamic-environment), such as Review Apps. + +```mermaid +flowchart LR + subgraph ProductionKubernetes["Production Kubernetes"] + subgraph ResourceGroupProductionFrontend["ResourceGroup"] + direction LR + ResourceGroupProductionFrontendService(["Service"]) + ResourceGroupProductionFrontendDeployment(["Deployment"]) + ResourceGroupProductionFrontendPod1(["Pod1"]) + ResourceGroupProductionFrontendPod2(["Pod2"]) + end + subgraph ResourceGroupProductionBackend["ResourceGroup"] + direction LR + ResourceGroupProductionBackendService(["Service"]) + ResourceGroupProductionBackendDeployment(["Deployment"]) + ResourceGroupProductionBackendPod1(["Pod1"]) + ResourceGroupProductionBackendPod2(["Pod2"]) + end + subgraph ResourceGroupProductionPrometheus["ResourceGroup"] + direction LR + ResourceGroupProductionPrometheusService(["Service"]) + ResourceGroupProductionPrometheusDeployment(["Deployment"]) + ResourceGroupProductionPrometheusPod1(["Pod1"]) + ResourceGroupProductionPrometheusPod2(["Pod2"]) + end + end + + subgraph GitLab + subgraph Organization + subgraph OperationGroup + subgraph DeploymentProject + DeploymentAgentProduction["Production agent"] + DeploymentManifestFiles["Kubernetes Manifest Files"] + DeploymentEnvironmentProductionPrometheus["production prometheus environment"] + DeploymentPipelines["CI/CD pipelines"] + end + end + subgraph DevelopmentGroup + subgraph FrontendAppProject + FrontendDeploymentPipelines["CI/CD pipelines"] + FrontendEnvironmentProduction["production environment"] + end + subgraph BackendAppProject + BackendDeploymentPipelines["CI/CD pipelines"] + BackendEnvironmentProduction["production environment"] + end + end + end + end + + FrontendEnvironmentProduction --- ResourceGroupProductionFrontend + BackendEnvironmentProduction --- ResourceGroupProductionBackend + DeploymentEnvironmentProductionPrometheus --- ResourceGroupProductionPrometheus + ResourceGroupProductionFrontendService -.- ResourceGroupProductionFrontendDeployment + ResourceGroupProductionFrontendDeployment -.- ResourceGroupProductionFrontendPod1 + ResourceGroupProductionFrontendDeployment -.- ResourceGroupProductionFrontendPod2 + ResourceGroupProductionBackendService -.- ResourceGroupProductionBackendDeployment + ResourceGroupProductionBackendDeployment -.- ResourceGroupProductionBackendPod1 + ResourceGroupProductionBackendDeployment -.- ResourceGroupProductionBackendPod2 + ResourceGroupProductionPrometheusService -.- ResourceGroupProductionPrometheusDeployment + ResourceGroupProductionPrometheusDeployment -.- ResourceGroupProductionPrometheusPod1 + ResourceGroupProductionPrometheusDeployment -.- ResourceGroupProductionPrometheusPod2 + FrontendDeploymentPipelines -- "Trigger downstream pipeline" --> DeploymentProject + BackendDeploymentPipelines -- "Trigger downstream pipeline" --> DeploymentProject + DeploymentPipelines -- "Deploy" --> ResourceGroupProductionFrontend + DeploymentPipelines -- "Deploy" --> ResourceGroupProductionBackend +``` + +#### View all Agent-managed Resource Groups on production environment + +At the group-level, we can accumulate all environments match a specific tier, for example, +listing all environments with `production` tier from subsequent projects. +This is useful to see the entire Agent-managed Resource Groups on production environment. +The following diagram examplifies the relationship between GitLab group and Kubernetes resources: + +```mermaid +flowchart LR + subgraph Kubernetes["Kubernetes"] + subgraph ResourceGroupProduction["ResourceGroup"] + direction LR + ResourceGroupProductionService(["Service"]) + ResourceGroupProductionDeployment(["Deployment"]) + ResourceGroupProductionPod1(["Pod1"]) + ResourceGroupProductionPod2(["Pod2"]) + end + subgraph ResourceGroupStaging["ResourceGroup"] + direction LR + ResourceGroupStagingService(["Service"]) + ResourceGroupStagingDeployment(["Deployment"]) + ResourceGroupStagingPod1(["Pod1"]) + ResourceGroupStagingPod2(["Pod2"]) + end + end + + subgraph GitLab + subgraph Organization + OrganizationProduction["All resources on production"] + subgraph Frontend project + FrontendEnvironmentProduction["production environment"] + end + subgraph Backend project + BackendEnvironmentProduction["production environment"] + end + end + end + + FrontendEnvironmentProduction --- ResourceGroupProduction + BackendEnvironmentProduction --- ResourceGroupStaging + ResourceGroupProductionService -.- ResourceGroupProductionDeployment + ResourceGroupProductionDeployment -.- ResourceGroupProductionPod1 + ResourceGroupProductionDeployment -.- ResourceGroupProductionPod2 + ResourceGroupStagingService -.- ResourceGroupStagingDeployment + ResourceGroupStagingDeployment -.- ResourceGroupStagingPod1 + ResourceGroupStagingDeployment -.- ResourceGroupStagingPod2 + OrganizationProduction --- FrontendEnvironmentProduction + OrganizationProduction --- BackendEnvironmentProduction +``` + +A few notes: + +- In the future, we'd have more granular filters for resource search. + For example, there are two environments `production/us-region` and `production/eu-region` in each project + and show only resources in US region at the group-level. + This could be achivable by query filtering in PostgreSQL or label/namespace filtering in Kubernetes. +- Please see [Add dynamically populated organization-level environments page](https://gitlab.com/gitlab-org/gitlab/-/issues/241506) for more information. + +## Design and implementation details + +NOTE: +The following solution might be only applicable for CI Access mode. GitOps mode will have significant architectural changes _outside of_ this blueprint, +such as [Flux switching](https://gitlab.com/gitlab-org/gitlab/-/issues/357947) and [Manifest projects outside of the Agent configuration project](https://gitlab.com/groups/gitlab-org/-/epics/7704). In order to derisk potential rework, we'll revisit the GitOps mode after these upstream changes have been settled. + +### Associate Environment with Agent + +As a preliminary step, we allow users to explicitly define "which deployment job" uses "which agent" and deploy to "which namespace". The following keywords are supported in `.gitlab-ci.yml`. + +- `environment:kubernetes:agent` ... Define which agent the deployment job uses. It can select the appropriate context from the `KUBE_CONFIG`. +- `environment:kubernetes:namespace` ... Define which namespace the deployment job deploys to. It injects `KUBE_NAMESPACE` predefined variable into the job. This keyword already [exists](../../../ci/yaml/index.md#environmentkubernetes). + +Here is an example of `.gitlab-ci.yml`. + +```yaml +deploy-production: + environment: + name: production + kubernetes: + agent: path/to/agent/repository:agent-name + namespace: default + script: + - helm --context="$KUBE_CONTEXT" --namespace="$KUBE_NAMESPACE" upgrade --install +``` + +When a deployment job is created, GitLab persists the relationship of specified agent, namespace and deployment job. If the CI job is NOT authorized to access the agent (Please refer [`Clusters::Agents::FilterAuthorizationsService`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/clusters/agents/filter_authorizations_service.rb) for more details), this relationship aren't recorded. This process happens in [`Deployments::CreateForBuildService`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/deployments/create_for_build_service.rb). The database table scheme is: + +```plaintext +agent_deployments: + - deployment_id (bigint/FK/NOT NULL/Unique) + - agent_id (bigint/FK/NOT NULL) + - kubernetes_namespace (character varying(255)/NOT NULL) +``` + +To idenfity an associated agent for a specific environment, `environment.last_deployment.agent` can be used in Rails. + +### Fetch resources through `user_access` + +When user visits an environment page, GitLab frontend fetches an environment via GraphQL. Frontend additionally fetches the associated agent-ID and namespace through deployment relationship, which being tracked by the `agent_deployments` table. + +Here is an example of GraphQL query: + +```graphql +{ + project(fullPath: "group/project") { + id + environment(name: "<environment-name>") { + slug + lastDeployment(status: SUCCESS) { + agent { + id + kubernetesNamespace + } + } + } + } +} +``` + +GitLab frontend authenticate/authorize the user access with [browser cookie](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/kubernetes_user_access.md#browser-cookie-on-gitlab-frontend). If the access is forbidden, frontend shows an error message that `You don't have access to an agent that deployed to this environment. Please contact agent administrator if you are allowed in "user_access" in agent config file. See <troubleshooting-doc-link>`. + +After the user gained access to the agent, GitLab frontend fetches available API Resource list in the Kubernetes and fetches the resources with the following parameters: + +- `namespace` ... `#{environment.lastDeployment.agent.kubernetesNamespace}` +- `labels` + - `app.gitlab.com/project_id=#{project.id}` _AND_ + - `app.gitlab.com/environment_slug: #{environment.slug}` + +If no resources are found, this is likely that the users have not embedded these lables into their resources. In this case, frontend shows an warning message `There are no resources found for the environment. Do resources have GitLab preserved labels? See <troubleshooting-doc-link>`. + +### Dependency graph + +- GitLab frontend uses [Owner References](https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/) to idenfity the dependencies between resources. These are embedded in resources as `metadata.ownerReferences` field. +- For the resoruces that don't have owner references, we can use [Well-Known Labels, Annotations and Taints](https://kubernetes.io/docs/reference/labels-annotations-taints/) as complement. e.g. `EndpointSlice` doesn't have `metadata.ownerReferences`, but has `kubernetes.io/service-name` as a reference to the parent `Service` resource. + +### Health status of resources + +- GitLab frontend computes the status summary from the fetched resources. Something similar to ArgoCD's [Resource Health](https://argo-cd.readthedocs.io/en/stable/operator-manual/health/) e.g. `Healthy`, `Progressing`, `Degraded` and `Suspended`. The formula is TBD. diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md index 8f02b502693..dfe4ac7446e 100644 --- a/doc/ci/yaml/index.md +++ b/doc/ci/yaml/index.md @@ -1711,7 +1711,7 @@ Use the `action` keyword to specify how the job interacts with the environment. |:----------|:----------------| | `start` | Default value. Indicates that the job starts the environment. The deployment is created after the job starts. | | `prepare` | Indicates that the job is only preparing the environment. It does not trigger deployments. [Read more about preparing environments](../environments/index.md#access-an-environment-for-preparation-or-verification-purposes). | -| `stop` | Indicates that the job stops a deployment. For more detail, read [Stop an environment](../environments/index.md#stop-an-environment). | +| `stop` | Indicates that the job stops an environment. [Read more about stopping an environment](../environments/index.md#stop-an-environment). | | `verify` | Indicates that the job is only verifying the environment. It does not trigger deployments. [Read more about verifying environments](../environments/index.md#access-an-environment-for-preparation-or-verification-purposes). | | `access` | Indicates that the job is only accessing the environment. It does not trigger deployments. [Read more about accessing environments](../environments/index.md#access-an-environment-for-preparation-or-verification-purposes). | |