Тщательно изучите серию статей etcd (5): использование etcdctl

задняя часть Архитектура
Тщательно изучите серию статей etcd (5): использование etcdctl

0 Обзор альбома

etcd является важным базовым компонентом облачной архитектуры, которая инкубируется и размещается CNCF. etcd можно использовать не только для регистрации и обнаружения сервисов в микросервисах и кластерах Kubernetes, но и как промежуточное ПО для хранения ключей и значений.

"Понимание статей серии etcd" познакомит с etcd с точки зрения базовой функциональной практики etcd, интерфейса API, принципа реализации, анализа исходного кода и опыта преодоления ям в реализации. Ожидается, что статей будет около 20, автор будет обновлять каждую неделю, прошу обратить внимание.

1 Практическое применение etcdctl

В предыдущей статье я представил связанные концепции etcd, различные методы установки отдельной машины и кластера, а также содержание, связанное с безопасной связью etcd. В этой статье в основном представлены общие команды и операции etcd на основе etcdctl.

etcdctl — это клиент командной строки, который предоставляет пользователям несколько кратких команд для непосредственного взаимодействия с сервисами etcd без необходимости использования подхода на основе HTTP API. Нам удобно протестировать сервис или вручную изменить содержимое базы данных. Сначала мы можем ознакомиться с соответствующими операциями через etdctl. Эти операции в основном соответствуют HTTP API. etcdctl также ведет себя совершенно по-разному в двух разных версиях etcd.

export ETCDCTL_API=2
export ETCDCTL_API=3

Здесь мы в основном сосредоточимся на объяснении API 3.

Инструмент etcdctl уже включен в бинарный дистрибутив проекта etcd Команды, поддерживаемые etcdctl, обычно делятся на две категории: операции с базой данных и операции вне базы данных.

2 Введение в общие команды

Сначала проверьте версию etcd:

$ etcd --version

etcd Version: 3.4.7
Git SHA: e784ba73c
Go Version: go1.12.12
Go OS/Arch: linux/amd64

Наша версия — etcd 3.4.7, ниже приведены общие команды etcdctl.

$ etcdctl -h

NAME:
	etcdctl - A simple command line client for etcd3.

USAGE:
	etcdctl [flags]

VERSION:
	3.4.7

API VERSION:
	3.4


COMMANDS:
	alarm disarm		Disarms all alarms
	alarm list		Lists all alarms
	auth disable		Disables authentication
	auth enable		Enables authentication
	check datascale		Check the memory usage of holding data for different workloads on a given server endpoint.
	check perf		Check the performance of the etcd cluster
	compaction		Compacts the event history in etcd
	defrag			Defragments the storage of the etcd members with given endpoints
	del			Removes the specified key or range of keys [key, range_end)
	elect			Observes and participates in leader election
	endpoint hashkv		Prints the KV history hash for each endpoint in --endpoints
	endpoint health		Checks the healthiness of endpoints specified in `--endpoints` flag
	endpoint status		Prints out the status of endpoints specified in `--endpoints` flag
	get			Gets the key or a range of keys
	help			Help about any command
	lease grant		Creates leases
	lease keep-alive	Keeps leases alive (renew)
	lease list		List all active leases
	lease revoke		Revokes leases
	lease timetolive	Get lease information
	lock			Acquires a named lock
	make-mirror		Makes a mirror at the destination etcd cluster
	member add		Adds a member into the cluster
	member list		Lists all members in the cluster
	member promote		Promotes a non-voting member in the cluster
	member remove		Removes a member from the cluster
	member update		Updates a member in the cluster
	migrate			Migrates keys in a v2 store to a mvcc store
	move-leader		Transfers leadership to another etcd cluster member.
	put			Puts the given key into the store
	role add		Adds a new role
	role delete		Deletes a role
	role get		Gets detailed information of a role
	role grant-permission	Grants a key to a role
	role list		Lists all roles
	role revoke-permission	Revokes a key from a role
	snapshot restore	Restores an etcd member snapshot to an etcd directory
	snapshot save		Stores an etcd node backend snapshot to a given file
	snapshot status		Gets backend snapshot status of a given file
	txn			Txn processes all the requests in one transaction
	user add		Adds a new user
	user delete		Deletes a user
	user get		Gets detailed information of a user
	user grant-role		Grants a role to a user
	user list		Lists all users
	user passwd		Changes password of user
	user revoke-role	Revokes a role from a user
	version			Prints the version of etcdctl
	watch			Watches events stream on keys or prefixes

OPTIONS:
      --cacert=""				verify certificates of TLS-enabled secure servers using this CA bundle
      --cert=""					identify secure client using this TLS certificate file
      --command-timeout=5s			timeout for short running command (excluding dial timeout)
      --debug[=false]				enable client-side debug logging
      --dial-timeout=2s				dial timeout for client connections
  -d, --discovery-srv=""			domain name to query for SRV records describing cluster endpoints
      --discovery-srv-name=""			service name to query when using DNS discovery
      --endpoints=[127.0.0.1:2379]		gRPC endpoints
  -h, --help[=false]				help for etcdctl
      --hex[=false]				print byte strings as hex encoded strings
      --insecure-discovery[=true]		accept insecure SRV records describing cluster endpoints
      --insecure-skip-tls-verify[=false]	skip server certificate verification
      --insecure-transport[=true]		disable transport security for client connections
      --keepalive-time=2s			keepalive time for client connections
      --keepalive-timeout=6s			keepalive timeout for client connections
      --key=""					identify secure client using this TLS key file
      --password=""				password for authentication (if this option is used, --user option shouldn't include password)
      --user=""					username[:password] for authentication (prompt if password is not supplied)
  -w, --write-out="simple"			set the output format (fields, json, protobuf, simple, table)

Как видите, etcdctl поддерживает множество команд, наиболее распространенными из которых являются:

--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 打印版本信息

Ниже мы введем команды общих баз данных.

3 Операции с базой данных

Операции с базой данных вращаются вокруг управления полным жизненным циклом ключей-значений и каталогов CRUD (то есть добавление, удаление, изменение и запрос, набор операций API в стиле REST).

etcd принимает иерархическую пространственную структуру (подобную концепции каталогов в файловой системе) в организации ключей.Ключ, указанный пользователем, может иметь отдельное имя, например: testkey, который фактически помещается в корневой каталог/ , а также Вы можете указать структуру каталогов, например /cluster1/node2/testkey, и соответствующая структура каталогов будет создана.

3.1 Основные операции

  • set задает значение ключа. Например:

    $ etcdctl put /testdir/testkey "Hello world"
    $ etcdctl put /testdir/testkey2 "Hello world2"
    $ etcdctl put /testdir/testkey3 "Hello world3"
    

    Были успешно записаны три пары ключевых значений: /testdir/testkey, /testdir/testkey2 и /testdir/testkey3.

  • get Получает значение указанного ключа. Например:

    $ etcdctl get /testdir/testkey
    Hello world
    
  • get считывает указанное значение в шестнадцатеричном формате:

    $ etcdctl get /testdir/testkey --hex
    \x2f\x74\x65\x73\x74\x64\x69\x72\x2f\x74\x65\x73\x74\x6b\x65\x79 #键
    \x48\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64 #值
    

    плюс--print-value-onlyСоответствующее значение может быть прочитано.

  • получить значение в диапазоне

     $ etcdctl get /testdir/testkey /testdir/testkey3
    
    /testdir/testkey
    Hello world
    /testdir/testkey2
    Hello world2
    

    Как видите, получаются пары ключ-значение, большие или равные /testdir/testkey и меньшие, чем /testdir/testkey3. testkey3 не входит в диапазон, поскольку диапазон представляет собой полуоткрытый интервал [testkey, testkey3), исключая testkey3.

  • Получить все пары ключ-значение префикса через --prefix Вы можете указать префикс:

    $ etcdctl get --prefix /testdir/testkey
    /testdir/testkey
    Hello world
    /testdir/testkey2
    Hello world2
    /testdir/testkey3
    Hello world3
    

    Это позволит получить все пары ключ-значение, начинающиеся с /testdir/testkey. Когда префикс дает слишком много результатов, вы также можете ограничить количество, полученное с помощью --limit=2:

    etcdctl get --prefix --limit=2 /testdir/testkey
    
  • Прочитать значение прошлой версии ключа Приложение может захотеть прочитать подставленное значение ключа. Например, приложение может захотеть вернуться к старой конфигурации, обратившись к прошлой версии ключа. В качестве альтернативы приложению может потребоваться получить единое представление, охватывающее несколько ключей, с помощью нескольких запросов, доступ к которым можно получить, обратившись к истории ключей. Поскольку каждое изменение хранилища ключей и значений в кластере etcd увеличивает глобальную версию кластера etcd, приложения могут считывать замененные ключи, предоставляя старую модификацию etcd. Доступны следующие пары ключ-значение:

    foo = bar         # revision = 2
    foo1 = bar2       # revision = 3
    foo = bar_new     # revision = 4
    foo1 = bar1_new   # revision = 5
    

    Вот пример доступа к ключу предыдущей версии:

    $ etcdctl get --prefix foo # 访问最新版本的key
    foo
    bar_new
    foo1
    bar1_new
    
    $ etcdctl get --prefix --rev=4 foo # 访问第4个版本的key
    foo
    bar_new
    foo1
    bar1
    
    $ etcdctl get --prefix --rev=3 foo #  访问第3个版本的key
    foo
    bar
    foo1
    bar1
    
    $ etcdctl get --prefix --rev=2 foo #  访问第3个版本的key
    foo
    bar
    
    $ etcdctl get --prefix --rev=1 foo #  访问第1个版本的key
    
  • Читает ключи, которые больше или равны значению байта указанного ключа Приложения могут захотеть прочитать ключи, которые больше или равны значению байта указанного ключа. Предположим, что в кластере etcd уже есть следующие ключи:

    a = 123
    b = 456
    z = 789
    

    Команда для чтения ключей, больших или равных байтовому значению ключа b:

    $ etcdctl get --from-key b
    b
    456
    z
    789
    
  • удалить ключ. Приложения могут удалять ключ или определенный диапазон ключей из кластера etcd. Предположим, что в кластере etcd уже есть следующие ключи:

    foo = bar
    foo1 = bar1
    foo3 = bar3
    zoo = val
    zoo1 = val1
    zoo2 = val2
    a = 123
    b = 456
    z = 789
    

    Команда для удаления ключа foo:

    $ etcdctl del foo
    1 # 删除了一个键
    

    Команда для удаления ключей из диапазона foo в foo9:

    $ etcdctl del foo foo9
    2 # 删除了两个键
    

    Команда для удаления зоопарка ключей и возврата удаленной пары ключ-значение:

    $ etcdctl del --prev-kv zoo
    1   # 一个键被删除
    zoo # 被删除的键
    val # 被删除的键的值
    

    Команда для удаления ключей с префиксом зоопарка:

    $ etcdctl del --prefix zoo
    2 # 删除了两个键
    

    Команда для удаления ключей, которые больше или равны байтовому значению ключа b:

    $ etcdctl del --from-key b
    2 # 删除了两个键
    

3.2 изменения истории просмотра

  • watch отслеживает изменение значения ключа. После обновления значения ключа выводит последнее значение и завершает работу. Например: пользователь обновляет значение ключа testkey на Hello watch.

    $ etcdctl watch  testkey
    # 在另外一个终端: etcdctl put  testkey Hello watch
    testkey
    Hello watch
    

    Команды от ключей в диапазоне от foo до foo9 :

    $ etcdctl watch foo foo9
    # 在另外一个终端: etcdctl put foo bar
    PUT
    foo
    bar
    # 在另外一个终端: etcdctl put foo1 bar1
    PUT
    foo1
    bar1
    

    Команда для наблюдения за ключом foo в шестнадцатеричном формате:

    $ etcdctl watch foo --hex
    # 在另外一个终端: etcdctl put foo bar
    PUT
    \x66\x6f\x6f          # 键
    \x62\x61\x72          # 值
    

    Обратите внимание на команды для нескольких ключей foo и zoo :

    $ etcdctl watch -i
    $ watch foo
    $ watch zoo
    # 在另外一个终端: etcdctl put foo bar
    PUT
    foo
    bar
    # 在另外一个终端: etcdctl put zoo val
    PUT
    zoo
    val
    
  • Чтобы просмотреть исторические изменения ключей, приложения могут захотеть просмотреть исторические изменения ключей в etcd. Например, приложение хочет получать все модификации ключа. Если приложение всегда подключено к etcd, то watch достаточно хорош. Однако в случае сбоя приложения или etcd изменение может произойти во время сбоя, так что приложение не получит обновление в режиме реального времени. Чтобы обеспечить доставку обновлений, приложения должны иметь возможность отслеживать исторические изменения ключей. Для этого приложения могут указывать историческую версию при наблюдении, как при чтении прошлых версий ключа.
    Предположим, мы выполняем следующую последовательность операций:

    $ etcdctl put foo bar         # revision = 2
    OK
    $ etcdctl put foo1 bar1       # revision = 3
    OK
    $ etcdctl put foo bar_new     # revision = 4
    OK
    $ etcdctl put foo1 bar1_new   # revision = 5
    OK
    

    Обратите внимание на исторические изменения:

    # 从修订版本 2 开始观察键 `foo` 的改动
    $ etcdctl watch --rev=2 foo
    PUT
    foo
    bar
    PUT
    foo
    bar_new
    

    Модификация истории наблюдается с самого начала:

    # 在键 `foo` 上观察变更并返回被修改的值和上个修订版本的值
    $ etcdctl watch --prev-kv foo
    # 在另外一个终端: etcdctl put foo bar_latest
    PUT
    foo         # 键
    bar_new     # 在修改前键foo的上一个值
    foo         # 键
    bar_latest  # 修改后键foo的值
    
  • Сжатая ревизия. Как мы уже упоминали, etcd сохраняет ревизии, чтобы приложения могли считывать прошлые версии ключей. Однако, чтобы избежать накопления бесконечного количества исторических данных, становится важным сжимать прошлые версии. После сжатия etcd удаляет исторические версии, освобождая ресурсы для будущего использования. Замененные данные всех ревизий до сжатой ревизии будут недоступны. Вот команда для архивации ревизии:

    $ etcdctl compact 5
    compacted revision 5 #在压缩修订版本之前的任何修订版本都不可访问
    $ etcdctl get --rev=4 foo
    {"level":"warn","ts":"2020-05-04T16:37:38.020+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-c0d35565-0584-4c07-bfeb-034773278656/127.0.0.1:2379","attempt":0,"error":"rpc error: code = OutOfRange desc = etcdserver: mvcc: required revision has been compacted"}
    Error: etcdserver: mvcc: required revision has been compacted
    

3.3 Аренда

  • сдать в аренду Приложения могут предоставлять аренду ключей в кластере etcd. Когда ключ прикрепляется к аренде, его срок жизни привязан к сроку жизни аренды, который, в свою очередь, управляется временем жизни (TTL). Минимальное значение TTL за аренду указывается приложением при предоставлении аренды. Фактическое значение TTL аренды не ниже минимального TTL, выбранного кластером etcd. По истечении TTL аренды срок действия аренды истекает, и все прикрепленные ключи удаляются.

    # 授予租约,TTL为100秒
    $ etcdctl lease grant 100
    lease 694d71ddacfda227 granted with TTL(10s)
    
    # 附加键 foo 到租约694d71ddacfda227
    $ etcdctl put --lease=694d71ddacfda227 foo10 bar
    OK
    

    Рекомендуется установить время больше, иначе возникнут следующие ошибки, если будет слишком поздно работать:

  • Отмена аренды Приложение может отозвать аренду по идентификатору аренды. Отмена аренды приведет к удалению всех прикрепленных к ней ключей. Предположим, мы сделали следующее:

    $ etcdctl lease revoke 694d71ddacfda227
    lease 694d71ddacfda227 revoked
    
    $ etcdctl get foo10
    
  • Обновить аренду
    Приложение может поддерживать аренду, обновляя ее TTL, чтобы срок ее действия не истекал.

    $ etcdctl lease keep-alive 694d71ddacfda227
    lease 694d71ddacfda227 keepalived with TTL(100)
    lease 694d71ddacfda227 keepalived with TTL(100)
    ...
    
  • Узнать срок аренды Приложения могут захотеть узнать информацию об аренде, чтобы они могли продлить или проверить, существует ли еще аренда или истек ли срок ее действия. Приложения также могут захотеть узнать ключ, прикрепленный к конкретной аренде.

    Предположим, мы выполняем следующую серию операций:

    $ etcdctl lease grant 300
    lease 694d71ddacfda22c granted with TTL(300s)
    
    $ etcdctl put --lease=694d71ddacfda22c foo10 bar
    OK
    

    Получите информацию об аренде и о том, какие ключи используют аренду:

    $ etcdctl lease timetolive 694d71ddacfda22c
    lease 694d71ddacfda22c granted with TTL(300s), remaining(282s)
    
    $ etcdctl lease timetolive --keys 694d71ddacfda22c
    lease 694d71ddacfda22c granted with TTL(300s), remaining(220s), attached keys([foo10])
    

4 Резюме

В этой статье в основном представлены общие команды и операции etcd на основе etcdctl, в том числе операции с парами ключ-значение, аренда и мониторинг паров-значений Watch. Используйте эти команды для реализации различных сценариев использования etcd, которые мы представили в предыдущей статье. В следующей статье мы познакомимся с определением API и использованием etcd v3, а также получим глубокое понимание внутренней части etcd.

Подписывайтесь на свежие статьи, приглашаю обратить внимание на мой публичный номер

Рекомендуемое чтение

  1. Сравнение etcd с другими компонентами k-v, такими как Zookeeper и Consul
  2. Тщательно изучите серию статей etcd (1): первое знакомство с etcd
  3. Тщательно изучите серию статей etcd (2): различные положения установки etcd
  4. Тщательно изучите серию статей etcd (3): эксплуатация и обслуживание кластера etcd, развертывание.
  5. Тщательно изучите серию статей etcd (4): безопасность etcd

Ссылаться на

etcd docs