Skip to content

Commit

Permalink
refs platform/#2581: change base image to alpine, upgrade tools and i…
Browse files Browse the repository at this point in the history
…mprove custom scripts
  • Loading branch information
Monska85 committed Dec 14, 2023
1 parent 4d01280 commit 4db082c
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 124 deletions.
101 changes: 75 additions & 26 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -1,55 +1,104 @@
name: Docker
on:
push:
branches:
- "**"
pull_request:
branches:
- main
push:
branches: main

env:
REGISTRY: ghcr.io
IMAGE_NAME: cloud-tools

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
# set latest tag for main branch
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
type=sha,format=long,prefix=
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3

- name: Build images
- name: Get the Google Cloud CLI image tag
id: vars
run: |
GOOGLE_CLOUD_CLI_IMAGE_TAG="$(make print-google-cloud-cli-image-tag)"
docker buildx build --build-arg GOOGLE_CLOUD_CLI_IMAGE_TAG=${GOOGLE_CLOUD_CLI_IMAGE_TAG} --load . --tag $IMAGE_NAME:latest
echo "google_cloud_cli_image_tag=$(make print-google-cloud-cli-image-tag)" >> "$GITHUB_OUTPUT"
- name: Build Docker image
uses: docker/build-push-action@v5
with:
load: true
push: false
context: .
build-args: |
GOOGLE_CLOUD_CLI_IMAGE_TAG=${{ steps.vars.outputs.google_cloud_cli_image_tag }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Log into GitHub Container Registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login https://ghcr.io -u ${{ github.actor }} --password-stdin
# We use commit sha here to be as safe as possible with credentials.
- name: Log in to the Container registry
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
# set latest tag for main branch
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
type=sha,format=long,prefix=
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3

- name: Build and push images to GitHub Container Registry
- name: Get the Google Cloud CLI image tag
id: vars
run: |
IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME
# Change all uppercase to lowercase.
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
echo IMAGE_ID=$IMAGE_ID
GOOGLE_CLOUD_CLI_IMAGE_TAG="$(make print-google-cloud-cli-image-tag)"
docker buildx build --build-arg GOOGLE_CLOUD_CLI_IMAGE_TAG=${GOOGLE_CLOUD_CLI_IMAGE_TAG} --push . --platform "linux/amd64,linux/arm64" \
--tag $IMAGE_ID:latest \
echo "google_cloud_cli_image_tag=$(make print-google-cloud-cli-image-tag)" >> "$GITHUB_OUTPUT"
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
push: true
platforms: linux/amd64,linux/arm64
context: .
build-args: |
GOOGLE_CLOUD_CLI_IMAGE_TAG=${{ steps.vars.outputs.google_cloud_cli_image_tag }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
format: "sarif"
output: "trivy-results.sarif"
ignore-unfixed: true
severity: "CRITICAL,HIGH"
vuln-type: "os,library"

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: "trivy-results.sarif"
115 changes: 65 additions & 50 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,38 +1,46 @@
# AWS CLI v2
ARG AWS_CLI_VERSION=2.15.0
ARG ALPINE_VERSION=3.18
# To fetch the right alpine version use:
# docker run --rm --entrypoint ash eu.gcr.io/google.com/cloudsdktool/google-cloud-cli:${GOOGLE_CLOUD_CLI_IMAGE_TAG} -c 'cat /etc/issue'
# Check the available version here: https://github.com/sparkfabrik/docker-alpine-aws-cli/pkgs/container/docker-alpine-aws-cli

# Use the same version of the base image in different stages
ARG GOOGLE_CLOUD_CLI_IMAGE_TAG

FROM ghcr.io/sparkfabrik/docker-alpine-aws-cli:${AWS_CLI_VERSION}-alpine${ALPINE_VERSION} as awscli

# Building and downloading all the tools in a single stage
FROM eu.gcr.io/google.com/cloudsdktool/google-cloud-cli:${GOOGLE_CLOUD_CLI_IMAGE_TAG} as build

# Build target arch passed by BuildKit
ARG TARGETARCH

# Install deps
RUN apt-get update && \
apt-get install -y -o APT::Install-Recommends=false -o APT::Install-Suggests=false \
gzip libtool autoconf automake
# Install components for the building stage.
RUN apk --no-cache add autoconf automake build-base curl gzip libtool make openssl unzip

# Download helm
# https://github.com/helm/helm/releases
ENV HELM_VERSION 3.12.3
ENV HELM_VERSION 3.13.2
RUN curl -o /tmp/helm-v${HELM_VERSION}-linux-${TARGETARCH}.tar.gz -L0 "https://get.helm.sh/helm-v${HELM_VERSION}-linux-${TARGETARCH}.tar.gz" \
&& tar -zxvf /tmp/helm-v${HELM_VERSION}-linux-${TARGETARCH}.tar.gz -C /tmp \
&& mv /tmp/linux-${TARGETARCH}/helm /usr/local/bin/helm

# Download stern
# https://github.com/stern/stern/releases
ENV STERN_VERSION 1.26.0
ENV STERN_VERSION 1.27.0
RUN curl -o /tmp/stern_${STERN_VERSION}_linux_${TARGETARCH}.tar.gz -LO "https://github.com/stern/stern/releases/download/v${STERN_VERSION}/stern_${STERN_VERSION}_linux_${TARGETARCH}.tar.gz" \
&& tar -zxvf /tmp/stern_${STERN_VERSION}_linux_${TARGETARCH}.tar.gz -C /tmp \
&& mv /tmp/stern /usr/local/bin/stern

# Download jq
# https://github.com/jqlang/jq/releases
ENV JQ_VERSION 1.6
ENV JQ_VERSION 1.7
RUN curl -o /tmp/jq-${JQ_VERSION}.tar.gz -L0 "https://github.com/stedolan/jq/archive/refs/tags/jq-${JQ_VERSION}.tar.gz" \
&& tar -zxvf /tmp/jq-${JQ_VERSION}.tar.gz -C /tmp

# https://github.com/kkos/oniguruma/tree/v6.9.7.1
ENV ONIGURUMA_VERSION 6.9.7.1
# https://github.com/kkos/oniguruma/tree/v6.9.9
ENV ONIGURUMA_VERSION 6.9.9
RUN curl -o /tmp/oniguruma-${ONIGURUMA_VERSION}.tar.gz -L0 "https://github.com/kkos/oniguruma/archive/refs/tags/v${ONIGURUMA_VERSION}.tar.gz" \
&& tar -zxvf /tmp/oniguruma-${ONIGURUMA_VERSION}.tar.gz -C /tmp

Expand All @@ -45,46 +53,49 @@ RUN cd /tmp/jq-jq-${JQ_VERSION} \
&& make LDFLAGS=-all-static -j4 \
&& mv jq /usr/local/bin/jq

# Cleanup unwanted files to keep the image light
RUN apt-get clean -q && apt-get autoremove --purge \
&& rm -rf /var/lib/apt/lists/*

# Use the same version of the base image in different stages
ARG GOOGLE_CLOUD_CLI_IMAGE_TAG

# Create the final image
FROM eu.gcr.io/google.com/cloudsdktool/google-cloud-cli:${GOOGLE_CLOUD_CLI_IMAGE_TAG}

LABEL org.opencontainers.image.source https://github.com/sparkfabrik/docker-cloud-tools
LABEL org.opencontainers.image.source=https://github.com/sparkfabrik/docker-cloud-tools

# Build target arch passed by BuildKit
ARG TARGETARCH

# Install deps
RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y -o APT::Install-Recommends=false -o APT::Install-Suggests=false \
unzip vim bash bash-completion
# Add additional components to gcloud SDK.
RUN gcloud components install app-engine-java beta gke-gcloud-auth-plugin

# Use the gke-auth-plugin to authenticate to the GKE cluster.
# Install gke-gcloud-auth-plugin (https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke)
ENV USE_GKE_GCLOUD_AUTH_PLUGIN=True
RUN gcloud components install gke-gcloud-auth-plugin

# Install aws-cli (https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
# We keep the final url used to download the awscli tool, it could be useful for debug purposes.
ENV AWSCLI_URL_FILE "/tmp/awscli.url"
RUN echo "https://awscli.amazonaws.com/awscli-exe-linux-$([ "${TARGETARCH}" = "arm64" ] && echo "aarch64" || echo "x86_64").zip" > "${AWSCLI_URL_FILE}" \
&& curl -o "/tmp/awscliv2.zip" -L0 "$(cat ${AWSCLI_URL_FILE})" \
&& unzip /tmp/awscliv2.zip -d /tmp \
&& /tmp/aws/install \
&& rm -rf /tmp/aws /tmp/awscliv2.zip
ENV USE_GKE_GCLOUD_AUTH_PLUGIN true

# Install additional components.
RUN apk --no-cache add bat curl less make vim \
bash-completion grep groff gettext \
openssl ncurses unzip yq

# Create utility folder
RUN mkdir -p /utility

# Install AWS CLI v2 using the binary builded in the awscli stage
COPY --from=awscli /usr/local/aws-cli/ /usr/local/aws-cli/
RUN ln -s /usr/local/aws-cli/v2/current/bin/aws /usr/local/bin/aws \
&& ln -s /usr/local/aws-cli/v2/current/bin/aws_completer /usr/local/bin/aws_completer

# Download kubectl
RUN curl -o /usr/local/bin/kubectl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/${TARGETARCH}/kubectl" \
RUN curl -o /usr/local/bin/kubectl -sLO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/${TARGETARCH}/kubectl" \
&& chmod +x /usr/local/bin/kubectl

# Download kubens
RUN curl -o /usr/local/bin/kubens -LO "https://raw.githubusercontent.com/ahmetb/kubectx/master/kubens" \
&& chmod +x /usr/local/bin/kubens
# Download kubectx and kubens utilities
# https://github.com/ahmetb/kubectx
ENV KUBECTX_VERSION 0.9.5
RUN curl -o /utility/kubens -sLO "https://github.com/ahmetb/kubectx/releases/download/v${KUBECTX_VERSION}/kubens" \
&& curl -o /utility/kubectx -sLO "https://github.com/ahmetb/kubectx/releases/download/v${KUBECTX_VERSION}/kubectx" \
&& chmod +x /utility/kubens /utility/kubectx \
&& curl -o /etc/profile.d/kubens.sh -sLO "https://raw.githubusercontent.com/ahmetb/kubectx/v${KUBECTX_VERSION}/completion/kubens.bash" \
&& curl -o /etc/profile.d/kubectx.sh -sLO "https://raw.githubusercontent.com/ahmetb/kubectx/v${KUBECTX_VERSION}/completion/kubectx.bash" \
&& chmod +x /etc/profile.d/kubectx.sh /etc/profile.d/kubens.sh

# Copy helm from previous stage
COPY --from=build /usr/local/bin/helm /usr/local/bin/helm
Expand All @@ -99,8 +110,9 @@ COPY --from=build /usr/local/bin/jq /usr/local/bin/jq
RUN chmod +x /usr/local/bin/jq

# Overwrite kubens with custom kubens script (we don't have namespace list permission)
COPY scripts/kubens /usr/local/bin/kubens
RUN chmod +x /usr/local/bin/kubens
COPY scripts/kubens /utility/kubens.patched
RUN chmod +x /utility/kubens.patched
RUN ln -s /utility/kubens.patched /usr/local/bin/kubens

# Create userless home, it will be used only for cache
ENV HOME /cloud-tools-cli
Expand All @@ -117,22 +129,25 @@ COPY scripts/prompter.sh /etc/profile.d/prompter.sh
RUN chmod +x /etc/profile.d/prompter.sh

# Final settings
RUN chmod 666 /etc/profile \
&& echo "alias k=\"kubectl\"" >> /etc/profile \
&& echo "complete -C '/usr/local/bin/aws_completer' aws" >> /etc/profile \
&& echo "source <(kubectl completion bash)" >> /etc/profile \
&& echo "source <(helm completion bash)" >> /etc/profile \
&& echo "source <(stern --completion bash)" >> /etc/profile \
&& echo "source /google-cloud-sdk/path.bash.inc" >> /etc/profile

# Cleanup unwanted files to keep the image light
RUN apt-get clean -q && apt-get autoremove --purge \
&& rm -rf /var/lib/apt/lists/*

# Entrypoint configuration
RUN touch /etc/profile.d/tools-completion.sh \
&& chmod +x /etc/profile.d/tools-completion.sh \
&& echo "source <(kubectl completion bash)" >> /etc/profile.d/tools-completion.sh \
&& echo "alias k=\"kubectl\"" >> /etc/profile.d/tools-completion.sh \
&& echo "complete -o default -F __start_kubectl k" >> /etc/profile.d/tools-completion.sh \
&& echo "source <(helm completion bash)" >> /etc/profile.d/tools-completion.sh \
&& echo "source <(stern --completion bash)" >> /etc/profile.d/tools-completion.sh \
&& echo "source /google-cloud-sdk/path.bash.inc" >> /etc/profile.d/tools-completion.sh \
&& echo "complete -C '/usr/local/bin/aws_completer' aws" >> /etc/profile.d/tools-completion.sh

# Additional entrypoints
RUN mkdir -p /docker-entrypoint.d
COPY docker-entrypoint.sh /docker-entrypoint.sh
COPY scripts/docker-entrypoint.d /docker-entrypoint.d

# Create custom directory for custom-docker-entrypoint.d
RUN mkdir -p /custom-docker-entrypoint.d

# Entrypoint configuration
RUN chmod +x /docker-entrypoint.sh \
&& find /docker-entrypoint.d -type f -exec chmod +x {} +

Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
# make cloud-tools
#

GOOGLE_CLOUD_CLI_IMAGE_TAG ?= 444.0.0-debian_component_based
GOOGLE_CLOUD_CLI_IMAGE_TAG ?= 456.0.0-alpine
IMAGE_NAME ?= sparkfabrik/cloud-tools
IMAGE_TAG ?= latest

cloud-tools: build-docker-image
@touch .env
@docker run --rm \
-v ${PWD}/dotfiles:/cloud-tools-cli/dotfiles \
-v ~/.config/gcloud:/cloud-tools-cli/.config/gcloud \
-w /mnt \
-v ${PWD}/dotfiles:/root/dotfiles \
-v ~/.config/gcloud:/root/.config/gcloud \
--hostname "SPARK-CLOUD-TOOLS-LOCAL" --name spark-cloud-tools-local \
--env-file .env \
-it $(IMAGE_NAME):$(IMAGE_TAG)
Expand Down
13 changes: 12 additions & 1 deletion docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
#!/bin/bash
#!/usr/bin/env bash

export ADDITIONAL_ENV_FILE=/tmp/.env.additional
touch "${ADDITIONAL_ENV_FILE}"

# Fix kubens bin
if [ "${ORIGINAL_KUBENS:-0}" = "1" ]; then
echo "Using original kubens!"
unlink /usr/local/bin/kubens
ln -s /utility/kubens /usr/local/bin/kubens
fi

if [ -d "/docker-entrypoint.d" ]; then
run-parts "/docker-entrypoint.d"
fi

if [ -d "/custom-docker-entrypoint.d" ]; then
run-parts "/custom-docker-entrypoint.d"
fi

# Load the additional environment variables
# shellcheck disable=SC1090
. "${ADDITIONAL_ENV_FILE}"
Expand Down
Loading

0 comments on commit 4db082c

Please sign in to comment.