我已经在kubernetes集群中创建了pypiserver,我使用了https://hub.docker.com/r/pypiserver/pypiserver docker镜像。我需要为我创建的服务器创建基本身份验证。我使用了这种方法https://kubernetes.github.io/ingress-nginx/examples/auth/basic/
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: pypiserver
labels:
app: pypiserver
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: 'true'
ingress.kubernetes.io/auth-type: basic
ingress.kubernetes.io/auth-secret: secret
ingress.kubernetes.io/auth-realm: "Authentication Required - ok"
spec:
rules:
- host: example.com
http:
paths:
- path: /
backend:
serviceName: pypiservice
servicePort: 8080
tls:
- hosts:
- example.com
secretName: secret-tls
但是我的主机名是“ www.example.com/8080”,我看不到入口在kubernetes集群中有任何Pod。 Ingress运行正常,但我没有对此主机进行身份验证。 (而且我还有http://IP地址:8080,我通过cloudflare转换为域)
请让我知道我在做错什么吗?
答案 0 :(得分:4)
我不确定您的 nginx入口控制器版本是什么,但是我可以分享对我有用的版本。我已经在我的GKE 集群上复制了它。
我按照this指南安装了Nginx入口控制器。基本上可以归结为运行以下命令:
如果您使用的是GKE,则需要将用户初始化为 使用以下命令执行cluster-admin:
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版本,因此本技巧也适用于我的情况:
提示
如果您使用的是
1.14
之前的Kubernetes版本,则需要 在第217行的kubernetes.io/os
更改为beta.kubernetes.io/os
mandatory.yaml
,请参阅标签详细信息。
但是我处理的方式大不相同。基本上,您需要Nodes
加上kubernetes.io/os=linux
标签,以便您可以简单地对其进行标签。以下命令将完成这项工作:
kubectl label node --all kubernetes.io/os=linux
然后我们要前往Provider Specific Steps,在GKE的情况下,可以应用以下yaml
:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.27.1/deploy/static/provider/cloud-generic.yaml
然后,您可能要verify安装:
要检查入口控制器舱是否已启动,请运行 以下命令:
kubectl get pods --all-namespaces -l app.kubernetes.io/name=ingress-nginx --watch
或简单地运行:
kubectl get all -n ingress-nginx
它还会告诉您是否正确部署了所有必需的资源。
接下来,我们需要编写包含basic-auth
相关annotations
的入口(入口对象/资源)。如您所提,我正在关注same tutorial。
首先,我们需要创建包含auth
和哈希值username
的{{1}}文件:
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
文件看起来与the instruction中的文件略有不同,即我刚刚添加了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
当我尝试使用此IP访问$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
ingress-with-auth foo.bar.com 80 117m
时,无需任何身份验证即可直接将我带到该页面。但是,如果您没有定义适当的入口类,则看起来像是使用默认值,因此实际上,您的pypi-server
定义和ingress
的详细信息不会被考虑,也不会传递给<我们在之前的步骤之一中安装了strong> nginx入口控制器。
那么应该使用哪个IP地址访问您的应用程序?运行以下命令,该命令将同时显示您的 nginx入口控制器auth-basic
(可以从群集中的任何CLUSTER-IP
或Pod
访问Node
) / strong>:
EXTERNAL-IP
您基本上可以在群集中托管许多不同的网站,并且所有这些网站都可以通过此IP访问。所有这些都可以在默认的$ 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
端口(或您的情况下为http 80
)上使用。它们之间的唯一区别是您在https 443
的{{1}}标头中传递的hostname
。
由于我没有指向该外部IP地址的域,并且无法通过访问http
来访问我的网站,因此我需要以某种方式传递我从{ {1}}地址。可以通过以下几种方式完成:
我已安装在 Google Chrome浏览器 ModHeader扩展程序中,该扩展程序允许我修改http请求标头并将http request
我的requestig设置为所需的任何值。
您也可以使用http://foo.bar.com
进行以下操作:
hostname
应该提示您进行身份验证。
如果您不提供35.111.112.113
标志,则应该获得hostname
。
基本上就是帽子。
让我知道它是否对您有帮助。如果有一些不清楚的地方,请随时询问其他问题。
还有一件事。如果仍然无法解决问题,则可以从连接到 nginx入口控制器 curl
开始(通过运行curl -v http://35.111.112.113 -H 'Host: foo.bar.com' -u 'foo:bar'
首先检查-u username:password
的名称):>
401 Authorization Required
并检查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
容器专门公开了端口8080的事实并不意味着您在通过入口访问该端口时需要使用此端口。在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
时需要指定它,但是Service
本身可以公开完全不同的端口。我使用以下命令定义了Container
:
targetPort
请注意,Service
应该设置为Service
或Service
。然后,在入口定义中,您不必使用kubectl expose deployment pypiserver --type=LoadBalancer --port=80 --target-port=8080
,而需要使用type
NodePort
公开的端口LoadBalancer
。请注意,我的8080
定义中有80
。您在 cloudflare 中的pypiserver
网域应指向Service
servicePort: 80
ingress object/resource
IP(example.com
)A record
而不指定任何端口。