Middleware / 运维笔记

Etcd 集群部署

Einic Yeo · 4月25日 · 2019年 ·

一、Etcd 简介

Etcd 是一种分布式 kv 存储设施, 他具有一定的一致性,高性能,高可用的方案. 类似的 zookeeper, 但没有 zookeeper 那么重型,功能也没有覆盖那么多. 简单直接的应用就是配置中心

节点信息:

namehost
node0 192.168.0.240
node1 192.168.0.241
node3192.168.0.242

二、准备工作

1.关闭并停用防火墙

systemctl stop firewalld.service 

systemctl disable firewalld.service

2.永久关闭SELinux 

vim /etc/selinux/config 

SELINUX=disabled

3.同步集群系统时间

 yum -y install ntp

 ntpdate cn.ntp.org.cn

4.重启机器

reboot

三、TLS密钥和证书

1.安装go语言组件

cd /usr/local/src
wget http://redirector.gvt1.com/edgedl/go/go1.9.2.linux-amd64.tar.gz
tar -xvf go1.9.2.linux-amd64.tar.gz -C /usr/local

2.配置go环境

cat >> /etc/profile << EOF
#go的安装路径
export GOROOT=/usr/local/go
#go安装的工具路径
export GOPATH=/opt/go
export PATH=$GOROOT/bin:$PATH
EOF
source /etc/profile

3.安装cfssl

将会用使用cfssl生成所需要的私钥和证书

go get -u github.com/cloudflare/cfssl/cmd/...

会在$GOPATH/bin下安装cfssl, cfssjosn, mkbundle等工具。

创建CA证书和私钥,准备为etcd和其它组件办法证书和签名

创建ca-config.json

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

ca-config.json中可以定义多个profile,分别设置不同的expiry和usages等参数。如上面的ca-config.json中定义了名称为aspire的profile,这个profile的expiry 87600h为10年,useages中:

  • signing表示此CA证书可以用于签名其他证书,ca.pem中的CA=TRUE
  • server auth表示TLS Server Authentication
  • client auth表示TLS Client Authentication

创建CA证书签名请求配置ca-csr.json

{
  "CN": "aspire",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "aspire",
      "OU": "cloudnative"
    }
  ]
}

生成CA证书和私钥

cfssl gencert -initca ca-csr.json | cfssljson -bare ca
ls
ca-config.json  ca.csr  ca-csr.json  ca-key.pem  ca.pem

生成etcd证书和私钥

创建etcd证书签名请求配置etcd-csr.json

{
    "CN": "aspire.etcd",
    "hosts": [
      "127.0.0.1",
      "192.168.0.240",
      "192.168.0.241",
      "192.168.0.242",
      "node0",
      "node1",
      "node2"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "BeiJing",
            "L": "BeiJing",
            "O": "aspire.etcd",
            "OU": "Operation and maintenance center"
        }
    ]
}

该”hosts”是可以使用该证书域名列表。‘CN’,kube-apiserver从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;

该”names”值实际上是名称对象的列表。每个名称对象应至少包含一个“C”,“L”,“O”,“OU”或“ST”值(或这些的任意组合)。这些值是:

  • “C”:国家
  • “L”:地区或城市(如城市或城镇名称)
  • “O”:组织 Organization,kube-apiserver从证书中提取该字段作为请求用户所属的组 (Group);
  • “OU”:组织单位,如负责拥有密钥的部门; 它也可以用于“版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!做生意”(DBS)的名称
  • “ST”:州或省

下面生成etcd的证书和私钥:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=aspire etcd-csr.json | cfssljson -bare etcd

对生成的证书可以使用cfssl或openssl查看

 $ cfssl-certinfo -cert etcd.pem
{
  "subject": {
   ...
      "cloudnative",
      "aspire"
    ]
  },
  "serial_number": "555738010691550377350124675225187029254417657480",
  "sans": [
      "127.0.0.1",
      "192.168.0.240",
      "192.168.0.241",
      "192.168.0.242",
      "node0",
      "node1",
      "node2"
  ],
  "not_before": "2018-12-18T06:57:00Z",
  "not_after": "2028-12-16T06:57:00Z",
  "sigalg": "SHA256WithRSA",
  "authority_key_id": "DB:5D:58:25:31:D5:2A:D8:DB:C1:EF:C4:68:B4:B0:13:FA:6B:42:C3",
  "subject_key_id": "6D:9B:6E:6A:F8:40:4D:4C:03:A4:0F:05:58:E1:9A:72:2E:8E:AB:58",
  "pem": "-----BEGIN CERTIFICATE-----\nMIIETjCCAzagAwIBAgIUYVgnfkNJEfm75Tye3fynwTrvrogwDQYJKoZIhvcNAQEL\nBQAwaTELMAkGA1UEBhMCQ04xEDAOBgNVBAgTB0JlaUppbmcxEDA...
  "

}

将生成的CA证书ca.pem, etcd秘钥etcd-key.pem, etcd证书etcd.pem拷贝到各节点的/etc/etcd/ssl目录中

四、ETCD 安装与配置

1. 安装ETCD:

yum -y install etcd (由于是rpm包所以可以用remove卸载)

2. 配置准备:

#创建数据与日志文件目录
mkdir -p /data/etcd/{data,logs}
#创建用户与目录授权
useradd -s /sbin/nologin -M -U etcd && chown -R etcd:etcd /data/etcd/

3. 配置etcd.service :

在每个节点上创建etcd的systemd unit文件/usr/lib/systemd/system/etcd.service,注意替换ETCD_NAME和INTERNAL_IP变量的值:

export ETCD_NAME=node1
export INTERNAL_IP=192.168.0.240
cat > /usr/lib/systemd/system/etcd.service <<EOF
[Unit]
Description=etcd server
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
WorkingDirectory=/var/lib/etcd
EnvironmentFile=-/etc/etcd/etcd.conf
ExecStart=/usr/bin/etcd \
  --name ${ETCD_NAME} \
  --cert-file=/etc/etcd/ssl/etcd.pem \
  --key-file=/etc/etcd/ssl/etcd-key.pem \
  --peer-cert-file=/etc/etcd/ssl/etcd.pem \
  --peer-key-file=/etc/etcd/ssl/etcd-key.pem \
  --trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
  --initial-advertise-peer-urls https://${INTERNAL_IP}:2380 \
  --listen-peer-urls https://${INTERNAL_IP}:2380 \
  --listen-client-urls https://${INTERNAL_IP}:2379,https://127.0.0.1:2379 \
  --advertise-client-urls https://${INTERNAL_IP}:2379 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-cluster node0=https://192.168.0.240:2380,node1=https://192.168.0.241:2380,node2=https://192.168.0.242:2380 \
  --initial-cluster-state new \
  --data-dir=/data/etcd/
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

上面在启动参数中指定了etcd的工作目录和数据目录是/var/lib/etcd

  • –cert-file和–key-file分别指定etcd的公钥证书和私钥
  • –peer-cert-file和–peer-key-file分别指定了etcd的Peers通信的公钥证书和私钥。
  • –trusted-ca-file指定了客户端的CA证书
  • –peer-trusted-ca-file指定了Peers的CA证书
  • –initial-cluster-state new表示这是新初始化集群,–name指定的参数值必须在–initial-cluster中

etcd 启动

在各节点启动etcd

systemctl daemon-reload
systemctl enable etcd
systemctl start etcd
systemctl status etcd

检查集群是否健康

etcdctl \
  --ca-file=/etc/etcd/ssl/ca.pem \
  --cert-file=/etc/etcd/ssl/etcd.pem \
  --key-file=/etc/etcd/ssl/etcd-key.pem \
  --endpoints=https://node0:2379,https://node1:2379,https://node2:2379 \
  cluster-health
  
2019-04-24 19:53:40.545148 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
2019-04-24 19:53:40.546127 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
member 4f2f99d70000fc19 is healthy: got healthy result from https://192.168.0.240:2379
member 99a756f799eb4163 is healthy: got healthy result from https://192.168.0.241:2379
member a9aff19397de2e4e is healthy: got healthy result from https://192.168.0.242:2379
cluster is healthy

增减成员节点

1.新增节点:

新增节点(例如192.168.0.243)

  在集群任意节点输入:

  etcdctl member add http://192.168.0.243:2380

  命令行返回:

  added member 9bf1b35fc7761a23 to cluster

  ETCD_NAME="node3"

  ETCD_INITIAL_CLUSTER="node0=http://192.168.0.240:2380,node1=http://192.168.0.241,node2=http://192.168.0.242:2380,node3=http://192.168.0.243:2380"

  ETCD_INITIAL_CLUSTER_STATE=existing

  其中ETCD_INITIAL_CLUSTER是最为重要的信息,记录了集群成员。

2.删除节点:

删除节点的etcd服务会自动停止,若要将其加入其他集群,需要先清除/ETCD/data下的数据内容。

etcdctl member remove 节点ID
版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!

3.备份数据:

etcdctl backup --data-dir /data/etcd/data/ --backup-dir /data/backup/etcd

五、ETCD 操作

etcd 在键的组织上采用了层次化的空间结构(类似于文件系统中目录的概念),用户指定的键可以为单独的名字,如 testkey,此时实际上放在根目录 / 下面,也可以为指定目录结构,如 cluster1/node2/testkey,则将创建相应的目录结构。

注:CRUD 即 Create, Read, Update, Delete,是符合 REST 风格的一套 API 操作。

set

指定某个键的值。例如

➜ ~ etcdctl set /testdir/testkey “Hello world”
Hello world

支持的选项包括:

–ttl ‘0’ 该键值的超时时间(单位为秒),不配置(默认为 0)则永不超时
–swap-with-value value 若该键现在的值是 value,则进行设置操作
–swap-with-index ‘0’ 若该键现在的索引值是指定索引,则进行设置操作

get

获取指定键的值。例如

➜ ~ etcdctl get /testdir/testkey
Hello world

当键不存在时,则会报错。例如

➜ ~ etcdctl get /testdir/testkey2
Error: 100: Key 版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!not found (/testdir/testkey2) [18]

支持的选项为

–sort 对结果进行排序
–consistent 将请求发给主节点,保证获取内容的一致性

update

当键存在时,更新值内容。例如

➜ ~ etcdctl update /testdir/testkey “Hello”
Hello

当键不存在时,则会报错。例如

➜ ~ etcdctl update /testdir/testkey2 “Hello”
Error: 100: Key not found (/testdir/testkey2) [19]

支持的选项为

–ttl ‘0’ 超时时间(单位为秒),不配置(默认为 0)则永不超时

rm

删除某个键值。例如

➜ ~ etcdctl rm /testdir/testkey
PrevNode.Value: Hello

当键不存在时,则会报错。例如

➜ ~ etcdctl rm /testdir/testkey
Error: 100: Key not found (/testdir/testkey) [20]

支持的选项为

–dir 如果键是个空目录或者键值对则删除
–recursive 删除目录和所有子键
–with-value 检查现有的值是否匹配
–with-index ‘0’ 检查现有的 index 是否匹配

mk

如果给定的键不存在,则创建一个新的键值。例如

➜ ~ etcdctl mk /testdir/testkey “Hello world”
Hello world

当键存在的时候,执行该命令会报错,例如

➜ ~ etcdctl mk /testdir/testkey “Hello world”
Error: 105: Key already exists (/testdir/testkey) [21]

支持的选项为

–ttl ‘0’ 超时时间(单位为秒),不配置(默认为 0)则永不超时

mkdir

如果给定的键目录不存在,则创建一个新的键目录。例如

➜ ~ etcdctl mkdir testdir2

当键目录存在的时候,执行该命令会报错,例如

➜ ~ etcdctl mkdir testdir2
Error: 105: Key already exists (/testdir2) [22]

支持的选项为

–ttl ‘0’ 超时时间(单位为秒),不配置(默认为 0)则永不超时

setdir

创建一个键目录,无论存在与否。

支持的选项为

–ttl ‘0’ 超时时间(单位为秒),不配置(默认为 0)则永不超时

updatedir

更新一个已经存在的目录。 支持的选项为

–ttl ‘0’ 超时时间(单位为秒),不配置(默认为 0)则永不超时

rmdir

删除一个空目录,或者键值对。

➜ ~ etcdctl setdir dir1
➜ ~ etcdctl rmdir dir1

若目录不空,会报错

➜ ~ etcdctl set /dir/testkey hi
hi
➜ ~ etcdctl rmdir /dir
Error: 108: Directory not empty (/dir) [29]

ls

列出目录(默认为根目录)下的键或者子目录,默认不显示子目录中内容。

例如

➜ ~ etcdctl ls
/testdir
/testdir2
/dir
➜ ~ etcdctl ls dir
/dir/testkey

支持版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!的选项包括

–sort 将输出结果排序
–recursive 如果目录下有子目录,则递归输出其中的内容
-p 对于输出为目录,在最后添加 `/` 进行区分

六、ETCD 管理

backup

备份 etcd 的数据。

支持的选项包括

–data-dir etcd 的数据目录
–backup-dir 备份到指定路径

watch

监测一个键值的变化,一旦键值发生更新,就会输出最新的值并退出。

例如,用户更新 testkey 键值为 Hello watch。

➜ ~ etcdctl get /testdir/testkey
Hello world
➜ ~ etcdctl set /testdir/testkey “Hello watch”
Hello watch
➜ ~ etcdctl watch testdir/testkey
Hello watch

支持的选项包括

–forever 一直监测,直到用户按 `CTRL+C` 退出
–after-index ‘0’ 在指定 index 之前一直监测
–recursive 返回所有的键值和子键值

exec-watch

监测一个键值的变化,一旦键值发生更新,就执行给定命令。

例如,用户更新 testkey 键值。

➜ ~ etcdctl exec-watch testkey — sh -c ‘ls’
default.etcd
Documentation
etcd
etcdctl
etcd-migrate
README-etcdctl.md
README.md

支持的选项包括

–after-index ‘0’ 在指定 index 之前一直监测
–recursive 返回所有的键值和子键值

member

通过 list、add、remove 命令列出、添加、删除 etcd 实例到 etcd 集群中。

例如本地启动一个 etcd 服务实例后,可以用如下命令进行查看。

$ etcdctl member list
ce2a822cea30bfca: name=default peerURLs=http://localhost:2380,http://localhost:7001 clientURLs=http://localhost:2379,http://localhost:4001

命令选项

--debug 输出 cURL 命令,显示执行命令的时候发起的请求
--no-sync 发出请求之前不同步集群信息
--output, -o 'simple' 输出内容的格式 (simple 为原始信息,json 为进行json格式解码,易读性好一些)
--peers, -C 指定集群中的同伴信息,用逗号隔开 (默认为: "127.0.0.1:4001")
--cert-file HTTPS 下客户端使用的 SSL 证书文件
--key-file HTTPS 下客户端使用的 SSL 密钥文件
--ca-file 服务端使用 HTTPS 时,使用 CA 文件进行验证
--help, -h 显示帮助命令信息
--version, -v 打印版本信息

七、ETCD 总结

    ETCD集群的操作分两个阶段,即启动与运行阶段,启动阶段的集群有3种配置方式,

  • 静态配置
  • etcd自发现模式
  • DNS自发现模式

    本文采用的是静态配置,etcd自发现模式与静态配置的区别在于静态模式预先知道所有节点的ip信息,而etcd自发现则不用,

配置方法与静态配置类似,仅仅将启动脚本 etcd.service 中–initial-cluster参数去掉,新增:

--discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de\

    其中,discovery参数的获取方法:

curl https://discovery.etcd.io/new?size=3
返回 
https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de

两种启动方法的运行阶段操作基本一致。

参考文献

https://github.com/etcd-io/etcd/blob/master/Documentation/v2/clustering.md#public-etcd-discovery-servi版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!ce

https://www.cnblogs.com/devilwind/p/8880686.html

https://dreambo8563.github.io/2018/09/14/Etcd-%E5%88%86%E5%B8%83%E5%BC%8F%E9%85%8D%E7%BD%AE%E4%B8%AD%E5%BF%83/

0 条回应