feat(inject): Support arbitrary proxy parameters from helm (#12493)

New proxy HTTP2 server parameters can be configured from the environment. These
environment variables take the form:

    LINKERD2_PROXY_[INBOUND|OUTBOUND]_[SERVER]_[HTTP2]_<PARAM>

We want to allow these parameters to be set, i.e., in a values.yaml file without
having to document all of the possible parameters (especially those that
primarily influence internals not exposed to the application).

To accomodate this, this commit introduces generic proxy environment templating
and a test to verify the behavior.

Values like the following:

    proxy:
      inbound:
        scope:
          proto:
            blueberryPi: 3.14
      outbound:
        scope:
          proto:
            applesauce: "valueA"

Manifest as a proxy environment including:

    LINKERD2_PROXY_INBOUND_SCOPE_PROTO_BLUEBERRY_PI="3.14"
    LINKERD2_PROXY_OUTBOUND_SCOPE_PROTO_APPLESAUCE=valueA

That is, Helm value keys are converted to SCREAMING_SNAKE_CASE environment
variable names.
This commit is contained in:
Oliver Gould 2024-04-24 13:55:45 -07:00 committed by GitHub
parent 7545d131cb
commit 9e241a74d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 288 additions and 0 deletions

View File

@ -104,6 +104,17 @@ env:
value: 10000ms
- name: LINKERD2_PROXY_OUTBOUND_CONNECT_KEEPALIVE
value: 10000ms
{{- /* Configure inbound and outbound parameters, e.g. for HTTP/2 servers. */}}
{{ range $proxyK, $proxyV := (dict "inbound" .Values.proxy.inbound "outbound" .Values.proxy.outbound) -}}
{{ range $scopeK, $scopeV := $proxyV -}}
{{ range $protoK, $protoV := $scopeV -}}
{{ range $paramK, $paramV := $protoV -}}
- name: LINKERD2_PROXY_{{snakecase $proxyK | upper}}_{{snakecase $scopeK | upper}}_{{snakecase $protoK | upper}}_{{snakecase $paramK | upper}}
value: {{ quote $paramV }}
{{ end -}}
{{ end -}}
{{ end -}}
{{ end -}}
{{ if .Values.proxy.opaquePorts -}}
- name: LINKERD2_PROXY_INBOUND_PORTS_DISABLE_PROTOCOL_DETECTION
value: {{.Values.proxy.opaquePorts | quote}}

View File

@ -357,6 +357,32 @@ func TestUninjectAndInject(t *testing.T) {
return values
}(),
},
{
inputFileName: "inject_emojivoto_deployment.input.yml",
goldenFileName: "inject_emojivoto_deployment_params.golden.yml",
reportFileName: "inject_emojivoto_deployment.report",
injectProxy: true,
testInjectConfig: func() *linkerd2.Values {
values := defaultConfig()
values.Proxy.Inbound = linkerd2.ProxyParams{
"scope": linkerd2.ProxyScopeParams{
"proto": linkerd2.ProxyProtoParams{
"appleSauce": "valueA",
"blueberry": 3.14,
},
},
}
values.Proxy.Outbound = linkerd2.ProxyParams{
"scope": linkerd2.ProxyScopeParams{
"proto": linkerd2.ProxyProtoParams{
"applesauce": "valueA",
"blueBerry": true,
},
},
}
return values
}(),
},
}
for i, tc := range testCases {
@ -382,6 +408,8 @@ type injectCmd struct {
}
func testInjectCmd(t *testing.T, tc injectCmd) {
t.Helper()
testConfig := tc.values
if testConfig == nil {
var err error

View File

@ -0,0 +1,242 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: emojivoto
spec:
replicas: 1
selector:
matchLabels:
app: web-svc
template:
metadata:
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
linkerd.io/proxy-version: test-inject-proxy-version
linkerd.io/trust-root-sha256: 8dc603abd4e755c25c94da05abbf29b9b283a784733651020d72f97ca8ab98e4
labels:
app: web-svc
linkerd.io/control-plane-ns: linkerd
linkerd.io/proxy-deployment: web
linkerd.io/workload-ns: emojivoto
spec:
containers:
- env:
- name: _pod_name
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: _pod_ns
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: _pod_nodeName
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: LINKERD2_PROXY_LOG
value: warn,linkerd=info,trust_dns=error
- name: LINKERD2_PROXY_LOG_FORMAT
value: plain
- name: LINKERD2_PROXY_DESTINATION_SVC_ADDR
value: linkerd-dst-headless.linkerd.svc.cluster.local.:8086
- name: LINKERD2_PROXY_DESTINATION_PROFILE_NETWORKS
value: 10.0.0.0/8,100.64.0.0/10,172.16.0.0/12,192.168.0.0/16,fd00::/8
- name: LINKERD2_PROXY_POLICY_SVC_ADDR
value: linkerd-policy.linkerd.svc.cluster.local.:8090
- name: LINKERD2_PROXY_POLICY_WORKLOAD
value: |
{"ns":"$(_pod_ns)", "pod":"$(_pod_name)"}
- name: LINKERD2_PROXY_INBOUND_DEFAULT_POLICY
value: all-unauthenticated
- name: LINKERD2_PROXY_POLICY_CLUSTER_NETWORKS
value: 10.0.0.0/8,100.64.0.0/10,172.16.0.0/12,192.168.0.0/16,fd00::/8
- name: LINKERD2_PROXY_CONTROL_STREAM_INITIAL_TIMEOUT
value: 3s
- name: LINKERD2_PROXY_CONTROL_STREAM_IDLE_TIMEOUT
value: 5m
- name: LINKERD2_PROXY_CONTROL_STREAM_LIFETIME
value: 1h
- name: LINKERD2_PROXY_INBOUND_CONNECT_TIMEOUT
value: 100ms
- name: LINKERD2_PROXY_OUTBOUND_CONNECT_TIMEOUT
value: 1000ms
- name: LINKERD2_PROXY_OUTBOUND_DISCOVERY_IDLE_TIMEOUT
value: 5s
- name: LINKERD2_PROXY_INBOUND_DISCOVERY_IDLE_TIMEOUT
value: 90s
- name: LINKERD2_PROXY_CONTROL_LISTEN_ADDR
value: 0.0.0.0:4190
- name: LINKERD2_PROXY_ADMIN_LISTEN_ADDR
value: 0.0.0.0:4191
- name: LINKERD2_PROXY_OUTBOUND_LISTEN_ADDR
value: 127.0.0.1:4140
- name: LINKERD2_PROXY_INBOUND_LISTEN_ADDR
value: 0.0.0.0:4143
- name: LINKERD2_PROXY_INBOUND_IPS
valueFrom:
fieldRef:
fieldPath: status.podIPs
- name: LINKERD2_PROXY_INBOUND_PORTS
value: "80"
- name: LINKERD2_PROXY_DESTINATION_PROFILE_SUFFIXES
value: svc.cluster.local.
- name: LINKERD2_PROXY_INBOUND_ACCEPT_KEEPALIVE
value: 10000ms
- name: LINKERD2_PROXY_OUTBOUND_CONNECT_KEEPALIVE
value: 10000ms
- name: LINKERD2_PROXY_INBOUND_SCOPE_PROTO_APPLE_SAUCE
value: valueA
- name: LINKERD2_PROXY_INBOUND_SCOPE_PROTO_BLUEBERRY
value: "3.14"
- name: LINKERD2_PROXY_OUTBOUND_SCOPE_PROTO_APPLESAUCE
value: valueA
- name: LINKERD2_PROXY_OUTBOUND_SCOPE_PROTO_BLUE_BERRY
value: "true"
- name: LINKERD2_PROXY_INBOUND_PORTS_DISABLE_PROTOCOL_DETECTION
value: 25,587,3306,4444,5432,6379,9300,11211
- name: LINKERD2_PROXY_DESTINATION_CONTEXT
value: |
{"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"}
- name: _pod_sa
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: _l5d_ns
value: linkerd
- name: _l5d_trustdomain
value: cluster.local
- name: LINKERD2_PROXY_IDENTITY_DIR
value: /var/run/linkerd/identity/end-entity
- name: LINKERD2_PROXY_IDENTITY_TRUST_ANCHORS
value: |
-----BEGIN CERTIFICATE-----
MIIBwTCCAWagAwIBAgIQeDZp5lDaIygQ5UfMKZrFATAKBggqhkjOPQQDAjApMScw
JQYDVQQDEx5pZGVudGl0eS5saW5rZXJkLmNsdXN0ZXIubG9jYWwwHhcNMjAwODI4
MDcxMjQ3WhcNMzAwODI2MDcxMjQ3WjApMScwJQYDVQQDEx5pZGVudGl0eS5saW5r
ZXJkLmNsdXN0ZXIubG9jYWwwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARqc70Z
l1vgw79rjB5uSITICUA6GyfvSFfcuIis7B/XFSkkwAHU5S/s1AAP+R0TX7HBWUC4
uaG4WWsiwJKNn7mgo3AwbjAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB
/wIBATAdBgNVHQ4EFgQU5YtjVVPfd7I7NLHsn2C26EByGV0wKQYDVR0RBCIwIIIe
aWRlbnRpdHkubGlua2VyZC5jbHVzdGVyLmxvY2FsMAoGCCqGSM49BAMCA0kAMEYC
IQCN7lBFLDDvjx6V0+XkjpKERRsJYf5adMvnloFl48ilJgIhANtxhndcr+QJPuC8
vgUC0d2/9FMueIVMb+46WTCOjsqr
-----END CERTIFICATE-----
- name: LINKERD2_PROXY_IDENTITY_TOKEN_FILE
value: /var/run/secrets/tokens/linkerd-identity-token
- name: LINKERD2_PROXY_IDENTITY_SVC_ADDR
value: linkerd-identity-headless.linkerd.svc.cluster.local.:8080
- name: LINKERD2_PROXY_IDENTITY_LOCAL_NAME
value: $(_pod_sa).$(_pod_ns).serviceaccount.identity.linkerd.cluster.local
- name: LINKERD2_PROXY_IDENTITY_SVC_NAME
value: linkerd-identity.linkerd.serviceaccount.identity.linkerd.cluster.local
- name: LINKERD2_PROXY_DESTINATION_SVC_NAME
value: linkerd-destination.linkerd.serviceaccount.identity.linkerd.cluster.local
- name: LINKERD2_PROXY_POLICY_SVC_NAME
value: linkerd-destination.linkerd.serviceaccount.identity.linkerd.cluster.local
image: cr.l5d.io/linkerd/proxy:test-inject-proxy-version
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command:
- /usr/lib/linkerd/linkerd-await
- --timeout=2m
- --port=4191
livenessProbe:
httpGet:
path: /live
port: 4191
initialDelaySeconds: 10
timeoutSeconds: 1
name: linkerd-proxy
ports:
- containerPort: 4143
name: linkerd-proxy
- containerPort: 4191
name: linkerd-admin
readinessProbe:
httpGet:
path: /ready
port: 4191
initialDelaySeconds: 2
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 2102
seccompProfile:
type: RuntimeDefault
terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- mountPath: /var/run/linkerd/identity/end-entity
name: linkerd-identity-end-entity
- mountPath: /var/run/secrets/tokens
name: linkerd-identity-token
- env:
- name: WEB_PORT
value: "80"
- name: EMOJISVC_HOST
value: emoji-svc.emojivoto:8080
- name: VOTINGSVC_HOST
value: voting-svc.emojivoto:8080
- name: INDEX_BUNDLE
value: dist/index_bundle.js
image: buoyantio/emojivoto-web:v10
name: web-svc
ports:
- containerPort: 80
name: http
initContainers:
- args:
- --incoming-proxy-port
- "4143"
- --outgoing-proxy-port
- "4140"
- --proxy-uid
- "2102"
- --inbound-ports-to-ignore
- 4190,4191,4567,4568
- --outbound-ports-to-ignore
- 4567,4568
image: cr.l5d.io/linkerd/proxy-init:v2.4.0
imagePullPolicy: IfNotPresent
name: linkerd-init
resources:
limits:
cpu: 100m
memory: 20Mi
requests:
cpu: 100m
memory: 20Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_ADMIN
- NET_RAW
privileged: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65534
seccompProfile:
type: RuntimeDefault
terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- mountPath: /run
name: linkerd-proxy-init-xtables-lock
volumes:
- emptyDir: {}
name: linkerd-proxy-init-xtables-lock
- emptyDir:
medium: Memory
name: linkerd-identity-end-entity
- name: linkerd-identity-token
projected:
sources:
- serviceAccountToken:
audience: identity.l5d.io
expirationSeconds: 86400
path: linkerd-identity-token
---

View File

@ -139,8 +139,15 @@ type (
AdditionalEnv []corev1.EnvVar `json:"additionalEnv"`
ExperimentalEnv []corev1.EnvVar `json:"experimentalEnv"`
Inbound ProxyParams `json:"inbound,omitempty"`
Outbound ProxyParams `json:"outbound,omitempty"`
}
ProxyParams = map[string]ProxyScopeParams
ProxyScopeParams = map[string]ProxyProtoParams
ProxyProtoParams = map[string]interface{}
ProxyControl struct {
Streams *ProxyControlStreams `json:"streams"`
}