zoukankan      html  css  js  c++  java
  • K8S Api Server认证

    认证类型

    kubernetes 提供了三种级别的客户端认证方式:

    • HTTPS证书认证,是基于CA根证书签名的双向数字证书认证方式,是最严格的认证
    • HTTP Token认证,通过Token识别每个合法的用户
    • HTTP Basic认证

    HTTP Token认证和Http Basic认证是相对简单的认证方式,Kubernetes的各组件与Api Server的通信方式仍然是HTTPS,但不再使用CA数字证书。

    基于CA证书的双向认证

    apiserver端配置

    使用kubeadm初始化 kubernetes集群中,kube-apiserver是以静态pod的形式运行在master node上的。可以在master node上找琪定义文件/etc/kubernetes/manifests/kube-apiserver.json,其中启动命令部分参数如下:

     "command": [
              "kube-apiserver",
              "--insecure-bind-address=127.0.0.1",
              "--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota",
              "--service-cluster-ip-range=10.96.0.0/12",
              "--service-account-key-file=/etc/kubernetes/pki/apiserver-key.pem",
              "--client-ca-file=/etc/kubernetes/pki/ca.pem",
              "--tls-cert-file=/etc/kubernetes/pki/apiserver.pem",
              "--tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem",
              "--token-auth-file=/etc/kubernetes/pki/tokens.csv",
              "--secure-port=6443",
              "--allow-privileged",
              "--advertise-address=192.168.61.100",
              "--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
              "--anonymous-auth=false",
              "--etcd-servers=http://127.0.0.1:2379"
            ],
    

    我们注意到有如下三个启动参数:

    • --client-ca-file: 指定CA根证书文件为/etc/kubernetes/pki/ca.pem,内置CA公钥用于验证某证书是否是CA签发的证书
    • --tls-private-key-file: 指定ApiServer私钥文件为/etc/kubernetes/pki/apiserver-key.pem
    • --tls-cert-file:指定ApiServer证书文件为/etc/kubernetes/pki/apiserver.pem

    说明Api Server已经启动了HTTPS证书认证,此时如果在集群外部使用浏览器访问https://:6443/api会提示Unauthorized。

    生成客户端私钥和证书

    客户端要通过https证书双向认证的形式访问apiserver需要生成客户端的私钥和证书。在最新版本的kubernetes中,已经不再需要手动为客户端生成证书。直接由Master端签发即可。

    客户端启动方式:

    /usr/bin/kubelet --logtostderr=false --log-dir=/var/log/kubernetes --v=2 --address=0.0.0.0 --hostname-override=10.1.61.140 --allow-privileged=true --cgroup-driver=systemd --max-pods=30 --cluster_dns=10.254.0.10 --cluster_domain=cluster.local --pod-infra-container-image=dk-reg.op.douyuyuba.com/library/pause-amd64:3.0 --experimental-bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig --require-kubeconfig --kubeconfig=/etc/kubernetes/kubelet.kubeconfig --cert-dir=/etc/kubernetes/pki --hairpin-mode promiscuous-bridge --serialize-image-pulls=false --pod-manifest-path=/etc/kubernetes/manifests
    
    

    master端允许其证书申请:

    # 查看 csr
    ➜  kubectl get csr
    NAME        AGE       REQUESTOR           CONDITION
    csr-l9d25   2m        kubelet-bootstrap   Pending
    
    # 签发证书
    ➜  kubectl certificate approve csr-l9d25
    certificatesigningrequest "csr-l9d25" approved
    
    # 查看 node
    ➜  kubectl get node
    NAME           STATUS    AGE       VERSION
    docker4.node   Ready     26s       v1.6.7
    

    master核心组件与apiserver的认证方式

    /etc/kubernetes/manifests下的kube-controller-manager.json和kube-scheduler.json说明Controller Manager和Scheduler都是以静态Pod的形式运行在Master Node上,注意到这两个文件里的启动参数--master=127.0.0.1:8080,说明它们直接通过insecure-port 8080和ApiServer通信。 而前面ApiServer的--insecure-bind-address=127.0.0.1,因此他们之间无需走secure-port。

    HTTP Token认证

    在上面master node的apiserver的启动命令里面,除了证书的双向认证,还同时启动了token认证。

    --token-auth-file=/etc/kubernetes/pki/token.csv 指定了静态token文件,这个文件的格式如下:

    token,user,uid,"group1,group2,group3"
    

    生成token方式如下:

    export BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ')
    cat > token.csv <<EOF
    ${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
    EOF
    

    请求Api时只要在Authorization头中加入Bearer Token即可:

    curl -k --header "Authorization: Bearer fe0b40f90ac632c26d79c39673f3dd80" https://10.1.61.129:6443/api
    {
      "kind": "APIVersions",
      "versions": [
        "v1"
      ],
      "serverAddressByClientCIDRs": [
        {
          "clientCIDR": "0.0.0.0/0",
          "serverAddress": "10.1.61.129:6443"
        }
      ]
    }
    

    kubectl使用Bearer访问apiserver:

    kubectl --server=https://10.1.61.129:6443 
    --token=fe0b40f90ac632c26d79c39673f3dd80 
    --insecure-skip-tls-verify=true 
    cluster-info
    

    HTTP Basic认证

    kubeadm在初始化集群时并没有开启http basic认证,官方也不建议在实践中使用。但是,在前面的两种认证方式中,如果我们要在外部通过https的方式访问dashboard,则无法办到,除非对外开启apiserver非安全认证的8080端口,这显然不是我们想看到的。在这种情况 下,我们就可以开启http basic认证,既可以通过https的方式 在外部打开dashboard,同时还能提供基本的安全认证。在这里也简单的列一下http basic认证的配置。

    1. 在master上创建/etc/kubernetes/basic_auth文件,文件中每行的格式如下:
    password,user,uid,"group1,group2,group3"
    

    示例如下:

    1234,admin,1
    
    1. 在启动apiserver的时候,启动项添加如下参数即可:
    --basic_auth_file=/etc/kubernetes/basic_auth
    
    1. 使用请求头Authorization Basic BASE64ENCODED(USER:PASSWORD)访问方式如下:
    echo admin:1234|base64
    YWRtaW46MTIzNAo=
    
    curl -k --header "Authorization:Basic YWRtaW46MTIzNAo=" https://10.1.61.129:6443/api
    {
      "kind": "APIVersions",
      "versions": [
        "v1"
      ],
      "serverAddressByClientCIDRs": [
        {
          "clientCIDR": "0.0.0.0/0",
          "serverAddress": "10.1.61.129:6443"
        }
      ]
    }
    
    1. 使用kubectl访问如下:
    kubectl --server=https://10.1.61.129:6443 
    --username=admin 
    --password=1234 
    --insecure-skip-tls-verify=true 
    cluster-info
    

    kubectl config简要说明

    从上面各种认证访问apiserver的过程中,不难看出,一旦使用了认证,kubectl的用法就会需要带上需多参数,变的非常复杂。kubectl config提供了一个简化的方法,就是将这些配置项都固化到配置文件中,而不用每次调用 都得作为参数手动带上。

    我们以http basic认证方式为例:

    1. 配置admin用户:
    kubectl config set-credentials cluster-admin --username=admin --password=123456
    
    1. 配置apiserver的访问方式,还需要给集群起个名字,就叫kubernetes:
    kubectl config set-cluster kubernetes --insecure-skip-tls-verify=true --server=https://10.1.61.129
    
    
    1. 创建一个context,它连接用户admin和集群kubernetes:
    kubectl config set-context default --user=admin  --cluster=kubernetes
    
    
    1. 将刚刚创建的context设置为默认的context:
    kubectl config use-context default
    
    

    这时,会在/roo/.kube目录下生成一个config的配置文件,内容如下:

    apiVersion: v1
    clusters:
    - cluster:
        insecure-skip-tls-verify: true
        server: https://10.1.61.129
      name: kubernetes
    contexts:
    - context:
        cluster: kubernetes
        namespace: default
        user: admin
      name: default
    current-context: default
    kind: Config
    preferences: {}
    users:
    - name: admin
      user:
        password: 123456
        username: admin
    

    我们后面再执行kubectl的时候,会自动读取该配置文件完成相关认证。

    也可以在配置的过程中,指定Kubeconfig文件的路径,如下:

    export KUBE_APISERVER="https://10.1.61.129:6443"
    # 设置集群参数,即api-server的访问方式,给集群起个名字就叫kubernetes
    kubectl config set-cluster kubernetes 
      --certificate-authority=ca.pem 
      --embed-certs=true 
      --server=${KUBE_APISERVER} 
      --kubeconfig=bootstrap.kubeconfig
      
    # 设置客户端认证参数,这里采用token认证
    kubectl config set-credentials kubelet-bootstrap 
      --token=${BOOTSTRAP_TOKEN} 
      --kubeconfig=bootstrap.kubeconf
    
    # 设置上下文参数,用于连接用户kubelet-bootstrap与集群kubernetes
    kubectl config set-context default 
      --cluster=kubernetes 
      --user=kubelet-bootstrap 
      --kubeconfig=bootstrap.kubeconfig
      
    # 设置默认上下文
    kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
    

    参考:http://blog.frognew.com/2017/01/kubernetes-api-server-authc.html#master-node核心组件与apiserver的认证方式

  • 相关阅读:
    问题 D: 错误探测
    问题 C: 计算矩阵边缘元素之和
    同行列对角线的格子
    矩形交换行
    问题 R: 鸡尾酒疗法
    问题 : 字符串p型编码
    循环结构 整数的个数
    字符串c++字符环
    ISBN码字符串c++
    Uva
  • 原文地址:https://www.cnblogs.com/breezey/p/9101705.html
Copyright © 2011-2022 走看看