kubernetes - 如何正确设置--kubelet-certificate-authority apiserver参数?

标签 kubernetes kubernetes-apiserver kube-apiserver

我正在使用 KubeSpray 在AWS上配置两个节点的集群。默认情况下,不使用--kubelet-certificate-authority参数。但是,我想设置它。
我不知道--kubelet-certificate-authority的正确设置。当我将其设置为/etc/kubernetes/pki/ca.crt时,我在日志中会看到类似以下的消息:

TLS handshake error from 10.245.207.223:59278: remote error: tls: unknown certificate authority
为了创建隔离的测试环境,我通过SSH连接到 Controller 节点以运行此命令,该命令在4667的非标准端口上运行apiserver。我直接从/etc/kubernetes/manifests/kube-apiserver.yaml复制了这些值。您需要调整值以匹配您自己的集群。我故意在交互模式下运行容器,以便可以查看日志消息。
sudo docker run \
  --name api-server-playground \
  -it \
  --rm \
  --network host \
  --volume /etc/kubernetes:/etc/kubernetes:ro \
  --volume /etc/pki:/etc/pki:ro \
  --volume /etc/ssl:/etc/ssl/:ro \
  k8s.gcr.io/kube-apiserver:v1.18.9 \
  kube-apiserver \
    --advertise-address=10.245.207.223 \
    --allow-privileged=true \
    --anonymous-auth=True \
    --apiserver-count=1 \
    --authorization-mode=Node,RBAC \
    --bind-address=0.0.0.0 \
    --client-ca-file=/etc/kubernetes/ssl/ca.crt \
    --cloud-config=/etc/kubernetes/cloud_config \
    --cloud-provider=aws \
    --enable-admission-plugins=NodeRestriction \
    --enable-aggregator-routing=False \
    --enable-bootstrap-token-auth=true \
    --endpoint-reconciler-type=lease \
    --etcd-cafile=/etc/ssl/etcd/ssl/ca.pem \
    --etcd-certfile=/etc/ssl/etcd/ssl/node-ip-10-245-207-223.ec2.internal.pem \
    --etcd-keyfile=/etc/ssl/etcd/ssl/node-ip-10-245-207-223.ec2.internal-key.pem \
    --etcd-servers=https://10.245.207.119:2379 \
    --event-ttl=1h0m0s \
    --insecure-port=0 \
    --kubelet-client-certificate=/etc/kubernetes/ssl/apiserver-kubelet-client.crt \
    --kubelet-client-key=/etc/kubernetes/ssl/apiserver-kubelet-client.key \
    --kubelet-preferred-address-types=InternalDNS,InternalIP,Hostname,ExternalDNS,ExternalIP \
    --profiling=False \
    --proxy-client-cert-file=/etc/kubernetes/ssl/front-proxy-client.crt \
    --proxy-client-key-file=/etc/kubernetes/ssl/front-proxy-client.key \
    --request-timeout=1m0s \
    --requestheader-allowed-names=front-proxy-client \
    --requestheader-client-ca-file=/etc/kubernetes/ssl/front-proxy-ca.crt \
    --requestheader-extra-headers-prefix=X-Remote-Extra- \
    --requestheader-group-headers=X-Remote-Group \
    --requestheader-username-headers=X-Remote-User \
    --secure-port=6447 \
    --service-account-key-file=/etc/kubernetes/ssl/sa.pub \
    --service-cluster-ip-range=10.233.0.0/18 \
    --service-node-port-range=30000-32767 \
    --storage-backend=etcd3 \
    --tls-cert-file=/etc/kubernetes/ssl/apiserver.crt \
    --tls-private-key-file=/etc/kubernetes/ssl/apiserver.key
现在可以再次通过SSH进入 Controller ,并使用curl与自定义apiserver容器进行交互。
  • 设置APISERVER变量以指向 Controller 节点。我正在使用上面的advertise-address参数的值。
  • APISERVER=https://10.245.207.223:6447
    
  • 获取 token 。

  • TOKEN=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.token}"|base64 --decode); echo "TOKEN=$TOKEN"
    
  • 发出api请求。该请求将失败,因为“无法识别对等证书颁发者。”。

  • curl --header "Authorization: Bearer $TOKEN" -X GET $APISERVER/api
    
    错误消息将出现在docker日志中。它看起来像这样:
    I0921 14:39:07.662368       1 log.go:172] http: TLS handshake error 
    from 10.245.207.223:59278: remote error: tls: unknown certificate authority
    
  • 现在使用-k curl参数绕过识别问题。
  • curl -k --header "Authorization: Bearer $TOKEN" -X GET $APISERVER/api
    {
      "kind": "APIVersions",
      "versions": [
        "v1"
      ],
      "serverAddressByClientCIDRs": [
        {
          "clientCIDR": "0.0.0.0/0",
          "serverAddress": "10.245.207.223:6447"
        }
      ]
    }
    
    您会看到请求正常运行。但是,我不想使用-k参数。因此,我尝试使用apiserver中的证书颁发机构。
  • 从apiserver获取证书颁发机构。

  • echo | \
        openssl s_client -connect $APISERVER 2>/dev/null | \
        openssl x509 -text | \
        sed -n "/BEGIN CERTIFICATE/,/END CERTIFICATE/p" \
        > apiserver.ca.crt
    
  • 将证书颁发机构文件用于api请求。

  • curl --cacert apiserver.ca.crt --header "Authorization: Bearer $TOKEN" -X GET $APISERVER/api
    
    更新
    遵循Wiktor的响应提示后,我添加了/etc/kubernetes/ssl/ca.crt作为证书颁发机构。并在我的curl命令中使用了该文件。
    curl --cacert /etc/kubernetes/ssl/ca.crt --header "Authorization: Bearer $TOKEN" -X GET $APISERVER/api
    
    这工作了。

    最佳答案

    为了使--kubelet-certificate-authority标志起作用,首先需要确保已启用Kubelet authenticationKubelet authorization。之后,您可以遵循Kubernetes文档并设置TLS connection between the apiserver and kubelet。最后,您可以在主节点上编辑API服务器pod规范文件/etc/kubernetes/manifests/kube-apiserver.yaml,并将--kubelet-certificate-authority参数设置为证书颁发机构的证书文件的路径。
    因此,总结一下要做的步骤是:

  • Kubelet authentication:
  • 使用--anonymous-auth=false标志启动kubelet
  • 使用--client-ca-file标志启动kubelet,并提供一个CA bundle 包以使用以下命令验证客户端证书
  • 使用--kubelet-client-certificate--kubelet-client-key标志启动apiserver
  • 确保在API服务器中启用了authentication.k8s.io/v1beta1 API组
  • 使用--authentication-token-webhook--kubeconfig flags启动kubelet
  • kubelet在已配置的API服务器上调用TokenReview API,以从承载 token 中确定用户信息
  • Kubelet authorization:
  • 确保在API服务器中启用了authorization.k8s.io/v1beta1 API组
  • 使用--authorization-mode=Webhook--kubeconfig标志启动kubelet
  • kubelet调用已配置的API服务器上的SubjectAccessReview API,以确定每个请求是否得到授权
  • 使用--kubelet-certificate-authority标志为apiserver提供一个根证书 bundle 包,用于验证kubelet的服务证书。

  • 可以在链接的文档中找到更多详细信息。

    关于kubernetes - 如何正确设置--kubelet-certificate-authority apiserver参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63994701/

    相关文章:

    kubernetes - Windows 10 Enterprise 和 Hyper-V 中的 Minikube

    logging - 使用客户端 api 获取 kubelet 日志

    kubernetes - 使用 kubeadm 时如何在 kubeapi-server 上设置审计相关标志?

    kubernetes - kubernetes 变异 webhook 服务器的 API 端点

    kubernetes - 使用 helm 安装 RabbitMQ HA 时,版本 "PrometheusRule"中没有匹配类型 "monitoring.coreos.com/v1"

    docker - 为什么docker ps无法显示我的minikube的docker容器?

    php - 如何使用 Kubernetes API 处理流响应?

    Kubernetes:过期的证书

    docker - kube-apiserver.yaml 在哪里?

    kubernetes - 如何在没有Tiller和Helm 2的情况下使用 'helm test'