Skip to content

Commit 155c4a3

Browse files
committed
docs: clarify the distinction between Velero BSL spec and S3 driver parameters for CA certificate handling
Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
1 parent 7d3e245 commit 155c4a3

File tree

1 file changed

+70
-23
lines changed

1 file changed

+70
-23
lines changed

docs/config/ca-certificate-bundle-for-imagestream-backups.md

Lines changed: 70 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,26 @@ OADP/Velero supports CA certificates through **two independent mechanisms**:
8888
| **ImageStream backups** | ✅ Works (requires `AWS_CA_BUNDLE`) | ❌ Fails with custom CAs |
8989
| **Velero BSL validation** | Uses `AWS_CA_BUNDLE` (overrides BSL `caCert`) via velero-plugin-for-aws | Uses BSL `caCert` via velero-plugin-for-aws |
9090

91-
**Why both mechanisms exist**: The BSL `caCert` field is passed by Velero to plugins, but docker-distribution S3 driver operates in openshift-velero-plugin context and can only read from `AWS_CA_BUNDLE` environment variable pointing to a mounted file. When `AWS_CA_BUNDLE` is set, the AWS SDK reads it at session creation and overrides any BSL `caCert` configuration for all AWS SDK operations (including BSL validation via velero-plugin-for-aws).
91+
**Why both mechanisms exist**:
92+
93+
The BSL `caCert` field is a **Velero BackupStorageLocation spec field**, but it's not an **S3 storage driver parameter**. Here's the critical distinction:
94+
95+
- **Velero BSL spec**: Contains fields like `caCert`, `bucket`, `region`, etc.
96+
- **S3 driver parameters**: The subset of configuration passed to the S3 storage driver (bucket, credentials, region, endpoint)
97+
- **S3 driver does NOT have a `caCert` parameter** - it has no way to receive CA certificates via configuration
98+
99+
When openshift-velero-plugin calls the docker-distribution S3 driver:
100+
1. It passes S3 driver parameters (bucket, region, credentials) extracted from BSL
101+
2. The S3 driver creates an AWS SDK session using these parameters
102+
3. The AWS SDK reads `AWS_CA_BUNDLE` from the **process environment** (not from driver parameters)
103+
4. There's no path to pass BSL `caCert` to the S3 driver - it must come from environment
104+
105+
When `AWS_CA_BUNDLE` is set in the Velero pod environment, the AWS SDK reads it at session creation and uses it for **all** AWS SDK operations, including:
106+
- ImageStream backups (via docker-distribution S3 driver)
107+
- BSL validation (via velero-plugin-for-aws)
108+
- Regular Velero backups (via velero-plugin-for-aws)
109+
110+
This is why `AWS_CA_BUNDLE` **overrides** BSL `caCert` for velero-plugin-for-aws when both are present.
92111

93112
### backupImages Control Field
94113

@@ -238,14 +257,16 @@ ImageStream backups involve a chain of components that work together to copy con
238257
239258
240259
┌─────────────────────────────────────────────────────────────────┐
241-
│ 4. openshift/docker-distribution
260+
│ 4. openshift/docker-distribution S3 Driver
242261
│ (github.com/openshift/docker-distribution) │
243262
│ │
244263
│ - OpenShift fork of distribution/distribution │
245264
│ - Container image distribution library │
265+
│ - Uses AWS SDK Go v1 (github.com/aws/aws-sdk-go v1.43.16) │
246266
│ - S3 storage driver: registry/storage/driver/s3-aws/s3.go │
247-
│ - Creates AWS SDK sessions for S3 operations │
248-
│ - Reads AWS_CA_BUNDLE environment variable at session init │
267+
│ - Creates AWS SDK sessions via session.NewSessionWithOptions │
268+
│ - AWS SDK automatically reads AWS_CA_BUNDLE env variable │
269+
│ during session initialization (built-in SDK behavior) │
249270
│ - Configures custom CA certificates for TLS verification │
250271
│ - Performs actual image layer upload/download operations │
251272
└─────────────────────────────────────────────────────────────────┘
@@ -296,29 +317,55 @@ ImageStream backups involve a chain of components that work together to copy con
296317

297318
### Code References
298319

299-
#### 1. OpenShift Velero Plugin - ImageStream Shared Code
300-
301-
- Location: [`openshift-velero-plugin/velero-plugins/imagestream/shared.go:57`](https://github.com/openshift/openshift-velero-plugin/blob/64292f953c3e2ecd623e9388b2a65c08bb9cfbe2/velero-plugins/imagestream/shared.go#L57)
302-
- This code initiates the imagestream backup and relies on environment variables for configuration
303-
304-
#### 2. Docker Distribution S3 Driver
305-
306-
- Location: [`openshift/docker-distribution/registry/storage/driver/s3-aws/s3.go`](https://github.com/openshift/docker-distribution/blob/release-4.19/registry/storage/driver/s3-aws/s3.go)
307-
- The S3 driver reads `AWS_CA_BUNDLE` from environment and configures AWS SDK accordingly
308-
- This is where the actual S3 operations happen for copying image layers
309-
310-
#### 3. AWS SDK Environment Configuration
311-
312-
- Location: [`aws-sdk-go-v2/config/env_config.go:176-192`](https://github.com/aws/aws-sdk-go-v2/blob/1c707a7bc6b5b0bba75e5643d9e3be2f3f779bc1/config/env_config.go#L176-L192)
313-
- AWS SDK reads `AWS_CA_BUNDLE` environment variable
314-
- Loads custom CA certificates for TLS validation
315-
- Merges custom CAs into HTTP client's Transport
316-
317-
#### 4. OADP Controller Implementation
320+
#### 1. OpenShift Velero Plugin - ImageStream Backup
321+
322+
- **Backup**: [`openshift-velero-plugin/velero-plugins/imagestream/backup.go`](https://github.com/openshift/openshift-velero-plugin/blob/master/velero-plugins/imagestream/backup.go)
323+
- Calls `GetUdistributionTransportForLocation()` to create udistribution transport
324+
- Passes transport to `imagecopy.CopyLocalImageStreamImages()` for image copying
325+
- **Shared Code**: [`openshift-velero-plugin/velero-plugins/imagestream/shared.go`](https://github.com/openshift/openshift-velero-plugin/blob/master/velero-plugins/imagestream/shared.go)
326+
- `GetRegistryEnvsForLocation()` retrieves **S3 storage driver parameters** from BSL and converts to env var strings
327+
- Storage driver parameters include: credentials, bucket, region, endpoint, etc.
328+
- `GetUdistributionTransportForLocation()` calls `udistribution.NewTransportFromNewConfig(config, envs)`
329+
- **Key distinction**: BSL has `caCert` field (Velero spec), but this is NOT an S3 driver parameter
330+
- **`AWS_CA_BUNDLE`** comes from Velero pod's environment (set by OADP controller), not from BSL storage config
331+
332+
#### 2. udistribution Client Library
333+
334+
- **Transport Creation**: [`migtools/udistribution/pkg/image/udistribution/docker_transport.go`](https://github.com/migtools/udistribution/blob/main/pkg/image/udistribution/docker_transport.go)
335+
- `NewTransportFromNewConfig(config, envs)` creates transport with client
336+
- Calls `client.NewClient(config, envs)` to initialize
337+
- **Client Initialization**: [`migtools/udistribution/pkg/client/client.go`](https://github.com/migtools/udistribution/blob/main/pkg/client/client.go)
338+
- `NewClient(config, envs)` parses configuration using `uconfiguration.ParseEnvironment(config, envs)`
339+
- Creates `handlers.App` which initializes storage drivers
340+
- **Key point**: Environment variables in `envs` parameter are **S3 storage driver parameters only**
341+
- S3 driver parameters do NOT include CA certificates - the S3 driver has no `caCert` parameter
342+
- `AWS_CA_BUNDLE` must already exist in the **process environment** from Velero pod
343+
- **Purpose**: Wraps distribution/distribution to provide programmatic storage driver access without HTTP server
344+
345+
#### 3. Docker Distribution S3 Driver
346+
347+
- **S3 Driver**: [`openshift/docker-distribution/registry/storage/driver/s3-aws/s3.go:559`](https://github.com/openshift/docker-distribution/blob/release-4.19/registry/storage/driver/s3-aws/s3.go#L559)
348+
- Creates AWS SDK session via `session.NewSessionWithOptions(sessionOptions)`
349+
- AWS SDK v1 (`github.com/aws/aws-sdk-go v1.43.16`) automatically reads environment variables during session initialization
350+
- The S3 driver itself does NOT directly read `AWS_CA_BUNDLE` - this is handled by the AWS SDK
351+
- **Session Creation**: AWS SDK's built-in environment variable loading includes `AWS_CA_BUNDLE`
352+
353+
#### 4. AWS SDK v1 Environment Configuration
354+
355+
- **Session Package**: [`aws-sdk-go/aws/session/env_config.go`](https://github.com/aws/aws-sdk-go/blob/main/aws/session/env_config.go)
356+
- `NewSessionWithOptions()` automatically loads configuration from **process environment variables** (via `os.Getenv`)
357+
- Reads `AWS_CA_BUNDLE` environment variable during session initialization
358+
- Loads custom CA certificates for TLS validation
359+
- Sets the CA bundle as the HTTP client's custom root CA
360+
- **Quote**: "Sets the path to a custom Credentials Authority (CA) Bundle PEM file that the SDK will use instead of the system's root CA bundle"
361+
- **Critical**: AWS SDK reads from process environment, NOT from configuration passed to storage driver
362+
363+
#### 5. OADP Controller Implementation
318364

319365
- Location: `internal/controller/velero.go:443`
320366
- Controls when CA certificate processing occurs based on `dpa.BackupImages()`
321367
- Calls `processCACertificatesForVelero()` only when imagestream backups are enabled
368+
- Mounts CA bundle as file and sets `AWS_CA_BUNDLE` environment variable pointing to it
322369

323370
### Why Different from Regular Velero Backups
324371

0 commit comments

Comments
 (0)