【问题标题】:Is it possible to access the Kubernetes API via https ingress?是否可以通过 https 入口访问 Kubernetes API?
【发布时间】:2018-10-19 15:22:16
【问题描述】:

我尝试通过 HTTPS 入口访问 Kubernetes API 失败,现在开始怀疑这是否可能?

任何直接远程访问的工作详细指南(不使用 ssh -> kubectl 代理以避免 Kubernetes 节点上的用户管理)将不胜感激。 :)

更新:

只是为了更清楚。这是本地部署的裸机(没有 GCE、AWZ、Azure 或任何其他),并且某些环境将完全脱机(这将增加获取安装包的其他问题)。

目的是能够在客户端主机上使用 kubectl 并通过 Keycloak 进行身份验证(如果遵循分步说明,也会失败)。使用 SSH 和 kubectl 进行管理访问不适合客户端访问。所以看起来我必须更新防火墙以公开 API 端口并创建 NodePort 服务。

设置:

[kubernetes - env] - [FW/SNAT] - [我]

FW/NAT 只允许 22,80 和 443 端口访问

因此,当我在 Kubernetes 上设置入口时,我无法创建将 443 重定向到 6443 的防火墙规则。似乎唯一的选择是创建一个 https 入口,以指向 kubernetes 服务的“api-kubernetes.node.lan”访问端口 6443。入口本身工作正常,我已经为 Keycloak auth 应用程序创建了一个工作入口。

我已将主节点的 .kube/config 复制到我的机器上,并将其放入 .kube/config(Cygwin 环境)

尝试了什么:

  • SSL 直通。无法启用,因为 kubernetes-ingress 控制器由于无法创建中间证书而无法启动。即使启动,也很可能会削弱其他 HTTPS 入口。
  • 已创建自签名 SSL 证书。结果,通过浏览器,当指向 https://api-kubernetes.node.lan/api 时,我可以获得 API 输出。但是,kubectl 由于未签名的证书而引发错误,这是显而易见的。
  • 将 apiserver.crt 放入 ingress tls: 定义。由于 cert 不适合 api-kubernetes.node.lan 而出现错误。也很明显。
  • 按照指南 [1] 创建 kube-ca 签名证书。现在浏览器根本不显示任何内容。使用 curl 访问 https://api-kubernetes.node.lan/api 会导致输出为空(使用 -v 时我可以看到 HTTP OK)。 Kubectl 现在收到以下错误:

    $ kubectl.exe version
    Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.0", GitCommit:"91e7b4fd31fcd3d5f436da26c980becec37ceefe", GitTreeState:"clean", BuildDate:"2018-06-27T20:17:28Z", GoVersion:"go1.10.2", Compiler:"gc", Platform:"windows/amd64"}
    Error from server: the server responded with the status code 0 but did not return more information
    

当尝试比较 apiserver.pem 和我生成的证书时,我看到了唯一的区别:

apiserver.pem
X509v3 Key Usage:
                 Digital Signature, Non Repudiation, Key Encipherment
generated.crt
X509v3 Extended Key Usage:
                 TLS Web Server Authentication

入口配置:

---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: kubernetes-api
  namespace: default  
  labels:
    app: kubernetes
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  tls:
    - secretName: kubernetes-api-cert
      hosts:    
        - api-kubernetes.node.lan

  rules:
  - host: api-kubernetes.node.lan
    http:
      paths:
      - path: "/"
        backend:
          serviceName: kubernetes
          servicePort: 6443

链接: [1]https://db-blog.web.cern.ch/blog/lukas-gedvilas/2018-02-creating-tls-certificates-using-kubernetes-api

【问题讨论】:

  • 只需使用 kubectl proxy 命令访问 API 服务器

标签: kubernetes kubectl kubernetes-ingress


【解决方案1】:

只要在kube-system 命名空间中公开kube-apiserver pod,您应该能够做到这一点。我试过这样:

$ kubectl -n kube-system expose pod kube-apiserver-xxxx --name=apiserver --port 6443
service/apiserver exposed
$ kubectl -n kube-system get svc
NAME                      TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                       AGE
apiserver                 ClusterIP   10.x.x.x         <none>        6443/TCP                      1m
...

然后去一个集群机器,指向我的~/.kube/config上下文IP10.x.x.x:6443

clusters:
- cluster:
    certificate-authority-data: [REDACTED]
    server: https://10.x.x.x:6443
  name: kubernetes
...

然后:

$ kubectl version --insecure-skip-tls-verify
Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.2", GitCommit:"bb9ffb1654d4a729bb4cec18ff088eacc153c239", GitTreeState:"clean", BuildDate:"2018-08-07T23:17:28Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.2", GitCommit:"bb9ffb1654d4a729bb4cec18ff088eacc153c239", GitTreeState:"clean", BuildDate:"2018-08-07T23:08:19Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}

我使用了--insecure-skip-tls-verify,因为10.x.x.x 需要在服务器证书上有效。您实际上可以像这样修复它:Configure AWS publicIP for a Master in Kubernetes

所以在你的情况下可能有几件事:

  1. 由于您最初是在 Ingress 上提供 SSL,因此您需要在您的 master 上的 /etc/kubernetes/pki/ 下使用相同的 kubeapi-server 证书
  2. 您需要将外部 IP 或名称添加到暴露 Ingress 的证书中。关注这样的事情:Configure AWS publicIP for a Master in Kubernetes

【讨论】:

  • 使用 kubectl proxy/port 存在身份验证问题 - 您必须管理并允许 shell 访问 Kubernetes 主控主机。虽然这对于 POC 来说不是问题,但这被认为是生产环境的安全风险。这正是我写的原因:“不使用 ssh -> kubectl 代理”。此外,我尝试使用 /etc/kubernetes/pki/ 证书失败,因为主机名不匹配。这是一个离线的本地云环境。
【解决方案2】:

部分回答我自己的问题。

目前我对基于令牌的身份验证感到满意:这允许拥有单独的访问级别并避免允许 shell 用户。基于 Keycloak 的仪表板身份验证工作,但登录后,无法注销。没有注销选项。 :D

为了通过 Ingress 访问仪表板本身,我在某处找到了一个有效的重写规则: nginx.ingress.kubernetes.io/configuration-snippet: "rewrite ^(/ui)$ $1/ui/ permanent;"

请注意,必须使用尾部斜杠“/”访问 UI:https://server_address/ui/

【讨论】:

    【解决方案3】:

    对于那些只想从另一个网络和另一个主机名看到他们的 kubernetes API 但不需要将 API 更改为默认 6443 以外的端口的人来说,不需要入口。

    如果这描述了您,您所要做的就是在您来自的 DNS 的 API 证书中添加额外的 SAN 规则。 This article describes the process in detail

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-14
      • 2019-03-14
      • 2020-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-11
      相关资源
      最近更新 更多