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

Add option to download IC binary #2107

Merged
merged 2 commits into from
Oct 20, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
16 changes: 13 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,23 @@ certificate-and-key: ## Create default cert and key
./build/generate_default_cert_and_key.sh

.PHONY: build
build: ## Build Ingress Controller binary
@docker -v || (code=$$?; printf "\033[0;31mError\033[0m: there was a problem with Docker\n"; exit $$code)
build: download-binary-docker ## Build Ingress Controller binary
ifeq (${TARGET},local)
@go version || (code=$$?; printf "\033[0;31mError\033[0m: unable to build locally, try using the parameter TARGET=container\n"; exit $$code)
@go version || (code=$$?; printf "\033[0;31mError\033[0m: unable to build locally, try using the parameter TARGET=container or TARGET=download\n"; exit $$code)
CGO_ENABLED=0 GO111MODULE=on GOOS=linux go build -trimpath -ldflags "-s -w -X main.version=${VERSION} -X main.commit=${GIT_COMMIT} -X main.date=$(DATE)" -o nginx-ingress github.com/nginxinc/kubernetes-ingress/cmd/nginx-ingress
endif

.PHONY: download-binary-docker
download-binary-docker: ## Download Docker image from which to extract Ingress Controller binary
@docker -v || (code=$$?; printf "\033[0;31mError\033[0m: there was a problem with Docker\n"; exit $$code)
ifeq (${TARGET},download)
DOWLOAD_TAG := $(shell ./hack/docker.sh $(GIT_COMMIT) $(GIT_TAG))
ifeq ($(DOWLOAD_TAG),fail)
$(error unable to build with TARGET=download, this function is only available when building from a git tag or from the latest commit matching the edge image)
endif
override DOCKER_BUILD_OPTIONS += --build-arg DOWLOAD_TAG=$(DOWLOAD_TAG)
endif

.PHONY: build-goreleaser
build-goreleaser: ## Build Ingress Controller binary using GoReleaser
@goreleaser -v || (code=$$?; printf "\033[0;31mError\033[0m: there was a problem with GoReleaser. Follow the docs to install it https://goreleaser.com/install\n"; exit $$code)
Expand Down
11 changes: 11 additions & 0 deletions build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
ARG BUILD_OS=debian
ARG NGINX_PLUS_VERSION=r25
ARG UBI_VERSION=8
ARG DOWNLOAD_TAG=edge

############################################# Base image for Debian #############################################
FROM nginx:1.21.3 AS debian
Expand Down Expand Up @@ -281,3 +282,13 @@ ARG TARGETARCH
LABEL org.nginx.kic.image.build.version="aws"

COPY --chown=nginx:0 ./dist/aws_linux_$TARGETARCH/nginx-ingress /


############################################# Create image with nginx-ingress extracted from image on Docker Hub #############################################
FROM nginx/nginx-ingress:${DOWNLOAD_TAG} as kic

FROM common as download

LABEL org.nginx.kic.image.build.version="binaries"

COPY --from=kic /nginx-ingress /
18 changes: 9 additions & 9 deletions docs/content/installation/building-ingress-controller-image.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
title: Building the Ingress Controller Image
description:
description:
weight: 2200
doctypes: [""]
toc: true
---

This document explains how to build an Ingress Controller image using the source code. You can also use pre-built images: please see [here](/nginx-ingress-controller/installation/using-the-jwt-token-docker-secret) and [here](/nginx-ingress-controller/installation/pulling-ingress-controller-image) for details on how to pull the NGINX Ingress Controller based on NGINX Plus from the F5 Docker registry; for NGINX Ingress Controller based on NGINX OSS, we provide the images through [DockerHub](https://hub.docker.com/r/nginx/nginx-ingress/).
This document explains how to build an Ingress Controller image using the source code. You can also use pre-built images: please see [here](/nginx-ingress-controller/installation/using-the-jwt-token-docker-secret) and [here](/nginx-ingress-controller/installation/pulling-ingress-controller-image) for details on how to pull the NGINX Ingress Controller based on NGINX Plus from the F5 Docker registry; for NGINX Ingress Controller based on NGINX OSS, we provide the images through [DockerHub](https://hub.docker.com/r/nginx/nginx-ingress/) and [GitHub Container](https://github.com/nginxinc/kubernetes-ingress/pkgs/container/kubernetes-ingress).

## Prerequisites

Expand All @@ -17,13 +17,13 @@ Before you can build the image, make sure that the following software is install
* [OpenSSL](https://www.openssl.org/), optionally, if you would like to generate a self-signed certificate and a key for the default server.
* For NGINX Plus, you must have the NGINX Plus license -- the certificate (`nginx-repo.crt`) and the key (`nginx-repo.key`).

Although the Ingress Controller is written in golang, golang is not required, you have the option to build the Ingress Controller in a Docker container.
Although the Ingress Controller is written in golang, golang is not required, you have the option to download the binary or to build the Ingress Controller in a Docker container.

## Building the Image and Pushing It to the Private Registry

We build the image using the make utility and the provided `Makefile`. Let’s create the Ingress Controller binary, build an image and push the image to the private registry.

**Note**: If you have a local golang environment, you can remove `TARGET=container` from the `make` commands to speed up the build.
**Note**: If you have a local golang environment and you want to build the binary, you can remove `TARGET=download` from the `make` commands. If you want to build the binary, but you don't have a local golang environment you can use `TARGET=container`.

1. Make sure to run the `docker login` command first to log in to the registry.

Expand All @@ -39,11 +39,11 @@ We build the image using the make utility and the provided `Makefile`. Let’s c
1. Build the image:
* For **NGINX**:
```
$ make debian-image PREFIX=myregistry.example.com/nginx-ingress TARGET=container
$ make debian-image PREFIX=myregistry.example.com/nginx-ingress TARGET=download
```
or if you wish to use alpine
```
$ make alpine-image PREFIX=myregistry.example.com/nginx-ingress TARGET=container
$ make alpine-image PREFIX=myregistry.example.com/nginx-ingress TARGET=download
```
`myregistry.example.com/nginx-ingress` defines the repo in your private registry where the image will be pushed. Substitute that value with the repo in your private registry.

Expand All @@ -56,13 +56,13 @@ We build the image using the make utility and the provided `Makefile`. Let’s c
```
Then run:
```
$ make debian-image-plus PREFIX=myregistry.example.com/nginx-plus-ingress TARGET=container
$ make debian-image-plus PREFIX=myregistry.example.com/nginx-plus-ingress TARGET=download
```
`myregistry.example.com/nginx-plus-ingress` defines the repo in your private registry where the image will be pushed. Substitute that value with the repo in your private registry.

As a result, the image **myregistry.example.com/nginx-plus-ingress:2.0.2** is built. Note that the tag `2.0.2` comes from the `VERSION` variable, defined in the Makefile.

**Note**: In the event of a patch version of [NGINX Plus being released](/nginx/releases/), make sure to rebuild your image to get the latest version. If your system is caching the Docker layers and not updating the packages, add `DOCKER_BUILD_OPTIONS="--no-cache"` to the `make` command.
**Note**: In the event of a patch version of [NGINX Plus being released](/nginx/releases/), make sure to rebuild your image to get the latest version. If your system is caching the Docker layers and not updating the packages, add `DOCKER_BUILD_OPTIONS="--pull --no-cache"` to the `make` command.

1. Push the image:
```
Expand Down Expand Up @@ -107,4 +107,4 @@ The **Makefile** contains the following main variables for you to customize (eit
* **VERSION** -- the current version of the Ingress Controller.
* **TAG** -- the tag added to the image. It's set to the value of the `VERSION` variable by default.
* **DOCKER_BUILD_OPTIONS** -- the [options](https://docs.docker.com/engine/reference/commandline/build/#options) for the `docker build` command. For example, `--pull`.
* **TARGET** -- By default, the Ingress Controller is compiled locally using a `local` golang environment. If you want to compile the Ingress Controller using your local golang environment, make sure that the Ingress Controller repo is in your `$GOPATH`. To compile the Ingress Controller using the Docker [golang](https://hub.docker.com/_/golang/) container, specify `TARGET=container`.
* **TARGET** -- By default, the Ingress Controller is compiled locally using a `local` golang environment. If you want to compile the Ingress Controller using your local golang environment, make sure that the Ingress Controller repo is in your `$GOPATH`. To compile the Ingress Controller using the Docker [golang](https://hub.docker.com/_/golang/) container, specify `TARGET=container`. If you checked out a tag or are on the latest commit on `master` you can specify `TARGET=download` to avoid compiling the binary.
26 changes: 26 additions & 0 deletions hack/docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#! /bin/bash
pleshakov marked this conversation as resolved.
Show resolved Hide resolved

git_commit=$1
git_tag=$2
docker_tag=edge

commit_tag=$(git tag --contains ${git_commit})

if [[ ${commit_tag} == ${git_tag} ]]; then
# we're on the tag, use the docker image for the tag
docker_tag=${git_tag//v/}
echo ${docker_tag}
exit 0

else
# we're on master or a branch, try to download the latest edge and see if sha matches
docker pull nginx/nginx-ingress:${docker_tag} >/dev/null 2>&1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we rebuild the edge images on every commit in the master or we optimize (for example, when no code changes were in the commit?)? if latter is the case, then we might not have an image that matches the commit

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We rebuild the images for every change except for docs and examples. In that case, you're right, it won't be possible to download the binary. Unfortunately, I don't see a workaround for this unless we want to always use the latest available binary, but I think that could cause more issues.

Similarly, if somebody is on an old commit, there's no way to get the corresponding edge image that was built in the past (unless we start tagging the image with the sha).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this can cause problems, perhaps we shall only support downloading for release tags then?

Copy link
Member Author

@lucacome lucacome Oct 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it's not the latest commit or a tag it will print this message:

unable to build with TARGET=download, this function is only available when building from a git tag or from the latest commit matching the edge image

do you think it's not enough?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you it's not enough?

yeah, I think it is enough

DOCKER_SHA=$(docker inspect --format '{{ index .Config.Labels "org.opencontainers.image.revision" }}' nginx/nginx-ingress:${docker_tag})
if [[ ${DOCKER_SHA} == ${git_commit} ]]; then
# we're on the same commit as the latest edge
echo ${docker_tag}
exit 0
fi
fi

echo "fail"