zoukankan      html  css  js  c++  java
  • k8s v1.9.9 二进制部署高可用(7)部署master节点

    部署 master 节点

    kubernetes master 节点运行如下组件:

    kube-apiserver
    kube-scheduler
    kube-controller-manager
    kube-scheduler 和 kube-controller-manager 可以以集群模式运行,通过 leader 选举产生一个工作进程,其它进程处于阻塞模式。

    对于 kube-apiserver,可以运行多个实例(本文档是 3 实例),但对其它组件需要提供统一的访问地址,该地址需要高可用。本文档使用 keepalived 和 haproxy 实现 kube-apiserver VIP 高可用和负载均衡。

    下载最新版本的二进制文件

    cd /root/work
    wget https://dl.k8s.io/v1.9.9/kubernetes-server-linux-amd64.tar.gz
    tar -xzvf kubernetes-server-linux-amd64.tar.gz
    

    将二进制文件拷贝到所有 master 节点:

    cd /root/work/kubernetes/server/bin/
    scp kube-apiserver kube-controller-manager kube-scheduler 10.0.0.10:/usr/bin/
    scp kube-apiserver kube-controller-manager kube-scheduler 10.0.0.11:/usr/bin/
    scp kube-apiserver kube-controller-manager kube-scheduler 10.0.0.12:/usr/bin/
    

    1、kube-apiserver

    创建 kubernetes 证书和私钥

    创建证书签名请求:

    IP地址写上master还有vip的地址即可。
    cd /root/work
    cat > kubernetes-csr.json <<EOF
    {
      "CN": "kubernetes",
      "hosts": [
        "127.0.0.1",
        "10.0.0.10",
        "10.0.0.11",
        "10.0.0.12",
        "10.0.0.252",
        "10.254.0.1",
        "kubernetes",
        "kubernetes.default",
        "kubernetes.default.svc",
        "kubernetes.default.svc.cluster",
        "kubernetes.default.svc.cluster.local"
      ],
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "CN",
          "ST": "BeiJing",
          "L": "BeiJing",
          "O": "k8s",
          "OU": "4Paradigm"
        }
      ]
    }
    EOF
    
    -hosts 字段指定授权使用该证书的 IP 或域名列表,这里列出了 VIP 、apiserver 节点 IP、kubernetes 服务 IP 和域名;
    -域名最后字符不能是 .(如不能为 kubernetes.default.svc.cluster.local.),否则解析时失败,提示: x509: cannot parse dnsName "kubernetes.default.svc.cluster.local.";
    -如果使用非 cluster.local 域名,如 opsnull.com,则需要修改域名列表中的最后两个域名为:kubernetes.default.svc.opsnull、kubernetes.default.svc.opsnull.com
    -kubernetes 服务 IP 是 apiserver 自动创建的,一般是 --service-cluster-ip-range 参数指定的网段的第一个IP,后续可以通过如下命令获取:
    $ kubectl get svc kubernetes
    NAME         CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    kubernetes   10.254.0.1   <none>        443/TCP   1d
    

    生成证书和私钥:

    $cfssl gencert -ca=/root/work/ca.pem 
    -ca-key=/root/work/ca-key.pem 
    -config=/root/work/ca-config.json 
    -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
    
    ls kubernetes*pem
    kubernetes-key.pem  kubernetes.pem
    

    将生成的证书和私钥文件拷贝到 master 节点:

    mkdir -p /etc/kubernetes/cert 所有master节点
    scp kubernetes*.pem 10.0.0.10:/etc/kubernetes/cert/
    scp kubernetes*.pem 10.0.0.11:/etc/kubernetes/cert/
    scp kubernetes*.pem 10.0.0.12:/etc/kubernetes/cert/
    

    创建 kube-apiserver 使用的客户端 token 文件

    kubelet 首次启动时向 kube-apiserver 发送 TLS Bootstrapping 请求,kube-apiserver 验证 kubelet 请求中的 token 是否与它配置的 token.csv 一致,如果一致则自动为 kubelet生成证书和秘钥。

    head -c 16 /dev/urandom | od -An -t x | tr -d ' '
    86bff28f07a55e60ba1e61ab765c0b55   #这个值写入到 token.csv文件里面,后面kubelet配置文件也需要用到这个值,有个印象哦。
    cat > token.csv <<EOF
    86bff28f07a55e60ba1e61ab765c0b55,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
    EOF
    
    master和work节点都需要有。
    scp token.csv 10.0.0.10:/etc/kubernetes/
    scp token.csv 10.0.0.11:/etc/kubernetes/
    scp token.csv 10.0.0.12:/etc/kubernetes/
    scp token.csv 10.0.0.13:/etc/kubernetes/
    scp token.csv 10.0.0.14:/etc/kubernetes/
    

    创建日志目录

    mkdir /etc/kubernetes/kube-apiserver 所有master节点创建。
    

    为各节点创建和分发 kube-apiserver systemd unit 文件

    10.0.0.10:
    注意:
    --advertise-address= 写入master本机地址
    --bind-address= 写入master本机地址
    --etcd-servers= 写入自己etcd集群地址

    cat > /usr/lib/systemd/system/kube-apiserver.service <<EOF
    [Unit]
    Description=Kubernetes API Server
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    After=network.target
    
    [Service]
    WorkingDirectory=/etc/kubernetes/kube-apiserver
    ExecStart=/usr/bin/kube-apiserver \
    --admission-control=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
    --anonymous-auth=false \
    --advertise-address=10.0.0.10 \
    --bind-address=10.0.0.10 \
    --feature-gates=RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true,Accelerators=true,DevicePlugins=true \
    --insecure-port=0 \
    --authorization-mode=Node,RBAC \
    --runtime-config=api/all \
    --enable-bootstrap-token-auth \
    --token-auth-file=/etc/kubernetes/token.csv \
    --service-cluster-ip-range=10.254.0.0/16 \
    --service-node-port-range=30000-32767 \
    --tls-cert-file=/etc/kubernetes/cert/kubernetes.pem \
    --tls-private-key-file=/etc/kubernetes/cert/kubernetes-key.pem \
    --client-ca-file=/etc/kubernetes/cert/ca.pem \
    --kubelet-client-certificate=/etc/kubernetes/cert/kubernetes.pem \
    --kubelet-client-key=/etc/kubernetes/cert/kubernetes-key.pem \
    --service-account-key-file=/etc/kubernetes/cert/ca-key.pem \
    --etcd-cafile=/etc/kubernetes/cert/ca.pem \
    --etcd-certfile=/etc/kubernetes/cert/kubernetes.pem \
    --etcd-keyfile=/etc/kubernetes/cert/kubernetes-key.pem \
    --etcd-servers=https://10.0.0.10:2379,https://10.0.0.11:2379,https://10.0.0.12:2379 \
    --enable-swagger-ui=true \
    --allow-privileged=true \
    --max-mutating-requests-inflight=2000 \
    --max-requests-inflight=4000 \
    --apiserver-count=3 \
    --audit-log-maxage=30 \
    --audit-log-maxbackup=3 \
    --audit-log-maxsize=100 \
    --audit-log-path=/etc/kubernetes/kube-apiserver/audit.log \
    --event-ttl=168h \
    --logtostderr=true \
    --v=2
    Restart=always
    RestartSec=5
    StartLimitInterval=0
    Type=notify
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    --authorization-mode=Node,RBAC: 开启 Node 和 RBAC 授权模式,拒绝未授权的请求;
    --admission-control:启用 ServiceAccount 和 NodeRestriction;
    --service-account-key-file:签名 ServiceAccount Token 的公钥文件,kube-controller-manager 的 --service-account-private-key-file 指定私钥文件,两者配对使用;
    --tls-*-file:指定 apiserver 使用的证书、私钥和 CA 文件。--client-ca-file 用于验证 client (kue-controller-manager、kube-scheduler、kubelet、kube-proxy 等)请求所带的证书;
    --kubelet-client-certificate、--kubelet-client-key:如果指定,则使用 https 访问 kubelet APIs;需要为证书对应的用户(上面 kubernetes*.pem 证书的用户为 kubernetes) 用户定义 RBAC 规则,否则访问 kubelet API 时提示未授权;
    --bind-address: 不能为 127.0.0.1,否则外界不能访问它的安全端口 6443;
    --feature-gates=Accelerators=true,DevicePlugins=true:支持 GPU 加速功能;
    --insecure-port=0:关闭监听非安全端口(8080);
    --service-cluster-ip-range: 指定 Service Cluster IP 地址段;
    --service-node-port-range: 指定 NodePort 的端口范围;
    --runtime-config=api/all=true: 启用所有版本的 APIs,如 autoscaling/v2alpha1;
    --enable-bootstrap-token-auth:启用 kubelet bootstrap 的 token 认证;
    --apiserver-count=3:指定集群运行模式,多台 kube-apiserver 会通过 leader 选举产生一个工作节点,其它节点处于阻塞状态;
    

    10.0.0.11:

    cat > /usr/lib/systemd/system/kube-apiserver.service <<EOF
    [Unit]
    Description=Kubernetes API Server
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    After=network.target
    
    [Service]
    WorkingDirectory=/etc/kubernetes/kube-apiserver
    ExecStart=/usr/bin/kube-apiserver \
    --admission-control=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
    --anonymous-auth=false \
    --advertise-address=10.0.0.11 \
    --bind-address=10.0.0.11 \
    --feature-gates=RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true,Accelerators=true,DevicePlugins=true \
    --insecure-port=0 \
    --authorization-mode=Node,RBAC \
    --runtime-config=api/all \
    --enable-bootstrap-token-auth \
    --token-auth-file=/etc/kubernetes/token.csv \
    --service-cluster-ip-range=10.254.0.0/16 \
    --service-node-port-range=30000-32767 \
    --tls-cert-file=/etc/kubernetes/cert/kubernetes.pem \
    --tls-private-key-file=/etc/kubernetes/cert/kubernetes-key.pem \
    --client-ca-file=/etc/kubernetes/cert/ca.pem \
    --kubelet-client-certificate=/etc/kubernetes/cert/kubernetes.pem \
    --kubelet-client-key=/etc/kubernetes/cert/kubernetes-key.pem \
    --service-account-key-file=/etc/kubernetes/cert/ca-key.pem \
    --etcd-cafile=/etc/kubernetes/cert/ca.pem \
    --etcd-certfile=/etc/kubernetes/cert/kubernetes.pem \
    --etcd-keyfile=/etc/kubernetes/cert/kubernetes-key.pem \
    --etcd-servers=https://10.0.0.10:2379,https://10.0.0.11:2379,https://10.0.0.12:2379 \
    --enable-swagger-ui=true \
    --allow-privileged=true \
    --max-mutating-requests-inflight=2000 \
    --max-requests-inflight=4000 \
    --apiserver-count=3 \
    --audit-log-maxage=30 \
    --audit-log-maxbackup=3 \
    --audit-log-maxsize=100 \
    --audit-log-path=/etc/kubernetes/kube-apiserver/audit.log \
    --event-ttl=168h \
    --logtostderr=true \
    --v=2
    Restart=always
    RestartSec=5
    StartLimitInterval=0
    Type=notify
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    EOF
    

    10.0.0.12:

    cat > /usr/lib/systemd/system/kube-apiserver.service <<EOF
    [Unit]
    Description=Kubernetes API Server
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    After=network.target
    
    [Service]
    WorkingDirectory=/etc/kubernetes/kube-apiserver
    ExecStart=/usr/bin/kube-apiserver \
    --admission-control=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
    --anonymous-auth=false \
    --advertise-address=10.0.0.12 \
    --bind-address=10.0.0.12 \
    --feature-gates=RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true,Accelerators=true,DevicePlugins=true \
    --insecure-port=0 \
    --authorization-mode=Node,RBAC \
    --runtime-config=api/all \
    --enable-bootstrap-token-auth \
    --token-auth-file=/etc/kubernetes/token.csv \
    --service-cluster-ip-range=10.254.0.0/16 \
    --service-node-port-range=30000-32767 \
    --tls-cert-file=/etc/kubernetes/cert/kubernetes.pem \
    --tls-private-key-file=/etc/kubernetes/cert/kubernetes-key.pem \
    --client-ca-file=/etc/kubernetes/cert/ca.pem \
    --kubelet-client-certificate=/etc/kubernetes/cert/kubernetes.pem \
    --kubelet-client-key=/etc/kubernetes/cert/kubernetes-key.pem \
    --service-account-key-file=/etc/kubernetes/cert/ca-key.pem \
    --etcd-cafile=/etc/kubernetes/cert/ca.pem \
    --etcd-certfile=/etc/kubernetes/cert/kubernetes.pem \
    --etcd-keyfile=/etc/kubernetes/cert/kubernetes-key.pem \
    --etcd-servers=https://10.0.0.10:2379,https://10.0.0.11:2379,https://10.0.0.12:2379 \
    --enable-swagger-ui=true \
    --allow-privileged=true \
    --max-mutating-requests-inflight=2000 \
    --max-requests-inflight=4000 \
    --apiserver-count=3 \
    --audit-log-maxage=30 \
    --audit-log-maxbackup=3 \
    --audit-log-maxsize=100 \
    --audit-log-path=/etc/kubernetes/kube-apiserver/audit.log \
    --event-ttl=168h \
    --logtostderr=true \
    --v=2
    Restart=always
    RestartSec=5
    StartLimitInterval=0
    Type=notify
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    EOF
    

    启动 kube-apiserver 服务

    systemctl daemon-reload && systemctl enable kube-apiserver 
    systemctl start kube-apiserver && systemctl status kube-apiserver 
    

    打印 kube-apiserver 写入 etcd 的数据

    ETCDCTL_API=3 etcdctl 
    --endpoints=https://10.0.0.10:2379,https://10.0.0.11:2379,https://10.0.0.12:2379 
    --cacert=/root/work/ca.pem 
    --cert=/etc/etcd/cert/etcd.pem 
    --key=/etc/etcd/cert/etcd-key.pem 
    get /registry/ --prefix --keys-only
    

    检查集群信息

    [root@master-ha-12 ~]# kubectl cluster-info dump
    Kubernetes master is running at https://10.0.0.252:8443
    
    [root@master-ha-12 ~]# kubectl get all --all-namespaces
    NAMESPACE   NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    default     svc/kubernetes   ClusterIP   10.254.0.1   <none>        443/TCP   8m
    
    [root@master-ha-12 ~]# kubectl get componentstatuses
    NAME                 STATUS      MESSAGE                                                                                        ERROR
    scheduler            Unhealthy   Get http://127.0.0.1:10251/healthz: dial tcp 127.0.0.1:10251: getsockopt: connection refused   
    controller-manager   Unhealthy   Get http://127.0.0.1:10252/healthz: dial tcp 127.0.0.1:10252: getsockopt: connection refused   
    etcd-1               Healthy     {"health":"true"}                                                                              
    etcd-2               Healthy     {"health":"true"}                                                                              
    etcd-0               Healthy     {"health":"true"}                                                                              
    
    注意:
    如果执行 kubectl 命令式时输出如下错误信息,则说明使用的 ~/.kube/config 文件不对,请切换到正确的账户后再执行该命令:
    The connection to the server localhost:8080 was refused - did you specify the right host or port?
    执行 kubectl get componentstatuses 命令时,apiserver 默认向 127.0.0.1 发送请求。当 controller-manager、scheduler 以集群模式运行时,有可能和 kube-apiserver 不在一台机器上,这时 controller-manager 或 scheduler 的状态为 Unhealthy,但实际上它们工作正常。
    

    检查 kube-apiserver 监听的端口

    [root@master-ha-12 ~]# netstat -lnpt|grep kube
    tcp        0      0 10.0.0.12:6443          0.0.0.0:*               LISTEN      2944/kube-apiserver 
    
    6443: 接收 https 请求的安全端口,对所有请求做认证和授权;
    由于关闭了非安全端口,故没有监听 8080;
    

    授予 kubernetes 证书访问 kubelet API 的权限

    在执行 kubectl exec、run、logs 等命令时,apiserver 会转发到 kubelet。这里定义 RBAC 规则,授权 apiserver 调用 kubelet API。
    定义 ClusterRole system:kubelet-api-admin 授予访问 kubelet 所有 API 的权限:

    cat > kubelet-api-admin.yaml <<EOF
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      annotations:
        rbac.authorization.kubernetes.io/autoupdate: "true"
      labels:
        kubernetes.io/bootstrapping: rbac-defaults
      name: system:kubelet-api-admin
    rules:
    - apiGroups:
      - ""
      resources:
      - nodes
      verbs:
      - get
      - list
      - watch
    - apiGroups:
      - ""
      resources:
      - nodes
      verbs:
      - proxy
    - apiGroups:
      - ""
      resources:
      - nodes/log
      - nodes/metrics
      - nodes/proxy
      - nodes/spec
      - nodes/stats
      verbs:
      - '*'
    EOF
    
    [root@master-ha-10 work]# kubectl create -f kubelet-api-admin.yaml
    clusterrole "system:kubelet-api-admin" created
    

    授予 kubernetes 证书访问 kubelet API 的权限:

    [root@master-ha-10 work]# kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes
    clusterrolebinding "kube-apiserver:kubelet-apis" created
    

    查看 ClusterRole 结果:

    [root@master-ha-10 work]# kubectl describe clusterrole system:kubelet-api-admin
    Name:         system:kubelet-api-admin
    Labels:       kubernetes.io/bootstrapping=rbac-defaults
    Annotations:  rbac.authorization.kubernetes.io/autoupdate=true
    PolicyRule:
      Resources      Non-Resource URLs  Resource Names  Verbs
      ---------      -----------------  --------------  -----
      nodes          []                 []              [get list watch proxy]
      nodes/log      []                 []              [*]
      nodes/metrics  []                 []              [*]
      nodes/proxy    []                 []              [*]
      nodes/spec     []                 []              [*]
      nodes/stats    []                 []              [*]
    

    部署kube-controller-manager

    本文档介绍部署高可用 kube-controller-manager 集群的步骤。
    该集群包含 3 个节点,启动后将通过竞争选举机制产生一个 leader 节点,其它节点为阻塞状态。当 leader 节点不可用后,剩余节点将再次进行选举产生新的 leader 节点,从而保证服务的可用性。
    为保证通信安全,本文档先生成 x509 证书和私钥,kube-controller-manager 在如下两种情况下使用该证书:
    1、与 kube-apiserver 的安全端口通信时;
    2、在安全端口(https,10252) 输出 prometheus 格式的 metrics;
    

    创建 kube-controller-manager 证书和私钥

    创建证书签名请求:

    cat > kube-controller-manager-csr.json <<EOF
    {
        "CN": "system:kube-controller-manager",
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "hosts": [
          "127.0.0.1",
          "10.0.0.10",
          "10.0.0.11",
          "10.0.0.12"
        ],
        "names": [
          {
            "C": "CN",
            "ST": "BeiJing",
            "L": "BeiJing",
            "O": "system:kube-controller-manager",
            "OU": "4Paradigm"
          }
        ]
    }
    EOF
    
    hosts 列表包含所有 kube-controller-manager 节点 IP;
    CN 为 system:kube-controller-manager、O 为 system:kube-controller-manager,kubernetes 内置的 ClusterRoleBindings system:kube-controller-manager 赋予 kube-controller-manager 工作所需的权限。
    

    生成证书和私钥:

    $cfssl gencert -ca=/root/work/ca.pem 
    -ca-key=/root/work/ca-key.pem 
    -config=/root/work/ca-config.json 
    -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
    
    ls kube-controller-manager*pem
    kube-controller-manager-key.pem  kube-controller-manager.pem
    

    分发到所有 master 节点:

    scp kube-controller-manager*.pem 10.0.0.10:/etc/kubernetes/cert/
    scp kube-controller-manager*.pem 10.0.0.11:/etc/kubernetes/cert/
    scp kube-controller-manager*.pem 10.0.0.12:/etc/kubernetes/cert/
    

    创建和分发 kubeconfig 文件

    kubeconfig 文件包含访问 apiserver 的所有信息,如 apiserver 地址、CA 证书和自身使用的证书;

    $kubectl config set-cluster kubernetes 
    --certificate-authority=/root/work/ca.pem 
    --embed-certs=true 
    --server=https://10.0.0.252:8443 
    --kubeconfig=kube-controller-manager.kubeconfig
    
    $kubectl config set-credentials system:kube-controller-manager 
    --client-certificate=/root/work/kube-controller-manager.pem 
    --client-key=/root/work/kube-controller-manager-key.pem 
    --embed-certs=true 
    --kubeconfig=kube-controller-manager.kubeconfig
    
    $kubectl config set-context system:kube-controller-manager 
    --cluster=kubernetes 
    --user=system:kube-controller-manager 
    --kubeconfig=kube-controller-manager.kubeconfig
    
    $kubectl config use-context system:kube-controller-manager --kubeconfig=kube-controller-manager.kubeconfig
    

    分发 kubeconfig 到所有 master 节点:

    scp kube-controller-manager.kubeconfig 10.0.0.10:/etc/kubernetes/
    scp kube-controller-manager.kubeconfig 10.0.0.11:/etc/kubernetes/
    scp kube-controller-manager.kubeconfig 10.0.0.12:/etc/kubernetes/
    
    mkdir /etc/kubernetes/kube-controller-manager #所有master节点操作
    

    分发 systemd unit 文件到所有 master 节点:

    cat > /usr/lib/systemd/system/kube-controller-manager.service <<EOF
    [Unit]
    Description=Kubernetes Controller Manager
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    
    [Service]
    WorkingDirectory=/etc/kubernetes/kube-controller-manager
    ExecStart=/usr/bin/kube-controller-manager \
      --port=10252 \
      --address=127.0.0.1 \
      --kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig \
      --service-cluster-ip-range=10.254.0.0/16 \
      --cluster-name=kubernetes \
      --cluster-signing-cert-file=/etc/kubernetes/cert/ca.pem \
      --cluster-signing-key-file=/etc/kubernetes/cert/ca-key.pem \
      --experimental-cluster-signing-duration=8760h \
      --root-ca-file=/etc/kubernetes/cert/ca.pem \
      --service-account-private-key-file=/etc/kubernetes/cert/ca-key.pem \
      --feature-gates=RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true,Accelerators=true,DevicePlugins=true \
      --leader-elect=true \
      --controllers=*,bootstrapsigner,tokencleaner \
      --use-service-account-credentials=true \
      --kube-api-qps=1000 \
      --kube-api-burst=2000 \
      --logtostderr=true \
      --v=2
    Restart=always
    RestartSec=5
    StartLimitInterval=0
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    --port=10252、--address=127.0.0.1:在 127.0.0.1:10252 监听 http /metrics 的请求;
    --kubeconfig:指定 kubeconfig 文件路径,kube-controller-manager 使用它连接和验证 kube-apiserver;
    --cluster-signing-*-file:签名 TLS Bootstrap 创建的证书;
    --experimental-cluster-signing-duration:指定 TLS Bootstrap 证书的有效期;
    --root-ca-file:放置到容器 ServiceAccount 中的 CA 证书,用来对 kube-apiserver 的证书进行校验;
    --service-account-private-key-file:签名 ServiceAccount 中 Token 的私钥文件,必须和 kube-apiserver 的 --service-account-key-file 指定的公钥文件配对使用;
    --service-cluster-ip-range :指定 Service Cluster IP 网段,必须和 kube-apiserver 中的同名参数一致;
    --leader-elect=true:集群运行模式,启用选举功能;被选为 leader 的节点负责处理工作,其它节点为阻塞状态;
    --controllers=*,bootstrapsigner,tokencleaner:启用的控制器列表,tokencleaner 用于自动清理过期的 Bootstrap token;
    --use-service-account-credentials=true: 各 controller 使用 ServiceAccount 访问 kube-apiserver;
    --feature-gates:支持 Kubelet Client 和 Server 证书轮转,支持 GPU 加速;
    kube-controller-manager 不对请求 https metrics 的 Client 证书进行校验,故不需要指定 --tls-ca-file 参数,而且该参数已被淘汰。
    

    kube-controller-manager 的权限

    -ClusteRole: system:kube-controller-manager 的权限很小,只能创建 secret、serviceaccount 等资源对象,各 controller 的权限分散到 ClusterRole system:controller:XXX 中。
    -需要在 kube-controller-manager 的启动参数中添加 --use-service-account-credentials=true 参数,这样 main controller 会为各 controller 创建对应的 ServiceAccount XXX-controller。
    -内置的 ClusterRoleBinding system:controller:XXX 将赋予各 XXX-controller ServiceAccount 对应的 ClusterRole system:controller:XXX 权限。
    

    启动 kube-controller-manager 服务

    systemctl daemon-reload && systemctl enable kube-controller-manager
    systemctl restart kube-controller-manager && systemctl status kube-controller-manager
    

    查看当前的 leader

    [root@master-ha-10 work]# kubectl get endpoints kube-controller-manager --namespace=kube-system -o yaml
    apiVersion: v1
    kind: Endpoints
    metadata:
      annotations:
        control-plane.alpha.kubernetes.io/leader: '{"holderIdentity":"master-ha-12","leaseDurationSeconds":15,"acquireTime":"2021-02-14T06:36:15Z","renewTime":"2021-02-14T06:36:31Z","leaderTransitions":0}'
      creationTimestamp: 2021-02-14T06:36:15Z
      name: kube-controller-manager
      namespace: kube-system
      resourceVersion: "238"
      selfLink: /api/v1/namespaces/kube-system/endpoints/kube-controller-manager
      uid: f0099368-6e8e-11eb-80ef-000c295d04a3
    subsets: null
    

    部署kube-scheduler

    本文档介绍部署高可用 kube-scheduler 集群的步骤。
    该集群包含 3 个节点,启动后将通过竞争选举机制产生一个 leader 节点,其它节点为阻塞状态。当 leader 节点不可用后,剩余节点将再次进行选举产生新的 leader 节点,从而保证服务的可用性。
    为保证通信安全,本文档先生成 x509 证书和私钥,kube-scheduler 在于 kube-apiserver 的安全端口通信时使用该证书。
    

    创建 kube-scheduler 证书和私钥

    创建证书签名请求:

    cat > kube-scheduler-csr.json <<EOF
    {
        "CN": "system:kube-scheduler",
        "hosts": [
          "127.0.0.1",
          "10.0.0.10",
          "10.0.0.11",
          "10.0.0.12"
        ],
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
          {
            "C": "CN",
            "ST": "BeiJing",
            "L": "BeiJing",
            "O": "system:kube-scheduler",
            "OU": "4Paradigm"
          }
        ]
    }
    EOF
    
    hosts 列表包含所有 kube-scheduler 节点 IP;
    CN 为 system:kube-scheduler、O 为 system:kube-scheduler,kubernetes 内置的 ClusterRoleBindings system:kube-scheduler 将赋予 kube-scheduler 工作所需的权限。
    

    生成证书和私钥

    cfssl gencert -ca=/root/work/ca.pem 
    -ca-key=/root/work/ca-key.pem 
    -config=/root/work/ca-config.json 
    -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler
    
    [root@master-ha-10 work]# ls kube-scheduler*pem
    kube-scheduler-key.pem  kube-scheduler.pem
    

    创建和分发 kubeconfig 文件

    kubeconfig 文件包含访问 apiserver 的所有信息,如 apiserver 地址、CA 证书和自身使用的证书;

    $kubectl config set-cluster kubernetes 
    --certificate-authority=/root/work/ca.pem 
    --embed-certs=true 
    --server=https://10.0.0.252:8443 
    --kubeconfig=kube-scheduler.kubeconfig
    
    $kubectl config set-credentials system:kube-scheduler 
    --client-certificate=/root/work/kube-scheduler.pem 
    --client-key=/root/work/kube-scheduler-key.pem 
    --embed-certs=true 
    --kubeconfig=kube-scheduler.kubeconfig
    
    $kubectl config set-context system:kube-scheduler 
    --cluster=kubernetes 
    --user=system:kube-scheduler 
    --kubeconfig=kube-scheduler.kubeconfig
    
    $kubectl config use-context system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig
    
    上一步创建的证书、私钥以及 kube-apiserver 地址被写入到 kubeconfig 文件中;
    

    分发 kubeconfig 到所有 master 节点:

    scp kube-scheduler.kubeconfig 10.0.0.10:/etc/kubernetes/
    scp kube-scheduler.kubeconfig 10.0.0.11:/etc/kubernetes/
    scp kube-scheduler.kubeconfig 10.0.0.12:/etc/kubernetes/
    
    mkdir /etc/kubernetes/kube-scheduler 所有master节点操作
    

    创建和分发 kube-scheduler systemd unit 文件

    所有master节点操作

    cat > /usr/lib/systemd/system/kube-scheduler.service <<EOF
    [Unit]
    Description=Kubernetes Scheduler
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    
    [Service]
    WorkingDirectory=/etc/kubernetes/kube-scheduler
    ExecStart=/usr/bin/kube-scheduler \
      --address=127.0.0.1 \
      --kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \
      --leader-elect=true \
      --kube-api-qps=100 \
      --logtostderr=true \
      --v=2
    Restart=always
    RestartSec=5
    StartLimitInterval=0
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    --address:在 127.0.0.1:10251 端口接收 http /metrics 请求;kube-scheduler 目前还不支持接收 https 请求;
    --kubeconfig:指定 kubeconfig 文件路径,kube-scheduler 使用它连接和验证 kube-apiserver;
    --leader-elect=true:集群运行模式,启用选举功能;被选为 leader 的节点负责处理工作,其它节点为阻塞状态;
    

    启动 kube-scheduler 服务

    systemctl daemon-reload && systemctl enable kube-scheduler 
    systemctl restart kube-scheduler && systemctl status kube-scheduler
    

    查看当前的 leader

    kubectl get endpoints kube-scheduler --namespace=kube-system  -o yaml
    apiVersion: v1
    kind: Endpoints
    metadata:
      annotations:
        control-plane.alpha.kubernetes.io/leader: '{"holderIdentity":"master-ha-10","leaseDurationSeconds":15,"acquireTime":"2021-02-14T06:46:16Z","renewTime":"2021-02-14T06:46:28Z","leaderTransitions":0}'
      creationTimestamp: 2021-02-14T06:46:16Z
      name: kube-scheduler
      namespace: kube-system
      resourceVersion: "543"
      selfLink: /api/v1/namespaces/kube-system/endpoints/kube-scheduler
      uid: 55f242ce-6e90-11eb-80ef-000c295d04a3
    subsets: null
    

    查看输出的 metrics

    注意:以下命令在 kube-scheduler 节点上执行。
    kube-scheduler 监听 10251 端口,接收 http 请求:

    curl -s http://127.0.0.1:10251/metrics | head
    # HELP go_gc_duration_seconds A summary of the GC invocation durations.
    # TYPE go_gc_duration_seconds summary
    go_gc_duration_seconds{quantile="0"} 7.8802e-05
    go_gc_duration_seconds{quantile="0.25"} 8.7325e-05
    go_gc_duration_seconds{quantile="0.5"} 0.000202452
    go_gc_duration_seconds{quantile="0.75"} 0.000473563
    go_gc_duration_seconds{quantile="1"} 0.000956121
    go_gc_duration_seconds_sum 0.002215629
    go_gc_duration_seconds_count 7
    # HELP go_goroutines Number of goroutines that currently exist.
    
  • 相关阅读:
    volcanol的工控博客
    volcanol的工控博客
    volcanol的工控博客
    volcanol的工控博客
    volcanol的工控博客
    volcanol的工控博客
    volcanol的工控博客
    volcanol的工控博客
    volcanol的工控博客
    Oracle分析函数-排序排列(rank、dense_rank、row_number、ntile)
  • 原文地址:https://www.cnblogs.com/you-xiaoqing/p/14411708.html
Copyright © 2011-2022 走看看