.1. ETCD介绍
ETCD是一个K-V分布式数据存储库,为分布式系统提供关键数据的存储服务。主要特点
- 简单:设计简单、部署简单,API简单
- 安全:可部署为自认证系统
- 快速:写入性能测试达到了10k/s
- 可靠:基于Raft算法
Raft算法的介绍,可以参考:The Raft Consensus Algorithm。Raft的提出,主要是为了解决Paxos算法的如下短板
- 晦涩难懂
- 落地困难
因此,Raft设计之初就是为了易与理解而设计。在上述参考文献中,详细介绍了Raft算的机制/原理等内容。
.2. 部署ETCD集群
ETCD集群的部署,也较为简单。不安全的集群部署,这里不再讨论。这里的部署,主要是指自认证的ETCD集群。
ETCD集群部署配置,可以参考:ETCD集群部署、etcd多台部署:启用https以及ca自签名。参考上述两篇博文的配置、操作步骤,但配置过程中略微存在差异。
.2.1. 编译cfssl组件
CFSSL主要是为了实现自认证配置,生成CA证书、公钥、私钥等内容。
最新版本cfssl已经不再提供通过官方网站下载,可以直接通过Github下载编译或直接安装
### 直接下载某个版本
wget https://github.com/cloudflare/cfssl/archive/1.3.4.tar.gz
### 下载Master分支,切换为某个tag的代码
1. Download:https://github.com/cloudflare/cfssl.git
2. 安装依赖组件:
go get -u github.com/cloudflare/cfssl/cli \
github.com/go-sql-driver/mysql \
github.com/lib/pq github.com/mattn/go-sqlite3 \
github.com/cloudflare/go-metrics
3. 编译安装:make ## 会在bin目录下面创建常用命令
### 切换分支命令:参考
git checkout tags/v1.0 -b v1.0-branch
.2.2. 创建CA证书
创建CA证书,主要涉及到两个操作步骤。通过CFSSL来创建证书,一般只需要编辑JSON配置文件即可。
.2.2.1. 创建CA证书
### 创建CA,配置文件如下
#### ca-config.json
{
"signing": {
"default": {
"expiry": "86400h"
},
"profiles": {
"server": {
"expiry": "86400h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
},
"client": {
"expiry": "86400h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
},
"peer": {
"expiry": "86400h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
#### 创建CA相关文件
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
.2.2.2. 创建业务Key
创建业务需求的公钥\私钥,需要明确业务是那种情况:server(peer)、client,这里配置了两种不同的适应场景。另外一点,需要定义一下业务的配置JSON文件。
### 配置业务JSON文件:etcd-csr.json
{
"CN": "etcd",
"hosts": [
"127.0.0.1",
"host1_ip",
"host2_ip",
"host3_ip"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Shanghai",
"L": "Shanghai",
"O": "test.com",
"OU": "System"
}
]
}
### 创建业务场景的公钥/私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server etcd-csr.json | cfssljson -bare etcd
至此,CA配置以及业务需要的配置的自认证配置已获取到。
.2.3. 集群配置部署
这里配置为service的形式,并使用ansible部署集群:主要涉及到配置文件(etcd.conf)、服务配置(etcd.service),以及ansible部署脚本。
.2.3.1. etcd.service.j2
### 配置路径:/usr/lib/systemd/system/etcd.service
{%- set hosts = [] -%}
{%- for host in groups['ETCD'] | sort -%}
{{ hosts.append( hostvars[host]['etcd_name'] + '=https://' + host + ':' + cluster_port|string ) }}
{%- endfor -%}
[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
User=etcd
# set GOMAXPROCS to number of processors
ExecStart=/usr/bin/etcd \
--name=${ETCD_NAME} \
--cert-file=/etc/etcd/ssl/cfssl/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/cfssl/ssl/etcd-key.pem \
--peer-cert-file=/etc/etcd/ssl/cfssl/ssl/etcd.pem \
--peer-key-file=/etc/etcd/ssl/cfssl/ssl/etcd-key.pem \
--trusted-ca-file=/etc/etcd/ssl/cfssl/ssl/ca.pem \
--peer-trusted-ca-file=/etc/etcd/ssl/cfssl/ssl/ca.pem \
--initial-advertise-peer-urls=${ETCD_INITIAL_ADVERTISE_PEER_URLS} \
--listen-peer-urls=${ETCD_LISTEN_PEER_URLS} \
--listen-client-urls=${ETCD_LISTEN_CLIENT_URLS} \
--advertise-client-urls=${ETCD_ADVERTISE_CLIENT_URLS} \
--initial-cluster-token=${ETCD_INITIAL_CLUSTER_TOKEN} \
--initial-cluster={{ hosts | join(',') }}
--initial-cluster-state=new \
--data-dir=${ETCD_DATA_DIR}
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
.2.3.2. etcd.conf.j2
#### 配置文件路径:/etc/etcd/etcd.conf
[member]
ETCD_NAME={{ etcd_name }}
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_LISTEN_PEER_URLS="https://{{ inventory_hostname }}:{{ cluster_port }}"
ETCD_LISTEN_CLIENT_URLS="https://{{ inventory_hostname }}:{{ client_port }},https://127.0.0.1:{{ client_port }}"
[cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://{{ inventory_hostname }}:{{ cluster_port }}"
ETCD_INITIAL_CLUSTER_TOKEN="{{ cluster_token }}"
ETCD_ADVERTISE_CLIENT_URLS="https://{{ inventory_hostname }}:{{ client_port }}"
编译好的脚本,可以在这里下载:cfssl.tar.gz
.2.3.3. 分发部署Playbook
---
- hosts: ETCD
tasks:
- name: install etcd
yum:
name: etcd
state: installed
- name: mkdir target dir
shell: mkdir -p /etc/etcd/ssl
- name: copy ssl files
copy:
src: cfssl.tar.gz
dest: /tmp/cfssl.tar.gz
- name: untar ssl files
shell: tar xvf /tmp/cfssl.tar.gz -C /etc/etcd/ssl
- name: set privileges for ca files
shell: chmod -R 755 /etc/etcd/ssl
- name: copy template configure - conf
template:
src: etcd.service.j2
dest: /usr/lib/systemd/system/etcd.service
- name: copy template configure - service
template:
src: etcd.conf.j2
dest: /etc/etcd/etcd.conf
- name: systemctl reload before start service
shell: systemctl daemon-reload
- name: start etcd service
service:
name: etcd
state: restarted
- name: etcdctl with ssl
template:
src: etcdctls.j2
dest: /usr/bin/etcdctls
mode: "0755"
.3. 集群状态检查及基本使用
### 健康状态检查: etcdctl 命令行访问
etcdctl \
--ca-file=/etc/etcd/ssl/cfssl/ssl/ca.pem \
--cert-file=/etc/etcd/ssl/cfssl/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/cfssl/ssl/etcd-key.pem \
--endpoint https://127.0.0.1:2379 \
cluster-health
#### 输出
member c3ca8ce4516450a is healthy: got healthy result from https://host1:2379
member 22c833e1835a442d is healthy: got healthy result from https://host2:2379
member 3254807a1a7e65ac is healthy: got healthy result from https://host3:2379
cluster is healthy
### 查看集群成员信息: rest api 访问
curl -k --cert /etc/etcd/ssl/cfssl/ssl/etcd.pem --key /etc/etcd/ssl/cfssl/ssl/etcd-key.pem https://host1:2379/v2/members
#### 输出
{
"members": [
{
"id": "c3ca8ce4516450a",
"name": "infra01",
"peerURLs": [
"https://host1:2380"
],
"clientURLs": [
"https://host1:2379"
]
},
{
"id": "22c833e1835a442d",
"name": "infra03",
"peerURLs": [
"https://host2:2380"
],
"clientURLs": [
"https://host2:2379"
]
},
{
"id": "3254807a1a7e65ac",
"name": "infra02",
"peerURLs": [
"https://host3:2380"
],
"clientURLs": [
"https://host3:2379"
]
}
]
}
如果新搭建的集群可以正常返回,那么基本可以表明搭建了一个健康、可用的ETCD集群。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!