diff --git a/manifests/v2.2.1/deploy/create-validation-webhook.sh b/manifests/v2.2.1/deploy/create-validation-webhook.sh new file mode 100755 index 0000000000..3ae772643d --- /dev/null +++ b/manifests/v2.2.1/deploy/create-validation-webhook.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# Copyright 2021 The Kubernetes Authors. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +set -e + +if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + cat </dev/null || true +kubectl delete validatingwebhookconfiguration.admissionregistration.k8s.io validation.csi.vsphere.vmware.com --namespace "${namespace}" 2>/dev/null || true +kubectl delete serviceaccount vsphere-csi-webhook --namespace "${namespace}" 2>/dev/null || true +kubectl delete clusterrole.rbac.authorization.k8s.io vsphere-csi-webhook-role 2>/dev/null || true +kubectl delete clusterrolebinding.rbac.authorization.k8s.io vsphere-csi-webhook-role-binding --namespace "${namespace}" 2>/dev/null || true +kubectl delete deployment vsphere-csi-webhook --namespace "${namespace}" || true + +# patch validatingwebhook.yaml with CA_BUNDLE and create service and validatingwebhookconfiguration +sed "s/caBundle: .*$/caBundle: ${CA_BUNDLE}/g" validatingwebhook.yaml | kubectl apply -f - diff --git a/manifests/v2.2.1/deploy/generate-signed-webhook-certs.sh b/manifests/v2.2.1/deploy/generate-signed-webhook-certs.sh new file mode 100755 index 0000000000..b9c11ddbf7 --- /dev/null +++ b/manifests/v2.2.1/deploy/generate-signed-webhook-certs.sh @@ -0,0 +1,148 @@ +#!/bin/bash +# Copyright 2021 The Kubernetes Authors. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# File originally from https://github.com/istio/istio/blob/release-0.7/install/kubernetes/webhook-create-signed-cert.sh +set -e + +if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + cat <> "${tmpdir}"/csr.conf +[req] +req_extensions = v3_req +distinguished_name = req_distinguished_name +[req_distinguished_name] +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth +subjectAltName = @alt_names +[alt_names] +DNS.1 = ${service} +DNS.2 = ${service}.${namespace} +DNS.3 = ${service}.${namespace}.svc +EOF + +openssl genrsa -out "${tmpdir}"/server-key.pem 2048 +openssl req -new -key "${tmpdir}"/server-key.pem -subj "/O=C=US/ST=CA/L=Palo Alto/O=VMware/OU=CNS" -out "${tmpdir}"/server.csr -config "${tmpdir}"/csr.conf + + +# clean-up any previously created CSR for our service. Ignore errors if not present. +kubectl delete csr ${csrName} 2>/dev/null || true + +# create server cert/key CSR and send to k8s API +cat <&2 + exit 1 +fi +echo "${serverCert}" | openssl base64 -d -A -out "${tmpdir}"/server-cert.pem + +cat <"${tmpdir}"/webhook.config +[WebHookConfig] +port = "8443" +cert-file = "/etc/webhook/cert.pem" +key-file = "/etc/webhook/key.pem" +eof + + +# create the secret with CA cert and server cert/key +kubectl create secret generic "${secret}" \ + --from-file=key.pem="${tmpdir}"/server-key.pem \ + --from-file=cert.pem="${tmpdir}"/server-cert.pem \ + --from-file=webhook.config="${tmpdir}"/webhook.config \ + --dry-run=client -o yaml | + kubectl -n "${namespace}" apply -f - \ No newline at end of file diff --git a/manifests/v2.2.1/deploy/validatingwebhook.yaml b/manifests/v2.2.1/deploy/validatingwebhook.yaml new file mode 100644 index 0000000000..d314a0e441 --- /dev/null +++ b/manifests/v2.2.1/deploy/validatingwebhook.yaml @@ -0,0 +1,126 @@ +apiVersion: v1 +kind: Service +metadata: + name: vsphere-webhook-svc + namespace: kube-system + labels: + app: vsphere-csi-webhook +spec: + ports: + - port: 443 + targetPort: 8443 + selector: + app: vsphere-csi-webhook +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: validation.csi.vsphere.vmware.com +webhooks: + - name: validation.csi.vsphere.vmware.com + clientConfig: + service: + name: vsphere-webhook-svc + namespace: kube-system + path: "/validate" + caBundle: ${CA_BUNDLE} + rules: + - apiGroups: ["storage.k8s.io"] + apiVersions: ["v1", "v1beta1"] + operations: ["CREATE", "UPDATE"] + resources: ["storageclasses"] + sideEffects: None + admissionReviewVersions: ["v1"] + failurePolicy: Fail +--- +kind: ServiceAccount +apiVersion: v1 +metadata: + name: vsphere-csi-webhook + namespace: kube-system +--- +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: vsphere-csi-webhook-role + namespace: kube-system +rules: + - apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "list", "watch"] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: vsphere-csi-webhook-role-binding + namespace: kube-system +subjects: + - kind: ServiceAccount + name: vsphere-csi-webhook + namespace: kube-system +roleRef: + kind: Role + name: vsphere-csi-webhook-role + apiGroup: rbac.authorization.k8s.io +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: vsphere-csi-webhook + namespace: kube-system +spec: + replicas: 1 + selector: + matchLabels: + app: vsphere-csi-webhook + template: + metadata: + labels: + app: vsphere-csi-webhook + role: vsphere-csi-webhook + spec: + serviceAccountName: vsphere-csi-webhook + nodeSelector: + node-role.kubernetes.io/master: "" + tolerations: + - key: node-role.kubernetes.io/master + operator: Exists + effect: NoSchedule + # uncomment below toleration if you need an aggressive pod eviction in case when + # node becomes not-ready or unreachable. Default is 300 seconds if not specified. + #- key: node.kubernetes.io/not-ready + # operator: Exists + # effect: NoExecute + # tolerationSeconds: 30 + #- key: node.kubernetes.io/unreachable + # operator: Exists + # effect: NoExecute + # tolerationSeconds: 30 + dnsPolicy: "Default" + containers: + - name: vsphere-webhook + image: gcr.io/cloud-provider-vsphere/csi/release/syncer:v2.2.1 + args: + - "--operation-mode=WEBHOOK_SERVER" + - "--fss-name=internal-feature-states.csi.vsphere.vmware.com" + - "--fss-namespace=$(CSI_NAMESPACE)" + imagePullPolicy: "Always" + env: + - name: WEBHOOK_CONFIG_PATH + value: "/etc/webhook/webhook.config" + - name: LOGGER_LEVEL + value: "PRODUCTION" # Options: DEVELOPMENT, PRODUCTION + - name: CSI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - mountPath: /etc/webhook + name: webhook-certs + readOnly: true + volumes: + - name: socket-dir + emptyDir: {} + - name: webhook-certs + secret: + secretName: vsphere-webhook-certs \ No newline at end of file diff --git a/manifests/v2.2.1/deploy/vsphere-csi-controller-deployment.yaml b/manifests/v2.2.1/deploy/vsphere-csi-controller-deployment.yaml new file mode 100644 index 0000000000..a402bdf72e --- /dev/null +++ b/manifests/v2.2.1/deploy/vsphere-csi-controller-deployment.yaml @@ -0,0 +1,211 @@ +kind: Deployment +apiVersion: apps/v1 +metadata: + name: vsphere-csi-controller + namespace: kube-system +spec: + replicas: 1 + selector: + matchLabels: + app: vsphere-csi-controller + template: + metadata: + labels: + app: vsphere-csi-controller + role: vsphere-csi + spec: + serviceAccountName: vsphere-csi-controller + nodeSelector: + node-role.kubernetes.io/master: "" + tolerations: + - key: node-role.kubernetes.io/master + operator: Exists + effect: NoSchedule + # uncomment below toleration if you need an aggressive pod eviction in case when + # node becomes not-ready or unreachable. Default is 300 seconds if not specified. + #- key: node.kubernetes.io/not-ready + # operator: Exists + # effect: NoExecute + # tolerationSeconds: 30 + #- key: node.kubernetes.io/unreachable + # operator: Exists + # effect: NoExecute + # tolerationSeconds: 30 + dnsPolicy: "Default" + containers: + - name: csi-attacher + image: quay.io/k8scsi/csi-attacher:v3.1.0 + args: + - "--v=4" + - "--timeout=300s" + - "--csi-address=$(ADDRESS)" + - "--leader-election" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - mountPath: /csi + name: socket-dir + - name: csi-resizer + image: quay.io/k8scsi/csi-resizer:v1.1.0 + args: + - "--v=4" + - "--timeout=300s" + - "--handle-volume-inuse-error=false" + - "--csi-address=$(ADDRESS)" + - "--kube-api-qps=100" + - "--kube-api-burst=100" + - "--leader-election" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - mountPath: /csi + name: socket-dir + - name: vsphere-csi-controller + image: gcr.io/cloud-provider-vsphere/csi/release/driver:v2.2.1 + args: + - "--fss-name=internal-feature-states.csi.vsphere.vmware.com" + - "--fss-namespace=$(CSI_NAMESPACE)" + imagePullPolicy: "Always" + env: + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + - name: X_CSI_MODE + value: "controller" + - name: VSPHERE_CSI_CONFIG + value: "/etc/cloud/csi-vsphere.conf" + - name: LOGGER_LEVEL + value: "PRODUCTION" # Options: DEVELOPMENT, PRODUCTION + - name: INCLUSTER_CLIENT_QPS + value: "100" + - name: INCLUSTER_CLIENT_BURST + value: "100" + - name: CSI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: X_CSI_SERIAL_VOL_ACCESS_TIMEOUT + value: 3m + volumeMounts: + - mountPath: /etc/cloud + name: vsphere-config-volume + readOnly: true + - mountPath: /csi + name: socket-dir + ports: + - name: healthz + containerPort: 9808 + protocol: TCP + - name: prometheus + containerPort: 2112 + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 10 + timeoutSeconds: 3 + periodSeconds: 5 + failureThreshold: 3 + - name: liveness-probe + image: quay.io/k8scsi/livenessprobe:v2.2.0 + args: + - "--v=4" + - "--csi-address=/csi/csi.sock" + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: vsphere-syncer + image: gcr.io/cloud-provider-vsphere/csi/release/syncer:v2.2.1 + args: + - "--leader-election" + - "--fss-name=internal-feature-states.csi.vsphere.vmware.com" + - "--fss-namespace=$(CSI_NAMESPACE)" + imagePullPolicy: "Always" + ports: + - containerPort: 2113 + name: prometheus + protocol: TCP + env: + - name: FULL_SYNC_INTERVAL_MINUTES + value: "30" + - name: VSPHERE_CSI_CONFIG + value: "/etc/cloud/csi-vsphere.conf" + - name: LOGGER_LEVEL + value: "PRODUCTION" # Options: DEVELOPMENT, PRODUCTION + - name: INCLUSTER_CLIENT_QPS + value: "100" + - name: INCLUSTER_CLIENT_BURST + value: "100" + - name: CSI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - mountPath: /etc/cloud + name: vsphere-config-volume + readOnly: true + - name: csi-provisioner + image: quay.io/k8scsi/csi-provisioner:v2.1.0 + args: + - "--v=4" + - "--timeout=300s" + - "--csi-address=$(ADDRESS)" + - "--kube-api-qps=100" + - "--kube-api-burst=100" + - "--leader-election" + - "--default-fstype=ext4" + # needed only for topology aware setup + #- "--feature-gates=Topology=true" + #- "--strict-topology" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - mountPath: /csi + name: socket-dir + volumes: + - name: vsphere-config-volume + secret: + secretName: vsphere-config-secret + - name: socket-dir + emptyDir: {} +--- +apiVersion: v1 +data: + "csi-migration": "false" + "csi-auth-check": "true" + "online-volume-extend": "true" +kind: ConfigMap +metadata: + name: internal-feature-states.csi.vsphere.vmware.com + namespace: kube-system +--- +apiVersion: storage.k8s.io/v1 # For k8s 1.17 use storage.k8s.io/v1beta1 +kind: CSIDriver +metadata: + name: csi.vsphere.vmware.com +spec: + attachRequired: true + podInfoOnMount: false +--- +apiVersion: v1 +kind: Service +metadata: + name: vsphere-csi-controller + namespace: kube-system + labels: + app: vsphere-csi-controller +spec: + ports: + - name: ctlr + port: 2112 + targetPort: 2112 + protocol: TCP + - name: syncer + port: 2113 + targetPort: 2113 + protocol: TCP + selector: + app: vsphere-csi-controller \ No newline at end of file diff --git a/manifests/v2.2.1/deploy/vsphere-csi-node-ds.yaml b/manifests/v2.2.1/deploy/vsphere-csi-node-ds.yaml new file mode 100644 index 0000000000..ce7c9705b1 --- /dev/null +++ b/manifests/v2.2.1/deploy/vsphere-csi-node-ds.yaml @@ -0,0 +1,151 @@ +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: vsphere-csi-node + namespace: kube-system +spec: + selector: + matchLabels: + app: vsphere-csi-node + updateStrategy: + type: "RollingUpdate" + rollingUpdate: + maxUnavailable: 1 + template: + metadata: + labels: + app: vsphere-csi-node + role: vsphere-csi + spec: + serviceAccountName: vsphere-csi-node + dnsPolicy: "Default" + containers: + - name: node-driver-registrar + image: quay.io/k8scsi/csi-node-driver-registrar:v2.1.0 + args: + - "--v=5" + - "--csi-address=$(ADDRESS)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + - "--health-port=9809" + env: + - name: ADDRESS + value: /csi/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: /var/lib/kubelet/plugins/csi.vsphere.vmware.com/csi.sock + volumeMounts: + - name: plugin-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + ports: + - containerPort: 9809 + name: healthz + livenessProbe: + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 5 + timeoutSeconds: 5 + - name: vsphere-csi-node + image: gcr.io/cloud-provider-vsphere/csi/release/driver:v2.2.1 + args: + - "--fss-name=internal-feature-states.csi.vsphere.vmware.com" + - "--fss-namespace=$(CSI_NAMESPACE)" + imagePullPolicy: "Always" + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + - name: X_CSI_MODE + value: "node" + - name: X_CSI_SPEC_REQ_VALIDATION + value: "false" + # needed only for topology aware setups + #- name: VSPHERE_CSI_CONFIG + # value: "/etc/cloud/csi-vsphere.conf" # here csi-vsphere.conf is the name of the file used for creating secret using "--from-file" flag + - name: X_CSI_DEBUG + value: "true" + - name: LOGGER_LEVEL + value: "PRODUCTION" # Options: DEVELOPMENT, PRODUCTION + - name: CSI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + volumeMounts: + # needed only for topology aware setups + #- name: vsphere-config-volume + # mountPath: /etc/cloud + # readOnly: true + - name: plugin-dir + mountPath: /csi + - name: pods-mount-dir + mountPath: /var/lib/kubelet + # needed so that any mounts setup inside this container are + # propagated back to the host machine. + mountPropagation: "Bidirectional" + - name: device-dir + mountPath: /dev + - name: blocks-dir + mountPath: /sys/block + - name: sys-devices-dir + mountPath: /sys/devices + ports: + - containerPort: 9808 + name: healthz + livenessProbe: + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 10 + timeoutSeconds: 5 + periodSeconds: 5 + failureThreshold: 3 + - name: liveness-probe + image: quay.io/k8scsi/livenessprobe:v2.2.0 + args: + - "--v=4" + - "--csi-address=/csi/csi.sock" + volumeMounts: + - name: plugin-dir + mountPath: /csi + volumes: + # needed only for topology aware setups + #- name: vsphere-config-volume + # secret: + # secretName: vsphere-config-secret + - name: registration-dir + hostPath: + path: /var/lib/kubelet/plugins_registry + type: Directory + - name: plugin-dir + hostPath: + path: /var/lib/kubelet/plugins/csi.vsphere.vmware.com + type: DirectoryOrCreate + - name: pods-mount-dir + hostPath: + path: /var/lib/kubelet + type: Directory + - name: device-dir + hostPath: + path: /dev + - name: blocks-dir + hostPath: + path: /sys/block + type: Directory + - name: sys-devices-dir + hostPath: + path: /sys/devices + type: Directory + tolerations: + - effect: NoExecute + operator: Exists + - effect: NoSchedule + operator: Exists diff --git a/manifests/v2.2.1/rbac/vsphere-csi-controller-rbac.yaml b/manifests/v2.2.1/rbac/vsphere-csi-controller-rbac.yaml new file mode 100644 index 0000000000..1e240bee3d --- /dev/null +++ b/manifests/v2.2.1/rbac/vsphere-csi-controller-rbac.yaml @@ -0,0 +1,54 @@ +kind: ServiceAccount +apiVersion: v1 +metadata: + name: vsphere-csi-controller + namespace: kube-system +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: vsphere-csi-controller-role +rules: + - apiGroups: [""] + resources: ["nodes", "persistentvolumeclaims", "pods", "configmaps"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["patch"] + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "update", "delete", "patch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses", "csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "patch"] + - apiGroups: ["cns.vmware.com"] + resources: ["cnsvspherevolumemigrations"] + verbs: ["create", "get", "list", "watch", "update", "delete"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["get", "create", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: vsphere-csi-controller-binding +subjects: + - kind: ServiceAccount + name: vsphere-csi-controller + namespace: kube-system +roleRef: + kind: ClusterRole + name: vsphere-csi-controller-role + apiGroup: rbac.authorization.k8s.io diff --git a/manifests/v2.2.1/rbac/vsphere-csi-node-rbac.yaml b/manifests/v2.2.1/rbac/vsphere-csi-node-rbac.yaml new file mode 100644 index 0000000000..79d865582a --- /dev/null +++ b/manifests/v2.2.1/rbac/vsphere-csi-node-rbac.yaml @@ -0,0 +1,29 @@ +kind: ServiceAccount +apiVersion: v1 +metadata: + name: vsphere-csi-node + namespace: kube-system +--- +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: vsphere-csi-node-role + namespace: kube-system +rules: + - apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "list", "watch"] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: vsphere-csi-node-binding + namespace: kube-system +subjects: + - kind: ServiceAccount + name: vsphere-csi-node + namespace: kube-system +roleRef: + kind: Role + name: vsphere-csi-node-role + apiGroup: rbac.authorization.k8s.io