Coder Social home page Coder Social logo

kaniko-build-private-repo's Introduction

kaniko-build-private-repo

Kaniko Builds with Private Repository Via the Kaniko context, we can git pull Private repositories and build Dockerfile with private git dependencies. This would be valid for other issues like Python private repository dependency. Kaniko is a tool to build container images from a Dockerfile, inside a container or Kubernetes cluster. You can get the motivation for using Kaniko here When using Kanik you can use mounting of secrets for the SSH or basic auth to git pull or Docker registry. When you have a Dockerfile using other private dependencies of private Git repo, it would not be sufficient and the build would fail. This post's motivation was the fact that there is a lot of documentation on Kaniko, but this use case had little to none documentation.

The Plot

You have a private repo named dummy-repo-kaniko-build.git, which you would like to build a container from using Kaniko. The Dockerfile is dependent on other private repo other-private-repo.git. You will have the Kaniko Pod Definition , defining the flow.  The Kaniko Pod is using initContainer to create a workspace folder for the Kaniko context. The Dockerfile The Dockerfile for such a case would be as follows, while it is cloning the private git repository: other-private-repo.git

(Dockerfile)[https://github.com/yossicohn/kaniko-build-private-repo/blob/main/Dockerfile] Note the usage of the private repo: RUN git clone [email protected]:/other-private-repo.git - single-branch Dockerfile-no-ssh

ARG BUILDER_HOME_DIR="/home/builder"

# first stage
FROM golang:1.16.3 as go-base
ARG BUILDER_HOME_DIR
# installing git
RUN apt-get update
RUN apt-get install -y git
WORKDIR $BUILDER_HOME_DIR
# cloaning the egit repos in the same shell context
RUN git clone [email protected]:<user>/other-private-repo.git --single-branch
# build the go code
RUN cd other-private-repo && go mod download
RUN cd other-private-repo && GOOS=linux GOARCH=amd64 go build -o "${BUILDER_HOME_DIR}/app-go" .
# final stage
FROM alpine:latest
ARG BUILDER_HOME_DIR
WORKDIR /app
ENV PORT=3000
# Expose port 3000 to the outside world
EXPOSE 3000
COPY --from=go-base "${BUILDER_HOME_DIR}/app-go" .
# Command to run the executable
ENTRYPOINT ["/app/app-go"]

**Kaniko Pod **

Note, the definition contains 2 containers:

  1. initContainer
  2. Kaniko Container The initContainer prepares the Kaniko workspace with the dummy-repo-kaniko-build.git The Pod contains mounting for secrets, the git SSH keys, and the Docker registry credentials.

Create Docker Secret

create secret docker-registry regcred --docker-server=https://index.docker.io/v1/ --docker-username=<user> --docker-password=<password> --docker-email=<[email protected]>

**Create Git SSH Secret ** We should create a git SSH key, to have the id_rsa and the id_rsa.pub

ssh-keygen -m PEM -t rsa -P ""

This will result in 2 files: id_rsa, d_rsa.pub Now the public key id_rsa.pub should be set in the git server configuration  2. Create the known-hosts

ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts_github
  1. Create the git config
Host github.com
  HostName github.com
  AddKeysToAgent yes
  StrictHostKeyChecking no
  ForwardAgent yes
  1. Create the SSH keys secret from the files
kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=.ssh/id_rsa --from-file=ssh-publickey=.ssh/id_rsa.pub --from-file=known_hosts=known_hosts.github --from-file=config=~/.ssh/config

Now the Kubernetes cluster has the needed secrets for mounting in the Pod.

Pod Definition file: kaniko-pod-no-ssh.yaml

apiVersion: v1
kind: Pod
metadata:
name: kaniko
spec:
initContainers:
- name: git-clone
image: alpine
command: ["sh", "-c"]
args:
- |
  apk add --no-cache git openssh
  eval `ssh-agent -s`
  mkdir ~/.ssh/
  cp .ssh-src/* ~/.ssh/
  eval `ssh-agent -s`
  ssh-add ~/.ssh/id_rsa
# you can see the log of the ssh command to insure the credentials are valid
  ssh -v [email protected]
  git clone [email protected]:<user>/dummy-repo-kaniko-build.git /workspace
volumeMounts:
- name: docker-volume
mountPath: /workspace
- name: ssh-key-volume
mountPath: ".ssh-src/"
containers:
- name: kaniko
image: gcr.io/kaniko-project/executor:latest
args:
- "--context=dir:///workspace"
- "--destination=<user>/myimage:1.0.0"
volumeMounts:
- name: kaniko-secret
mountPath: /kaniko/.docker/
- name: docker-volume
mountPath: /workspace
restartPolicy: Never
volumes:
- name: kaniko-secret
secret:
secretName: regcred
items:
- key: .dockerconfigjson
path: config.json
- name: ssh-key-volume
secret:
secretName: ssh-key-secret
defaultMode: 0400
- name: docker-volume
emptyDir: {}
- name: ssh-hosts
emptyDir: {}

Running the Pod would show failure:

kubectl create -f kaniko-pod-no-ssh.yaml

The initContainer would finish successfully as the SSH keys are available for the git clone of dummy-repo-kaniko-build.git But, unfortunately the Kaniko container would fail. The reason this would not be working, is that the other-private-repo.git is private and the build of the dummy-repo-kaniko-build/Dockerfile would fail on the git clone of the private repo other-private-repo.git This would occur since the SSH keys are not in the context of the Kaniko build. The Solution We should copy the SSH keys to the context (workspace folder)and use them in the Dockerfile while building the container. In the Kaniko Pod definition, we will add in the InitContainer the copy of the SSH keys:

mkdir /workspace/.ssh
cp .ssh-src/* /workspace/.ssh/

Fixing the Kaniko Pod for the SSH keys:

Kaniko Pod

apiVersion: v1
kind: Pod
metadata:
name: kaniko
spec:
initContainers:
- name: git-clone
image: alpine
command: ["sh", "-c"]
args:
- |
apk add --no-cache git openssh
eval `ssh-agent -s`
mkdir ~/.ssh/
cp .ssh-src/* ~/.ssh/
eval `ssh-agent -s`
ssh-add ~/.ssh/id_rsa
# you can see the log of the ssh command to insure the credentials are valid
ssh -v [email protected]
git clone [email protected]:<user>/dummy-repo-kaniko-build.git /workspace
mkdir /workspace/.ssh
cp .ssh-src/* /workspace/.ssh/
volumeMounts:
- name: docker-volume
mountPath: /workspace
- name: ssh-key-volume
mountPath: ".ssh-src/"
containers:
- name: kaniko
image: gcr.io/kaniko-project/executor:latest
args:
- "--context=dir:///workspace"
- "--destination=<user>/myimage:1.0.0"
volumeMounts:
- name: kaniko-secret
mountPath: /kaniko/.docker/
- name: docker-volume
mountPath: /workspace
restartPolicy: Never
volumes:
- name: kaniko-secret
secret:
secretName: regcred
items:
- key: .dockerconfigjson
path: config.json
- name: ssh-key-volume
secret:
secretName: ssh-key-secret
defaultMode: 0400
- name: docker-volume
emptyDir: {}
- name: ssh-hosts
emptyDir: {}

Dockerfile

ARG BUILDER_HOME_DIR="/home/builder"

FROM golang:1.16.3 as go-base
ARG BUILDER_HOME_DIR

# installing git
RUN apt-get update
RUN apt-get install -y git

# copying the ssh keys  to/root/.ssh
RUN mkdir -p /root/.ssh/
COPY .ssh/* /root/.ssh/

WORKDIR $BUILDER_HOME_DIR

# 1. restarting the ssh agent
# 2. adding the private key to the agent
# 3. cloaning th egit repos in the same shell context
RUN eval $(ssh-agent -s) && ssh-add /root/.ssh/id_rsa && git clone [email protected]:<user>/other-private-repo.git --single-branch
RUN cd other-private-repo && go mod download
RUN cd other-private-repo && GOOS=linux GOARCH=amd64 go build -o "${BUILDER_HOME_DIR}/app-go" .


# final stage
FROM alpine:latest
ARG BUILDER_HOME_DIR
WORKDIR /app

ENV PORT=3000

# Expose port 3000 to the outside world
EXPOSE 3000

COPY --from=go-base "${BUILDER_HOME_DIR}/app-go" .

# Command to run the executable
ENTRYPOINT ["/app/app-go"]

kaniko-build-private-repo's People

Contributors

yossicohn avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.