Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: harden image using apko and wolfi #2697

Merged
merged 4 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -188,15 +188,31 @@ jobs:
build-image:
needs: [test-unit, lint-go, lint-charts, lint-proto, lint-ui, check-codegen]
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
- name: Build
with:
driver-opts: network=host
- name: Checkout code
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
- name: Build base image
run: |
BASE_IMAGE=localhost:5000/kargo-base make build-base-image
docker push localhost:5000/kargo-base:latest-arm64
docker push localhost:5000/kargo-base:latest-amd64
- name: Build final image
uses: docker/build-push-action@5176d81f87c23d6fc96624dfdbcd9f3830bbe445 # v6.5.0
with:
platforms: linux/amd64,linux/arm64
build-args: |
BASE_IMAGE=localhost:5000/kargo-base
push: false
cache-from: type=gha
cache-to: type=gha,mode=max
Expand Down
13 changes: 12 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ jobs:
packages: write # Used to push images to `ghcr.io`
id-token: write # Needed to create an OIDC token for keyless signing
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
outputs:
image-digest: ${{ steps.image.outputs.digest }}
kargo-repo: ${{ steps.repo.outputs.repo }}
Expand Down Expand Up @@ -67,12 +72,18 @@ jobs:
tags: |
type=semver,pattern={{raw}}
type=raw,value=${{ steps.unstable-version.outputs.unstable-version }},enable=${{ github.event_name != 'release'}}
- name: Build and push
- name: Build base image
run: |
BASE_IMAGE=localhost:5000/kargo-base make build-base-image
docker push localhost:5000/kargo-base:latest-arm64
docker push localhost:5000/kargo-base:latest-amd64
- name: Build and push final image
id: image
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
build-args: |
BASE_IMAGE=localhost:5000/kargo-base
VERSION=${{ github.ref_name }}
GIT_COMMIT=${{ github.sha }}
GIT_TREE_STATE=clean
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.pnpm-store/
.vscode/
bin/
build/
charts/kargo/*.tgz
coverage.txt
hack/include/
Expand Down
30 changes: 5 additions & 25 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
ARG BASE_IMAGE=kargo-base

####################################################################################################
# ui-builder
####################################################################################################
Expand Down Expand Up @@ -68,33 +70,16 @@ RUN GRPC_HEALTH_PROBE_VERSION=v0.4.15 && \
curl -fL -o /tools/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-${TARGETOS}-${TARGETARCH} && \
chmod +x /tools/grpc_health_probe

####################################################################################################
# base
# - install necessary packages
####################################################################################################
FROM ghcr.io/akuity/kargo-render:v0.1.0-rc.39 AS base

USER root

RUN apk update \
&& apk add ca-certificates gpg gpg-agent

COPY --from=tools /tools/ /usr/local/bin/

USER 1000:0

CMD ["/usr/local/bin/kargo"]

####################################################################################################
# back-end-dev
# - no UI
# - relies on go build that runs on host
# - supports development
# - not used for official image builds
####################################################################################################
FROM base AS back-end-dev
FROM alpine:3.20.3 AS back-end-dev

USER root
RUN apk update && apk add git gpg gpg-agent openssh-client

COPY bin/credential-helper /usr/local/bin/credential-helper
COPY bin/controlplane/kargo /usr/local/bin/kargo
Expand Down Expand Up @@ -129,14 +114,9 @@ CMD ["pnpm", "dev"]
# - the official image we publish
# - purposefully last so that it is the default target when building
####################################################################################################
FROM base AS final

USER root
FROM ${BASE_IMAGE}:latest-${TARGETARCH} AS final

COPY --from=back-end-builder /kargo/bin/ /usr/local/bin/
COPY --from=tools /tools/ /usr/local/bin/

RUN adduser -D -H -u 1000 kargo
USER 1000:0

CMD ["/usr/local/bin/kargo"]
44 changes: 37 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ VERSION_PACKAGE := github.com/akuity/kargo/internal/version
CONTAINER_RUNTIME ?= docker

IMAGE_REPO ?= kargo
LOCAL_REG_PORT ?= 5000
BASE_IMAGE ?= localhost:$(LOCAL_REG_PORT)/$(IMAGE_REPO)-base
IMAGE_TAG ?= dev
IMAGE_PUSH ?= false
IMAGE_PLATFORMS =
Expand Down Expand Up @@ -119,6 +121,26 @@ test-unit:
# required tools, refer to the hacking section toward the bottom of this file. #
################################################################################

################################################################################
# Build: Targets to help build #
################################################################################

.PHONY: clean
clean:
rm -rf build

.PHONY: build-base-image
build-base-image:
mkdir -p build
cp kargo-base.apko.yaml build
docker run \
--rm \
-v $(dir $(realpath $(firstword $(MAKEFILE_LIST))))build:/build \
-w /build \
cgr.dev/chainguard/apko \
build kargo-base.apko.yaml $(BASE_IMAGE) kargo-base.tar.gz
docker image load -i build/kargo-base.tar.gz

.PHONY: build-cli
build-cli:
CGO_ENABLED=0 go build \
Expand Down Expand Up @@ -269,13 +291,21 @@ hack-codegen: hack-build-dev-tools
# Build a linux/amd64 image with a docker build option to not re-use docker build cache
# make hack-build IMAGE_PLATFORMS=linux/amd64 DOCKER_BUILD_OPTS=--no-cache
.PHONY: hack-build
hack-build:
$(CONTAINER_RUNTIME) buildx build \
$(DOCKER_BUILD_OPTS) \
--build-arg GIT_COMMIT=$(shell git rev-parse HEAD) \
--build-arg GIT_TREE_STATE=$(shell if [ -z "`git status --porcelain`" ]; then echo "clean" ; else echo "dirty"; fi) \
--tag $(IMAGE_REPO):$(IMAGE_TAG) \
.
hack-build: build-base-image
@{ \
$(CONTAINER_RUNTIME) run -d -p 5000:$(LOCAL_REG_PORT) --name tmp-registry registry:2; \
trap '$(CONTAINER_RUNTIME) rm -f tmp-registry' EXIT; \
docker push $(BASE_IMAGE):latest-amd64; \
docker push $(BASE_IMAGE):latest-arm64; \
$(CONTAINER_RUNTIME) buildx build \
$(DOCKER_BUILD_OPTS) \
--network host \
--build-arg BASE_IMAGE=$(BASE_IMAGE) \
--build-arg GIT_COMMIT=$(shell git rev-parse HEAD) \
--build-arg GIT_TREE_STATE=$(shell if [ -z "`git status --porcelain`" ]; then echo "clean" ; else echo "dirty"; fi) \
--tag $(IMAGE_REPO):$(IMAGE_TAG) \
.;\
}

.PHONY: hack-build-cli
hack-build-cli: hack-build-dev-tools
Expand Down
4 changes: 3 additions & 1 deletion charts/kargo/templates/api/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ spec:
{{- if or .Values.api.cabundle.configMapName .Values.api.cabundle.secretName }}
initContainers:
- name: parse-cabundle
image: {{ include "kargo.image" . }}
image: alpine:latest
krancour marked this conversation as resolved.
Show resolved Hide resolved
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
runAsUser: 0
Expand All @@ -127,6 +127,8 @@ spec:
- "-c"
args:
- |
apk update
apk add ca-certificates
for file in /tmp/source/*; do
base_filename=$(basename "$file" .crt)
awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "/usr/local/share/ca-certificates/" base_filename "." c ".crt"}' base_filename="$base_filename" < $file
Expand Down
4 changes: 3 additions & 1 deletion charts/kargo/templates/controller/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ spec:
{{- if or .Values.controller.cabundle.configMapName .Values.controller.cabundle.secretName }}
initContainers:
- name: parse-cabundle
image: {{ include "kargo.image" . }}
image: alpine:latest
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
runAsUser: 0
Expand All @@ -103,6 +103,8 @@ spec:
- "-c"
args:
- |
apk update
apk add ca-certificates
for file in /tmp/source/*; do
base_filename=$(basename "$file" .crt)
awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "/usr/local/share/ca-certificates/" base_filename "." c ".crt"}' base_filename="$base_filename" < $file
Expand Down
24 changes: 24 additions & 0 deletions kargo-base.apko.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
contents:
keyring:
- https://packages.wolfi.dev/os/wolfi-signing.rsa.pub
repositories:
- https://packages.wolfi.dev/os
packages:
- git~2
- gpg~2
- gpg-agent~2
- openssh-client~9

accounts:
groups:
- groupname: nonroot
gid: 65532
users:
- username: nonroot
uid: 65532
gid: 65532
run-as: "65532"

archs:
- arm64
- amd64