Files
cozystack/packages/apps/kubernetes/values.schema.json
Myasnikov Daniil f3486f4e3a docs: move the operator guides out of docs/ to where readers find them
Five guides in docs/ were written next to the feature code that needed
them and left in the source tree, where no operator looks. They are on
the website, so a second copy here only drifts: edits kept landing in
docs/ after the website copy was made.

docs/vm-external-vlan.md is split rather than moved. Its section on
staging the reference CNI plugins is a contract that
hack/cni-plugins-staging-contract.bats asserts against the multus
Dockerfile, the daemonset manifest and the platform values, so that half
is package documentation and goes to packages/system/multus/README.md,
which the suite now reads. The operator half goes to the website.

Assisted-by: LLM
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-10-14 16:24:16 +05:00

1090 lines
42 KiB
JSON

{
"title": "Chart Values",
"type": "object",
"x-cozystack-name": {
"type": "string",
"description": "Cluster name. Every worker pool is a separate KubernetesNodes release named `kubernetes-nodes-\u003cname\u003e-\u003cpool\u003e`, so the name must leave room for the default `md0` pool inside the 53-character Helm release name limit.",
"maxLength": 32
},
"properties": {
"storageClass": {
"description": "Default StorageClass inside the tenant cluster. Remote-accessible LINSTOR classes are auto-propagated to the tenant under the same name.",
"type": "string",
"default": "replicated",
"x-kubernetes-validations": [
{
"rule": "self == oldSelf",
"message": "storageClass is immutable"
}
],
"x-cozystack-options": {
"source": "storageclass"
}
},
"version": {
"description": "Kubernetes major.minor version to deploy",
"type": "string",
"default": "v1.35",
"enum": [
"v1.35",
"v1.34",
"v1.33",
"v1.32",
"v1.31"
]
},
"host": {
"description": "External hostname for Kubernetes cluster. Defaults to `\u003ccluster-name\u003e.\u003ctenant-host\u003e` if empty.",
"type": "string",
"default": ""
},
"substrate": {
"description": "Which infrastructure provider backs this cluster's worker VMs. `kubevirt` runs them inside this cluster; `proxmox` runs them on an external Proxmox VE cluster through capmox. The control plane is Kamaji either way — this selects the infrastructure half only. Must match the `substrate` of every KubernetesNodes pool attached to this cluster: the pools reference this cluster's infrastructure object by kind, and a mismatch leaves their Machines unreconciled. Switching an existing cluster is not supported; create a new one.",
"type": "string",
"default": "kubevirt",
"x-kubernetes-validations": [
{
"rule": "self == oldSelf",
"message": "substrate is immutable"
}
]
},
"proxmox": {
"description": "Proxmox substrate settings.",
"type": "object",
"default": {},
"required": [
"ipv4Config"
],
"properties": {
"allowedNodes": {
"description": "Proxmox nodes capmox may place VMs on. Empty means every node in the Proxmox cluster.",
"type": "array",
"default": [],
"items": {
"type": "string"
}
},
"ccm": {
"description": "Proxmox cloud-controller-manager settings.",
"type": "object",
"default": {},
"required": [
"credentialsSecretName"
],
"properties": {
"credentialsSecretName": {
"description": "Secret in THIS namespace holding the controller's Proxmox API credentials under the keys `url`, `token_id`, `token_secret` and `region`. May name the same Secret as `csi.credentialsSecretName`; it is a separate knob so the two can hold separate tokens, since this one only reads VM inventory while the driver attaches and detaches disks.",
"type": "string",
"default": ""
}
}
},
"csi": {
"description": "Proxmox CSI driver settings.",
"type": "object",
"default": {},
"required": [
"credentialsSecretName",
"enabled"
],
"properties": {
"credentialsSecretName": {
"description": "Secret in THIS namespace holding the driver's Proxmox API credentials under the keys `url`, `token_id`, `token_secret` and `region`. The parent chart composes them into the controller's config file here, in the management cluster; nothing reaches the tenant, and no token is written into a rendered manifest. Distinct from the capmox credentials on purpose: the driver attaches and detaches disks, which is a different blast radius from creating VMs.",
"type": "string",
"default": ""
},
"enabled": {
"description": "Install the driver. Without it a Proxmox-backed tenant has no way to provision PersistentVolumes at all.",
"type": "boolean",
"default": true
},
"storageClasses": {
"description": "StorageClasses to create in the tenant.",
"type": "array",
"default": [],
"items": {
"type": "object",
"required": [
"name",
"storage"
],
"properties": {
"fstype": {
"description": "Filesystem the driver formats volumes with: ext4 or xfs.",
"type": "string"
},
"name": {
"description": "StorageClass name inside the tenant cluster.",
"type": "string"
},
"reclaimPolicy": {
"description": "Delete or Retain.",
"type": "string"
},
"ssd": {
"description": "Mark volumes as SSD-backed, which changes the discard/cache defaults Proxmox applies.",
"type": "boolean"
},
"storage": {
"description": "Proxmox storage id the volumes are created on (as it appears in `pvesm status`).",
"type": "string"
}
}
}
}
}
},
"dnsServers": {
"description": "Nameservers written into each worker's network config. Required by the ProxmoxCluster schema.",
"type": "array",
"default": [],
"items": {
"type": "string"
}
},
"insecure": {
"description": "Skip verification of the Proxmox API server certificate in the CCM and the CSI controller, both of which run in the management cluster. Default false: the certificate is verified unless an operator turns that off. A stock Proxmox VE install serves a self-signed one, so set true for it, or install a certificate the management cluster trusts.",
"type": "boolean",
"default": false
},
"ipv4Config": {
"description": "Address pool for workers. capmox assigns static addresses and has no DHCP mode, so this is required rather than optional.",
"type": "object",
"default": {},
"required": [
"gateway",
"prefix"
],
"properties": {
"addresses": {
"description": "Ranges or CIDRs, e.g. `[\"10.0.0.120-10.0.0.170\"]`. capmox turns these into an InClusterIPPool, so they must not overlap any DHCP range on the same L2 or two workers will answer to one address.",
"type": "array",
"default": [],
"items": {
"type": "string"
}
},
"gateway": {
"description": "Default gateway for the workers.",
"type": "string",
"default": ""
},
"prefix": {
"description": "Netmask prefix length.",
"type": "integer",
"default": 24
}
}
}
}
},
"addons": {
"description": "Cluster addons configuration.",
"type": "object",
"default": {},
"required": [
"certManager",
"cilium",
"coredns",
"gatewayAPI",
"gpuOperator",
"hami",
"ingressNginx",
"monitoringAgents",
"ouroboros",
"velero",
"verticalPodAutoscaler"
],
"properties": {
"certManager": {
"description": "Cert-manager addon.",
"type": "object",
"default": {},
"required": [
"enabled",
"valuesOverride"
],
"properties": {
"enabled": {
"description": "Enable cert-manager.",
"type": "boolean",
"default": false
},
"valuesOverride": {
"description": "Custom Helm values overrides.",
"type": "object",
"default": {},
"x-kubernetes-preserve-unknown-fields": true
}
}
},
"cilium": {
"description": "Cilium CNI plugin. Always installed as the tenant cluster's CNI; this section only overrides its Helm values.",
"type": "object",
"default": {},
"required": [
"valuesOverride"
],
"properties": {
"valuesOverride": {
"description": "Custom Helm values overrides.",
"type": "object",
"default": {},
"x-kubernetes-preserve-unknown-fields": true
}
},
"x-cozystack-no-enable-switch": true
},
"coredns": {
"description": "CoreDNS addon. Always installed as the tenant cluster's DNS; this section only overrides its Helm values.",
"type": "object",
"default": {},
"required": [
"valuesOverride"
],
"properties": {
"valuesOverride": {
"description": "Custom Helm values overrides.",
"type": "object",
"default": {},
"x-kubernetes-preserve-unknown-fields": true
}
},
"x-cozystack-no-enable-switch": true
},
"gatewayAPI": {
"description": "Gateway API addon.",
"type": "object",
"default": {},
"required": [
"enabled"
],
"properties": {
"enabled": {
"description": "Enable Gateway API.",
"type": "boolean",
"default": false
}
}
},
"gpuOperator": {
"description": "NVIDIA GPU Operator.",
"type": "object",
"default": {},
"required": [
"enabled",
"valuesOverride"
],
"properties": {
"enabled": {
"description": "Enable GPU Operator.",
"type": "boolean",
"default": false
},
"valuesOverride": {
"description": "Custom Helm values overrides.",
"type": "object",
"default": {},
"x-kubernetes-preserve-unknown-fields": true
}
}
},
"hami": {
"description": "HAMi GPU virtualization middleware.",
"type": "object",
"default": {},
"required": [
"enabled",
"valuesOverride"
],
"properties": {
"enabled": {
"description": "Enable HAMi (requires GPU Operator).",
"type": "boolean",
"default": false
},
"valuesOverride": {
"description": "Custom Helm values overrides.",
"type": "object",
"default": {},
"x-kubernetes-preserve-unknown-fields": true
}
}
},
"ingressNginx": {
"description": "Ingress-NGINX controller.",
"type": "object",
"default": {},
"required": [
"enabled",
"exposeMethod",
"valuesOverride"
],
"properties": {
"enabled": {
"description": "Enable the controller (requires nodes labeled `ingress-nginx`).",
"type": "boolean",
"default": false
},
"exposeMethod": {
"description": "Method to expose the controller. Allowed values: `Proxied`, `LoadBalancer`.",
"type": "string",
"default": "Proxied",
"enum": [
"Proxied",
"LoadBalancer"
]
},
"hosts": {
"description": "Domains routed to this tenant cluster when `exposeMethod` is `Proxied`.",
"type": "array",
"default": [],
"items": {
"type": "string"
}
},
"valuesOverride": {
"description": "Custom Helm values overrides.",
"type": "object",
"default": {},
"x-kubernetes-preserve-unknown-fields": true
}
}
},
"monitoringAgents": {
"description": "Monitoring agents.",
"type": "object",
"default": {},
"required": [
"enabled",
"valuesOverride"
],
"properties": {
"enabled": {
"description": "Enable monitoring agents.",
"type": "boolean",
"default": false
},
"valuesOverride": {
"description": "Custom Helm values overrides.",
"type": "object",
"default": {},
"x-kubernetes-preserve-unknown-fields": true
}
}
},
"ouroboros": {
"description": "Hairpin-NAT fix for ingress-nginx with PROXY-protocol.",
"type": "object",
"default": {},
"required": [
"enabled",
"valuesOverride"
],
"properties": {
"enabled": {
"description": "Enable ouroboros. Requires addons.ingressNginx.enabled (chart-render fail otherwise). Only useful when PROXY-protocol is wired on the tenant ingress-nginx via valuesOverride.",
"type": "boolean",
"default": false
},
"valuesOverride": {
"description": "Custom Helm values overrides. Operator-key wins over cozystack defaults.",
"type": "object",
"default": {},
"x-kubernetes-preserve-unknown-fields": true
}
}
},
"velero": {
"description": "Velero backup/restore addon.",
"type": "object",
"default": {},
"required": [
"enabled",
"valuesOverride"
],
"properties": {
"enabled": {
"description": "Enable Velero.",
"type": "boolean",
"default": false
},
"valuesOverride": {
"description": "Custom Helm values overrides.",
"type": "object",
"default": {},
"x-kubernetes-preserve-unknown-fields": true
}
}
},
"verticalPodAutoscaler": {
"description": "Vertical Pod Autoscaler. Installed and removed together with addons.monitoringAgents.enabled; this section only overrides its Helm values.",
"type": "object",
"default": {},
"required": [
"valuesOverride"
],
"properties": {
"valuesOverride": {
"description": "Custom Helm values overrides.",
"type": "object",
"default": {},
"x-kubernetes-preserve-unknown-fields": true
}
},
"x-cozystack-no-enable-switch": true
}
}
},
"controlPlane": {
"description": "Kubernetes control-plane configuration.",
"type": "object",
"default": {},
"required": [
"apiServer",
"controllerManager",
"konnectivity",
"replicas",
"scheduler"
],
"properties": {
"apiServer": {
"description": "API Server configuration.",
"type": "object",
"default": {},
"required": [
"resources",
"resourcesPreset"
],
"properties": {
"admissionControllers": {
"description": "Admission plugins the tenant kube-apiserver enables, passed through to KamajiControlPlane `spec.admissionControllers`, which the control plane renders as `--enable-admission-plugins`. A non-empty list replaces the control plane's default set instead of adding to it. The kube-apiserver enables these plugins in addition to its own default ones, so leaving a plugin out does not turn it off; to turn one off, name it in `--disable-admission-plugins` in `controlPlane.apiServer.extraArgs` and keep it out of this list, since the apiserver refuses to start with a plugin in both, and the control plane's default set names several. Empty by default, which keeps that default set, taken from the TenantControlPlane CRD: CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, LimitRanger, MutatingAdmissionWebhook, NamespaceLifecycle, PersistentVolumeClaimResize, Priority, ResourceQuota, RuntimeClass, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook. `NodeRestriction` is not in it.",
"type": "array",
"default": [],
"items": {
"type": "string",
"enum": [
"AlwaysAdmit",
"AlwaysDeny",
"AlwaysPullImages",
"CertificateApproval",
"CertificateSigning",
"CertificateSubjectRestriction",
"DefaultIngressClass",
"DefaultStorageClass",
"DefaultTolerationSeconds",
"DenyEscalatingExec",
"DenyExecOnPrivileged",
"DenyServiceExternalIPs",
"EventRateLimit",
"ExtendedResourceToleration",
"ImagePolicyWebhook",
"LimitPodHardAntiAffinityTopology",
"LimitRanger",
"MutatingAdmissionWebhook",
"NamespaceAutoProvision",
"NamespaceExists",
"NamespaceLifecycle",
"NodeRestriction",
"OwnerReferencesPermissionEnforcement",
"PersistentVolumeClaimResize",
"PersistentVolumeLabel",
"PodNodeSelector",
"PodSecurity",
"PodSecurityPolicy",
"PodTolerationRestriction",
"Priority",
"ResourceQuota",
"RuntimeClass",
"SecurityContextDeny",
"ServiceAccount",
"StorageObjectInUseProtection",
"TaintNodesByCondition",
"ValidatingAdmissionWebhook"
]
}
},
"extraArgs": {
"description": "Extra command-line flags appended to the tenant kube-apiserver, passed through to KamajiControlPlane `spec.apiServer.extraArgs`. For OIDC use `spec.oidc.mode` — this passthrough is the escape hatch for unrelated apiserver flags. The tenant control plane sets each of the following flags itself and drops an entry naming one before the apiserver sees it. The chart moves an `--enable-admission-plugins=` entry into `controlPlane.apiServer.admissionControllers` and a `--kubelet-preferred-address-types=` entry into `controlPlane.kubelet.preferredAddressTypes` while that field is empty, and refuses any other entry naming one of them: `--advertise-address`, `--client-ca-file`, `--enable-admission-plugins`, `--service-cluster-ip-range`, `--kubelet-client-certificate`, `--kubelet-client-key`, `--kubelet-preferred-address-types`, `--proxy-client-cert-file`, `--proxy-client-key-file`, `--requestheader-allowed-names`, `--requestheader-client-ca-file`, `--secure-port`, `--service-account-key-file`, `--service-account-signing-key-file`, `--tls-cert-file`, `--tls-private-key-file`, `--etcd-servers`, `--etcd-cafile`, `--etcd-certfile`, `--etcd-keyfile`, `--etcd-prefix`, `--etcd-compaction-interval`, `--egress-selector-config-file`. When `spec.oidc.mode` is not `None` the chart also renders OIDC flags here, reads what you have written on them, and refuses some combinations outright; the Aggregated API servers section of the Kubernetes OIDC guide on cozystack.io carries which flags, which combinations, and why. Do NOT add legacy `--oidc-*` flags here when `spec.oidc.mode` is not `None`; the chart injects `--authentication-config` and the apiserver refuses to boot with both. Empty by default (no change to current behavior).",
"type": "array",
"default": [],
"items": {
"type": "string"
}
},
"extraVolumeMounts": {
"description": "Extra volume mounts added to the tenant kube-apiserver container, passed through to KamajiControlPlane `spec.apiServer.extraVolumeMounts`. Each `name` must reference a volume declared in `extraVolumes`; the chart-managed talos secret volumes cannot be mounted. Each item is a core/v1 VolumeMount. Empty by default.",
"type": "array",
"default": [],
"items": {
"type": "object",
"x-kubernetes-preserve-unknown-fields": true
}
},
"extraVolumes": {
"description": "Extra volumes added to the control-plane Deployment, passed through to KamajiControlPlane `spec.deployment.extraVolumes`. Use to mount a ConfigMap or Secret holding an AuthenticationConfiguration file referenced by `extraArgs`. Each item is a core/v1 Volume, but because the control-plane pod runs on the management cluster only `configMap` and `secret` sources are allowed (host-reaching sources like `hostPath`/`csi` and token-projection via `projected` are rejected); each volume must have a unique, non-empty name and exactly one source. The names `talos-ca` and `talos-tls-cert` are reserved by the chart. Empty by default.",
"type": "array",
"default": [],
"items": {
"type": "object",
"x-kubernetes-preserve-unknown-fields": true
}
},
"resources": {
"description": "CPU and memory resources for API Server.",
"type": "object",
"default": {},
"properties": {
"cpu": {
"description": "CPU available.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"x-kubernetes-int-or-string": true
},
"memory": {
"description": "Memory (RAM) available.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"x-kubernetes-int-or-string": true
}
}
},
"resourcesPreset": {
"description": "Preset if `resources` omitted.",
"type": "string",
"default": "c1.medium",
"enum": [
"t1.nano",
"t1.micro",
"t1.small",
"t1.medium",
"t1.large",
"t1.xlarge",
"t1.2xlarge",
"t1.4xlarge",
"c1.nano",
"c1.micro",
"c1.small",
"c1.medium",
"c1.large",
"c1.xlarge",
"c1.2xlarge",
"c1.4xlarge",
"s1.nano",
"s1.micro",
"s1.small",
"s1.medium",
"s1.large",
"s1.xlarge",
"s1.2xlarge",
"s1.4xlarge",
"u1.nano",
"u1.micro",
"u1.small",
"u1.medium",
"u1.large",
"u1.xlarge",
"u1.2xlarge",
"u1.4xlarge",
"m1.nano",
"m1.micro",
"m1.small",
"m1.medium",
"m1.large",
"m1.xlarge",
"m1.2xlarge",
"m1.4xlarge",
"nano",
"micro",
"small",
"medium",
"large",
"xlarge",
"2xlarge"
]
}
}
},
"controllerManager": {
"description": "Controller Manager configuration.",
"type": "object",
"default": {},
"required": [
"resources",
"resourcesPreset"
],
"properties": {
"resources": {
"description": "CPU and memory resources for Controller Manager.",
"type": "object",
"default": {},
"properties": {
"cpu": {
"description": "CPU available.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"x-kubernetes-int-or-string": true
},
"memory": {
"description": "Memory (RAM) available.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"x-kubernetes-int-or-string": true
}
}
},
"resourcesPreset": {
"description": "Preset if `resources` omitted.",
"type": "string",
"default": "t1.micro",
"enum": [
"t1.nano",
"t1.micro",
"t1.small",
"t1.medium",
"t1.large",
"t1.xlarge",
"t1.2xlarge",
"t1.4xlarge",
"c1.nano",
"c1.micro",
"c1.small",
"c1.medium",
"c1.large",
"c1.xlarge",
"c1.2xlarge",
"c1.4xlarge",
"s1.nano",
"s1.micro",
"s1.small",
"s1.medium",
"s1.large",
"s1.xlarge",
"s1.2xlarge",
"s1.4xlarge",
"u1.nano",
"u1.micro",
"u1.small",
"u1.medium",
"u1.large",
"u1.xlarge",
"u1.2xlarge",
"u1.4xlarge",
"m1.nano",
"m1.micro",
"m1.small",
"m1.medium",
"m1.large",
"m1.xlarge",
"m1.2xlarge",
"m1.4xlarge",
"nano",
"micro",
"small",
"medium",
"large",
"xlarge",
"2xlarge"
]
}
}
},
"konnectivity": {
"description": "Konnectivity configuration.",
"type": "object",
"default": {},
"required": [
"server"
],
"properties": {
"server": {
"description": "Konnectivity Server configuration.",
"type": "object",
"default": {},
"required": [
"resources",
"resourcesPreset"
],
"properties": {
"resources": {
"description": "CPU and memory resources for Konnectivity.",
"type": "object",
"default": {},
"properties": {
"cpu": {
"description": "CPU available.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"x-kubernetes-int-or-string": true
},
"memory": {
"description": "Memory (RAM) available.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"x-kubernetes-int-or-string": true
}
}
},
"resourcesPreset": {
"description": "Preset if `resources` omitted.",
"type": "string",
"default": "t1.micro",
"enum": [
"t1.nano",
"t1.micro",
"t1.small",
"t1.medium",
"t1.large",
"t1.xlarge",
"t1.2xlarge",
"t1.4xlarge",
"c1.nano",
"c1.micro",
"c1.small",
"c1.medium",
"c1.large",
"c1.xlarge",
"c1.2xlarge",
"c1.4xlarge",
"s1.nano",
"s1.micro",
"s1.small",
"s1.medium",
"s1.large",
"s1.xlarge",
"s1.2xlarge",
"s1.4xlarge",
"u1.nano",
"u1.micro",
"u1.small",
"u1.medium",
"u1.large",
"u1.xlarge",
"u1.2xlarge",
"u1.4xlarge",
"m1.nano",
"m1.micro",
"m1.small",
"m1.medium",
"m1.large",
"m1.xlarge",
"m1.2xlarge",
"m1.4xlarge",
"nano",
"micro",
"small",
"medium",
"large",
"xlarge",
"2xlarge"
]
}
}
}
}
},
"kubelet": {
"description": "Kubelet connection settings.",
"type": "object",
"default": {},
"properties": {
"preferredAddressTypes": {
"description": "Node address types the tenant kube-apiserver tries, in order, when it connects to a kubelet, passed through to KamajiControlPlane `spec.kubelet.preferredAddressTypes`, which the control plane renders as `--kubelet-preferred-address-types`. The KamajiControlPlane CRD rejects a repeated name. Empty by default, which renders `InternalIP`, `ExternalIP`, or the list of a `--kubelet-preferred-address-types=` entry in `controlPlane.apiServer.extraArgs` when there is one.",
"type": "array",
"default": [],
"items": {
"type": "string",
"enum": [
"Hostname",
"InternalIP",
"ExternalIP",
"InternalDNS",
"ExternalDNS"
]
}
}
}
},
"replicas": {
"description": "Number of control-plane replicas.",
"type": "integer",
"default": 2
},
"scheduler": {
"description": "Scheduler configuration.",
"type": "object",
"default": {},
"required": [
"resources",
"resourcesPreset"
],
"properties": {
"resources": {
"description": "CPU and memory resources for Scheduler.",
"type": "object",
"default": {},
"properties": {
"cpu": {
"description": "CPU available.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"x-kubernetes-int-or-string": true
},
"memory": {
"description": "Memory (RAM) available.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"x-kubernetes-int-or-string": true
}
}
},
"resourcesPreset": {
"description": "Preset if `resources` omitted.",
"type": "string",
"default": "t1.micro",
"enum": [
"t1.nano",
"t1.micro",
"t1.small",
"t1.medium",
"t1.large",
"t1.xlarge",
"t1.2xlarge",
"t1.4xlarge",
"c1.nano",
"c1.micro",
"c1.small",
"c1.medium",
"c1.large",
"c1.xlarge",
"c1.2xlarge",
"c1.4xlarge",
"s1.nano",
"s1.micro",
"s1.small",
"s1.medium",
"s1.large",
"s1.xlarge",
"s1.2xlarge",
"s1.4xlarge",
"u1.nano",
"u1.micro",
"u1.small",
"u1.medium",
"u1.large",
"u1.xlarge",
"u1.2xlarge",
"u1.4xlarge",
"m1.nano",
"m1.micro",
"m1.small",
"m1.medium",
"m1.large",
"m1.xlarge",
"m1.2xlarge",
"m1.4xlarge",
"nano",
"micro",
"small",
"medium",
"large",
"xlarge",
"2xlarge"
]
}
}
}
}
},
"images": {
"description": "Optional image overrides for air-gapped or rate-limited registries.",
"type": "object",
"default": {},
"properties": {
"kubectl": {
"description": "Image used by the bootstrap-token tenant Job (kubectl). Empty falls back to images/kubectl.tag.",
"type": "string",
"default": ""
},
"talosCsrSigner": {
"description": "Image used by the talos-csr-signer sidecar in the Kamaji control plane. Empty falls back to images/talos-csr-signer.tag.",
"type": "string",
"default": ""
},
"waitForKubeconfig": {
"description": "Image used by the wait-for-kubeconfig init container. Empty falls back to images/busybox.tag.",
"type": "string",
"default": ""
}
}
},
"talos": {
"description": "Talos worker image configuration.",
"type": "object",
"default": {},
"required": [
"imageFactoryURL",
"installerRepository",
"registryMirrors",
"schematicID",
"version"
],
"properties": {
"imageFactoryURL": {
"description": "Base URL of the Talos Image Factory that serves the worker OS disk image (the `openstack-amd64.raw.xz` raw artifact streamed in by CDI over HTTP). Defaults to the public factory. Point at a self-hosted Image Factory, a caching mirror, or an internal HTTP file server for air-gapped, rate-limited, or flaky-egress environments. No trailing slash.",
"type": "string",
"default": "https://factory.talos.dev"
},
"installerRepository": {
"description": "OCI repository prefix for the Talos installer image used by the in-guest `talos-reconcile` upgrade Job. Resolved as `\u003cinstallerRepository\u003e/\u003cschematicID\u003e:\u003cversion\u003e`. Defaults to the public factory's installer path. Override for air-gapped or mirrored registries. No trailing slash.",
"type": "string",
"default": "factory.talos.dev/installer"
},
"registryMirrors": {
"description": "Talos `machine.registries.mirrors` passthrough for worker nodes: a map of upstream registry host to `{ endpoints: [ ... ] }`. Empty by default, so workers pull container images (the Talos `kubelet` image included) directly from the upstream registry. Point a host such as `ghcr.io` at an in-cluster pull-through mirror for air-gapped, rate-limited, or flaky-egress environments so a worker's boot does not depend on live public egress. Talos still falls back to the upstream registry unless a host also sets `skipFallback: true`, so a mirror alone does not enforce air-gap.",
"type": "object",
"default": {},
"x-kubernetes-preserve-unknown-fields": true
},
"schematicID": {
"description": "Talos image-factory schematic ID. Defaults to the cozystack-tested vanilla schematic. Operators using custom schematics (system extensions, kernel args) override here.",
"type": "string",
"default": "ce4c980550dd2ab1b17bbf2b08801c7eb59418eafe8f279833297925d67c7515"
},
"version": {
"description": "Talos release used for worker OS image and installer. Must satisfy the chart's Talos\u003c-\u003eKubernetes support matrix against the chosen `version`.",
"type": "string",
"default": "v1.13.6"
}
}
},
"oidc": {
"description": "OIDC authentication and per-user RBAC for the tenant kube-apiserver. See https://cozystack.io/docs/v1.6/kubernetes/oidc-authentication/ for the operator guide.",
"type": "object",
"default": {},
"required": [
"mode"
],
"properties": {
"customConfig": {
"description": "Tenant-supplied AuthenticationConfiguration; consumed only when `mode: CustomConfig`.",
"type": "object",
"default": {},
"properties": {
"config": {
"description": "Inline AuthenticationConfiguration YAML (`apiserver.config.k8s.io/v1beta1`). The chart writes the value verbatim into a Secret mounted at `/etc/kubernetes/authentication-config/config.yaml` on the kube-apiserver. Mutually exclusive with `secretRef.name`.",
"type": "string",
"default": ""
},
"secretRef": {
"description": "Reference to an existing Secret in the tenant namespace carrying the `AuthenticationConfiguration`.",
"type": "object",
"default": {},
"properties": {
"name": {
"description": "Name of an existing Secret in the tenant (release) namespace whose `config.yaml` key holds an `apiserver.config.k8s.io/v1beta1` `AuthenticationConfiguration`. Mutually exclusive with `customConfig.config`.",
"type": "string",
"default": ""
}
}
}
}
},
"mode": {
"description": "Identity mode. `None`: no OIDC, only the static admin kubeconfig works. `System`: trust the platform Keycloak realm (`cozy` by default) via a per-cluster public client with audience binding; zero-config default. `CustomConfig`: trust a tenant-supplied issuer directly (BYO); `cozy` is not in the path.",
"type": "string",
"default": "None",
"enum": [
"None",
"System",
"CustomConfig"
]
},
"users": {
"description": "Users granted access to the tenant cluster; each entry produces one ClusterRoleBinding inside the tenant cluster. Works for both `System` and `CustomConfig` modes.",
"type": "array",
"default": [],
"items": {
"type": "object",
"required": [
"email",
"role"
],
"properties": {
"email": {
"description": "Email address matched against the `email` claim from the issuer. Used verbatim as the `User:` subject in the ClusterRoleBinding inside the tenant cluster. The `email` claim is a built-in OIDC scope requested explicitly by the chart-generated `kubectl oidc-login` kubeconfig; every conformant OIDC provider (cozy realm included) emits it.",
"type": "string"
},
"role": {
"description": "Role to bind: `admin` maps to `ClusterRole/cluster-admin`, `view` maps to `ClusterRole/view`.",
"type": "string",
"enum": [
"admin",
"view"
]
}
}
}
}
}
}
}
}