├── .chglog ├── CHANGELOG.tpl.md └── config.yml ├── LICENSE ├── README.md └── chart ├── .helmignore ├── Chart.yaml ├── templates ├── NOTES.txt ├── _helpers.tpl ├── rbac │ ├── clusterrole.yaml │ ├── clusterrolebinding.yaml │ ├── role.yaml │ └── rolebinding.yaml ├── service.yaml ├── serviceaccount.yaml ├── statefulset-service.yaml └── statefulset.yaml └── values.yaml /.chglog/CHANGELOG.tpl.md: -------------------------------------------------------------------------------- 1 | {{ range .Versions }} 2 | 3 | {{- if .NoteGroups -}} 4 | {{ range .NoteGroups -}} 5 | ### {{ .Title }} 6 | {{ range .Notes }} 7 | {{ .Body }} 8 | {{ end }} 9 | {{ end -}} 10 | {{ end -}} 11 | 12 | {{ range .CommitGroups -}} 13 | ### {{ .Title }} 14 | {{ range .Commits -}} 15 | - {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} 16 | {{ end }} 17 | {{ end -}} 18 | 19 | {{- if .RevertCommits -}} 20 | ### Reverts 21 | {{ range .RevertCommits -}} 22 | - {{ .Revert.Header }} 23 | {{ end }} 24 | {{ end -}} 25 | 26 | -------DOCS------- 27 | 28 | {{ $headlinePrinted := "false"}} 29 | {{ range $i, $commit := .Commits -}} 30 | {{ if not $commit.Type -}} 31 | {{ if not $commit.Merge -}} 32 | {{ if not $commit.Revert -}} 33 | {{ if eq $headlinePrinted "false" -}} 34 | ### 📦 Other 35 | {{ end -}} 36 | {{ $headlinePrinted = "true" -}} 37 | - {{ if $commit.Scope }}**{{ .Scope }}:** {{ end }}{{ $commit.Subject }} 38 | {{ end -}} 39 | {{ end -}} 40 | {{ end -}} 41 | {{ end -}} 42 | 43 | {{ end -}} 44 | -------------------------------------------------------------------------------- /.chglog/config.yml: -------------------------------------------------------------------------------- 1 | style: github 2 | template: CHANGELOG.tpl.md 3 | info: 4 | title: CHANGELOG 5 | repository_url: https://github.com/loft-sh/virtual-cluster 6 | options: 7 | commits: 8 | # filters: 9 | # Type: 10 | # - feat 11 | # - fix 12 | # - perf 13 | # - refactor 14 | # - docs 15 | commit_groups: 16 | title_maps: 17 | feat: 🚀 New Features 18 | fix: 🐛 Bug Fixes 19 | perf: 🏃‍♀️ Performance Improvements 20 | chart: 📊 Helm Chart 21 | refactor: 💡 Code Refactoring 22 | style: 💅 Code Style & Formatting 23 | test: 🧪 Tests Added/Fixed 24 | build: 🧱 Build Process Changes 25 | ci: 🤖 Changes to CI/CD 26 | header: 27 | pattern: "(?i)^(?:((?:feat)|(?:fix)|(?:perf)|(?:refactor)|(?:style)|(?:test)|(?:docs)|(?:build)|(?:ci)|)(?:(?:(?:[^):]*)\\()?([^)]*)\\)?)?:)?(.+)$" 28 | pattern_maps: 29 | - Type 30 | - Scope 31 | - Subject 32 | merges: 33 | pattern: "(?i)^Merges?(?: branch ')?(.+?)'?$" 34 | pattern_maps: 35 | - Source 36 | reverts: 37 | pattern: "(?i)^Reverts?(?: \")?(.+?)(?:\")?$" 38 | pattern_maps: 39 | - Header 40 | notes: 41 | keywords: 42 | - BREAKING CHANGE 43 | - "!" 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2020 - present DevSpace Technologies, Inc. 2 | 3 | Every source code file in this git repository is licensed under Apache License Version 2.0. 4 | You may obtain a copy of the Apache License Version 2.0 at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | This Apache License Version 2.0 license applies to the source code files in the git repository 9 | that contains this LICENSE file. 10 | 11 | The source code files of Loft are **not** contained in this git repository. 12 | Loft is a closed-source product of DevSpace Technologies, Inc. and may be used 13 | solely in accordance with the Loft Terms Of Service: https://loft.sh/terms 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | # THIS PROJECT HAS BEEN MOVED TO 5 | # [https://github.com/loft-sh/vcluster](https://github.com/loft-sh/vcluster) 6 | 7 | --- 8 | --- 9 | 10 | # Virtual Kubernetes Cluster 11 | 12 | Virtual Kubernetes Clusters are fully functional Kubernetes clusters but they run inside a namespace of another cluster. Virtual Clusters are a part of [loft](https://loft.sh) (see [loft documentation](https://loft.sh/docs/vclusters/basics) for more information) 13 | 14 | ## Why Virtual Clusters? 15 | 16 | Virtual clusters: 17 | 18 | - are much cheaper than "real" clusters (shared resources and single virtual cluster pod) 19 | - can be created and cleaned up again in seconds (great for CI/CD or testing) 20 | - much more powerful than a simple namespace (virtual clusters allow users to use CRDs etc.) 21 | - allow users to install apps which require cluster-wide permissions while being limited to actually just one namespace within the host cluster 22 | - provide strict isolation while still allowing you to share certain services of the underlying host cluster (e.g. using the host's ingress-controller and cert-manager) 23 | 24 | ## How does it work? 25 | 26 | The basic idea of a virtual cluster is to spin up an incomplete new Kubernetes cluster within an existing cluster and sync certain core resources between the two clusters to make the virtual cluster fully functional. The virtual cluster itself only consists of the core Kubernetes components: API server, controller manager and etcd. Besides some core kubernetes resources like pods, services, persistentvolumeclaims etc. that are needed for actual execution, all other kubernetes resources (like deployments, replicasets, resourcequotas, clusterroles, crds, apiservices etc.) are purely handled within the virtual cluster and NOT synced to the host cluster. This makes it possible to allow each user access to an complete own kubernetes cluster with full functionality, while still being able to separate them in namespaces in the actual host cluster. 27 | 28 | - A virtual Kubernetes cluster is tied to a single namespace. The virtual cluster and hypervisor run within a single pod that consists of two parts: 29 | - a k3s instance which contains the Kubernetes control plane (API server, controller manager and etcd) for the virtual cluster 30 | an instance of a virtual cluster hypervisor which is mainly responsible for syncing cluster resources between the k3s powered virtual cluster and the underlying host cluster 31 | 32 | ![virtual cluster architecture](https://loft.sh/docs/media/ui/vclusters/vcluster-architecture.png) 33 | 34 | ## Install 35 | 36 | For a one click solution take a look at [loft](https://loft.sh). For the manual install process without loft follow the guide below. 37 | 38 | ### Find out host cluster Service CIDR 39 | 40 | In order to install virtual cluster you need to find out the Service CIDR of your host cluster. This can be done by creating a service with a faulty ClusterIP in the host cluster: 41 | 42 | ``` 43 | apiVersion: v1 44 | kind: Service 45 | metadata: 46 | name: faulty-service 47 | spec: 48 | clusterIP: 1.1.1.1 49 | ports: 50 | - port: 80 51 | protocol: TCP 52 | ``` 53 | 54 | Then create the service via kubectl: 55 | 56 | ``` 57 | kubectl apply -f mysecret.yaml 58 | The Service "faulty-service" is invalid: spec.clusterIP: Invalid value: "1.1.1.1": provided IP is not in the valid range. The range of valid IPs is 10.96.0.0/12 59 | ``` 60 | 61 | The error message shows the correct Service CIDR of the cluster, in this case `10.96.0.0/12` 62 | 63 | ### Install Virtual Cluster via helm 64 | 65 | To start a new virtual cluster in any given namespace, you can use helm. 66 | 67 | Create a values.yaml depending on your host cluster kubernetes version: 68 |
69 | Host Kubernetes v1.16 70 |
71 | 72 | ``` 73 | virtualCluster: 74 | image: rancher/k3s:v1.16.13-k3s1 75 | extraArgs: 76 | - --service-cidr=10.96.0.0/12 # THE CLUSTER SERVICE CIDR HERE 77 | baseArgs: 78 | - server 79 | - --write-kubeconfig=/k3s-config/kube-config.yaml 80 | - --data-dir=/data 81 | - --no-deploy=traefik,servicelb,metrics-server,local-storage 82 | - --disable-network-policy 83 | - --disable-agent 84 | - --disable-scheduler 85 | - --disable-cloud-controller 86 | - --flannel-backend=none 87 | - --kube-controller-manager-arg=controllers=*,-nodeipam,-nodelifecycle,-persistentvolume-binder,-attachdetach,-persistentvolume-expander,-cloud-node-lifecycle 88 | storage: 89 | size: 5Gi 90 | 91 | # If you don't want to sync ingresses from the vCluster to 92 | # the host cluster uncomment the next lines 93 | #syncer: 94 | # extraArgs: ["--disable-sync-resources=ingresses"] 95 | ``` 96 | 97 |
98 | 99 |
100 | Host Kubernetes v1.17 101 |
102 | 103 | ``` 104 | virtualCluster: 105 | image: rancher/k3s:v1.17.9-k3s1 106 | extraArgs: 107 | - --service-cidr=10.96.0.0/12 # THE CLUSTER SERVICE CIDR HERE 108 | baseArgs: 109 | - server 110 | - --write-kubeconfig=/k3s-config/kube-config.yaml 111 | - --data-dir=/data 112 | - --no-deploy=traefik,servicelb,metrics-server,local-storage 113 | - --disable-network-policy 114 | - --disable-agent 115 | - --disable-scheduler 116 | - --disable-cloud-controller 117 | - --flannel-backend=none 118 | - --kube-controller-manager-arg=controllers=*,-nodeipam,-nodelifecycle,-persistentvolume-binder,-attachdetach,-persistentvolume-expander,-cloud-node-lifecycle 119 | storage: 120 | size: 5Gi 121 | 122 | # If you don't want to sync ingresses from the vCluster to 123 | # the host cluster uncomment the next lines 124 | #syncer: 125 | # extraArgs: ["--disable-sync-resources=ingresses"] 126 | ``` 127 | 128 |
129 | 130 |
131 | Host Kubernetes v1.18 132 |
133 | 134 | ``` 135 | virtualCluster: 136 | image: rancher/k3s:v1.18.6-k3s1 137 | extraArgs: 138 | - --service-cidr=10.96.0.0/12 # THE CLUSTER SERVICE CIDR HERE 139 | storage: 140 | size: 5Gi 141 | 142 | # If you don't want to sync ingresses from the vCluster to 143 | # the host cluster uncomment the next lines 144 | #syncer: 145 | # extraArgs: ["--disable-sync-resources=ingresses"] 146 | ``` 147 | 148 |
149 | 150 | Then run: 151 | ``` 152 | helm install virtualcluster virtualcluster --repo https://charts.devspace.sh/ \ 153 | --namespace virtualcluster \ 154 | --values values.yaml \ 155 | --create-namespace \ 156 | --wait 157 | ``` 158 | 159 | ### Connect to the virtual cluster 160 | 161 | After installing the virtual cluster, make sure the virtual-cluster is running via kubectl: 162 | 163 | ``` 164 | kubectl get po -n virtualcluster 165 | NAME READY STATUS RESTARTS AGE 166 | coredns-d798c9dd-kq64p-x-kube-system-x-virtualcluster 1/1 Running 0 3d17h 167 | virtualcluster-0 2/2 Running 0 3d17h 168 | ``` 169 | 170 | Retrieve the kubeconfig via kubectl: 171 | ``` 172 | kubectl exec virtualcluster-0 --namespace virtualcluster -c syncer -- cat /root/.kube/config > kubeconfig.yaml 173 | ``` 174 | 175 | Forward the virtual cluster api port to localhost: 176 | ``` 177 | kubectl port-forward test-0 -n virtualcluster 8443:8443 178 | Forwarding from 127.0.0.1:8443 -> 8443 179 | Forwarding from [::1]:8443 -> 8443 180 | ``` 181 | 182 | Now you can access the virtual cluster via kubectl: 183 | ``` 184 | kubectl --kubeconfig kubeconfig.yaml get namespaces 185 | NAME STATUS AGE 186 | default Active 83s 187 | kube-system Active 83s 188 | kube-public Active 83s 189 | kube-node-lease Active 83s 190 | ``` 191 | 192 | Congratulations, you now have a fully functional virtual kubernetes cluster! 193 | 194 | ## Delete the virtual cluster 195 | 196 | To delete a virtual cluster and its created resources in the host cluster, you just have to delete the helm chart: 197 | ``` 198 | helm delete virtualcluster -n virtualcluster 199 | ``` 200 | -------------------------------------------------------------------------------- /chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: vcluster 3 | description: vcluster - Virtual Kubernetes Clusters 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | version: 0.0.1 # version is auto-generated by release pipeline 16 | -------------------------------------------------------------------------------- /chart/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Thank you for installing {{ .Chart.Name }}. 2 | 3 | Your release is named {{ .Release.Name }}. 4 | 5 | To learn more about the release, try: 6 | 7 | $ helm status {{ .Release.Name }} 8 | $ helm get all {{ .Release.Name }} -------------------------------------------------------------------------------- /chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "vcluster.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "vcluster.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{- define "vcluster.clusterRoleName" -}} 28 | {{- printf "vc-%s-v-%s" .Release.Name .Release.Namespace | trunc 63 | trimSuffix "-" -}} 29 | {{- end -}} 30 | 31 | {{/* 32 | Create chart name and version as used by the chart label. 33 | */}} 34 | {{- define "vcluster.chart" -}} 35 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 36 | {{- end -}} 37 | 38 | {{/* 39 | Common labels 40 | */}} 41 | {{- define "vcluster.labels" -}} 42 | app.kubernetes.io/name: {{ include "vcluster.name" . }} 43 | helm.sh/chart: {{ include "vcluster.chart" . }} 44 | app.kubernetes.io/instance: {{ .Release.Name }} 45 | {{- if .Chart.AppVersion }} 46 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 47 | {{- else }} 48 | app.kubernetes.io/version: {{ .Chart.Version | quote }} 49 | {{- end }} 50 | app.kubernetes.io/managed-by: {{ .Release.Service }} 51 | {{- end -}} 52 | 53 | {{/* 54 | Get 55 | */}} 56 | {{- $}} 57 | {{- define "vcluster.admin.accessKey" -}} 58 | {{- now | unixEpoch | toString | trunc 8 | sha256sum -}} 59 | {{- end -}} -------------------------------------------------------------------------------- /chart/templates/rbac/clusterrole.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.clusterRole.create }} 2 | kind: ClusterRole 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | metadata: 5 | name: {{ template "vcluster.clusterRoleName" . }} 6 | labels: 7 | app: vcluster 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | rules: 12 | - apiGroups: [""] 13 | resources: ["nodes", "nodes/proxy", "persistentvolumes"] 14 | verbs: ["get", "watch", "list"] 15 | - apiGroups: ["storage.k8s.io"] 16 | resources: ["storageclasses"] 17 | verbs: ["get", "watch", "list"] 18 | {{- end }} -------------------------------------------------------------------------------- /chart/templates/rbac/clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.clusterRole.create }} 2 | kind: ClusterRoleBinding 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | metadata: 5 | name: {{ template "vcluster.clusterRoleName" . }} 6 | labels: 7 | app: vcluster 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | subjects: 12 | - kind: ServiceAccount 13 | name: vc-{{ .Release.Name }} 14 | namespace: {{ .Release.Namespace }} 15 | roleRef: 16 | kind: ClusterRole 17 | name: {{ template "vcluster.clusterRoleName" . }} 18 | apiGroup: rbac.authorization.k8s.io 19 | {{- end }} -------------------------------------------------------------------------------- /chart/templates/rbac/role.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.role.create }} 2 | kind: Role 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | metadata: 5 | name: {{ .Release.Name }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app: vcluster 9 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | rules: 13 | - apiGroups: [""] 14 | resources: ["configmaps", "secrets", "services", "services/proxy", "pods", "pods/proxy", "pods/attach", "pods/portforward", "pods/exec", "pods/log", "events", "endpoints", "persistentvolumeclaims"] 15 | verbs: ["*"] 16 | - apiGroups: ["networking.k8s.io"] 17 | resources: ["ingresses"] 18 | verbs: ["*"] 19 | - apiGroups: [""] 20 | resources: ["namespaces"] 21 | verbs: ["get", "list", "watch"] 22 | - apiGroups: ["apps"] 23 | resources: ["statefulsets"] 24 | verbs: ["get", "list", "watch"] 25 | {{- end }} -------------------------------------------------------------------------------- /chart/templates/rbac/rolebinding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.role.create }} 2 | kind: RoleBinding 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | metadata: 5 | name: {{ .Release.Name }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app: vcluster 9 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | subjects: 13 | - kind: ServiceAccount 14 | name: vc-{{ .Release.Name }} 15 | namespace: {{ .Release.Namespace }} 16 | roleRef: 17 | kind: Role 18 | name: {{ .Release.Name }} 19 | apiGroup: rbac.authorization.k8s.io 20 | {{- end }} -------------------------------------------------------------------------------- /chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Release.Name }} 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | app: vcluster 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | spec: 12 | type: ClusterIP 13 | ports: 14 | - name: https 15 | port: 443 16 | targetPort: 8443 17 | protocol: TCP 18 | selector: 19 | app: vcluster 20 | release: {{ .Release.Name }} 21 | -------------------------------------------------------------------------------- /chart/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create }} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: vc-{{ .Release.Name }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app: vcluster 9 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | {{- if .Values.serviceAccount.imagePullSecrets }} 13 | imagePullSecrets: 14 | {{ toYaml .Values.serviceAccount.imagePullSecrets | indent 2 }} 15 | {{- end }} 16 | {{- end }} 17 | -------------------------------------------------------------------------------- /chart/templates/statefulset-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Release.Name }}-headless 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | app: {{ template "vcluster.fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | spec: 12 | ports: 13 | - name: https 14 | port: 443 15 | targetPort: 8443 16 | protocol: TCP 17 | clusterIP: None 18 | selector: 19 | app: vcluster 20 | release: "{{ .Release.Name }}" -------------------------------------------------------------------------------- /chart/templates/statefulset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: StatefulSet 3 | metadata: 4 | name: {{ .Release.Name }} 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | app: vcluster 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | spec: 12 | serviceName: {{ .Release.Name }}-headless 13 | replicas: 1 14 | selector: 15 | matchLabels: 16 | app: vcluster 17 | release: {{ .Release.Name }} 18 | volumeClaimTemplates: 19 | - metadata: 20 | name: data 21 | spec: 22 | accessModes: [ "ReadWriteOnce" ] 23 | storageClassName: {{ .Values.storage.className }} 24 | resources: 25 | requests: 26 | storage: {{ .Values.storage.size }} 27 | template: 28 | metadata: 29 | labels: 30 | app: vcluster 31 | release: {{ .Release.Name }} 32 | spec: 33 | terminationGracePeriodSeconds: 10 34 | serviceAccountName: vc-{{ .Release.Name }} 35 | containers: 36 | - image: {{ .Values.vcluster.image }} 37 | name: vcluster 38 | command: 39 | {{- range $f := .Values.vcluster.command }} 40 | - {{ $f | quote }} 41 | {{- end }} 42 | args: 43 | {{- range $f := .Values.vcluster.baseArgs }} 44 | - {{ $f | quote }} 45 | {{- end }} 46 | {{- range $f := .Values.vcluster.extraArgs }} 47 | - {{ $f | quote }} 48 | {{- end }} 49 | env: 50 | {{ toYaml .Values.vcluster.env | indent 10 }} 51 | volumeMounts: 52 | {{ toYaml .Values.vcluster.volumeMounts | indent 10 }} 53 | resources: 54 | {{ toYaml .Values.vcluster.resources | indent 10 }} 55 | - name: syncer 56 | {{- if .Values.syncer.image }} 57 | image: "{{ .Values.syncer.image }}" 58 | {{- else }} 59 | image: "loftsh/vcluster:{{ .Chart.Version }}" 60 | {{- end }} 61 | {{- if not .Values.syncer.noArgs }} 62 | args: 63 | - --service-name={{ .Release.Name }} 64 | - --suffix={{ .Release.Name }} 65 | - --owning-statefulset={{ .Release.Name }} 66 | - --out-kube-config-secret=vc-{{ .Release.Name }} 67 | {{- range $f := .Values.syncer.extraArgs }} 68 | - {{ $f | quote }} 69 | {{- end }} 70 | {{- else }} 71 | args: 72 | {{ toYaml .Values.syncer.extraArgs | indent 10 }} 73 | {{- end }} 74 | env: 75 | {{ toYaml .Values.syncer.env | indent 10 }} 76 | volumeMounts: 77 | {{ toYaml .Values.syncer.volumeMounts | indent 10 }} 78 | resources: 79 | {{ toYaml .Values.syncer.resources | indent 10 }} 80 | -------------------------------------------------------------------------------- /chart/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for loft. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | syncer: 5 | extraArgs: [] 6 | env: [] 7 | volumeMounts: 8 | - mountPath: /data 9 | name: data 10 | resources: {} 11 | 12 | vcluster: 13 | image: rancher/k3s:v1.19.1-k3s1 14 | command: 15 | - /bin/k3s 16 | baseArgs: 17 | - server 18 | - --write-kubeconfig=/k3s-config/kube-config.yaml 19 | - --data-dir=/data 20 | - --disable=traefik,servicelb,metrics-server,local-storage 21 | - --disable-network-policy 22 | - --disable-agent 23 | - --disable-scheduler 24 | - --disable-cloud-controller 25 | - --flannel-backend=none 26 | - --kube-controller-manager-arg=controllers=*,-nodeipam,-nodelifecycle,-persistentvolume-binder,-attachdetach,-persistentvolume-expander,-cloud-node-lifecycle 27 | extraArgs: 28 | - --service-cidr=10.96.0.0/12 29 | volumeMounts: 30 | - mountPath: /data 31 | name: data 32 | env: [] 33 | resources: {} 34 | 35 | storage: 36 | size: 5Gi 37 | mountPath: /data 38 | 39 | serviceAccount: 40 | create: true 41 | 42 | rbac: 43 | clusterRole: 44 | create: false 45 | role: 46 | create: true 47 | --------------------------------------------------------------------------------