Project Resources Documentation
This document provides a comprehensive overview of all resources created by the Kube-DC Project controller, their finalizers, ownership patterns, and deletion dependencies.
Resource Creation Order
When a Project is created, resources are synchronized in this order:
- Namespace - Project namespace (
{org}-{project}) - VPC - Kube-OVN Virtual Private Cloud
- EIp (Default Gateway) - External IP for project gateway
- Subnet - Kube-OVN subnet for project pods
- NetworkAttachmentDefinition - CNI network configuration
- OvnSnatRule - SNAT rule for outbound traffic
- Secrets - SSH keypairs and authorized keys
- RBAC - Roles and RoleBindings
- VpcDns - DNS configuration for VPC
Detailed Resource Breakdown
1. Namespace
- Resource:
v1.Namespace - Name:
{organization}-{project}(e.g.,shalb-envoy) - Finalizer: None (managed by Kubernetes)
- Created by:
NewProjectNamespace()ininternal/project/res_namespace.go - Dependencies: None (first resource created)
2. VPC (Virtual Private Cloud)
-
Resource:
kubeovn.io/v1.Vpc -
Name:
{organization}-{project}(e.g.,shalb-envoy) -
Finalizer:
kubeovn.io/kube-ovn-controller -
Created by:
NewProjectVpc()ininternal/project/res_vpc.go -
Dependencies: Namespace must exist
-
Configuration:
- Static routes to external subnets
- Extra external subnets based on
egressNetworkType
3. EIp (External IP - Default Gateway)
-
Resource:
kube-dc.com/v1.EIp -
Name:
default-gw -
Namespace:
{organization}-{project} -
Finalizer:
eip.kube-dc.com/finalizer -
Created by:
NewProjectEip()ininternal/project/res_eip_default.go -
Dependencies: Namespace must exist
-
Ownership States:
Released: No active owners (initial state)Shared: Has SNAT rule and/or LoadBalancer services as ownersExclusive: Used by FIp resources
4. OvnEip (Underlying OVN External IP)
-
Resource:
kubeovn.io/v1.OvnEip -
Name:
{organization}-{project}-{external-subnet}(e.g.,shalb-envoy-ext-public) -
Finalizer:
kubeovn.io/kube-ovn-controller -
Created by: EIp controller via
NewOvEipRes()ininternal/eip/ovn_eip_res.go -
Dependencies: EIp must exist, external subnet must be available
-
Labels:
network.kube-dc.com/eip:{namespace}.{eip-name}
-
Annotations:
kube-dc.com/ovn-eip-created-by-eip:{namespace}.{eip-name}
5. Subnet
-
Resource:
kubeovn.io/v1.Subnet -
Name:
{organization}-{project}-default(e.g.,shalb-envoy-default) -
Finalizer:
kubeovn.io/kube-ovn-controller -
Created by:
NewProjectSubnet()ininternal/project/res_subnet.go -
Dependencies: VPC must exist
-
Configuration:
- CIDR block from project spec
- Associated with project VPC
- Gateway IP (first IP in CIDR)
6. NetworkAttachmentDefinition
- Resource:
k8s.cni.cncf.io/v1.NetworkAttachmentDefinition - Name:
default - Namespace:
{organization}-{project} - Finalizer:
project.kube-dc.com/finalizer - Created by:
NewProjectNad()ininternal/project/res_nad.go - Dependencies: Subnet must exist
- Configuration: Kube-OVN CNI configuration pointing to project subnet
7. OvnSnatRule
-
Resource:
kubeovn.io/v1.OvnSnatRule -
Name:
{organization}-{project}(e.g.,shalb-envoy) -
Finalizer:
kubeovn.io/kube-ovn-controller -
Created by:
NewProjectSnat()ininternal/project/res_snat.go -
Dependencies: OvnEip must exist and have IP assigned
-
Configuration:
- Links project subnet to external IP
- Enables outbound internet access for pods
8. Secrets
SSH Key Pair Secret
- Resource:
v1.Secret - Name:
ssh-keypair-default - Namespace:
{organization}-{project} - Finalizer:
project.kube-dc.com/finalizer - Created by:
NewProjectKeyPairSeret()ininternal/project/res_secret.go - Content: Generated SSH public/private key pair
Authorized Keys Secret
- Resource:
v1.Secret - Name:
authorized-keys-default - Namespace:
{organization}-{project} - Finalizer:
project.kube-dc.com/finalizer - Created by:
NewProjectAuthKeySecret()ininternal/project/res_secret.go - Content: SSH public keys for VM access
9. RBAC Resources
Role
- Resource:
rbac.authorization.k8s.io/v1.Role - Name:
admin - Namespace:
{organization}-{project} - Finalizer:
project.kube-dc.com/finalizer - Created by:
NewProjectRole()ininternal/project/res_role.go - Permissions: Full access to project resources (pods, services, VMs, etc.)
RoleBinding
- Resource:
rbac.authorization.k8s.io/v1.RoleBinding - Name:
org-admin - Namespace:
{organization}-{project} - Finalizer:
project.kube-dc.com/finalizer - Created by:
NewProjectRoleBinding()ininternal/project/res_role_binding.go - Subject:
{organization}:org-admingroup
10. VpcDns Service
- Resource:
v1.Service - Name:
slr-vpc-dns-{organization}-{project} - Namespace:
kube-system - Finalizer: None (managed by service controller)
- Created by:
NewProjectVpcDns()ininternal/project/res_vpc_dns.go - Purpose: DNS resolution for VPC
Finalizers Summary
| Resource Type | Finalizer | Controller |
|---|---|---|
| Project | project.kube-dc.com/finalizer | kube-dc-manager |
| EIp | eip.kube-dc.com/finalizer | kube-dc-manager |
| OvnEip | kubeovn.io/kube-ovn-controller | kube-ovn-controller |
| Vpc | kubeovn.io/kube-ovn-controller | kube-ovn-controller |
| Subnet | kubeovn.io/kube-ovn-controller | kube-ovn-controller |
| OvnSnatRule | kubeovn.io/kube-ovn-controller | kube-ovn-controller |
| NetworkAttachmentDefinition | project.kube-dc.com/finalizer | kube-dc-manager |
| Secrets | project.kube-dc.com/finalizer | kube-dc-manager |
| Role | project.kube-dc.com/finalizer | kube-dc-manager |
| RoleBinding | project.kube-dc.com/finalizer | kube-dc-manager |
Deletion Order and Dependencies
When a Project is deleted, resources must be removed in reverse dependency order:
Phase 1: Application Resources
- Pods, Services, VMs - User workloads (deleted by users/operators)
- FIp resources - Floating IPs (if any exist)
Phase 2: SNAT and Networking
- OvnSnatRule - Must be deleted before OvnEip
- OvnEip - Must be deleted before EIp and Subnet
Phase 3: Project Infrastructure
- EIp - External IP resource
- NetworkAttachmentDefinition - CNI configuration
- Secrets - SSH keys and authorized keys
- RBAC - Roles and RoleBindings
- Subnet - Must be deleted before VPC
- VPC - Virtual Private Cloud
- VpcDns - DNS service
- Namespace - Project namespace (last)
Common Deletion Issues
Stuck Finalizers
- OvnEip: May get stuck if SNAT rule deletion fails
- Subnet: May get stuck if pods are still running
- EIp: May get stuck if project is deleted before EIp controller processes it
Manual Cleanup Commands
# Remove stuck finalizers (use with caution)
kubectl patch ovn-snat-rule {name} -p '{"metadata":{"finalizers":null}}' --type=merge
kubectl patch ovn-eip {name} -p '{"metadata":{"finalizers":null}}' --type=merge
kubectl patch subnet {name} -p '{"metadata":{"finalizers":null}}' --type=merge
kubectl patch eip {name} -n {namespace} -p '{"metadata":{"finalizers":null}}' --type=merge
kubectl patch project {name} -n {org-namespace} -p '{"metadata":{"finalizers":null}}' --type=merge
EIp Ownership Patterns
Ownership States
- Released:
ownershipType: Released,owners: []- No active users - Shared:
ownershipType: Shared,owners: [...]- Multiple users (SNAT + Services) - Exclusive:
ownershipType: Exclusive,owners: [single]- Single FIp owner
Owner Types
Snat: SNAT rule using the EIP for outbound trafficServiceLb: LoadBalancer service using the EIPFIp: Floating IP using the EIP exclusively
Ownership Transitions
Released → Shared (first owner added)
Shared → Released (last owner removed)
Released → Exclusive (FIp claims EIP)
Exclusive → Released (FIp releases EIP)
Organization Limits
Organizations have a configurable limit on the number of ready projects they can contain (default: 3). This limit is enforced by the Project controller during reconciliation.
- Configuration: Set via
MasterConfig.OrganizationProjectsLimit - Enforcement: Projects exceeding the limit will not be reconciled until space becomes available
- Status: Projects blocked by limits show as not ready but remain in the cluster
Enhanced Limit Enforcement (v0.1.31-dev1+)
The Project controller now provides comprehensive feedback when organization limits are hit:
Detailed Logging:
- Organization project status with ready/pending counts and project names
- Clear error messages with organization, namespace, and limit context
- Debug-level logs showing available slots and project lists
Status Conditions:
Projects blocked by limits receive a LimitCheck condition:
status:
ready: false
conditions:
- type: LimitCheck
status: "False"
reason: LimitExceeded
message: "organization limit (3 projects) reached - ready projects: 3 (limit: 3)"
lastTransitionTime: "2025-01-19T16:45:00Z"
Automatic Retry:
- Projects are automatically requeued every 30 seconds
- Reconciliation proceeds when limit space becomes available
- No manual intervention required
Projects can use different external network types:
- cloud: Uses
ext-cloudsubnet (default) - public: Uses
ext-publicsubnet (real public IPs)
The egressNetworkType in Project spec determines which external subnet is used for the default gateway EIP.