kubernetes etcd ssl安装

    技术2022-07-12  71

    etcd是一个类似于ZK的玩意,用来给分布式系统存储key-value数据,官方给了明确的定义:

    etcd is a strongly consistent, distributed key-value store that provides a reliable way to store data that needs to be accessed by a distributed system or cluster of machines. It gracefully handles leader elections during network partitions and can tolerate machine failure, even in the leader node

    kubernetes使用etcd作为后端数据的存储,所以etcd属于非常重要的一个组件,和hadoop依赖于zk是一个道理。一旦etcd服务出现问题,可以理解为整个k8s集群都无法工作。

    1. 下载etcd的二进制包,打开官网的文档,点击download and build,就会进去以下地址,选择合适的版本进行下载即可。

    https://github.com/etcd-io/etcd/releases/

    解压缩之后会发现其实就2个主要的命令 etcd和etcdctl, 前者是etcd服务启动命令,后者是etcd的客户端,可以通过etcdctl来操作etcd.

    etcd基本知识介绍:

    etcd有2个端口,一个是peer端口2380,主要作用是cluster的通信端口,另外一个是client端口2379, 作用是etcd客户端通过2379来对etcd进行操作,比如etcdctl就是使用2379来连接到etcd服务的。

    如果是单机使用etcd,直接用 ./etcd 启动服务即可,但是生产环境肯定需要使用cluster保证高可用,类似于zk。

    2. etcd cluster的安装方法

    先来看看官方安装etcd cluster的demo:

    TOKEN=token-01 CLUSTER_STATE=new NAME_1=machine-1 NAME_2=machine-2 NAME_3=machine-3 HOST_1=10.240.0.17 HOST_2=10.240.0.18 HOST_3=10.240.0.19 CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_3}=http://${HOST_3}:2380 # For machine 1 THIS_NAME=${NAME_1} THIS_IP=${HOST_1} etcd --data-dir=data.etcd --name ${THIS_NAME} \ --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \ --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \ --initial-cluster ${CLUSTER} \ --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN} # For machine 2 THIS_NAME=${NAME_2} THIS_IP=${HOST_2} etcd --data-dir=data.etcd --name ${THIS_NAME} \ --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \ --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \ --initial-cluster ${CLUSTER} \ --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN} # For machine 3 THIS_NAME=${NAME_3} THIS_IP=${HOST_3} etcd --data-dir=data.etcd --name ${THIS_NAME} \ --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \ --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \ --initial-cluster ${CLUSTER} \ --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}

    以上是一个3台集群的安装方式,其实没有什么需要安装的,仅仅是在启动的时候指定几个重要的参数,表示是cluster. 

    当我们下载好了etcd的包,我们找奇数机器,一般3,5台就够了。然后把安装包分发到各个机器,然后配置以上的启动参数即可构建一个cluster.  以上参数并不难理解,只要是peer就表示是集群内部通信,端口都是2380,而client是2379

    3. etcd ssl,采用自签证书

    如果不需要ssl,那么以上操作就已经可以构建一个集群了。但是k8s希望我们采用ssl,实际上我很难理解,k8s属于内部集群为什么非要使用ssl。不管怎么样,我们根据官方要求构建ssl

    证书的颁发流程是:生成ca根证书CSR证书申请文件->生成ca私钥以及ca根证书-> 生成用户端CSR证书申请文件->通过ca根证书及私钥+用csr文件产生签名证书

    如果不是自签证书,是不需要生成ca私钥和ca根证书的,因为ca版发机构会处理这个东西。用户只要发送csr证书申请文件给ca颁发机构即可,然后证书颁发机构通过你的csr然后会产生私钥及证书。 证书及私钥永远是配对出现,不会单一出现。(就算是根证书也是一样)

    此处采用cfssl来生产自签证书:

    1) 下载cfssl, cfssl就是3个命令,我们按照下面的地址,把几个命令下载下来即可,一般放到/usr/local/bin 目录下即可。

    wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 chmod +x cfssl_linux-amd64 sudo mv cfssl_linux-amd64 /root/local/bin/cfssl wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 chmod +x cfssljson_linux-amd64 sudo mv cfssljson_linux-amd64 /root/local/bin/cfssljson wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 chmod +x cfssl-certinfo_linux-amd64 sudo mv cfssl-certinfo_linux-amd64 /root/local/bin/cfssl-certinfo

    2)生成ca根证书及ca密钥

    参考网址:

    https://kubernetes.io/zh/docs/concepts/cluster-administration/certificates/

    csr文件可以根据上面网址的提示,自己创建即可,当然直接拷贝下面的ca-csr.json也一样。

    mkdir cert cd cert ../cfssl print-defaults config > config.json ../cfssl print-defaults csr > csr.json

    既然要生产ca根证书,所以必须有一个csr文件:ca-csr.json, 格式如下,尖括号写入自己的信息即可,随便写写就好了。

    { "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names":[{ "C": "<country>", "ST": "<state>", "L": "<city>", "O": "<organization>", "OU": "<organization unit>" }] }

    生成ca密钥和ca根证书

    cfssl gencert -initca ca-csr.json | cfssljson -bare ca

     会产生2个重要文件:ca-key.pem  ca.pem 前者是密钥,后者是证书,这是根证书,用来给其他人颁发签名证书的。

    3. 使用上面的ca证书给其他用户颁发签名证书

    准备一个ca-config.json文件,这个文件是作用是一些基本配置,比如证书过期时间之类的,用户签名证书会根据这个配置来生成

    { "signing": { "default": { "expiry": "87600h" }, "profiles": { "kubernetes": { "usages": [ "signing", "key encipherment", "server auth", "client auth" ], "expiry": "87600h" } } } }

    刚才说了,既然用户要申请证书,就一定需要一个csr申请文件,用户证书的csr文件如下, server-csr.json:

    { "CN": "kubernetes", "hosts": [ "10.203.0.46", "10.203.3.96", "10.203.0.43", "10.203.3.91", "10.203.0.44", "10.203.3.92" ], "key": { "algo": "rsa", "size": 2048 }, "names": [{ "C": "china", "ST": "shanghai", "L": "pudong", "O": "oyo", "OU": "IT" }] }

    上面有一个非常重要的配置就是 hosts, 比如我们构建etcd是3台,那么必须把3台机器全部写进去,否者内部无法信任,也就无法进行通信。

    利用之前生成的ca根证书及私钥,配合证书申请文件server-csr.json及ca-config.json证书生成的配置文件就可以为用户生成签名证书了。

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

    最后一共有4个文件, 2个是ca根证书和key, 另外2个是用户的证书及key:

    ca-key.pem ca.pem peer-key.pem peer.pem

    4. 通过签名证书构建etcd ssl并启动

    回头看一下之前不用ssl启动etcd cluster的命令:

    etcd --data-dir=data.etcd --name ${THIS_NAME} \ --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \ --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \ --initial-cluster ${CLUSTER} \ --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}

    证书生成之后,就需要把证书添加进去了, 下面是我自己的etcd启动命令:

    /data/etcd/etcd --name=etcd-node1 --data-dir=/data/etcd/data --listen-client-urls=https://10.203.0.46:2379 --listen-peer-urls=https://10.203.0.46:2380 --advertise-client-urls=https://10.203.0.46:2379 --initial-advertise-peer-urls=https://10.203.0.46:2380 --initial-cluster=etcd-node1=https://10.203.0.46:2380,etcd-node2=https://10.203.3.96:2380,etcd-node3=https://10.203.0.43:2380 --initial-cluster-state=new --peer-key-file=/data/etcd/cert/peer-key.pem --peer-cert-file=/data/etcd/cert/peer.pem --key-file=/data/etcd/cert/peer-key.pem --cert-file=/data/etcd/cert/peer.pem --client-cert-auth --trusted-ca-file=/data/etcd/cert/ca.pem --peer-client-cert-auth --peer-trusted-ca-file=/data/etcd/cert/ca.pem /data/etcd/etcd --name=etcd-node2 --data-dir=/data/etcd/data --listen-client-urls=https://10.203.3.96:2379 --listen-peer-urls=https://10.203.3.96:2380 --advertise-client-urls=https://10.203.3.96:2379 --initial-advertise-peer-urls=https://10.203.3.96:2380 --initial-cluster=etcd-node1=https://10.203.0.46:2380,etcd-node2=https://10.203.3.96:2380,etcd-node3=https://10.203.0.43:2380 --initial-cluster-state=new --peer-key-file=/data/etcd/cert/peer-key.pem --peer-cert-file=/data/etcd/cert/peer.pem --key-file=/data/etcd/cert/peer-key.pem --cert-file=/data/etcd/cert/peer.pem --client-cert-auth --trusted-ca-file=/data/etcd/cert/ca.pem --peer-client-cert-auth --peer-trusted-ca-file=/data/etcd/cert/ca.pem /data/etcd/etcd --name=etcd-node3 --data-dir=/data/etcd/data --listen-client-urls=https://10.203.0.43:2379 --listen-peer-urls=https://10.203.0.43:2380 --advertise-client-urls=https://10.203.0.43:2379 --initial-advertise-peer-urls=https://10.203.0.43:2380 --initial-cluster=etcd-node1=https://10.203.0.46:2380,etcd-node2=https://10.203.3.96:2380,etcd-node3=https://10.203.0.43:2380 --initial-cluster-state=new --peer-key-file=/data/etcd/cert/peer-key.pem --peer-cert-file=/data/etcd/cert/peer.pem --key-file=/data/etcd/cert/peer-key.pem --cert-file=/data/etcd/cert/peer.pem --client-cert-auth --trusted-ca-file=/data/etcd/cert/ca.pem --peer-client-cert-auth --peer-trusted-ca-file=/data/etcd/cert/ca.pem

    5. 测试etcd集群

    /data/etcd/etcdctl --cacert=/data/etcd/cert/ca.pem --cert=/data/etcd/cert/peer.pem --key=/data/etcd/cert/peer-key.pem --endpoints=https://10.203.3.96:2379,https://10.203.0.46:2379,https://10.203.0.43:2379 endpoint health https://10.203.0.46:2379 is healthy: successfully committed proposal: took = 13.515841ms https://10.203.0.43:2379 is healthy: successfully committed proposal: took = 13.55121ms https://10.203.3.96:2379 is healthy: successfully committed proposal: took = 14.013761ms

    因为etcd是ssl的,所以作为客户端etcdctl需要使用证书及ca颁发机构来连接etcd集群。如果不用证书,直接连接,服务器无法信任客户端。

    之前提到的非常重要的参数hosts,那个是给服务器自己用的,也就是服务器内部通信会根据hosts的配置来验证,只要配置了,就表示主机可信任。

    6. 制作etcd.service 

    此处忽略了,如果你想使用systemctl来启动关闭etcd服务,那么就制作etcd.service,交给os来管理,如果是手动启动就不需要了。

    Processed: 0.014, SQL: 9