Repository: kubernetes/ingress-nginx
Pull request #8848 (2022-07-20 19:20:40)

update dd-opentracing-cpp version in nginx build script
## What this PR does / why we need it:
Upgrades the Datadog tracing plugin to new release v1.3.2: https://github.com/DataDog/dd-opentracing-cpp/releases/tag/v1.3.2

## Types of changes
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Documentation only
- [x] Upgrade tracing plugin

## How Has This Been Tested?
The nginx base image builds and runs and produces traces using the Datadog tracing plugin.

## Checklist:
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [x] I've read the [CONTRIBUTION](https://github.com/kubernetes/ingress-nginx/blob/main/CONTRIBUTING.md) guide
- [ ] I have added tests to cover my changes.
- [ ] All new and existing tests passed.


linux-foundation-easycla[bot]:  <a href="https://api.easycla.lfx.linuxfoundation.org/v2/repository-provider/github/sign/18706487/72891330/8848/#/?version=2"><img src="https://s3.amazonaws.com/cla-project-logo-prod/cla-not-signed.svg" alt="CLA Not Signed" align="left" height="28" width="328"></a><br/><br /><ul><li><a href='https://api.easycla.lfx.linuxfoundation.org/v2/repository-provider/github/sign/18706487/72891330/8848/#/?version=2' target='_blank'>:x:</a> - login: @dgoffredo / name: David Goffredo . The commit (eeeb5e59082e959e89c455f26eee98de0074c4d1) is not authorized under a signed CLA. <a href='https://api.easycla.lfx.linuxfoundation.org/v2/repository-provider/github/sign/18706487/72891330/8848/#/?version=2' target='_blank'>Please click here to be authorized</a>. For further assistance with EasyCLA, <a href='https://jira.linuxfoundation.org/servicedesk/customer/portal/4' target='_blank'>please submit a support request ticket</a>.</li></ul>
k8s-ci-robot: @dgoffredo: This issue is currently awaiting triage.

If Ingress contributors determines this is a relevant issue, they will accept it by applying the `triage/accepted` label and provide further guidance.

The `triage/accepted` label can be added by org members by writing `/triage accepted` in a comment.


<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>
k8s-ci-robot: Welcome @dgoffredo! <br><br>It looks like this is your first PR to <a href='https://github.com/kubernetes/ingress-nginx'>kubernetes/ingress-nginx</a> 🎉. Please refer to our [pull request process documentation](https://git.k8s.io/community/contributors/guide/pull-requests.md) to help your PR have a smooth ride to approval. <br><br>You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. [Here is the bot commands documentation](https://go.k8s.io/bot-commands). <br><br>You can also check if kubernetes/ingress-nginx has [its own contribution guidelines](https://github.com/kubernetes/ingress-nginx/tree/master/CONTRIBUTING.md). <br><br>You may want to refer to our [testing guide](https://git.k8s.io/community/contributors/devel/sig-testing/testing.md) if you run into trouble with your tests not passing. <br><br>If you are having difficulty getting your pull request seen, please follow the [recommended escalation practices](https://github.com/kubernetes/community/blob/master/contributors/guide/pull-requests.md#why-is-my-pull-request-not-getting-reviewed). Also, for tips and tricks in the contribution process you may want to read the [Kubernetes contributor cheat sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet/README.md). We want to make sure your contribution gets all the attention it needs! <br><br>Thank you, and welcome to Kubernetes. :smiley:
k8s-ci-robot: Hi @dgoffredo. Thanks for your PR.

I'm waiting for a [kubernetes](https://github.com/orgs/kubernetes/people) member to verify that this patch is reasonable to test. If it is, they should reply with `/ok-to-test` on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should [join the org](https://git.k8s.io/community/community-membership.md#member) to skip this step.

Once the patch is verified, the new status will be reflected by the `ok-to-test` label.

I understand the commands that are listed [here](https://go.k8s.io/bot-commands?repo=kubernetes%2Fingress-nginx).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>


Patch:
diff --git a/Makefile b/Makefile
index bafddeef2..5ba8e8ed5 100644
--- a/Makefile
+++ b/Makefile
@@ -54,8 +54,9 @@ ifneq ($(PLATFORM),)
 endif
 
 MAC_OS = $(shell uname -s)
+
 ifeq ($(MAC_OS), Darwin)
-	MAC_DOCKER_FLAGS="--load"
+	MAC_DOCKER_FLAGS=
 else
 	MAC_DOCKER_FLAGS=
 endif
diff --git a/build/build.sh b/build/build.sh
index 210a8e10f..3b51d665e 100755
--- a/build/build.sh
+++ b/build/build.sh
@@ -49,6 +49,7 @@ echo "Building targets for ${ARCH}, generated targets in ${TARGETS_DIR} director
 
 echo "Building ${PKG}/cmd/nginx"
 
+git config --add safe.directory /go/src/k8s.io/ingress-nginx
 ${GO_BUILD_CMD} \
   -trimpath -ldflags="-buildid= -w -s \
     -X ${PKG}/version.RELEASE=${TAG} \
diff --git a/build/run-in-docker.sh b/build/run-in-docker.sh
index d2cfe9552..3cb1f8ef5 100755
--- a/build/run-in-docker.sh
+++ b/build/run-in-docker.sh
@@ -65,12 +65,14 @@ fi
 
 USER=${USER:-nobody}
 
+MAC_OS="`uname -s`"
 MAC_OS="${MAC_OS:-}"
 if [[ ${MAC_OS} == "Darwin" ]]; then
 	MAC_DOCKER_FLAGS=""
 else
 	MAC_DOCKER_FLAGS="-u $(id -u ${USER}):$(id -g ${USER})" #idk why mac/git fails on the gobuild if these are presented to dockerrun.sh script
 fi
+echo "MAC_OS = ${MAC_OS}, MAC_OS_FLAGS = ${MAC_DOCKER_FLAGS}"
 
 echo "..printing env & other vars to stdout"
 echo "HOSTNAME=`hostname`"
diff --git a/docs/examples/customization/sysctl/patch.json b/docs/examples/customization/sysctl/patch.json
index 683b4ec6b..319ccf4f8 100644
--- a/docs/examples/customization/sysctl/patch.json
+++ b/docs/examples/customization/sysctl/patch.json
@@ -4,7 +4,7 @@
 			"spec": {
 				"initContainers": [{
 					"name": "sysctl",
-					"image": "alpine:3.16.0",
+					"image": "alpine:3.16.1",
 					"securityContext": {
 						"privileged": true
 					},
diff --git a/docs/index.md b/docs/index.md
index 91661cba3..5687bf5d3 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -228,3 +228,13 @@ If you start Ingress-Nginx B with the command line argument `--watch-ingress-wit
   --set controller.ingressClassByName=true
   ```
 - If you need to install yet another instance, then repeat the procedure to create a new namespace, change the values such as names & namespaces (for example from "-2" to "-3"), or anything else that meets your needs.
+- If you need to install all instances in the same namespace, then you need to specify a different **election id**, like this:
+  ```
+  helm install ingress-nginx-2 ingress-nginx/ingress-nginx  \
+  --namespace kube-system \
+  --set controller.electionID=nginx-two-leader \
+  --set controller.ingressClassResource.name=nginx-two \
+  --set controller.ingressClassResource.controllerValue="example.com/ingress-nginx-2" \
+  --set controller.ingressClassResource.enabled=true \
+  --set controller.ingressClassByName=true
+  ```
\ No newline at end of file
diff --git a/docs/user-guide/multiple-ingress.md b/docs/user-guide/multiple-ingress.md
index 4825b8458..35e0e45dc 100644
--- a/docs/user-guide/multiple-ingress.md
+++ b/docs/user-guide/multiple-ingress.md
@@ -8,7 +8,7 @@ To fix this problem, use [IngressClasses](https://kubernetes.io/docs/concepts/se
 
 If all ingress controllers respect IngressClasses (e.g. multiple instances of ingress-nginx v1.0), you can deploy two Ingress controllers by granting them control over two different IngressClasses, then selecting one of the two IngressClasses with `ingressClassName`.
 
-First, ensure the `--controller-class=` and `--ingress-class` are set to something different on each ingress controller:
+First, ensure the `--controller-class=` and `--ingress-class` are set to something different on each ingress controller, If your additional ingress controller is to be installed in a namespace, where there is/are one/more-than-one ingress-nginx-controller(s) already installed, then you need to specify a different unique `--election-id` for the new instance of the controller.
 
 ```yaml
 # ingress-nginx Deployment/Statefulset
@@ -19,6 +19,7 @@ spec:
          - name: ingress-nginx-internal-controller
            args:
              - /nginx-ingress-controller
+             - '--election-id=ingress-controller-leader'
              - '--controller-class=k8s.io/internal-ingress-nginx'
              - '--ingress-class=k8s.io/internal-nginx'
             ...
@@ -53,6 +54,7 @@ or if installing with Helm:
 
 ```yaml
 controller:
+  electionID: ingress-controller-leader
   ingressClassResource:
     name: internal-nginx  # default: nginx
     enabled: true
diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh
index 9023a3a1a..fadc67633 100755
--- a/hack/update-codegen.sh
+++ b/hack/update-codegen.sh
@@ -38,7 +38,7 @@ chmod +x ${CODEGEN_PKG}/generate-groups.sh
 #  nginxingress:v1alpha1 \
 #  --output-base "$(dirname ${BASH_SOURCE})/../../.."
 ${CODEGEN_PKG}/generate-groups.sh "deepcopy" \
-  k8s.io/ingress-nginx/internal k8s.io/ingress-nginx/internal \
+  k8s.io/ingress-nginx/internal k8s.io/ingress-nginx/pkg/apis \
   .:ingress \
   --output-base "$(dirname ${BASH_SOURCE})/../../.." \
   --go-header-file ${SCRIPT_ROOT}/hack/boilerplate/boilerplate.generated.go.txt
diff --git a/images/cfssl/rootfs/Dockerfile b/images/cfssl/rootfs/Dockerfile
index bfe19cfd9..59a89d92c 100644
--- a/images/cfssl/rootfs/Dockerfile
+++ b/images/cfssl/rootfs/Dockerfile
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM alpine:3.16.0
+FROM alpine:3.16.1
 
 RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
 RUN apk add --no-cache \
diff --git a/images/httpbin/rootfs/Dockerfile b/images/httpbin/rootfs/Dockerfile
index 5ee58d69c..016ab913f 100644
--- a/images/httpbin/rootfs/Dockerfile
+++ b/images/httpbin/rootfs/Dockerfile
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM alpine:3.16.0
+FROM alpine:3.16.1
 
 ENV LC_ALL=C.UTF-8
 ENV LANG=C.UTF-8
diff --git a/images/nginx/rootfs/Dockerfile b/images/nginx/rootfs/Dockerfile
index fd3dfe5ba..a93a58f8f 100644
--- a/images/nginx/rootfs/Dockerfile
+++ b/images/nginx/rootfs/Dockerfile
@@ -11,7 +11,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-FROM alpine:3.16.0 as builder
+FROM alpine:3.16.1 as builder
 
 COPY . /
 
@@ -21,7 +21,7 @@ RUN apk update \
   && /build.sh
 
 # Use a multi-stage build
-FROM alpine:3.16.0
+FROM alpine:3.16.1
 
 ENV PATH=$PATH:/usr/local/luajit/bin:/usr/local/nginx/sbin:/usr/local/nginx/bin
 
diff --git a/images/nginx/rootfs/build.sh b/images/nginx/rootfs/build.sh
index c23ed8681..f3efb3663 100755
--- a/images/nginx/rootfs/build.sh
+++ b/images/nginx/rootfs/build.sh
@@ -53,8 +53,8 @@ export JAEGER_VERSION=0.7.0
 # Check for recent changes: https://github.com/msgpack/msgpack-c/compare/cpp-3.3.0...master
 export MSGPACK_VERSION=3.3.0
 
-# Check for recent changes: https://github.com/DataDog/dd-opentracing-cpp/compare/v1.3.0...master
-export DATADOG_CPP_VERSION=af53c523787cca108ae9f458ea5c962e48187a36
+# Check for recent changes: https://github.com/DataDog/dd-opentracing-cpp/compare/v1.3.2...master
+export DATADOG_CPP_VERSION=1.3.2
 
 # Check for recent changes: https://github.com/SpiderLabs/ModSecurity-nginx/compare/v1.0.2...master
 export MODSECURITY_VERSION=1.0.2
@@ -264,8 +264,8 @@ get_src 1ee6dad809a5bb22efb45e6dac767f7ce544ad652d353a93d7f26b605f69fe3f \
         "https://github.com/openresty/luajit2/archive/v$LUAJIT_VERSION.tar.gz"
 fi
 
-get_src f29393f2cd9288105a0029a6a324fe1f7558a9e7e852d59a6355f7581bb90e30 \
-        "https://github.com/DataDog/dd-opentracing-cpp/archive/$DATADOG_CPP_VERSION.tar.gz"
+get_src 586f92166018cc27080d34e17c59d68219b85af745edf3cc9fe41403fc9b4ac6 \
+        "https://github.com/DataDog/dd-opentracing-cpp/archive/v$DATADOG_CPP_VERSION.tar.gz"
 
 get_src 1af5a5632dc8b00ae103d51b7bf225de3a7f0df82f5c6a401996c080106e600e \
         "https://github.com/influxdata/nginx-influxdb-module/archive/$NGINX_INFLUXDB_VERSION.tar.gz"
diff --git a/images/opentelemetry/rootfs/Dockerfile b/images/opentelemetry/rootfs/Dockerfile
index 18fea3d51..ccab2223d 100644
--- a/images/opentelemetry/rootfs/Dockerfile
+++ b/images/opentelemetry/rootfs/Dockerfile
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 
-FROM alpine:3.16.0 as base
+FROM alpine:3.16.1 as base
 
 RUN mkdir -p /opt/third_party/install
 COPY . /opt/third_party/
@@ -39,7 +39,7 @@ COPY --from=grpc /opt/third_party/install/ /usr
 COPY --from=otel-cpp /opt/third_party/install/ /usr
 RUN bash /opt/third_party/build.sh -n
 
-FROM alpine:3.16.0
+FROM alpine:3.16.1
 COPY --from=base /opt/third_party/init_module.sh /usr/local/bin/init_module.sh
 COPY --from=nginx /etc/nginx/modules /etc/nginx/modules
 COPY --from=nginx /opt/third_party/install/lib /etc/nginx/modules
diff --git a/internal/ingress/annotations/authreq/main.go b/internal/ingress/annotations/authreq/main.go
index b5dc4c70b..b607f5482 100644
--- a/internal/ingress/annotations/authreq/main.go
+++ b/internal/ingress/annotations/authreq/main.go
@@ -28,7 +28,7 @@ import (
 	"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
 	ing_errors "k8s.io/ingress-nginx/internal/ingress/errors"
 	"k8s.io/ingress-nginx/internal/ingress/resolver"
-	"k8s.io/ingress-nginx/internal/sets"
+	"k8s.io/ingress-nginx/pkg/util/sets"
 )
 
 // Config returns external authentication configuration for an Ingress rule
diff --git a/internal/ingress/annotations/globalratelimit/main.go b/internal/ingress/annotations/globalratelimit/main.go
index c5763d0cb..ea9fc4678 100644
--- a/internal/ingress/annotations/globalratelimit/main.go
+++ b/internal/ingress/annotations/globalratelimit/main.go
@@ -27,7 +27,7 @@ import (
 	ing_errors "k8s.io/ingress-nginx/internal/ingress/errors"
 	"k8s.io/ingress-nginx/internal/ingress/resolver"
 	"k8s.io/ingress-nginx/internal/net"
-	"k8s.io/ingress-nginx/internal/sets"
+	"k8s.io/ingress-nginx/pkg/util/sets"
 )
 
 const defaultKey = "$remote_addr"
diff --git a/internal/ingress/annotations/ipwhitelist/main.go b/internal/ingress/annotations/ipwhitelist/main.go
index 38610ade6..63c049fef 100644
--- a/internal/ingress/annotations/ipwhitelist/main.go
+++ b/internal/ingress/annotations/ipwhitelist/main.go
@@ -27,7 +27,7 @@ import (
 	"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
 	ing_errors "k8s.io/ingress-nginx/internal/ingress/errors"
 	"k8s.io/ingress-nginx/internal/ingress/resolver"
-	"k8s.io/ingress-nginx/internal/sets"
+	"k8s.io/ingress-nginx/pkg/util/sets"
 )
 
 // SourceRange returns the CIDR
diff --git a/internal/ingress/annotations/ratelimit/main.go b/internal/ingress/annotations/ratelimit/main.go
index 4011c2542..84a5f10f0 100644
--- a/internal/ingress/annotations/ratelimit/main.go
+++ b/internal/ingress/annotations/ratelimit/main.go
@@ -26,7 +26,7 @@ import (
 	"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
 	"k8s.io/ingress-nginx/internal/ingress/resolver"
 	"k8s.io/ingress-nginx/internal/net"
-	"k8s.io/ingress-nginx/internal/sets"
+	"k8s.io/ingress-nginx/pkg/util/sets"
 )
 
 const (
diff --git a/internal/ingress/controller/config/config.go b/internal/ingress/controller/config/config.go
index dfc90c385..4ee2df965 100644
--- a/internal/ingress/controller/config/config.go
+++ b/internal/ingress/controller/config/config.go
@@ -24,8 +24,8 @@ import (
 
 	apiv1 "k8s.io/api/core/v1"
 
-	"k8s.io/ingress-nginx/internal/ingress"
 	"k8s.io/ingress-nginx/internal/ingress/defaults"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 	"k8s.io/ingress-nginx/pkg/util/runtime"
 )
 
diff --git a/internal/ingress/controller/controller.go b/internal/ingress/controller/controller.go
index 44385f175..d0f85bb01 100644
--- a/internal/ingress/controller/controller.go
+++ b/internal/ingress/controller/controller.go
@@ -32,7 +32,6 @@ import (
 	"k8s.io/apimachinery/pkg/util/sets"
 	"k8s.io/apimachinery/pkg/util/wait"
 	clientset "k8s.io/client-go/kubernetes"
-	"k8s.io/ingress-nginx/internal/ingress"
 	"k8s.io/ingress-nginx/internal/ingress/annotations"
 	"k8s.io/ingress-nginx/internal/ingress/annotations/log"
 	"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
@@ -45,6 +44,7 @@ import (
 	"k8s.io/ingress-nginx/internal/ingress/metric/collectors"
 	"k8s.io/ingress-nginx/internal/k8s"
 	"k8s.io/ingress-nginx/internal/nginx"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 	"k8s.io/klog/v2"
 )
 
diff --git a/internal/ingress/controller/endpoints.go b/internal/ingress/controller/endpoints.go
index 26d7f298e..5615fadea 100644
--- a/internal/ingress/controller/endpoints.go
+++ b/internal/ingress/controller/endpoints.go
@@ -29,8 +29,8 @@ import (
 
 	corev1 "k8s.io/api/core/v1"
 
-	"k8s.io/ingress-nginx/internal/ingress"
 	"k8s.io/ingress-nginx/internal/k8s"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 // getEndpoints returns a list of Endpoint structs for a given service/target port combination.
diff --git a/internal/ingress/controller/location.go b/internal/ingress/controller/location.go
index d40e88960..9776f8c87 100644
--- a/internal/ingress/controller/location.go
+++ b/internal/ingress/controller/location.go
@@ -21,7 +21,7 @@ import (
 	"strings"
 
 	networking "k8s.io/api/networking/v1"
-	"k8s.io/ingress-nginx/internal/ingress"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 var (
diff --git a/internal/ingress/controller/nginx.go b/internal/ingress/controller/nginx.go
index 41ec0445a..d0f4abe27 100644
--- a/internal/ingress/controller/nginx.go
+++ b/internal/ingress/controller/nginx.go
@@ -44,9 +44,9 @@ import (
 	v1core "k8s.io/client-go/kubernetes/typed/core/v1"
 	"k8s.io/client-go/tools/record"
 	"k8s.io/client-go/util/flowcontrol"
+	"k8s.io/ingress-nginx/pkg/tcpproxy"
 
 	adm_controller "k8s.io/ingress-nginx/internal/admission/controller"
-	"k8s.io/ingress-nginx/internal/ingress"
 	ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config"
 	"k8s.io/ingress-nginx/internal/ingress/controller/process"
 	"k8s.io/ingress-nginx/internal/ingress/controller/store"
@@ -58,7 +58,7 @@ import (
 	"k8s.io/ingress-nginx/internal/net/ssl"
 	"k8s.io/ingress-nginx/internal/nginx"
 	"k8s.io/ingress-nginx/internal/task"
-	"k8s.io/ingress-nginx/internal/watch"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 
 	"k8s.io/ingress-nginx/pkg/util/file"
 	klog "k8s.io/klog/v2"
@@ -102,7 +102,7 @@ func NewNGINXController(config *Configuration, mc metric.Collector) *NGINXContro
 
 		runningConfig: new(ingress.Configuration),
 
-		Proxy: &TCPProxy{},
+		Proxy: &tcpproxy.TCPProxy{},
 
 		metricCollector: mc,
 
@@ -172,7 +172,7 @@ func NewNGINXController(config *Configuration, mc metric.Collector) *NGINXContro
 
 	n.t = ngxTpl
 
-	_, err = watch.NewFileWatcher(nginx.TemplatePath, onTemplateChange)
+	_, err = file.NewFileWatcher(nginx.TemplatePath, onTemplateChange)
 	if err != nil {
 		klog.Fatalf("Error creating file watcher for %v: %v", nginx.TemplatePath, err)
 	}
@@ -196,7 +196,7 @@ func NewNGINXController(config *Configuration, mc metric.Collector) *NGINXContro
 	}
 
 	for _, f := range filesToWatch {
-		_, err = watch.NewFileWatcher(f, func() {
+		_, err = file.NewFileWatcher(f, func() {
 			klog.InfoS("File changed detected. Reloading NGINX", "path", f)
 			n.syncQueue.EnqueueTask(task.GetDummyObject("file-change"))
 		})
@@ -242,7 +242,7 @@ type NGINXController struct {
 
 	isShuttingDown bool
 
-	Proxy *TCPProxy
+	Proxy *tcpproxy.TCPProxy
 
 	store store.Storer
 
@@ -440,7 +440,7 @@ func (n NGINXController) DefaultEndpoint() ingress.Endpoint {
 func (n NGINXController) generateTemplate(cfg ngx_config.Configuration, ingressCfg ingress.Configuration) ([]byte, error) {
 
 	if n.cfg.EnableSSLPassthrough {
-		servers := []*TCPServer{}
+		servers := []*tcpproxy.TCPServer{}
 		for _, pb := range ingressCfg.PassthroughBackends {
 			svc := pb.Service
 			if svc == nil {
@@ -465,7 +465,7 @@ func (n NGINXController) generateTemplate(cfg ngx_config.Configuration, ingressC
 			}
 
 			// TODO: Allow PassthroughBackends to specify they support proxy-protocol
-			servers = append(servers, &TCPServer{
+			servers = append(servers, &tcpproxy.TCPServer{
 				Hostname:      pb.Hostname,
 				IP:            svc.Spec.ClusterIP,
 				Port:          port,
@@ -752,8 +752,8 @@ func (n *NGINXController) setupSSLProxy() {
 	proxyPort := n.cfg.ListenPorts.SSLProxy
 
 	klog.InfoS("Starting TLS proxy for SSL Passthrough")
-	n.Proxy = &TCPProxy{
-		Default: &TCPServer{
+	n.Proxy = &tcpproxy.TCPProxy{
+		Default: &tcpproxy.TCPServer{
 			Hostname:      "localhost",
 			IP:            "127.0.0.1",
 			Port:          proxyPort,
diff --git a/internal/ingress/controller/store/backend_ssl.go b/internal/ingress/controller/store/backend_ssl.go
index 96164b95e..6f0fcf189 100644
--- a/internal/ingress/controller/store/backend_ssl.go
+++ b/internal/ingress/controller/store/backend_ssl.go
@@ -24,7 +24,7 @@ import (
 	networking "k8s.io/api/networking/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	"k8s.io/ingress-nginx/internal/ingress"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 
 	klog "k8s.io/klog/v2"
 
diff --git a/internal/ingress/controller/store/ingress.go b/internal/ingress/controller/store/ingress.go
index 1d8ccb342..d05b2624b 100644
--- a/internal/ingress/controller/store/ingress.go
+++ b/internal/ingress/controller/store/ingress.go
@@ -19,7 +19,7 @@ package store
 import (
 	networking "k8s.io/api/networking/v1"
 	"k8s.io/client-go/tools/cache"
-	"k8s.io/ingress-nginx/internal/ingress"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 // IngressLister makes a Store that lists Ingress.
diff --git a/internal/ingress/controller/store/ingress_annotation.go b/internal/ingress/controller/store/ingress_annotation.go
index c9c596d1e..b70ceb1c6 100644
--- a/internal/ingress/controller/store/ingress_annotation.go
+++ b/internal/ingress/controller/store/ingress_annotation.go
@@ -18,7 +18,7 @@ package store
 
 import (
 	"k8s.io/client-go/tools/cache"
-	"k8s.io/ingress-nginx/internal/ingress"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 // IngressWithAnnotationsLister makes a Store that lists Ingress rules with annotations already parsed
diff --git a/internal/ingress/controller/store/local_secret.go b/internal/ingress/controller/store/local_secret.go
index ee3ced398..8b26e7a53 100644
--- a/internal/ingress/controller/store/local_secret.go
+++ b/internal/ingress/controller/store/local_secret.go
@@ -21,7 +21,7 @@ import (
 
 	"k8s.io/client-go/tools/cache"
 
-	"k8s.io/ingress-nginx/internal/ingress"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 // SSLCertTracker holds a store of referenced Secrets in Ingress rules
diff --git a/internal/ingress/controller/store/store.go b/internal/ingress/controller/store/store.go
index 72300a4de..239fbaaf5 100644
--- a/internal/ingress/controller/store/store.go
+++ b/internal/ingress/controller/store/store.go
@@ -48,7 +48,6 @@ import (
 	"k8s.io/ingress-nginx/pkg/util/file"
 	klog "k8s.io/klog/v2"
 
-	"k8s.io/ingress-nginx/internal/ingress"
 	"k8s.io/ingress-nginx/internal/ingress/annotations"
 	"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
 	ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config"
@@ -58,6 +57,7 @@ import (
 	"k8s.io/ingress-nginx/internal/ingress/errors"
 	"k8s.io/ingress-nginx/internal/ingress/resolver"
 	"k8s.io/ingress-nginx/internal/k8s"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 // IngressFilterFunc decides if an Ingress should be omitted or not
diff --git a/internal/ingress/controller/template/template.go b/internal/ingress/controller/template/template.go
index a331c196a..8d4cb6e75 100644
--- a/internal/ingress/controller/template/template.go
+++ b/internal/ingress/controller/template/template.go
@@ -40,12 +40,12 @@ import (
 	"k8s.io/apimachinery/pkg/util/sets"
 	"k8s.io/klog/v2"
 
-	"k8s.io/ingress-nginx/internal/ingress"
 	"k8s.io/ingress-nginx/internal/ingress/annotations/influxdb"
 	"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
 	"k8s.io/ingress-nginx/internal/ingress/annotations/ratelimit"
 	"k8s.io/ingress-nginx/internal/ingress/controller/config"
 	ing_net "k8s.io/ingress-nginx/internal/net"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 const (
diff --git a/internal/ingress/controller/util.go b/internal/ingress/controller/util.go
index a8232ed0e..6562dd17c 100644
--- a/internal/ingress/controller/util.go
+++ b/internal/ingress/controller/util.go
@@ -28,7 +28,7 @@ import (
 	api "k8s.io/api/core/v1"
 	networking "k8s.io/api/networking/v1"
 	"k8s.io/apimachinery/pkg/util/intstr"
-	"k8s.io/ingress-nginx/internal/ingress"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 	klog "k8s.io/klog/v2"
 )
 
diff --git a/internal/ingress/metric/collectors/controller.go b/internal/ingress/metric/collectors/controller.go
index e4e2655c8..5822f0d57 100644
--- a/internal/ingress/metric/collectors/controller.go
+++ b/internal/ingress/metric/collectors/controller.go
@@ -22,7 +22,7 @@ import (
 
 	"github.com/prometheus/client_golang/prometheus"
 	"k8s.io/apimachinery/pkg/util/sets"
-	"k8s.io/ingress-nginx/internal/ingress"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 	"k8s.io/ingress-nginx/version"
 	"k8s.io/klog/v2"
 )
diff --git a/internal/ingress/metric/dummy.go b/internal/ingress/metric/dummy.go
index 8360dc87d..4a6366b84 100644
--- a/internal/ingress/metric/dummy.go
+++ b/internal/ingress/metric/dummy.go
@@ -18,7 +18,7 @@ package metric
 
 import (
 	"k8s.io/apimachinery/pkg/util/sets"
-	"k8s.io/ingress-nginx/internal/ingress"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 // NewDummyCollector returns a dummy metric collector
diff --git a/internal/ingress/metric/main.go b/internal/ingress/metric/main.go
index a0aea1e71..b3323c7fe 100644
--- a/internal/ingress/metric/main.go
+++ b/internal/ingress/metric/main.go
@@ -25,8 +25,8 @@ import (
 	"k8s.io/klog/v2"
 
 	"k8s.io/apimachinery/pkg/util/sets"
-	"k8s.io/ingress-nginx/internal/ingress"
 	"k8s.io/ingress-nginx/internal/ingress/metric/collectors"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 // Collector defines the interface for a metric collector
diff --git a/internal/ingress/status/status.go b/internal/ingress/status/status.go
index bf79701fc..2e53682a0 100644
--- a/internal/ingress/status/status.go
+++ b/internal/ingress/status/status.go
@@ -34,9 +34,9 @@ import (
 	"k8s.io/apimachinery/pkg/util/wait"
 	clientset "k8s.io/client-go/kubernetes"
 
-	"k8s.io/ingress-nginx/internal/ingress"
 	"k8s.io/ingress-nginx/internal/k8s"
 	"k8s.io/ingress-nginx/internal/task"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 // UpdateInterval defines the time interval, in seconds, in
diff --git a/internal/net/ssl/ssl.go b/internal/net/ssl/ssl.go
index 339724095..05ec10bc5 100644
--- a/internal/net/ssl/ssl.go
+++ b/internal/net/ssl/ssl.go
@@ -40,12 +40,11 @@ import (
 	"github.com/zakjan/cert-chain-resolver/certUtil"
 	"k8s.io/apimachinery/pkg/util/sets"
 
-	"k8s.io/ingress-nginx/internal/ingress"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 
 	ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config"
-	"k8s.io/ingress-nginx/internal/watch"
-
 	"k8s.io/ingress-nginx/pkg/util/file"
+
 	klog "k8s.io/klog/v2"
 )
 
@@ -509,8 +508,8 @@ func NewTLSListener(certificate, key string) *TLSListener {
 
 	l.load()
 
-	_, _ = watch.NewFileWatcher(certificate, l.load)
-	_, _ = watch.NewFileWatcher(key, l.load)
+	_, _ = file.NewFileWatcher(certificate, l.load)
+	_, _ = file.NewFileWatcher(key, l.load)
 
 	return &l
 }
diff --git a/internal/ingress/sslcert.go b/pkg/apis/ingress/sslcert.go
similarity index 100%
rename from internal/ingress/sslcert.go
rename to pkg/apis/ingress/sslcert.go
diff --git a/internal/ingress/types.go b/pkg/apis/ingress/types.go
similarity index 98%
rename from internal/ingress/types.go
rename to pkg/apis/ingress/types.go
index db4f37f99..8460ee684 100644
--- a/internal/ingress/types.go
+++ b/pkg/apis/ingress/types.go
@@ -42,13 +42,8 @@ import (
 	"k8s.io/ingress-nginx/internal/ingress/annotations/rewrite"
 )
 
-var (
-	// DefaultSSLDirectory defines the location where the SSL certificates will be generated
-	// This directory contains all the SSL certificates that are specified in Ingress rules.
-	// The name of each file is <namespace>-<secret name>.pem. The content is the concatenated
-	// certificate and key.
-	DefaultSSLDirectory = "/ingress-controller/ssl"
-)
+// TODO: The API shouldn't be importing structs from annotation code. Instead we probably want a conversion from internal
+// to API object, or see how much effort is to move the structs of annotations to become an "API'ish" as well
 
 // Configuration holds the definition of all the parts required to describe all
 // ingresses reachable by the ingress controller (using a filter by namespace)
diff --git a/internal/ingress/types_equals.go b/pkg/apis/ingress/types_equals.go
similarity index 99%
rename from internal/ingress/types_equals.go
rename to pkg/apis/ingress/types_equals.go
index 3e39940a3..1ba80d07e 100644
--- a/internal/ingress/types_equals.go
+++ b/pkg/apis/ingress/types_equals.go
@@ -17,7 +17,7 @@ limitations under the License.
 package ingress
 
 import (
-	"k8s.io/ingress-nginx/internal/sets"
+	"k8s.io/ingress-nginx/pkg/util/sets"
 )
 
 // Equal tests for equality between two Configuration types
diff --git a/internal/ingress/zz_generated.deepcopy.go b/pkg/apis/ingress/zz_generated.deepcopy.go
similarity index 100%
rename from internal/ingress/zz_generated.deepcopy.go
rename to pkg/apis/ingress/zz_generated.deepcopy.go
diff --git a/internal/ingress/controller/tcp.go b/pkg/tcpproxy/tcp.go
similarity index 99%
rename from internal/ingress/controller/tcp.go
rename to pkg/tcpproxy/tcp.go
index eedecc71a..7bbff80b4 100644
--- a/internal/ingress/controller/tcp.go
+++ b/pkg/tcpproxy/tcp.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package controller
+package tcpproxy
 
 import (
 	"fmt"
diff --git a/internal/watch/file_watcher.go b/pkg/util/file/file_watcher.go
similarity index 99%
rename from internal/watch/file_watcher.go
rename to pkg/util/file/file_watcher.go
index b393045b2..eeb7b5721 100644
--- a/internal/watch/file_watcher.go
+++ b/pkg/util/file/file_watcher.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package watch
+package file
 
 import (
 	"log"
diff --git a/internal/sets/match.go b/pkg/util/sets/match.go
similarity index 100%
rename from internal/sets/match.go
rename to pkg/util/sets/match.go
diff --git a/internal/sets/match_test.go b/pkg/util/sets/match_test.go
similarity index 100%
rename from internal/sets/match_test.go
rename to pkg/util/sets/match_test.go
diff --git a/rootfs/Dockerfile-chroot b/rootfs/Dockerfile-chroot
index 69d2a0f71..de2fd6da0 100644
--- a/rootfs/Dockerfile-chroot
+++ b/rootfs/Dockerfile-chroot
@@ -23,7 +23,7 @@ RUN apk update \
   && apk upgrade \
   && /chroot.sh
 
-FROM alpine:3.16.0
+FROM alpine:3.16.1
 
 ARG TARGETARCH
 ARG VERSION


Test patch:
diff --git a/internal/ingress/controller/controller_test.go b/internal/ingress/controller/controller_test.go
index 0e8ae9d62..f875632e0 100644
--- a/internal/ingress/controller/controller_test.go
+++ b/internal/ingress/controller/controller_test.go
@@ -39,7 +39,7 @@ import (
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/client-go/kubernetes/fake"
 
-	"k8s.io/ingress-nginx/internal/ingress"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 
 	"k8s.io/ingress-nginx/internal/ingress/annotations"
 	"k8s.io/ingress-nginx/internal/ingress/annotations/canary"
diff --git a/internal/ingress/controller/endpoints_test.go b/internal/ingress/controller/endpoints_test.go
index 83c8e1837..f38ffabe7 100644
--- a/internal/ingress/controller/endpoints_test.go
+++ b/internal/ingress/controller/endpoints_test.go
@@ -22,7 +22,7 @@ import (
 
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/util/intstr"
-	"k8s.io/ingress-nginx/internal/ingress"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 func TestGetEndpoints(t *testing.T) {
diff --git a/internal/ingress/controller/nginx_test.go b/internal/ingress/controller/nginx_test.go
index d168efffd..c2c71b797 100644
--- a/internal/ingress/controller/nginx_test.go
+++ b/internal/ingress/controller/nginx_test.go
@@ -32,8 +32,8 @@ import (
 	apiv1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/util/wait"
 
-	"k8s.io/ingress-nginx/internal/ingress"
 	"k8s.io/ingress-nginx/internal/nginx"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 func TestIsDynamicConfigurationEnough(t *testing.T) {
diff --git a/internal/ingress/controller/store/store_test.go b/internal/ingress/controller/store/store_test.go
index 4868f792f..9b8947f9c 100644
--- a/internal/ingress/controller/store/store_test.go
+++ b/internal/ingress/controller/store/store_test.go
@@ -36,9 +36,9 @@ import (
 	"k8s.io/client-go/tools/cache"
 	"sigs.k8s.io/controller-runtime/pkg/envtest"
 
-	"k8s.io/ingress-nginx/internal/ingress"
 	"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
 	"k8s.io/ingress-nginx/internal/ingress/controller/ingressclass"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 	"k8s.io/ingress-nginx/test/e2e/framework"
 )
 
diff --git a/internal/ingress/controller/template/template_test.go b/internal/ingress/controller/template/template_test.go
index a741919ed..cb1ebd1b7 100644
--- a/internal/ingress/controller/template/template_test.go
+++ b/internal/ingress/controller/template/template_test.go
@@ -34,7 +34,6 @@ import (
 	networking "k8s.io/api/networking/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	"k8s.io/ingress-nginx/internal/ingress"
 	"k8s.io/ingress-nginx/internal/ingress/annotations/authreq"
 	"k8s.io/ingress-nginx/internal/ingress/annotations/influxdb"
 	"k8s.io/ingress-nginx/internal/ingress/annotations/modsecurity"
@@ -43,6 +42,7 @@ import (
 	"k8s.io/ingress-nginx/internal/ingress/annotations/rewrite"
 	"k8s.io/ingress-nginx/internal/ingress/controller/config"
 	"k8s.io/ingress-nginx/internal/nginx"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 func init() {
diff --git a/internal/ingress/metric/collectors/controller_test.go b/internal/ingress/metric/collectors/controller_test.go
index bc9f21c60..ef80bc96a 100644
--- a/internal/ingress/metric/collectors/controller_test.go
+++ b/internal/ingress/metric/collectors/controller_test.go
@@ -24,7 +24,7 @@ import (
 	"time"
 
 	"github.com/prometheus/client_golang/prometheus"
-	"k8s.io/ingress-nginx/internal/ingress"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 func TestControllerCounters(t *testing.T) {
diff --git a/internal/ingress/status/status_test.go b/internal/ingress/status/status_test.go
index fefca5ff2..d4ef09e7c 100644
--- a/internal/ingress/status/status_test.go
+++ b/internal/ingress/status/status_test.go
@@ -28,10 +28,10 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	testclient "k8s.io/client-go/kubernetes/fake"
 
-	"k8s.io/ingress-nginx/internal/ingress"
 	"k8s.io/ingress-nginx/internal/ingress/controller/ingressclass"
 	"k8s.io/ingress-nginx/internal/k8s"
 	"k8s.io/ingress-nginx/internal/task"
+	"k8s.io/ingress-nginx/pkg/apis/ingress"
 )
 
 func buildLoadBalancerIngressByIP() []apiv1.LoadBalancerIngress {
diff --git a/internal/ingress/types_equals_test.go b/pkg/apis/ingress/types_equals_test.go
similarity index 96%
rename from internal/ingress/types_equals_test.go
rename to pkg/apis/ingress/types_equals_test.go
index 8119d26c7..78d29d46c 100644
--- a/internal/ingress/types_equals_test.go
+++ b/pkg/apis/ingress/types_equals_test.go
@@ -25,19 +25,19 @@ import (
 )
 
 func TestEqualConfiguration(t *testing.T) {
-	ap, _ := filepath.Abs("../../test/manifests/configuration-a.json")
+	ap, _ := filepath.Abs("../../../test/manifests/configuration-a.json")
 	a, err := readJSON(ap)
 	if err != nil {
 		t.Errorf("unexpected error reading JSON file: %v", err)
 	}
 
-	bp, _ := filepath.Abs("../../test/manifests/configuration-b.json")
+	bp, _ := filepath.Abs("../../../test/manifests/configuration-b.json")
 	b, err := readJSON(bp)
 	if err != nil {
 		t.Errorf("unexpected error reading JSON file: %v", err)
 	}
 
-	cp, _ := filepath.Abs("../../test/manifests/configuration-c.json")
+	cp, _ := filepath.Abs("../../../test/manifests/configuration-c.json")
 	c, err := readJSON(cp)
 	if err != nil {
 		t.Errorf("unexpected error reading JSON file: %v", err)
diff --git a/internal/watch/file_watcher_test.go b/pkg/util/file/file_watcher_test.go
similarity index 96%
rename from internal/watch/file_watcher_test.go
rename to pkg/util/file/file_watcher_test.go
index e1f5ed30d..316cb6f1e 100644
--- a/internal/watch/file_watcher_test.go
+++ b/pkg/util/file/file_watcher_test.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package watch
+package file
 
 import (
 	"os"
@@ -22,8 +22,6 @@ import (
 	"path/filepath"
 	"testing"
 	"time"
-
-	"k8s.io/ingress-nginx/pkg/util/file"
 )
 
 func prepareTimeout() chan bool {
@@ -61,7 +59,7 @@ func TestFileWatcher(t *testing.T) {
 		t.Fatalf("expected no events before writing a file")
 	case <-timeoutChan:
 	}
-	os.WriteFile(f.Name(), []byte{}, file.ReadWriteByUser)
+	os.WriteFile(f.Name(), []byte{}, ReadWriteByUser)
 	select {
 	case <-events:
 	case <-timeoutChan:
diff --git a/test/e2e-image/Dockerfile b/test/e2e-image/Dockerfile
index e29c7524b..d88338d65 100644
--- a/test/e2e-image/Dockerfile
+++ b/test/e2e-image/Dockerfile
@@ -1,7 +1,7 @@
 ARG E2E_BASE_IMAGE
 FROM ${E2E_BASE_IMAGE} AS BASE
 
-FROM alpine:3.16.0
+FROM alpine:3.16.1
 
 RUN apk add -U --no-cache \
   ca-certificates \