本文へ移動

1 - etcdクラスターとアプリケーションのアップグレード

etcdクラスターとアプリケーションのアップグレードに関するドキュメント一覧

このセクションには、etcdクラスターとアプリケーションのアップグレードに関するドキュメントをまとめています。

アップグレード方針

アップグレードを始める前に、etcdでサポートされるアップグレードは次の2つの場合だけであることに注意してください。

  • パッチアップグレード: 同じマイナーバージョン内でのパッチリリース間のアップグレードです(例:3.7.0 - 3.7.1)。
  • マイナーアップグレード: マイナーバージョンを1つずつ上げるアップグレードです(例:3.6 - 3.7)。マイナーバージョンを飛ばすアップグレードはサポートされず、失敗する可能性が高くなります。次のマイナーバージョンにアップグレードする前に、最新のパッチバージョンに更新してください。

etcd v3.xクラスターのアップグレード

etcd v2.3からのアップグレード

2 - etcdをv3.6からv3.7にアップグレード

etcdをv3.6からv3.7にアップグレードする手順、チェックリスト、注意事項

通常、etcd v3.6からv3.7へのアップグレードは、停止時間なしのローリングアップグレードで実行できます。

  • etcd v3.6のプロセスを1つずつ停止し、etcd v3.7のプロセスに置き換えます。
  • すべてのプロセスがv3.7で稼働すると、クラスターでv3.7の新機能を利用できます。

アップグレードを開始する 前に、このガイドの残りを読んで準備してください。

アップグレードのチェックリスト

3.6の更新

重要

3.7にアップグレードする前に、すべての3.6メンバーが3.6.11以降に更新されていることを確認してください。それより前の3.6パッチリリースは、3.7へのローリングアップグレードと互換性がない可能性があります。

V2ストア

v3.7ではv2ストアが完全に削除されました。v2 HTTP API(--enable-v2)、v2-on-v3エミュレーション(--experimental-enable-v2v3)、v2ディスカバリーサービス、client/v2パッケージ、v2スナップショットファイルの読み込みは、すべて削除されています。CHANGELOG-3.7 にある互換性を損なう変更の参照先を確認してください。

3.6クラスターからアップグレードする場合、これらのフラグはすでに存在せず、作業は不要です。カスタムv2データがある古いリリースから移行する場合は、アップグレード前にv2移行ガイド に従ってください。

Goのリファクタリング

v3.7には大規模な内部リファクタリングが含まれています。通常のアップグレードには影響しませんが、独自の連携機能をアップグレードする際には把握しておくと役立ちます。

  • gogo/protobufから標準のgoogle.golang.org/protobufへの移行(#14533 で追跡)。
  • 非推奨のgo-grpc-middleware v1のログおよびタグライブラリから、v2インターセプターへの移行(#20420 )。
  • OpenTelemetryのgRPCインターセプターをotelgrpc v0.61.0に更新し、非推奨のUnaryServerInterceptorとStreamServerInterceptorをNewServerHandlerに置き換えました(#20017 )。

etcdをライブラリとして組み込んでいる場合、clientv3 APIを使用してビルドしている場合、または内部パッケージに依存している場合は、アップグレード前にCHANGELOG を確認してください。

削除されたフラグ

v3.7では、非推奨の--experimental-*フラグがすべて削除されました(#19959 )。v3.6では、それぞれ同名の非実験的フラグ、または--feature-gatesのエントリーに置き換えられています。これらのフラグがまだ設定されている場合は、v3.7へのローリングアップグレードを行う前に、v3.6の対応する設定に置き換えてください。そうしないと、v3.7のプロセスは起動に失敗します。

-etcd --experimental-bootstrap-defrag-threshold-megabytes
-etcd --experimental-compact-hash-check-enabled
-etcd --experimental-compact-hash-check-time
-etcd --experimental-compaction-batch-limit
-etcd --experimental-compaction-sleep-interval
-etcd --experimental-corrupt-check-time
-etcd --experimental-distributed-tracing-address
-etcd --experimental-distributed-tracing-instance-id
-etcd --experimental-distributed-tracing-sampling-rate
-etcd --experimental-distributed-tracing-service-name
-etcd --experimental-downgrade-check-time
-etcd --experimental-enable-distributed-tracing
-etcd --experimental-enable-lease-checkpoint
-etcd --experimental-enable-lease-checkpoint-persist
-etcd --experimental-initial-corrupt-check
-etcd --experimental-memory-mlock
-etcd --experimental-peer-skip-client-san-verification
-etcd --experimental-snapshot-catchup-entries
-etcd --experimental-stop-grpc-service-on-defrag
-etcd --experimental-txn-mode-write-with-shared-buffer
-etcd --experimental-warning-apply-duration
-etcd --experimental-warning-unary-request-duration
-etcd --experimental-watch-progress-notify-interval

削除された各フラグと、対応する非実験的フラグまたは--feature-gatesのエントリーとの対応関係は、v3.5からv3.6へのアップグレードガイド を参照してください。

追加されたフラグ

ありません。

デフォルト値が変更されたフラグ

ありません。

サーバーアップグレードのチェックリスト

アップグレードの要件

既存のetcd環境をv3.7にアップグレードするには、稼働中のクラスターがv3.6.11以降でなければなりません。それより古いマイナーバージョンを使用している場合は、先にv3.6にアップグレード してください。etcdでサポートされるのは、マイナーバージョンを1つずつ上げるアップグレードだけです。

また、ローリングアップグレードを円滑に進めるには、稼働中のクラスターが正常でなければなりません。作業を進める前に、etcdctl endpoint healthコマンドでクラスターの正常性を確認してください。

準備

etcdをアップグレードする際は、必ず本番環境に適用する前に、etcdに依存するサービスをステージング環境でテストしてください。

作業を始める前に、スナップショットバックアップをダウンロード してください。アップグレードで問題が発生した場合は、このバックアップを使用して元のetcdバージョンにロールバック できます。

バージョンの混在

アップグレード中のetcdクラスターでは、異なるバージョンのetcdメンバーの混在がサポートされ、全メンバーに共通する最も低いバージョンのプロトコルで動作します。すべてのメンバーがバージョンv3.7にアップグレードされて初めて、クラスターのアップグレードが完了したと見なされます。内部では、etcdメンバーが相互にネゴシエーションを行ってクラスター全体のバージョンを決定し、そのバージョンによって報告されるバージョンとサポートされる機能が決まります。

ロールバック

etcdクラスターをアップグレードする前に、クラスターのスナップショットバックアップを作成してダウンロード してください。このスナップショットを使えば、必要に応じてクラスターをアップグレード前の状態にリストアできます。アップグレード中に問題が発生した場合は、まず根本原因を特定して解決することをお勧めします。少なくとも1つのメンバーがv3.6のままで、クラスターのバージョンがまだ混在している場合は、バイナリまたはイメージを以前のv3.6のものに置き換えるか、スナップショットを使用してクラスターを直接リストアできます。この混在状態ではクラスターはv3.6クラスターとして動作し続けるため、正式なダウングレード手順を踏まずにロールバックできます。

ただし、すべてのメンバーをv3.7にアップグレードすると、クラスターのアップグレードは完了したと見なされ、バイナリによるロールバックはできなくなります。その場合、アップグレードに問題があったときのリカバリー方法は、アップグレード前に取得したスナップショットからリストアするか、公式のダウングレードガイド に従うかのいずれかに限られます。

アップグレード手順

この例では、ローカルマシンで稼働する3メンバー構成のv3.6 etcdクラスターをアップグレードする方法を説明します。以下の出力は、1台のホスト上で3つのループバックポートを使用し、etcd v3.6.12とetcd v3.7.0-rc.0を実際に稼働させたときのものです。

手順1:アップグレード要件の確認

クラスターは正常で、v3.6.11以降で稼働していますか。

etcdctl --endpoints=localhost:2379,localhost:22379,localhost:32379 endpoint health
<<COMMENT
localhost:2379 is healthy: successfully committed proposal: took = 7.681459ms
localhost:22379 is healthy: successfully committed proposal: took = 7.691750ms
localhost:32379 is healthy: successfully committed proposal: took = 7.698000ms
COMMENT

curl http://localhost:2379/version
<<COMMENT
{"etcdserver":"3.6.12","etcdcluster":"3.6.0","storage":"3.6.0"}
COMMENT

手順2:リーダーからスナップショットバックアップをダウンロード

問題が発生した場合にダウングレードできるよう、スナップショットバックアップをダウンロード してください。

etcdのリーダーには最新のアプリケーションデータがあることが保証されているため、リーダーからスナップショットを取得します。

for p in 2379 22379 32379; do
  echo -n "localhost:$p leader="
  curl -sL http://localhost:$p/metrics | grep "^etcd_server_is_leader " | awk '{print $2}'
done
<<COMMENT
localhost:2379 leader=1
localhost:22379 leader=0
localhost:32379 leader=0
COMMENT

etcdctl --endpoints=localhost:2379 snapshot save backup.db
<<COMMENT
{"level":"info","ts":"2026-06-02T07:01:41.863225+0300","caller":"snapshot/v3_snapshot.go:83","msg":"created temporary db file","path":"backup.db.part"}
{"level":"info","ts":"2026-06-02T07:01:41.866451+0300","logger":"client","caller":"v3@v3.6.12/maintenance.go:236","msg":"opened snapshot stream; downloading"}
{"level":"info","ts":"2026-06-02T07:01:41.874080+0300","caller":"snapshot/v3_snapshot.go:96","msg":"fetching snapshot","endpoint":"localhost:2379"}
{"level":"info","ts":"2026-06-02T07:01:41.877203+0300","caller":"snapshot/v3_snapshot.go:111","msg":"fetched snapshot","endpoint":"localhost:2379","size":"98 kB","took":"13.822583ms","etcd-version":"3.6.0"}
{"level":"info","ts":"2026-06-02T07:01:41.877303+0300","caller":"snapshot/v3_snapshot.go:121","msg":"saved","path":"backup.db"}
Snapshot saved at backup.db
Server version 3.6.0
COMMENT

手順3:既存のetcdサーバーを1つ停止

各etcdプロセスを停止すると、他のクラスターメンバーに想定どおりのエラーが記録されます。クラスターメンバーへの接続が(一時的に)切断されたためであり、正常な動作です。リーダーは終了前にリーダーシップを移譲します。

{"level":"info","ts":"2026-06-02T07:01:54.949299+0300","caller":"etcdserver/server.go:1274","msg":"leadership transfer finished","local-member-id":"7339c4e5e833c029","old-leader-member-id":"7339c4e5e833c029","new-leader-member-id":"b548c2511513015","took":"101.052625ms"}
{"level":"info","ts":"2026-06-02T07:01:54.949369+0300","caller":"etcdserver/server.go:2349","msg":"server has stopped; stopping cluster version's monitor"}
{"level":"info","ts":"2026-06-02T07:01:55.503219+0300","caller":"embed/etcd.go:626","msg":"stopped serving peer traffic","address":"127.0.0.1:2380"}

手順4:同じ設定でetcdサーバーを再起動

同じ設定で、新しいetcdバイナリを使用してetcdサーバーを再起動します。

-etcd-old --name ${name} \
+etcd-new --name ${name} \
  --data-dir /path/to/${name}.etcd \
  --listen-client-urls http://localhost:2379 \
  --advertise-client-urls http://localhost:2379 \
  --listen-peer-urls http://localhost:2380 \
  --initial-advertise-peer-urls http://localhost:2380 \
  --initial-cluster s1=http://localhost:2380,s2=http://localhost:22380,s3=http://localhost:32380 \
  --initial-cluster-token tkn \
  --initial-cluster-state new

新しいv3.7のetcdは、自身の情報をクラスターに公開します。この時点では、クラスターは引き続き全メンバーに共通する最も低いバージョンであるv3.6のプロトコルで動作します。

{"level":"info","ts":"2026-06-02T07:01:58.920780+0300","caller":"membership/cluster.go:296","msg":"set cluster version from store","cluster-version":"3.6"}

{"level":"info","ts":"2026-06-02T07:01:58.979186+0300","caller":"etcdserver/server.go:1828","msg":"published local member to cluster through raft","local-member-id":"7339c4e5e833c029","local-member-attributes":"{Name:s1 ClientURLs:[http://localhost:2379]}","cluster-id":"7dee9ba76d59ed53","publish-timeout":"7s"}

新しいv3.7のetcdバイナリで、各メンバー、続いてクラスター全体が正常になることを確認してください。

etcdctl --endpoints=localhost:2379,localhost:22379,localhost:32379 endpoint status -w table
<<COMMENT
+-----------------+------------------+------------+-----------------+---------+--------+-----------+
|    ENDPOINT     |        ID        |  VERSION   | STORAGE VERSION | DB SIZE | LEADER | RAFT TERM |
+-----------------+------------------+------------+-----------------+---------+--------+-----------+
|  localhost:2379 | 7339c4e5e833c029 | 3.7.0-rc.0 |           3.6.0 |   98 kB |  false |         3 |
| localhost:22379 | 729934363faa4a24 |     3.6.12 |           3.6.0 |   98 kB |  false |         3 |
| localhost:32379 |  b548c2511513015 |     3.6.12 |           3.6.0 |   98 kB |   true |         3 |
+-----------------+------------------+------------+-----------------+---------+--------+-----------+
COMMENT

クラスター全体のアップグレードが完了するまでは、未アップグレードのメンバーとアップグレード済みのメンバーに、バージョンの混在状態に関するメッセージが記録されます。これは想定された動作で、すべてのetcdクラスターメンバーをv3.7にアップグレードすると表示されなくなります。

手順5:残りのメンバーで手順3と手順4を繰り返す

すべてのメンバーのアップグレードが完了すると、クラスターはv3.7へのアップグレードが成功したことを報告します。

{"level":"info","ts":"2026-06-02T07:02:36.054783+0300","caller":"etcdserver/server.go:2311","msg":"updating cluster version using v3 API","from":"3.6","to":"3.7"}

{"level":"info","ts":"2026-06-02T07:02:36.059345+0300","caller":"membership/cluster.go:593","msg":"updated cluster version","cluster-id":"7dee9ba76d59ed53","local-member-id":"7339c4e5e833c029","from":"3.6","to":"3.7"}

{"level":"info","ts":"2026-06-02T07:02:36.059409+0300","caller":"etcdserver/server.go:2326","msg":"cluster version is updated","cluster-version":"3.7"}

etcdctl --endpoints=localhost:2379,localhost:22379,localhost:32379 endpoint health
<<COMMENT
localhost:2379 is healthy: successfully committed proposal: took = 550.833µs
localhost:32379 is healthy: successfully committed proposal: took = 733.458µs
localhost:22379 is healthy: successfully committed proposal: took = 714.416µs
COMMENT

curl http://localhost:2379/version
<<COMMENT
{"etcdserver":"3.7.0-rc.0","etcdcluster":"3.7.0","storage":"3.7.0"}
COMMENT

curl http://localhost:22379/version
<<COMMENT
{"etcdserver":"3.7.0-rc.0","etcdcluster":"3.7.0","storage":"3.7.0"}
COMMENT

curl http://localhost:32379/version
<<COMMENT
{"etcdserver":"3.7.0-rc.0","etcdcluster":"3.7.0","storage":"3.7.0"}
COMMENT

3 - etcdをv3.5からv3.6にアップグレード

etcdをv3.5からv3.6にアップグレードする手順、チェックリスト、注意事項

通常、etcd v3.5からv3.6へのアップグレードは、停止時間なしのローリングアップグレードで実行できます。

  • etcd v3.5のプロセスを1つずつ停止し、etcd v3.6のプロセスに置き換えます。
  • すべてのプロセスがv3.6で稼働すると、クラスターでv3.6の新機能を利用できます。

アップグレードを開始する 前に、このガイドの残りを読んで準備してください。

アップグレードのチェックリスト

3.5の更新

重要

3.6にアップグレードする前に、すべての3.5メンバーが3.5.32以降に更新されている ことを確認してください。パッチリリース3.5.24から3.5.26では、アップグレードを妨げる可能性のある問題がいくつか修正されています。3.5.32 では--v2-deprecation=write-only-skip-checkが追加され、etcdutl check v2storeが拡張されてv2スナップショットに加えてWALレコードも検査するようになりました。

V2ストア

注記

--enable-v2フラグを設定していない、またはfalseに設定している場合、追加の作業は不要です。

--enable-v2を設定している場合は、etcdutl check v2storeコマンドを実行し、v2storeにメンバー構成以外の(カスタム)データが含まれていないか確認してください。カスタムデータがなければ、このフラグを安全に削除できます。含まれている場合は、v2移行ガイド で詳細を確認してください。

追加されたフラグ

+etcd --discovery-token ''
+etcd --discovery-endpoints ''
+etcd --discovery-dial-timeout '2s'
+etcd --discovery-request-timeout '5s'
+etcd --discovery-keepalive-time '2s'
+etcd --discovery-keepalive-timeout '6s'
+etcd --discovery-insecure-transport 'true'
+etcd --discovery-insecure-skip-tls-verify 'false'
+etcd --discovery-cert ''
+etcd --discovery-key ''
+etcd --discovery-cacert ''
+etcd --discovery-user ''
+etcd --discovery-password ''
+etcd --feature-gates
+etcd --log-format

削除されたフラグ

-etcd --enable-v2
-etcd --experimental-enable-v2v3
-etcd --proxy
-etcd --proxy-failure-wait
-etcd --proxy-refresh-interval
-etcd --proxy-dial-timeout
-etcd --proxy-write-timeout
-etcd --proxy-read-timeout

非推奨になったフラグ

etcd --experimental-bootstrap-defrag-threshold-megabytesフラグは非推奨になりました。


-etcd --experimental-bootstrap-defrag-threshold-megabytes

+etcd --bootstrap-defrag-threshold-megabytes

etcd --experimental-compaction-batch-limitフラグは非推奨になりました。


-etcd --experimental-compaction-batch-limit

+etcd --compaction-batch-limit

etcd --experimental-compact-hash-check-timeフラグは非推奨になりました。


-etcd --experimental-compact-hash-check-time

+etcd --compact-hash-check-time

etcd --experimental-compaction-sleep-intervalフラグは非推奨になりました。


-etcd --experimental-compaction-sleep-interval

+etcd --compaction-sleep-interval

etcd --experimental-corrupt-check-timeフラグは非推奨になりました。


-etcd --experimental-corrupt-check-time

+etcd --corrupt-check-time

etcd --experimental-enable-distributed-tracingフラグは非推奨になりました。


-etcd --experimental-enable-distributed-tracing

+etcd --enable-distributed-tracing

etcd --experimental-distributed-tracing-addressフラグは非推奨になりました。


-etcd --experimental-distributed-tracing-address

+etcd --distributed-tracing-address

etcd --experimental-distributed-tracing-instance-idフラグは非推奨になりました。


-etcd --experimental-distributed-tracing-instance-id

+etcd --distributed-tracing-instance-id

etcd --experimental-distributed-tracing-sampling-rateフラグは非推奨になりました。


-etcd --experimental-distributed-tracing-sampling-rate

+etcd --distributed-tracing-sampling-rate

etcd --experimental-distributed-tracing-service-nameフラグは非推奨になりました。


-etcd --experimental-distributed-tracing-service-name

+etcd --distributed-tracing-service-name

etcd --experimental-downgrade-check-timeフラグは非推奨になりました。


-etcd --experimental-downgrade-check-time

+etcd --downgrade-check-time

etcd --experimental-max-learnersフラグは非推奨になりました。


-etcd --experimental-max-learners

+etcd --max-learners

etcd --experimental-memory-mlockフラグは非推奨になりました。


-etcd --experimental-memory-mlock

+etcd --memory-mlock

etcd --experimental-peer-skip-client-san-verificationフラグは非推奨になりました。


-etcd --experimental-peer-skip-client-san-verification

+etcd --peer-skip-client-san-verification

etcd --experimental-snapshot-catchup-entriesフラグは非推奨になりました。


-etcd --experimental-snapshot-catchup-entries

+etcd --snapshot-catchup-entries

etcd --experimental-warning-apply-durationフラグは非推奨になりました。


-etcd --experimental-warning-apply-duration

+etcd --warning-apply-duration

etcd --experimental-warning-unary-request-durationフラグは非推奨になりました。


-etcd --experimental-warning-unary-request-duration

+etcd --warning-unary-request-duration

etcd --experimental-watch-progress-notify-intervalフラグは非推奨になりました。


-etcd --experimental-watch-progress-notify-interval

+etcd --watch-progress-notify-interval

v3.5の実験的フラグからフィーチャーゲートへの移行

etcd --experimental-compact-hash-check-enabled=trueに対応するフィーチャーゲート


-etcd --experimental-compact-hash-check-enabled=true

+etcd --feature-gates=CompactHashCheck=true

etcd --experimental-initial-corrupt-check=trueに対応するフィーチャーゲート


-etcd --experimental-initial-corrupt-check=true

+etcd --feature-gates=InitialCorruptCheck=true

etcd --experimental-enable-lease-checkpoint=trueに対応するフィーチャーゲート


-etcd --experimental-enable-lease-checkpoint=true

+etcd --feature-gates=LeaseCheckpoint=true

etcd --experimental-enable-lease-checkpoint-persist=trueに対応するフィーチャーゲート


-etcd --experimental-enable-lease-checkpoint-persist=true

+etcd --feature-gates=LeaseCheckpointPersist=true

etcd --experimental-stop-grpc-service-on-defrag=trueに対応するフィーチャーゲート


-etcd --experimental-stop-grpc-service-on-defrag=true

+etcd --feature-gates=StopGRPCServiceOnDefrag=true

etcd --experimental-txn-mode-write-with-shared-buffer=falseに対応するフィーチャーゲート


-etcd --experimental-txn-mode-write-with-shared-buffer=false

+etcd --feature-gates=TxnModeWriteWithSharedBuffer=false

デフォルト値が変更されたフラグ

以前のデフォルトフラグetcd --snapshot-count=100000


-etcd --snapshot-count=100000

+etcd --snapshot-count=10000

以前のデフォルトフラグetcd --v2-deprecation='not-yet'


-etcd --v2-deprecation='not-yet'

+etcd --v2-deprecation='write-only'

以前のデフォルトフラグetcd --discovery-fallback='proxy'


-etcd --discovery-fallback='proxy'

+etcd --discovery-fallback='exit'

Prometheusメトリクスの違い

# metrics added in v3.6
+etcd_network_known_peers
+etcd_server_feature_enabled

サーバーアップグレードのチェックリスト

アップグレードの要件

既存のetcd環境をv3.6にアップグレードするには、稼働中のクラスターがv3.5以降でなければなりません。v3.5より前の場合は、v3.6にアップグレードする前にv3.5にアップグレード してください。

また、ローリングアップグレードを円滑に進めるには、稼働中のクラスターが正常でなければなりません。作業を進める前に、etcdctl endpoint healthコマンドでクラスターの正常性を確認してください。

準備

etcdをアップグレードする際は、必ず本番環境に適用する前に、etcdに依存するサービスをステージング環境でテストしてください。

作業を始める前に、スナップショットバックアップをダウンロード してください。アップグレードで問題が発生した場合は、このバックアップを使用して元のetcdバージョンにロールバック できます。snapshotコマンドでバックアップされるのはv3データのみであることに注意してください。

バージョンの混在

アップグレード中のetcdクラスターでは、異なるバージョンのetcdメンバーの混在がサポートされ、全メンバーに共通する最も低いバージョンのプロトコルで動作します。すべてのメンバーがバージョンv3.6にアップグレードされて初めて、クラスターのアップグレードが完了したと見なされます。内部では、etcdメンバーが相互にネゴシエーションを行ってクラスター全体のバージョンを決定し、そのバージョンによって報告されるバージョンとサポートされる機能が決まります。

ロールバック

etcdクラスターをアップグレードする前に、クラスターのスナップショットバックアップを作成してダウンロード してください。このスナップショットを使えば、必要に応じてクラスターをアップグレード前の状態にリストアできます。アップグレード中に問題が発生した場合は、まず根本原因を特定して解決することをお勧めします。少なくとも1つのメンバーがv3.5のままで、クラスターのバージョンがまだ混在している場合は、バイナリまたはイメージを以前のv3.5のものに置き換えるか、スナップショットを使用してクラスターを直接リストアできます。この混在状態ではクラスターはv3.5クラスターとして動作し続けるため、正式なダウングレード手順を踏まずにロールバックできます。

ただし、すべてのメンバーをv3.6にアップグレードすると、クラスターのアップグレードは完了したと見なされ、バイナリを置き換えるだけでは正しくロールバックできません。リカバリーするには、アップグレード前に取得したスナップショットからリストアするか、公式のダウングレードガイドに従って元のバージョンに戻し、一貫性を確保してデータ破損を防ぐ方法があります。

アップグレード手順

この例では、ローカルマシンで稼働する3メンバー構成のv3.5 etcdクラスターをアップグレードする方法を説明します。

手順1:アップグレード要件の確認

クラスターは正常で、v3.5.xで稼働していますか。

etcdctl --endpoints=localhost:2379,localhost:22379,localhost:32379 endpoint health
<<COMMENT
localhost:2379 is healthy: successfully committed proposal: took = 2.555774ms
localhost:32379 is healthy: successfully committed proposal: took = 2.631133ms
localhost:22379 is healthy: successfully committed proposal: took = 3.020958ms
COMMENT

curl http://localhost:2379/version
<<COMMENT
{"etcdserver":"3.5.18","etcdcluster":"3.5.0"}
COMMENT

curl http://localhost:22379/version
<<COMMENT
{"etcdserver":"3.5.18","etcdcluster":"3.5.0"}
COMMENT

curl http://localhost:32379/version
<<COMMENT
{"etcdserver":"3.5.18","etcdcluster":"3.5.0"}
COMMENT

手順2:リーダーからスナップショットバックアップをダウンロード

問題が発生した場合にダウングレードできるよう、スナップショットバックアップをダウンロード してください。

etcdのリーダーには最新のアプリケーションデータがあることが保証されているため、リーダーからスナップショットを取得します。

curl -sL http://localhost:2379/metrics | grep etcd_server_is_leader
<<COMMENT
# HELP etcd_server_is_leader Whether or not this member is a leader. 1 if is, 0 otherwise.
# TYPE etcd_server_is_leader gauge
etcd_server_is_leader 1
COMMENT

curl -sL http://localhost:22379/metrics | grep etcd_server_is_leader
<<COMMENT
etcd_server_is_leader 0
COMMENT

curl -sL http://localhost:32379/metrics | grep etcd_server_is_leader
<<COMMENT
etcd_server_is_leader 0
COMMENT

etcdctl --endpoints=localhost:2379 snapshot save backup.db
<<COMMENT
{"level":"info","ts":"2025-03-01T04:34:10.336768+0530","caller":"snapshot/v3_snapshot.go:65","msg":"created temporary db file","path":"backup.db.part"}
{"level":"info","ts":"2025-03-01T04:34:10.342373+0530","logger":"client","caller":"v3@v3.5.18/maintenance.go:212","msg":"opened snapshot stream; downloading"}
{"level":"info","ts":"2025-03-01T04:34:10.342433+0530","caller":"snapshot/v3_snapshot.go:73","msg":"fetching snapshot","endpoint":"localhost:2379"}
{"level":"info","ts":"2025-03-01T04:34:10.346482+0530","logger":"client","caller":"v3@v3.5.18/maintenance.go:220","msg":"completed snapshot read; closing"}
{"level":"info","ts":"2025-03-01T04:34:10.348801+0530","caller":"snapshot/v3_snapshot.go:88","msg":"fetched snapshot","endpoint":"localhost:2379","size":"20 kB","took":"now"}
{"level":"info","ts":"2025-03-01T04:34:10.348933+0530","caller":"snapshot/v3_snapshot.go:97","msg":"saved","path":"backup.db"}
Snapshot saved at backup.db
COMMENT

手順3:既存のetcdサーバーを1つ停止

各etcdプロセスを停止すると、他のクラスターメンバーに想定どおりのエラーが記録されます。クラスターメンバーへの接続が(一時的に)切断されたためであり、正常な動作です。

{"level":"info","ts":"2025-03-01T04:31:50.654520+0530","caller":"etcdserver/server.go:2676","msg":"cluster version is updated","cluster-version":"3.5"}
{"level":"info","ts":"2025-03-01T04:34:10.345927+0530","caller":"v3rpc/maintenance.go:130","msg":"sending database snapshot to client","total-bytes":20480,"size":"20 kB"}
{"level":"info","ts":"2025-03-01T04:34:10.346094+0530","caller":"v3rpc/maintenance.go:170","msg":"sending database sha256 checksum to client","total-bytes":20480,"checksum-size":32}
{"level":"info","ts":"2025-03-01T04:34:10.346108+0530","caller":"v3rpc/maintenance.go:179","msg":"successfully sent database snapshot to client","total-bytes":20480,"size":"20 kB","took":"now"}
^C
{"level":"info","ts":"2025-03-01T04:35:01.443045+0530","caller":"osutil/interrupt_unix.go:64","msg":"received signal; shutting down","signal":"interrupt"}
{"level":"info","ts":"2025-03-01T04:35:01.443088+0530","caller":"embed/etcd.go:408","msg":"closing etcd server","name":"node1","data-dir":"/tmp/etcd-node1","advertise-peer-urls":["http://127.0.0.1:2380"],"advertise-client-urls":["http://127.0.0.1:2379"]}
{"level":"info","ts":"2025-03-01T04:35:01.443417+0530","caller":"etcdserver/server.go:1503","msg":"leadership transfer starting","local-member-id":"bf9071f4639c75cc","current-leader-member-id":"bf9071f4639c75cc","transferee-member-id":"91bc3c398fb3c146"}
{"level":"info","ts":"2025-03-01T04:35:01.443441+0530","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"bf9071f4639c75cc [term 2] starts to transfer leadership to 91bc3c398fb3c146"}
{"level":"info","ts":"2025-03-01T04:35:01.443455+0530","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"bf9071f4639c75cc sends MsgTimeoutNow to 91bc3c398fb3c146 immediately as 91bc3c398fb3c146 already has up-to-date log"}
{"level":"warn","ts":"2025-03-01T04:35:01.443517+0530","caller":"embed/serve.go:179","msg":"stopping insecure grpc server due to error","error":"accept tcp 127.0.0.1:2379: use of closed network connection"}
{"level":"warn","ts":"2025-03-01T04:35:01.443548+0530","caller":"embed/serve.go:181","msg":"stopped insecure grpc server due to error","error":"accept tcp 127.0.0.1:2379: use of closed network connection"}
{"level":"info","ts":"2025-03-01T04:35:01.445536+0530","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"bf9071f4639c75cc [term: 2] received a MsgVote message with higher term from 91bc3c398fb3c146 [term: 3]"}
{"level":"info","ts":"2025-03-01T04:35:01.445556+0530","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"bf9071f4639c75cc became follower at term 3"}
{"level":"info","ts":"2025-03-01T04:35:01.445565+0530","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"bf9071f4639c75cc [logterm: 2, index: 12, vote: 0] cast MsgVote for 91bc3c398fb3c146 [logterm: 2, index: 12] at term 3"}
{"level":"info","ts":"2025-03-01T04:35:01.445572+0530","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"raft.node: bf9071f4639c75cc lost leader bf9071f4639c75cc at term 3"}
{"level":"info","ts":"2025-03-01T04:35:01.446773+0530","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"raft.node: bf9071f4639c75cc elected leader 91bc3c398fb3c146 at term 3"}
{"level":"info","ts":"2025-03-01T04:35:01.544062+0530","caller":"etcdserver/server.go:1520","msg":"leadership transfer finished","local-member-id":"bf9071f4639c75cc","old-leader-member-id":"bf9071f4639c75cc","new-leader-member-id":"91bc3c398fb3c146","took":"100.640374ms"}
{"level":"info","ts":"2025-03-01T04:35:01.544160+0530","caller":"rafthttp/peer.go:330","msg":"stopping remote peer","remote-peer-id":"91bc3c398fb3c146"}
{"level":"warn","ts":"2025-03-01T04:35:01.544956+0530","caller":"rafthttp/stream.go:286","msg":"closed TCP streaming connection with remote peer","stream-writer-type":"stream MsgApp v2","remote-peer-id":"91bc3c398fb3c146"}
{"level":"info","ts":"2025-03-01T04:35:01.544984+0530","caller":"rafthttp/stream.go:294","msg":"stopped TCP streaming connection with remote peer","stream-writer-type":"stream MsgApp v2","remote-peer-id":"91bc3c398fb3c146"}
{"level":"warn","ts":"2025-03-01T04:35:01.545050+0530","caller":"rafthttp/stream.go:286","msg":"closed TCP streaming connection with remote peer","stream-writer-type":"stream Message","remote-peer-id":"91bc3c398fb3c146"}
{"level":"info","ts":"2025-03-01T04:35:01.545065+0530","caller":"rafthttp/stream.go:294","msg":"stopped TCP streaming connection with remote peer","stream-writer-type":"stream Message","remote-peer-id":"91bc3c398fb3c146"}
{"level":"info","ts":"2025-03-01T04:35:01.545099+0530","caller":"rafthttp/pipeline.go:85","msg":"stopped HTTP pipelining with remote peer","local-member-id":"bf9071f4639c75cc","remote-peer-id":"91bc3c398fb3c146"}
{"level":"warn","ts":"2025-03-01T04:35:01.545156+0530","caller":"rafthttp/stream.go:421","msg":"lost TCP streaming connection with remote peer","stream-reader-type":"stream MsgApp v2","local-member-id":"bf9071f4639c75cc","remote-peer-id":"91bc3c398fb3c146","error":"context canceled"}
{"level":"warn","ts":"2025-03-01T04:35:01.545178+0530","caller":"rafthttp/peer_status.go:66","msg":"peer became inactive (message send to peer failed)","peer-id":"91bc3c398fb3c146","error":"failed to read 91bc3c398fb3c146 on stream MsgApp v2 (context canceled)"}
{"level":"info","ts":"2025-03-01T04:35:01.545199+0530","caller":"rafthttp/stream.go:442","msg":"stopped stream reader with remote peer","stream-reader-type":"stream MsgApp v2","local-member-id":"bf9071f4639c75cc","remote-peer-id":"91bc3c398fb3c146"}
{"level":"warn","ts":"2025-03-01T04:35:01.545246+0530","caller":"rafthttp/stream.go:421","msg":"lost TCP streaming connection with remote peer","stream-reader-type":"stream Message","local-member-id":"bf9071f4639c75cc","remote-peer-id":"91bc3c398fb3c146","error":"context canceled"}
{"level":"info","ts":"2025-03-01T04:35:01.545263+0530","caller":"rafthttp/stream.go:442","msg":"stopped stream reader with remote peer","stream-reader-type":"stream Message","local-member-id":"bf9071f4639c75cc","remote-peer-id":"91bc3c398fb3c146"}
{"level":"info","ts":"2025-03-01T04:35:01.545272+0530","caller":"rafthttp/peer.go:335","msg":"stopped remote peer","remote-peer-id":"91bc3c398fb3c146"}
{"level":"info","ts":"2025-03-01T04:35:01.545282+0530","caller":"rafthttp/peer.go:330","msg":"stopping remote peer","remote-peer-id":"fd422379fda50e48"}
{"level":"warn","ts":"2025-03-01T04:35:01.545307+0530","caller":"rafthttp/stream.go:286","msg":"closed TCP streaming connection with remote peer","stream-writer-type":"stream MsgApp v2","remote-peer-id":"fd422379fda50e48"}
{"level":"info","ts":"2025-03-01T04:35:01.545328+0530","caller":"rafthttp/stream.go:294","msg":"stopped TCP streaming connection with remote peer","stream-writer-type":"stream MsgApp v2","remote-peer-id":"fd422379fda50e48"}
{"level":"warn","ts":"2025-03-01T04:35:01.545359+0530","caller":"rafthttp/stream.go:286","msg":"closed TCP streaming connection with remote peer","stream-writer-type":"stream Message","remote-peer-id":"fd422379fda50e48"}
{"level":"info","ts":"2025-03-01T04:35:01.545379+0530","caller":"rafthttp/stream.go:294","msg":"stopped TCP streaming connection with remote peer","stream-writer-type":"stream Message","remote-peer-id":"fd422379fda50e48"}
{"level":"info","ts":"2025-03-01T04:35:01.545410+0530","caller":"rafthttp/pipeline.go:85","msg":"stopped HTTP pipelining with remote peer","local-member-id":"bf9071f4639c75cc","remote-peer-id":"fd422379fda50e48"}
{"level":"warn","ts":"2025-03-01T04:35:01.545467+0530","caller":"rafthttp/stream.go:421","msg":"lost TCP streaming connection with remote peer","stream-reader-type":"stream MsgApp v2","local-member-id":"bf9071f4639c75cc","remote-peer-id":"fd422379fda50e48","error":"context canceled"}
{"level":"warn","ts":"2025-03-01T04:35:01.545485+0530","caller":"rafthttp/peer_status.go:66","msg":"peer became inactive (message send to peer failed)","peer-id":"fd422379fda50e48","error":"failed to read fd422379fda50e48 on stream MsgApp v2 (context canceled)"}
{"level":"info","ts":"2025-03-01T04:35:01.545504+0530","caller":"rafthttp/stream.go:442","msg":"stopped stream reader with remote peer","stream-reader-type":"stream MsgApp v2","local-member-id":"bf9071f4639c75cc","remote-peer-id":"fd422379fda50e48"}
{"level":"warn","ts":"2025-03-01T04:35:01.545560+0530","caller":"rafthttp/stream.go:421","msg":"lost TCP streaming connection with remote peer","stream-reader-type":"stream Message","local-member-id":"bf9071f4639c75cc","remote-peer-id":"fd422379fda50e48","error":"context canceled"}
{"level":"info","ts":"2025-03-01T04:35:01.545577+0530","caller":"rafthttp/stream.go:442","msg":"stopped stream reader with remote peer","stream-reader-type":"stream Message","local-member-id":"bf9071f4639c75cc","remote-peer-id":"fd422379fda50e48"}
{"level":"info","ts":"2025-03-01T04:35:01.545592+0530","caller":"rafthttp/peer.go:335","msg":"stopped remote peer","remote-peer-id":"fd422379fda50e48"}
{"level":"warn","ts":"2025-03-01T04:35:01.545669+0530","caller":"rafthttp/http.go:413","msg":"failed to find remote peer in cluster","local-member-id":"bf9071f4639c75cc","remote-peer-id-stream-handler":"bf9071f4639c75cc","remote-peer-id-from":"91bc3c398fb3c146","cluster-id":"59a05384c9b79ee"}
{"level":"warn","ts":"2025-03-01T04:35:01.545698+0530","caller":"rafthttp/http.go:413","msg":"failed to find remote peer in cluster","local-member-id":"bf9071f4639c75cc","remote-peer-id-stream-handler":"bf9071f4639c75cc","remote-peer-id-from":"fd422379fda50e48","cluster-id":"59a05384c9b79ee"}
{"level":"warn","ts":"2025-03-01T04:35:01.545732+0530","caller":"rafthttp/http.go:413","msg":"failed to find remote peer in cluster","local-member-id":"bf9071f4639c75cc","remote-peer-id-stream-handler":"bf9071f4639c75cc","remote-peer-id-from":"91bc3c398fb3c146","cluster-id":"59a05384c9b79ee"}
{"level":"warn","ts":"2025-03-01T04:35:01.545765+0530","caller":"rafthttp/http.go:413","msg":"failed to find remote peer in cluster","local-member-id":"bf9071f4639c75cc","remote-peer-id-stream-handler":"bf9071f4639c75cc","remote-peer-id-from":"fd422379fda50e48","cluster-id":"59a05384c9b79ee"}
{"level":"info","ts":"2025-03-01T04:35:01.549658+0530","caller":"embed/etcd.go:613","msg":"stopping serving peer traffic","address":"127.0.0.1:2380"}
{"level":"info","ts":"2025-03-01T04:35:02.550532+0530","caller":"embed/etcd.go:618","msg":"stopped serving peer traffic","address":"127.0.0.1:2380"}
{"level":"info","ts":"2025-03-01T04:35:02.550561+0530","caller":"embed/etcd.go:410","msg":"closed etcd server","name":"node1","data-dir":"/tmp/etcd-node1","advertise-peer-urls":["http://127.0.0.1:2380"],"advertise-client-urls":["http://127.0.0.1:2379"]}

手順4:同じ設定でetcdサーバーを再起動

同じ設定で、新しいetcdバイナリを使用してetcdサーバーを再起動します。

-etcd-old --name ${name} \
+etcd-new --name ${name} \
  --data-dir /path/to/${name}.etcd \
  --listen-client-urls http://localhost:2379 \
  --advertise-client-urls http://localhost:2379 \
  --listen-peer-urls http://localhost:2380 \
  --initial-advertise-peer-urls http://localhost:2380 \
  --initial-cluster s1=http://localhost:2380,s2=http://localhost:22380,s3=http://localhost:32380 \
  --initial-cluster-token tkn \
  --initial-cluster-state new

新しいv3.6のetcdは、自身の情報をクラスターに公開します。この時点では、クラスターは引き続き全メンバーに共通する最も低いバージョンであるv3.5のプロトコルで動作します。

{"level":"info","ts":"2025-03-01T04:40:36.828+0530","caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.5"}

{"level":"info","ts":"2025-03-01T04:40:36.889+0530","caller":"membership/cluster.go:539","msg":"updated cluster version","cluster-id":"59a05384c9b79ee","local-member-id":"bf9071f4639c75cc","from":"3.0","to":"3.5"}

{"level":"info","ts":"2025-03-01T04:40:36.828+0530","caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.5"}

{"level":"info","ts":"2025-03-01T04:40:36.894+0530","caller":"etcdserver/server.go:1686","msg":"published local member to cluster through raft","local-member-id":"bf9071f4639c75cc","local-member-attributes":"{Name:node1 ClientURLs:[http://127.0.0.1:2379]}","cluster-id":"59a05384c9b79ee","publish-timeout":"7s"}

新しいv3.6のetcdバイナリで、各メンバー、続いてクラスター全体が正常になることを確認してください。

etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
<<COMMENT
localhost:2379 is healthy: successfully committed proposal: took = 1.704998ms
localhost:22379 is healthy: successfully committed proposal: took = 2.331754ms
localhost:32379 is healthy: successfully committed proposal: took = 2.490705ms
COMMENT

クラスター全体のアップグレードが完了するまでは、未アップグレードのメンバーに次のような警告が記録されます。

これは想定された動作で、すべてのetcdクラスターメンバーをv3.6にアップグレードすると表示されなくなります。

{"level":"warn","ts":"2025-03-01T04:40:37.545960+0530","caller":"etcdserver/cluster_util.go:189","msg":"leader found higher-versioned member","local-member-version":"3.5.18","remote-member-id":"bf9071f4639c75cc","remote-member-version":"3.6.0-alpha.0"}

手順5:残りのメンバーで手順3と手順4を繰り返す

すべてのメンバーのアップグレードが完了すると、クラスターはv3.6へのアップグレードが成功したことを報告します。

メンバー1:

{"level":"info","ts":"2025-03-01T04:58:32.375+0530","caller":"etcdserver/server.go:2149","msg":"updating cluster version using v3 API","from":"3.5","to":"3.6"} {"level":"info","ts":"2025-03-01T04:58:32.377+0530","caller":"etcdserver/server.go:2164","msg":"cluster version is updated","cluster-version":"3.6"}

メンバー2:

{"level":"info","ts":"2025-03-01T04:58:32.377+0530","caller":"membership/cluster.go:539","msg":"updated cluster version","cluster-id":"59a05384c9b79ee","local-member-id":"91bc3c398fb3c146","from":"3.5","to":"3.6"}

メンバー3:

{"level":"info","ts":"2025-03-01T04:58:32.377+0530","caller":"membership/cluster.go:539","msg":"updated cluster version","cluster-id":"59a05384c9b79ee","local-member-id":"fd422379fda50e48","from":"3.5","to":"3.6"}

endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
<<COMMENT
localhost:2379 is healthy: successfully committed proposal: took = 492.834µs
localhost:22379 is healthy: successfully committed proposal: took = 1.015025ms
localhost:32379 is healthy: successfully committed proposal: took = 1.853077ms
COMMENT

curl http://localhost:2379/version
<<COMMENT
{"etcdserver":"3.6.0-alpha.0","etcdcluster":"3.6.0"}
COMMENT

curl http://localhost:22379/version
<<COMMENT
{"etcdserver":"3.6.0-alpha.0","etcdcluster":"3.6.0"}
COMMENT

curl http://localhost:32379/version
<<COMMENT
{"etcdserver":"3.6.0-alpha.0","etcdcluster":"3.6.0"}
COMMENT

4 - etcdを3.4から3.5にアップグレード

etcdを3.4から3.5にアップグレードする手順、チェックリスト、注意事項

通常、etcd 3.4から3.5へのアップグレードは、停止時間なしのローリングアップグレードで実行できます。

  • etcd v3.4のプロセスを1つずつ停止し、etcd v3.5のプロセスに置き換えます。
  • すべてのプロセスがv3.5で稼働すると、クラスターでv3.5の新機能を利用できます。

アップグレードを開始する 前に、このガイドの残りを読んで準備してください。

アップグレードのチェックリスト

警告

v3データのないv2から移行する 場合、v3のETCD_DATA_DIR/member/snap/dbファイルがない状態で既存のスナップショットからリストアすると、etcdサーバーv3.2+でパニックが発生します。これは、以前のv3データがないままサーバーをv2から移行した場合に起こります。この動作は、v3データの意図しない消失(たとえばdbファイルが移動された場合)を防ぐ役割も果たします。etcdでは、v3への移行後はv3データが存在する場合にのみ、さらに移行を進められます。v3.0サーバーにv3データが存在するまでは、それより新しいv3バージョンにアップグレードしないでください。

警告

クラスターで認証を有効にしている場合、3.5では認証に関するWALエントリーの形式が変更される ため、3.4以前のバージョンからのローリングアップグレードはサポートされません。

3.5の主な互換性を損なう変更は次のとおりです。

Prometheusメトリクスetcd_debugging_mvcc_db_total_size_in_bytesの非推奨化

v3.5では、etcdストレージの監視を促すため、Prometheusメトリクスetcd_debugging_mvcc_db_total_size_in_bytesをetcd_mvcc_db_total_size_in_bytesに昇格させました。また、v3.5ではetcd_debugging_mvcc_db_total_size_in_bytesが完全に非推奨になります。

-etcd_debugging_mvcc_db_total_size_in_bytes
+etcd_mvcc_db_total_size_in_bytes

etcd_debugging_*名前空間のメトリクスは、実験的機能と位置付けられていることに注意してください。監視ガイドの改善に伴い、さらに多くのメトリクスを昇格させる可能性があります。

Prometheusメトリクスetcd_debugging_mvcc_put_totalの非推奨化

v3.5では、etcdストレージの監視を促すため、Prometheusメトリクスetcd_debugging_mvcc_put_totalをetcd_mvcc_put_totalに昇格させました。また、v3.5ではetcd_debugging_mvcc_put_totalが完全に非推奨になります。

-etcd_debugging_mvcc_put_total
+etcd_mvcc_put_total

etcd_debugging_*名前空間のメトリクスは、実験的機能と位置付けられていることに注意してください。監視ガイドの改善に伴い、さらに多くのメトリクスを昇格させる可能性があります。

Prometheusメトリクスetcd_debugging_mvcc_delete_totalの非推奨化

v3.5では、etcdストレージの監視を促すため、Prometheusメトリクスetcd_debugging_mvcc_delete_totalをetcd_mvcc_delete_totalに昇格させました。また、v3.5ではetcd_debugging_mvcc_delete_totalが完全に非推奨になります。

-etcd_debugging_mvcc_delete_total
+etcd_mvcc_delete_total

etcd_debugging_*名前空間のメトリクスは、実験的機能と位置付けられていることに注意してください。監視ガイドの改善に伴い、さらに多くのメトリクスを昇格させる可能性があります。

Prometheusメトリクスetcd_debugging_mvcc_txn_totalの非推奨化

v3.5では、etcdストレージの監視を促すため、Prometheusメトリクスetcd_debugging_mvcc_txn_totalをetcd_mvcc_txn_totalに昇格させました。また、v3.5ではetcd_debugging_mvcc_txn_totalが完全に非推奨になります。

-etcd_debugging_mvcc_txn_total
+etcd_mvcc_txn_total

etcd_debugging_*名前空間のメトリクスは、実験的機能と位置付けられていることに注意してください。監視ガイドの改善に伴い、さらに多くのメトリクスを昇格させる可能性があります。

Prometheusメトリクスetcd_debugging_mvcc_range_totalの非推奨化

v3.5では、etcdストレージの監視を促すため、Prometheusメトリクスetcd_debugging_mvcc_range_totalをetcd_mvcc_range_totalに昇格させました。また、v3.5ではetcd_debugging_mvcc_range_totalが完全に非推奨になります。

-etcd_debugging_mvcc_range_total
+etcd_mvcc_range_total

etcd_debugging_*名前空間のメトリクスは、実験的機能と位置付けられていることに注意してください。監視ガイドの改善に伴い、さらに多くのメトリクスを昇格させる可能性があります。

etcd --logger capnslogの非推奨化

v3.5では、複数のログ出力と構造化ログをサポートするため、--logger=zapがデフォルトです。

v3.5ではetcd --logger=capnslogが非推奨となり、--logger=zapがデフォルトになりました。

-etcd --logger=capnslog
+etcd --logger=zap --log-outputs=stderr

+# to write logs to stderr and a.log file at the same time
+etcd --logger=zap --log-outputs=stderr,a.log

v3.4では、構造化ログと複数のログ出力に対応するため、etcd --logger=zapのサポートを追加しています。主な狙いは、障害が発生してからサーバーログを調べるのではなく、etcdの監視を自動化することです。今後の開発ではetcdのログ出力をできるだけ少なくし、メトリクスとアラートでetcdを監視しやすくします。etcd --logger=capnslogはv3.5で非推奨になります。

etcd --log-outputの非推奨化

v3.4では、複数のログ出力をサポートするため、etcd --log-outputを--log-outputsに改名しました 。

v3.5ではetcd --log-outputが非推奨になりました。

-etcd --log-output=stderr
+etcd --log-outputs=stderr

etcd --debugフラグの非推奨化(現在は--log-level=debug)

etcd --debugフラグは非推奨になりました。

-etcd --debug
+etcd --log-level debug

etcd --log-package-levelsの非推奨化

capnslog用のetcd --log-package-levelsフラグは非推奨になりました。

現在は、**etcd --logger=zap**がデフォルトです。

-etcd --log-package-levels 'etcdmain=CRITICAL,etcdserver=DEBUG'
+etcd --logger=zap --log-outputs=stderr

[CLIENT-URL]/config/local/logの非推奨化

v3.5では、/config/local/logエンドポイントとetcd --log-package-levelsフラグが非推奨になります。

-$ curl http://127.0.0.1:2379/config/local/log -XPUT -d '{"Level":"DEBUG"}'
-# debug logging enabled

gRPCゲートウェイのHTTPエンドポイントの変更(/v3betaを非推奨化)

変更前

curl -L http://localhost:2379/v3beta/kv/put \
  -X POST -d '{"key": "Zm9v", "value": "YmFy"}'

変更後

curl -L http://localhost:2379/v3/kv/put \
  -X POST -d '{"key": "Zm9v", "value": "YmFy"}'

/v3betaは3.5リリースで削除されました。

サーバーアップグレードのチェックリスト

アップグレードの要件

既存のetcd環境を3.5にアップグレードするには、稼働中のクラスターが3.4以降でなければなりません。3.4より前の場合は、3.5にアップグレードする前に3.4にアップグレード してください。

また、ローリングアップグレードを円滑に進めるには、稼働中のクラスターが正常でなければなりません。作業を進める前に、etcdctl endpoint healthコマンドでクラスターの正常性を確認してください。

準備

etcdをアップグレードする際は、必ず本番環境に適用する前に、etcdに依存するサービスをステージング環境でテストしてください。

作業を始める前に、スナップショットバックアップをダウンロード してください。アップグレードで問題が発生した場合は、このバックアップを使用して元のetcdバージョンにダウングレード できます。snapshotコマンドでバックアップされるのはv3データのみであることに注意してください。v2データについては、v2データストアのバックアップ を参照してください。

バージョンの混在

アップグレード中のetcdクラスターでは、異なるバージョンのetcdメンバーの混在がサポートされ、全メンバーに共通する最も低いバージョンのプロトコルで動作します。すべてのメンバーがバージョン3.5にアップグレードされて初めて、クラスターのアップグレードが完了したと見なされます。内部では、etcdメンバーが相互にネゴシエーションを行ってクラスター全体のバージョンを決定し、そのバージョンによって報告されるバージョンとサポートされる機能が決まります。

制限事項

注:クラスターにv3データしかなく、v2データがない場合、この制限は適用されません。

クラスターが50MBを超えるv2データセットを提供している場合、新しくアップグレードした各メンバーが既存のクラスターに追いつくまでに最大2分かかることがあります。直近のスナップショットのサイズを調べて、データの総量を見積もってください。つまり、各メンバーのアップグレードの間に2分待つのが最も安全です。

データの総量が100MB以上とさらに大きい場合、この1回限りの処理にはより長い時間がかかることがあります。この規模の非常に大きなetcdクラスターを管理している場合は、アップグレード前にetcdチーム までお気軽にお問い合わせください。手順についてアドバイスします。

ダウングレード

すべてのメンバーをv3.5にアップグレードすると、クラスターもv3.5にアップグレードされ、この完了状態からのダウングレードはできません。ただし、1つでもv3.4のメンバーが残っていれば、クラスターとその動作は「v3.4」のままであり、この混在状態からすべてのメンバーでv3.4のetcdバイナリを使用する状態に戻せます。

アップグレード完了後でもクラスターをダウングレードできるように、スナップショットバックアップをダウンロード してください。

アップグレード手順

この例では、ローカルマシンで稼働する3メンバー構成のv3.4 etcdクラスターをアップグレードする方法を説明します。

手順1:アップグレード要件の確認

クラスターは正常で、v3.4.xで稼働していますか。

etcdctl --endpoints=localhost:2379,localhost:22379,localhost:32379 endpoint health
<<COMMENT
localhost:2379 is healthy: successfully committed proposal: took = 2.118638ms
localhost:22379 is healthy: successfully committed proposal: took = 3.631388ms
localhost:32379 is healthy: successfully committed proposal: took = 2.157051ms
COMMENT

curl http://localhost:2379/version
<<COMMENT
{"etcdserver":"3.4.0","etcdcluster":"3.4.0"}
COMMENT

curl http://localhost:22379/version
<<COMMENT
{"etcdserver":"3.4.0","etcdcluster":"3.4.0"}
COMMENT

curl http://localhost:32379/version
<<COMMENT
{"etcdserver":"3.4.0","etcdcluster":"3.4.0"}
COMMENT

手順2:リーダーからスナップショットバックアップをダウンロード

問題が発生した場合にダウングレードできるよう、スナップショットバックアップをダウンロード してください。

etcdのリーダーには最新のアプリケーションデータがあることが保証されているため、リーダーからスナップショットを取得します。

curl -sL http://localhost:2379/metrics | grep etcd_server_is_leader
<<COMMENT
# HELP etcd_server_is_leader Whether or not this member is a leader. 1 if is, 0 otherwise.
# TYPE etcd_server_is_leader gauge
etcd_server_is_leader 1
COMMENT

curl -sL http://localhost:22379/metrics | grep etcd_server_is_leader
<<COMMENT
etcd_server_is_leader 0
COMMENT

curl -sL http://localhost:32379/metrics | grep etcd_server_is_leader
<<COMMENT
etcd_server_is_leader 0
COMMENT

etcdctl --endpoints=localhost:2379 snapshot save backup.db
<<COMMENT
{"level":"info","ts":1526585787.148433,"caller":"snapshot/v3_snapshot.go:109","msg":"created temporary db file","path":"backup.db.part"}
{"level":"info","ts":1526585787.1485257,"caller":"snapshot/v3_snapshot.go:120","msg":"fetching snapshot","endpoint":"localhost:2379"}
{"level":"info","ts":1526585787.1519694,"caller":"snapshot/v3_snapshot.go:133","msg":"fetched snapshot","endpoint":"localhost:2379","took":0.003502721}
{"level":"info","ts":1526585787.1520295,"caller":"snapshot/v3_snapshot.go:142","msg":"saved","path":"backup.db"}
Snapshot saved at backup.db
COMMENT

手順3:既存のetcdサーバーを1つ停止

各etcdプロセスを停止すると、他のクラスターメンバーに想定どおりのエラーが記録されます。クラスターメンバーへの接続が(一時的に)切断されたためであり、正常な動作です。

{"level":"info","ts":1526587281.2001143,"caller":"etcdserver/server.go:2249","msg":"updating cluster version","from":"3.0","to":"3.4"}
{"level":"info","ts":1526587281.2010646,"caller":"membership/cluster.go:473","msg":"updated cluster version","cluster-id":"7dee9ba76d59ed53","local-member-id":"7339c4e5e833c029","from":"3.0","from":"3.4"}
{"level":"info","ts":1526587281.2012327,"caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.4"}
{"level":"info","ts":1526587281.2013083,"caller":"etcdserver/server.go:2272","msg":"cluster version is updated","cluster-version":"3.4"}



^C{"level":"info","ts":1526587299.0717514,"caller":"osutil/interrupt_unix.go:63","msg":"received signal; shutting down","signal":"interrupt"}
{"level":"info","ts":1526587299.0718873,"caller":"embed/etcd.go:285","msg":"closing etcd server","name":"s1","data-dir":"/tmp/etcd/s1","advertise-peer-urls":["http://localhost:2380"],"advertise-client-urls":["http://localhost:2379"]}
{"level":"info","ts":1526587299.0722554,"caller":"etcdserver/server.go:1341","msg":"leadership transfer starting","local-member-id":"7339c4e5e833c029","current-leader-member-id":"7339c4e5e833c029","transferee-member-id":"729934363faa4a24"}
{"level":"info","ts":1526587299.0723994,"caller":"raft/raft.go:1107","msg":"7339c4e5e833c029 [term 3] starts to transfer leadership to 729934363faa4a24"}
{"level":"info","ts":1526587299.0724802,"caller":"raft/raft.go:1113","msg":"7339c4e5e833c029 sends MsgTimeoutNow to 729934363faa4a24 immediately as 729934363faa4a24 already has up-to-date log"}
{"level":"info","ts":1526587299.0737045,"caller":"raft/raft.go:797","msg":"7339c4e5e833c029 [term: 3] received a MsgVote message with higher term from 729934363faa4a24 [term: 4]"}
{"level":"info","ts":1526587299.0737681,"caller":"raft/raft.go:656","msg":"7339c4e5e833c029 became follower at term 4"}
{"level":"info","ts":1526587299.073831,"caller":"raft/raft.go:882","msg":"7339c4e5e833c029 [logterm: 3, index: 9, vote: 0] cast MsgVote for 729934363faa4a24 [logterm: 3, index: 9] at term 4"}
{"level":"info","ts":1526587299.0738947,"caller":"raft/node.go:312","msg":"raft.node: 7339c4e5e833c029 lost leader 7339c4e5e833c029 at term 4"}
{"level":"info","ts":1526587299.0748374,"caller":"raft/node.go:306","msg":"raft.node: 7339c4e5e833c029 elected leader 729934363faa4a24 at term 4"}
{"level":"info","ts":1526587299.1726425,"caller":"etcdserver/server.go:1362","msg":"leadership transfer finished","local-member-id":"7339c4e5e833c029","old-leader-member-id":"7339c4e5e833c029","new-leader-member-id":"729934363faa4a24","took":0.100389359}
{"level":"info","ts":1526587299.1728148,"caller":"rafthttp/peer.go:333","msg":"stopping remote peer","remote-peer-id":"b548c2511513015"}
{"level":"warn","ts":1526587299.1751974,"caller":"rafthttp/stream.go:291","msg":"closed TCP streaming connection with remote peer","stream-writer-type":"stream MsgApp v2","remote-peer-id":"b548c2511513015"}
{"level":"warn","ts":1526587299.1752589,"caller":"rafthttp/stream.go:301","msg":"stopped TCP streaming connection with remote peer","stream-writer-type":"stream MsgApp v2","remote-peer-id":"b548c2511513015"}
{"level":"warn","ts":1526587299.177348,"caller":"rafthttp/stream.go:291","msg":"closed TCP streaming connection with remote peer","stream-writer-type":"stream Message","remote-peer-id":"b548c2511513015"}
{"level":"warn","ts":1526587299.1774004,"caller":"rafthttp/stream.go:301","msg":"stopped TCP streaming connection with remote peer","stream-writer-type":"stream Message","remote-peer-id":"b548c2511513015"}
{"level":"info","ts":1526587299.177515,"caller":"rafthttp/pipeline.go:86","msg":"stopped HTTP pipelining with remote peer","local-member-id":"7339c4e5e833c029","remote-peer-id":"b548c2511513015"}
{"level":"warn","ts":1526587299.1777067,"caller":"rafthttp/stream.go:436","msg":"lost TCP streaming connection with remote peer","stream-reader-type":"stream MsgApp v2","local-member-id":"7339c4e5e833c029","remote-peer-id":"b548c2511513015","error":"read tcp 127.0.0.1:34636->127.0.0.1:32380: use of closed network connection"}
{"level":"info","ts":1526587299.1778402,"caller":"rafthttp/stream.go:459","msg":"stopped stream reader with remote peer","stream-reader-type":"stream MsgApp v2","local-member-id":"7339c4e5e833c029","remote-peer-id":"b548c2511513015"}
{"level":"warn","ts":1526587299.1780295,"caller":"rafthttp/stream.go:436","msg":"lost TCP streaming connection with remote peer","stream-reader-type":"stream Message","local-member-id":"7339c4e5e833c029","remote-peer-id":"b548c2511513015","error":"read tcp 127.0.0.1:34634->127.0.0.1:32380: use of closed network connection"}
{"level":"info","ts":1526587299.1780987,"caller":"rafthttp/stream.go:459","msg":"stopped stream reader with remote peer","stream-reader-type":"stream Message","local-member-id":"7339c4e5e833c029","remote-peer-id":"b548c2511513015"}
{"level":"info","ts":1526587299.1781602,"caller":"rafthttp/peer.go:340","msg":"stopped remote peer","remote-peer-id":"b548c2511513015"}
{"level":"info","ts":1526587299.1781986,"caller":"rafthttp/peer.go:333","msg":"stopping remote peer","remote-peer-id":"729934363faa4a24"}
{"level":"warn","ts":1526587299.1802843,"caller":"rafthttp/stream.go:291","msg":"closed TCP streaming connection with remote peer","stream-writer-type":"stream MsgApp v2","remote-peer-id":"729934363faa4a24"}
{"level":"warn","ts":1526587299.1803446,"caller":"rafthttp/stream.go:301","msg":"stopped TCP streaming connection with remote peer","stream-writer-type":"stream MsgApp v2","remote-peer-id":"729934363faa4a24"}
{"level":"warn","ts":1526587299.1824749,"caller":"rafthttp/stream.go:291","msg":"closed TCP streaming connection with remote peer","stream-writer-type":"stream Message","remote-peer-id":"729934363faa4a24"}
{"level":"warn","ts":1526587299.18255,"caller":"rafthttp/stream.go:301","msg":"stopped TCP streaming connection with remote peer","stream-writer-type":"stream Message","remote-peer-id":"729934363faa4a24"}
{"level":"info","ts":1526587299.18261,"caller":"rafthttp/pipeline.go:86","msg":"stopped HTTP pipelining with remote peer","local-member-id":"7339c4e5e833c029","remote-peer-id":"729934363faa4a24"}
{"level":"warn","ts":1526587299.1827736,"caller":"rafthttp/stream.go:436","msg":"lost TCP streaming connection with remote peer","stream-reader-type":"stream MsgApp v2","local-member-id":"7339c4e5e833c029","remote-peer-id":"729934363faa4a24","error":"read tcp 127.0.0.1:51482->127.0.0.1:22380: use of closed network connection"}
{"level":"info","ts":1526587299.182845,"caller":"rafthttp/stream.go:459","msg":"stopped stream reader with remote peer","stream-reader-type":"stream MsgApp v2","local-member-id":"7339c4e5e833c029","remote-peer-id":"729934363faa4a24"}
{"level":"warn","ts":1526587299.1830168,"caller":"rafthttp/stream.go:436","msg":"lost TCP streaming connection with remote peer","stream-reader-type":"stream Message","local-member-id":"7339c4e5e833c029","remote-peer-id":"729934363faa4a24","error":"context canceled"}
{"level":"warn","ts":1526587299.1831107,"caller":"rafthttp/peer_status.go:65","msg":"peer became inactive","peer-id":"729934363faa4a24","error":"failed to read 729934363faa4a24 on stream Message (context canceled)"}
{"level":"info","ts":1526587299.1831737,"caller":"rafthttp/stream.go:459","msg":"stopped stream reader with remote peer","stream-reader-type":"stream Message","local-member-id":"7339c4e5e833c029","remote-peer-id":"729934363faa4a24"}
{"level":"info","ts":1526587299.1832306,"caller":"rafthttp/peer.go:340","msg":"stopped remote peer","remote-peer-id":"729934363faa4a24"}
{"level":"warn","ts":1526587299.1837125,"caller":"rafthttp/http.go:424","msg":"failed to find remote peer in cluster","local-member-id":"7339c4e5e833c029","remote-peer-id-stream-handler":"7339c4e5e833c029","remote-peer-id-from":"b548c2511513015","cluster-id":"7dee9ba76d59ed53"}
{"level":"warn","ts":1526587299.1840093,"caller":"rafthttp/http.go:424","msg":"failed to find remote peer in cluster","local-member-id":"7339c4e5e833c029","remote-peer-id-stream-handler":"7339c4e5e833c029","remote-peer-id-from":"b548c2511513015","cluster-id":"7dee9ba76d59ed53"}
{"level":"warn","ts":1526587299.1842315,"caller":"rafthttp/http.go:424","msg":"failed to find remote peer in cluster","local-member-id":"7339c4e5e833c029","remote-peer-id-stream-handler":"7339c4e5e833c029","remote-peer-id-from":"729934363faa4a24","cluster-id":"7dee9ba76d59ed53"}
{"level":"warn","ts":1526587299.1844475,"caller":"rafthttp/http.go:424","msg":"failed to find remote peer in cluster","local-member-id":"7339c4e5e833c029","remote-peer-id-stream-handler":"7339c4e5e833c029","remote-peer-id-from":"729934363faa4a24","cluster-id":"7dee9ba76d59ed53"}
{"level":"info","ts":1526587299.2056687,"caller":"embed/etcd.go:473","msg":"stopping serving peer traffic","address":"127.0.0.1:2380"}
{"level":"info","ts":1526587299.205819,"caller":"embed/etcd.go:480","msg":"stopped serving peer traffic","address":"127.0.0.1:2380"}
{"level":"info","ts":1526587299.2058413,"caller":"embed/etcd.go:289","msg":"closed etcd server","name":"s1","data-dir":"/tmp/etcd/s1","advertise-peer-urls":["http://localhost:2380"],"advertise-client-urls":["http://localhost:2379"]}

手順4:同じ設定でetcdサーバーを再起動

同じ設定で、新しいetcdバイナリを使用してetcdサーバーを再起動します。

-etcd-old --name s1 \
+etcd-new --name s1 \
  --data-dir /tmp/etcd/s1 \
  --listen-client-urls http://localhost:2379 \
  --advertise-client-urls http://localhost:2379 \
  --listen-peer-urls http://localhost:2380 \
  --initial-advertise-peer-urls http://localhost:2380 \
  --initial-cluster s1=http://localhost:2380,s2=http://localhost:22380,s3=http://localhost:32380 \
  --initial-cluster-token tkn \
  --initial-cluster-state new

新しいv3.5のetcdは、自身の情報をクラスターに公開します。この時点では、クラスターは引き続き全メンバーに共通する最も低いバージョンであるv3.4のプロトコルで動作します。

{"level":"info","ts":1526586617.1647713,"caller":"membership/cluster.go:485","msg":"set initial cluster version","cluster-id":"7dee9ba76d59ed53","local-member-id":"7339c4e5e833c029","cluster-version":"3.0"}

{"level":"info","ts":1526586617.1648536,"caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.0"}

{"level":"info","ts":1526586617.1649303,"caller":"membership/cluster.go:473","msg":"updated cluster version","cluster-id":"7dee9ba76d59ed53","local-member-id":"7339c4e5e833c029","from":"3.0","from":"3.4"}

{"level":"info","ts":1526586617.1649797,"caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.4"}

{"level":"info","ts":1526586617.2107732,"caller":"etcdserver/server.go:1770","msg":"published local member to cluster through raft","local-member-id":"7339c4e5e833c029","local-member-attributes":"{Name:s1 ClientURLs:[http://localhost:2379]}","request-path":"/0/members/7339c4e5e833c029/attributes","cluster-id":"7dee9ba76d59ed53","publish-timeout":7}

新しいv3.5のetcdバイナリで、各メンバー、続いてクラスター全体が正常になることを確認してください。

etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
<<COMMENT
localhost:32379 is healthy: successfully committed proposal: took = 2.337471ms
localhost:22379 is healthy: successfully committed proposal: took = 1.130717ms
localhost:2379 is healthy: successfully committed proposal: took = 2.124843ms
COMMENT

クラスター全体のアップグレードが完了するまでは、未アップグレードのメンバーに次のような警告が記録されます。

これは想定された動作で、すべてのetcdクラスターメンバーをv3.5にアップグレードすると表示されなくなります。

:41.942121 W | etcdserver: member 7339c4e5e833c029 has a higher version 3.5.0
:45.945154 W | etcdserver: the local etcd version 3.4.0 is not up-to-date

手順5:残りのメンバーで手順3と手順4を繰り返す

すべてのメンバーのアップグレードが完了すると、クラスターは3.5へのアップグレードが成功したことを報告します。

メンバー1:

{"level":"info","ts":1526586949.0920913,"caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.5"} {"level":"info","ts":1526586949.0921566,"caller":"etcdserver/server.go:2272","msg":"cluster version is updated","cluster-version":"3.5"}

メンバー2:

{"level":"info","ts":1526586949.092117,"caller":"membership/cluster.go:473","msg":"updated cluster version","cluster-id":"7dee9ba76d59ed53","local-member-id":"729934363faa4a24","from":"3.4","from":"3.5"} {"level":"info","ts":1526586949.0923078,"caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.5"}

メンバー3:

{"level":"info","ts":1526586949.0921423,"caller":"membership/cluster.go:473","msg":"updated cluster version","cluster-id":"7dee9ba76d59ed53","local-member-id":"b548c2511513015","from":"3.4","from":"3.5"} {"level":"info","ts":1526586949.0922918,"caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.5"}

endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
<<COMMENT
localhost:2379 is healthy: successfully committed proposal: took = 492.834µs
localhost:22379 is healthy: successfully committed proposal: took = 1.015025ms
localhost:32379 is healthy: successfully committed proposal: took = 1.853077ms
COMMENT

curl http://localhost:2379/version
<<COMMENT
{"etcdserver":"3.5.0","etcdcluster":"3.5.0"}
COMMENT

curl http://localhost:22379/version
<<COMMENT
{"etcdserver":"3.5.0","etcdcluster":"3.5.0"}
COMMENT

curl http://localhost:32379/version
<<COMMENT
{"etcdserver":"3.5.0","etcdcluster":"3.5.0"}
COMMENT

5 - etcdを3.3から3.4にアップグレード

etcdを3.3から3.4にアップグレードする手順、チェックリスト、注意事項

通常、etcd 3.3から3.4へのアップグレードは、停止時間なしのローリングアップグレードで実行できます。

  • etcd v3.3のプロセスを1つずつ停止し、etcd v3.4のプロセスに置き換えます。
  • すべてのプロセスがv3.4で稼働すると、クラスターでv3.4の新機能を利用できます。

アップグレードを開始する 前に、このガイドの残りを読んで準備してください。

アップグレードのチェックリスト

警告

v3データのないv2から移行する 場合、v3のETCD_DATA_DIR/member/snap/dbファイルがない状態で既存のスナップショットからリストアすると、etcdサーバーv3.2+でパニックが発生します。これは、以前のv3データがないままサーバーをv2から移行した場合に起こります。この動作は、v3データの意図しない消失(たとえばdbファイルが移動された場合)を防ぐ役割も果たします。etcdでは、v3への移行後はv3データが存在する場合にのみ、さらに移行を進められます。v3.0サーバーにv3データが存在するまでは、それより新しいv3バージョンにアップグレードしないでください。

3.4の主な互換性を損なう変更は次のとおりです。

ETCDCTL_API=3 etcdctlをデフォルトに変更

ETCDCTL_API=3がデフォルトになりました。

etcdctl set foo bar
Error: unknown command "set" for "etcdctl"

-etcdctl set foo bar
+ETCDCTL_API=2 etcdctl set foo bar
bar

ETCDCTL_API=3 etcdctl put foo bar
OK

-ETCDCTL_API=3 etcdctl put foo bar
+etcdctl put foo bar

etcd --enable-v2=falseをデフォルトに変更

etcd --enable-v2=false がデフォルトになりました。

つまり、etcd --enable-v2=trueを指定しない限り、etcd v3.4サーバーはv2 APIリクエストを処理しません。

v2 APIを使用していた場合は、v3.4で必ずv2 APIを有効にしてください。

-etcd
+etcd --enable-v2=true

その他のHTTP APIは引き続き動作します(例:[CLIENT-URL]/metrics、[CLIENT-URL]/health、v3 gRPCゲートウェイ)。

etcd --ca-fileおよびetcd --peer-ca-fileフラグの非推奨化

--ca-fileおよび--peer-ca-fileフラグは非推奨です。これらはv2.1から非推奨となっています。

このパラメーターを設定すると、--client-cert-authの値にかかわらず、クライアント証明書認証も自動的に有効になることに注意してください。

-etcd --ca-file ca-client.crt
+etcd --trusted-ca-file ca-client.crt
-etcd --peer-ca-file ca-peer.crt
+etcd --peer-trusted-ca-file ca-peer.crt

grpc.ErrClientConnClosingエラーの非推奨化

grpc.ErrClientConnClosingはgRPC >= 1.10で非推奨になりました 。

import (
+	"go.etcd.io/etcd/clientv3"

	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
)

_, err := kvc.Get(ctx, "a")
-if err == grpc.ErrClientConnClosing {
+if clientv3.IsConnCanceled(err) {

// or
+s, ok := status.FromError(err)
+if ok {
+  if s.Code() == codes.Canceled

クライアントの接続にgrpc.WithBlockが必要

新しいクライアントバランサー は、非同期リゾルバーを使用してgRPCの接続関数にエンドポイントを渡します。そのため、v3.4クライアントでは、基盤となる接続の確立を待つために、接続オプションgrpc.WithBlockが必要です。

import (
	"time"
	"go.etcd.io/etcd/clientv3"
+	"google.golang.org/grpc"
)

+// "grpc.WithBlock()" to block until the underlying connection is up
ccfg := clientv3.Config{
  Endpoints:            []string{"localhost:2379"},
  DialTimeout:          time.Second,
+ DialOptions:          []grpc.DialOption{grpc.WithBlock()},
  DialKeepAliveTime:    time.Second,
  DialKeepAliveTimeout: 500 * time.Millisecond,
}

Prometheusメトリクスetcd_debugging_mvcc_db_total_size_in_bytesの非推奨化

v3.4では、etcdストレージの監視を促すため、Prometheusメトリクスetcd_debugging_mvcc_db_total_size_in_bytesをetcd_mvcc_db_total_size_in_bytesに昇格させています。

後方互換性のため、v3.4ではetcd_debugging_mvcc_db_total_size_in_bytesも引き続き提供されます。v3.5で完全に非推奨になります。

-etcd_debugging_mvcc_db_total_size_in_bytes
+etcd_mvcc_db_total_size_in_bytes

etcd_debugging_*名前空間のメトリクスは、実験的機能と位置付けられていることに注意してください。監視ガイドの改善に伴い、さらに多くのメトリクスを昇格させる可能性があります。

Prometheusメトリクスetcd_debugging_mvcc_put_totalの非推奨化

v3.4では、etcdストレージの監視を促すため、Prometheusメトリクスetcd_debugging_mvcc_put_totalをetcd_mvcc_put_totalに昇格させています。

後方互換性のため、v3.4ではetcd_debugging_mvcc_put_totalも引き続き提供されます。v3.5で完全に非推奨になります。

-etcd_debugging_mvcc_put_total
+etcd_mvcc_put_total

etcd_debugging_*名前空間のメトリクスは、実験的機能と位置付けられていることに注意してください。監視ガイドの改善に伴い、さらに多くのメトリクスを昇格させる可能性があります。

Prometheusメトリクスetcd_debugging_mvcc_delete_totalの非推奨化

v3.4では、etcdストレージの監視を促すため、Prometheusメトリクスetcd_debugging_mvcc_delete_totalをetcd_mvcc_delete_totalに昇格させています。

後方互換性のため、v3.4ではetcd_debugging_mvcc_delete_totalも引き続き提供されます。v3.5で完全に非推奨になります。

-etcd_debugging_mvcc_delete_total
+etcd_mvcc_delete_total

etcd_debugging_*名前空間のメトリクスは、実験的機能と位置付けられていることに注意してください。監視ガイドの改善に伴い、さらに多くのメトリクスを昇格させる可能性があります。

Prometheusメトリクスetcd_debugging_mvcc_txn_totalの非推奨化

v3.4では、etcdストレージの監視を促すため、Prometheusメトリクスetcd_debugging_mvcc_txn_totalをetcd_mvcc_txn_totalに昇格させています。

後方互換性のため、v3.4ではetcd_debugging_mvcc_txn_totalも引き続き提供されます。v3.5で完全に非推奨になります。

-etcd_debugging_mvcc_txn_total
+etcd_mvcc_txn_total

etcd_debugging_*名前空間のメトリクスは、実験的機能と位置付けられていることに注意してください。監視ガイドの改善に伴い、さらに多くのメトリクスを昇格させる可能性があります。

Prometheusメトリクスetcd_debugging_mvcc_range_totalの非推奨化

v3.4では、etcdストレージの監視を促すため、Prometheusメトリクスetcd_debugging_mvcc_range_totalをetcd_mvcc_range_totalに昇格させています。

後方互換性のため、v3.4ではetcd_debugging_mvcc_range_totalも引き続き提供されます。v3.5で完全に非推奨になります。

-etcd_debugging_mvcc_range_total
+etcd_mvcc_range_total

etcd_debugging_*名前空間のメトリクスは、実験的機能と位置付けられていることに注意してください。監視ガイドの改善に伴い、さらに多くのメトリクスを昇格させる可能性があります。

etcd --log-outputフラグの非推奨化(現在は--log-outputs)

複数のログ出力をサポートするため、etcd --log-outputを--log-outputsに改名しました 。etcd --logger=capnslogは複数のログ出力をサポートしません。

etcd --log-outputはv3.5で非推奨になります。etcd --logger=capnslogはv3.5で非推奨になります。

-etcd --log-output=stderr
+etcd --log-outputs=stderr

+# to write logs to stderr and a.log file at the same time
+# only "--logger=zap" supports multiple writers
+etcd --logger=zap --log-outputs=stderr,a.log

v3.4では、構造化ログと複数のログ出力に対応するため、etcd --logger=zap --log-outputs=stderrのサポートを追加しています。主な狙いは、障害が発生してからサーバーログを調べるのではなく、etcdの監視を自動化することです。今後の開発ではetcdのログ出力をできるだけ少なくし、メトリクスとアラートでetcdを監視しやすくします。etcd --logger=capnslogはv3.5で非推奨になります。

etcd --config-fileのlog-outputsフィールドの型を[]stringに変更

log-outputs(以前のフィールド名はlog-output)が複数のライターを受け付けるようになったため、etcdの設定YAMLファイルのlog-outputsフィールドは、次のように[]string型に変更しなければなりません。

 # Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd.
-log-output: default
+log-outputs: [default]

embed.Config.LogOutputをembed.Config.LogOutputsに改名

複数のログ出力をサポートするため、**embed.Config.LogOutputをembed.Config.LogOutputs**に改名しました 。また、複数のログ出力をサポートするため、embed.Config.LogOutputの型をstringから[]stringに変更しました 。

import "github.com/coreos/etcd/embed"

cfg := &embed.Config{Debug: false}
-cfg.LogOutput = "stderr"
+cfg.LogOutputs = []string{"stderr"}

v3.5でcapnslogを非推奨化

v3.5では、capnslog用のetcd --log-package-levelsフラグが非推奨になります。etcd --logger=zap --log-outputs=stderrがデフォルトになります。v3.5では、[CLIENT-URL]/config/local/logエンドポイントが非推奨になります。

-etcd
+etcd --logger zap

etcd --debugフラグの非推奨化(現在は--log-level=debug)

v3.4では、etcd --debug フラグが非推奨になります。代わりにetcd --log-level=debugフラグを使用してください。

-etcd --debug
+etcd --logger zap --log-level debug

pkg/transport.TLSInfo.CAFileフィールドの非推奨化

pkg/transport.TLSInfo.CAFileフィールドは非推奨になりました。

import "github.com/coreos/etcd/pkg/transport"

tlsInfo := transport.TLSInfo{
    CertFile: "/tmp/test-certs/test.pem",
    KeyFile: "/tmp/test-certs/test-key.pem",
-   CAFile: "/tmp/test-certs/trusted-ca.pem",
+   TrustedCAFile: "/tmp/test-certs/trusted-ca.pem",
}
tlsConfig, err := tlsInfo.ClientConfig()
if err != nil {
    panic(err)
}

embed.Config.SnapCountをembed.Config.SnapshotCountに変更

フラグ名etcd --snapshot-countと一貫性を持たせるため、embed.Config.SnapCountフィールドはembed.Config.SnapshotCountに改名されました。

import "github.com/coreos/etcd/embed"

cfg := embed.NewConfig()
-cfg.SnapCount = 100000
+cfg.SnapshotCount = 100000

etcdserver.ServerConfig.SnapCountをetcdserver.ServerConfig.SnapshotCountに変更

フラグ名etcd --snapshot-countと一貫性を持たせるため、etcdserver.ServerConfig.SnapCountフィールドはetcdserver.ServerConfig.SnapshotCountに改名されました。

import "github.com/coreos/etcd/etcdserver"

srvcfg := etcdserver.ServerConfig{
-  SnapCount: 100000,
+  SnapshotCount: 100000,

walパッケージの関数シグネチャの変更

構造化ロガーをサポートするため、walの関数シグネチャを変更しました。

import "github.com/coreos/etcd/wal"
+import "go.uber.org/zap"

+lg, _ = zap.NewProduction()

-wal.Open(dirpath, snap)
+wal.Open(lg, dirpath, snap)

-wal.OpenForRead(dirpath, snap)
+wal.OpenForRead(lg, dirpath, snap)

-wal.Repair(dirpath)
+wal.Repair(lg, dirpath)

-wal.Create(dirpath, metadata)
+wal.Create(lg, dirpath, metadata)

pkg/adtパッケージのIntervalTree型の変更

pkg/adt.IntervalTreeはinterfaceとして定義されるようになりました。

import (
    "fmt"

    "go.etcd.io/etcd/pkg/adt"
)

func main() {
-    ivt := &adt.IntervalTree{}
+    ivt := adt.NewIntervalTree()

embed.Config.SetupLoggingの非推奨化

誤ったログ設定を防ぐため、embed.Config.SetupLoggingは削除され、ログ設定は自動的に行われるようになりました。

import "github.com/coreos/etcd/embed"

cfg := &embed.Config{Debug: false}
-cfg.SetupLogging()

gRPCゲートウェイのHTTPエンドポイントの変更(/v3betaを/v3に置き換え)

変更前

curl -L http://localhost:2379/v3beta/kv/put \
  -X POST -d '{"key": "Zm9v", "value": "YmFy"}'

変更後

curl -L http://localhost:2379/v3/kv/put \
  -X POST -d '{"key": "Zm9v", "value": "YmFy"}'

/v3betaエンドポイントへのリクエストは/v3にリダイレクトされ、/v3betaは3.5リリースで削除されます。

コンテナーイメージタグの非推奨化

latestおよびマイナーバージョンのイメージタグは非推奨になりました。

-docker pull gcr.io/etcd-development/etcd:latest
+docker pull gcr.io/etcd-development/etcd:v3.4.0

-docker pull gcr.io/etcd-development/etcd:v3.4
+docker pull gcr.io/etcd-development/etcd:v3.4.0

-docker pull gcr.io/etcd-development/etcd:v3.4
+docker pull gcr.io/etcd-development/etcd:v3.4.1

-docker pull gcr.io/etcd-development/etcd:v3.4
+docker pull gcr.io/etcd-development/etcd:v3.4.2

サーバーアップグレードのチェックリスト

アップグレードの要件

既存のetcd環境を3.4にアップグレードするには、稼働中のクラスターが3.3以降でなければなりません。3.3より前の場合は、3.4にアップグレードする前に3.3にアップグレード してください。

また、ローリングアップグレードを円滑に進めるには、稼働中のクラスターが正常でなければなりません。作業を進める前に、etcdctl endpoint healthコマンドでクラスターの正常性を確認してください。

準備

etcdをアップグレードする際は、必ず本番環境に適用する前に、etcdに依存するサービスをステージング環境でテストしてください。

作業を始める前に、スナップショットバックアップをダウンロード してください。アップグレードで問題が発生した場合は、このバックアップを使用して元のetcdバージョンにダウングレード できます。snapshotコマンドでバックアップされるのはv3データのみであることに注意してください。v2データについては、v2データストアのバックアップ を参照してください。

バージョンの混在

アップグレード中のetcdクラスターでは、異なるバージョンのetcdメンバーの混在がサポートされ、全メンバーに共通する最も低いバージョンのプロトコルで動作します。すべてのメンバーがバージョン3.4にアップグレードされて初めて、クラスターのアップグレードが完了したと見なされます。内部では、etcdメンバーが相互にネゴシエーションを行ってクラスター全体のバージョンを決定し、そのバージョンによって報告されるバージョンとサポートされる機能が決まります。

制限事項

注:クラスターにv3データしかなく、v2データがない場合、この制限は適用されません。

クラスターが50MBを超えるv2データセットを提供している場合、新しくアップグレードした各メンバーが既存のクラスターに追いつくまでに最大2分かかることがあります。直近のスナップショットのサイズを調べて、データの総量を見積もってください。つまり、各メンバーのアップグレードの間に2分待つのが最も安全です。

データの総量が100MB以上とさらに大きい場合、この1回限りの処理にはより長い時間がかかることがあります。この規模の非常に大きなetcdクラスターを管理している場合は、アップグレード前にetcdチーム までお気軽にお問い合わせください。手順についてアドバイスします。

ダウングレード

すべてのメンバーをv3.4にアップグレードすると、クラスターもv3.4にアップグレードされ、この完了状態からのダウングレードはできません。ただし、1つでもv3.3のメンバーが残っていれば、クラスターとその動作は「v3.3」のままであり、この混在状態からすべてのメンバーでv3.3のetcdバイナリを使用する状態に戻せます。

アップグレード完了後でもクラスターをダウングレードできるように、スナップショットバックアップをダウンロード してください。

アップグレード手順

この例では、ローカルマシンで稼働する3メンバー構成のv3.3 etcdクラスターをアップグレードする方法を説明します。

手順1:アップグレード要件の確認

クラスターは正常で、v3.3.xで稼働していますか。

etcdctl --endpoints=localhost:2379,localhost:22379,localhost:32379 endpoint health
<<COMMENT
localhost:2379 is healthy: successfully committed proposal: took = 2.118638ms
localhost:22379 is healthy: successfully committed proposal: took = 3.631388ms
localhost:32379 is healthy: successfully committed proposal: took = 2.157051ms
COMMENT

curl http://localhost:2379/version
<<COMMENT
{"etcdserver":"3.3.5","etcdcluster":"3.3.0"}
COMMENT

curl http://localhost:22379/version
<<COMMENT
{"etcdserver":"3.3.5","etcdcluster":"3.3.0"}
COMMENT

curl http://localhost:32379/version
<<COMMENT
{"etcdserver":"3.3.5","etcdcluster":"3.3.0"}
COMMENT

手順2:リーダーからスナップショットバックアップをダウンロード

問題が発生した場合にダウングレードできるよう、スナップショットバックアップをダウンロード してください。

etcdのリーダーには最新のアプリケーションデータがあることが保証されているため、リーダーからスナップショットを取得します。

curl -sL http://localhost:2379/metrics | grep etcd_server_is_leader
<<COMMENT
# HELP etcd_server_is_leader Whether or not this member is a leader. 1 if is, 0 otherwise.
# TYPE etcd_server_is_leader gauge
etcd_server_is_leader 1
COMMENT

curl -sL http://localhost:22379/metrics | grep etcd_server_is_leader
<<COMMENT
etcd_server_is_leader 0
COMMENT

curl -sL http://localhost:32379/metrics | grep etcd_server_is_leader
<<COMMENT
etcd_server_is_leader 0
COMMENT

etcdctl --endpoints=localhost:2379 snapshot save backup.db
<<COMMENT
{"level":"info","ts":1526585787.148433,"caller":"snapshot/v3_snapshot.go:109","msg":"created temporary db file","path":"backup.db.part"}
{"level":"info","ts":1526585787.1485257,"caller":"snapshot/v3_snapshot.go:120","msg":"fetching snapshot","endpoint":"localhost:2379"}
{"level":"info","ts":1526585787.1519694,"caller":"snapshot/v3_snapshot.go:133","msg":"fetched snapshot","endpoint":"localhost:2379","took":0.003502721}
{"level":"info","ts":1526585787.1520295,"caller":"snapshot/v3_snapshot.go:142","msg":"saved","path":"backup.db"}
Snapshot saved at backup.db
COMMENT

手順3:既存のetcdサーバーを1つ停止

各etcdプロセスを停止すると、他のクラスターメンバーに想定どおりのエラーが記録されます。クラスターメンバーへの接続が(一時的に)切断されたためであり、正常な動作です。

10.237579 I | etcdserver: updating the cluster version from 3.0 to 3.3
10.238315 N | etcdserver/membership: updated the cluster version from 3.0 to 3.3
10.238451 I | etcdserver/api: enabled capabilities for version 3.3


^C21.192174 N | pkg/osutil: received interrupt signal, shutting down...
21.192459 I | etcdserver: 7339c4e5e833c029 starts leadership transfer from 7339c4e5e833c029 to 729934363faa4a24
21.192569 I | raft: 7339c4e5e833c029 [term 8] starts to transfer leadership to 729934363faa4a24
21.192619 I | raft: 7339c4e5e833c029 sends MsgTimeoutNow to 729934363faa4a24 immediately as 729934363faa4a24 already has up-to-date log
WARNING: 2018/05/17 12:45:21 grpc: addrConn.resetTransport failed to create client transport: connection error: desc = "transport: Error while dialing dial tcp: operation was canceled"; Reconnecting to {localhost:2379 0  <nil>}
WARNING: 2018/05/17 12:45:21 grpc: addrConn.transportMonitor exits due to: grpc: the connection is closing
21.193589 I | raft: 7339c4e5e833c029 [term: 8] received a MsgVote message with higher term from 729934363faa4a24 [term: 9]
21.193626 I | raft: 7339c4e5e833c029 became follower at term 9
21.193651 I | raft: 7339c4e5e833c029 [logterm: 8, index: 9, vote: 0] cast MsgVote for 729934363faa4a24 [logterm: 8, index: 9] at term 9
21.193675 I | raft: raft.node: 7339c4e5e833c029 lost leader 7339c4e5e833c029 at term 9
21.194424 I | raft: raft.node: 7339c4e5e833c029 elected leader 729934363faa4a24 at term 9
21.292898 I | etcdserver: 7339c4e5e833c029 finished leadership transfer from 7339c4e5e833c029 to 729934363faa4a24 (took 100.436391ms)
21.292975 I | rafthttp: stopping peer 729934363faa4a24...
21.293206 I | rafthttp: closed the TCP streaming connection with peer 729934363faa4a24 (stream MsgApp v2 writer)
21.293225 I | rafthttp: stopped streaming with peer 729934363faa4a24 (writer)
21.293437 I | rafthttp: closed the TCP streaming connection with peer 729934363faa4a24 (stream Message writer)
21.293459 I | rafthttp: stopped streaming with peer 729934363faa4a24 (writer)
21.293514 I | rafthttp: stopped HTTP pipelining with peer 729934363faa4a24
21.293590 W | rafthttp: lost the TCP streaming connection with peer 729934363faa4a24 (stream MsgApp v2 reader)
21.293610 I | rafthttp: stopped streaming with peer 729934363faa4a24 (stream MsgApp v2 reader)
21.293680 W | rafthttp: lost the TCP streaming connection with peer 729934363faa4a24 (stream Message reader)
21.293700 I | rafthttp: stopped streaming with peer 729934363faa4a24 (stream Message reader)
21.293711 I | rafthttp: stopped peer 729934363faa4a24
21.293720 I | rafthttp: stopping peer b548c2511513015...
21.293987 I | rafthttp: closed the TCP streaming connection with peer b548c2511513015 (stream MsgApp v2 writer)
21.294063 I | rafthttp: stopped streaming with peer b548c2511513015 (writer)
21.294467 I | rafthttp: closed the TCP streaming connection with peer b548c2511513015 (stream Message writer)
21.294561 I | rafthttp: stopped streaming with peer b548c2511513015 (writer)
21.294742 I | rafthttp: stopped HTTP pipelining with peer b548c2511513015
21.294867 W | rafthttp: lost the TCP streaming connection with peer b548c2511513015 (stream MsgApp v2 reader)
21.294892 I | rafthttp: stopped streaming with peer b548c2511513015 (stream MsgApp v2 reader)
21.294990 W | rafthttp: lost the TCP streaming connection with peer b548c2511513015 (stream Message reader)
21.295004 E | rafthttp: failed to read b548c2511513015 on stream Message (context canceled)
21.295013 I | rafthttp: peer b548c2511513015 became inactive
21.295024 I | rafthttp: stopped streaming with peer b548c2511513015 (stream Message reader)
21.295035 I | rafthttp: stopped peer b548c2511513015

手順4:同じ設定でetcdサーバーを再起動

同じ設定で、新しいetcdバイナリを使用してetcdサーバーを再起動します。

-etcd-old --name s1 \
+etcd-new --name s1 \
  --data-dir /tmp/etcd/s1 \
  --listen-client-urls http://localhost:2379 \
  --advertise-client-urls http://localhost:2379 \
  --listen-peer-urls http://localhost:2380 \
  --initial-advertise-peer-urls http://localhost:2380 \
  --initial-cluster s1=http://localhost:2380,s2=http://localhost:22380,s3=http://localhost:32380 \
  --initial-cluster-token tkn \
+ --initial-cluster-state new \
+ --logger zap \
+ --log-outputs stderr

新しいv3.4のetcdは、自身の情報をクラスターに公開します。この時点では、クラスターは引き続き全メンバーに共通する最も低いバージョンであるv3.3のプロトコルで動作します。

{"level":"info","ts":1526586617.1647713,"caller":"membership/cluster.go:485","msg":"set initial cluster version","cluster-id":"7dee9ba76d59ed53","local-member-id":"7339c4e5e833c029","cluster-version":"3.0"}

{"level":"info","ts":1526586617.1648536,"caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.0"}

{"level":"info","ts":1526586617.1649303,"caller":"membership/cluster.go:473","msg":"updated cluster version","cluster-id":"7dee9ba76d59ed53","local-member-id":"7339c4e5e833c029","from":"3.0","from":"3.3"}

{"level":"info","ts":1526586617.1649797,"caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.3"}

{"level":"info","ts":1526586617.2107732,"caller":"etcdserver/server.go:1770","msg":"published local member to cluster through raft","local-member-id":"7339c4e5e833c029","local-member-attributes":"{Name:s1 ClientURLs:[http://localhost:2379]}","request-path":"/0/members/7339c4e5e833c029/attributes","cluster-id":"7dee9ba76d59ed53","publish-timeout":7}

新しいv3.4のetcdバイナリで、各メンバー、続いてクラスター全体が正常になることを確認してください。

etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
<<COMMENT
localhost:32379 is healthy: successfully committed proposal: took = 2.337471ms
localhost:22379 is healthy: successfully committed proposal: took = 1.130717ms
localhost:2379 is healthy: successfully committed proposal: took = 2.124843ms
COMMENT

クラスター全体のアップグレードが完了するまでは、未アップグレードのメンバーに次のような警告が記録されます。

これは想定された動作で、すべてのetcdクラスターメンバーをv3.4にアップグレードすると表示されなくなります。

:41.942121 W | etcdserver: member 7339c4e5e833c029 has a higher version 3.4.0
:45.945154 W | etcdserver: the local etcd version 3.3.5 is not up-to-date

手順5:残りのメンバーで手順3と手順4を繰り返す

すべてのメンバーのアップグレードが完了すると、クラスターは3.4へのアップグレードが成功したことを報告します。

メンバー1:

{"level":"info","ts":1526586949.0920913,"caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.4"} {"level":"info","ts":1526586949.0921566,"caller":"etcdserver/server.go:2272","msg":"cluster version is updated","cluster-version":"3.4"}

メンバー2:

{"level":"info","ts":1526586949.092117,"caller":"membership/cluster.go:473","msg":"updated cluster version","cluster-id":"7dee9ba76d59ed53","local-member-id":"729934363faa4a24","from":"3.3","from":"3.4"} {"level":"info","ts":1526586949.0923078,"caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.4"}

メンバー3:

{"level":"info","ts":1526586949.0921423,"caller":"membership/cluster.go:473","msg":"updated cluster version","cluster-id":"7dee9ba76d59ed53","local-member-id":"b548c2511513015","from":"3.3","from":"3.4"} {"level":"info","ts":1526586949.0922918,"caller":"api/capability.go:76","msg":"enabled capabilities for version","cluster-version":"3.4"}

endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
<<COMMENT
localhost:2379 is healthy: successfully committed proposal: took = 492.834µs
localhost:22379 is healthy: successfully committed proposal: took = 1.015025ms
localhost:32379 is healthy: successfully committed proposal: took = 1.853077ms
COMMENT

curl http://localhost:2379/version
<<COMMENT
{"etcdserver":"3.4.0","etcdcluster":"3.4.0"}
COMMENT

curl http://localhost:22379/version
<<COMMENT
{"etcdserver":"3.4.0","etcdcluster":"3.4.0"}
COMMENT

curl http://localhost:32379/version
<<COMMENT
{"etcdserver":"3.4.0","etcdcluster":"3.4.0"}
COMMENT

6 - etcdを3.2から3.3にアップグレード

etcdを3.2から3.3にアップグレードする手順、チェックリスト、注意事項

通常、etcd 3.2から3.3へのアップグレードは、停止時間なしのローリングアップグレードで実行できます。

  • etcd v3.2のプロセスを1つずつ停止し、etcd v3.3のプロセスに置き換えます。
  • すべてのプロセスがv3.3で稼働すると、クラスターでv3.3の新機能を利用できます。

アップグレードを開始する 前に、このガイドの残りを読んで準備してください。

アップグレードのチェックリスト

警告

v3データのないv2から移行する 場合、v3のETCD_DATA_DIR/member/snap/dbファイルがない状態で既存のスナップショットからリストアすると、etcdサーバーv3.2+でパニックが発生します。これは、以前のv3データがないままサーバーをv2から移行した場合に起こります。この動作は、v3データの意図しない消失(たとえばdbファイルが移動された場合)を防ぐ役割も果たします。etcdでは、v3への移行後はv3データが存在する場合にのみ、さらに移行を進められます。v3.0サーバーにv3データが存在するまでは、それより新しいv3バージョンにアップグレードしないでください。

警告

認証を有効にしてリースを使用している場合(リースのTTLが短い場合)、データの不整合を引き起こす問題 に遭遇する可能性が高くなります。この問題を修正するため、まず3.2.31+にアップグレードしてから3.3にアップグレードすることを強くお勧めします。また、アップグレード中に権限のないユーザーが3.3ノードへLeaseRevokeリクエストを送信すると、データが破損する可能性が残ります。アップグレード前に、そのような異常な呼び出しが環境内に存在しないことを確認するのが最善です。詳細は#11691 を参照してください。

3.3の主な互換性を損なう変更は次のとおりです。

etcd --auto-compaction-retentionフラグの値の型をstringに変更

--auto-compaction-retentionフラグを変更して文字列値を受け付ける ようにし、より細かい粒度 で指定できるようにしました。--auto-compaction-retentionが文字列値を受け付けるようになったため、etcdの設定YAMLファイルのauto-compaction-retentionフィールドをstring型に変更しなければなりません。以前は--config-file etcd.config.yamlにauto-compaction-retention: 24フィールドを指定できましたが、今後はauto-compaction-retention: "24"またはauto-compaction-retention: "24h"にする必要があります。--auto-compaction-mode periodic --auto-compaction-retention "24h"と設定する場合、--auto-compaction-retentionフラグの期間の値は、Goのtime.ParseDuration 関数で有効な値でなければなりません。

# etcd.config.yaml
+auto-compaction-mode: periodic
-auto-compaction-retention: 24
+auto-compaction-retention: "24"
+# Or
+auto-compaction-retention: "24h"

*etcdserver.ServerConfigをetcdserver.ServerConfigに変更

etcdserver.EtcdServerのメンバーフィールドの型は、*etcdserver.ServerConfigからetcdserver.ServerConfigに変更されました。また、etcdserver.NewServerは*etcdserver.ServerConfigではなくetcdserver.ServerConfigを受け取るようになりました。

変更前と変更後(例:k8s.io/kubernetes/test/e2e_node/services/etcd.go )

import "github.com/coreos/etcd/etcdserver"

type EtcdServer struct {
	*etcdserver.EtcdServer
-	config *etcdserver.ServerConfig
+	config etcdserver.ServerConfig
}

func NewEtcd(dataDir string) *EtcdServer {
-	config := &etcdserver.ServerConfig{
+	config := etcdserver.ServerConfig{
		DataDir: dataDir,
        ...
	}
	return &EtcdServer{config: config}
}

func (e *EtcdServer) Start() error {
	var err error
	e.EtcdServer, err = etcdserver.NewServer(e.config)
    ...

embed.Config.LogOutputフィールドの追加

警告

v3.4では、このフィールドが[]string型のembed.Config.LogOutputsに変更されたことに注意してください。詳細はv3.4アップグレードガイド を参照してください。

embed.ConfigにLogOutputフィールドが追加されました。

package embed

type Config struct {
 	Debug bool `json:"debug"`
 	LogPkgLevels string `json:"log-package-levels"`
+	LogOutput string `json:"log-output"`
 	...

以前は、gRPCサーバーの警告はetcdserverに記録されていました。

WARNING: 2017/11/02 11:35:51 grpc: addrConn.resetTransport failed to create client transport: connection error: desc = "transport: Error while dialing dial tcp: operation was canceled"; Reconnecting to {localhost:2379 <nil>}
WARNING: 2017/11/02 11:35:51 grpc: addrConn.resetTransport failed to create client transport: connection error: desc = "transport: Error while dialing dial tcp: operation was canceled"; Reconnecting to {localhost:2379 <nil>}

v3.3以降、gRPCサーバーのログはデフォルトで無効です。

警告

v3.4では、embed.Config.SetupLoggingメソッドが非推奨になったことに注意してください。詳細はv3.4アップグレードガイド を参照してください。

import "github.com/coreos/etcd/embed"

cfg := &embed.Config{Debug: false}
cfg.SetupLogging()

gRPCサーバーのログを有効にするには、embed.Config.Debugフィールドをtrueに設定します。

/healthエンドポイントのレスポンスの変更

以前は、[endpoint]:[client-port]/healthが手動でマーシャリングしたJSON値を返していました。3.3ではetcdhttp.Health 構造体を定義するようになりました。

v3.3.0-rc.0、v3.3.0-rc.1、v3.3.0-rc.2では、etcdhttp.Healthの"health"と"errors"フィールドがboolean型であったことに注意してください。後方互換性のため、"health"フィールドをstring型に戻し、"errors"フィールドを削除しました。追加の正常性情報は、別のAPIで提供される予定です。

$ curl http://localhost:2379/health
{"health":"true"}

gRPCゲートウェイのHTTPエンドポイントの変更(/v3alphaを/v3betaに置き換え)

変更前

curl -L http://localhost:2379/v3alpha/kv/put \
  -X POST -d '{"key": "Zm9v", "value": "YmFy"}'

変更後

curl -L http://localhost:2379/v3beta/kv/put \
  -X POST -d '{"key": "Zm9v", "value": "YmFy"}'

/v3alphaエンドポイントへのリクエストは/v3betaにリダイレクトされ、/v3alphaは3.4リリースで削除されます。

リクエストの最大サイズ制限の変更

3.3では、サーバー側とクライアント側の両方でリクエストサイズ制限をカスタマイズできるようになりました。以前のバージョン(v3.2.10、v3.2.11)では、クライアントのレスポンスサイズはわずか4 MiBに制限されていました。

サーバー側のリクエスト制限は、--max-request-bytesフラグで設定できます。

# limits request size to 1.5 KiB
etcd --max-request-bytes 1536

# client writes exceeding 1.5 KiB will be rejected
etcdctl put foo [LARGE VALUE...]
# etcdserver: request is too large

または、embed.Config.MaxRequestBytesフィールドで設定します。

import "github.com/coreos/etcd/embed"
import "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"

// limit requests to 5 MiB
cfg := embed.NewConfig()
cfg.MaxRequestBytes = 5 * 1024 * 1024

// client writes exceeding 5 MiB will be rejected
_, err := cli.Put(ctx, "foo", [LARGE VALUE...])
err == rpctypes.ErrRequestTooLarge

指定しない場合、サーバー側の制限のデフォルトは1.5 MiBです。

クライアント側のリクエスト制限は、サーバー側の制限に基づいて設定しなければなりません。

# limits request size to 1 MiB
etcd --max-request-bytes 1048576
import "github.com/coreos/etcd/clientv3"

cli, _ := clientv3.New(clientv3.Config{
    Endpoints: []string{"127.0.0.1:2379"},
    MaxCallSendMsgSize: 2 * 1024 * 1024,
    MaxCallRecvMsgSize: 3 * 1024 * 1024,
})


// client writes exceeding "--max-request-bytes" will be rejected from etcd server
_, err := cli.Put(ctx, "foo", strings.Repeat("a", 1*1024*1024+5))
err == rpctypes.ErrRequestTooLarge


// client writes exceeding "MaxCallSendMsgSize" will be rejected from client-side
_, err = cli.Put(ctx, "foo", strings.Repeat("a", 5*1024*1024))
err.Error() == "rpc error: code = ResourceExhausted desc = grpc: trying to send message larger than max (5242890 vs. 2097152)"


// some writes under limits
for i := range []int{0,1,2,3,4} {
    _, err = cli.Put(ctx, fmt.Sprintf("foo%d", i), strings.Repeat("a", 1*1024*1024-500))
    if err != nil {
        panic(err)
    }
}
// client reads exceeding "MaxCallRecvMsgSize" will be rejected from client-side
_, err = cli.Get(ctx, "foo", clientv3.WithPrefix())
err.Error() == "rpc error: code = ResourceExhausted desc = grpc: received message larger than max (5240509 vs. 3145728)"

指定しない場合、クライアント側の送信制限のデフォルトは2 MiB(1.5 MiB + gRPCのオーバーヘッド分のバイト数)、受信制限のデフォルトはmath.MaxInt32です。詳細はclientv3 godoc を参照してください。

低水準gRPCクライアントラッパーの関数シグネチャの変更

3.3では、clientv3のgRPCクライアントラッパーの関数シグネチャが変更されています。この変更は、メッセージサイズ制限を指定するカスタムgrpc.CallOption をサポートするために必要でした。

変更前と変更後

-func NewKVFromKVClient(remote pb.KVClient) KV {
+func NewKVFromKVClient(remote pb.KVClient, c *Client) KV {

-func NewClusterFromClusterClient(remote pb.ClusterClient) Cluster {
+func NewClusterFromClusterClient(remote pb.ClusterClient, c *Client) Cluster {

-func NewLeaseFromLeaseClient(remote pb.LeaseClient, keepAliveTimeout time.Duration) Lease {
+func NewLeaseFromLeaseClient(remote pb.LeaseClient, c *Client, keepAliveTimeout time.Duration) Lease {

-func NewMaintenanceFromMaintenanceClient(remote pb.MaintenanceClient) Maintenance {
+func NewMaintenanceFromMaintenanceClient(remote pb.MaintenanceClient, c *Client) Maintenance {

-func NewWatchFromWatchClient(wc pb.WatchClient) Watcher {
+func NewWatchFromWatchClient(wc pb.WatchClient, c *Client) Watcher {

clientv3のSnapshot APIのエラー型の変更

以前は、clientv3のSnapshot APIが低水準の[grpc/*status.statusError]型のエラーを返していました。v3.3では、他のAPIとの一貫性を保つため、これらのエラーを対応する公開エラー型に変換します。

変更前

import "context"

// reading snapshot with canceled context should error out
ctx, cancel := context.WithCancel(context.Background())
rc, _ := cli.Snapshot(ctx)
cancel()
_, err := io.Copy(f, rc)
err.Error() == "rpc error: code = Canceled desc = context canceled"

// reading snapshot with deadline exceeded should error out
ctx, cancel = context.WithTimeout(context.Background(), time.Second)
defer cancel()
rc, _ = cli.Snapshot(ctx)
time.Sleep(2 * time.Second)
_, err = io.Copy(f, rc)
err.Error() == "rpc error: code = DeadlineExceeded desc = context deadline exceeded"

変更後

import "context"

// reading snapshot with canceled context should error out
ctx, cancel := context.WithCancel(context.Background())
rc, _ := cli.Snapshot(ctx)
cancel()
_, err := io.Copy(f, rc)
err == context.Canceled

// reading snapshot with deadline exceeded should error out
ctx, cancel = context.WithTimeout(context.Background(), time.Second)
defer cancel()
rc, _ = cli.Snapshot(ctx)
time.Sleep(2 * time.Second)
_, err = io.Copy(f, rc)
err == context.DeadlineExceeded

etcdctl lease timetoliveコマンドの出力の変更

以前は、有効期限切れのリースに対してlease timetolive LEASE_IDコマンドを実行すると、残り秒数として-1sが表示されていました。3.3では、より明確なメッセージを出力します。

変更前

lease 2d8257079fa1bc0c granted with TTL(0s), remaining(-1s)

変更後

lease 2d8257079fa1bc0c already expired

golang.org/x/net/contextのインポートの変更

clientv3ではgolang.org/x/net/contextが非推奨となりました。プロジェクトが他のコード(etcdが生成したprotocol bufferコードなど)にgolang.org/x/net/contextを取り込み、github.com/coreos/etcd/clientv3をインポートしている場合、コンパイルにはGo 1.9+が必要です。

変更前

import "golang.org/x/net/context"
cli.Put(context.Background(), "f", "v")

変更後

import "context"
cli.Put(context.Background(), "f", "v")

gRPC依存関係の変更

3.3では、grpc/grpc-go のv1.7.5が必要になりました。

grpclog.Loggerの非推奨化

grpclog.Loggerは非推奨となり、代わりにgrpclog.LoggerV2 を使用します。clientv3.Loggerはgrpclog.LoggerV2になりました。

変更前

import "github.com/coreos/etcd/clientv3"
clientv3.SetLogger(log.New(os.Stderr, "grpc: ", 0))

変更後

import "github.com/coreos/etcd/clientv3"
import "google.golang.org/grpc/grpclog"
clientv3.SetLogger(grpclog.NewLoggerV2(os.Stderr, os.Stderr, os.Stderr))

// log.New above cannot be used (not implement grpclog.LoggerV2 interface)
grpc.ErrClientConnTimeoutの非推奨化

以前は、クライアントの接続タイムアウト時にgrpc.ErrClientConnTimeoutエラーが返されていました。3.3では代わりにcontext.DeadlineExceededを返します(#8504 を参照)。

変更前

// expect dial time-out on ipv4 blackhole
_, err := clientv3.New(clientv3.Config{
    Endpoints:   []string{"http://254.0.0.1:12345"},
    DialTimeout: 2 * time.Second
})
if err == grpc.ErrClientConnTimeout {
	// handle errors
}

変更後

_, err := clientv3.New(clientv3.Config{
    Endpoints:   []string{"http://254.0.0.1:12345"},
    DialTimeout: 2 * time.Second
})
if err == context.DeadlineExceeded {
	// handle errors
}

公式コンテナーレジストリの変更

etcdは、主なコンテナーレジストリとしてgcr.io/etcd-development/etcd を、補助のレジストリとしてquay.io/coreos/etcd を使用するようになりました。

変更前

docker pull quay.io/coreos/etcd:v3.2.5

変更後

docker pull gcr.io/etcd-development/etcd:v3.3.0

>= v3.3.14へのアップグレード

v3.3.14 では、クライアントバランサーの実装の差異を最小限に抑えるため、3.4の一部の機能を取り込む必要がありました。このリリースでは、「最初のetcd-serverが利用できないとkube-apiserver 1.13.xが動作しない」(kubernetes#72102) を修正しています。

grpc.ErrClientConnClosingはgRPC >= 1.10で非推奨になりました 。

import (
+	"go.etcd.io/etcd/clientv3"

	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
)

_, err := kvc.Get(ctx, "a")
-if err == grpc.ErrClientConnClosing {
+if clientv3.IsConnCanceled(err) {

// or
+s, ok := status.FromError(err)
+if ok {
+  if s.Code() == codes.Canceled

新しいクライアントバランサー は、非同期リゾルバーを使用してgRPCの接続関数にエンドポイントを渡します。そのため、v3.3.14 以降では、基盤となる接続の確立を待つために、接続オプションgrpc.WithBlockが必要です。

import (
	"time"
	"go.etcd.io/etcd/clientv3"
+	"google.golang.org/grpc"
)

+// "grpc.WithBlock()" to block until the underlying connection is up
ccfg := clientv3.Config{
  Endpoints:            []string{"localhost:2379"},
  DialTimeout:          time.Second,
+ DialOptions:          []grpc.DialOption{grpc.WithBlock()},
  DialKeepAliveTime:    time.Second,
  DialKeepAliveTimeout: 500 * time.Millisecond,
}

変更の全一覧は、CHANGELOG を参照してください。

サーバーアップグレードのチェックリスト

アップグレードの要件

既存のetcd環境を3.3にアップグレードするには、稼働中のクラスターが3.2以降でなければなりません。3.2より前の場合は、3.3にアップグレードする前に3.2にアップグレード してください。

また、ローリングアップグレードを円滑に進めるには、稼働中のクラスターが正常でなければなりません。作業を進める前に、etcdctl endpoint healthコマンドでクラスターの正常性を確認してください。

準備

etcdをアップグレードする際は、必ず本番環境に適用する前に、etcdに依存するサービスをステージング環境でテストしてください。

作業を始める前に、etcdのデータをバックアップ してください。アップグレードで問題が発生した場合は、このバックアップを使用して元のetcdバージョンにダウングレード できます。snapshotコマンドでバックアップされるのはv3データのみであることに注意してください。v2データについては、v2データストアのバックアップ を参照してください。

バージョンの混在

アップグレード中のetcdクラスターでは、異なるバージョンのetcdメンバーの混在がサポートされ、全メンバーに共通する最も低いバージョンのプロトコルで動作します。すべてのメンバーがバージョン3.3にアップグレードされて初めて、クラスターのアップグレードが完了したと見なされます。内部では、etcdメンバーが相互にネゴシエーションを行ってクラスター全体のバージョンを決定し、そのバージョンによって報告されるバージョンとサポートされる機能が決まります。

制限事項

注:クラスターにv3データしかなく、v2データがない場合、この制限は適用されません。

クラスターが50MBを超えるv2データセットを提供している場合、新しくアップグレードした各メンバーが既存のクラスターに追いつくまでに最大2分かかることがあります。直近のスナップショットのサイズを調べて、データの総量を見積もってください。つまり、各メンバーのアップグレードの間に2分待つのが最も安全です。

データの総量が100MB以上とさらに大きい場合、この1回限りの処理にはより長い時間がかかることがあります。この規模の非常に大きなetcdクラスターを管理している場合は、アップグレード前にetcdチーム までお気軽にお問い合わせください。手順についてアドバイスします。

ダウングレード

すべてのメンバーをv3.3にアップグレードすると、クラスターもv3.3にアップグレードされ、この完了状態からのダウングレードはできません。ただし、1つでもv3.2のメンバーが残っていれば、クラスターとその動作は「v3.2」のままであり、この混在状態からすべてのメンバーでv3.2のetcdバイナリを使用する状態に戻せます。

アップグレード完了後でもクラスターをダウングレードできるように、すべてのetcdメンバーのデータディレクトリをバックアップ してください。

アップグレード手順

この例では、ローカルマシンで稼働する3メンバー構成のv3.2 etcdクラスターをアップグレードする方法を説明します。

1. アップグレード要件の確認

クラスターは正常で、v3.2.xで稼働していますか。

$ ETCDCTL_API=3 etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
localhost:2379 is healthy: successfully committed proposal: took = 6.600684ms
localhost:22379 is healthy: successfully committed proposal: took = 8.540064ms
localhost:32379 is healthy: successfully committed proposal: took = 8.763432ms

$ curl http://localhost:2379/version
{"etcdserver":"3.2.7","etcdcluster":"3.2.0"}

2. 既存のetcdプロセスの停止

各etcdプロセスを停止すると、他のクラスターメンバーに想定どおりのエラーが記録されます。クラスターメンバーへの接続が(一時的に)切断されたためであり、正常な動作です。

14:13:31.491746 I | raft: c89feb932daef420 [term 3] received MsgTimeoutNow from 6d4f535bae3ab960 and starts an election to get leadership.
14:13:31.491769 I | raft: c89feb932daef420 became candidate at term 4
14:13:31.491788 I | raft: c89feb932daef420 received MsgVoteResp from c89feb932daef420 at term 4
14:13:31.491797 I | raft: c89feb932daef420 [logterm: 3, index: 9] sent MsgVote request to 6d4f535bae3ab960 at term 4
14:13:31.491805 I | raft: c89feb932daef420 [logterm: 3, index: 9] sent MsgVote request to 9eda174c7df8a033 at term 4
14:13:31.491815 I | raft: raft.node: c89feb932daef420 lost leader 6d4f535bae3ab960 at term 4
14:13:31.524084 I | raft: c89feb932daef420 received MsgVoteResp from 6d4f535bae3ab960 at term 4
14:13:31.524108 I | raft: c89feb932daef420 [quorum:2] has received 2 MsgVoteResp votes and 0 vote rejections
14:13:31.524123 I | raft: c89feb932daef420 became leader at term 4
14:13:31.524136 I | raft: raft.node: c89feb932daef420 elected leader c89feb932daef420 at term 4
14:13:31.592650 W | rafthttp: lost the TCP streaming connection with peer 6d4f535bae3ab960 (stream MsgApp v2 reader)
14:13:31.592825 W | rafthttp: lost the TCP streaming connection with peer 6d4f535bae3ab960 (stream Message reader)
14:13:31.693275 E | rafthttp: failed to dial 6d4f535bae3ab960 on stream Message (dial tcp [::1]:2380: getsockopt: connection refused)
14:13:31.693289 I | rafthttp: peer 6d4f535bae3ab960 became inactive
14:13:31.936678 W | rafthttp: lost the TCP streaming connection with peer 6d4f535bae3ab960 (stream Message writer)

問題が発生した場合にダウングレードできるよう、この時点でetcdのデータをバックアップ することをお勧めします。

$ etcdctl snapshot save backup.db

3. etcd v3.3バイナリへの置き換えと新しいetcdプロセスの起動

新しいv3.3のetcdは、自身の情報をクラスターに公開します。

14:14:25.363225 I | etcdserver: published {Name:s1 ClientURLs:[http://localhost:2379]} to cluster a9ededbffcb1b1f1

新しいv3.3のetcdバイナリで、各メンバー、続いてクラスター全体が正常になることを確認してください。

$ ETCDCTL_API=3 /etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
localhost:22379 is healthy: successfully committed proposal: took = 5.540129ms
localhost:32379 is healthy: successfully committed proposal: took = 7.321771ms
localhost:2379 is healthy: successfully committed proposal: took = 10.629901ms

クラスター全体のアップグレードが完了するまでは、アップグレード済みのメンバーに次のような警告が記録されます。これは想定された動作で、すべてのetcdクラスターメンバーをv3.3にアップグレードすると表示されなくなります。

14:15:17.071804 W | etcdserver: member c89feb932daef420 has a higher version 3.3.0
14:15:21.073110 W | etcdserver: the local etcd version 3.2.7 is not up-to-date
14:15:21.073142 W | etcdserver: member 6d4f535bae3ab960 has a higher version 3.3.0
14:15:21.073157 W | etcdserver: the local etcd version 3.2.7 is not up-to-date
14:15:21.073164 W | etcdserver: member c89feb932daef420 has a higher version 3.3.0

4. 残りのすべてのメンバーで手順2から手順3を繰り返す

5. 完了

すべてのメンバーのアップグレードが完了すると、クラスターは3.3へのアップグレードが成功したことを報告します。

14:15:54.536901 N | etcdserver/membership: updated the cluster version from 3.2 to 3.3
14:15:54.537035 I | etcdserver/api: enabled capabilities for version 3.3
$ ETCDCTL_API=3 /etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
localhost:2379 is healthy: successfully committed proposal: took = 2.312897ms
localhost:22379 is healthy: successfully committed proposal: took = 2.553476ms
localhost:32379 is healthy: successfully committed proposal: took = 2.517902ms

7 - etcdを3.1から3.2にアップグレード

etcdを3.1から3.2にアップグレードする手順、チェックリスト、注意事項

通常、etcd 3.1から3.2へのアップグレードは、停止時間なしのローリングアップグレードで実行できます。

  • etcd v3.1のプロセスを1つずつ停止し、etcd v3.2のプロセスに置き換えます。
  • すべてのプロセスがv3.2で稼働すると、クラスターでv3.2の新機能を利用できます。

アップグレードを開始する 前に、このガイドの残りを読んで準備してください。

アップグレードのチェックリスト

警告

v3データのないv2から移行する 場合、v3のETCD_DATA_DIR/member/snap/dbファイルがない状態で既存のスナップショットからリストアすると、etcdサーバーv3.2+でパニックが発生します。これは、以前のv3データがないままサーバーをv2から移行した場合に起こります。この動作は、v3データの意図しない消失(たとえばdbファイルが移動された場合)を防ぐ役割も果たします。etcdでは、v3への移行後はv3データが存在する場合にのみ、さらに移行を進められます。v3.0サーバーにv3データが存在するまでは、それより新しいv3バージョンにアップグレードしないでください。

3.2の主な互換性を損なう変更は次のとおりです。

snapshot-countのデフォルト値の変更

--snapshot-countを大きくすると、スナップショットを作成するまでより多くのRaftエントリーをメモリーに保持するため、メモリー使用量が繰り返し増大 します。リーダーが最新のRaftエントリーをより長く保持するので、遅いフォロワーはリーダーのスナップショット作成前に追いつくための時間を多く確保できます。--snapshot-countは、メモリー使用量の増加と遅いフォロワーの可用性向上とのトレードオフです。

v3.2以降、--snapshot-countのデフォルト値は10,000から100,000に変更されました 。

gRPC依存関係の変更(>=3.2.10)

3.2.10以降では、grpc/grpc-go のv1.7.5が必要になりました(<=3.2.9ではv1.2.1が必要です)。

grpclog.Loggerの非推奨化

grpclog.Loggerは非推奨となり、代わりにgrpclog.LoggerV2 を使用します。clientv3.Loggerはgrpclog.LoggerV2になりました。

変更前

import "github.com/coreos/etcd/clientv3"
clientv3.SetLogger(log.New(os.Stderr, "grpc: ", 0))

変更後

import "github.com/coreos/etcd/clientv3"
import "google.golang.org/grpc/grpclog"
clientv3.SetLogger(grpclog.NewLoggerV2(os.Stderr, os.Stderr, os.Stderr))

// log.New above cannot be used (not implement grpclog.LoggerV2 interface)
grpc.ErrClientConnTimeoutの非推奨化

以前は、クライアントの接続タイムアウト時にgrpc.ErrClientConnTimeoutエラーが返されていました。3.2では代わりにcontext.DeadlineExceededを返します(#8504 を参照)。

変更前

// expect dial time-out on ipv4 blackhole
_, err := clientv3.New(clientv3.Config{
    Endpoints:   []string{"http://254.0.0.1:12345"},
    DialTimeout: 2 * time.Second
})
if err == grpc.ErrClientConnTimeout {
	// handle errors
}

変更後

_, err := clientv3.New(clientv3.Config{
    Endpoints:   []string{"http://254.0.0.1:12345"},
    DialTimeout: 2 * time.Second
})
if err == context.DeadlineExceeded {
	// handle errors
}

リクエストの最大サイズ制限の変更(>=3.2.10)

3.2.10と3.2.11では、サーバー側のリクエストサイズ制限をカスタマイズできます。>=3.2.12では、サーバー側とクライアント側の両方でリクエストサイズ制限をカスタマイズできます。以前のバージョン(v3.2.10、v3.2.11)では、クライアントのレスポンスサイズはわずか4 MiBに制限されていました。

サーバー側のリクエスト制限は、--max-request-bytesフラグで設定できます。

# limits request size to 1.5 KiB
etcd --max-request-bytes 1536

# client writes exceeding 1.5 KiB will be rejected
etcdctl put foo [LARGE VALUE...]
# etcdserver: request is too large

または、embed.Config.MaxRequestBytesフィールドで設定します。

import "github.com/coreos/etcd/embed"
import "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"

// limit requests to 5 MiB
cfg := embed.NewConfig()
cfg.MaxRequestBytes = 5 * 1024 * 1024

// client writes exceeding 5 MiB will be rejected
_, err := cli.Put(ctx, "foo", [LARGE VALUE...])
err == rpctypes.ErrRequestTooLarge

指定しない場合、サーバー側の制限のデフォルトは1.5 MiBです。

クライアント側のリクエスト制限は、サーバー側の制限に基づいて設定しなければなりません。

# limits request size to 1 MiB
etcd --max-request-bytes 1048576
import "github.com/coreos/etcd/clientv3"

cli, _ := clientv3.New(clientv3.Config{
    Endpoints: []string{"127.0.0.1:2379"},
    MaxCallSendMsgSize: 2 * 1024 * 1024,
    MaxCallRecvMsgSize: 3 * 1024 * 1024,
})


// client writes exceeding "--max-request-bytes" will be rejected from etcd server
_, err := cli.Put(ctx, "foo", strings.Repeat("a", 1*1024*1024+5))
err == rpctypes.ErrRequestTooLarge


// client writes exceeding "MaxCallSendMsgSize" will be rejected from client-side
_, err = cli.Put(ctx, "foo", strings.Repeat("a", 5*1024*1024))
err.Error() == "rpc error: code = ResourceExhausted desc = grpc: trying to send message larger than max (5242890 vs. 2097152)"


// some writes under limits
for i := range []int{0,1,2,3,4} {
    _, err = cli.Put(ctx, fmt.Sprintf("foo%d", i), strings.Repeat("a", 1*1024*1024-500))
    if err != nil {
        panic(err)
    }
}
// client reads exceeding "MaxCallRecvMsgSize" will be rejected from client-side
_, err = cli.Get(ctx, "foo", clientv3.WithPrefix())
err.Error() == "rpc error: code = ResourceExhausted desc = grpc: received message larger than max (5240509 vs. 3145728)"

指定しない場合、クライアント側の送信制限のデフォルトは2 MiB(1.5 MiB + gRPCのオーバーヘッド分のバイト数)、受信制限のデフォルトはmath.MaxInt32です。詳細はclientv3 godoc を参照してください。

低水準gRPCクライアントラッパーの変更

3.2.12以降では、clientv3のgRPCクライアントラッパーの関数シグネチャが変更されています。この変更は、メッセージサイズ制限を指定するカスタムgrpc.CallOption をサポートするために必要でした。

変更前と変更後

-func NewKVFromKVClient(remote pb.KVClient) KV {
+func NewKVFromKVClient(remote pb.KVClient, c *Client) KV {

-func NewClusterFromClusterClient(remote pb.ClusterClient) Cluster {
+func NewClusterFromClusterClient(remote pb.ClusterClient, c *Client) Cluster {

-func NewLeaseFromLeaseClient(remote pb.LeaseClient, keepAliveTimeout time.Duration) Lease {
+func NewLeaseFromLeaseClient(remote pb.LeaseClient, c *Client, keepAliveTimeout time.Duration) Lease {

-func NewMaintenanceFromMaintenanceClient(remote pb.MaintenanceClient) Maintenance {
+func NewMaintenanceFromMaintenanceClient(remote pb.MaintenanceClient, c *Client) Maintenance {

-func NewWatchFromWatchClient(wc pb.WatchClient) Watcher {
+func NewWatchFromWatchClient(wc pb.WatchClient, c *Client) Watcher {

clientv3.Lease.TimeToLive APIの変更

以前は、clientv3.Lease.TimeToLive APIに存在しないリースIDを指定すると、lease.ErrLeaseNotFoundが返されていました。3.2では代わりにレスポンスでTTL=-1を返し、エラーは返しません(#7305 を参照)。

変更前

// when leaseID does not exist
resp, err := TimeToLive(ctx, leaseID)
resp == nil
err == lease.ErrLeaseNotFound

変更後

// when leaseID does not exist
resp, err := TimeToLive(ctx, leaseID)
resp.TTL == -1
err == nil

clientv3.NewFromConfigFileをclientv3.yaml.NewConfigに移動

clientv3.NewFromConfigFileはyaml.NewConfigに移動しました。

変更前

import "github.com/coreos/etcd/clientv3"
clientv3.NewFromConfigFile

変更後

import clientv3yaml "github.com/coreos/etcd/clientv3/yaml"
clientv3yaml.NewConfig

--listen-peer-urlsと--listen-client-urlsの変更

ドメイン名はネットワークインターフェースのバインド先として無効であるため、3.2では--listen-peer-urlsと--listen-client-urlsのドメイン名を拒否するようになりました(3.1では警告の表示のみでした)。これらのURLがscheme://IP:portの正しい形式であることを確認してください。

背景については、issue #6336 を参照してください。

サーバーアップグレードのチェックリスト

アップグレードの要件

既存のetcd環境を3.2にアップグレードするには、稼働中のクラスターが3.1以降でなければなりません。3.1より前の場合は、3.2にアップグレードする前に3.1にアップグレード してください。

また、ローリングアップグレードを円滑に進めるには、稼働中のクラスターが正常でなければなりません。作業を進める前に、etcdctl endpoint healthコマンドでクラスターの正常性を確認してください。

準備

etcdをアップグレードする際は、必ず本番環境に適用する前に、etcdに依存するサービスをステージング環境でテストしてください。

作業を始める前に、etcdのデータをバックアップ してください。アップグレードで問題が発生した場合は、このバックアップを使用して元のetcdバージョンにダウングレード できます。snapshotコマンドでバックアップされるのはv3データのみであることに注意してください。v2データについては、v2データストアのバックアップ を参照してください。

バージョンの混在

アップグレード中のetcdクラスターでは、異なるバージョンのetcdメンバーの混在がサポートされ、全メンバーに共通する最も低いバージョンのプロトコルで動作します。すべてのメンバーがバージョン3.2にアップグレードされて初めて、クラスターのアップグレードが完了したと見なされます。内部では、etcdメンバーが相互にネゴシエーションを行ってクラスター全体のバージョンを決定し、そのバージョンによって報告されるバージョンとサポートされる機能が決まります。

制限事項

注:クラスターにv3データしかなく、v2データがない場合、この制限は適用されません。

クラスターが50MBを超えるv2データセットを提供している場合、新しくアップグレードした各メンバーが既存のクラスターに追いつくまでに最大2分かかることがあります。直近のスナップショットのサイズを調べて、データの総量を見積もってください。つまり、各メンバーのアップグレードの間に2分待つのが最も安全です。

データの総量が100MB以上とさらに大きい場合、この1回限りの処理にはより長い時間がかかることがあります。この規模の非常に大きなetcdクラスターを管理している場合は、アップグレード前にetcdチーム までお気軽にお問い合わせください。手順についてアドバイスします。

ダウングレード

すべてのメンバーをv3.2にアップグレードすると、クラスターもv3.2にアップグレードされ、この完了状態からのダウングレードはできません。ただし、1つでもv3.1のメンバーが残っていれば、クラスターとその動作は「v3.1」のままであり、この混在状態からすべてのメンバーでv3.1のetcdバイナリを使用する状態に戻せます。

アップグレード完了後でもクラスターをダウングレードできるように、すべてのetcdメンバーのデータディレクトリをバックアップ してください。

アップグレード手順

この例では、ローカルマシンで稼働する3メンバー構成のv3.1 etcdクラスターをアップグレードする方法を説明します。

1. アップグレード要件の確認

クラスターは正常で、v3.1.xで稼働していますか。

$ ETCDCTL_API=3 etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
localhost:2379 is healthy: successfully committed proposal: took = 6.600684ms
localhost:22379 is healthy: successfully committed proposal: took = 8.540064ms
localhost:32379 is healthy: successfully committed proposal: took = 8.763432ms

$ curl http://localhost:2379/version
{"etcdserver":"3.1.7","etcdcluster":"3.1.0"}

2. 既存のetcdプロセスの停止

各etcdプロセスを停止すると、他のクラスターメンバーに想定どおりのエラーが記録されます。クラスターメンバーへの接続が(一時的に)切断されたためであり、正常な動作です。

2017-04-27 14:13:31.491746 I | raft: c89feb932daef420 [term 3] received MsgTimeoutNow from 6d4f535bae3ab960 and starts an election to get leadership.
2017-04-27 14:13:31.491769 I | raft: c89feb932daef420 became candidate at term 4
2017-04-27 14:13:31.491788 I | raft: c89feb932daef420 received MsgVoteResp from c89feb932daef420 at term 4
2017-04-27 14:13:31.491797 I | raft: c89feb932daef420 [logterm: 3, index: 9] sent MsgVote request to 6d4f535bae3ab960 at term 4
2017-04-27 14:13:31.491805 I | raft: c89feb932daef420 [logterm: 3, index: 9] sent MsgVote request to 9eda174c7df8a033 at term 4
2017-04-27 14:13:31.491815 I | raft: raft.node: c89feb932daef420 lost leader 6d4f535bae3ab960 at term 4
2017-04-27 14:13:31.524084 I | raft: c89feb932daef420 received MsgVoteResp from 6d4f535bae3ab960 at term 4
2017-04-27 14:13:31.524108 I | raft: c89feb932daef420 [quorum:2] has received 2 MsgVoteResp votes and 0 vote rejections
2017-04-27 14:13:31.524123 I | raft: c89feb932daef420 became leader at term 4
2017-04-27 14:13:31.524136 I | raft: raft.node: c89feb932daef420 elected leader c89feb932daef420 at term 4
2017-04-27 14:13:31.592650 W | rafthttp: lost the TCP streaming connection with peer 6d4f535bae3ab960 (stream MsgApp v2 reader)
2017-04-27 14:13:31.592825 W | rafthttp: lost the TCP streaming connection with peer 6d4f535bae3ab960 (stream Message reader)
2017-04-27 14:13:31.693275 E | rafthttp: failed to dial 6d4f535bae3ab960 on stream Message (dial tcp [::1]:2380: getsockopt: connection refused)
2017-04-27 14:13:31.693289 I | rafthttp: peer 6d4f535bae3ab960 became inactive
2017-04-27 14:13:31.936678 W | rafthttp: lost the TCP streaming connection with peer 6d4f535bae3ab960 (stream Message writer)

問題が発生した場合にダウングレードできるよう、この時点でetcdのデータをバックアップ することをお勧めします。

$ etcdctl snapshot save backup.db

3. etcd v3.2バイナリへの置き換えと新しいetcdプロセスの起動

新しいv3.2のetcdは、自身の情報をクラスターに公開します。

2017-04-27 14:14:25.363225 I | etcdserver: published {Name:s1 ClientURLs:[http://localhost:2379]} to cluster a9ededbffcb1b1f1

新しいv3.2のetcdバイナリで、各メンバー、続いてクラスター全体が正常になることを確認してください。

$ ETCDCTL_API=3 /etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
localhost:22379 is healthy: successfully committed proposal: took = 5.540129ms
localhost:32379 is healthy: successfully committed proposal: took = 7.321771ms
localhost:2379 is healthy: successfully committed proposal: took = 10.629901ms

クラスター全体のアップグレードが完了するまでは、アップグレード済みのメンバーに次のような警告が記録されます。これは想定された動作で、すべてのetcdクラスターメンバーをv3.2にアップグレードすると表示されなくなります。

2017-04-27 14:15:17.071804 W | etcdserver: member c89feb932daef420 has a higher version 3.2.0
2017-04-27 14:15:21.073110 W | etcdserver: the local etcd version 3.1.7 is not up-to-date
2017-04-27 14:15:21.073142 W | etcdserver: member 6d4f535bae3ab960 has a higher version 3.2.0
2017-04-27 14:15:21.073157 W | etcdserver: the local etcd version 3.1.7 is not up-to-date
2017-04-27 14:15:21.073164 W | etcdserver: member c89feb932daef420 has a higher version 3.2.0

4. 残りのすべてのメンバーで手順2から手順3を繰り返す

5. 完了

すべてのメンバーのアップグレードが完了すると、クラスターは3.2へのアップグレードが成功したことを報告します。

2017-04-27 14:15:54.536901 N | etcdserver/membership: updated the cluster version from 3.1 to 3.2
2017-04-27 14:15:54.537035 I | etcdserver/api: enabled capabilities for version 3.2
$ ETCDCTL_API=3 /etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
localhost:2379 is healthy: successfully committed proposal: took = 2.312897ms
localhost:22379 is healthy: successfully committed proposal: took = 2.553476ms
localhost:32379 is healthy: successfully committed proposal: took = 2.517902ms

8 - etcdを3.0から3.1にアップグレード

etcdを3.0から3.1にアップグレードする手順、チェックリスト、注意事項

通常、etcd 3.0から3.1へのアップグレードは、停止時間なしのローリングアップグレードで実行できます。

  • etcd v3.0のプロセスを1つずつ停止し、etcd v3.1のプロセスに置き換えます。
  • すべてのプロセスがv3.1で稼働すると、クラスターでv3.1の新機能を利用できます。

アップグレードを開始する 前に、このガイドの残りを読んで準備してください。

アップグレードのチェックリスト

警告

v3データのないv2から移行する 場合、v3のETCD_DATA_DIR/member/snap/dbファイルがない状態で既存のスナップショットからリストアすると、etcdサーバーv3.2+でパニックが発生します。これは、以前のv3データがないままサーバーをv2から移行した場合に起こります。この動作は、v3データの意図しない消失(たとえばdbファイルが移動された場合)を防ぐ役割も果たします。etcdでは、v3への移行後はv3データが存在する場合にのみ、さらに移行を進められます。v3.0サーバーにv3データが存在するまでは、それより新しいv3バージョンにアップグレードしないでください。

監視

v3.0.xの次のメトリクスは非推奨となり、go-grpc-prometheus に置き換えられました。

  • etcd_grpc_requests_total
  • etcd_grpc_requests_failed_total
  • etcd_grpc_active_streams
  • etcd_grpc_unary_requests_duration_seconds

アップグレードの要件

既存のetcd環境を3.1にアップグレードするには、稼働中のクラスターが3.0以降でなければなりません。3.0より前の場合は、3.1にアップグレードする前に3.0にアップグレード してください。

また、ローリングアップグレードを円滑に進めるには、稼働中のクラスターが正常でなければなりません。作業を進める前に、etcdctl endpoint healthコマンドでクラスターの正常性を確認してください。

準備

etcdをアップグレードする際は、必ず本番環境に適用する前に、etcdに依存するサービスをステージング環境でテストしてください。

作業を始める前に、etcdのデータをバックアップ してください。アップグレードで問題が発生した場合は、このバックアップを使用して元のetcdバージョンにダウングレード できます。snapshotコマンドでバックアップされるのはv3データのみであることに注意してください。v2データについては、v2データストアのバックアップ を参照してください。

バージョンの混在

アップグレード中のetcdクラスターでは、異なるバージョンのetcdメンバーの混在がサポートされ、全メンバーに共通する最も低いバージョンのプロトコルで動作します。すべてのメンバーがバージョン3.1にアップグレードされて初めて、クラスターのアップグレードが完了したと見なされます。内部では、etcdメンバーが相互にネゴシエーションを行ってクラスター全体のバージョンを決定し、そのバージョンによって報告されるバージョンとサポートされる機能が決まります。

制限事項

注:クラスターにv3データしかなく、v2データがない場合、この制限は適用されません。

クラスターが50MBを超えるv2データセットを提供している場合、新しくアップグレードした各メンバーが既存のクラスターに追いつくまでに最大2分かかることがあります。直近のスナップショットのサイズを調べて、データの総量を見積もってください。つまり、各メンバーのアップグレードの間に2分待つのが最も安全です。

データの総量が100MB以上とさらに大きい場合、この1回限りの処理にはより長い時間がかかることがあります。この規模の非常に大きなetcdクラスターを管理している場合は、アップグレード前にetcdチーム までお気軽にお問い合わせください。手順についてアドバイスします。

ダウングレード

すべてのメンバーをv3.1にアップグレードすると、クラスターもv3.1にアップグレードされ、この完了状態からのダウングレードはできません。ただし、1つでもv3.0のメンバーが残っていれば、クラスターとその動作は「v3.0」のままであり、この混在状態からすべてのメンバーでv3.0のetcdバイナリを使用する状態に戻せます。

アップグレード完了後でもクラスターをダウングレードできるように、すべてのetcdメンバーのデータディレクトリをバックアップ してください。

アップグレード手順

この例では、ローカルマシンで稼働する3メンバー構成のv3.0 etcdクラスターをアップグレードする方法を説明します。

1. アップグレード要件の確認

クラスターは正常で、v3.0.xで稼働していますか。

$ ETCDCTL_API=3 etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
localhost:2379 is healthy: successfully committed proposal: took = 6.600684ms
localhost:22379 is healthy: successfully committed proposal: took = 8.540064ms
localhost:32379 is healthy: successfully committed proposal: took = 8.763432ms

$ curl http://localhost:2379/version
{"etcdserver":"3.0.16","etcdcluster":"3.0.0"}

2. 既存のetcdプロセスの停止

各etcdプロセスを停止すると、他のクラスターメンバーに想定どおりのエラーが記録されます。クラスターメンバーへの接続が(一時的に)切断されたためであり、正常な動作です。

2017-01-17 09:34:18.352662 I | raft: raft.node: 1640829d9eea5cfb elected leader 1640829d9eea5cfb at term 5
2017-01-17 09:34:18.359630 W | etcdserver: failed to reach the peerURL(http://localhost:2380) of member fd32987dcd0511e0 (Get http://localhost:2380/version: dial tcp 127.0.0.1:2380: getsockopt: connection refused)
2017-01-17 09:34:18.359679 W | etcdserver: cannot get the version of member fd32987dcd0511e0 (Get http://localhost:2380/version: dial tcp 127.0.0.1:2380: getsockopt: connection refused)
2017-01-17 09:34:18.548116 W | rafthttp: lost the TCP streaming connection with peer fd32987dcd0511e0 (stream Message writer)
2017-01-17 09:34:19.147816 W | rafthttp: lost the TCP streaming connection with peer fd32987dcd0511e0 (stream MsgApp v2 writer)
2017-01-17 09:34:34.364907 W | etcdserver: failed to reach the peerURL(http://localhost:2380) of member fd32987dcd0511e0 (Get http://localhost:2380/version: dial tcp 127.0.0.1:2380: getsockopt: connection refused)

問題が発生した場合にダウングレードできるよう、この時点でetcdのデータをバックアップ することをお勧めします。

$ etcdctl snapshot save backup.db

3. etcd v3.1バイナリへの置き換えと新しいetcdプロセスの起動

新しいv3.1のetcdは、自身の情報をクラスターに公開します。

2017-01-17 09:36:00.996590 I | etcdserver: published {Name:my-etcd-1 ClientURLs:[http://localhost:2379]} to cluster 46bc3ce73049e678

新しいv3.1のetcdバイナリで、各メンバー、続いてクラスター全体が正常になることを確認してください。

$ ETCDCTL_API=3 /etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
localhost:22379 is healthy: successfully committed proposal: took = 5.540129ms
localhost:32379 is healthy: successfully committed proposal: took = 7.321671ms
localhost:2379 is healthy: successfully committed proposal: took = 10.629901ms

クラスター全体のアップグレードが完了するまでは、アップグレード済みのメンバーに次のような警告が記録されます。これは想定された動作で、すべてのetcdクラスターメンバーをv3.1にアップグレードすると表示されなくなります。

2017-01-17 09:36:38.406268 W | etcdserver: the local etcd version 3.0.16 is not up-to-date
2017-01-17 09:36:38.406295 W | etcdserver: member fd32987dcd0511e0 has a higher version 3.1.0
2017-01-17 09:36:42.407695 W | etcdserver: the local etcd version 3.0.16 is not up-to-date
2017-01-17 09:36:42.407730 W | etcdserver: member fd32987dcd0511e0 has a higher version 3.1.0

4. 残りのすべてのメンバーで手順2から手順3を繰り返す

5. 完了

すべてのメンバーのアップグレードが完了すると、クラスターは3.1へのアップグレードが成功したことを報告します。

2017-01-17 09:37:03.100015 I | etcdserver: updating the cluster version from 3.0 to 3.1
2017-01-17 09:37:03.104263 N | etcdserver/membership: updated the cluster version from 3.0 to 3.1
2017-01-17 09:37:03.104374 I | etcdserver/api: enabled capabilities for version 3.1
$ ETCDCTL_API=3 /etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379
localhost:2379 is healthy: successfully committed proposal: took = 2.312897ms
localhost:22379 is healthy: successfully committed proposal: took = 2.553476ms
localhost:32379 is healthy: successfully committed proposal: took = 2.516902ms

9 - etcdを2.3から3.0にアップグレード

etcdを2.3から3.0にアップグレードする手順、チェックリスト、注意事項

通常、etcd 2.3から3.0へのアップグレードは、停止時間なしのローリングアップグレードで実行できます。

  • etcd v2.3のプロセスを1つずつ停止し、etcd v3.0のプロセスに置き換えます。
  • すべてのプロセスがv3.0で稼働すると、クラスターでv3.0の新機能を利用できます。

アップグレードを開始する 前に、このガイドの残りを読んで準備してください。

アップグレードのチェックリスト

警告

v3データのないv2から移行する 場合、v3のETCD_DATA_DIR/member/snap/dbファイルがない状態で既存のスナップショットからリストアすると、etcdサーバーv3.2+でパニックが発生します。これは、以前のv3データがないままサーバーをv2から移行した場合に起こります。この動作は、v3データの意図しない消失(たとえばdbファイルが移動された場合)を防ぐ役割も果たします。etcdでは、v3への移行後はv3データが存在する場合にのみ、さらに移行を進められます。v3.0サーバーにv3データが存在するまでは、それより新しいv3バージョンにアップグレードしないでください。

アップグレードの要件

既存のetcd環境を3.0にアップグレードするには、稼働中のクラスターが2.3以降でなければなりません。2.3より前の場合は、3.0にアップグレードする前に2.3 にアップグレードしてください。

また、ローリングアップグレードを円滑に進めるには、稼働中のクラスターが正常でなければなりません。作業を進める前に、etcdctl cluster-healthコマンドでクラスターの正常性を確認してください。

準備

etcdをアップグレードする際は、必ず本番環境に適用する前に、etcdに依存するサービスをステージング環境でテストしてください。

作業を始める前に、etcdのデータディレクトリをバックアップ してください。アップグレードで問題が発生した場合は、このバックアップを使用して元のetcdバージョンにダウングレード できます。

バージョンの混在

アップグレード中のetcdクラスターでは、異なるバージョンのetcdメンバーの混在がサポートされ、全メンバーに共通する最も低いバージョンのプロトコルで動作します。すべてのメンバーがバージョン3.0にアップグレードされて初めて、クラスターのアップグレードが完了したと見なされます。内部では、etcdメンバーが相互にネゴシエーションを行ってクラスター全体のバージョンを決定し、そのバージョンによって報告されるバージョンとサポートされる機能が決まります。

制限事項

データの総量が50MBを超える場合、新しくアップグレードしたメンバーが既存のクラスターに追いつくまでに最大2分かかることがあります。直近のスナップショットのサイズを調べて、データの総量を見積もってください。つまり、各メンバーのアップグレードの間に2分待つのが最も安全です。

データの総量が100MB以上とさらに大きい場合、この1回限りの処理にはより長い時間がかかることがあります。この規模の非常に大きなetcdクラスターを管理している場合は、アップグレード前にetcdチーム までお気軽にお問い合わせください。手順についてアドバイスします。

ダウングレード

すべてのメンバーをv3.0にアップグレードすると、クラスターもv3.0にアップグレードされ、この完了状態からのダウングレードはできません。ただし、1つでもv2.3のメンバーが残っていれば、クラスターとその動作は「v2.3」のままであり、この混在状態からすべてのメンバーでv2.3のetcdバイナリを使用する状態に戻せます。

アップグレード完了後でもクラスターをダウングレードできるように、すべてのetcdメンバーのデータディレクトリをバックアップ してください。

アップグレード手順

この例では、ローカルマシンで稼働する3メンバー構成のv2.3 etcdクラスターをアップグレードする手順を詳しく説明します。

1. アップグレード要件の確認

クラスターは正常で、v.2.3.xで稼働していますか。

$ etcdctl cluster-health
member 6e3bd23ae5f1eae0 is healthy: got healthy result from http://localhost:22379
member 924e2e83e93f2560 is healthy: got healthy result from http://localhost:32379
member 8211f1d0f64f3269 is healthy: got healthy result from http://localhost:12379
cluster is healthy

$ curl http://localhost:2379/version
{"etcdserver":"2.3.x","etcdcluster":"2.3.8"}

2. 既存のetcdプロセスの停止

各etcdプロセスを停止すると、他のクラスターメンバーに想定どおりのエラーが記録されます。クラスターメンバーへの接続が(一時的に)切断されたためであり、正常な動作です。

2016-06-27 15:21:48.624124 E | rafthttp: failed to dial 8211f1d0f64f3269 on stream Message (dial tcp 127.0.0.1:12380: getsockopt: connection refused)
2016-06-27 15:21:48.624175 I | rafthttp: the connection with 8211f1d0f64f3269 became inactive

問題が発生した場合にダウングレードできるよう、この時点でetcdのデータディレクトリをバックアップ することをお勧めします。

$ etcdctl backup \
      --data-dir /var/lib/etcd \
      --backup-dir /tmp/etcd_backup

3. etcd v3.0バイナリへの置き換えと新しいetcdプロセスの起動

新しいv3.0のetcdは、自身の情報をクラスターに公開します。

09:58:25.938673 I | etcdserver: published {Name:infra1 ClientURLs:[http://localhost:12379]} to cluster 524400597fb1d5f6

新しいv3.0のetcdバイナリで、各メンバー、続いてクラスター全体が正常になることを確認してください。

$ etcdctl cluster-health
member 6e3bd23ae5f1eae0 is healthy: got healthy result from http://localhost:22379
member 924e2e83e93f2560 is healthy: got healthy result from http://localhost:32379
member 8211f1d0f64f3269 is healthy: got healthy result from http://localhost:12379
cluster is healthy

クラスター全体のアップグレードが完了するまでは、アップグレード済みのメンバーに次のような警告が記録されます。これは想定された動作で、すべてのetcdクラスターメンバーをv3.0にアップグレードすると表示されなくなります。

2016-06-27 15:22:05.679644 W | etcdserver: the local etcd version 2.3.7 is not up-to-date
2016-06-27 15:22:05.679660 W | etcdserver: member 8211f1d0f64f3269 has a higher version 3.0.0

4. 残りのすべてのメンバーで手順2から手順3を繰り返す

5. 完了

すべてのメンバーのアップグレードが完了すると、クラスターは3.0へのアップグレードが成功したことを報告します。

2016-06-27 15:22:19.873751 N | membership: updated the cluster version from 2.3 to 3.0
2016-06-27 15:22:19.914574 I | api: enabled capabilities for version 3.0.0
$ ETCDCTL_API=3 etcdctl endpoint health
127.0.0.1:12379 is healthy: successfully committed proposal: took = 18.440155ms
127.0.0.1:32379 is healthy: successfully committed proposal: took = 13.651368ms
127.0.0.1:22379 is healthy: successfully committed proposal: took = 18.513301ms

その他の考慮事項

  • etcdctlの環境変数が更新されています。ETCDCTL_API=2 etcdctl cluster-healthは正常に動作するのに、ETCDCTL_API=3 etcdctl endpoints healthがError: grpc: timed out when dialingを返す場合は、必ず新しい変数名 を使用してください。

既知の問題

  • etcd < v3.1は、Go > v1.7でビルドすると正常に動作しません。詳細はIssue 6951 を参照してください。
  • etcdサーバーのログにtransport: http2Client.notifyError got notified that the client transport was broken unexpected EOF.などのエラーが表示される場合は、ビルド済みのリリース、または(etcd v3.1+ & go v1.7+)もしくは(etcd <v3.1 & go v1.6.x)でビルドしたetcdを使用していることを確認してください。
  • アップグレード中にv2.3クラスターへv3ノードを追加することはサポートされておらず、パニックを引き起こす可能性があります。詳細はIssue 7249 を参照してください。etcdメンバーのバージョン混在が許可されるのは、v3への移行中のみです。メンバー構成を変更する前に、アップグレードを完了してください。