Skip to content

Commit

Permalink
feature: Add configuretion to run setup/teardown command in helper co…
Browse files Browse the repository at this point in the history
…ntainer instead of run with script

(cherry picked from commit a4c1f74)
  • Loading branch information
name212 authored and derekbit committed Nov 19, 2023
1 parent 233b35e commit 5895d2d
Show file tree
Hide file tree
Showing 14 changed files with 402 additions and 24 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ data:
"node":"yasker-lp-dev3",
"paths":[]
}
]
],
"setupCommand": "/manager",
"teardownCommand": "/manager"
}
setup: |-
#!/bin/sh
Expand Down Expand Up @@ -200,6 +202,16 @@ In addition `volumeBindingMode: Immediate` can be used in StorageClass definiti

Please note that `nodePathMap` and `sharedFileSystemPath` are mutually exclusive. If `sharedFileSystemPath` is used, then `nodePathMap` must be set to `[]`.

The `setupCommand` and `teardownCommand` allow you to specify the path to binary files in helperPod that will be called when creating or deleting pvc respectively. This can be useful if you need to use distroless images for security reasons. See the examples/distroless directory for an example. A binary file can take the following parameters:
| Parameter | Description |
| -------------------- | ----------- |
| -p | Volume directory that should be created or removed. | -m | -p | Volume directory that should be created or removed. |
| -m | The PersistentVolume mode (`Block` or `Filesystem`). | -m | The PersistentVolume mode (`Block` or `Filesystem`). |
| -s | Requested volume size in bytes. | -s | Requested volume size in bytes. |
| -a | Action type. Can be `create` or `delete` | -a | -a | Action type.

The `setupCommand` and `teardownCommand` have higher priority than the `setup` and `teardown` scripts from the ConfigMap.

##### Rules
The configuration must obey following rules:
1. `config.json` must be a valid json file.
Expand Down
13 changes: 13 additions & 0 deletions examples/distroless/Dockerfile.helper
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM golang:1.17-alpine AS builder

COPY main.go /main.go
COPY go.mod /go.mod

RUN cd / && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-extldflags -static -s -w" -o /manager && \
chmod 777 /manager

FROM scratch

COPY --from=builder /manager /manager

ENTRYPOINT [ "/manager" ]
21 changes: 21 additions & 0 deletions examples/distroless/Dockerfile.provisioner
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM golang:1.17-alpine AS builder

ARG GIT_REPO
ARG GIT_BRANCH

RUN apk add --no-cache git

ENV GIT_REPO=$GIT_REPO
ENV GIT_BRANCH=$GIT_BRANCH

RUN mkdir /src && \
git clone --depth 1 --branch "${GIT_BRANCH}" "${GIT_REPO}" /src && \
cd /src && \
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-X main.VERSION=dev -extldflags -static -s -w" -o /local-path-provisioner && \
chmod 777 /local-path-provisioner

FROM scratch

COPY --from=builder /local-path-provisioner /local-path-provisioner

ENTRYPOINT [ "/local-path-provisioner" ]
2 changes: 2 additions & 0 deletions examples/distroless/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Overview
this is an example to use distroless image for local path provisioner
38 changes: 38 additions & 0 deletions examples/distroless/build_and_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash

set -e

source=$1
branch=$2

if [ -z "$source" ]; then
source="https://github.com/rancher/local-path-provisioner.git"
fi

if [ -z "$branch" ]; then
branch="master"
fi

docker build --build-arg="GIT_REPO=$source" --build-arg="GIT_BRANCH=$branch" -t lpp-distroless-provider:v0.0.1 -f Dockerfile.provisioner .

docker build -t lpp-distroless-helper:v0.0.1 -f Dockerfile.helper .

kind create cluster --config=kind.yaml --name test-lpp-distroless

kind load docker-image --name test-lpp-distroless lpp-distroless-provider:v0.0.1 lpp-distroless-provider:v0.0.1

kind load docker-image --name test-lpp-distroless lpp-distroless-helper:v0.0.1 lpp-distroless-helper:v0.0.1

kubectl apply -k .

echo "Waiting 30 seconds before deploy sts"

sleep 30

kubectl create -f sts.yaml

echo "Waiting 15 seconds before getting pv"

sleep 15

kubectl get pv
10 changes: 10 additions & 0 deletions examples/distroless/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"nodePathMap":[
{
"node":"DEFAULT_PATH_FOR_NON_LISTED_NODES",
"paths":["/opt/local-path-provisioner"]
}
],
"setupCommand": "/manager",
"teardownCommand": "/manager"
}
3 changes: 3 additions & 0 deletions examples/distroless/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module manager

go 1.17
9 changes: 9 additions & 0 deletions examples/distroless/helperPod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v1
kind: Pod
metadata:
name: helper-pod
spec:
containers:
- name: helper-pod
image: lpp-distroless-helper:v0.0.1
imagePullPolicy: IfNotPresent
5 changes: 5 additions & 0 deletions examples/distroless/kind.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
16 changes: 16 additions & 0 deletions examples/distroless/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- local-path-storage.yaml

configMapGenerator:
- name: local-path-config
namespace: local-path-storage
behavior: merge
files:
- helperPod.yaml
- config.json

generatorOptions:
disableNameSuffixHash: true
124 changes: 124 additions & 0 deletions examples/distroless/local-path-storage.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
apiVersion: v1
kind: Namespace
metadata:
name: local-path-storage

---
apiVersion: v1
kind: ServiceAccount
metadata:
name: local-path-provisioner-service-account
namespace: local-path-storage

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: local-path-provisioner-role
namespace: local-path-storage
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: local-path-provisioner-role
rules:
- apiGroups: [""]
resources: ["nodes", "persistentvolumeclaims", "configmaps", "pods"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "patch"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: local-path-provisioner-bind
namespace: local-path-storage
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: local-path-provisioner-role
subjects:
- kind: ServiceAccount
name: local-path-provisioner-service-account
namespace: local-path-storage

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: local-path-provisioner-bind
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: local-path-provisioner-role
subjects:
- kind: ServiceAccount
name: local-path-provisioner-service-account
namespace: local-path-storage

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: local-path-provisioner
namespace: local-path-storage
spec:
replicas: 1
selector:
matchLabels:
app: local-path-provisioner
template:
metadata:
labels:
app: local-path-provisioner
spec:
serviceAccountName: local-path-provisioner-service-account
containers:
- name: local-path-provisioner
image: lpp-distroless-provider:v0.0.1
imagePullPolicy: IfNotPresent
command:
- /local-path-provisioner
- --debug
- start
- --config
- /etc/config/config.json
volumeMounts:
- name: config-volume
mountPath: /etc/config/
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumes:
- name: config-volume
configMap:
name: local-path-config
---
kind: ConfigMap
apiVersion: v1
metadata:
name: local-path-config
namespace: local-path-storage
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-path
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete
63 changes: 63 additions & 0 deletions examples/distroless/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package main

import (
"flag"
"fmt"
"os"
"syscall"
)

var (
dirMode string
path string
sizeInBytes string
action string
)

const (
SETUP = "create"
TEARDOWN = "delete"
)

func init() {
flag.StringVar(&path, "p", "", "Absolute path")
flag.StringVar(&sizeInBytes, "s", "", "Size in bytes")
flag.StringVar(&dirMode, "m", "", "Dir mode")
flag.StringVar(&action, "a", "", fmt.Sprintf("Action name. Can be '%s' or '%s'", SETUP, TEARDOWN))
}

func main() {
flag.Parse()
if action != SETUP && action != TEARDOWN {
fmt.Fprintf(os.Stderr, "Incorrect action: %s\n", action)
os.Exit(1)
}

if path == "" {
fmt.Fprintf(os.Stderr, "Path is empty\n")
os.Exit(1)
}

if path == "/" {
fmt.Fprintf(os.Stderr, "Path cannot be '/'\n")
os.Exit(1)
}

if action == TEARDOWN {
err := os.RemoveAll(path)

if err != nil {
fmt.Fprintf(os.Stderr, "Cannot remove directory %s: %s\n", path, err)
os.Exit(1)
}
return
}

syscall.Umask(0)

err := os.MkdirAll(path, 0777)
if err != nil {
fmt.Fprintf(os.Stderr, "Cannot create directory %s: %s\n", path, err)
os.Exit(1)
}
}
33 changes: 33 additions & 0 deletions examples/distroless/sts.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: local-path
resources:
requests:
storage: 1Gi
Loading

0 comments on commit 5895d2d

Please sign in to comment.