Create Your First Environment¶
An Environment is where a tenant's workloads live: a Namespace owned by a Capsule Tenant, plus the VPC and subnet its clusters attach to.
A Tenant is a collector of Environments, so one tenant can hold several (one per stage, per region, per workload) each with a network of its own.
This page adds an Environment called dynamo-prod to the dynamo tenant from Create First Tenant.
Prerequisites¶
- A Tenant, and the identity that owns it (see Create First Tenant).
- A CIDR for the Environment's subnet that does not overlap another subnet in the same VPC.
Create the Environment¶
An Environment is a plain Namespace that belongs to a Tenant.
There is no Environment CRD: the Namespace is the Environment, and Capsule adopts it into the Tenant.
Create it as the tenant's owner, so Capsule assigns it to that Tenant:
Capsule stamps the namespace with the Tenant it belongs to, and sets the Tenant as its owner so the Environment is cleaned up with it:
$ kubectl get namespace dynamo-prod --show-labels
NAME STATUS AGE LABELS
dynamo-prod Active 3s capsule.clastix.io/tenant=dynamo
$ kubectl get tenant dynamo
NAME STATE NAMESPACE QUOTA NAMESPACE COUNT NODE SELECTOR READY STATUS AGE
dynamo Active 1 True reconciled 28h
A Tenant may own as many Environments as it needs (one per stage, per region, per workload) and each gets its own network below.
Claim a VPC¶
The Environment's network is declared with two namespaced claims. The tenant writes intent; the platform owns the routing rules that make it safe.
Exactly one VpcClaim may exist per Environment.
It reconciles into a cluster-scoped Kube-OVN Vpc named after the namespace:
apiVersion: network.kmetal.io/v1alpha1
kind: VpcClaim
metadata:
name: main
namespace: dynamo-prod
spec:
# Egress to the outside world. The static route and the isolation
# policy routes that go with it are injected by the platform, not
# written here.
externalAccess: true
With externalAccess: true the controller enables external access on the VPC, adds the administrator-configured default route,
and injects the drop rule that keeps this VPC off the provider segment and away from other tenants.
It also creates the well-known external EipClaim the VPC's router port needs — that is not yours to write.
Per-tenant egress isolation
A VpcClaim can also name a specific provider network to egress through,
instead of the cluster default — which is how a tenant is given a network segment of its own.
That is an advanced setup, and is covered separately.
Claim specs are immutable
Both VpcClaim.spec and SubnetClaim.spec are rejected on update.
Getting the CIDR or the external-access decision wrong means deleting the claim and re-creating it — which takes the Kube-OVN objects with it.
Decide before applying.
Check it landed:
$ kubectl get vpcclaim -n dynamo-prod
NAME VPC EXTERNAL PROVIDERNETWORK READY AGE
main dynamo-prod true True 12s
Claim a subnet¶
Each SubnetClaim reconciles into one Kube-OVN Subnet inside that VPC.
An Environment may hold several — one per cluster, for instance.
apiVersion: network.kmetal.io/v1alpha1
kind: SubnetClaim
metadata:
name: primary
namespace: dynamo-prod
spec:
cidrBlock: 10.100.0.0/24
# Defaults to the first usable address in cidrBlock when omitted.
gateway: 10.100.0.1
protocol: IPv4
excludeIps:
- 10.100.0.1
# Creates the NetworkAttachmentDefinition worker VMs attach through,
# in this namespace. On by default.
attachment:
managed: true
# SNATs this subnet's egress through the VPC's router-port EIP.
# Requires externalAccess on the VpcClaim above.
enableSnatRule: true
The VPC and the namespace binding are derived from the Environment's VpcClaim — they are deliberately absent from the claim's spec,
so a tenant cannot attach a subnet to a VPC that is not theirs.
The CIDR must not overlap another subnet in the same VPC.
The claim reports the cluster-scoped objects it bound:
$ kubectl get subnetclaim -n dynamo-prod
NAME SUBNET VPC CIDR READY AGE
primary dynamo-prod-primary dynamo-prod 10.100.0.0/24 True 8s
SUBNET is the cluster-scoped Subnet the claim created, derived from the namespace and the claim name.
A SubnetClaim that reports WaitingForVpc is in an Environment whose VpcClaim is not Ready yet.
A Cluster joins this subnet by the claim's own name — primary — not by the derived name in the SUBNET column.
What the tenant has now¶
Tenant dynamo
└── Environment dynamo-prod (Namespace, Capsule-adopted)
├── VpcClaim main → Vpc dynamo-prod
└── SubnetClaim primary → Subnet dynamo-prod-primary
NetworkAttachmentDefinition primary-net
Everything a Cluster needs to exist: a namespace to be created in, and a subnet for its worker VMs to attach to.
Next Steps¶
Create a cluster in this Environment — Create First Cluster.