diff --git a/.wordlist.txt b/.wordlist.txt index 867d87c..e94f932 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -196,6 +196,7 @@ OpenID openjdk ORA oras +osscluster OSSF permalink PKI @@ -206,6 +207,7 @@ pollInterval pprof PR preimage +prepended prometheus PRs pulledWithin @@ -214,6 +216,7 @@ pushedWithin Qualys rc README +redis regclient regctl regionendpoint diff --git a/docs/articles/clustering.md b/docs/articles/clustering.md index da0244f..8b82b48 100644 --- a/docs/articles/clustering.md +++ b/docs/articles/clustering.md @@ -145,10 +145,10 @@ backend zot-instance3 -### zot S3 configuration +### zot S3 configuration with DynamoDB
- Click here to view a sample zot configuration for S3. + Click here to view a sample zot configuration for S3 and DynamoDB. ```json @@ -157,6 +157,7 @@ backend zot-instance3 "storage": { "rootDirectory": "/tmp/zot", "dedupe": false, + "remoteCache": true, "storageDriver": { "name": "s3", "rootdirectory": "/zot", @@ -183,3 +184,47 @@ backend zot-instance3 ```
+ +### zot S3 configuration with Redis + +Multiple zot instances can share the same S3 `storageDriver` and Redis `cacheDriver` configurations. +The Redis server, DB, and `keyprefix` must match for all zot instances. + +While the Redis `cacheDriver` implementation does support local storage, zot clustering with Redis is only supported for S3. + +
+ Click here to view a sample zot configuration for S3 and Redis. + +```json + +{ + "distSpecVersion": "1.0.1-dev", + "storage": { + "rootDirectory": "/tmp/zot", + "dedupe": false, + "remoteCache": true, + "storageDriver": { + "name": "s3", + "rootdirectory": "/zot", + "region": "us-east-2", + "bucket": "zot-storage", + "secure": true, + "skipverify": false + }, + "cacheDriver": { + "name": "redis", + "url": "redis://host:6379", + "keyprefix": "zot" + } + }, + "http": { + "address": "127.0.0.1", + "port": "8080" + }, + "log": { + "level": "debug" + } +} + +``` +
\ No newline at end of file diff --git a/docs/articles/storage.md b/docs/articles/storage.md index 57723da..5f4cd37 100644 --- a/docs/articles/storage.md +++ b/docs/articles/storage.md @@ -389,7 +389,7 @@ To use [DynamoDB](https://aws.amazon.com/dynamodb/) as the cache driver, the fol "cacheDriver": { "name": "dynamodb", // driver name "endpoint": "http://localhost:4566", // aws endpoint - "region": "us-east-2" // aws region + "region": "us-east-2", // aws region "cacheTablename": "ZotBlobTable" // table to store deduped blobs } }, @@ -441,6 +441,109 @@ The following AWS policy is required by zot for caching blobs. For more details about configuring AWS DynamoDB, see the [AWS documentation](https://docs.aws.amazon.com/dynamodb/). +### Redis + +[Redis](https://redis.io/) is an alternative to BoltDB (which cannot be shared by multiple zot instances) and DynamoDB (which requires access to AWS). + +To use Redis as the cache driver, the following storage configuration must be present: + +- `remoteCache` is enabled +- `cacheDriver` attribute is configured as in the following example: + +```json + "storage": { + "rootDirectory": "/tmp/zot", + "remoteCache": true, + "cacheDriver": { + "name": "redis", + "url": "redis://localhost:6379", + "keyprefix": "zot" + } + }, +``` + +The cache driver name `redis` selects the Redis driver implementation. + +The key `keyprefix` is a string prepended to all Redis keys created by this zot instance. If no string is specified, the default value is `zot`. +If multiple zot instances share the same Redis database and storage, `keyprefix` should be the same in all their configurations. +If multiple zot instances share the same Redis database, but have different storage locations containing different images, `keyprefix` should be different in all their configurations. + +The `url` string can contain query parameters for various settings, and it can be used for both Redis single instance and cluster configurations. +More details on how `url` is parsed are available at: +- https://github.com/redis/go-redis/blob/v9.7.0/options.go#L247 +- https://github.com/redis/go-redis/blob/v9.7.0/osscluster.go#L144 + +At this time the library we import for `url` parsing does not support Redis sentry. For this reason we also support passing the parameters individually as keys in the same `cacheDriver` map. +If and only if the `url` setting is missing, the other parameters are read from `cacheDriver`. +The keys are the same as the attributes that would otherwise be included in the `url`. + +In the case of a Redis Sentinel setup, you would need to add each key manually in the `cacheDriver` map and make sure to specify +a `master_name` key, see https://github.com/redis/go-redis/blob/v9.7.0/universal.go#L240 + +#### Redis cluster configuration + +The following storage configuration is for a Redis cluster: + +```json + "storage": { + "rootDirectory": "/tmp/zot", + "remoteCache": true, + "cacheDriver": { + "name": "redis", + "url": "redis://user:password@host1:6379?addr=host2:6379&addr=host3:6379", + "keyprefix": "zot" + } + } +``` + +#### Add Redis configuration parameters + +The following storage configuration contains all Redis parameters: + +```json + "storage": { + "rootDirectory": "/tmp/zot", + "remoteCache": true, + "cacheDriver": { + "name": "redis", + "keyprefix": "zot", + "addr": ["host1:6379", "host2:6379", "host3:6379"], + "client_name": "client", + "db": 1, + "protocol": 3, + "username": "user1", + "password": "pass1", + "sentinel_username": "user2", + "sentinel_password": "pass2", + "max_retries": 3, + "min_retry_backoff": "5s", + "max_retry_backoff": "5s", + "dial_timeout": "5s", + "read_timeout": "5s", + "write_timeout": "5s", + "context_timeout_enabled": false, + "pool_fifo": false, + "pool_size": 3, + "pool_timeout": "5s", + "min_idle_conns": 1, + "max_idle_conns": 3, + "max_active_conns": 3, + "conn_max_idle_time": "5s", + "conn_max_lifetime": "5s", + "max_redirects": 3, + "read_only": false, + "route_by_latency": false, + "route_randomly": false, + "master_name": "zotmeta", + "disable_identity": false, + "identity_suffix": "zotmeta", + "unstable_resp3": false + }, + } +``` + +> :warning: setting all of the parameters above for the same use case does not make sense, as some parameters for single instance, cluster and sentry configurations exclude one another. + ## Remote storage subpaths As in the case with local filesystem storage, you can use multiple remote storage locations using the `subpath` attribute, as in the following example.