diff --git a/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/cluster-role-binding.yaml b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/cluster-role-binding.yaml new file mode 100644 index 0000000..d06db37 --- /dev/null +++ b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/cluster-role-binding.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/instance: kubelet-serving-cert-approver + app.kubernetes.io/name: kubelet-serving-cert-approver + name: kubelet-serving-cert-approver +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: certificates:kubelet-serving-cert-approver +subjects: +- kind: ServiceAccount + name: kubelet-serving-cert-approver + namespace: kubelet-serving-cert-approver diff --git a/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/cluster-role-certificates.yaml b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/cluster-role-certificates.yaml new file mode 100644 index 0000000..83066da --- /dev/null +++ b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/cluster-role-certificates.yaml @@ -0,0 +1,36 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/instance: kubelet-serving-cert-approver + app.kubernetes.io/name: kubelet-serving-cert-approver + name: certificates:kubelet-serving-cert-approver +rules: +- apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests + verbs: + - get + - list + - watch +- apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests/approval + verbs: + - update +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +- apiGroups: + - certificates.k8s.io + resourceNames: + - kubernetes.io/kubelet-serving + resources: + - signers + verbs: + - approve diff --git a/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/cluster-role-events.yaml b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/cluster-role-events.yaml new file mode 100644 index 0000000..e1422ee --- /dev/null +++ b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/cluster-role-events.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/instance: kubelet-serving-cert-approver + app.kubernetes.io/name: kubelet-serving-cert-approver + name: events:kubelet-serving-cert-approver +rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/deployment.yaml b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/deployment.yaml new file mode 100644 index 0000000..8b838d9 --- /dev/null +++ b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/deployment.yaml @@ -0,0 +1,100 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/instance: kubelet-serving-cert-approver + app.kubernetes.io/name: kubelet-serving-cert-approver + name: kubelet-serving-cert-approver + namespace: kubelet-serving-cert-approver +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/instance: kubelet-serving-cert-approver + app.kubernetes.io/name: kubelet-serving-cert-approver + template: + metadata: + labels: + app.kubernetes.io/instance: kubelet-serving-cert-approver + app.kubernetes.io/name: kubelet-serving-cert-approver + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: node-role.kubernetes.io/control-plane + operator: DoesNotExist + weight: 100 + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/instance: kubelet-serving-cert-approver + topologyKey: kubernetes.io/hostname + containers: + - args: + - serve + - --enable-leader-election + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: ghcr.io/alex1989hu/kubelet-serving-cert-approver:0.12.1 + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz + port: health + initialDelaySeconds: 6 + name: cert-approver + ports: + - containerPort: 8080 + name: health + - containerPort: 9090 + name: metrics + readinessProbe: + httpGet: + path: /readyz + port: health + initialDelaySeconds: 3 + resources: + limits: + cpu: 250m + memory: 32Mi + requests: + cpu: 10m + memory: 18Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + startupProbe: + failureThreshold: 30 + httpGet: + path: /healthz + port: health + periodSeconds: 10 + priorityClassName: system-cluster-critical + securityContext: + fsGroup: 65534 + runAsGroup: 65534 + runAsUser: 65534 + seccompProfile: + type: RuntimeDefault + serviceAccountName: kubelet-serving-cert-approver + tolerations: + - effect: NoSchedule + key: node.cloudprovider.kubernetes.io/uninitialized + operator: Exists + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane + operator: Exists diff --git a/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/kustomization.yaml b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/kustomization.yaml index 4036500..7cfcd45 100644 --- a/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/kustomization.yaml +++ b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/kustomization.yaml @@ -1,5 +1,29 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - - https://raw.githubusercontent.com/alex1989hu/kubelet-serving-cert-approver/main/deploy/standalone-install.yaml + # Vendored from the upstream v0.12.1 release's deploy/ha-install.yaml + # (tag commit f72897c68e38185aeca848952d10a094054642ba), one document per + # file with the upstream bytes unchanged. The HA variant runs 2 replicas with + # leader election (one active approver plus a warm standby) and a required + # hostname anti-affinity, so losing a node does not stop kubelet + # serving-certificate approval. On a version bump, re-vendor every document + # from the new release tag and update newTag and digest below together. + - namespace.yaml + - service-account.yaml + - role.yaml + - cluster-role-certificates.yaml + - cluster-role-events.yaml + - role-binding-events.yaml + - role-binding-leader-election.yaml + - cluster-role-binding.yaml + - service.yaml + - deployment.yaml + - pod-disruption-budget.yaml - cilium-network-policy.yaml +# Pin the image by digest here rather than in the vendored deployment.yaml, so +# those bytes stay upstream's. Renders as `:@`; the digest is +# the release's multi-arch image index. +images: + - name: ghcr.io/alex1989hu/kubelet-serving-cert-approver + newTag: 0.12.1 + digest: sha256:445a8e5584f659701092d2ec8b625da8929dc75fe4d45274333bd9fe6db8fb75 diff --git a/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/namespace.yaml b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/namespace.yaml new file mode 100644 index 0000000..c6bb482 --- /dev/null +++ b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/namespace.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/instance: kubelet-serving-cert-approver + app.kubernetes.io/name: kubelet-serving-cert-approver + pod-security.kubernetes.io/audit: restricted + pod-security.kubernetes.io/enforce: restricted + pod-security.kubernetes.io/warn: restricted + name: kubelet-serving-cert-approver diff --git a/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/pod-disruption-budget.yaml b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/pod-disruption-budget.yaml new file mode 100644 index 0000000..c6ca9c9 --- /dev/null +++ b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/pod-disruption-budget.yaml @@ -0,0 +1,16 @@ +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: kubelet-serving-cert-approver + namespace: kubelet-serving-cert-approver +spec: + # The upstream ha-install.yaml runs 2 leader-elected replicas on different + # nodes but ships no PDB. maxUnavailable: 1 keeps a node drainable at any + # replica count (minAvailable: 1 would block a drain while only one replica + # is ready) and keeps the warm standby approving kubelet serving-certificate + # requests while a node drains. + maxUnavailable: 1 + selector: + matchLabels: + app.kubernetes.io/name: kubelet-serving-cert-approver + app.kubernetes.io/instance: kubelet-serving-cert-approver diff --git a/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/role-binding-events.yaml b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/role-binding-events.yaml new file mode 100644 index 0000000..6777b77 --- /dev/null +++ b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/role-binding-events.yaml @@ -0,0 +1,16 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/instance: kubelet-serving-cert-approver + app.kubernetes.io/name: kubelet-serving-cert-approver + name: events:kubelet-serving-cert-approver + namespace: default +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: events:kubelet-serving-cert-approver +subjects: +- kind: ServiceAccount + name: kubelet-serving-cert-approver + namespace: kubelet-serving-cert-approver diff --git a/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/role-binding-leader-election.yaml b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/role-binding-leader-election.yaml new file mode 100644 index 0000000..e34aaa9 --- /dev/null +++ b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/role-binding-leader-election.yaml @@ -0,0 +1,16 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/instance: kubelet-serving-cert-approver + app.kubernetes.io/name: kubelet-serving-cert-approver + name: leader-election:kubelet-serving-cert-approver + namespace: kubelet-serving-cert-approver +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: leader-election:kubelet-serving-cert-approver +subjects: +- kind: ServiceAccount + name: kubelet-serving-cert-approver + namespace: kubelet-serving-cert-approver diff --git a/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/role.yaml b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/role.yaml new file mode 100644 index 0000000..b5830aa --- /dev/null +++ b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/role.yaml @@ -0,0 +1,24 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/instance: kubelet-serving-cert-approver + app.kubernetes.io/name: kubelet-serving-cert-approver + name: leader-election:kubelet-serving-cert-approver + namespace: kubelet-serving-cert-approver +rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - update diff --git a/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/service-account.yaml b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/service-account.yaml new file mode 100644 index 0000000..64a870e --- /dev/null +++ b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/service-account.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/instance: kubelet-serving-cert-approver + app.kubernetes.io/name: kubelet-serving-cert-approver + name: kubelet-serving-cert-approver + namespace: kubelet-serving-cert-approver diff --git a/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/service.yaml b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/service.yaml new file mode 100644 index 0000000..4c21787 --- /dev/null +++ b/k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/instance: kubelet-serving-cert-approver + app.kubernetes.io/name: kubelet-serving-cert-approver + name: kubelet-serving-cert-approver + namespace: kubelet-serving-cert-approver +spec: + ports: + - name: metrics + port: 9090 + protocol: TCP + targetPort: metrics + selector: + app.kubernetes.io/instance: kubelet-serving-cert-approver + app.kubernetes.io/name: kubelet-serving-cert-approver