Ingress Controller можно сравнить с консьержем в многоквартирном доме, где квартиры — это ваши приложения, к которым вы хотите получить доступ извне.
Когда кто-то из интернета хочет получить доступ к вашему приложению, запрос сначала поступает на Ingress Controller, а он уже перенаправляет его по адресу.
Рассмотрим на практике.
Создадим виртуальную машину на Ubuntu 22.04 LTS, установим Docker и сделаем Snapshot (он пригодится нам для следующих примеров).
Теперь установим minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube && rm minikube-linux-amd64
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker run hello-world
minikube config set driver docker
sudo usermod -aG docker $USER && newgrp docker
minikube start
Подождем, установим kubectl и проверим
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
kubectl version --client
kubectl get po -A
Теперь рассмотрим пример с Ingress Controller
Установим Ingress в наш minikube кластер
minikube addons enable ingress
Подождем и проверим
kubectl get pods -n ingress-nginx
Сделаем так, чтобы запрос на myapplication.ru/v1 был перенаправлен на версию приложения 1.0, а на myapplication.ru/v2 соответственно на версию 2.0.
В /etc/hosts добавим наш домен myapplication.ru и резолв на свой ip адрес
nano applications.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: appv1
spec:
replicas: 1
selector:
matchLabels:
app: v1
template:
metadata:
labels:
app: v1
spec:
containers:
- name: appv1
image: gcr.io/google-samples/hello-app:1.0
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: appv2
spec:
replicas: 1
selector:
matchLabels:
app: v2
template:
metadata:
labels:
app: v2
spec:
containers:
- name: appv2
image: gcr.io/google-samples/hello-app:2.0
---
apiVersion: v1
kind: Service
metadata:
name: appv1-service
labels:
app: v1
spec:
ports:
- port: 8080
nodePort: 30005
type: NodePort
selector:
app: v1
---
apiVersion: v1
kind: Service
metadata:
name: appv2-service
labels:
app: v2
spec:
ports:
- port: 8080
nodePort: 30006
type: NodePort
selector:
app: v2
Я выбрал NodePort, а не ClusterIP просто для примера, у нас не прод.
Запустим и проверим
kubectl apply -f applications.yaml
kubectl get pods
kubectl get services
Создадим наш Ingress
nano ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: appingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: myapplication.ru
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: appv1-service
port:
number: 8080
- path: /v2
pathType: Prefix
backend:
service:
name: appv2-service
port:
number: 8080
Запустим и проверим
kubectl apply -f ingress.yaml
kubectl get ingress
Теперь проверим
testvm:~$ curl http://myapplication.ru/v1
Hello, world!
Version: 1.0.0
Hostname: appv1-5d7fb68ff5-bd49l
testvm:~$ curl http://myapplication.ru/v2
Hello, world!
Version: 2.0.0
Hostname: appv2-69cb58d76b-fdwl2
Как видим все работает
Теперь остановим запущенные ресурсы или откатимся к нашему snapshot и рассмотрим другой пример
kubectl delete -f applications.yaml
kubectl delete -f ingress.yaml
Остановим minikube
minikube stop
Установим kind
[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.23.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
Запустим кластер
nano kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
extraPortMappings:
- containerPort: 80
hostPort: 80
listenAddress: "0.0.0.0"
- containerPort: 443
hostPort: 443
listenAddress: "0.0.0.0"
kind create cluster --config kind-config.yaml
Проверим
kubectl get nodes
Далее установим и проверим Contour
kubectl apply -f https://projectcontour.io/quickstart/contour.yaml
kubectl get pods -n projectcontour -o wide
Установим httpbin и проверим
kubectl apply -f https://projectcontour.io/examples/httpbin.yaml
kubectl get po,svc,ing -l app=httpbin
Сделаем port-forward с локальной машины на Envoy
kubectl -n projectcontour port-forward service/envoy 8888:80
В моей случае виртуалка запущена в Яндекс Облако, поэтому добавим опцию —address чтобы проверить доступ из интернета
kubectl -n projectcontour port-forward service/envoy 8888:80 --address 0.0.0.0
В браузере открываем http://158.160.109.6:8888 (у вас будет свой ip) и видим страницу httpbin.org

Далее остановим httpbin и удалим кластер
kubectl delete -f https://projectcontour.io/examples/httpbin.yaml
kind delete cluster
kind get clusters
Рассмотрим последний пример
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
EOF
kubectl get nodes
kind get clusters
Далее выполним
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
Проверим
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=90s
Запустим
kubectl apply -f https://kind.sigs.k8s.io/examples/ingress/usage.yaml
Проверим
curl localhost/foo/hostname
curl localhost/bar/hostname
В ответ видим
foo-app
bar-app
Мы рассмотрели очень простые примеры как локально, так и в облаке, но для базового понимания работы Ingress они вполне подходят.