This feature is available for BYOC Pro clusters only with trusted mode enabled. To enable trusted mode, submit a support ticket through StreamNative support.
BYOC Pro users can build and use custom runner images for Pulsar functions and IO connectors when trusted mode is enabled. This capability provides the following benefits:
  • Include custom dependencies and libraries
  • Use specific versions of runtime environments
  • Customize the execution environment for your workloads
  • Package application-specific configurations
Custom runner images provide low-level control over the execution environment. Incorrect image configuration affects the normal operation of Pulsar functions and IO connectors. Test thoroughly in development environments before deploying to production.

Prerequisites

  • BYOC Pro cluster with trusted mode enabled
  • Docker installed and configured
  • Access to a Docker registry (Docker Hub, private registry, etc.)
  • Basic understanding of Dockerfile syntax and container concepts

Base Images

StreamNative provides official base images for different runtime environments:

Java Functions

FROM streamnative/pulsar-functions-pulsarctl-java-runner:4.0.5.2

Python Functions

FROM streamnative/pulsar-functions-pulsarctl-python-runner:4.0.5.2
Use the appropriate base image version that matches your StreamNative Cloud cluster version. Check the release notes for compatibility information.

Building Custom Images

1. Create Dockerfile

Create a Dockerfile that extends the StreamNative base image:
FROM streamnative/pulsar-functions-pulsarctl-java-runner:4.0.5.2

# Install additional system packages if needed
USER root
RUN apt-get update && apt-get install -y your-package
USER $UID
# Copy your function JAR and dependencies
COPY --chown=$UID:$GID example-function.jar /pulsar/
COPY --chown=$UID:$GID dependencies/ /pulsar/lib/
Always use --chown=$UID:$GID when copying files. The $UID and $GID environment variables are provided by StreamNative base images and ensure proper file permissions. Do not change these values.

2. Build and Push Image

# Build the Docker image
docker build -t your-registry/custom-function:v1.0 .

# Push to your registry
docker push your-registry/custom-function:v1.0

3. Deploy Function with Custom Image

Use the runnerImage parameter in custom-runtime-options:
snctl pulsar admin functions create \
  --tenant your-tenant \
  --namespace your-namespace \
  --name custom-function \
  --jar example-function.jar \
  --classname com.example.MyFunction \
  --inputs input-topic \
  --output output-topic \
  --custom-runtime-options '{"runnerImage": "your-registry/custom-function:v1.0"}'

Examples

Java Function with Custom Dependencies

FROM streamnative/pulsar-functions-pulsarctl-java-runner:4.0.5.2

# Copy function JAR and custom dependencies
COPY --chown=$UID:$GID target/my-function.jar /pulsar/
COPY --chown=$UID:$GID target/lib/*.jar /pulsar/lib/

# Copy additional configuration files
COPY --chown=$UID:$GID config/logging.properties /pulsar/conf/

Configuration with Other Trusted Mode Options

Combine custom images with other trusted mode configurations:
{
  "runnerImage": "your-registry/custom-function:v1.0",
  "javaOPTs": ["-Dmy.custom.config=value"]
}

Best Practices

Security

  • Use minimal base images to reduce attack surface
  • Scan images for vulnerabilities before deployment
  • Use private registries for proprietary code
  • Follow principle of least privilege for container permissions

Performance

  • Optimize image layers for efficient caching
  • Remove unnecessary files and packages
  • Use multi-stage builds for smaller final images
  • Consider image pull time in high-throughput scenarios

Maintenance

  • Tag images with semantic versions
  • Maintain compatibility with StreamNative base image updates
  • Document custom dependencies and configurations
  • Test images thoroughly before production deployment

Troubleshooting

Common Issues

Image Pull Failures
  • Verify registry credentials and access permissions
  • Check network connectivity from cluster to registry
  • Ensure image tag exists and is properly formatted
Permission Errors
  • Verify --chown=$UID:$GID is used for all COPY operations
  • Check that files have correct permissions within the image
  • Ensure service account has proper Kubernetes permissions
Runtime Failures
  • Validate base image compatibility with cluster version
  • Check that required dependencies are properly installed
  • Verify classpath and module path configurations
For additional troubleshooting support, contact StreamNative support with your custom image configuration details.