我不确切知道您的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
我在我的 GKE 上使用 1.13 版本,所以这个技巧也适用于我的案例:
小费
如果您使用的是之前的 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
然后我们将前往提供者特定步骤,如果是GKE,则归结为应用以下内容yaml
:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.27.1/deploy/static/provider/cloud-generic.yaml
然后您可能想要验证您的安装:
要检查入口控制器 pod 是否已启动,请运行以下命令:
kubectl get pods --all-namespaces -l app.kubernetes.io/name=ingress-nginx --watch
或简单地运行:
kubectl get all -n ingress-nginx
它还会告诉您是否正确部署了所有必需的资源。
接下来我们需要编写包含basic-auth
相关的入口(入口对象/资源) 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
中的文件略有不同,即我刚刚添加以确保使用我的nginx 入口控制器而不是内置的 GKE 解决方案:kubernetes.io/ingress.class: nginx
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
or访问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
I'm requestig 设置为我想要的任何值。
您也可以使用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
对您的定义的注释。容器专门公开端口 8080的事实pypiserver
并不意味着您在通过入口访问它时需要使用此端口。在Service
定义中,由 暴露的端口Container
被称为targetPort
。您需要在定义时指定它,Service
但Service
它本身可以公开完全不同的端口。我Service
使用以下命令定义了我的:
kubectl expose deployment pypiserver --type=LoadBalancer --port=80 --target-port=8080
请注意,type
应设置为NodePort
或LoadBalancer
。然后在您的入口定义中,您不必使用8080
,而是80
您的pypiserver
Service
. 请注意,servicePort: 80
在我的ingress object/resource
定义中有。您example.com
在cloudflare中的域应该指向A record
您的nginx ingress controller
LoadBalancer
Service
IP ( kubectl get svc -n ingress-nginx
),而不指定任何端口。