kubernetes集群安装指南:创建CA证书及相关组件证书密钥

在实际kubernetes应用场景中,集群内组件之间访问都是通过TLS双向认证安全访问,即https访问,所以在部署时,给kubernetes各个组件创建证书是必要的,这是因为没有https安全访问会导致集群间节点通信访问不安全,非法用户可以通过客户端操作,对集群资源非法操作,引起集群服务异常,甚至集群宕机。例如:非法操作etcd存储的数据,因此集群开启https访问双向认证是必要的。

1 准备工作

1.1 变量定义及各组件使用证书说明
环境变量
# 证书及密钥存放路径
SSL_BIN_PATH=/usr/local/cfssl
CA_DIR=/etc/k8s/ssl
# 外网和内网apiserver vip访问地址
VIP_KUBEAPI_OUTSIDE=192.168.20.100
VIP_KUBEAPI_INSIDE=10.10.10.100
# master集群各节点组件监听地址
MASTER1_IP=10.10.10.22
MASTER2_IP=10.10.10.23
MASTER3_IP=10.10.10.24
# etcd集群内各节点监听地址
ETCD1_IP=10.10.10.22
ETCD2_IP=10.10.10.23
ETCD3_IP=10.10.10.24
# kubernetes默认service发地址
CLUSTER_KUBERNETES_SVC_IP=10.254.0.1
证书认证域名
DOMAIN=mo9.com
证书使用说明
kube-apiserver组件:
使用 ca.pem、kubernetes.pem、kubernetes-key.pem、etcd公私钥证书、 metric公私钥等证书;
kube-controller-manager组件
使用 ca-key.pem, ca.pem, kuber-controller-manager公私钥等证书;
kube-scheduler组件: 
使用ca.pem、kube-scheduler.pem、kube-scheduler-key.pem等证书;
kube-proxy组件:
使用 ca.pem、kube-proxy-key.pem、kube-proxy.pem等证书;
kubelet组件:
使用 ca.pem等证书;
kubectl组件:
使用 ca.pem、admin-key.pem、admin.pem等证书;
etcd组件:
使用 ca.pem、etcd-key.pem、etcd.pem等证书;
flannel组件:
使用ca.pem、flannel.pem、flannel-key.pem等证书;
备注说明:

本安装文档为所有的组件生成证书文件,实际情况下也可以选择部分组件共用某个证书或不选择开启https访问。如:etcd、flannel共用apiserver组件证书或不启用https访问,controller-manager,scheduler也可以基于http访问;

1.2 创建相关目录
mkdir -p $SSL_BIN_PATH
mkdir -p $CA_DIR
1.3 安装 cfssl 工具集

大多数情况下,kubernetes集群都是建立在自己的私有网络里,比如公有云vpc区域,自建数据中心等等,由于k8s所有相关组件都是需要TLS双向认证,合法证书机构大多都是提供ssl单向认证证书,所以必须自建CA根证书,并生成相应的公钥和私钥根证书,可以通过openssl或cfssl创建CA证书,这里以cfssl为例:

mkdir -p $SSL_BIN_PATH/bin  > /dev/null 2>&1
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -P $SS_BINL_PATH/bin/ 
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -P $SSL_BIN__PATH/bin/ 
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -P $SSL_BIN_PATH/bin/
cd  $SSL_BIN_PATH/bin/
mv cfssl_linux-amd64 cfssl  && mv cfssljson_linux-amd64 cfssljson
mv cfssl-certinfo_linux-amd64 cfssl-certinfo
chmod +x * && ln -sf $SSL_BIN_PATH/bin/cfssl* /usr/local/bin/

2. 创建相关证书


2.1 创建根证书 (CA)

CA 证书是集群所有节点共享的,只需要创建一个 CA 证书,后续创建的所有证书都由它签名。

创建CA配置文件

CA 配置文件用于配置根证书的使用场景 (profile) 和具体参数 (usage,过期时间、服务端认证、客户端认证、加密等),后续在签名其它证书时需要指定特定场景。

cat >$CA_DIR/ca-config.json<<EOF
{
  "signing": {
    "default": {
      "expiry": "175200h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "175200h"
      }
    }
  }
}
EOF
  • signing:表示该证书可用于签名其它证书,生成的 ca.pem 证书 中 CA=TRUE;
  • server auth:表示 client 可以用该该证书对 server 提供的证书进行验证;
  • client auth:表示 server 可以用该该证书对 client 提供的证书进行验证;
  • expiry 表示证书使用时间,即30年;
创建CA证书签名请求文件
cat >$CA_DIR/ca-csr.json<<EOF
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "ShangHai",
      "L": "ShangHai",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
  • CN:Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name),浏览器使用该字段验证网站是否合法;
  • O:Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group);
  • kube-apiserver 将提取的 User、Group 作为 RBAC 授权的用户标识;
生成 CA 证书公钥和私钥
cd $CA_DIR
cfssl gencert --initca=true ca-csr.json | cfssljson --bare ca
2.2 创建kubernetes公钥和私钥
创建证书签名请求:
cat >$CA_DIR/kubernetes-csr.json << EOF
{
    "CN": "kubernetes",
    "hosts": [
      "127.0.0.1",
      "${MASTER1_IP}",
      "${MASTER2_IP}",
      "${MASTER3_IP}",
      "${VIP_KUBEAPI_INSIDE}",
      "${VIP_KUBEAPI_OUTSIDE}",
      "${CLUSTER_KUBERNETES_SVC_IP}",
      "*.${DOMAIN}",
      "kubernetes",
      "kubernetes.default",
      "kubernetes.default.svc",
      "kubernetes.default.svc.cluster",
      "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "ShangHai",
            "L": "SahgnHai",
            "O": "k8s",
            "OU": "System"
        }
    ]
}
EOF
  • apiserver需要开启https访问,需要使用到服务端证书,所以需要指定host字段,哪些域名或IP使用;
  • hosts 字段指定授权使用该证书的 IP 和域名列表,这里列出了 master 节点 IP、kubernetes 服务的 IP 和域名;
  • kubernetes证书也叫kube-apiserver证书,也可以定义为kube-apiserver证书;
  • 如果需要额外指定域名,请使用泛域名方式填写,即域名型证书要求,填写对应的域名即可;
  • 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
  • kubernetes中默认的server-cluster ip以10.254.0.0开头,如需要其他网络请在apiserver配置中指定;
生成证书公钥和私钥
cd $CA_DIR
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \
kubernetes-csr.json | cfssljson -bare kubernetes
2.3 创建kube-controller-manager证书公钥和私钥
创建证书签名请求:
cat > $CA_DIR/kube-controller-manager-csr.json <<EOF
{
    "CN": "system:kube-controller-manager",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "hosts": [
      "127.0.0.1",
      "${MASTER1_IP}",
      "${MASTER2_IP}",
      "${MASTER3_IP}"
    ],
    "names": [
      {
        "C": "CN",
        "ST": "ShangHai",
        "L": "ShangHai",
        "O": "system:kube-controller-manager",
        "OU": "System"
      }
    ]
}
EOF
  • kube-controller-manager开启https访问,需要使用到服务端证书,所以需要指定host字段,哪些IP使用;
  • hosts 列表包含所有 kube-controller-manager 节点 IP,否则无法认证;
  • CN 和 O 均为 system:kube-controller-manager,kubernetes 内置的 ClusterRoleBindings system:kube-controller-manager 赋予 kube-controller-manager 工作所需的权限。
生成证书公钥和私钥
cd $CA_DIR
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \
kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
2.4 创建kube-scheduler证书公钥和私钥
创建证书签名请求:
cat > $CA_DIR/kube-scheduler-csr.json <<EOF
{
    "CN": "system:kube-scheduler",
    "hosts": [
      "127.0.0.1",
      "${MASTER1_IP}",
      "${MASTER2_IP}",
      "${MASTER3_IP}"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
      {
        "C": "CN",
        "ST": "ShangHai",
        "L": "ShangHai",
        "O": "system:kube-scheduler",
        "OU": "System"
      }
    ]
}
EOF
  • kube-scheduler开启https访问,需要使用到服务端证书,所以需要指定host字段,IP使用;
  • hosts 列表包含所有 kube-scheduler 节点 IP,否则无法认证;
  • CN 和 O 均为 system:kube-scheduler,kubernetes 内置的 ClusterRoleBindings system:kube-scheduler 将赋予 kube-scheduler 工作所需的权限;
生成证书公钥和私钥
cd $CA_DIR
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes  \
kube-scheduler-csr.json | cfssljson -bare kube-scheduler
2.5 创建kube-proxy证书公钥和私钥
创建证书签名请求:
cat > $CA_DIR/kube-proxy-csr.json << EOF
{
  "CN": "system:kube-proxy",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "ShangHai",
      "L": "SahgnHai",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
  • 该证书只会被 kube-proxy 当做 client 证书链接apiserver使用,所以 hosts 字段为空;
  • CN:指定该证书的 User 为 system:kube-proxy;
  • 预定义的 RoleBinding system:node-proxier 将User system:kube-proxy 与 Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限;
生成证书公钥和私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \
kube-proxy-csr.json | cfssljson -bare kube-proxy
2.6 创建kubectl证书公钥和私钥
创建证书签名请求:
cat > $CA_DIR/admin-csr.json << EOF
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "ShangHai",
      "L": "SahgnHai",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}
EOF
  • 该证书只会被 kubectl 当做 client 证书链接apiserver使用,所以 hosts 字段为空;
  • O 为 system:masters,kube-apiserver 收到该证书后将请求的 Group 设置为 system:masters;
  • 预定义的 ClusterRoleBinding cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予所有 API的权限;
  • kubectl证书为集群最高权限证书,对集群所有的资源都有root权限,所以请谨慎存放;
生成证书公钥和私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \
admin-csr.json | cfssljson -bare admin
2.7 创建etcd证书公钥和私钥
创建证书签名请求:
cat > $CA_DIR/etcd-csr.json << EOF
{
  "CN": "etcd",
  "hosts": [
    "127.0.0.1",
    "${ETCD1_IP}",
    "${ETCD2_IP}",
    "${ETCD3_IP}"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "ShangHai",
      "L": "SahgnHai",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
  • etcd开启https访问,需要用到服务端证书,所以需要指定哪些IP使用该证书
  • hosts 字段指定授权使用该证书的 etcd 节点 IP 或域名列表,需要将 etcd 集群的三个节点 IP 都列在其中;
生成证书公钥和私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \
etcd-csr.json | cfssljson -bare etcd
2.8 创建网络插件(Flannel)证书公钥和私钥
创建证书签名请求:
cat > $CA_DIR/flannel-csr.json << EOF
{
  "CN": "flanneld",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "ShangHai",
      "L": "ShangHai",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
  • flanneld 从 etcd 集群存取网段分配信息,而 etcd 集群启用了双向 x509 证书认证,所以需要为 flanneld 生成证书和私钥用于认证etcd安全访问。
  • 该证书只会被 kubectl 当做 client 证书使用,所以 hosts 字段为空;
生成证书公钥和私钥
cd $CA_DIR
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \
flannel-csr.json | cfssljson -bare flannel
2.9 创建metric server证书公钥和私钥
创建证书签名请求:
cat > $CA_DIR/proxy-client-csr.json <<EOF
{
  "CN": "aggregator",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "ShangHai",
      "L": "ShangHai",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
  • CN 名称需要位于 kube-apiserver 的 --requestheader-allowed-names 参数中,否则后续访问 metrics 时会提示权限不足。
生成证书公钥和私钥
cd $CA_DIR
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \
proxy-client-csr.json | cfssljson -bare proxy-client
2.10 删除签名请求相关文件(可选)
cd $CA_DIR
rm -rf *csr* && rm -rf *json
chmod 666 *

3 同步证书

  1. master节点
    同步master节点所有组件(apiserver,controller-manager,scheduler)、flannel证书、etcd证书、metric证书,ca证书;
    ansible master_k8s_vgs -m \
    synchronize -a "src=${CA_DIR} dest=${CA_DIR}/ mode=push delete=yes rsync_opts=-avz'" -b
    ansible master_k8s_vgs -m shell -a "chmod 666 ${CA_DIR}/*" -b
    ansible master_k8s_vgs -m shell -a "cd ${CA_DIR} && rm -rf kube-proxy*" -b
  2. worker节点
    同步worker节点所有证书(kube-proxy证书),flannel证书,ca证书公钥
    ansible worker_k8s_vgs -m copy -a "src=${CA_DIR}/ca.pem dest=${CA_DIR}/" -b
    ansible worker_k8s_vgs -m copy -a "src=${CA_DIR}/flannel.pem dest=${CA_DIR}/" -b
    ansible worker_k8s_vgs -m copy -a "src=${CA_DIR}/flannel-key.pem dest=${CA_DIR}/" -b

    备注:

    • ansible部分在上一小节已经配置完成,此处使用同步模块,将证书同步到各个节点服务;
    • 如果组件需要开启https访问才需要将对应的证书文件拷贝到对应的组件所在的节点上,worker节点只需要kubeconfig认证文件以及flannel等证书,kube-apiserver会自动为kubelet轮转证书;

证书创建内容基本完成,关于tls证书双向认证请自行查阅文档,创建完成证书后,还需要创建各组件认证文件,请参阅下一节:kubernetes集群安装指南:客户端安装及各组件认证文件创建

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值