|
| 1 | +--- |
| 2 | +title: microshift-router-configuration-errors-logging |
| 3 | +authors: |
| 4 | + - "@pacevedom" |
| 5 | +reviewers: |
| 6 | + - "@eslutsky" |
| 7 | + - "@copejon" |
| 8 | + - "@ggiguash" |
| 9 | + - "@pmtk" |
| 10 | + - "@pliurh" |
| 11 | + - "@Miciah" |
| 12 | +approvers: |
| 13 | + - "@jerpeter1" |
| 14 | +api-approvers: |
| 15 | + - None |
| 16 | +creation-date: 2025-04-24 |
| 17 | +last-updated: 2025-05-09 |
| 18 | +tracking-link: |
| 19 | + - https://issues.redhat.com/browse/USHIFT-4092 |
| 20 | +--- |
| 21 | + |
| 22 | +# MicroShift router errors and logging configuration options |
| 23 | + |
| 24 | +## Summary |
| 25 | +MicroShift's default router is created as part of the platform, but does not |
| 26 | +allow configuring some of its specific parameters. For example, you cannot |
| 27 | +configure custom behavior with error pages, or whether headers and cookies are |
| 28 | +captured in the access logs. |
| 29 | + |
| 30 | +In order to allow these operations and more, a set of configuration options is |
| 31 | +proposed. |
| 32 | + |
| 33 | +## Motivation |
| 34 | +Microshift Customers need a way to override the default Ingress Controller |
| 35 | +logging configuration similar as OpenShift does. |
| 36 | + |
| 37 | +### User Stories |
| 38 | +* As a MicroShift admin, I want to configure custom error code pages in the |
| 39 | + router. |
| 40 | +* As a MicroShift admin, I want to enable/disable access logging in the |
| 41 | + router. |
| 42 | +* As a MicroShift admin, I want to configure which HTTP headers are captured |
| 43 | + in the access logs. |
| 44 | +* As a MicroShift admin, I want to configure which HTTP cookies are captured |
| 45 | + in the access logs. |
| 46 | + |
| 47 | +### Goals |
| 48 | +Allow users to configure the additional Router customization parameters. |
| 49 | + |
| 50 | +### Non-Goals |
| 51 | +N/A |
| 52 | + |
| 53 | +## Proposal |
| 54 | +Microshift doesn't use [ingress operator](https://github.com/openshift/cluster-ingress-operator), |
| 55 | +which means all the customization is performed through the configuration file. |
| 56 | +The configuration will propagate to the router deployment [manifest](https://github.com/openshift/microshift/blob/aea40ae1ee66dc697996c309268be1939b018f56/assets/components/openshift-router/deployment.yaml) through environment variables, just like what the ingress operator does. |
| 57 | + |
| 58 | +See the API Extensions section to check the details. |
| 59 | + |
| 60 | +See full [OpenShift Router](https://docs.openshift.com/container-platform/4.18/networking/ingress-operator.html) |
| 61 | +configuration reference for more information. |
| 62 | + |
| 63 | +### Workflow Description |
| 64 | +***configuring errors and logging options*** |
| 65 | +1. The cluster admin adds specific configuration for the router prior to |
| 66 | + MicroShift's start. |
| 67 | +2. After MicroShift starts, the system will read the configuration and setup |
| 68 | + the router according to it. |
| 69 | + |
| 70 | +### API Extensions |
| 71 | +As mentioned in the proposal, there is an entire new section in the configuration: |
| 72 | +```yaml |
| 73 | +ingress: |
| 74 | + httpErrorCodePages: |
| 75 | + name: <string> |
| 76 | + accessLogging: |
| 77 | + status: <Enabled|Disabled> |
| 78 | + format: <string> |
| 79 | + destination: |
| 80 | + type: <Container|Syslog> |
| 81 | + container: |
| 82 | + maxLength: <int> |
| 83 | + syslog: |
| 84 | + address: <ip address> |
| 85 | + facility: <string> |
| 86 | + maxLength: <int> |
| 87 | + port: <int> |
| 88 | + httpCaptureHeaders: |
| 89 | + request: |
| 90 | + - maxLength: <integer> |
| 91 | + name: <string> |
| 92 | + response: |
| 93 | + - maxLength: <integer> |
| 94 | + name: <string> |
| 95 | + httpCaptureCookies: |
| 96 | + - matchType: <Exact|Prefix> |
| 97 | + maxLength: <integer> |
| 98 | + name: <string> |
| 99 | + namePrefix: <string> |
| 100 | +``` |
| 101 | +
|
| 102 | +For more information check each individual section. |
| 103 | +
|
| 104 | +#### Hypershift / Hosted Control Planes |
| 105 | +N/A |
| 106 | +### Topology Considerations |
| 107 | +N/A |
| 108 | +
|
| 109 | +#### Standalone Clusters |
| 110 | +N/A |
| 111 | +
|
| 112 | +#### Single-node Deployments or MicroShift |
| 113 | +Enhancement is solely intended for MicroShift. |
| 114 | +
|
| 115 | +### Implementation Details/Notes/Constraints |
| 116 | +The default router is composed of a bunch of assets that are embedded as part |
| 117 | +of the MicroShift binary. These assets come from the rebase, copied from the |
| 118 | +original router in [cluster-ingress-operator](https://github.com/openshift/cluster-ingress-operator). |
| 119 | +
|
| 120 | +Based on the configuration parameters, the manifest for the router pod will |
| 121 | +mutate to translate all the new options. |
| 122 | +
|
| 123 | +#### Enabling access logging |
| 124 | +TODO reword this. |
| 125 | +HAProxy allows configuration for access logging. This happens through rsyslog, |
| 126 | +which needs to be running in an endpoints. Options for this are discussed below. |
| 127 | +
|
| 128 | +The second container (named `access-log`) will print through stdout all the |
| 129 | +logs from the router. |
| 130 | + |
| 131 | +This approach does not require configuring rsyslogd in the host and is self |
| 132 | +contained, not dedicating any resources in case it is not enabled. |
| 133 | + |
| 134 | +Configuring either of `ingress.accessLogging.httpCaptureHeaders` or |
| 135 | +`ingress.accessLogging.httpCaptureCookies` will also enable `ingress.accessLogging.status`. |
| 136 | + |
| 137 | +`ingress.accessLogging.status` defaults to `Disabled`. |
| 138 | + |
| 139 | +##### Access logging destination |
| 140 | +There are two supported ways of configuring the destination: container or |
| 141 | +remote. |
| 142 | + |
| 143 | +These are configured by means of `ingress.accessLogging.destination.type`, |
| 144 | +which is an enum accepting either `Container` or `Syslog`. |
| 145 | +If `ingress.accessLogging.status` is `Enabled` it defaults to `Container`. |
| 146 | + |
| 147 | +`Container` destination type configuration: |
| 148 | +* `maxLength`: maximum length of the log message. Range between 480 and 8192. |
| 149 | + Defaults to 1024. Optional. |
| 150 | + |
| 151 | +`Syslog` destination type configuration: |
| 152 | +* `address`: IP address of the syslog endpoint that receives log messages. |
| 153 | + Required. |
| 154 | +* `port`: UDP port number of the syslog endpoint that receives log messages. |
| 155 | + Required. |
| 156 | +* `facility`: Syslog facility of log messages. If empty it will default to |
| 157 | + `local1`. Allowed values: `kern;user;mail;daemon;auth;syslog;lpr;news;uucp;cron;auth2;ftp;ntp;audit;alert;cron2;local0;local1;local2;local3;local4;local5;local6;local7`. |
| 158 | + Optional. |
| 159 | +* `maxLength`: maximum length of the log message. Range between 480 and 8192. |
| 160 | + Defaults to 1024. Optional. |
| 161 | + |
| 162 | +#### Configuring access log format |
| 163 | +`ingress.accessLogging.format` specifies the format of the log message for an |
| 164 | +HTTP request. If this field is empty, log messages use the implementation's |
| 165 | +default HTTP log format, which is described [here](http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#8.2.3). |
| 166 | + |
| 167 | +Note that this format only applies to cleartext and encryption terminated |
| 168 | +requests. |
| 169 | + |
| 170 | +#### Configuring custom error code pages |
| 171 | +To configure custom error code pages the user needs to specify a configmap name |
| 172 | +in `ingress.httpErrorCodePages.name`. This configmap must be in the |
| 173 | +`openshift-config` namespace and should have keys in the format of |
| 174 | +`error-page-<error code>.http` where `<error code>` is an HTTP status code. |
| 175 | + |
| 176 | +Each value in the configmap should be the full response, including HTTP |
| 177 | +headers. |
| 178 | + |
| 179 | +As of today, only errors for 503 and 404 can be customized. |
| 180 | + |
| 181 | +`ingress.httpErrorCodePages.name` defaults to empty. |
| 182 | + |
| 183 | +#### Capturing headers |
| 184 | +To configure specific HTTP header capture so they are included in the access |
| 185 | +logs the user needs to create entries in `ingress.accessLogging.httpCaptureHeaders`. |
| 186 | +This field is a list and allows capturing request and response headers |
| 187 | +independently. Each of the entries in the list has different parameters that |
| 188 | +follow. If the list is empty (which is the default value) no headers will be |
| 189 | +captured. |
| 190 | + |
| 191 | +This option only applies to cleartext HTTP or reencrypt connections. Headers |
| 192 | +can not be captured for TLS passthrough connections. |
| 193 | + |
| 194 | +Each element of the list includes: |
| 195 | +* `request`. Specifies which HTTP request headers to capture. If this field is |
| 196 | + empty, no request headers are captured. |
| 197 | +* `response`. Specifies which HTTP response headers to capture. If this field |
| 198 | + is empty, no request headers are captured. |
| 199 | + |
| 200 | +Both elements have the same fields: |
| 201 | +* `maxLength`. Specifies a maximum length for the header value. If a header |
| 202 | + value exceeds this length, the value will be truncated in the log message. Minimum value 1. |
| 203 | +* `name`. Specifies a header name. Its value must be a valid HTTP header name |
| 204 | + as defined in RFC 2616 section 4.2. String regex ```^[-!#$%&'*+.0-9A-Z^_`a-z|~]+$```. |
| 205 | + |
| 206 | +If configured, it is mandatory to include at least `maxLength` and `name`. |
| 207 | + |
| 208 | +`ingress.accessLogging.httpCaptureHeaders` defaults to an empty list. |
| 209 | + |
| 210 | +#### Capturing cookies |
| 211 | +To configure specific HTTP cookie capture so they are included in the access |
| 212 | +logs the user needs to create an entry in `ingress.accessLogging.httpCaptureCookies`. |
| 213 | +This field is a list (limited to 1 element) which includes information on which |
| 214 | +cookie to capture. If the list is empty (which is the default value) no cookies |
| 215 | +will be captured. |
| 216 | + |
| 217 | +In each element of the list we find: |
| 218 | +* `matchType`. Specifies the type of match to perform against the cookie name. |
| 219 | + Allowed values are `Exact` and `Prefix`. |
| 220 | +* `maxLength`. Specifies a maximum length of the string that will be logged, |
| 221 | + which includes the cookie name, cookie value, and one-character delimiter. |
| 222 | + If the log entry exceeds this length, the value will be truncated in the log |
| 223 | + message. Minimum value 1, maximum value 1024. |
| 224 | +* `name`. Specifies a cookie name. It must be a valid HTTP cookie name as |
| 225 | + defined in RFC 6265 section 4.1. String regex ```^[-!#$%&'*+.0-9A-Z^_`a-z|~]*$```. |
| 226 | + Minimum length 0, maximum length 1024. |
| 227 | +* `namePrefix`. Specifies a cookie name prefix. It must be a valid HTTP cookie |
| 228 | + name as defined in RFC 6265 section 4.1. String regex ```^[-!#$%&'*+.0-9A-Z^_`a-z|~]*$```. |
| 229 | + Minimum length 0, maximum length 1024. |
| 230 | + |
| 231 | +If configured, it is mandatory to include at least `matchType` and `maxLength`. |
| 232 | + |
| 233 | +`ingress.accessLogging.httpCaptureCookies` defaults to an empty list. |
| 234 | + |
| 235 | +#### How config options change manifests |
| 236 | +Each of the configuration options described above has a direct effect on the |
| 237 | +manifests that MicroShift will apply after starting. |
| 238 | +See the full Implementation details in the [router-configuration](microshift-router-configuration.md) |
| 239 | +enhancement. |
| 240 | + |
| 241 | +### Risks and Mitigations |
| 242 | +* Not configuring custom error pages will return the default ones, which are |
| 243 | + usually empty and only return the http status code. |
| 244 | +* Not configuring capture of http headers and/or cookies will not include them |
| 245 | + in the access logs of the router. |
| 246 | + |
| 247 | +### Drawbacks |
| 248 | +N/A |
| 249 | + |
| 250 | +## Open Questions |
| 251 | +N/A |
| 252 | + |
| 253 | +## Test Plan |
| 254 | +All configuration changes will be included in already existing e2e router |
| 255 | +tests. Testing router functionality is out of scope of this enhancement. |
| 256 | + |
| 257 | + |
| 258 | +## Graduation Criteria |
| 259 | +Not applicable |
| 260 | + |
| 261 | +### Dev Preview -> Tech Preview |
| 262 | +- Ability to utilize the enhancement end to end |
| 263 | +- End user documentation, relative API stability |
| 264 | +- Sufficient test coverage |
| 265 | + |
| 266 | +### Tech Preview -> GA |
| 267 | +- More testing (upgrade, downgrade) |
| 268 | +- Sufficient time for feedback |
| 269 | +- Available by default |
| 270 | +- User facing documentation created in [openshift-docs](https://github.com/openshift/openshift-docs/) |
| 271 | + |
| 272 | +### Removing a deprecated feature |
| 273 | +N/A |
| 274 | + |
| 275 | +## Upgrade / Downgrade Strategy |
| 276 | +When upgrading from 4.19 or earlier the new configuration fields will remain |
| 277 | +unset, causing the existing defaults to be used. |
| 278 | + |
| 279 | +When downgrading from 4.20 to earlier versions the new parameters will be |
| 280 | +ignored. |
| 281 | + |
| 282 | +## Version Skew Strategy |
| 283 | +N/A |
| 284 | + |
| 285 | +## Operational Aspects of API Extensions |
| 286 | + |
| 287 | +### Failure Modes |
| 288 | +N/A |
| 289 | + |
| 290 | +## Support Procedures |
| 291 | +Access logging, if enabled, will be part of the logs of the openshift-router |
| 292 | +logs. Logs from this pod are captured in the already existing sos report |
| 293 | +procedure available for MicroShift. |
| 294 | + |
| 295 | +## Implementation History |
| 296 | +Implementation [PR](https://github.com/openshift/microshift/pull/4474/) for Micorshift |
| 297 | +## Alternatives (Not Implemented) |
| 298 | +N/A |
0 commit comments