Juliusz Nadberezny created FLINK-40531:
------------------------------------------

             Summary: K8s Operator Autoscaler Parallelism overrides serialized 
in standard-YAML format break the deployed job
                 Key: FLINK-40531
                 URL: https://issues.apache.org/jira/browse/FLINK-40531
             Project: Flink
          Issue Type: Bug
          Components: Autoscaler, Kubernetes Operator
            Reporter: Juliusz Nadberezny


{{Affects unreleased 1.17.0 version}}

{{}}

Flink can write map-valued config settings in two styles: the old {{a:1,b:2}} 
and the newer {{{}{a: '1', b: '2'}{}}}. Every Flink version can read the old 
style; only newer parsers can read the new one.

{{}}

The autoscaler lets Flink choose the style automatically, and that choice 
depends on which config file the operator itself was started with. So if the 
operator runs with {{{}config.yaml{}}}, it writes parallelism overrides in the 
new style into every FlinkDeployment it scales. Any JobManager still reading a 
legacy {{flink-conf.yaml}} then fails to start, because it cannot parse the 
value. The operator itself reports no problem — only the job breaks.



{{KubernetesScalingRealizer}} and the autoscaler state stores serialize the 
parallelism overrides map with {{{}ConfigurationUtils.convertValue(overrides, 
String.class){}}}. The two-arg overload picks its format from 
{{{}GlobalConfiguration.isStandardYaml(){}}}, which is derived from the config 
file the _operator's own JVM_ loaded.

If the operator runs with {{config.yaml}} (standard YAML) instead of 
{{{}flink-conf.yaml{}}}, it writes {{pipeline.jobvertex-parallelism-overrides: 
\{a: '1', b: '2'}}} into every FlinkDeployment it scales. A JobManager loading 
a legacy {{flink-conf.yaml}} cannot parse that and fails on startup with 
{{{}Could not split string. Illegal quoting at position: 5{}}}. The operator 
logs nothing — only the deployed job breaks.

The legacy {{a:1,b:2}} form is parseable by all Flink versions, including 2.x 
(which reads both forms even though it serializes the new one). The flow form 
is not. So serialization should be pinned to the portable format rather than 
inherited from ambient operator state.

Made worse by a self-inflicted trap: {{getOverrideString}} reuses the previous 
string verbatim when the override map is unchanged, to avoid a no-op redeploy. 
That pins a broken string in place permanently, so an affected job cannot 
recover on its own.

*Steps to reproduce*
 # Deploy the operator with {{defaultConfiguration.config.yaml}} instead of 
{{{}flink-conf.yaml{}}}.
 # Let the autoscaler scale a {{v1_20}} FlinkDeployment.
 # Inspect {{spec.flinkConfiguration}} — the override string is {{{...}}} and 
the JobManager crash-loops.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to