diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/K3s.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/K3s.kt index 12b5c37..e161e4c 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/K3s.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/K3s.kt @@ -119,7 +119,7 @@ fun Prov.installK3s(k3sConfig: K3sConfig): ProvResult { } applyK3sFileFromResource(localPathProvisionerConfig) - // TODO: jem 2022-11-25: Why do we need sudo here?? + cmd("kubectl set env deployment -n kube-system local-path-provisioner DEPLOY_DATE=\"$(date)\"", sudo = true) cmd("ln -sf $k3sKubeConfig " + k8sCredentialsDir + "admin.conf", sudo = true) diff --git a/src/main/resources/org/domaindrivenarchitecture/provs/server/infrastructure/k3s/metallb-0.10.2-manifest.yaml b/src/main/resources/org/domaindrivenarchitecture/provs/server/infrastructure/k3s/metallb-0.10.2-manifest.yaml deleted file mode 100644 index 9d6b683..0000000 --- a/src/main/resources/org/domaindrivenarchitecture/provs/server/infrastructure/k3s/metallb-0.10.2-manifest.yaml +++ /dev/null @@ -1,480 +0,0 @@ -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - labels: - app: metallb - name: controller -spec: - allowPrivilegeEscalation: false - allowedCapabilities: [] - allowedHostPaths: [] - defaultAddCapabilities: [] - defaultAllowPrivilegeEscalation: false - fsGroup: - ranges: - - max: 65535 - min: 1 - rule: MustRunAs - hostIPC: false - hostNetwork: false - hostPID: false - privileged: false - readOnlyRootFilesystem: true - requiredDropCapabilities: - - ALL - runAsUser: - ranges: - - max: 65535 - min: 1 - rule: MustRunAs - seLinux: - rule: RunAsAny - supplementalGroups: - ranges: - - max: 65535 - min: 1 - rule: MustRunAs - volumes: - - configMap - - secret - - emptyDir ---- -apiVersion: policy/v1beta1 -kind: PodSecurityPolicy -metadata: - labels: - app: metallb - name: speaker -spec: - allowPrivilegeEscalation: false - allowedCapabilities: - - NET_RAW - allowedHostPaths: [] - defaultAddCapabilities: [] - defaultAllowPrivilegeEscalation: false - fsGroup: - rule: RunAsAny - hostIPC: false - hostNetwork: true - hostPID: false - hostPorts: - - max: 7472 - min: 7472 - - max: 7946 - min: 7946 - privileged: true - readOnlyRootFilesystem: true - requiredDropCapabilities: - - ALL - runAsUser: - rule: RunAsAny - seLinux: - rule: RunAsAny - supplementalGroups: - rule: RunAsAny - volumes: - - configMap - - secret - - emptyDir ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app: metallb - name: controller - namespace: metallb-system ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app: metallb - name: speaker - namespace: metallb-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app: metallb - name: metallb-system:controller -rules: -- apiGroups: - - '' - resources: - - services - verbs: - - get - - list - - watch -- apiGroups: - - '' - resources: - - services/status - verbs: - - update -- apiGroups: - - '' - resources: - - events - verbs: - - create - - patch -- apiGroups: - - policy - resourceNames: - - controller - resources: - - podsecuritypolicies - verbs: - - use ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app: metallb - name: metallb-system:speaker -rules: -- apiGroups: - - '' - resources: - - services - - endpoints - - nodes - verbs: - - get - - list - - watch -- apiGroups: ["discovery.k8s.io"] - resources: - - endpointslices - verbs: - - get - - list - - watch -- apiGroups: - - '' - resources: - - events - verbs: - - create - - patch -- apiGroups: - - policy - resourceNames: - - speaker - resources: - - podsecuritypolicies - verbs: - - use ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app: metallb - name: config-watcher - namespace: metallb-system -rules: -- apiGroups: - - '' - resources: - - configmaps - verbs: - - get - - list - - watch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app: metallb - name: pod-lister - namespace: metallb-system -rules: -- apiGroups: - - '' - resources: - - pods - verbs: - - list ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app: metallb - name: controller - namespace: metallb-system -rules: -- apiGroups: - - '' - resources: - - secrets - verbs: - - create -- apiGroups: - - '' - resources: - - secrets - resourceNames: - - memberlist - verbs: - - list -- apiGroups: - - apps - resources: - - deployments - resourceNames: - - controller - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app: metallb - name: metallb-system:controller -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: metallb-system:controller -subjects: -- kind: ServiceAccount - name: controller - namespace: metallb-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app: metallb - name: metallb-system:speaker -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: metallb-system:speaker -subjects: -- kind: ServiceAccount - name: speaker - namespace: metallb-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app: metallb - name: config-watcher - namespace: metallb-system -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: config-watcher -subjects: -- kind: ServiceAccount - name: controller -- kind: ServiceAccount - name: speaker ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app: metallb - name: pod-lister - namespace: metallb-system -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: pod-lister -subjects: -- kind: ServiceAccount - name: speaker ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app: metallb - name: controller - namespace: metallb-system -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: controller -subjects: -- kind: ServiceAccount - name: controller ---- -apiVersion: apps/v1 -kind: DaemonSet -metadata: - labels: - app: metallb - component: speaker - name: speaker - namespace: metallb-system -spec: - selector: - matchLabels: - app: metallb - component: speaker - template: - metadata: - annotations: - prometheus.io/port: '7472' - prometheus.io/scrape: 'true' - labels: - app: metallb - component: speaker - spec: - containers: - - args: - - --port=7472 - - --config=config - - --log-level=info - env: - - name: METALLB_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: METALLB_HOST - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: METALLB_ML_BIND_ADDR - valueFrom: - fieldRef: - fieldPath: status.podIP - # needed when another software is also using memberlist / port 7946 - # when changing this default you also need to update the container ports definition - # and the PodSecurityPolicy hostPorts definition - #- name: METALLB_ML_BIND_PORT - # value: "7946" - - name: METALLB_ML_LABELS - value: "app=metallb,component=speaker" - - name: METALLB_ML_SECRET_KEY - valueFrom: - secretKeyRef: - name: memberlist - key: secretkey - image: quay.io/metallb/speaker:v0.12.1 - name: speaker - ports: - - containerPort: 7472 - name: monitoring - - containerPort: 7946 - name: memberlist-tcp - - containerPort: 7946 - name: memberlist-udp - protocol: UDP - livenessProbe: - httpGet: - path: /metrics - port: monitoring - initialDelaySeconds: 10 - periodSeconds: 10 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 3 - readinessProbe: - httpGet: - path: /metrics - port: monitoring - initialDelaySeconds: 10 - periodSeconds: 10 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 3 - securityContext: - allowPrivilegeEscalation: false - capabilities: - add: - - NET_RAW - drop: - - ALL - readOnlyRootFilesystem: true - hostNetwork: true - nodeSelector: - kubernetes.io/os: linux - serviceAccountName: speaker - terminationGracePeriodSeconds: 2 - tolerations: - - effect: NoSchedule - key: node-role.kubernetes.io/master - operator: Exists ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: metallb - component: controller - name: controller - namespace: metallb-system -spec: - revisionHistoryLimit: 3 - selector: - matchLabels: - app: metallb - component: controller - template: - metadata: - annotations: - prometheus.io/port: '7472' - prometheus.io/scrape: 'true' - labels: - app: metallb - component: controller - spec: - containers: - - args: - - --port=7472 - - --config=config - - --log-level=info - env: - - name: METALLB_ML_SECRET_NAME - value: memberlist - - name: METALLB_DEPLOYMENT - value: controller - image: quay.io/metallb/controller:v0.12.1 - name: controller - ports: - - containerPort: 7472 - name: monitoring - livenessProbe: - httpGet: - path: /metrics - port: monitoring - initialDelaySeconds: 10 - periodSeconds: 10 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 3 - readinessProbe: - httpGet: - path: /metrics - port: monitoring - initialDelaySeconds: 10 - periodSeconds: 10 - timeoutSeconds: 1 - successThreshold: 1 - failureThreshold: 3 - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - all - readOnlyRootFilesystem: true - nodeSelector: - kubernetes.io/os: linux - securityContext: - runAsNonRoot: true - runAsUser: 65534 - fsGroup: 65534 - serviceAccountName: controller - terminationGracePeriodSeconds: 0 diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/K3sKtTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/K3sKtTest.kt index 85296de..60405a1 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/K3sKtTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/server/infrastructure/K3sKtTest.kt @@ -5,7 +5,6 @@ import org.domaindrivenarchitecture.provs.framework.core.local import org.domaindrivenarchitecture.provs.framework.core.remote import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createDir import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createSecretFile -import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.fileContent import org.domaindrivenarchitecture.provs.framework.ubuntu.secret.secretSources.PromptSecretSource import org.domaindrivenarchitecture.provs.server.domain.k3s.K3sConfig import org.domaindrivenarchitecture.provs.server.domain.k3s.Node @@ -18,14 +17,14 @@ import java.lang.Thread.sleep class K3sKtTest { @Test // Extensive test, takes several minutes - @Disabled("update remoteIp and user and run manually") + @Disabled("1. update remoteIp and user, 2. enable remote ssh connection and 3. enable this test and then 4. run manually") fun installK3s() { // given - val remoteHostIp = "192.168.56.146" + val remoteIp = "192.168.56.146" val user = "xxx" - // enable ssh connection either manually or by the commented-out code below to copy local authorized_keys to remote -// remote(remoteHostIp, user, PromptSecretSource("PW for $user on $remoteHostIp").secret()).task { + // enable remote ssh connection either manually or by the commented-out code below to copy local authorized_keys to remote +// remote(remoteIp, user, PromptSecretSource("PW for $user on $remoteIp").secret()).task { // val authorizedKeysFilename = ".ssh/authorized_keys" // val publicSshKey = local().getSecret("cat $authorizedKeysFilename") ?: Secret("") // or set directly by: val publicSshKey = Secret("public ssh key") // createDir(".ssh") @@ -33,8 +32,8 @@ class K3sKtTest { // } // when - val res = remote(remoteHostIp, user).task { // connect by ssh - provisionK3s(K3sConfig(remoteHostIp, Node(remoteHostIp), echo = true, reprovision = false)) + val res = remote(remoteIp, user).task { // connect by ssh + provisionK3s(K3sConfig(remoteIp, Node(remoteIp), echo = true, reprovision = false)) } // then @@ -42,8 +41,8 @@ class K3sKtTest { // check response echo pod sleep(10000) // if time too short, increase or check curl manually - val echoResponse = local().cmd("curl http://$remoteHostIp/echo/").out + val echoResponse = local().cmd("curl http://$remoteIp/echo/").out assertTrue(echoResponse?.contains("Hostname: echo-app") ?: false) - assertTrue(echoResponse?.contains("Host: $remoteHostIp") ?: false) + assertTrue(echoResponse?.contains("Host: $remoteIp") ?: false) } }