4.1 kube-apiserver

作者: 一瓶多先生 | 来源:发表于2020-11-18 07:40 被阅读0次

    目录

    kube-apiserver

    kube-apiserver既然为kubernetes中master的核心组件,并且是cluster中所有请求的终点,那么kubernetes是如何接收请求,又是如何将结果返回至客户端?

    部署策略:

    • 3个节点高可用, 使用负载均衡或者haproxy/nginx 等4层透明代理实现高可用;
    • 关闭非安全端口 8080 和匿名访问;
    • 在安全端口 6443 接收 https 请求;
    • 严格的认证和授权策略 (x509、token、RBAC);
    • 开启 bootstrap token 认证,支持 kubelet TLS bootstrapping;
    • 使用 https 访问 kubelet、etcd,加密通信;

    部署软件规划

    IP 部署软件包
    10.40.61.116 kube-apiserver
    10.40.58.153 kube-apiserver
    10.40.58.154 kube-apiserver

    01.创建 kubernetes-master 证书和私钥

    API Server证书主要用于客户端程序连接apiserver时进行加密和验证。Kubernetes API Server 凭证中必需包含 master 的静态 IP 地址。

    创建 Kubernetes API Server 凭证签发请求文件:

    cat > kube-apiserver-csr.json <<EOF
    {
      "CN": "kubernetes",
      "hosts": [
        "10.40.61.116",
        "10.40.58.153",
        "10.40.58.154",
        "127.0.0.1",
        "kubernetes",
        "kubernetes.default",
        "kubernetes.default.svc",
        "kubernetes.default.svc.cluster",
        "kubernetes.default.svc.cluster.local",
        "apiserver-p001.svc.gxd88.cn"
      ],
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "China",
          "L": "Beijing",
          "O": "Kubernetes",
          "OU": "Kubernetes",
          "ST": "Beijing"
        }
      ]
    }
    EOF
    

    hosts 字段指定授权使用该证书的 IP 和域名列表,这里列出了 master 节点 IP、kubernetes 服务的 IP 和域名;
    kubernetes 服务 IP 是 apiserver 自动创建的,一般是 --service-cluster-ip-range 参数指定的网段的第一个IP

    创建 Kubernetes API Server 凭证与私钥:

    cfssl gencert \
      -ca=ca.pem \
      -ca-key=ca-key.pem \
      -config=ca-config.json \
      -profile=kubernetes \
      kube-apiserver-csr.json | cfssljson -bare kube-apiserver
    

    结果产生以下两个文件:

    kube-apiserver-key.pem
    kube-apiserver.pem
    

    02.Service Account 证书

    Service Account证书用于生成各个Namespace默认的token,以及进行token验证。在集群内部服务访问API Server时会使用这个token进行身份认证,

    其中kube-apiserver使用公钥, kube-controller-manager使用私钥

    cat > service-account-csr.json <<EOF
    {
      "CN": "service-accounts",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "China",
          "L": "Beijing",
          "O": "Kubernetes",
          "OU": "Kubernetes",
          "ST": "Beijing"
        }
      ]
    }
    EOF
    

    创建 Kubernetes service-account 凭证与私钥:

    cfssl gencert \
      -ca=ca.pem \
      -ca-key=ca-key.pem \
      -config=ca-config.json \
      -profile=kubernetes \
      service-account-csr.json | cfssljson -bare service-account
    

    结果将生成以下两个文件

    service-account-key.pem
    service-account.pem
    

    03.使用systemd管理kube-apiserver

    tee > /etc/systemd/system/kube-apiserver.service <<EOF
    [Unit]
    Description=Kubernetes API Server
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    After=network.target
    
    
    [Service]
    ExecStart=/srv/kubernetes/bin/kube-apiserver \\
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota,NodeRestriction \\
      --bind-address=0.0.0.0 \\
      --authorization-mode=Node,RBAC \\
      --enable-bootstrap-token-auth \\
      --token-auth-file=/srv/kubernetes/pki/bootstrap-token.csv \\
      --runtime-config=rbac.authorization.k8s.io/v1 \\
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname \\
      --kubelet-https=true \\
      --kubelet-client-certificate=/srv/kubernetes/pki/kube-apiserver.pem \\
      --kubelet-client-key=/srv/kubernetes/pki/kube-apiserver-key.pem \\
      --anonymous-auth=false \\
      --requestheader-client-ca-file=/srv/kubernetes/pki/ca.pem \\
      --requestheader-allowed-names= \\
      --requestheader-extra-headers-prefix=X-Remote-Extra- \\
      --requestheader-group-headers=X-Remote-Group \\
      --requestheader-username-headers=X-Remote-User \\
      --proxy-client-cert-file=/srv/kubernetes/pki/admin.pem \\
      --proxy-client-key-file=/srv/kubernetes/pki/admin-key.pem \\
      --service-cluster-ip-range=10.244.0.0/16 \\
      --service-node-port-range=20000-45000 \\
      --tls-cert-file=/srv/kubernetes/pki/kube-apiserver.pem \\
      --tls-private-key-file=/srv/kubernetes/pki/kube-apiserver-key.pem \\
      --client-ca-file=/srv/kubernetes/pki/ca.pem \\
      --enable-aggregator-routing=true \\
      --service-account-key-file=/srv/kubernetes/pki/service-account.pem \\
      --etcd-cafile=/srv/kubernetes/pki/ca.pem \\
      --etcd-certfile=/srv/kubernetes/pki/etcd.pem \\
      --etcd-keyfile=/srv/kubernetes/pki/etcd-key.pem \\
      --etcd-servers=https://10.40.61.116:2379,https://10.40.58.153:2379,https://10.40.58.154:2379 \\
      --allow-privileged=true \\
      --audit-log-maxage=30 \\
      --audit-log-maxbackup=3 \\
      --audit-log-maxsize=100 \\
      --audit-log-path=/srv/kubernetes/log/api-audit.log \\
      --event-ttl=1h \\
      --v=2 \\
      --logtostderr=false \\
      --log-dir=/srv/kubernetes/log
    
    Restart=on-failure
    RestartSec=5
    Type=notify
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    
    EOF
    

    04.启动/停止 kube-apiserver

    To configure kube-apiserver to start automatically when the system boots up, run the following commands:

    sudo /bin/systemctl daemon-reload
    sudo /bin/systemctl enable kube-apiserver.service
    

    kube-apiserver can be started and stopped as follows:

    sudo systemctl start kube-apiserver.service
    sudo systemctl stop kube-apiserver.service
    

    05.验证

    检查kube-apiserver服务:

     $ systemctl status kube-apiserver |grep Active
       Active: active (running) since 四 2020-04-16 13:44:33 CST; 2 days ago
    

    查看kube-apiserver写入etcd的数据:

     /srv/kubernetes/bin/etcdctl \
        --endpoints=https://10.40.58.153:2379,https://10.40.58.154:2379,https://10.40.61.116:2379 \
        --cacert=/srv/kubernetes/pki/ca.pem \
        --cert=/srv/kubernetes/pki/etcd.pem \
        --key=/srv/kubernetes/pki/etcd-key.pem get /  --prefix --keys-only
    

    检查集群信息

    $ kubectl cluster-info
    $ kubectl get all --all-namespaces
    $ kubectl get componentstatuses
    

    06.参数详解

    kube-apiserver的参数,主要包括:

    • 准入插件
    • 扩展apiserver
    • 认证方式
    • 审计
    • 日志
    • etcd配置
    • 各种证书
    • 外部认证
    • ......

    必须参数

    /srv/kubernetes/bin/kube-apiserver \
        --service-cluster-ip-range=10.223.0.0/16 \
        --etcd-servers=https://etcd-1:2379,https://etcd-2:2379,https://etcd-3:2379
    

    --service-cluster-ip-range: CIDR 表示的 IP 范围,服务的 cluster ip 将从中分配。 一定不要和分配给 nodes 和 pods 的 IP 范围产生重叠。

    --etcd-servers: 连接的 etcd 服务器列表 , 形式为(scheme://ip:port),使用逗号分隔。

    准入插件

    比如开启PodPreset

    /srv/kubernetes/bin/kube-apiserver \
        --enable-admission-plugins
    

    apiserver租约

    apiserver使用租约上网方式进行注册,能够感知上下线

    /srv/kubernetes/bin/kube-apiserver \
        --endpoint-reconciler-type=lease
    

    认证方式

    节点使用Node,其他使用RBAC,某些组件可能会用到Webhook

    /srv/kubernetes/bin/kube-apiserver \
        --authorization-mode=Node,RBAC
    

    证书相关

    /srv/kubernetes/bin/kube-apiserver \
        --tls-cert-file=/srv/kubernetes/pki/apiserver.pem \
      --tls-private-key-file=/srv/kubernetes/pki/apiserver-key.pem \
      --client-ca-file=/srv/kubernetes/pki/ca.pem \
      --service-account-key-file=/srv/kubernetes/pki/service-account.pem
    

    --tls-cert-file: 包含用于 HTTPS 的默认 x509 证书的文件。(如果有 CA 证书,则附加于 server 证书之后)。如果启用了 HTTPS 服务,并且没有提供 --tls-cert-file 和 --tls-private-key-file,则将为公共地址生成一个自签名的证书和密钥并保存于 /var/run/kubernetes 目录。

    --tls-private-key-file: 包含匹配 --tls-cert-file 的 x509 证书私钥的文件。

    --client-ca-file: 如果设置此标志,对于任何请求,如果存包含 client-ca-file 中的 authorities 签名的客户端证书,将会使用客户端证书中的 CommonName 对应的身份进行认证。 所有的客户端证书由该CA进行签发

    --service-account-key-file: 包含 PEM 加密的 x509 RSA 或 ECDSA 私钥或公钥的文件,用于验证 ServiceAccount 令牌。如果设置该值,--tls-private-key-file 将会被使用。指定的文件可以包含多个密钥,并且这个标志可以和不同的文件一起多次使用。

    kubelet 接入配置

    /srv/kubernetes/bin/kube-apiserver \
        --kubelet-https=true \
      --kubelet-client-certificate=/srv/kubernetes/pki/apiserver.pem \
      --kubelet-client-key=/srv/kubernetes/pki/apiserver-key.pem
    

    --kubelet-client-certificate: 用于 TLS 的客户端证书文件路径。

    --kubelet-client-key: 用于 TLS 的客户端证书密钥文件路径 .

    --kubelet-https:为 kubelet 启用 https。 (默认值 true)

    这个里面配置的证书是kube-apiserver访问kubelet时使用

    设置API访问审计日志

    开启k8s的审计功能,必须配置--audit-policy-file才会生效。

    /srv/kubernetes/bin/kube-apiserver \
      --audit-log-maxage=30 \
      --audit-log-maxbackup=3 \
      --audit-log-maxsize=100 \
      --audit-log-path=/srv/kubernetes/log/api-audit.log \
      --audit-policy-file=/srv/kubernetes/conf/audit-policy-minimal.yml
    

    --audit-log-path: 如果设置该值,所有到apiserver 的请求都将会被记录到这个文件。'-' 表示记录到标准输出。

    --audit-log-maxage: 基于文件名中的时间戳,旧审计日志文件的最长保留天数

    --audit-log-maxbackup: 旧审计日志文件的最大保留个数

    --audit-log-maxsize: 审计日志被轮转前的最大兆字节数。

    --audit-policy-file: 定义审计策略配置的文件的路径。需要打开 AdvancedAuditing'特性开关。AdvancedAuditing 需要一个配置来启用审计功能。

    程序运行日志

    /srv/kubernetes/bin/kube-apiserver \
      --v=2 \
      --logtostderr=false \
      --log-dir=/srv/kubernetes/log
    

    设置ETCD证书信息

    /srv/kubernetes/bin/kube-apiserver \
      --etcd-cafile=/srv/kubernetes/pki/ca.pem \
      --etcd-certfile=/srv/kubernetes/pki/apiserver.pem \
      --etcd-keyfile=/srv/kubernetes/pki/apiserver-key.pem \
      --etcd-servers=https://etcd-1:2379,https://etcd-2:2379,https://etcd-3:2379
    

    --etcd-cafile: 用于保护 etcd 通信的 SSL CA 文件。

    --etcd-certfile: 用于保护 etcd 通信的的 SSL 证书文件。

    --etcd-keyfile: 用于保护 etcd 通信的 SSL 密钥文件。

    --etcd-servers: 连接的 etcd 服务器列表 , 形式为(scheme://ip:port),使用逗号分隔。

    开启扩展apiserver

    开启扩展apiserver,比如metrics-server,再比如prometheus-adapter

    /srv/kubernetes/bin/kube-apiserver \
      --requestheader-client-ca-file=/srv/kubernetes/pki/ca.pem
      --requestheader-allowed-names=
      --requestheader-extra-headers-prefix=X-Remote-Extra-
      --requestheader-group-headers=X-Remote-Group
      --requestheader-username-headers=X-Remote-User
      --proxy-client-cert-file=/srv/kubernetes/pki/admin.pem
      --proxy-client-key-file=/srv/kubernetes/pki/admin-key.pem
    

    --requestheader-allowed-names: 使用 --requestheader-username-headers 指定的,允许在头部提供用户名的客户端证书通用名称列表。如果为空,任何通过 --requestheader-client-ca-file 中 authorities 验证的客户端证书都是被允许的。

    --requestheader-client-ca-file: 在信任请求头中以 --requestheader-username-headers 指示的用户名之前,用于验证接入请求中客户端证书的根证书捆绑。

    --requestheader-extra-headers-prefix: 用于检查的请求头的前缀列表。建议使用 X-Remote-Extra-。

    --requestheader-group-headers: 用于检查群组的请求头列表。建议使用 X-Remote-Group.

    --requestheader-username-headers : 用于检查用户名的请求头列表。建议使用 X-Remote-User。

    --proxy-client-cert-file: 当必须调用外部程序时,用于证明 aggregator 或者 kube-apiserver 的身份的客户端证书。包括代理到用户 api-server 的请求和调用 webhook 准入控制插件的请求。它期望这个证书包含一个来自于 CA 中的 --requestheader-client-ca-file 标记的签名。该 CA 在 kube-system 命名空间的 'extension-apiserver-authentication' configmap 中发布。从 Kube-aggregator 收到调用的组件应该使用该 CA 进行他们部分的双向 TLS 验证。

    --proxy-client-key-file: 当必须调用外部程序时,用于证明 aggregator 或者 kube-apiserver 的身份的客户端证书密钥。包括代理到用户 api-server 的请求和调用 webhook 准入控制插件的请求。

    支持节点以bootstrap-token加入集群

    /srv/kubernetes/bin/kube-apiserver \
      --enable-bootstrap-token-auth
      --token-auth-file=/srv/kubernetes/pki/bootstrap-token.csv
    

    --enable-bootstrap-token-auth: 启用此选项以允许 kube-system 命名空间中的bootstrap.kubernetes.io/token'类型密钥可以被用于 TLS 的启动认证

    --token-auth-file: 如果设置该值,这个文件将被用于通过令牌认证来保护 API 服务的安全端口。

    开放某些api组支持

    /srv/kubernetes/bin/kube-apiserver \
      --runtime-config=rbac.authorization.k8s.io/v1=true
      --runtime-config=rbac.authorization.k8s.io/v1beta1=true
      --runtime-config=settings.k8s.io/v1alpha1=true
    

    比如podpreset需要--runtime-config=settings.k8s.io/v1alpha1=true,再比如custom metrics需要--runtime-config=rbac.authorization.k8s.io/v1beta1=true

    service的虚拟IP,也就是ClusterIP网段

    /srv/kubernetes/bin/kube-apiserver \
        --service-cluster-ip-range=10.223.0.0/16
    

    NodePort的端口范围

    /srv/kubernetes/bin/kube-apiserver \
        --service-node-port-range=20000-45000
    

    相关文章

      网友评论

        本文标题:4.1 kube-apiserver

        本文链接:https://www.haomeiwen.com/subject/bhfqbktx.html