diff --git a/.gitignore b/.gitignore index 6633775..2b37a9e 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ infra/hcloud-tf-k8s-talos/data/k8s-secret-external-secret.yml k8s-apps/linkerd/ infra/test *.log +k8s-apps/hegerdes-kubernetes-service/generated +k8s-apps/hegerdes-kubernetes-service/helper/generated +k8s-apps/hegerdes-kubernetes-service/helper/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0dcebfd..38635a3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: check-yaml args: [--allow-multiple-documents] - exclude: .gitlab-ci.yml|infra/.*/cloud-init.yml + exclude: .gitlab-ci.yml|infra/.*/cloud-init.yml|k8s-apps/hegerdes-kubernetes-service/hks/templates/extra-manifests.yaml|k8s-apps/hegerdes-kubernetes-service/hks/templates/pdb.yaml|k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/.*|k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/templates/extra-manifests.yaml|k8s-apps/hegerdes-kubernetes-service/hks/templates/eso.yaml|k8s-apps/hegerdes-kubernetes-service/hks/templates/tls-route.yaml - id: check-json - id: pretty-format-json args: [--autofix, --no-sort-keys, --no-ensure-ascii] diff --git a/k8s-apps/hegerdes-kubernetes-service/Kube-tasks.md b/k8s-apps/hegerdes-kubernetes-service/Kube-tasks.md new file mode 100644 index 0000000..08569c2 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/Kube-tasks.md @@ -0,0 +1,40 @@ +Hennes Kubernes Service + +Tasks: + * Create deploymets for: + * kube-apiserver ✅ + * kube-controller ✅ + * etcd ✅ + * Create certs - hacky ✅ + * Ensure communication ✅ + * Refine Deployments ✅ + * Create certs - prod ✅ + * GitOps: + * HKS ✅ + * Slave Cluster + * Generate join token + * POC ✅ + * Service-Controller + * Join Worker + * Ensure Connectivity + * Worker -> CP + * CP -> Worker + * Worker Apps + * CoreDNS + * Cilium + + +```bash +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.19.2/cert-manager.yaml +kubectl create namespace argocd +kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v3.2.3/manifests/install.yaml +# kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/standard-install.yaml +kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/experimental-install.yaml +kubectl kustomize "https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v2.3.0" | kubectl apply -f - --server-side +helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric --create-namespace -n nginx-gateway --set nginxGateway.gwAPIExperimentalFeatures.enable=true + +kaf argo-hks-shared.yaml +kaf ../../k8s-cluster-hcloud-critical/argo-external-secrets.yml +kaf ../argo-nginx-gateway-fabric.yml +kaf argo-appset-hks.yaml +``` diff --git a/k8s-apps/hegerdes-kubernetes-service/argo-appset-hks.yaml b/k8s-apps/hegerdes-kubernetes-service/argo-appset-hks.yaml new file mode 100644 index 0000000..f3aab28 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/argo-appset-hks.yaml @@ -0,0 +1,48 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: hks-appset + namespace: argocd +spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] + generators: + - git: + repoURL: https://github.com/hegerdes/GitOps.git + revision: feat/hks + directories: + - path: k8s-apps/hegerdes-kubernetes-service/clusters/* + template: + metadata: + name: "hks-{{.path.basename}}" + labels: + name: hks + finalizers: + - resources-finalizer.argocd.argoproj.io/background + spec: + project: default + source: + repoURL: https://github.com/hegerdes/GitOps.git + targetRevision: feat/hks + path: k8s-apps/hegerdes-kubernetes-service/hks + helm: + valuesObject: + extraObjects: [] + destination: + server: https://kubernetes.default.svc + namespace: "{{.path.basename}}" + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + ignoreDifferences: + - kind: StatefulSet + group: apps + jqPathExpressions: + - .spec.updateStrategy.rollingUpdate.maxUnavailable + - kind: ConfigMap + name: cluster-data + jqPathExpressions: + - .data.advertiseIP diff --git a/k8s-apps/hegerdes-kubernetes-service/argo-hks-manager.yaml b/k8s-apps/hegerdes-kubernetes-service/argo-hks-manager.yaml new file mode 100644 index 0000000..f02c566 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/argo-hks-manager.yaml @@ -0,0 +1,25 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: hks-manager + namespace: argocd + labels: + name: hks-manager +spec: + project: default + source: + repoURL: https://github.com/hegerdes/GitOps.git + targetRevision: feat/hks + path: k8s-apps/hegerdes-kubernetes-service/hks-manager + helm: + valuesObject: + extraObjects: [] + destination: + server: https://kubernetes.default.svc + namespace: hks-manager + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-apps/hegerdes-kubernetes-service/argo-hks-shared.yaml b/k8s-apps/hegerdes-kubernetes-service/argo-hks-shared.yaml new file mode 100644 index 0000000..a372667 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/argo-hks-shared.yaml @@ -0,0 +1,24 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: hks-shared + namespace: argocd + labels: + name: hks +spec: + project: default + source: + repoURL: https://github.com/hegerdes/GitOps.git + targetRevision: feat/hks + path: k8s-apps/hegerdes-kubernetes-service/shared + directory: + recurse: false + destination: + server: https://kubernetes.default.svc + namespace: argocd + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-apps/hegerdes-kubernetes-service/clusters/test1/values.yaml b/k8s-apps/hegerdes-kubernetes-service/clusters/test1/values.yaml new file mode 100644 index 0000000..e69de29 diff --git a/k8s-apps/hegerdes-kubernetes-service/clustes-shared/cm-kubelet-conf.yaml b/k8s-apps/hegerdes-kubernetes-service/clustes-shared/cm-kubelet-conf.yaml new file mode 100644 index 0000000..ca9b5fc --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/clustes-shared/cm-kubelet-conf.yaml @@ -0,0 +1,70 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: kubelet-config + namespace: kube-system +data: + kubelet: | + apiVersion: kubelet.config.k8s.io/v1beta1 + authentication: + anonymous: + enabled: false + webhook: + cacheTTL: 0s + enabled: true + x509: + clientCAFile: /etc/kubernetes/pki/ca.crt + authorization: + mode: Webhook + webhook: + cacheAuthorizedTTL: 0s + cacheUnauthorizedTTL: 0s + cgroupDriver: systemd + clusterDNS: + - 10.96.0.10 + clusterDomain: cluster.local + containerRuntimeEndpoint: unix:///run/containerd/containerd.sock + cpuManagerReconcilePeriod: 0s + crashLoopBackOff: {} + enableDebugFlagsHandler: false + enableProfilingHandler: false + evictionPressureTransitionPeriod: 0s + failCgroupV1: true + failSwapOn: true + featureGates: + ClusterTrustBundle: true + ClusterTrustBundleProjection: true + fileCheckFrequency: 0s + healthzBindAddress: 0.0.0.0 + healthzPort: 10248 + httpCheckFrequency: 0s + imageMaximumGCAge: 1h0m0s + imageMinimumGCAge: 5m0s + kind: KubeletConfiguration + logging: + flushFrequency: 0 + options: + json: + infoBufferSize: "0" + text: + infoBufferSize: "0" + verbosity: 0 + maxParallelImagePulls: 8 + maxPods: 220 + memorySwap: {} + nodeStatusMaxImages: -1 + nodeStatusReportFrequency: 0s + nodeStatusUpdateFrequency: 0s + protectKernelDefaults: true + resolvConf: /etc/resolv.conf + rotateCertificates: true + runtimeRequestTimeout: 0s + seccompDefault: true + serializeImagePulls: false + serverTLSBootstrap: true + shutdownGracePeriod: 0s + shutdownGracePeriodCriticalPods: 0s + staticPodPath: /etc/kubernetes/manifests + streamingConnectionIdleTimeout: 0s + syncFrequency: 0s + volumeStatsAggPeriod: 5m0s diff --git a/k8s-apps/hegerdes-kubernetes-service/clustes-shared/rbac-super-user.yaml b/k8s-apps/hegerdes-kubernetes-service/clustes-shared/rbac-super-user.yaml new file mode 100644 index 0000000..844488e --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/clustes-shared/rbac-super-user.yaml @@ -0,0 +1,31 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kube-apiserver-kubelet-client-extra +rules: + - apiGroups: [""] + resources: ["pods/log"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["nodes/proxy"] + verbs: ["get", "create"] + - apiGroups: [""] + resources: + - pods/exec + - pods/attach + - pods/portforward + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kube-apiserver-kubelet-client-extra-binding +subjects: + - kind: User + name: kube-apiserver-kubelet-client + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: kube-apiserver-kubelet-client-extra + apiGroup: rbac.authorization.k8s.io diff --git a/k8s-apps/hegerdes-kubernetes-service/clustes-shared/rbac.yaml b/k8s-apps/hegerdes-kubernetes-service/clustes-shared/rbac.yaml new file mode 100644 index 0000000..e81c785 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/clustes-shared/rbac.yaml @@ -0,0 +1,200 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kubeadm:get-nodes +rules: + - apiGroups: + - "" + resources: + - nodes + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kubeadm:node-autoapprove-bootstrap +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:certificates.k8s.io:certificatesigningrequests:nodeclient +subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:bootstrappers:kubeadm:default-node-token + - apiGroup: rbac.authorization.k8s.io + kind: User + name: system:bootstrap:60ae1c +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kubeadm:get-nodes +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: kubeadm:get-nodes +subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:bootstrappers:kubeadm:default-node-token + - apiGroup: rbac.authorization.k8s.io + kind: User + name: system:bootstrap:60ae1c +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kubeadm:kubelet-bootstrap +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:node-bootstrapper +subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:bootstrappers:kubeadm:default-node-token + - apiGroup: rbac.authorization.k8s.io + kind: User + name: system:bootstrap:60ae1c +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kubeadm:node-autoapprove-certificate-rotation +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient +subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:nodes + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: kubeadm:kubeadm-certs + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: kubeadm:kubeadm-certs +subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:bootstrappers:kubeadm:default-node-token + - apiGroup: rbac.authorization.k8s.io + kind: User + name: system:bootstrap:60ae1c +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: kubeadm:nodes-kubeadm-config + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: kubeadm:nodes-kubeadm-config +subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:bootstrappers:kubeadm:default-node-token + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:nodes + - apiGroup: rbac.authorization.k8s.io + kind: User + name: system:bootstrap:60ae1c +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: kubeadm:kubelet-config + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: kubeadm:kubelet-config +subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:nodes + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:bootstrappers:kubeadm:default-node-token + - apiGroup: rbac.authorization.k8s.io + kind: User + name: system:bootstrap:60ae1c +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: kubeadm:nodes-kubeadm-config + namespace: kube-system +rules: + - apiGroups: + - "" + resourceNames: + - kubeadm-config + resources: + - configmaps + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: kubeadm:kubelet-config + namespace: kube-system +rules: + - apiGroups: + - "" + resourceNames: + - kubelet-config + resources: + - configmaps + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: anonymous-read-cluster-info + namespace: kube-public +subjects: + - kind: User + name: system:anonymous + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: Role + name: read-cluster-info + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: read-cluster-info + namespace: kube-public +rules: + - apiGroups: [""] + resources: ["configmaps"] + resourceNames: ["cluster-info"] + verbs: ["get", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: kubeadm:kubeadm-certs + namespace: kube-system +rules: + - apiGroups: + - "" + resourceNames: + - kubeadm-certs + resources: + - secrets + verbs: + - get diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/Chart.yaml b/k8s-apps/hegerdes-kubernetes-service/hks-manager/Chart.yaml new file mode 100644 index 0000000..f893482 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +appVersion: 0.1.0 +description: A Helm chart for Kubernetes +name: hks-manager +type: application +version: 0.1.0 diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/chart_schema.yaml b/k8s-apps/hegerdes-kubernetes-service/hks-manager/chart_schema.yaml new file mode 100644 index 0000000..2a26d9b --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/chart_schema.yaml @@ -0,0 +1,37 @@ +name: str() +home: str(required=False) +version: str() +apiVersion: str() +appVersion: any(str(), num(), required=False) +description: str(required=False) +keywords: list(str(), required=False) +sources: list(str(), required=False) +maintainers: list(include('maintainer'), required=False) +dependencies: list(include('dependency'), required=False) +icon: str(required=False) +engine: str(required=False) +condition: str(required=False) +tags: str(required=False) +deprecated: bool(required=False) +kubeVersion: str(required=False) +annotations: map(str(), str(), required=False) +type: str(required=False) +--- +maintainer: + name: str() + email: str(required=False) + url: str(required=False) +--- +dependency: + name: str() + version: str() + repository: str(required=False) + condition: str(required=False) + tags: list(str(), required=False) + enabled: bool(required=False) + import-values: any(list(str()), list(include('import-value')), required=False) + alias: str(required=False) +--- +import-value: + child: str() + parent: str() diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/lintconf.yaml b/k8s-apps/hegerdes-kubernetes-service/hks-manager/lintconf.yaml new file mode 100644 index 0000000..90f48c8 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/lintconf.yaml @@ -0,0 +1,42 @@ +--- +rules: + braces: + min-spaces-inside: 0 + max-spaces-inside: 0 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 + brackets: + min-spaces-inside: 0 + max-spaces-inside: 0 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 + colons: + max-spaces-before: 0 + max-spaces-after: 1 + commas: + max-spaces-before: 0 + min-spaces-after: 1 + max-spaces-after: 1 + comments: + require-starting-space: true + min-spaces-from-content: 2 + document-end: disable + document-start: disable # No --- to start a file + empty-lines: + max: 2 + max-start: 0 + max-end: 0 + hyphens: + max-spaces-after: 1 + indentation: + spaces: consistent + indent-sequences: whatever # - list indentation will handle both indentation and without + check-multi-line-strings: false + key-duplicates: enable + line-length: disable # Lines can be any length + new-line-at-end-of-file: enable + new-lines: + type: unix + trailing-spaces: enable + truthy: + level: warning diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/NOTES.txt b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/NOTES.txt new file mode 100644 index 0000000..a1f26f6 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/NOTES.txt @@ -0,0 +1,23 @@ +# Template by https://dev.to/harisharavindan/helm-starter-chart-m1j +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "hks-manager.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "hks-manager.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "hks-manager.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "hks-manager.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/_helpers.tpl b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/_helpers.tpl new file mode 100644 index 0000000..fd34dcc --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/_helpers.tpl @@ -0,0 +1,85 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "hks-manager.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "hks-manager.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "hks-manager.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "hks-manager.labels" -}} +helm.sh/chart: {{ include "hks-manager.chart" . }} +{{ include "hks-manager.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "hks-manager.selectorLabels" -}} +app.kubernetes.io/name: {{ include "hks-manager.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Pod annotations +*/}} +{{- define "hks-manager.pod.annotations" -}} +{{- range $k, $v := .Values.podAnnotations }} +{{- $k }}: {{ $v }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "hks-manager.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "hks-manager.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Renders a value that contains template. +Usage: +{{ include "hks-manager.render" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define "hks-manager.render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/deployment.yaml b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/deployment.yaml new file mode 100644 index 0000000..587b50e --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/deployment.yaml @@ -0,0 +1,91 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "hks-manager.fullname" . }} + labels: + {{- include "hks-manager.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "hks-manager.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "hks-manager.pod.annotations" . | nindent 8 }} + labels: + {{- include "hks-manager.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "hks-manager.serviceAccountName" . }} + {{- if .Values.useUserNamespaces }} + hostUsers: true + {{- end }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + {{- with (concat .Values.podEnvs .Values.defaultEnvs) | uniq }} + {{- toYaml . | nindent 12}} + {{- end }} + - name: HKS_CLUSTER_ZONE + value: {{ .Values.clusterZone | quote }} + - name: PORT + value: {{ .Values.podContainerPort | quote }} + ports: + - name: http + containerPort: {{ .Values.podContainerPort }} + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: http + readinessProbe: + httpGet: + path: /healthz + port: http + {{- with .Values.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.extraContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.volumes }} + volumes: + {{- toYaml . | nindent 10 }} + {{- end }} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/extra-manifests.yaml b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/extra-manifests.yaml new file mode 100644 index 0000000..4501047 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{- range .Values.extraDeploy }} +--- +{{ include "hks-manager.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/hpa.yaml b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/hpa.yaml new file mode 100644 index 0000000..8eef778 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "hks-manager.fullname" . }} + labels: + {{- include "hks-manager.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "hks-manager.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/httproute.yaml b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/httproute.yaml new file mode 100644 index 0000000..8f2e8de --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/httproute.yaml @@ -0,0 +1,38 @@ +{{- if .Values.httpRoute.enabled -}} +{{- $fullName := include "hks-manager.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ $fullName }} + labels: + {{- include "hks-manager.labels" . | nindent 4 }} + {{- with .Values.httpRoute.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + parentRefs: + {{- with .Values.httpRoute.parentRefs }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.httpRoute.hostnames }} + hostnames: + {{- toYaml . | nindent 4 }} + {{- end }} + rules: + {{- range .Values.httpRoute.rules }} + {{- with .matches }} + - matches: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .filters }} + filters: + {{- toYaml . | nindent 8 }} + {{- end }} + backendRefs: + - name: {{ $fullName }} + port: {{ $svcPort }} + weight: 1 + {{- end }} +{{- end }} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/ingress.yaml b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/ingress.yaml new file mode 100644 index 0000000..3c00e63 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/ingress.yaml @@ -0,0 +1,45 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "hks-manager.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "hks-manager.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: {{ .pathType }} + {{- end }} + backend: + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- end }} + {{- end }} +{{- end }} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/rbac.yaml b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/rbac.yaml new file mode 100644 index 0000000..59e46d3 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/rbac.yaml @@ -0,0 +1,30 @@ +{{- if .Values.rbac.enabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "hks-manager.labels" . | nindent 4 }} + name: {{ include "hks-manager.fullname" . }} +rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - "*" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "hks-manager.fullname" . }} + labels: + {{- include "hks-manager.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ include "hks-manager.serviceAccountName" . }} + namespace: {{ .Release.Namespace}} +roleRef: + kind: ClusterRole + name: {{ include "hks-manager.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/service.yaml b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/service.yaml new file mode 100644 index 0000000..d485cea --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/service.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "hks-manager.fullname" . }} + labels: + {{- include "hks-manager.labels" . | nindent 4 }} + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + internalTrafficPolicy: {{ .Values.service.internalTrafficPolicy }} + ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "hks-manager.selectorLabels" . | nindent 4 }} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/serviceaccount.yaml b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/serviceaccount.yaml new file mode 100644 index 0000000..d1f9532 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "hks-manager.serviceAccountName" . }} + labels: + {{- include "hks-manager.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/servicemonitor.yaml b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/servicemonitor.yaml new file mode 100644 index 0000000..8651c4b --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/templates/servicemonitor.yaml @@ -0,0 +1,83 @@ +{{- if and (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "hks-manager.fullname" . }} + labels: + {{- include "hks-manager.labels" . | nindent 4 }} + {{- with .Values.metrics.serviceMonitor.selector }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.metrics.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.metrics.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.metrics.service.portName }} + {{- with .Values.metrics.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + path: /metrics + {{- with .Values.metrics.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + honorLabels: {{ .Values.metrics.serviceMonitor.honorLabels }} + {{- with .Values.metrics.serviceMonitor.scheme }} + scheme: {{ . }} + {{- end }} + {{- with .Values.metrics.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ include "hks-manager.namespace" . }} + selector: + matchLabels: + {{- include "hks-manager.selectorLabels" (dict "context" . "component" .Values.name "name" (printf "%s-metrics" .Values.name)) | nindent 6 }} +{{- end }} +--- +{{- if .Values.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "hks-manager.fullname" . }}-metrics + namespace: {{ include "hks-manager.namespace" . }} + labels: + {{- include "hks-manager.labels" (dict "context" . "component" .Values.name "name" (printf "%s-metrics" .Values.name)) | nindent 4 }} + {{- with .Values.metrics.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.metrics.prometheusAnnotations.enabled }} + prometheus.io/port: {{ .Values.metrics.prometheusAnnotations.port | quote }} + prometheus.io/scheme: {{ .Values.metrics.prometheusAnnotations.scheme | quote}} + prometheus.io/path: {{ .Values.metrics.prometheusAnnotations.path | quote}} + prometheus.io/scrape: "true" + {{- end }} + {{- range $key, $value := .Values.metrics.service.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + type: {{ .Values.metrics.service.type }} + ipFamilyPolicy: {{ .Values.metrics.service.ipFamilyPolicy }} + ports: + - name: metrics + protocol: TCP + port: {{ .Values.metrics.service.servicePort }} + targetPort: metrics + selector: + {{- include "hks-manager.selectorLabels" (dict "context" . "name" .Values.name) | nindent 4 }} +{{- end }} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/values.schema.json b/k8s-apps/hegerdes-kubernetes-service/hks-manager/values.schema.json new file mode 100644 index 0000000..315d766 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/values.schema.json @@ -0,0 +1,264 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "properties": { + "affinity": { + "properties": {}, + "type": "object" + }, + "autoscaling": { + "properties": { + "enabled": { + "type": "boolean" + }, + "maxReplicas": { + "type": "integer" + }, + "minReplicas": { + "type": "integer" + }, + "targetCPUUtilizationPercentage": { + "type": "integer" + } + }, + "type": "object" + }, + "commonLabels": { + "properties": {}, + "type": "object" + }, + "defaultEnvs": { + "type": "array" + }, + "extraContainers": { + "type": "array" + }, + "extraDeploy": { + "type": "array" + }, + "fullnameOverride": { + "type": "string" + }, + "httpRoute": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "hostnames": { + "items": { + "type": "string" + }, + "type": "array" + }, + "parentRefs": { + "items": { + "properties": { + "name": { + "type": "string" + }, + "sectionName": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "rules": { + "items": { + "properties": { + "matches": { + "items": { + "properties": { + "path": { + "properties": { + "type": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "image": { + "properties": { + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "imagePullSecrets": { + "type": "array" + }, + "ingress": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "className": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "hosts": { + "items": { + "properties": { + "host": { + "type": "string" + }, + "paths": { + "items": { + "properties": { + "path": { + "type": "string" + }, + "pathType": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "tls": { + "type": "array" + } + }, + "type": "object" + }, + "initContainers": { + "type": "array" + }, + "nameOverride": { + "type": "string" + }, + "nodeSelector": { + "properties": {}, + "type": "object" + }, + "podAnnotations": { + "properties": {}, + "type": "object" + }, + "podContainerPort": { + "type": "integer" + }, + "podEnvs": { + "items": { + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "podSecurityContext": { + "properties": {}, + "type": "object" + }, + "replicaCount": { + "type": "integer" + }, + "resources": { + "properties": {}, + "type": "object" + }, + "securityContext": { + "properties": {}, + "type": "object" + }, + "service": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "port": { + "type": "integer" + }, + "prometheus": { + "properties": { + "enabled": { + "type": "boolean" + }, + "path": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "scheme": { + "type": "string" + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "serviceAccount": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "create": { + "type": "boolean" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "tolerations": { + "type": "array" + }, + "volumeMounts": { + "type": "array" + }, + "volumes": { + "type": "array" + } + }, + "type": "object" +} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks-manager/values.yaml b/k8s-apps/hegerdes-kubernetes-service/hks-manager/values.yaml new file mode 100644 index 0000000..ed9acc0 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks-manager/values.yaml @@ -0,0 +1,231 @@ +# Default values for hks-manager. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# -- Number of replicas for that pod +replicaCount: 1 +clusterZone: hks.eu-central.hegerdes.com + +image: + # -- The container registry and image to use. + repository: hegerdes/hks + # -- Pull policy of that image. + pullPolicy: Always + # -- The image tag and/or sha. + tag: latest + +# -- Any repository secrets needed to pull the image. +imagePullSecrets: [] +# -- Override the application name. +nameOverride: "" +# -- Override full release name. +fullnameOverride: "" + +# -- Labels applied to all manifests. +commonLabels: {} +# -- Any additional init containers. +initContainers: [] +# -- Any additional containers. +extraContainers: [] + +serviceAccount: + # -- Specifies whether a service account should be created. + create: false + # -- Annotations to add to the service account. + annotations: {} + # -- The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template. + name: "" + +rbac: + # -- En able (Cluster)Role and (Cluster)RoleBinding creation. + enabled: true + +# -- Extra annotations for the pod. +podAnnotations: {} + +# -- App and Container note. Change also in ENVs. +podContainerPort: 8080 + +# -- List of ENVs to configure the app. +podEnvs: [] + # - name: MY_ENV + # value: "MY_VAL" + # - name: ACCESS_TOKEN + # valueFrom: + # secretKeyRef: + # key: token + # name: sec_name + +# -- List of default ENVs. No need to change +defaultEnvs: [] + +# -- If pod should use user namespaces. Must be supported by CRI. See https://kubernetes.io/docs/tasks/configure-pod-container/user-namespaces/ +useUserNamespaces: false + +# -- PodSecurity settings that will be applied to all containers. +podSecurityContext: {} + # fsGroup: 2000 + +# -- Security settings for the container. +securityContext: {} + # runAsNonRoot: true + # runAsUser: 1000 + # runAsGroup: 1000 + # allowPrivilegeEscalation: false + # capabilities: + # drop: [ALL] + # privileged: false + # readOnlyRootFilesystem: true + +# -- Resources for the container. +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +# -- Volume mount's for container. +volumeMounts: [] + +# -- Volumes where data should be persisted. +volumes: [] + # - name: config-vol + # configMap: + # name: log-config + # items: + # - key: log_level + # path: log_level + +# -- Node selector for pod. +# nodeSelector: {} +nodeSelector: + kubernetes.io/arch: arm64 + +# -- Tolerations for pod. +tolerations: [] + +# -- Affinity for pod. +affinity: {} + +# -- How the service is exposed. +service: + # -- Service type. + type: ClusterIP + # -- Service and container port. + port: 8080 + # -- Annotations for the service. + annotations: {} + # -- Service traffic policy. + internalTrafficPolicy: Cluster + # -- Service IP family. + ipFamilyPolicy: SingleStack + +# -- Metrics configuration. +metrics: + # -- If metrics endpoint should be enabled. + enabled: false + service: + # -- Service type. + type: ClusterIP + # -- Service and container port. + port: 8080 + # -- Annotations for the service. + annotations: {} + # -- Service IP family + ipFamilyPolicy: SingleStack + # -- Prometheus service annotations. + prometheusAnnotations: + enabled: false + scheme: http + path: /metrics + port: 80 + + # -- ServiceMonitor configuration. + serviceMonitor: + enabled: false + interval: 30s + scrapeTimeout: 30s + honorLabels: false + scheme: http + tlsConfig: {} + selector: {} + additionalLabels: {} + annotations: {} + relabelings: [] + metricRelabelings: [] + +# -- How the service is exposed via ingress. +ingress: + # -- Ingress enabled. + enabled: false + # -- Ingress class. + className: nginx + # -- Ingress annotations. + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + # -- Hostname and path config. + - host: ingress.k8s.internal + paths: + - path: / + pathType: Prefix + # -- TLS config. + tls: [] + # - secretName: ingress.k8s.internal + # hosts: + # - ingress.k8s.internal + +# -- How the service is exposed via gateway-apis HTTPRoute. +httpRoute: + # -- HTTPRoute enabled. + enabled: false + # -- HTTPRoute annotations. + annotations: {} + # -- Which Gateways this Route is attached to + parentRefs: + - name: cilium-gateway + namespace: cilium-gateway + sectionName: http + # -- Hostnames matching HTTP header. + hostnames: + - "manager.hks.eu-central" + # -- List of rules and filters applied. + rules: + - matches: + - path: + type: PathPrefix + value: / + # filters: + # - type: RequestHeaderModifier + # requestHeaderModifier: + # set: + # - name: My-Overwrite-Header + # value: this-is-the-only-value + # remove: + # - User-Agent + # - matches: + # - path: + # type: PathPrefix + # value: /echo + # headers: + # - name: version + # value: v2 + + # -- Autoscaling +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +# -- Extra manifests +extraDeploy: [] diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/.helmignore b/k8s-apps/hegerdes-kubernetes-service/hks/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/Chart.yaml b/k8s-apps/hegerdes-kubernetes-service/hks/Chart.yaml new file mode 100644 index 0000000..2e01207 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: hks +description: A Helm chart for deploying managed Kubernetes-Clusters + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/templates/_helpers.tpl b/k8s-apps/hegerdes-kubernetes-service/hks/templates/_helpers.tpl new file mode 100644 index 0000000..4839a9e --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/templates/_helpers.tpl @@ -0,0 +1,65 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "hks.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "hks.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "hks.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "hks.labels" -}} +helm.sh/chart: {{ include "hks.chart" . }} +{{ include "hks.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "hks.selectorLabels" -}} +app.kubernetes.io/name: {{ include "hks.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + + +{{/* +Renders a value that contains template. +Usage: +{{ include ".render" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define ".render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/templates/eso.yaml b/k8s-apps/hegerdes-kubernetes-service/hks/templates/eso.yaml new file mode 100644 index 0000000..b5809e8 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/templates/eso.yaml @@ -0,0 +1,75 @@ +--- +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: kubeconfig-credentials-{{ .Release.Namespace }} + namespace: argocd +spec: + refreshInterval: 1h0m0s + secretStoreRef: + kind: SecretStore + name: secret-sync-{{ .Release.Namespace }} + target: + name: kubeconfig-credentials-{{ .Release.Namespace }} + template: + metadata: + annotations: + hks.hegerdes.com/public-ipv4: "unknown" + hks.hegerdes.com/public-host: "{{ .Release.Namespace }}.{{ .Values.controlplane.domainSuffix }}" + hks.hegerdes.com/private-host: "kube-apiserver.{{ .Release.Namespace }}" + hks.hegerdes.com/private-port: "6443" + hks.hegerdes.com/public-port: "6443" + labels: + argocd.argoproj.io/secret-type: cluster + hks.hegerdes.com/managed-cluster: "true" + hks.hegerdes.com/cluster-type: "downstream" + argocd.argoproj.io/auto-label-cluster-info: "true" + type: Opaque + data: + server: https://kube-apiserver.{{ .Release.Namespace }}:6443 + name: "{{ .Release.Namespace }}" + namespaces: kube-system,kube-public,default,cilium,cilium-secrets,kubelet-serving-cert-approver + clusterResources: "true" + config: | + { + "tlsClientConfig": { + "caData": "{{ "{{ .ca | b64enc }}" }}", + "certData": "{{ "{{ .clientCert | b64enc }}" }}", + "keyData": "{{ "{{ .clientKey | b64enc }}" }}" + } + } + data: + - secretKey: ca + remoteRef: + # key: argocd-client-tls + key: kube-super-admin-client-tls + property: ca.crt + - secretKey: clientCert + remoteRef: + # key: argocd-client-tls + key: kube-super-admin-client-tls + property: tls.crt + - secretKey: clientKey + remoteRef: + # key: argocd-client-tls + key: kube-super-admin-client-tls + property: tls.key +--- +apiVersion: external-secrets.io/v1 +kind: SecretStore +metadata: + name: secret-sync-{{ .Release.Namespace }} + namespace: argocd +spec: + provider: + kubernetes: + auth: + serviceAccount: + name: external-secrets + remoteNamespace: "{{ .Release.Namespace }}" + server: + url: "https://kubernetes.default.svc.cluster.local" + caProvider: + type: ConfigMap + name: kube-root-ca.crt + key: ca.crt diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/templates/extra-manifests.yaml b/k8s-apps/hegerdes-kubernetes-service/hks/templates/extra-manifests.yaml new file mode 100644 index 0000000..0f48fe1 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{- range .Values.extraObjects }} +--- +{{ include ".render" (dict "value" . "context" $) }} +{{- end }} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-apiserver.yaml b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-apiserver.yaml new file mode 100644 index 0000000..6de5dc5 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-apiserver.yaml @@ -0,0 +1,298 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kube-apiserver + labels: + app: kube-apiserver + component: kube-apiserver + tier: control-plane + annotations: + reloader.stakater.com/auto: "true" +spec: + replicas: 1 + selector: + matchLabels: + app: kube-apiserver + component: kube-apiserver + tier: control-plane + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + maxSurge: 1 + minReadySeconds: 10 + template: + metadata: + labels: + app: kube-apiserver + component: kube-apiserver + tier: control-plane + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + seccompProfile: + type: RuntimeDefault + automountServiceAccountToken: false + enableServiceLinks: false + initContainers: + - name: etcd-check + image: curlimages/curl + command: + - sh + - -c + - | + set -eu + ETCD_ENDPOINT="https://etcd:2379/health" + CA_CERT="/etc/kubernetes/etcd/pki/ca.crt" + CLIENT_CERT="/etc/kubernetes/etcd/pki/apiserver-etcd-client.crt" + CLIENT_KEY="/etc/kubernetes/etcd/pki/apiserver-etcd-client.key" + while true; do + if curl --silent --show-error --fail --cacert "$CA_CERT" \ + --cert "$CLIENT_CERT" --key "$CLIENT_KEY" \ + "$ETCD_ENDPOINT" | grep -q '"health":.*"true"'; then + echo "etcd is ready!" + break + fi + echo "waiting for etcd..." + sleep 2 + done + volumeMounts: + - mountPath: /etc/kubernetes/etcd/pki/ + name: tls-etcd + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: [ALL] + containers: + - name: kube-apiserver + image: registry.k8s.io/kube-apiserver:v1.35.0 + imagePullPolicy: IfNotPresent + env: + - name: ADVERTISE_IP + valueFrom: + configMapKeyRef: + key: advertiseIP + name: cluster-data + # Docs: https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/ + command: + - kube-apiserver + - --secure-port=6443 + - --profiling=false + - --external-hostname={{ .Release.Namespace }}.{{ .Values.controlplane.domainSuffix }} + - --advertise-address=$(ADVERTISE_IP) + - --enable-admission-plugins=NodeRestriction + - --enable-bootstrap-token-auth=true + - --allow-privileged=true + - --audit-log-maxage=30 + - --audit-log-maxbackup=10 + - --audit-log-maxsize=100 + - --audit-log-path=/var/log/kube-apiserver/audit.log + - --client-ca-file=/etc/kubernetes/pki/ca.crt + - --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt + - --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key + - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname + - --audit-policy-file=/etc/kubernetes/extras/audit-policy.yaml + - --authentication-config=/etc/kubernetes/extras/authentication-conf.yaml + - --authorization-config=/etc/kubernetes/extras/authorization-conf.yaml + - --admission-control-config-file=/etc/kubernetes/extras/admission-control-config.yaml + - --encryption-provider-config=/etc/kubernetes/extras/encryption-config.yaml + - --encryption-provider-config-automatic-reload=true + - --etcd-servers=https://etcd:2379 + - --etcd-cafile=/etc/kubernetes/etcd/pki/ca.crt + - --etcd-certfile=/etc/kubernetes/etcd/pki/apiserver-etcd-client.crt + - --etcd-keyfile=/etc/kubernetes/etcd/pki/apiserver-etcd-client.key + - --service-account-issuer=https://kubernetes.default.svc.cluster.local + - --service-cluster-ip-range=10.96.0.0/16 + - --service-account-key-file=/etc/kubernetes/pki/sa.pub + - --service-account-signing-key-file=/etc/kubernetes/pki/sa.key + - --tls-min-version=VersionTLS13 + - --tls-cert-file=/etc/kubernetes/pki/apiserver.crt + - --tls-private-key-file=/etc/kubernetes/pki/apiserver.key + - --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt + - --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key + - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt + - --requestheader-allowed-names=front-proxy-client + - --requestheader-extra-headers-prefix=X-Remote-Extra- + - --requestheader-group-headers=X-Remote-Group + - --requestheader-username-headers=X-Remote-User + resources: + requests: + cpu: 200m + memory: 200Mi + limits: + cpu: 2 + memory: 4Gi + ports: + - containerPort: 6443 + name: kube-api + protocol: TCP + securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: [all] + add: ["NET_BIND_SERVICE"] + livenessProbe: + failureThreshold: 8 + httpGet: + path: /livez + port: kube-api + scheme: HTTPS + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 15 + readinessProbe: + failureThreshold: 3 + httpGet: + path: /readyz + port: kube-api + scheme: HTTPS + periodSeconds: 1 + timeoutSeconds: 15 + startupProbe: + failureThreshold: 24 + httpGet: + path: /livez + port: kube-api + scheme: HTTPS + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 15 + volumeMounts: + - mountPath: /var/log/kube-apiserver/ + name: audit-log + - mountPath: /etc/kubernetes/pki/ + name: tls-kube + - mountPath: /etc/kubernetes/etcd/pki/ + name: tls-etcd + - mountPath: /etc/kubernetes/extras/ + name: kube-extra-conf + # - mountPath: /etc/ssl/certs + # name: ca-certs + # readOnly: true + # - mountPath: /etc/ca-certificates + # name: etc-ca-certificates + # readOnly: true + # - mountPath: /usr/local/share/ca-certificates + # name: usr-local-share-ca-certificates + # readOnly: true + # - mountPath: /usr/share/ca-certificates + # name: usr-share-ca-certificates + # readOnly: true + # priority: 2000001000 + # priorityClassName: system-node-critical + volumes: + - name: audit-log + emptyDir: + sizeLimit: 265Mi + # persistentVolumeClaim: + # claimName: kube-adit-log + - name: kube-extra-conf + projected: + sources: + - configMap: + name: kube-api-configs + items: + - key: admission-control-config.yaml + path: admission-control-config.yaml + - key: authorization-conf.yaml + path: authorization-conf.yaml + - key: authentication-conf.yaml + path: authentication-conf.yaml + - key: audit-policy.yaml + path: audit-policy.yaml + - secret: + name: kube-encryption + items: + - key: encryption-config.yaml + path: encryption-config.yaml + - name: tls-etcd + projected: + sources: + - secret: + name: kube-apiserver-etcd-client-tls + items: + - key: tls.key + path: apiserver-etcd-client.key + - key: tls.crt + path: apiserver-etcd-client.crt + - key: ca.crt + path: ca.crt + - name: tls-kube + projected: + sources: + # Serving cert for server + - secret: + name: kube-apiserver-tls + items: + - key: ca.crt + path: ca.crt + - key: tls.crt + path: apiserver.crt + - key: tls.key + path: apiserver.key + # Client cert for kubelet auth + - secret: + name: kube-apiserver-kubelet-client-tls + items: + - key: tls.crt + path: apiserver-kubelet-client.crt + - key: tls.key + path: apiserver-kubelet-client.key + # Client cert for front-proxy auth + - secret: + name: kube-front-proxy-client-tls + items: + - key: tls.crt + path: front-proxy-client.crt + - key: tls.key + path: front-proxy-client.key + - key: ca.crt + path: front-proxy-ca.crt + # Sign and validate JWTs + - secret: + name: kube-sa-tls + items: + - key: tls.key + path: sa.key + - key: sa.pub + path: sa.pub +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: kube-apiserver + component: kube-apiserver + tier: control-plane + name: kube-apiserver +spec: + ports: + - port: 6443 + protocol: TCP + targetPort: kube-api + name: kube-api + selector: + app: kube-apiserver + component: kube-apiserver + tier: control-plane +--- +# persistent volume claim +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: kube-adit-log + labels: + app: kube-apiserver + component: kube-apiserver + tier: control-plane +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-certs-core.yaml b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-certs-core.yaml new file mode 100644 index 0000000..558252f --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-certs-core.yaml @@ -0,0 +1,279 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: kube-apiserver +spec: + secretName: kube-apiserver-tls + commonName: kube-apiserver + duration: 2160h # 90d + renewBefore: 360h # 15d + isCA: false + usages: + - digital signature + - key encipherment + - server auth + + privateKey: + algorithm: RSA + size: 2048 + + subject: + organizationalUnits: + - controlplane-serving + organizations: + - kubernetes + + dnsNames: + - "{{ .Release.Namespace }}.{{ .Values.controlplane.domainSuffix }}" + - "kube-apiserver" + - "kube-apiserver.{{ .Release.Namespace }}" + - "kube-apiserver.{{ .Release.Namespace }}.svc" + - "kube-apiserver.{{ .Release.Namespace }}.svc.cluster.local" + - "kubernetes" + - "kubernetes.default" + - "kubernetes.default.svc" + - "kubernetes.default.svc.cluster.local" + emailAddresses: + - kubernetes-pki@hegerdes.com + + issuerRef: + name: ca-kube-controlplane + kind: Issuer +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: kube-scheduler-serving +spec: + secretName: kube-scheduler-serving-tls + commonName: kube-scheduler + duration: 2160h # 90d + renewBefore: 360h # 15d + isCA: false + usages: + - digital signature + - key encipherment + - server auth + + privateKey: + algorithm: RSA + size: 2048 + + subject: + organizationalUnits: + - scheduler-serving + organizations: + - kubernetes + + dnsNames: + - localhost + - "kube-scheduler" + - "kube-scheduler.{{ .Release.Namespace }}" + - "kube-scheduler.{{ .Release.Namespace }}.svc" + - "kube-scheduler.{{ .Release.Namespace }}.svc.cluster.local" + emailAddresses: + - kubernetes-pki@hegerdes.com + + issuerRef: + name: ca-kube-controlplane + kind: Issuer +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: kube-controller-manager-serving +spec: + secretName: kube-controller-manager-serving-tls + commonName: kube-controller-manager + duration: 2160h # 90d + renewBefore: 360h # 15d + isCA: false + usages: + - digital signature + - key encipherment + - server auth + + privateKey: + algorithm: RSA + size: 2048 + + subject: + organizationalUnits: + - kube-controller-manager-serving + organizations: + - kubernetes + + dnsNames: + - localhost + - "kube-controller-manager" + - "kube-controller-manager.{{ .Release.Namespace }}" + - "kube-controller-manager.{{ .Release.Namespace }}.svc" + - "kube-controller-manager.{{ .Release.Namespace }}.svc.cluster.local" + emailAddresses: + - kubernetes-pki@hegerdes.com + + issuerRef: + name: ca-kube-controlplane + kind: Issuer +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: kube-apiserver-kubelet-client +spec: + secretName: kube-apiserver-kubelet-client-tls + commonName: kube-apiserver-kubelet-client + duration: 2160h # 90d + renewBefore: 360h # 15d + isCA: false + usages: + - digital signature + - key encipherment + - client auth + + privateKey: + algorithm: RSA + size: 2048 + + subject: + organizationalUnits: + - controlplane-kubelet-auth + organizations: + - kubernetes + + dnsNames: [] + emailAddresses: + - kubernetes-pki@hegerdes.com + + issuerRef: + name: ca-kube-controlplane + kind: Issuer +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: kube-front-proxy-client-kube +spec: + secretName: kube-front-proxy-client-tls + commonName: front-proxy-client + duration: 2160h # 90d + renewBefore: 360h # 15d + isCA: false + usages: + - digital signature + - key encipherment + - client auth + privateKey: + algorithm: RSA + size: 2048 + + subject: + organizationalUnits: + - front-proxy-client + organizations: + - kubernetes + + dnsNames: [] + emailAddresses: + - kubernetes-pki@hegerdes.com + + issuerRef: + name: ca-kube-front-proxy + kind: Issuer +--- +############################ KUBECONF CERTS ############################ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: kube-scheduler-client +spec: + secretName: kube-scheduler-client-tls + commonName: system:kube-scheduler + duration: 2160h # 90d + renewBefore: 360h # 15d + isCA: false + usages: + - digital signature + - key encipherment + - client auth + privateKey: + algorithm: RSA + size: 2048 + + subject: + organizationalUnits: + - scheduler-client + organizations: + - kubernetes + + dnsNames: [] + emailAddresses: + - kubernetes-pki@hegerdes.com + + issuerRef: + name: ca-kube-controlplane + kind: Issuer +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: kube-controller-manager-client +spec: + secretName: kube-controller-manager-client-tls + commonName: system:kube-controller-manager + duration: 2160h # 90d + renewBefore: 360h # 15d + isCA: false + usages: + - digital signature + - key encipherment + - client auth + privateKey: + algorithm: RSA + size: 2048 + + subject: + organizationalUnits: + - controller-manager-client + organizations: + - kubernetes + + dnsNames: [] + emailAddresses: + - kubernetes-pki@hegerdes.com + + issuerRef: + name: ca-kube-controlplane + kind: Issuer +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: kube-super-admin-client +spec: + secretName: kube-super-admin-client-tls + commonName: kubernetes-super-admin + duration: 2160h # 90d + renewBefore: 360h # 15d + isCA: false + usages: + - digital signature + - key encipherment + - client auth + privateKey: + algorithm: RSA + size: 2048 + + subject: + organizationalUnits: + - super-admin-client + organizations: + - system:masters + + dnsNames: [] + emailAddresses: + - kubernetes-pki@hegerdes.com + + issuerRef: + name: ca-kube-controlplane + kind: Issuer diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-certs-etcd.yaml b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-certs-etcd.yaml new file mode 100644 index 0000000..9987501 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-certs-etcd.yaml @@ -0,0 +1,121 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: kube-apiserver-etcd-client +spec: + secretName: kube-apiserver-etcd-client-tls + commonName: kube-apiserver-etcd-client + duration: 2160h # 90d + renewBefore: 360h # 15d + isCA: false + usages: + - digital signature + - key encipherment + - client auth + + privateKey: + algorithm: RSA + size: 2048 + + subject: + organizationalUnits: + - controlplane-etcd-auth + organizations: + - kubernetes + + dnsNames: [] + emailAddresses: + - kubernetes-pki@hegerdes.com + + issuerRef: + name: ca-etcd + kind: Issuer +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: kube-etcd-peer +spec: + secretName: etcd-peer-tls + commonName: etcd + duration: 2160h # 90d + renewBefore: 360h # 15d + isCA: false + usages: + - digital signature + - key encipherment + - server auth + - client auth + + privateKey: + algorithm: RSA + size: 2048 + + subject: + organizationalUnits: + - etcd-peer + organizations: + - kubernetes + + dnsNames: + - "etcd" + - "etcd.{{ .Release.Namespace }}" + - "etcd.{{ .Release.Namespace }}.svc" + - "etcd.{{ .Release.Namespace }}.svc.cluster.local" + - "etcd-0.etcd" + - "etcd-1.etcd" + - "etcd-2.etcd" + - "etcd-0.etcd.{{ .Release.Namespace }}" + - "etcd-1.etcd.{{ .Release.Namespace }}" + - "etcd-2.etcd.{{ .Release.Namespace }}" + emailAddresses: + - kubernetes-pki@hegerdes.com + + issuerRef: + name: ca-etcd + kind: Issuer +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: kube-etcd-server +spec: + secretName: etcd-server-tls + commonName: etcd + duration: 2160h # 90d + renewBefore: 360h # 15d + isCA: false + usages: + - digital signature + - key encipherment + - server auth + - client auth + + privateKey: + algorithm: RSA + size: 2048 + + subject: + organizationalUnits: + - etcd-server + organizations: + - kubernetes + + dnsNames: + - etcd + - etcd-0 + - etcd-1 + - etcd-2 + - localhost + - etcd.default + - etcd.default.svc + - etcd.default.svc.cluster.local + - "etcd.{{ .Release.Namespace }}" + - "etcd.{{ .Release.Namespace }}.svc" + - "etcd.{{ .Release.Namespace }}.svc.cluster.local" + emailAddresses: + - kubernetes-pki@hegerdes.com + + issuerRef: + name: ca-etcd + kind: Issuer diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-certs-util.yaml b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-certs-util.yaml new file mode 100644 index 0000000..bb271f6 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-certs-util.yaml @@ -0,0 +1,28 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: argocd-client +spec: + secretName: argocd-client-tls + commonName: argocd-client + duration: 2160h # 90d + renewBefore: 360h # 15d + isCA: false + usages: + - digital signature + - key encipherment + - client auth + privateKey: + algorithm: RSA + size: 2048 + subject: + organizationalUnits: + - argocd-auth + organizations: + - kubernetes + dnsNames: [] + emailAddresses: + - kubernetes-pki@hegerdes.com + issuerRef: + name: ca-kube-controlplane + kind: Issuer diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-confs.yaml b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-confs.yaml new file mode 100644 index 0000000..d2ba429 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-confs.yaml @@ -0,0 +1,297 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + tier: control-plane + name: kubeconf-template +data: + kubeconfig.yml: | + apiVersion: v1 + kind: Config + current-context: kubernetes@default + contexts: + - context: + cluster: default + user: default + name: kubernetes@default + clusters: + - cluster: + certificate-authority: /etc/kubernetes/ca.crt + server: https://kube-apiserver:6443 + name: default + users: + - name: default + user: + client-certificate: /etc/kubernetes/kube.crt + client-key: /etc/kubernetes/kube.key + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: cluster-data +data: + advertiseIP: 10.0.0.1 # placeholder + info: hks-managed-cluster +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: kube-api-configs + labels: + tier: control-plane +data: + authentication-conf.yaml: | + # Docs: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens + apiVersion: apiserver.config.k8s.io/v1beta1 + kind: AuthenticationConfiguration + anonymous: + enabled: true + conditions: + # kubeadm also needs to read the discovery info: + - path: /api/v1/namespaces/kube-public/configmaps/cluster-info + # for status checks: + - path: /healthz + - path: /readyz + - path: /livez + jwt: [] + authorization-conf.yaml: | + # Docs: https://kubernetes.io/docs/reference/access-authn-authz/authorization/ + apiVersion: apiserver.config.k8s.io/v1 + kind: AuthorizationConfiguration + authorizers: + - type: Node + name: node + - type: RBAC + name: rbac + audit-policy.yaml: | + apiVersion: audit.k8s.io/v1 + kind: Policy + + # Don't log the initial RequestReceived stage to cut down on volume + omitStages: + - RequestReceived + + # The rules are evaluated in order; the first matching rule applies. + rules: + # The following requests were manually identified as high-volume and low-risk,so drop them. + - level: None + users: ["system:kube-proxy"] + verbs: ["watch", "get"] + resources: + - group: "" # core + resources: ["endpoints", "services", "services/status"] + - level: None + userGroups: ["system:nodes"] + verbs: ["get", "watch"] + resources: + - group: "" # core + resources: ["nodes", "nodes/status"] + - level: None + users: + - system:kube-controller-manager + - system:kube-scheduler + - system:serviceaccount:kube-system:endpoint-controller + verbs: ["get", "update", "watch"] + namespaces: ["kube-system"] + resources: + - group: "" # core + resources: ["endpoints"] + - level: None + users: ["system:apiserver"] + verbs: ["get", "watch"] + resources: + - group: "" # core + resources: ["namespaces", "namespaces/status", "namespaces/finalize"] + # Don't log HPA fetching metrics. + - level: None + users: + - system:kube-controller-manager + verbs: ["get", "list"] + resources: + - group: "metrics.k8s.io" + # Don't log these read-only URLs. + - level: None + nonResourceURLs: + - /healthz* + - /version + - /swagger* + - "/metrics" + - "/openapi*" + # Don't log events requests. + - level: None + resources: + - group: "" # core + resources: ["events"] + # Secrets, TokenRequest and TokenReviews can contain sensitive & binary data, + # so only log at the Metadata level. + - level: Metadata + resources: + - group: "" # core + resources: ["secrets", "serviceaccounts/token"] + - group: authentication.k8s.io + resources: ["tokenreviews"] + + # Log request+response bodies for any mutating action + - level: RequestResponse + verbs: ["create", "update", "patch", "delete"] + # userGroups: [oidc:] + + # Log metadata only for all other resource requests + - level: Metadata + + # (Optional) If you have custom API groups you care about, you can add them here + # - level: RequestResponse + # resources: + # - group: "myorg.example.com" + # resources: ["widgets","gadgets"] + + admission-control-config.yaml: | + apiVersion: apiserver.config.k8s.io/v1 + kind: AdmissionConfiguration + plugins: + - name: PodSecurity # Enable the built-in Pod Security admission plugin + configuration: + apiVersion: pod-security.admission.config.k8s.io/v1 + kind: PodSecurityConfiguration + + # -------------------------------------------------------------------- + # 1. Cluster-wide defaults + # -------------------------------------------------------------------- + defaults: + # Reject any pod that violates the baseline profile + enforce: "baseline" + enforce-version: "latest" + + # Log (audit) and warn on anything that would break the stricter + # restricted profile so you can spot future hardening issues early + audit: "restricted" + audit-version: "latest" + warn: "restricted" + warn-version: "latest" + + # -------------------------------------------------------------------- + # 2. Exemptions for critical system components + # -------------------------------------------------------------------- + exemptions: + usernames: [] # (add human break-glass accounts if required) + runtimeClasses: [] # (e.g. kata-containers, gvisor, etc.) + namespaces: + - kube-system # Core control-plane add-ons + - kube-public # Cluster-info ConfigMap & bootstrap helpers + - kube-node-lease # Node heart-beat leases +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: etcd-configs + labels: + tier: control-plane +data: + generate-conf.sh: | + #!/bin/sh + + # This is the configuration file for the etcd server + # Full example: https://github.com/etcd-io/etcd/blob/main/etcd.conf.yml.sample + cat > /etc/etcd/etcd-conf.yaml < $WORKSPACE/encryption-config.yaml + + echo "KEY GENERATED: ENCRYPTION_KEY" + kubectl create secret generic kube-encryption \ + --from-file=encryption-config.yaml=$WORKSPACE/encryption-config.yaml \ + --from-literal=key=$ENCRYPTION_KEY + echo "SECRET CREATE: ENCRYPTION_KEY" + else + echo "ENCRYPTION_KEY is already set" + fi + + echo "Checking for file: $CA_ETCD_PATH_KEY" + if [ ! -e "$CA_ETCD_PATH_KEY" ]; then + echo "NOT FOUND: $CA_ETCD_PATH_KEY. Generating..." + openssl genrsa -out $WORKSPACE/etcd-ca.key $KEY_SIZE + openssl req -new -key $WORKSPACE/etcd-ca.key -x509 -days $CA_VALID_DAYS -batch \ + -subj "/CN=${CLUSTER_ID}/O=kubernetes/OU=pki/emailAddress=kubernetes-pki@hegerdes.com" \ + -out $WORKSPACE/ca.crt + + echo "KEY GENERATED: $CA_ETCD_PATH_KEY" + echo "SECRET CREATE: $CA_ETCD_PATH_KEY" + kubectl create secret generic etcd-ca-tls --type=kubernetes.io/tls \ + --from-file=tls.key=$WORKSPACE/etcd-ca.key \ + --from-file=tls.crt=$WORKSPACE/ca.crt + echo "SECRET CREATED: $CA_ETCD_PATH_KEY" + else + echo "FOUND: $CA_ETCD_PATH_KEY" + fi + + echo "Checking for file: $CA_CP_PATH_KEY" + if [ ! -e "$CA_CP_PATH_KEY" ]; then + echo "NOT FOUND: $CA_CP_PATH_KEY. Generating..." + openssl genrsa -out $WORKSPACE/kube-ca.key $KEY_SIZE + openssl req -new -key $WORKSPACE/kube-ca.key -x509 -days $CA_VALID_DAYS -batch \ + -subj "/CN=${CLUSTER_ID}/O=kubernetes/OU=pki/emailAddress=kubernetes-pki@hegerdes.com" \ + -out $WORKSPACE/ca.crt + + echo "KEY GENERATED: $CA_CP_PATH_KEY" + echo "SECRET CREATE: $CA_CP_PATH_KEY" + kubectl create secret generic kube-ca-tls --type=kubernetes.io/tls \ + --from-file=tls.key=$WORKSPACE/kube-ca.key \ + --from-file=tls.crt=$WORKSPACE/ca.crt + echo "SECRET CREATED: $CA_CP_PATH_KEY" + else + echo "FOUND: $CA_CP_PATH_KEY" + fi + + echo "Checking for file: $CA_PROXY_PATH_KEY" + if [ ! -e "$CA_PROXY_PATH_KEY" ]; then + echo "NOT FOUND: $CA_PROXY_PATH_KEY. Generating..." + openssl genrsa -out $WORKSPACE/front-proxy-ca.key $KEY_SIZE + openssl req -new -key $WORKSPACE/front-proxy-ca.key -x509 -days $CA_VALID_DAYS -batch \ + -subj "/CN=${CLUSTER_ID}/O=kubernetes/OU=pki/emailAddress=kubernetes-pki@hegerdes.com" \ + -out $WORKSPACE/front-proxy-ca.crt + + echo "KEY GENERATED: $CA_PROXY_PATH_KEY" + echo "SECRET CREATE: $CA_PROXY_PATH_KEY" + kubectl create secret generic kube-front-proxy-ca-tls --type=kubernetes.io/tls \ + --from-file=tls.key=$WORKSPACE/front-proxy-ca.key \ + --from-file=tls.crt=$WORKSPACE/front-proxy-ca.crt + echo "SECRET CREATED: $CA_PROXY_PATH_KEY" + else + echo "FOUND: $CA_PROXY_PATH_KEY" + fi + + echo "Checking for file: $CA_SA_PATH_KEY" + if [ ! -e "$CA_SA_PATH_KEY" ]; then + echo "NOT FOUND: $CA_SA_PATH_KEY. Generating..." + openssl genrsa -out $WORKSPACE/sa.key $KEY_SIZE + openssl req -new -key $WORKSPACE/sa.key -x509 -days $CA_VALID_DAYS -batch \ + -subj "/CN=${CLUSTER_ID}/O=kubernetes/OU=pki/emailAddress=kubernetes-pki@hegerdes.com" \ + -out $WORKSPACE/sa.crt + openssl rsa -in $WORKSPACE/sa.key -pubout -out $WORKSPACE/sa.pub + + echo "KEY GENERATED: $CA_SA_PATH_KEY" + echo "SECRET CREATE: $CA_SA_PATH_KEY" + kubectl create secret generic kube-sa-tls --type=kubernetes.io/tls \ + --from-file=tls.key=$WORKSPACE/sa.key \ + --from-file=tls.crt=$WORKSPACE/sa.crt \ + --from-file=$WORKSPACE/sa.pub + echo "SECRET CREATED: $CA_SA_PATH_KEY" + else + echo "FOUND: $CA_SA_PATH_KEY" + fi + # Make sure all keys are gone from fs + rm -rf $WORKSPACE/* || true + securityContext: + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /etc/kubernetes/pki + name: tls-kube + readOnly: true + - mountPath: /workspace + name: workdir + volumes: + - name: workdir + emptyDir: + sizeLimit: 10Mi + - name: tls-kube + projected: + sources: + - secret: + name: etcd-ca-tls + optional: true + items: + - key: tls.key + path: etcd-ca.key + - key: tls.crt + path: etcd-ca.crt + - secret: + name: kube-ca-tls + optional: true + items: + - key: tls.key + path: kube-ca.key + - key: tls.crt + path: kube-ca.crt + - secret: + name: kube-sa-tls + optional: true + items: + - key: tls.key + path: sa.key + - key: tls.crt + path: sa.crt + - key: sa.pub + path: sa.pub + - secret: + name: kube-front-proxy-ca-tls + optional: true + items: + - key: tls.key + path: front-proxy-ca.key + - key: tls.crt + path: front-proxy-ca.crt +--- +apiVersion: v1 +kind: Namespace +metadata: + name: "{{ .Release.Namespace }}" + labels: + hks.hegerdes.com/cluster: "true" + hks.hegerdes.com/region: "{{ .Values.controlplane.domainSuffix }}" +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kube-init-ca-gen + annotations: + argocd.argoproj.io/hook: PreSync + argocd.argoproj.io/sync-wave: "-1" +--- +# Role granting create on secrets & configmaps +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: kube-init-ca-gen + annotations: + argocd.argoproj.io/hook: PreSync + argocd.argoproj.io/sync-wave: "-1" +rules: + - apiGroups: [""] + resources: ["secrets", "configmaps"] + verbs: ["create"] +--- +# Bind the Role to the ServiceAccount +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: kube-init-ca-gen-rolebinding + annotations: + argocd.argoproj.io/hook: PreSync + argocd.argoproj.io/sync-wave: "-1" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: kube-init-ca-gen +subjects: + - kind: ServiceAccount + name: kube-init-ca-gen diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-issuer.yml b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-issuer.yml new file mode 100644 index 0000000..5ec3c52 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-issuer.yml @@ -0,0 +1,23 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: ca-kube-controlplane +spec: + ca: + secretName: kube-ca-tls +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: ca-etcd +spec: + ca: + secretName: etcd-ca-tls +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: ca-kube-front-proxy +spec: + ca: + secretName: kube-front-proxy-ca-tls diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-scheduler.yaml b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-scheduler.yaml new file mode 100644 index 0000000..256faca --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/templates/kube-scheduler.yaml @@ -0,0 +1,157 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kube-scheduler + labels: + component: kube-scheduler + tier: control-plane + app: kube-scheduler + annotations: + reloader.stakater.com/auto: "true" +spec: + replicas: 1 + selector: + matchLabels: + component: kube-scheduler + tier: control-plane + app: kube-scheduler + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + maxSurge: 1 + minReadySeconds: 10 + template: + metadata: + labels: + component: kube-scheduler + tier: control-plane + app: kube-scheduler + spec: + enableServiceLinks: false + containers: + - name: kube-scheduler + image: registry.k8s.io/kube-scheduler:v1.35.0 + imagePullPolicy: IfNotPresent + # Docs: https://kubernetes.io/docs/reference/command-line-tools-reference/kube-scheduler/ + command: + - kube-scheduler + - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt + - --authentication-kubeconfig=/etc/kubernetes/kubeconfig.yml + - --authorization-kubeconfig=/etc/kubernetes/kubeconfig.yml + - --kubeconfig=/etc/kubernetes/kubeconfig.yml + - --leader-elect=true + - --profiling=false + - --secure-port=10259 + - --tls-min-version=VersionTLS13 + - --tls-cert-file=/etc/kubernetes/pki/tls.crt + - --tls-private-key-file=/etc/kubernetes/pki/tls.key + - --client-ca-file=/etc/kubernetes/pki/kube-ca.crt + - --leader-elect-resource-namespace=default + ports: + - containerPort: 10259 + name: scheduler-port + protocol: TCP + securityContext: + readOnlyRootFilesystem: true + capabilities: + drop: [all] + add: ["NET_BIND_SERVICE"] + livenessProbe: + failureThreshold: 8 + httpGet: + path: /livez + port: scheduler-port + scheme: HTTPS + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 15 + readinessProbe: + failureThreshold: 3 + httpGet: + path: /readyz + port: scheduler-port + scheme: HTTPS + periodSeconds: 1 + timeoutSeconds: 15 + resources: + requests: + cpu: 100m + startupProbe: + failureThreshold: 24 + httpGet: + path: /livez + port: scheduler-port + scheme: HTTPS + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 15 + volumeMounts: + - mountPath: /etc/kubernetes + name: kubeconfig + readOnly: true + - mountPath: /etc/kubernetes/pki + name: tls-kube + readOnly: true + # priority: 2000001000 + # priorityClassName: system-node-critical + securityContext: + seccompProfile: + type: RuntimeDefault + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + volumes: + - name: kubeconfig + projected: + sources: + - secret: + name: kube-scheduler-client-tls + items: + - key: ca.crt + path: ca.crt + - key: tls.crt + path: kube.crt + - key: tls.key + path: kube.key + - configMap: + name: kubeconf-template + items: + - key: kubeconfig.yml + path: kubeconfig.yml + - name: tls-kube + projected: + sources: + - secret: + name: kube-front-proxy-client-tls + items: + - key: ca.crt + path: front-proxy-ca.crt + - secret: + name: kube-scheduler-serving-tls + items: + - key: ca.crt + path: kube-ca.crt + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: kube-scheduler + component: kube-scheduler + tier: control-plane + name: kube-scheduler +spec: + ports: + - port: 10259 + protocol: TCP + targetPort: scheduler-port + name: scheduler-port + selector: + app: kube-scheduler + component: kube-scheduler + tier: control-plane diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/templates/pdb.yaml b/k8s-apps/hegerdes-kubernetes-service/hks/templates/pdb.yaml new file mode 100644 index 0000000..651db9f --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/templates/pdb.yaml @@ -0,0 +1,13 @@ +{{- if .Values.controlplane.pdb.enabled -}} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: kube-apiserver +spec: + minAvailable: 1 + selector: + matchLabels: + app: kube-apiserver + component: kube-apiserver + tier: control-plane +{{- end }} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/templates/tls-route.yaml b/k8s-apps/hegerdes-kubernetes-service/hks/templates/tls-route.yaml new file mode 100644 index 0000000..34f8510 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/templates/tls-route.yaml @@ -0,0 +1,19 @@ +{{- if .Values.controlplane.tlsRoute.enabled -}} +apiVersion: gateway.networking.k8s.io/v1alpha2 +kind: TLSRoute +metadata: + name: "{{ .Release.Namespace }}" +spec: + hostnames: + # - "{{ .Release.Namespace }}.localhost" + - "{{ .Release.Namespace }}.{{ .Values.controlplane.domainSuffix }}" + parentRefs: + - name: cilium-gateway + namespace: cilium-gateway + rules: + - backendRefs: + - name: kube-apiserver + kind: Service + namespace: "{{ .Release.Namespace }}" + port: 6443 +{{- end }} diff --git a/k8s-apps/hegerdes-kubernetes-service/hks/values.yaml b/k8s-apps/hegerdes-kubernetes-service/hks/values.yaml new file mode 100644 index 0000000..9ba521f --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/hks/values.yaml @@ -0,0 +1,14 @@ +controlplane: + domainSuffix: hks.eu-central.hegerdes.com + publicIp: "publicIpServiceRef" + publicIpServiceRef: + namespace: cilium-gateway + name: cilium-gateway-cilium-gateway + tlsRoute: + enabled: true + parentRefs: + + pdb: + enabled: false + +extraObjects: [] diff --git a/k8s-apps/hegerdes-kubernetes-service/shared/argo-cilium.yaml b/k8s-apps/hegerdes-kubernetes-service/shared/argo-cilium.yaml new file mode 100644 index 0000000..f3e04fa --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/shared/argo-cilium.yaml @@ -0,0 +1,85 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: cilium + namespace: argocd +spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] + generators: + - clusters: + selector: + matchLabels: + hks.hegerdes.com/managed-cluster: "true" + hks.hegerdes.com/cluster-type: "downstream" + template: + metadata: + name: "{{.name}}-cilium" + spec: + project: default + source: + chart: cilium + repoURL: https://helm.cilium.io/ + targetRevision: 1.* + helm: + releaseName: cilium + valuesObject: + cluster: + name: "{{.name}}" + + k8sServiceHost: '{{ index .metadata.annotations "hks.hegerdes.com/public-host" }}' + k8sServicePort: 6443 + kubeProxyReplacement: true + rollOutCiliumPods: true + annotateK8sNode: true + + l7Proxy: false + envoy: + enabled: false + rollOutPods: true + operator: + rollOutPods: true + replicas: 1 + + endpointRoutes: + enabled: false + + loadBalancer: + algorithm: maglev + serviceTopology: true + + hubble: + enabled: false + rollOutPods: true + relay: + enabled: false + rollOutPods: true + ui: + enabled: false + rollOutPods: true + # Needed if tailscale services are routed + socketLB: + hostNamespaceOnly: true + + ipam: + mode: kubernetes + operator: + clusterPoolIPv4PodCIDRList: [10.244.0.0/16] + # clusterPoolIPv6PodCIDRList: ["{{ k8s_pod_network_cidr_ipv6 }}"] + + destination: + server: "{{.server}}" + namespace: kube-system + info: + - name: "Source Info" + value: "https://artifacthub.io/packages/helm/cilium/cilium" + syncPolicy: + automated: + prune: true + selfHeal: true + retry: + limit: 3 + backoff: + duration: 30s + factor: 2 + maxDuration: 5m diff --git a/k8s-apps/hegerdes-kubernetes-service/shared/argo-coredns.yml b/k8s-apps/hegerdes-kubernetes-service/shared/argo-coredns.yml new file mode 100644 index 0000000..3d2c614 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/shared/argo-coredns.yml @@ -0,0 +1,146 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: coredns + namespace: argocd +spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] + generators: + - clusters: + selector: + matchLabels: + hks.hegerdes.com/managed-cluster: "true" + hks.hegerdes.com/cluster-type: "downstream" + template: + metadata: + name: "{{.name}}-coredns" + spec: + project: default + destination: + server: "{{.server}}" + namespace: kube-system + sources: + - repoURL: https://github.com/hegerdes/GitOps.git + targetRevision: feat/hks + path: k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering + helm: + valuesObject: + extraObjects: + - apiVersion: v1 + kind: ConfigMap + metadata: + name: coredns-kubeconf + namespace: kube-system + data: + kubeconfig: | + kind: Config + apiVersion: v1 + current-context: default + contexts: + - name: default + context: + cluster: kubernetes + user: coredns + clusters: + - name: kubernetes + cluster: + server: "https://{{ index .metadata.annotations "hks.hegerdes.com/public-host" }}:6443" + certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + users: + - name: coredns + user: + tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + - chart: coredns + repoURL: https://coredns.github.io/helm + targetRevision: 1.* + helm: + releaseName: coredns + valuesObject: + image: + tag: 1.14.1 + serviceAccount: + create: true + name: coredns + service: + clusterIP: "10.96.0.10" + name: "kube-dns" + replicaCount: 2 + extraVolumes: + - name: kubeconf-volume + configMap: + name: coredns-kubeconf + defaultMode: 420 + items: + - key: kubeconfig + path: kubeconfig + extraVolumeMounts: + - name: kubeconf-volume + mountPath: /etc/kube-auth + priorityClassName: system-cluster-critical + isClusterService: true + deployment: + annotations: + configmap.reloader.stakater.com/reload: coredns + prometheus: + service: + enabled: true + # Default zone is what Kubernetes recommends: + # https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#coredns-configmap-options + servers: + - zones: + - zone: . + port: 53 + plugins: + - name: errors + # Serves a /health endpoint on :8080, required for livenessProbe + - name: health + configBlock: |- + lameduck 10s + # Serves a /ready endpoint on :8181, required for readinessProbe + - name: ready + - name: log + parameters: "." + configBlock: |- + class error + # Required to query kubernetes API for data + - name: kubernetes + parameters: cluster.local in-addr.arpa ip6.arpa + configBlock: |- + kubeconfig /etc/kube-auth/kubeconfig + pods insecure + fallthrough in-addr.arpa ip6.arpa + ttl 30 + # Serves a /metrics endpoint on :9153, required for serviceMonitor + - name: prometheus + parameters: :9153 + - name: forward + # parameters: . /etc/resolv.conf + # parameters: . 2a00:1098:2b::1 2a00:1098:2c::1 # nat64 + parameters: . tls://1.1.1.1 tls://[2606:4700:4700::1111]:853 tls://1.0.0.1 tls://[2606:4700:4700::1001]:853 + configBlock: |- + tls_servername tls.cloudflare-dns.com + health_check 5s + max_concurrent 1000 + - name: cache + parameters: 60 + configBlock: |- + disable success cluster.local + disable denial cluster.local + - name: loop + - name: reload + - name: loadbalance + # affinity: + # podAntiAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # - topologyKey: "kubernetes.io/hostname" + # labelSelector: + # matchLabels: + # k8s-app: kube-dns + info: + - name: Chart-Info CoreDNS + value: https://github.com/coredns/helm/ + syncPolicy: + automated: + prune: false + selfHeal: false diff --git a/k8s-apps/hegerdes-kubernetes-service/shared/argo-hks-conf.yaml b/k8s-apps/hegerdes-kubernetes-service/shared/argo-hks-conf.yaml new file mode 100644 index 0000000..07895c0 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/shared/argo-hks-conf.yaml @@ -0,0 +1,68 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: cluster-conf + namespace: argocd +spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] + generators: + - clusters: + selector: + matchLabels: + hks.hegerdes.com/managed-cluster: "true" + hks.hegerdes.com/cluster-type: "downstream" + # argocd.argoproj.io/kubernetes-version: "1.35" + template: + metadata: + name: "{{.name}}-cluster-conf" + spec: + project: default + sources: + - repoURL: https://github.com/hegerdes/GitOps.git + targetRevision: feat/hks + path: k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering + helm: + valuesObject: + extraObjects: + - apiVersion: v1 + kind: ConfigMap + metadata: + name: kubeadm-config + namespace: kube-system + data: + ClusterConfiguration: | + apiVersion: kubeadm.k8s.io/v1beta4 + kind: ClusterConfiguration + caCertificateValidityPeriod: 87600h0m0s + certificateValidityPeriod: 8760h0m0s + certificatesDir: /etc/kubernetes/pki + clusterName: {{.name}} + controlPlaneEndpoint: {{ index .metadata.annotations "hks.hegerdes.com/public-host" }}:6443 + dns: {} + encryptionAlgorithm: RSA-2048 + imageRepository: registry.k8s.io + kubernetesVersion: v{{ index .metadata.labels "argocd.argoproj.io/kubernetes-version" }}.0 + networking: + dnsDomain: cluster.local + podSubnet: 10.244.0.0/16 + serviceSubnet: 10.96.0.0/16 + - repoURL: https://github.com/hegerdes/GitOps.git + targetRevision: feat/hks + path: k8s-apps/hegerdes-kubernetes-service/clustes-shared + destination: + server: "{{.server}}" + namespace: kube-system + info: + - name: "Source Info" + value: "https://github.com/hegerdes/GitOps" + syncPolicy: + automated: + prune: true + selfHeal: true + retry: + limit: 3 + backoff: + duration: 30s + factor: 2 + maxDuration: 5m diff --git a/k8s-apps/hegerdes-kubernetes-service/shared/argo-metrics.yml b/k8s-apps/hegerdes-kubernetes-service/shared/argo-metrics.yml new file mode 100644 index 0000000..20e8336 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/shared/argo-metrics.yml @@ -0,0 +1,52 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: metrics + namespace: argocd +spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] + generators: + - clusters: + selector: + matchLabels: + hks.hegerdes.com/managed-cluster: "true" + hks.hegerdes.com/cluster-type: "downstream" + template: + metadata: + name: "{{.name}}-metrics" + spec: + project: default + source: + chart: metrics-server + repoURL: https://kubernetes-sigs.github.io/metrics-server/ + targetRevision: 3.* + helm: + releaseName: metrics-server + valuesObject: + # serviceAccount: + # create: false + # rbac: + # create: false + defaultArgs: + - --cert-dir=/tmp + - --kubelet-use-node-status-port + - --metric-resolution=15s + - --profiling=false + - --kubelet-preferred-address-types=InternalDNS,InternalIP,ExternalDNS,ExternalIP + # - --kubeconfig=TODO + # - --kubelet-certificate-authority string Path to the CA to use to validate the Kubelet's serving certificates. + # - --kubelet-client-certificate string Path to a client cert file for TLS. + # - --kubelet-client-key string + destination: + server: "{{.server}}" + namespace: kube-system + info: + - name: Chart-Info Metrics-Server + value: https://artifacthub.io/packages/helm/metrics-server/metrics-server + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s-apps/hegerdes-kubernetes-service/shared/gateway.yaml b/k8s-apps/hegerdes-kubernetes-service/shared/gateway.yaml new file mode 100644 index 0000000..e092877 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/shared/gateway.yaml @@ -0,0 +1,89 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: cilium-gateway +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: cilium-gateway + namespace: cilium-gateway +spec: + gatewayClassName: cilium + infrastructure: + annotations: + load-balancer.hetzner.cloud/location: nbg1 + load-balancer.hetzner.cloud/name: k8s-hks-gateway-lb + load-balancer.hetzner.cloud/network: k8s-network + load-balancer.hetzner.cloud/use-private-ip: "true" + load-balancer.hetzner.cloud/uses-proxyprotocol: "true" + load-balancer.hetzner.cloud/ipv6-disabled: "true" + listeners: + - name: tls + protocol: TLS + port: 6443 + hostname: "*.hks.eu-central.hegerdes.com" + allowedRoutes: + namespaces: + from: All + kinds: + - kind: TLSRoute + tls: + mode: Passthrough + + # - name: http + # allowedRoutes: + # namespaces: + # from: All + # kinds: + # - kind: HTTPRoute + # hostname: "manager.hks.eu-central" + # port: 80 + # protocol: HTTP + +# --- +# https://docs.nginx.com/nginx-gateway-fabric/traffic-management/tls-passthrough/ +# apiVersion: gateway.networking.k8s.io/v1 +# kind: Gateway +# metadata: +# name: hks-kube-gw +# namespace: nginx-gateway +# spec: +# gatewayClassName: nginx +# infrastructure: +# annotations: +# load-balancer.hetzner.cloud/location: nbg1 +# load-balancer.hetzner.cloud/name: k8s-hks-gateway-lb +# load-balancer.hetzner.cloud/network: k8s-network +# load-balancer.hetzner.cloud/use-private-ip: "true" +# load-balancer.hetzner.cloud/uses-proxyprotocol: "true" +# parametersRef: +# group: gateway.nginx.org +# kind: NginxProxy +# name: ngf-proxy-config +# listeners: +# - name: tls +# protocol: TLS +# port: 6443 +# hostname: "*.hks.eu-central.hegerdes.com" +# allowedRoutes: +# namespaces: +# from: All +# kinds: +# - kind: TLSRoute +# tls: +# mode: Passthrough +# # certificateRefs: +# # - kind: Secret +# # name: kube-apiserver-tls +# # namespace: test1 +# # - name: test1-tls +# # protocol: TLS +# # port: 443 +# # hostname: bar.example.com +# # tls: +# # certificateRefs: +# # - kind: Secret +# # group: "" +# # name: bar-example-com-cert +# --- diff --git a/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/.helmignore b/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/Chart.yaml b/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/Chart.yaml new file mode 100644 index 0000000..26768ea --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: helm-rendering +description: A Helm chart for helm templates + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/templates/_helpers.tpl b/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/templates/_helpers.tpl new file mode 100644 index 0000000..4839a9e --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/templates/_helpers.tpl @@ -0,0 +1,65 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "hks.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "hks.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "hks.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "hks.labels" -}} +helm.sh/chart: {{ include "hks.chart" . }} +{{ include "hks.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "hks.selectorLabels" -}} +app.kubernetes.io/name: {{ include "hks.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + + +{{/* +Renders a value that contains template. +Usage: +{{ include ".render" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define ".render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} diff --git a/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/templates/extra-manifests.yaml b/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/templates/extra-manifests.yaml new file mode 100644 index 0000000..0f48fe1 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{- range .Values.extraObjects }} +--- +{{ include ".render" (dict "value" . "context" $) }} +{{- end }} diff --git a/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/values.yaml b/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/values.yaml new file mode 100644 index 0000000..3face71 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/shared/helm-rendering/values.yaml @@ -0,0 +1 @@ +extraObjects: [] diff --git a/k8s-apps/hegerdes-kubernetes-service/shared/rbac-secret-read.yaml b/k8s-apps/hegerdes-kubernetes-service/shared/rbac-secret-read.yaml new file mode 100644 index 0000000..fb8df65 --- /dev/null +++ b/k8s-apps/hegerdes-kubernetes-service/shared/rbac-secret-read.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: external-secrets + namespace: argocd +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: secret-reader +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: [authorization.k8s.io] + resources: [selfsubjectrulesreviews] + verbs: [create] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: external-secrets-reader-binding +subjects: + - kind: ServiceAccount + name: external-secrets + namespace: argocd +roleRef: + kind: ClusterRole + name: secret-reader + apiGroup: rbac.authorization.k8s.io