Skip to content

Commit

Permalink
make wrapper server work with distroless-based images (#3070)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mengqi Yu committed Apr 30, 2022
1 parent f454d9a commit 236b74f
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 31 deletions.
10 changes: 7 additions & 3 deletions porch/config/deploy/2-function-runner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,13 @@ spec:
image: gcr.io/example-google-project-id/porch-function-runner:latest
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- /server --config=/config.yaml --functions=/functions --pod-namespace=porch-fn-system --wrapper-server-image=gcr.io/example-google-project-id/porch-wrapper-server:latest
- /server
- --config=/config.yaml
- --functions=/functions
- --pod-namespace=porch-fn-system
env:
- name: WRAPPER_SERVER_IMAGE
value: gcr.io/example-google-project-id/porch-wrapper-server:latest
ports:
- containerPort: 9445
# Add grpc readiness probe to ensure the cache is ready
Expand Down
3 changes: 3 additions & 0 deletions porch/func/Dockerfile-wrapperserver
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ FROM golang:1.17.8-alpine3.15 as builder

WORKDIR /go/src/github.com/GoogleContainerTools/kpt

# Ensure the wrapper server and grpc-health-probe is statically linked so that they works in distroless-based images.
ENV CGO_ENABLED=0

COPY go.mod go.sum ./
COPY porch/go.mod porch/go.sum porch/
COPY porch/api/go.mod porch/api/go.sum porch/api/
Expand Down
24 changes: 12 additions & 12 deletions porch/func/internal/podevaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,12 @@ func (pcm *podCacheManager) podCacheManager() {
channels := pcm.waitlists[resp.image]
delete(pcm.waitlists, resp.image)
for i := range channels {
// The channel has one buffer size, nothing will be blocking.
channels[i] <- &clientConnAndError{
grpcClient: resp.grpcClient,
err: resp.err,
cce := &clientConnAndError{err: resp.err}
if resp.podAndGRPCClient != nil {
cce.grpcClient = resp.podAndGRPCClient.grpcClient
}
// The channel has one buffer size, nothing will be blocking.
channels[i] <- cce
}
case <-tick:
// synchronous GC
Expand Down Expand Up @@ -497,8 +498,10 @@ func (pm *podManager) retrieveOrCreatePod(ctx context.Context, image string, ttl
Name: "copy-wrapper-server",
Image: pm.wrapperServerImage,
Command: []string{
"sh", "-c",
fmt.Sprintf("cp /wrapper-server/* %v", volumeMountPath),
"cp",
"-a",
"/wrapper-server/.",
volumeMountPath,
},
VolumeMounts: []corev1.VolumeMount{
{
Expand All @@ -510,12 +513,9 @@ func (pm *podManager) retrieveOrCreatePod(ctx context.Context, image string, ttl
},
Containers: []corev1.Container{
{
Name: "function",
Image: image,
Command: []string{
"sh", "-c",
strings.Join(cmd, " "),
},
Name: "function",
Image: image,
Command: cmd,
ReadinessProbe: &corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{
Expand Down
25 changes: 15 additions & 10 deletions porch/func/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,19 @@ import (
const (
execRuntime = "exec"
podRuntime = "pod"

wrapperServerImageEnv = "WRAPPER_SERVER_IMAGE"
)

var (
port = flag.Int("port", 9445, "The server port")
functions = flag.String("functions", "./functions", "Path to cached functions.")
config = flag.String("config", "./config.yaml", "Path to the config file.")
podCacheConfig = flag.String("pod-cache-config", "/pod-cache-config/pod-cache-config.yaml", "Path to the pod cache config file. The file is map of function name to TTL.")
podNamespace = flag.String("pod-namespace", "porch-fn-system", "Namespace to run KRM functions pods.")
podTTL = flag.Duration("pod-ttl", 30*time.Minute, "TTL for pods before GC.")
scanInterval = flag.Duration("scan-interval", time.Minute, "The interval of GC between scans.")
wrapperServerImage = flag.String("wrapper-server-image", "", "Image name of the wrapper server.")
disableRuntimes = flag.String("disable-runtimes", "", fmt.Sprintf("The runtime(s) to disable. Multiple runtimes should separated by `,`. Available runtimes: `%v`, `%v`.", execRuntime, podRuntime))
port = flag.Int("port", 9445, "The server port")
functions = flag.String("functions", "./functions", "Path to cached functions.")
config = flag.String("config", "./config.yaml", "Path to the config file.")
podCacheConfig = flag.String("pod-cache-config", "/pod-cache-config/pod-cache-config.yaml", "Path to the pod cache config file. The file is map of function name to TTL.")
podNamespace = flag.String("pod-namespace", "porch-fn-system", "Namespace to run KRM functions pods.")
podTTL = flag.Duration("pod-ttl", 30*time.Minute, "TTL for pods before GC.")
scanInterval = flag.Duration("scan-interval", time.Minute, "The interval of GC between scans.")
disableRuntimes = flag.String("disable-runtimes", "", fmt.Sprintf("The runtime(s) to disable. Multiple runtimes should separated by `,`. Available runtimes: `%v`, `%v`.", execRuntime, podRuntime))
)

func main() {
Expand Down Expand Up @@ -83,7 +84,11 @@ func run() error {
}
runtimes = append(runtimes, execEval)
case podRuntime:
podEval, err := internal.NewPodEvaluator(*podNamespace, *wrapperServerImage, *scanInterval, *podTTL, *podCacheConfig)
wrapperServerImage := os.Getenv(wrapperServerImageEnv)
if wrapperServerImage == "" {
return fmt.Errorf("environment variable %v must be set to use pod function evaluator runtime", wrapperServerImageEnv)
}
podEval, err := internal.NewPodEvaluator(*podNamespace, wrapperServerImage, *scanInterval, *podTTL, *podCacheConfig)
if err != nil {
return fmt.Errorf("failed to initialize pod evaluator: %w", err)
}
Expand Down
28 changes: 22 additions & 6 deletions porch/hack/create-deployment-blueprint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,30 @@ function customize-image {
"newTag=${TAG}"
}

function customize-image-in-command {
function customize-image-in-env {
local OLD="${1}"
local NEW="${2}"
local TAG="${NEW##*:}"
local IMG="${NEW%:*}"

cat > set-image-config.yaml << EOF
apiVersion: fn.kpt.dev/v1alpha1
kind: SetImage
metadata:
name: my-func-config
image:
name: ${OLD}
newName: ${IMG}
newTag: ${TAG}
additionalImageFields:
- group: apps
version: v1
kind: Deployment
path: spec/template/spec/containers[]/env[]/value
EOF

kpt fn eval "${DESTINATION}" --image search-replace:v0.2.0 -- \
"by-path=spec.template.spec.containers[*].command[*]" \
"by-value-regex=(.*)${OLD}" \
"put-value=\${1}${NEW}"
kpt fn eval "${DESTINATION}" --image set-image:v0.1.0 --fn-config set-image-config.yaml
rm set-image-config.yaml
}

function customize-sa {
Expand Down Expand Up @@ -170,7 +186,7 @@ function main() {
customize-image \
"gcr.io/example-google-project-id/porch-controllers:latest" \
"${CONTROLLERS_IMAGE}"
customize-image-in-command \
customize-image-in-env \
"gcr.io/example-google-project-id/porch-wrapper-server:latest" \
"${WRAPPER_SERVER_IMAGE}"

Expand Down

0 comments on commit 236b74f

Please sign in to comment.