K&

ETCD(基于TLS部署)外部集群

 

 

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

 

利用CFSSL生成需要的证书

 

创建CA签名配置文件

 

cat > ca-config.json << EOF
{
    "signing": {
        "default": {
            "expiry": "87600h"
        },
        "profiles": {
     #给服务端用的
"etcdserver": { "expiry": "87600h", "usages": [ "signing", "key encipherment", "server auth", "client auth" ] },
      #给etcdctl查询信息用的
"etcdclient": { "expiry": "87600h", "usages": [ "signing", "key encipherment", "client auth" ] },
      #给member用的
"etcdpeer": { "expiry": "87600h", "usages": [ "signing", "key encipherment", "server auth", "client auth" ] } } } } EOF

 

 

ca-config.json:可以定义多个profiles,分别指定不同的过期时间、使用场景等参数。后续在签名证书时使用定义的某个profile

 

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


signing:表示该证书可用于签名其它证书


key encipherment:密钥加密


server auth:表示client可以用该CA对server提供的证书进行验证


client auth:表示server可以用该CA对client提供的证书进行验证

 

创建签名请求文件

 

cat > ca-csr.json <<EOF
{
    "CN": "Etcd CA",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Beijing",
            "ST": "Beijing"
        }
    ]
}
EOF

 

 

 

CN(Common Name):kubernetes的apiserver从证书中提取该字段作为请求的用户名 (User Name),浏览器使用该字段验证网站是否合法。对于 SSL 证书,一般为网站域名,而对于代码签名证书则为申请单位名称,而对于客户端证书则为证书申请者的姓名。

O(Organization):kubernetes的apiserver从证书中提取该字段作为请求用户所属的组 (Group)。对于客户端单位证书则为证书申请者所在单位名称。

C(Country):所在国家

L(Locality):所在城市

ST(State/Provice):所在省(没记错应该有叫S的,可选)这东西都是国外的所以国外把省好像叫州个人猜测

 

 

单向认证双向认证


SSL/TLS单向认证,双向认证?


单向认证指的是只有单一一侧对象校验对端的证书合法性。


多数都是client来校验服务端的合法性。那么client需要一个ca.crt,服务器需要server.crt,server.key

 

双向认证指的是相互校验,你看我我也看你(互相伤害)。


server 需要 server.key 、server.crt 、ca.crt(CA证书)


client 需要 client.key 、client.crt 、ca.crt

 

 

生成根证书和私钥

 

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

 

 

会生成多出几个文件:


ca-key.pem
ca.csr
ca.pem

 

查看证书的信息的话用openssl吧,cfssl的信息太简陋了。命令如下

 

cfssl certinfo -cert=ca.pem
openssl x509
-noout -text -in ca.pem

 

创建服务端的签名请求配置文件(提供给客户端进行校验)

 

cat > server-csr.json << EOF
{
    "CN": "etcd server",
    "hosts": [
    "172.21.130.169",
    "172.21.130.168",
    "172.28.17.85"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing"
        }
    ]
}
EOF

 

 

生成server证书与私钥

 

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

 

可以在生成一个member-csr.json给etcd成员之间使用,client就给etcdctl使用也可以(server-csr.json  copy  member-csr.json修改一下名字即可)

 

生成etcdctl客户端使用的证书

 

配置签名请求文件

 

cat > client.json <<EOF
{
    "CN": "etcdclient",
    "hosts": [
    "172.21.130.169",
    "172.21.130.168",
    "172.28.17.85"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing"
        }
    ]
}
EOF

 

生成证书

 

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcdclient client.json | cfssljson -bare client

 

开始部署ETCD服务

 

1、规划的etcd应用家目录在/var/local/etcd下

 

ETCD所有文件都在/var/local/etcd/下。分别是ssl(证书)、cfg(配置文件)、data(数据文件)数据可以在细分为wal与data

 

2、所以每个节点创建ETCD家目录

 

mkdir /var/local/etcd 

 

3、在etcd1上把所有文件都cp过去

 

 

scp /usr/lib/systemd/system/etcd.service root@172.21.130.168:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/etcd.service root@172.28.17.85:/usr/lib/systemd/system/
scp -r /var/local/etcd/ root@172.21.130.168:/var/local/etcd/
scp -r /var/local/etcd/ root@172.28.17.85:/var/local/etcd/
scp -r /usr/local/bin/{etcd,etcdctl} root@172.21.130.168:/usr/local/bin
scp -r /usr/local/bin/{etcd,etcdctl} root@172.28.17.85:/usr/local/bin

 

 

4、修改每个节点配置文件

 

 

#节点1

[root@master etcd_ssl]# cat /var/local/etcd/cfg/etcd.conf 
#[Member]

#冲突就失败,而且报错不明显,默认是default也就是http://localhost:2380
ETCD_NAME
="etcd-1" ETCD_DATA_DIR="/var/local/etcd/data/default.etcd"

#监听集群内部其他member发过来的请求通过这个设置的ip:port

ETCD_LISTEN_PEER_URLS="https://172.21.130.169:2380"
#监听客户端发过来的请求通过这个设置的ip:port
ETCD_LISTEN_CLIENT_URLS
="https://172.21.130.169:2379" #[Clustering]
#通过这个参数告诉member如果联系我请通过这个ip:port
ETCD_INITIAL_ADVERTISE_PEER_URLS
="https://172.21.130.169:2380"
#通过这个参数告诉客户端如果联系我请通过这个ip:port
ETCD_ADVERTISE_CLIENT_URLS
="https://172.21.130.169:2379"
#这个是静态的配置方式还有动态发现的不过依赖于已有etcd集群才可以,启动会通过这个参数配置找对应的机器
ETCD_INITIAL_CLUSTER
="etcd-1=https://172.21.130.169:2380,etcd-2=https://172.21.130.168:2380,etcd-3=https://172.28.17.85:2380"
ETCD_INITIAL_CLUSTER_TOKEN
="my-etcd-cluster"

#有两个值new和existing。如果填为existing,则该member启动时会尝试与其他member交互。

集群初次建立时,要填为new,通过测试发现最后一个节点填existing也正常(因为属于后加入,不能同时启动进程,existing要落后前两个节点一丢丢时间启动),其他节点不能填为existing。

集群运行过程中,一个member故障后恢复时填为existing,如果是new的话需要集群没有业务数据。

概括如下:

new适用于无数据集群加入(就是所有节点都没有业务数据)

existing适用于有数据的集群加入(有两个节点有数据,新节点没有数据)

ETCD_INITIAL_CLUSTER_STATE="new"

#[security]
ETCD_CERT_FILE="/var/local/etcd/ssl/server.pem"
ETCD_KEY_FILE="/var/local/etcd/ssl/server-key.pem"

#受信任的CA证书
ETCD_TRUSTED_CA_FILE
="/var/local/etcd/ssl/ca.pem" ETCD_PEER_CERT_FILE="/var/local/etcd/ssl/member.pem" ETCD_PEER_KEY_FILE="/var/local/etcd/ssl/member-key.pem"
#受信任的CA证书
ETCD_PEER_TRUSTED_CA_FILE
="/var/local/etcd/ssl/ca.pem"
#将为受信任CA签名的证书的客户端,检查所有的传入的HTTPS请求,不能提供有效客户端证书的请求会失败
ETCD_CLIENT_CERT_AUTH
="true"
#将为受信任CA签名的证书的客户端,检查所有传入的对等请求
ETCD_PEER_CLIENT_CERT_AUTH
="true"
#为客户端的TLS链接,使用自动生成的自签名证书
ETCD_AUTO_TLS
="true"

#为对等体之间的TLS链接使用自动生成的自签名证书 ETCD_PEER_AUTO_TLS="true" #节点2 #[Member] ETCD_NAME="etcd-2" ETCD_DATA_DIR="/var/local/etcd/data/default.etcd" ETCD_LISTEN_PEER_URLS="https://172.21.130.168:2380" ETCD_LISTEN_CLIENT_URLS="https://172.21.130.168:2379" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.21.130.168:2380" ETCD_ADVERTISE_CLIENT_URLS="https://172.21.130.168:2379" ETCD_INITIAL_CLUSTER="etcd-1=https://172.21.130.169:2380,etcd-2=https://172.21.130.168:2380,etcd-3=https://172.28.17.85:2380" ETCD_INITIAL_CLUSTER_TOKEN="my-etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" #[security] ETCD_CERT_FILE="/var/local/etcd/ssl/server.pem" ETCD_KEY_FILE="/var/local/etcd/ssl/server-key.pem" ETCD_TRUSTED_CA_FILE="/var/local/etcd/ssl/ca.pem" ETCD_PEER_CERT_FILE="/var/local/etcd/ssl/member.pem" ETCD_PEER_KEY_FILE="/var/local/etcd/ssl/member-key.pem" ETCD_PEER_TRUSTED_CA_FILE="/var/local/etcd/ssl/ca.pem" ETCD_CLIENT_CERT_AUTH="true" ETCD_PEER_CLIENT_CERT_AUTH="true" ETCD_AUTO_TLS="true" ETCD_PEER_AUTO_TLS="true" #节点3 #[Member] ETCD_NAME="etcd-3" ETCD_DATA_DIR="/var/local/etcd/data/default.etcd" ETCD_LISTEN_PEER_URLS="https://172.28.17.85:2380" ETCD_LISTEN_CLIENT_URLS="https://172.28.17.85:2379,http://172.28.17.85:2379" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.28.17.85:2380" ETCD_ADVERTISE_CLIENT_URLS="https://172.28.17.85:2379" ETCD_INITIAL_CLUSTER="etcd-1=https://172.21.130.169:2380,etcd-2=https://172.21.130.168:2380,etcd-3=https://172.28.17.85:2380" ETCD_INITIAL_CLUSTER_TOKEN="my-etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" #[security] ETCD_CERT_FILE="/var/local/etcd/ssl/server.pem" ETCD_KEY_FILE="/var/local/etcd/ssl/server-key.pem" ETCD_TRUSTED_CA_FILE="/var/local/etcd/ssl/ca.pem" ETCD_PEER_CERT_FILE="/var/local/etcd/ssl/member.pem" ETCD_PEER_KEY_FILE="/var/local/etcd/ssl/member-key.pem" ETCD_PEER_TRUSTED_CA_FILE="/var/local/etcd/ssl/ca.pem" ETCD_CLIENT_CERT_AUTH="true" ETCD_PEER_CLIENT_CERT_AUTH="true" ETCD_AUTO_TLS="true" ETCD_PEER_AUTO_TLS="true"

 

 

5、启动

 

 

[root@master etcd_ssl]# cat /usr/lib/systemd/system/etcd.service 
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
EnvironmentFile=/var/local/etcd/cfg/etcd.conf
ExecStart=/usr/local/bin/etcd --logger=zap
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

启动

 

systemctl start etcd

 

 

 

 

 

6、检查集群状态

 

 

ETCDCTL_API=3 /var/local/etcd/bin/etcdctl --cacert=/var/local/etcd/ssl/ca.pem --cert=/var/local/etcd/ssl/client.pem --key=/var/local/etcd/ssl/client-key.pem --endpoints="https://172.21.130.169:2379,https://172.21.130.168:2379,https://172.28.17.85:2379" endpoint health --write-out=table

 

如果嫌太长麻烦,把相关证书设置成环境变量即可。而且endpoints可以写一个,目的实际就是想写的那个节点发送查询请求。

 

 

导致下面的原因:

conflicting environment variable "ETCD_CERT_FILE" is shadowed by corresponding command-line flag (either unset environment variable or disable flag)

 

下面的参数如果在配置文件中配置了,就不要在unit启动文件中再次配置了,会因为冲突导致启动失败因为会自动加载配置文件中的参数,然后在加载下面的参数导致上面的结果

 

WorkingDirectory 这是个奇葩如果在unit中配置了一定要确保指定的目录存在,不存在会报错。日志没有相关明确点出该错误。

[Unit]
Description=Etcd Server
After=network.target
 
[Service]
Type=notify
WorkingDirectory=/var/local/etcd/
EnvironmentFile=/var/local/etcd/cfg/etcd.conf
ExecStart=/usr/local/bin/etcd \
--name=${ETCD_NAME} \
--data-dir=${ETCD_DATA_DIR} \
--listen-peer-urls=${ETCD_LISTEN_PEER_URLS} \
--listen-client-urls=${ETCD_LISTEN_CLIENT_URLS} \
--advertise-client-urls=${ETCD_ADVERTISE_CLIENT_URLS} \
--initial-advertise-peer-urls=${ETCD_INITIAL_ADVERTISE_PEER_URLS} \
--initial-cluster=${ETCD_INITIAL_CLUSTER} \
--initial-cluster-token=${ETCD_INITIAL_CLUSTER_TOKEN} \
--initial-cluster-state=${ETCD_INITIAL_CLUSTER_STATE} \
--cert-file=${ETCD_CERT_FILE} \
--key-file=${ETCD_KEY_FILE} \
--trusted-ca-file=${ETCD_TRUSTED_CA_FILE} \
--peer-cert-file=${ETCD_PEER_CERT_FILE} \
--peer-key-file=${ETCD_PEER_KEY_FILE} \
--peer-trusted-ca-file=${ETCD_PEER_TRUSTED_CA_FILE}
Restart=on-failure
LimitNOFILE=65536
 
[Install]
WantedBy=multi-user.target

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2021-05-17 18:38  K&  阅读(492)  评论(0)    收藏  举报