CNI add support for priorityClassName (#4742)

* CNI add support for priorityClassName

As requested in #2981 one should be able to optionally define a priorityClassName for the linkerd2 pods.

With this commit support for priorityClassName is added to the CNI plugin helm chart as well as to the
cli command for installing the CNI plugin.

Also added an `installNamespace` Helm option for the CNI installation.

Implements part of #2981.

Signed-off-by: alex.berger@nexiot.ch <alex.berger@nexiot.ch>
This commit is contained in:
Alexander Berger 2020-07-30 17:43:06 +02:00 committed by GitHub
parent 96f662dfac
commit 4ffea3ba08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 241 additions and 3 deletions

View File

@ -30,3 +30,5 @@ and their default values.
|`portsToRedirect` | Ports to redirect to proxy || |`portsToRedirect` | Ports to redirect to proxy ||
|`proxyUID` | User id under which the proxy shall be ran |`2102`| |`proxyUID` | User id under which the proxy shall be ran |`2102`|
|`useWaitFlag` | Configures the CNI plugin to use the -w flag for the iptables command |`false`| |`useWaitFlag` | Configures the CNI plugin to use the -w flag for the iptables command |`false`|
|`installNamespace` | Whether to create the CNI plugin plane namespace or not |`true`|
|`priorityClassName` | Kubernetes priorityClassName for the CNI plugin's Pods ||

View File

@ -17,7 +17,7 @@ limitations under the License.
This file was inspired by This file was inspired by
1) https://github.com/istio/cni/blob/c63a509539b5ed165a6617548c31b686f13c2133/deployments/kubernetes/install/manifests/istio-cni.yaml 1) https://github.com/istio/cni/blob/c63a509539b5ed165a6617548c31b686f13c2133/deployments/kubernetes/install/manifests/istio-cni.yaml
*/ -}} */ -}}
{{- if .Values.installNamespace -}}
kind: Namespace kind: Namespace
apiVersion: v1 apiVersion: v1
metadata: metadata:
@ -28,6 +28,7 @@ metadata:
{{.Values.cniResourceLabel}}: "true" {{.Values.cniResourceLabel}}: "true"
config.linkerd.io/admission-webhooks: disabled config.linkerd.io/admission-webhooks: disabled
--- ---
{{ end -}}
apiVersion: policy/v1beta1 apiVersion: policy/v1beta1
kind: PodSecurityPolicy kind: PodSecurityPolicy
metadata: metadata:
@ -183,6 +184,9 @@ spec:
beta.kubernetes.io/os: linux beta.kubernetes.io/os: linux
hostNetwork: true hostNetwork: true
serviceAccountName: linkerd-cni serviceAccountName: linkerd-cni
{{- if .Values.priorityClassName }}
priorityClassName: {{ .Values.priorityClassName }}
{{- end }}
containers: containers:
# This container installs the linkerd CNI binaries # This container installs the linkerd CNI binaries
# and CNI network config file on each node. The install # and CNI network config file on each node. The install

View File

@ -1,4 +1,5 @@
namespace: linkerd-cni namespace: linkerd-cni
installNamespace: true
cniResourceLabel: linkerd.io/cni-resource cniResourceLabel: linkerd.io/cni-resource
inboundProxyPort: 4143 inboundProxyPort: 4143
outboundProxyPort: 4140 outboundProxyPort: 4140
@ -13,6 +14,7 @@ proxyUID: 2102
destCNINetDir: "/etc/cni/net.d" destCNINetDir: "/etc/cni/net.d"
destCNIBinDir: "/opt/cni/bin" destCNIBinDir: "/opt/cni/bin"
useWaitFlag: false useWaitFlag: false
priorityClassName: ""
# namespace annotation and labels - do not edit # namespace annotation and labels - do not edit
proxyInjectAnnotation: linkerd.io/inject proxyInjectAnnotation: linkerd.io/inject

View File

@ -38,6 +38,8 @@ type cniPluginOptions struct {
destCNINetDir string destCNINetDir string
destCNIBinDir string destCNIBinDir string
useWaitFlag bool useWaitFlag bool
priorityClassName string
installNamespace bool
} }
func (options *cniPluginOptions) validate() error { func (options *cniPluginOptions) validate() error {
@ -102,7 +104,8 @@ assumes that the 'linkerd install' command will be executed with the
cmd.PersistentFlags().StringVar(&options.cniPluginImage, "cni-image", options.cniPluginImage, "Image for the cni-plugin") cmd.PersistentFlags().StringVar(&options.cniPluginImage, "cni-image", options.cniPluginImage, "Image for the cni-plugin")
cmd.PersistentFlags().StringVar(&options.logLevel, "cni-log-level", options.logLevel, "Log level for the cni-plugin") cmd.PersistentFlags().StringVar(&options.logLevel, "cni-log-level", options.logLevel, "Log level for the cni-plugin")
cmd.PersistentFlags().StringVar(&options.destCNINetDir, "dest-cni-net-dir", options.destCNINetDir, "Directory on the host where the CNI configuration will be placed") cmd.PersistentFlags().StringVar(&options.destCNINetDir, "dest-cni-net-dir", options.destCNINetDir, "Directory on the host where the CNI configuration will be placed")
cmd.PersistentFlags().StringVar(&options.destCNIBinDir, "dest-cni-bin-dir", options.destCNIBinDir, "Directory on the host where the CNI plugin binaries reside") cmd.PersistentFlags().StringVar(&options.priorityClassName, "priority-class-name", options.priorityClassName, "Pod priorityClassName for CNI daemonset's pods")
cmd.PersistentFlags().BoolVar(&options.installNamespace, "install-namespace", options.installNamespace, "Whether to create the CNI namespace or not")
cmd.PersistentFlags().BoolVar( cmd.PersistentFlags().BoolVar(
&options.useWaitFlag, &options.useWaitFlag,
"use-wait-flag", "use-wait-flag",
@ -132,6 +135,8 @@ func newCNIInstallOptionsWithDefaults() (*cniPluginOptions, error) {
destCNINetDir: defaults.DestCNINetDir, destCNINetDir: defaults.DestCNINetDir,
destCNIBinDir: defaults.DestCNIBinDir, destCNIBinDir: defaults.DestCNIBinDir,
useWaitFlag: defaults.UseWaitFlag, useWaitFlag: defaults.UseWaitFlag,
priorityClassName: defaults.PriorityClassName,
installNamespace: defaults.InstallNamespace,
}, nil }, nil
} }
@ -166,6 +171,8 @@ func (options *cniPluginOptions) buildValues() (*cnicharts.Values, error) {
installValues.DestCNIBinDir = options.destCNIBinDir installValues.DestCNIBinDir = options.destCNIBinDir
installValues.UseWaitFlag = options.useWaitFlag installValues.UseWaitFlag = options.useWaitFlag
installValues.Namespace = cniNamespace installValues.Namespace = cniNamespace
installValues.PriorityClassName = options.priorityClassName
installValues.InstallNamespace = options.installNamespace
return installValues, nil return installValues, nil
} }

View File

@ -27,6 +27,8 @@ func TestRenderCNIPlugin(t *testing.T) {
logLevel: "debug", logLevel: "debug",
destCNINetDir: "/etc/kubernetes/cni/net.d", destCNINetDir: "/etc/kubernetes/cni/net.d",
destCNIBinDir: "/opt/my-cni/bin", destCNIBinDir: "/opt/my-cni/bin",
priorityClassName: "system-node-critical",
installNamespace: true,
} }
otherNamespace := "other" otherNamespace := "other"
@ -45,6 +47,26 @@ func TestRenderCNIPlugin(t *testing.T) {
logLevel: "debug", logLevel: "debug",
destCNINetDir: "/etc/kubernetes/cni/net.d", destCNINetDir: "/etc/kubernetes/cni/net.d",
destCNIBinDir: "/etc/kubernetes/cni/net.d", destCNIBinDir: "/etc/kubernetes/cni/net.d",
priorityClassName: "system-node-critical",
installNamespace: true,
}
fullyConfiguredOptionsNoNamespace := &cniPluginOptions{
linkerdVersion: "awesome-linkerd-version.1",
dockerRegistry: "gcr.io/linkerd-io",
proxyControlPort: 5190,
proxyAdminPort: 5191,
inboundPort: 5143,
outboundPort: 5140,
ignoreInboundPorts: make([]string, 0),
ignoreOutboundPorts: make([]string, 0),
proxyUID: 12102,
cniPluginImage: "my-docker-registry.io/awesome/cni-plugin-test-image",
logLevel: "debug",
destCNINetDir: "/etc/kubernetes/cni/net.d",
destCNIBinDir: "/opt/my-cni/bin",
priorityClassName: "system-node-critical",
installNamespace: false,
} }
testCases := []struct { testCases := []struct {
@ -55,6 +77,7 @@ func TestRenderCNIPlugin(t *testing.T) {
{defaultOptions, defaultCniNamespace, "install-cni-plugin_default.golden"}, {defaultOptions, defaultCniNamespace, "install-cni-plugin_default.golden"},
{fullyConfiguredOptions, otherNamespace, "install-cni-plugin_fully_configured.golden"}, {fullyConfiguredOptions, otherNamespace, "install-cni-plugin_fully_configured.golden"},
{fullyConfiguredOptionsEqualDsts, otherNamespace, "install-cni-plugin_fully_configured_equal_dsts.golden"}, {fullyConfiguredOptionsEqualDsts, otherNamespace, "install-cni-plugin_fully_configured_equal_dsts.golden"},
{fullyConfiguredOptionsNoNamespace, otherNamespace, "install-cni-plugin_fully_configured_no_namespace.golden"},
} }
for i, tc := range testCases { for i, tc := range testCases {

View File

@ -40,7 +40,8 @@ func TestRenderCniHelm(t *testing.T) {
"destCNINetDir": "/etc/cni/net.d-test", "destCNINetDir": "/etc/cni/net.d-test",
"destCNIBinDir": "/opt/cni/bin-test", "destCNIBinDir": "/opt/cni/bin-test",
"useWaitFlag": true, "useWaitFlag": true,
"cliVersion": "test-version" "cliVersion": "test-version",
"priorityClassName": "system-node-critical"
}` }`
overrideConfig := &pb.Config{Raw: overrideJSON} overrideConfig := &pb.Config{Raw: overrideJSON}

View File

@ -159,6 +159,7 @@ spec:
beta.kubernetes.io/os: linux beta.kubernetes.io/os: linux
hostNetwork: true hostNetwork: true
serviceAccountName: linkerd-cni serviceAccountName: linkerd-cni
priorityClassName: system-node-critical
containers: containers:
# This container installs the linkerd CNI binaries # This container installs the linkerd CNI binaries
# and CNI network config file on each node. The install # and CNI network config file on each node. The install

View File

@ -159,6 +159,7 @@ spec:
beta.kubernetes.io/os: linux beta.kubernetes.io/os: linux
hostNetwork: true hostNetwork: true
serviceAccountName: linkerd-cni serviceAccountName: linkerd-cni
priorityClassName: system-node-critical
containers: containers:
# This container installs the linkerd CNI binaries # This container installs the linkerd CNI binaries
# and CNI network config file on each node. The install # and CNI network config file on each node. The install

View File

@ -0,0 +1,194 @@
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: linkerd-other-cni
labels:
linkerd.io/cni-resource: "true"
spec:
allowPrivilegeEscalation: false
fsGroup:
rule: RunAsAny
hostNetwork: true
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- hostPath
- secret
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: linkerd-cni
namespace: other
labels:
linkerd.io/cni-resource: "true"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: linkerd-cni
namespace: other
labels:
linkerd.io/cni-resource: "true"
rules:
- apiGroups: ['extensions', 'policy']
resources: ['podsecuritypolicies']
resourceNames:
- linkerd-other-cni
verbs: ['use']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: linkerd-cni
namespace: other
labels:
linkerd.io/cni-resource: "true"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: linkerd-cni
subjects:
- kind: ServiceAccount
name: linkerd-cni
namespace: other
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-cni
labels:
linkerd.io/cni-resource: "true"
rules:
- apiGroups: [""]
resources: ["pods", "nodes", "namespaces"]
verbs: ["list", "get", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: linkerd-cni
labels:
linkerd.io/cni-resource: "true"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: linkerd-cni
subjects:
- kind: ServiceAccount
name: linkerd-cni
namespace: other
---
kind: ConfigMap
apiVersion: v1
metadata:
name: linkerd-cni-config
namespace: other
labels:
linkerd.io/cni-resource: "true"
data:
dest_cni_net_dir: "/etc/kubernetes/cni/net.d"
dest_cni_bin_dir: "/opt/my-cni/bin"
# The CNI network configuration to install on each node. The special
# values in this config will be automatically populated.
cni_network_config: |-
{
"name": "linkerd-cni",
"type": "linkerd-cni",
"log_level": "debug",
"policy": {
"type": "k8s",
"k8s_api_root": "https://__KUBERNETES_SERVICE_HOST__:__KUBERNETES_SERVICE_PORT__",
"k8s_auth_token": "__SERVICEACCOUNT_TOKEN__"
},
"kubernetes": {
"kubeconfig": "__KUBECONFIG_FILEPATH__"
},
"linkerd": {
"incoming-proxy-port": 5143,
"outgoing-proxy-port": 5140,
"proxy-uid": 12102,
"ports-to-redirect": [],
"inbound-ports-to-ignore": ["5190","5191"],
"outbound-ports-to-ignore": [],
"simulate": false,
"use-wait-flag": false
}
}
---
kind: DaemonSet
apiVersion: apps/v1
metadata:
name: linkerd-cni
namespace: other
labels:
k8s-app: linkerd-cni
linkerd.io/cni-resource: "true"
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
spec:
selector:
matchLabels:
k8s-app: linkerd-cni
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
k8s-app: linkerd-cni
annotations:
linkerd.io/created-by: linkerd/cli dev-undefined
spec:
nodeSelector:
beta.kubernetes.io/os: linux
hostNetwork: true
serviceAccountName: linkerd-cni
priorityClassName: system-node-critical
containers:
# This container installs the linkerd CNI binaries
# and CNI network config file on each node. The install
# script copies the files into place and then sleeps so
# that Kubernetes doesn't keep trying to restart it.
- name: install-cni
image: my-docker-registry.io/awesome/cni-plugin-test-image:awesome-linkerd-version.1
env:
- name: DEST_CNI_NET_DIR
valueFrom:
configMapKeyRef:
name: linkerd-cni-config
key: dest_cni_net_dir
- name: DEST_CNI_BIN_DIR
valueFrom:
configMapKeyRef:
name: linkerd-cni-config
key: dest_cni_bin_dir
- name: CNI_NETWORK_CONFIG
valueFrom:
configMapKeyRef:
name: linkerd-cni-config
key: cni_network_config
- name: SLEEP
value: "true"
lifecycle:
preStop:
exec:
command: ["kill","-15","1"]
volumeMounts:
- mountPath: /host/opt/my-cni/bin
name: cni-bin-dir
- mountPath: /host/etc/kubernetes/cni/net.d
name: cni-net-dir
volumes:
- name: cni-bin-dir
hostPath:
path: /opt/my-cni/bin
- name: cni-net-dir
hostPath:
path: /etc/kubernetes/cni/net.d
---

View File

@ -161,6 +161,7 @@ spec:
beta.kubernetes.io/os: linux beta.kubernetes.io/os: linux
hostNetwork: true hostNetwork: true
serviceAccountName: linkerd-cni serviceAccountName: linkerd-cni
priorityClassName: system-node-critical
containers: containers:
# This container installs the linkerd CNI binaries # This container installs the linkerd CNI binaries
# and CNI network config file on each node. The install # and CNI network config file on each node. The install

View File

@ -33,6 +33,8 @@ type Values struct {
UseWaitFlag bool `json:"useWaitFlag"` UseWaitFlag bool `json:"useWaitFlag"`
ProxyInjectAnnotation string `json:"proxyInjectAnnotation"` ProxyInjectAnnotation string `json:"proxyInjectAnnotation"`
ProxyInjectDisabled string `json:"proxyInjectDisabled"` ProxyInjectDisabled string `json:"proxyInjectDisabled"`
PriorityClassName string `json:"priorityClassName"`
InstallNamespace bool `json:"installNamespace"`
} }
// NewValues returns a new instance of the Values type. // NewValues returns a new instance of the Values type.