diff --git a/.gitignore b/.gitignore index d52a43fb..23789ac3 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,4 @@ bin *~ # control-plane kubeconfig file -kubeconfig \ No newline at end of file +*kubeconfig \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 92bcf452..d098d54a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,6 @@ COPY main.go main.go COPY api/ api/ COPY controllers/ controllers/ COPY pkg/ pkg/ -COPY external.yaml external.yaml # Build RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager main.go @@ -24,6 +23,7 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager FROM gcr.io/distroless/static:nonroot WORKDIR / COPY --from=builder /workspace/manager . +COPY external.yaml external.yaml USER nonroot:nonroot ENTRYPOINT ["/manager"] diff --git a/Makefile b/Makefile index bc48dd5c..add3e4ee 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,7 @@ docker-build: docker-push: docker push ${IMG}:${VERSION} -kind-load-image: +kind-load-image: docker-build kind load docker-image ${IMG}:${VERSION} -v 1 # find or download controller-gen @@ -97,3 +97,14 @@ endif copy-external-yaml: kubectl apply -k github.com/zalando/postgres-operator/manifests --dry-run=client -o yaml > external.yaml sed 's/resourceVersion/# resourceVersion/' -i ./external.yaml + +secret: + @{ \ + NS="postgres-controller-system" ;\ + SECRET_DIR="postgreslet-secret" ;\ + kubectl create ns $$NS --dry-run=client --save-config -o yaml | kubectl apply -f - ;\ + if [ -d $$SECRET_DIR ]; then rm -fr $$SECRET_DIR; fi ;\ + mkdir $$SECRET_DIR ;\ + cp kubeconfig $$SECRET_DIR/controlplane-kubeconfig ;\ + kubectl create secret generic postgreslet -n $$NS --from-file $$SECRET_DIR/ --dry-run=client -o yaml | kubectl apply -f - ;\ + } \ No newline at end of file diff --git a/README.md b/README.md index 1508bd8d..baff7358 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,16 @@ A small controller which acts as a bridge between the zalando-postgres-operator ```bash # Create a local control-cluster. This step is optional if you already have a working kubeconfig/cluster -kind create cluster --name ctrl +# IMPORTANT: update the apiServerAddress to your needs so the service-cluster from down below can access the control-cluster. +kind create cluster --name ctrl --kubeconfig ./kubeconfig --config ctrl-cluster-config # Copy the kubeconfig of the control-cluster to the project folder and name it `kubeconfig`. -# When using kind as describe above, this file now uses our newly created kind-ctrl Cluster as current-context -cp ~/.kube/config ./kubeconfig +# When using kind as describe above, this file was already created +# cp ./kubeconfig # Create a local service-cluster. This step is optional if you already have a working kubeconfig/cluster -# This step will no set the kind-svc as current context, which is important for the next step -kind create cluster --name svc +# This step will now set the kind as current context, which is important for the next step +kind create cluster # Build and install our CRD in the control-cluster. # This step uses the "external" kubeconfig we copied to ./kubeconfig earlier. This can be configured in the Makefile @@ -38,3 +39,15 @@ kubectl --kubeconfig kubeconfig delete -f config/samples/database_v1_postgres.ya # Uninstall the dependencies of this project from the remote control-cluster. make uninstall ``` + +## Install a local kubeconfig as secret in the cluster + +The following steps will create a _Secret_ called `postgreslet`, and add all files in the folder as keys to that secret. + +As we only copy one file, the secret will contain only one key named `controlplane-kubeconfig` which will contain the control plane kube config. + +```sh +make kind-load-image +make secret +make deploy +``` diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 4645a5e0..48edb22b 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -39,6 +39,9 @@ patchesStrategicMerge: # 'CERTMANAGER' needs to be enabled to use ca injection #- webhookcainjection_patch.yaml +# Mount the controlplane kube config file from a secret. +- manager_secret_patch.yaml + # the following config is for teaching kustomize how to do var substitution vars: # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml index 21506fdb..e4031a5c 100644 --- a/config/default/manager_auth_proxy_patch.yaml +++ b/config/default/manager_auth_proxy_patch.yaml @@ -1,4 +1,4 @@ -# This patch inject a sidecar container which is a HTTP proxy for the +# This patch inject a sidecar container which is a HTTP proxy for the # controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. apiVersion: apps/v1 kind: Deployment @@ -20,7 +20,8 @@ spec: - containerPort: 8443 name: https - name: manager +# Todo: Do we need two kube-rbac-proxy? Since we have two metrics-addr. args: - - "--metrics-addr-svc-mgr=127.0.0.1:8081" - - "--metrics-addr-ctrl-mgr=127.0.0.1:8082" - - "--enable-leader-election" + - "--enable-leader-election=false" + - "--partition-id=sample-partition" + - "--tenant=sample-tenant" diff --git a/config/default/manager_secret_patch.yaml b/config/default/manager_secret_patch.yaml new file mode 100644 index 00000000..fc09b954 --- /dev/null +++ b/config/default/manager_secret_patch.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + volumeMounts: + - mountPath: /var/run/secrets/postgreslet + name: controlplane-kubeconfig + readOnly: true + volumes: + - name: controlplane-kubeconfig + secret: + secretName: postgreslet + items: + - key: controlplane-kubeconfig + path: kube/config + \ No newline at end of file diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 8ebba171..2e617066 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -4,5 +4,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: controller - newName: postgres-controller + newName: r.metal-stack.io/extensions/postgreslet newTag: latest diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 7aec68a1..2e3adb87 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -26,7 +26,9 @@ spec: - command: - /manager args: - - --enable-leader-election --partition-id sample-partition --tenant sample-tenant + - --enable-leader-election=false + - --partition-id=sample-partition + - --tenant=sample-tenant image: controller:latest imagePullPolicy: IfNotPresent name: manager diff --git a/config/rbac/role_binding.yaml b/config/rbac/role_binding.yaml index 5ab180be..151a64c2 100644 --- a/config/rbac/role_binding.yaml +++ b/config/rbac/role_binding.yaml @@ -10,3 +10,16 @@ subjects: - kind: ServiceAccount name: default namespace: system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cluster-admin-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: + - kind: ServiceAccount + name: default + namespace: system diff --git a/ctrl-cluster-config b/ctrl-cluster-config new file mode 100644 index 00000000..a736d8bc --- /dev/null +++ b/ctrl-cluster-config @@ -0,0 +1,4 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +networking: + apiServerAddress: 10.0.0.13 \ No newline at end of file diff --git a/main.go b/main.go index d9d140be..e79806db 100644 --- a/main.go +++ b/main.go @@ -60,7 +60,7 @@ func main() { "Enabling this will ensure there is only one active controller manager.") flag.StringVar(&partitionID, "partition-id", "", "The partition ID of the worker-cluster.") flag.StringVar(&tenant, "tenant", "", "The tenant name.") - flag.StringVar(&ctrlClusterKubeconfig, "controlplane-kubeconfig", "", "The path to the kubeconfig to talk to the control plane") + flag.StringVar(&ctrlClusterKubeconfig, "controlplane-kubeconfig", "/var/run/secrets/postgreslet/kube/config", "The path to the kubeconfig to talk to the control plane") flag.Parse() ctrl.SetLogger(zap.New(zap.UseDevMode(true)))