diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/404.html b/404.html new file mode 100644 index 0000000000..9ee8cd3a8a --- /dev/null +++ b/404.html @@ -0,0 +1,1060 @@ + + + +
+ + + + + + + + + + + + + + + + + +ldflags
?Using -ldflags is a common way to embed version info in go binaries (In fact, we do this for ko
!).
+Unfortunately, because ko
wraps go build
, it's not possible to use this flag directly; however, you can use the GOFLAGS
environment variable instead:
Currently, there is a limitation that does not allow to set multiple arguments in ldflags
using GOFLAGS
.
+Using -ldflags
multiple times also does not work.
+In this use case, it works best to use the builds
section in the .ko.yaml
file.
In order to support reproducible builds, ko
doesn't embed timestamps in the images it produces by default.
However, ko
does respect the SOURCE_DATE_EPOCH
environment variable, which will set the container image's timestamp accordingly.
Similarly, the KO_DATA_DATE_EPOCH
environment variable can be used to set the modtime timestamp of the files in KO_DATA_PATH
.
For example, you can set the container image's timestamp to the current timestamp by executing:
+ +or set the timestamp of the files in KO_DATA_PATH
to the latest git commit's timestamp with:
Yes, but support for Windows containers is new, experimental, and tenuous. Be prepared to file bugs. 🐛
+The default base image does not provide a Windows image.
+You can try out building a Windows container image by setting the base image to a Windows base image and building with --platform=windows/amd64
or --platform=all
:
For example, to build a Windows container image, update your .ko.yaml
to set the base image:
And build for windows/amd64
.
kodata
are ignored when building Windows images; only regular files and directories will be included in the Windows image.ko
support autocompletion?Yes! ko completion
generates a Bash/Zsh/Fish/PowerShell completion script.
+You can get how to load it from help document.
Or, you can source it directly:
+ +ko
work with Kustomize?Yes! ko resolve -f -
will read and process input from stdin, so you can have ko
easily process the output of the kustomize
command.
ko
integrate with other build and development tools?Oh, you betcha. Here's a partial list:
+ko
support in Skaffoldko
support for goreleaserko
task in the Tekton catalogko
support in Carvel's kbld
ko
extension for Tiltko
work with OpenShift Internal Registry?Yes! Follow these steps:
+$HOME/.docker/config.json
:ko-images
KO_DOCKER_REPO
to publish images to the internal registry.ko
's functionality can be consumed as a library in a Go application.
To build an image, use pkg/build
, and publish it with pkg/publish
.
This is a minimal example of using the packages together, to implement the core subset of ko
's functionality:
package main
+
+import (
+ "context"
+ "fmt"
+ "log"
+
+ "github.com/google/go-containerregistry/pkg/authn"
+ "github.com/google/go-containerregistry/pkg/name"
+ "github.com/google/go-containerregistry/pkg/v1/remote"
+ "github.com/google/ko/pkg/build"
+ "github.com/google/ko/pkg/publish"
+)
+
+const (
+ baseImage = "cgr.dev/chainguard/static:latest"
+ targetRepo = "example.registry/my-repo"
+ importpath = "github.com/my-org/miniko"
+ commitSHA = "deadbeef"
+)
+
+func main() {
+ ctx := context.Background()
+
+ b, err := build.NewGo(ctx, ".",
+ build.WithPlatforms("linux/amd64"), // only build for these platforms.
+ build.WithBaseImages(func(ctx context.Context, _ string) (name.Reference, build.Result, error) {
+ ref := name.MustParseReference(baseImage)
+ base, err := remote.Index(ref, remote.WithContext(ctx))
+ return ref, base, err
+ }))
+ if err != nil {
+ log.Fatalf("NewGo: %v", err)
+ }
+ r, err := b.Build(ctx, importpath)
+ if err != nil {
+ log.Fatalf("Build: %v", err)
+ }
+
+ p, err := publish.NewDefault(targetRepo, // publish to example.registry/my-repo
+ publish.WithTags([]string{commitSHA}), // tag with :deadbeef
+ publish.WithAuthFromKeychain(authn.DefaultKeychain)) // use credentials from ~/.docker/config.json
+ if err != nil {
+ log.Fatalf("NewDefault: %v", err)
+ }
+ ref, err := p.Publish(ctx, r, importpath)
+ if err != nil {
+ log.Fatalf("Publish: %v", err)
+ }
+ fmt.Println(ref.String())
+}
+
ko
can build images that can be deployed as AWS Lambda functions, using Lambda's container support.
For best results, use the Go runtime interface client provided by the lambda
package.
For example:
+package main
+
+import (
+ "context"
+ "fmt"
+ "github.com/aws/aws-lambda-go/lambda"
+)
+
+type Event struct {
+ Name string `json:"name"`
+ // TODO: add other request fields here.
+}
+
+func main() {
+ lambda.Start(func(ctx context.Context, event Event) (string, error) {
+ return fmt.Sprintf("Hello %s!", event.Name), nil
+ })
+}
+
See AWS's documentation for more information on writing Lambda functions in Go.
+To deploy to Lambda, you must push to AWS Elastic Container Registry (ECR):
+ +Then, create a Lambda function using the image in ECR:
+aws lambda create-function \
+ --function-name hello-world \
+ --package-type Image \
+ --code ImageUri=${image} \
+ --role arn:aws:iam::[account-id]:role/lambda-ex
+
See AWS's documentation for more information on deploying Lambda functions using Go container images, including how to configure push access to ECR, and how to configure the IAM role for the function.
+The base image that ko
uses by default supports both x86 and Graviton2 architectures.
You can also use the ko
Terraform provider to build and deploy Lambda functions as part of your IaC workflow, using the aws_lambda_function
resource. See the provider example to get started.
ko
works best when your application has no dependencies on the underlying image.
This means ko
is ideal when you don't require cgo, and builds are executed with CGO_ENABLED=0
by default.
To install other OS packages, make those available in your configured base image.
+ko
only supports Go applications.
+For a similar tool targeting Java applications, try Jib.
+For other languages, try apko and melange.
In Linux, capabilities are a way to selectively grant privileges to a running process.
+Docker provides --cap-add
and --cap-drop
+run options
+to tweak container capabilities, e.g:
If container runs as a non-root user,
+capabilities are narrowed by intersecting with file capabilities of the
+application binary. When building images with a Dockerfile, one
+typically uses setcap
tool to modify file capabilities, e.g:
+setcap FILE bpf=ep
.
To set file capabilities with ko
, specify linux_capabilities
+in builds configuration section in your .ko.yaml
. Use setcap
syntax:
A list of capability names is equivalent to cap1,cap2,cap3=p
.
A capability can be permitted (=p
), or both permitted and effective (=ep
).
+Effective capabilities are used for permission checks.
+A program can promote permitted capability to effective when needed.
Initially, =ep
might look like a good idea.
+There's no need to explicitly promote permitted capabilities.
+Application takes advantage of effective capabilities right away.
There is a catch though.
+$ docker run --cap-add bpf ko.local/caps.test-4b8f7bca75c467b3d2803e1c087a3287
+exec /ko-app/caps.test: operation not permitted
+
When run options request fewer capabilities than specified in file capabilities,
+container fails to start. It is hard to tell what went wrong since
+operation not permitted
is a generic error. (Docker is unlikely to improve diagnostics
+for this failure case since the check is implemented in Linux kernel.)
We suggest to use =p
instead. This option puts application in charge of verifying and
+promoting permitted capabilities to effective. It can produce much better diagnostics:
If your Dockerfile
looks like either of the examples in the official tutorial for writing a Dockerfile to containerize a Go application, you can easily migrate to use ko
instead.
Let's review the best practice multi-stage Dockerfile in that tutorial first:
+# syntax=docker/dockerfile:1
+
+##
+## Build
+##
+FROM golang:1.16-buster AS build
+
+WORKDIR /app
+
+COPY go.mod ./
+COPY go.sum ./
+RUN go mod download
+
+COPY *.go ./
+
+RUN go build -o /docker-gs-ping
+
+##
+## Deploy
+##
+FROM gcr.io/distroless/base-debian10
+
+WORKDIR /
+
+COPY --from=build /docker-gs-ping /docker-gs-ping
+
+EXPOSE 8080
+
+USER nonroot:nonroot
+
+ENTRYPOINT ["/docker-gs-ping"]
+
This Dockerfile
:
golang:1.16
imageCOPY
s your local source into the container environment (COPY
ing go.mod
and go.sum
first and running go mod download
, to cache dependencies in the container environment)RUN
s go build
on your source, inside the container, to produce an executableCOPY
s the executable built in the previous step into a new image, on top of a minimal distroless base image.The result is a Go application built on a minimal base image, with an optimally cached build sequence.
+After running docker build
on this Dockerfile
, don't forget to push that image to the registry so you can deploy it.
ko
If your Go source is laid out as described in the tutorial, and you've installed and set up your environment, you can simply run ko build ./
to build and push the container image to your registry.
You're done. You can delete your Dockerfile
and uninstall docker
.
ko
takes advantage of your local Go build cache without needing to be told to, and it sets the ENTRYPOINT
and uses a nonroot distroless base image by default.
To build a multi-arch image, simply add --platform=all
.
+Compare this to the equivalent Docker instructions.
To install a root certificate into your container built using ko
, you can use one of the following methods.
incert
allows you to append CA certificates to an image and push the modified image to a specified registry.
incert
can be run after ko build
to build your Go application container image with custom root CA certificates.
Build and push your Go application container image using ko build
+
Append the built image with your custom CA certificate(s) using incert
+
New root certificates can be installed into a custom image using standard OS packages. Then, this custom image can be used to override the base image for ko
. Once the Go application container image is built using ko
with the custom base image, the root certificates installed on the base image will be trusted by the Go application.
Make a custom container image with your new root certificates +
+Build and push the custom container image to a container registry +
+Configure ko
to override the default base image with the custom image
+
OR +
+Build the Go app container image with ko
+
Alternatively, root certificates can be installed into the Go application container image using a combination of ko
static assets and overriding the default system location for SSL certificates.
Using ko
's support for static assets, root certificates can be stored in the <importpath>/kodata
directory (either checked into the repository, or injected dynamically by a CI pipeline). After running ko build
, the certificate files are then bundled into the built image at the path $KO_DATA_PATH
.
To enable the Go application to trust the bundled certificate(s), the container runtime or orchestrator (Docker, Kubernetes, etc) must set the environment variable SSL_CERT_DIR
to the same value as KO_DATA_PATH
. Go uses SSL_CERT_DIR
to determine the directory to check for SSL certificate files. Once this variable is set, the Go application will trust the bundled root certificates in $KO_DATA_PATH
.
Copy the root certificate(s) to the <importpath>/kodata/
directory
+
Build the Go application container image +
+Run the Go application container image with SSL_CERT_DIR
equal to /var/run/ko
(the default value for $KO_DATA_PATH
)
+
A functional client-server example for this can be seen here.
+ + + + + + + + + + + + + +In addition to the CLI, ko
's functionality is also available as a Terraform provider.
This allows ko
to be integrated with your Infrastructure-as-Code (IaC) workflows, and makes building your code a seamless part of your deployment process.
Using the Terraform provider is as simple as adding a ko_build
resource to your Terraform configuration:
// Require the `ko-build/ko` provider.
+terraform {
+ required_providers {
+ ko = { source = "ko-build/ko" }
+ }
+}
+
+// Configure the provider to push to your repo.
+provider "ko" {
+ repo = "example.registry/my-repo" // equivalent to KO_DOCKER_REPO
+}
+
+// Build your code.
+resource "ko_build" "app" {
+ importpath = "github.com/example/repo/cmd/app"
+}
+
+// TODO: use the `ko_build.app` resource elsewhere in your Terraform configuration.
+
+// Report the build image's digest.
+output "image" {
+ value = ko_build.app.image_ref
+}
+
See the ko-build/ko
provider on the Terraform Registry for more information, and the GitHub repo for more examples.