Environments
An Environment is a group of Clusters that the Orders of its namespace deploy to, such as dev, staging or the production fleet. Each decides:
- which Clusters of its namespace it covers, by their labels;
- the engine that deploys there, Argo CD, and its AppProject;
- which Environments an Order must run after before it deploys there.
Order authors name an Environment of their namespace in spec.environmentRef
when they create an Order; see
Deploy to several clusters.
# The Clusters of this namespace labeled fleet: edge, deployed to through
# Argo CD's project default. Outside Kokumi's own namespace, the project must
# admit the namespace in its sourceNamespaces.
apiVersion: delivery.kokumi.dev/v1alpha1
kind: Environment
metadata:
name: edge
spec:
description: Edge clusters
clusterSelector:
matchLabels:
fleet: edge
deployer:
type: ArgoCD
argoCD:
project: defaultThe multi-cluster example applies it with the Cluster it selects; see Clusters:
kubectl apply -n platform -k "https://github.com/kokumi-dev/kokumi//examples/multi-cluster/platform?ref=0.17.0"Clusters
clusterSelector selects Clusters of the Environment’s namespace by their
labels; {} selects every one. A Cluster joins or leaves an Environment when
its labels change:
kubectl label clusters.delivery.kokumi.dev spoke -n <namespace> fleet=edge
kubectl label clusters.delivery.kokumi.dev spoke -n <namespace> fleet-A Cluster that leaves gets no new deployments, and Kokumi leaves what runs there in place; see What runs where. Remove it by hand when you mean to.
The status counts the Clusters it selects, and those of them that are ready,
in status.clusters; its Ready message names the first ten. Each Cluster
reports on its own whether Orders can deploy to it:
kubectl get environments.delivery.kokumi.dev -n <namespace> -o wide
# NAME DEPLOYER PROJECT CLUSTERS READY CLUSTERS READY REASON AGE
# edge ArgoCD default 2 2 True Ready 5m
kubectl get clusters.delivery.kokumi.dev -n <namespace> -l fleet=edgeThe short name of Environments is env. Its Ready condition says whether
the Environment is set up so that Orders may deploy there: it selects a
Cluster, and its engine admits it. It does not follow the readiness of its
Clusters: an Environment none of whose Clusters is Ready is still Ready,
and only READY CLUSTERS shows it. Its Orders then deploy nowhere; see
What runs where.
| Reason | Meaning |
|---|---|
Ready | It selects a Cluster, and its engine admits it. |
NoClusters | It selects no Cluster of its namespace. |
InvalidSelector | Its clusterSelector is not a valid label selector. |
ProjectNotFound | Its Argo CD AppProject does not exist. |
ProjectNotPermitted | Its AppProject does not admit its namespace in sourceNamespaces. |
ArgoCDNotInstalled | Argo CD’s CRDs are not installed. |
The status is for people: Servings do not read it. Each Serving checks the Environment again whenever it deploys; see The engine.
Who may deploy where
Whoever may create Orders in the Environment’s namespace may deploy there: namespace RBAC decides. The built-in editor and viewer roles read Environments and Clusters, for the Order form’s picker; the admin role creates and changes them.
The boundary of a workspace is the Argo CD AppProject its Environments name, Argo CD’s own model for teams:
spec.sourceNamespacesdecides which namespaces’ Environments may use the project. Kokumi applies Argo CD’s rule for Applications outside its control-plane namespace: an Environment in Kokumi’s own namespace may use any project, one in another namespace only a project that admits its namespace; otherwise it and the Servings of its Orders reportProjectNotPermitted, and no Application is written. Kokumi matches each entry as a glob, with Go’spath.Match:*,?and[…], such asteam-*. It reads no entry as a regular expression (/…/) or a negation (!…): such an entry admits no namespace for Kokumi, whatever Argo CD makes of it, so list the namespaces as globs. Argo CD’sdefaultproject admits no namespace. Set the list where a project has none, and add to it where it has one:kubectl -n argocd patch appproject default --type=merge \ -p '{"spec":{"sourceNamespaces":["platform","team-*"]}}' kubectl -n argocd patch appproject default --type=json \ -p '[{"op":"add","path":"/spec/sourceNamespaces/-","value":"shop"}]'spec.destinationsdecides which servers and namespaces an Order may deploy into. Argo CD checks it: it refuses an Application whose destination the project does not permit; see What runs where for how the Serving reports it.
The engine
deployer names the engine that deploys to the Environment’s Clusters.
Today it is Argo CD: every Order deploys to each Cluster through an Argo CD
Application of its own, in the project deployer.argoCD.project, into the
Order’s target namespace; see
The namespace on the clusters.
Whenever a Serving deploys, it asks the engine whether the Order may deploy
there. For Argo CD, its CRDs must be installed, and the AppProject must exist
and, for an Environment outside Kokumi’s namespace, admit the namespace in
sourceNamespaces. A change of the Environment or of the AppProject counts
at once. For what the Serving reports when an Order may not deploy at all,
see Where an Order deploys.
Environments that come first
promotion.requireAfter lists Environments of the same namespace an Order
must run after: every Order that deploys to the Environment must name, in
spec.promotion.after, an Order of each of them, with at least
minSoakSeconds. A Preparation that does not is held, and its Serving reports
UpstreamDeployed=False with reason PipelineRequired. A Preparation the
Serving promoted before passes, so that a rollback always works. The
promotion-pipeline example’s prod requires staging:
# The environments of the pipeline, in the namespace of its Orders. All three
# deploy to the cluster Kokumi runs in, the Cluster of the namespace labeled
# delivery.kokumi.dev/in-cluster: Kokumi keeps one in its own namespace, and
# examples/local adds one to any other. With more clusters each would select
# its own.
apiVersion: delivery.kokumi.dev/v1alpha1
kind: Environment
metadata:
name: dev
spec:
clusterSelector:
matchLabels:
delivery.kokumi.dev/in-cluster: "true"
deployer:
type: ArgoCD
argoCD:
project: default
---
apiVersion: delivery.kokumi.dev/v1alpha1
kind: Environment
metadata:
name: staging
spec:
clusterSelector:
matchLabels:
delivery.kokumi.dev/in-cluster: "true"
deployer:
type: ArgoCD
argoCD:
project: default
---
# Every Order that deploys to prod must run after an Order of staging, with
# a soak of at least 60 seconds: a stage that skips staging is held.
apiVersion: delivery.kokumi.dev/v1alpha1
kind: Environment
metadata:
name: prod
spec:
clusterSelector:
matchLabels:
delivery.kokumi.dev/in-cluster: "true"
deployer:
type: ArgoCD
argoCD:
project: default
promotion:
requireAfter:
- environment: staging
minSoakSeconds: 60The Environment local
Kokumi keeps the Environment local in its own namespace, so that Orders there
deploy to the cluster Kokumi runs in out of the box. It selects the Clusters of
its namespace labeled delivery.kokumi.dev/in-cluster: "true", a label Kokumi
sets only on the Cluster in-cluster it keeps next to it, when it creates it.
Other namespaces get theirs from the example local, whose Cluster carries
the label, and an AppProject that admits them:
# Orders of this namespace that name the Environment local deploy to the
# cluster Kokumi runs in, through Argo CD's project default. Outside Kokumi's
# own namespace, that project must admit the namespace in its
# sourceNamespaces; Argo CD's default project admits none. This replaces the
# list:
#
# kubectl -n argocd patch appproject default --type=merge \
# -p '{"spec":{"sourceNamespaces":["<namespace>"]}}'
apiVersion: delivery.kokumi.dev/v1alpha1
kind: Environment
metadata:
name: local
spec:
description: The cluster Kokumi runs in
clusterSelector:
matchLabels:
delivery.kokumi.dev/in-cluster: "true"
deployer:
type: ArgoCD
argoCD:
project: defaultkubectl apply -n shop -k "https://github.com/kokumi-dev/kokumi//examples/local?ref=0.17.0"In the UI
Environments lists the Environments of every namespace you may read. Each has the tabs Overview, Clusters and Orders. Admins create and edit them; the cluster selector previews which Clusters of the namespace it selects.