Я точно не знаю, какая у вас nginx входная версия контроллера , но я могу поделиться тем, что сработало для меня. Я воспроизвел его на своем кластере GKE .
Я установил свой nginx входной контроллер, следуя этому руководству. В основном это сводилось к выполнению следующих команд:
Если вы используете GKE, вам нужно инициализировать вашего пользователя как администратор кластера с помощью следующей команды:
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole cluster-admin \
--user $(gcloud config get-value account)
Следующая обязательная команда требуется для всех развертываний.
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.27.1/deploy/static/mandatory.yaml
Я использую версию 1.13 в моем GKE, поэтому этот совет также применяется в моем случае:
Совет
Если вы используете версию Kubernetes, предшествующую 1.14
, вам нужно изменить kubernetes.io/os
на beta.kubernetes.io/os
в строке 217 из mandatory.yaml
, см. Детали меток.
Но я имел дело с этим совершенно по-другому. В основном вам нужно, чтобы у вашего Nodes
была метка kubernetes.io/os=linux
, чтобы вы могли просто пометить их. Следующая команда выполнит эту работу:
kubectl label node --all kubernetes.io/os=linux
Затем мы перейдем к Спецификация поставщика c Шаги , который в случае GKE сводится к применению следующие yaml
:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.27.1/deploy/static/provider/cloud-generic.yaml
Затем вы можете проверить вашу установку:
Чтобы проверить, запущены ли модули входного контроллера, запустите следующая команда:
kubectl get pods --all-namespaces -l app.kubernetes.io/name=ingress-nginx --watch
или просто запустить:
kubectl get all -n ingress-nginx
Она также сообщит вам, правильно ли развернуты все необходимые ресурсы.
Далее мы нужно написать наш входной (входной объект / ресурс), содержащий basic-auth
related annotations
. Я следовал тому же уроку , как указано в вашем вопросе.
Сначала нам нужно создать наш auth
файл, содержащий username
и хэшированный password
:
$ htpasswd -c auth foo
New password: <bar>
New password:
Re-type new password:
Adding password for user foo
Как только мы его получим, нам нужно создать Secret
объект, который мы будем использовать во входе:
$ kubectl create secret generic basic-auth --from-file=auth
secret "basic-auth" created
Как только он будет создан, мы можем проверить, все ли прошло хорошо:
$ kubectl get secret basic-auth -o yaml
apiVersion: v1
data:
auth: Zm9vOiRhcHIxJE9GRzNYeWJwJGNrTDBGSERBa29YWUlsSDkuY3lzVDAK
kind: Secret
metadata:
name: basic-auth
namespace: default
type: Opaque
Хорошо, пока все хорошо ...
Тогда нам нужно создать наш ingress resource/object
.
Мой ingress-with-auth.yaml
файл выглядит немного иначе, чем в инструкции , а именно я только что добавил kubernetes.io/ingress.class: nginx
, чтобы убедиться, что мой nginx входной контроллер используется вместо встроенного решения GKE:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-with-auth
annotations:
kubernetes.io/ingress.class: nginx
# type of authentication
nginx.ingress.kubernetes.io/auth-type: basic
# name of the secret that contains the user/password definitions
nginx.ingress.kubernetes.io/auth-secret: basic-auth
# message to display with an appropriate context why the authentication is required
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /
backend:
serviceName: pypiserver
servicePort: 80
В вашем примере вам может понадобиться добавить префикс nginx
в ваши basic-auth
связанные аннотации:
ingress.kubernetes.io/auth-type: basic
ingress.kubernetes.io/auth-secret: secret
ingress.kubernetes.io/auth-realm: "Authentication Required - ok"
, чтобы он выглядел как это:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: secret
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required - ok"
Сначала я использовал адрес, указанный в моем входном ресурсе (он больше не появляется, когда я добавил kubernetes.io/ingress.class: nginx
аннотацию в моем ingress
определении:
$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
ingress-with-auth foo.bar.com 80 117m
Когда я пытался получить доступ к pypi-server
с использованием этого IP-адреса, он сразу выводил меня на страницу без необходимости какой-либо аутентификации. Но похоже, что если вы не определили правильный класс доступа, вместо него используется значение по умолчанию, поэтому в попрактикуйтесь в определении ingress
с auth-basic
, детали не принимаются во внимание и не передаются на nginx входной контроллер , который мы установили на одном из предыдущих шагов.
Так какой IP-адрес следует использовать для получить доступ к вашему приложению? Выполните следующую команду, которая покажет вам как CLUSTER-IP
(доступ к которому возможен в вашем кластере из любого Pod
или Node
), так и EXTERNAL-IP
вашего nginx входного контроллера :
$ kubectl get service --namespace ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx LoadBalancer 10.0.3.220 35.111.112.113 80:30452/TCP,443:30006/TCP 18h
Вы можете разместить в своем кластере много разных сайтов, и все они будут доступны через этот IP. Все они могут быть доступны по умолчанию http 80
порт (или https 443
в вашем случае). Единственная разница между ними будет hostname
, который вы передадите в http
заголовок вашего http request
.
, так как у меня нет домена, указывающего на этот внешний IP-адрес, и я не могу просто зайдите на мой сайт, перейдя по http://foo.bar.com
Мне нужно как-то передать hostname
, который я запрашиваю с 35.111.112.113
адреса. Это можно сделать несколькими способами:
Я установил в своем браузере Google Chrome ModHeader расширение, которое позволяет мне изменять заголовки http-запроса и устанавливать hostname
Я запрашиваю любое значение, которое хочу.
Вы также можете сделать это, используя curl
следующим образом:
curl -v http://35.111.112.113 -H 'Host: foo.bar.com' -u 'foo:bar'
Вам будет предложено ввести аутентификацию.
Если вы не поставите флаг -u username:password
, вы должны получить 401 Authorization Required
.
В основном это все.
Дайте мне знать, помогло ли это вам. Не стесняйтесь задавать дополнительные вопросы, если что-то не совсем понятно.
Еще одна вещь. Если что-то по-прежнему не работает, вы можете начать с подключения к nginx входному контроллеру Pod
(сначала проверьте свое имя Pod
, введя kubectl get pods -n ingress-nginx
):
kubectl exec -ti -n ingress-nginx nginx-ingress-controller-pod /bin/bash
и проверьте содержимое вашего /etc/nginx/nginx.conf
файла. Ищите foo.bar.com
(или в вашем случае example.com
). Он должен содержать аналогичные строки:
auth_basic "Authentication Required - foo";
auth_basic_user_file /etc/ingress-controller/auth/default-ingress-with-auth.passwd;
Затем проверьте, присутствует ли файл в указанном месте /etc/ingress-controller/auth/default-ingress-with-auth.passwd
.
Одна заметка к вашему определению Service
. Тот факт, что контейнер pypiserver
предоставляет конкретный порт 8080, не означает, что вам нужно использовать этот порт при доступе к нему через вход. В определении Service
порт, предоставляемый Container
, называется targetPort
. Вы должны указать это при определении вашего Service
, но сам Service
может предоставить совершенно другой порт. Я определил Service
, используя следующую команду:
kubectl expose deployment pypiserver --type=LoadBalancer --port=80 --target-port=8080
Обратите внимание, что type
должно быть установлено на NodePort
или LoadBalancer
. Тогда в вашем входном определении вам не нужно использовать 8080
, а 80
, который является портом, выставленным вашим pypiserver
Service
. Обратите внимание, что в моем определении ingress object/resource
есть servicePort: 80
. Ваш example.com
домен в cloudflare должен указывать с A record
на ваш nginx ingress controller
LoadBalancer
Service
IP (kubectl get svc -n ingress-nginx
) без указания каких-либо портов.