服务环境搭建-Etcd+Confd服务注册与发现

服务环境搭建-Etcd+Confd服务注册与发现

1. 说明

1.1 简介

  • Etcd是一个分布式、高可用的Key/Value存储系统,主要用于分享配置与服务发现。

  • Confd是一个轻量级的配置管理工具。通过查询Etcd,结合配置模板引擎,保持本地配置最新,同时具备定期探测机制,配置变更自动reload。对应的后端存储可以是etcd,redis、zookeeper等。

1.2 服务注册与发现业务流程

nginx为例,当docker容器健康运行起来后,会通过接口向etcd注册相关k/v信息,confd检测到etcd的k/v变化后,立即触发程序通过模板形成新的nginx配置文件,先做离线语法测试,如果没问题就覆盖原配置,进而reload,测试不通过就不覆盖原配置,整个过程是安全可控的。在容器注册到nginx的upstream后,nginx会对容器做健康检查发现,如果正常,则分发流量过去。对应的业务流程图如下:

服务环境搭建-Etcd+Confd服务注册与发现_第1张图片

2. Etcd使用与环境搭建

2.1 Docker运行Etcd

# docker-compose.yml
version: '3'

services:
  etcd:
    image: quay.io/coreos/etcd:v3.2.20
    container_name: etcd
    command: /usr/local/bin/etcd
    restart: always
    networks:
      - etcdtest
    ports:
      # etcd服务启动后提供给外部客户端通信的端口是2379
      - "2379:2379"
      # etcd服务中成员间的通信端口是2380
      - "2380:2380"
    environment:
      ETCDCTL_API: 2
      ETCD_LOGGER: capnslog
      # etcd数据的存储目录
      ETCD_DATA_DIR: /etcd-data

      ETCD_NAME: node1
      # 通知集群中其他成员本节点的peer urls,一定要保证从其他member能可访问该地址。
      ETCD_INITIAL_ADVERTISE_PEER_URLS: http://0.0.0.0:2380
      # 监听的用于节点之间通信的url,可建通多个,集群内部将通过这些url进行数据交互(选举、数据同步),用于监听其他member发送信息的地址
      ETCD_LISTEN_PEER_URLS: http://0.0.0.0:2380
      # 监听的用于客户端通信的的urls,可以是多个,用于监听etcd客户端发送信息的地址
      ETCD_LISTEN_CLIENT_URLS: http://0.0.0.0:2379
      # 通知集群中其他成员本节点的client url,一定要保证从客户侧能可访问该地址。
      ETCD_ADVERTISE_CLIENT_URLS: http://0.0.0.0:2379
      # #广播给集群内其他成员访问的URL
      ETCD_INITIAL_CLUSTER: node1=http://0.0.0.0:2380

networks:
  etcdtest:
    external: true

2.2 etcdctl(V3)

etcdctl是一个命令行客户端,它能提供一些简洁的命令,供用户直接跟etcd服务打交道,而无需基于 HTTP API 方式。

2.2.1 PUT

PUT [options]

PUT使用指定的键赋值。如果key已经保存了一个值,它将被覆盖。

RPC: Put

Option

  • lease – 将key绑定到lease ID(十六进制).
  • prev-kv – 返回修改前的键值对.
  • ignore-value – 使用当前值更新键.
  • ignore-lease – 使用其当前租约更新key.

Output

ok

Examples

# 写入一对key-value: /foo-Hello World
etcdctl --endpoints=http://127.0.0.1:2379 put /foo "Hello World"
# OK
2.2.2 GET

GET [options] [range_end]

GET如果给出了range_end,则GET获取键或键范围

RPC: Range

Option

  • hex – 将键和值打印为十六进制编码字符串
  • limit – 最大结果数
  • prefix – 通过匹配前缀获取键值
  • order – 结果排序; ASCEND or DESCEND
  • sort-by – sort target; CREATE, KEY, MODIFY, VALUE, or VERSION
  • rev – 指定kv版本
  • print-value-only – 与write-out = simple一起使用时仅打印值
  • consistency – Linearizable(l) or Serializable(s)
  • from-key – 使用字节比较获取大于或等于给定key的键
  • keys-only – 仅获取键

Output

\n\n\n

Examples

# 查询key为foo的value
etcdctl --endpoints=http://127.0.0.1:2379 get /foo
# /foo
# Hello World

# 查询所有的key
etcdctl --endpoints=http://127.0.0.1:2379 get --from-key ''
# foo
# /testkey
2.2.3 DEL

DEL [options] [range_end]

如果给定范围结束,则删除指定的键或键[键,范围结束)范围。

RPC: DeleteRange

Option

  • prefix – 通过匹配前缀删除键
  • prev-kv – 返回删除的键值对
  • from-key – 使用字节比较删除大于或等于给定键的键

Output

如果DEL成功,则打印以十进制删除的键的数目。

Examples

# 删除key为foo的键值对
etcdctl --endpoints=http://127.0.0.1:2379 del foo
# 1

3. Confd安装与使用

3.1 Confd动态更新配置文件架构与作用流程

Confd动态更新配置文件架构:

server端调用config-server对应客户端获取配置,和监听配置变更。

服务环境搭建-Etcd+Confd服务注册与发现_第2张图片

Confd的作用流程:

服务环境搭建-Etcd+Confd服务注册与发现_第3张图片

3.2 Confd安装

下载confd的二进制文件,下载地址为:https://github.com/kelseyhightower/confd/releases。

# 下载二进制文件
wget https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-amd64

# 重命名二进制文件,并移动到PATH的目录下
mv confd-0.16.0-linux-amd64 /usr/local/bin/confd

# 赋予执行权限
chmod +x /usr/local/bin/confd

# 验证是否安装成功
confd -version

3.3 Confd配置

Confd通过读取后端存储的配置信息来动态更新对应的配置文件,对应的后端存储可以是etcdredis等,其中etcd的v3版本对应的存储后端为etcdv3

创建confdir

confdir是存储模板资源配置和源模板的地方,包含两个目录:

  • conf.d:confd的配置文件,主要包含配置的生成逻辑,例如模板源,后端存储对应的keys,命令执行等。
  • templates:配置模板Template,即基于不同组件的配置,修改为符合 Golang text templates的模板文件。
sudo mkdir -p /etc/confd/{conf.d,templates}

插入数据

使用etcd作为confd的后端存储。

etcdctl --endpoints=http://127.0.0.1:2379 put /myapp/database/url db.example.com
etcdctl --endpoints=http://127.0.0.1:2379 put /myapp/database/user rob

创建模板资源配置

模板资源定义在confdir下的TOML配置文件中。

必要参数

  • dest (string) - 目标文件.
  • keys (array of strings) - 一组键值对.
  • src (string) - 配置模板的相对路径.

可选参数

  • gid (int) - 应该拥有该文件的gid。默认为有效的gid。
  • mode (string) - 文件的权限模式.
  • uid (int) - 应该拥有该文件的uid. 默认为有效uid.
  • reload_cmd (string) - 重新加载配置的命令.
  • check_cmd (string) - 用于检查配置的命令。 使用{{.src}}引用渲染的源模板。.
  • prefix (string) - 作为键前缀的字符串.

/etc/confd/conf.d/myconfig.toml

[template]
## templates中的模板文件名
src = "myconfig.conf.tmpl"
## 配置文件生成的路径
dest = "/tmp/myconfig.conf"

## 键值对组
keys = [
    "/myapp/database/url",
    "/myapp/database/user",
]

创建源模板

应符合 Golang text templates的模板文件

/etc/confd/templates/myconfig.conf.tmpl

[myconfig]
database_url = {{getv "/myapp/database/url"}}
database_user = {{getv "/myapp/database/user"}}

生成配置文件

confd支持两种运行方式,即daemononetime。 在守护程序模式下,confd轮询后端以进行更改,并在必要时更新目标配置文件。

etcd

# confd onetime只生成一次
confd -onetime -backend etcdv3 -node http://127.0.0.1:2379

# confd监听etcd,一旦发现etcd数据变化,则重新生成配置文件
confd -watch -backend etcdv3 -node http://127.0.0.1:2379

# 每隔60秒轮询一次。一旦后端etcd相应的值发生变化就会重新生成相应的配置文件 
confd -interval=60 -backend etcdv3 -node http://127.0.0.1:2379 

查看生成的配置文件

/tmp/myconfig.conf

[myconfig]
database_url = db.example.com
database_user = rob

4. 使用实例

在这个例子中,我们将使用etcd作为后端存储,用confd使用一个模板来管理两个nginx配置文件。

etcd存入数据

etcdctl put /myapp/subdomain myapp
etcdctl put /myapp/upstream/app2 "10.0.1.100:80"
etcdctl put /myapp/upstream/app1 "10.0.1.101:80"
etcdctl put /yourapp/subdomain yourapp
etcdctl put /yourapp/upstream/app2 "10.0.1.102:80"
etcdctl put /yourapp/upstream/app1 "10.0.1.103:80"

创建模板资源配置

/etc/confd/conf.d/myapp-nginx.toml

[template]
# 做为键的前缀
prefix = "/myapp"
# templates中的模板文件名
src = "nginx.tmpl"
# 配置文件生成路径
dest = "/tmp/myapp.conf"
# 配置生成配置文件的用户
owner = "nginx"
# 文件的权限模式
mode = "0644"
# 一组键值对
keys = [
  "/subdomain",
  "/upstream",
]
# 检查nginx配置
check_cmd = "/usr/sbin/nginx -t -c {{.src}}"
# 重新加载配置
reload_cmd = "/usr/sbin/service nginx reload"

/etc/confd/conf.d/yourapp-nginx.toml

[template]
# 做为键的前缀
prefix = "/yourapp"
# templates中的模板文件名
src = "nginx.tmpl"
# 配置文件生成路径
dest = "/tmp/yourapp.conf"
# 配置生成配置文件的用户
owner = "nginx"
# 文件的权限模式
mode = "0644"
# 一组键值对
keys = [
  "/subdomain",
  "/upstream",
]
# 检查nginx配置
check_cmd = "/usr/sbin/nginx -t -c {{.src}}"
# 重新加载配置
reload_cmd = "/usr/sbin/service nginx reload"

创建源模板

/etc/confd/templates/nginx.tmpl

upstream {{getv "/subdomain"}} {
{{range getvs "/upstream/*"}}
    server {{.}};
{{end}}
}

server {
    server_name  {{getv "/subdomain"}}.example.com;
    location / {
        proxy_pass        http://{{getv "/subdomain"}};
        proxy_redirect    off;
        proxy_set_header  Host             $host;
        proxy_set_header  X-Real-IP        $remote_addr;
        proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
   }
}

生成配置文件

生成配置文件

confd -onetime -backend etcdv3 -node http://127.0.0.1:2379

查看配置文件

/tmp/myapp.conf

upstream myapp {

    server 10.0.1.100:80;

    server 10.0.1.101:80;

}

server {
    server_name  myapp.example.com;
    location / {
        proxy_pass        http://myapp;
        proxy_redirect    off;
        proxy_set_header  Host             $host;
        proxy_set_header  X-Real-IP        $remote_addr;
        proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
   }
}

/tmp/yourapp.conf

upstream yourapp {

    server 10.0.1.102:80;

    server 10.0.1.103:80;

}

server {
    server_name  yourapp.example.com;
    location / {
        proxy_pass        http://yourapp;
        proxy_redirect    off;
        proxy_set_header  Host             $host;
        proxy_set_header  X-Real-IP        $remote_addr;
        proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
   }
}

你可能感兴趣的:(docker,etcd,confd,docker,服务注册,服务发现)