From 9005cfec6f6c13398d8af396c94e7455edee0420 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Mon, 29 Aug 2022 00:14:02 +0200 Subject: add kubernetes cluster addon: node-feature-discovery --- .../node-feature-discovery/defaults/main.yml | 2 + .../addons/node-feature-discovery/tasks/main.yml | 45 ++ .../node-feature-discovery/tasks/tls-ca-master.yml | 101 +++ .../node-feature-discovery/tasks/tls-worker.yml | 79 +++ .../templates/config.0.11.2.yml.j2 | 710 +++++++++++++++++++++ .../templates/kustomization.yml.j2 | 14 + 6 files changed, 951 insertions(+) create mode 100644 roles/kubernetes/addons/node-feature-discovery/defaults/main.yml create mode 100644 roles/kubernetes/addons/node-feature-discovery/tasks/main.yml create mode 100644 roles/kubernetes/addons/node-feature-discovery/tasks/tls-ca-master.yml create mode 100644 roles/kubernetes/addons/node-feature-discovery/tasks/tls-worker.yml create mode 100644 roles/kubernetes/addons/node-feature-discovery/templates/config.0.11.2.yml.j2 create mode 100644 roles/kubernetes/addons/node-feature-discovery/templates/kustomization.yml.j2 (limited to 'roles/kubernetes') diff --git a/roles/kubernetes/addons/node-feature-discovery/defaults/main.yml b/roles/kubernetes/addons/node-feature-discovery/defaults/main.yml new file mode 100644 index 00000000..36f8b848 --- /dev/null +++ b/roles/kubernetes/addons/node-feature-discovery/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# kubernetes_node_feature_discovery_version: 0.11.2 diff --git a/roles/kubernetes/addons/node-feature-discovery/tasks/main.yml b/roles/kubernetes/addons/node-feature-discovery/tasks/main.yml new file mode 100644 index 00000000..80acb7b9 --- /dev/null +++ b/roles/kubernetes/addons/node-feature-discovery/tasks/main.yml @@ -0,0 +1,45 @@ +--- +- name: create base directory for node-feature-discovery addon + run_once: true + delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + file: + path: /etc/kubernetes/addons/node-feature-discovery + state: directory + +- name: install python-cryptoraphy + apt: + name: "{{ python_basename }}-cryptography" + state: present + +- name: generate certificate authority and master certificate + run_once: true + delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + import_tasks: tls-ca-master.yml + +- name: generate certificate + import_tasks: tls-worker.yml + +- name: deploy node-feature-discovery addon + run_once: true + delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + block: + - name: copy config for node-feature-discovery + template: + src: "config.{{ kubernetes_node_feature_discovery_version }}.yml.j2" + dest: /etc/kubernetes/addons/node-feature-discovery/config.yml + + - name: generate kustomization file + template: + src: "kustomization.yml.j2" + dest: /etc/kubernetes/addons/node-feature-discovery/kustomization.yml + + - name: check if node-feature-discovery is already installed + check_mode: no + command: kubectl --kubeconfig /etc/kubernetes/admin.conf diff -k /etc/kubernetes/addons/node-feature-discovery/ + failed_when: false + changed_when: false + register: kube_node_feature_discovery_diff_result + + - name: install node-feature-discovery onto the cluster + when: kube_node_feature_discovery_diff_result.rc != 0 + command: kubectl --kubeconfig /etc/kubernetes/admin.conf apply -k /etc/kubernetes/addons/node-feature-discovery/ diff --git a/roles/kubernetes/addons/node-feature-discovery/tasks/tls-ca-master.yml b/roles/kubernetes/addons/node-feature-discovery/tasks/tls-ca-master.yml new file mode 100644 index 00000000..a433ab32 --- /dev/null +++ b/roles/kubernetes/addons/node-feature-discovery/tasks/tls-ca-master.yml @@ -0,0 +1,101 @@ +--- +- name: create CA directory + file: + path: /etc/kubernetes/addons/node-feature-discovery/ca + state: directory + owner: root + group: root + mode: 0700 + +- name: create CA private key + openssl_privatekey: + path: /etc/kubernetes/addons/node-feature-discovery/ca/key.pem + type: RSA + size: 4096 + owner: root + group: root + mode: 0600 + +- name: create signing request for CA certificate + openssl_csr: + path: /etc/kubernetes/addons/node-feature-discovery/ca/csr.pem + privatekey_path: /etc/kubernetes/addons/node-feature-discovery/ca/key.pem + CN: "CA for kubernetes cluster addon node-feature discovery" + useCommonNameForSAN: no + key_usage: + - cRLSign + - keyCertSign + key_usage_critical: yes + basic_constraints: + - 'CA:TRUE' + - 'pathlen:0' + basic_constraints_critical: yes + +- name: create self-signed CA certificate + openssl_certificate: + path: /etc/kubernetes/addons/node-feature-discovery/ca/crt.pem + csr_path: /etc/kubernetes/addons/node-feature-discovery/ca/csr.pem + privatekey_path: /etc/kubernetes/addons/node-feature-discovery/ca/key.pem + provider: selfsigned + selfsigned_digest: sha256 + selfsigned_not_after: "+18250d" ## 50 years + selfsigned_create_subject_key_identifier: always_create + +- name: slurp CA certificate for worker to use + slurp: + src: /etc/kubernetes/addons/node-feature-discovery/ca/crt.pem + register: node_feature_discovery_ca_certificate + + +- name: create private key for master certificate + openssl_privatekey: + path: /etc/kubernetes/addons/node-feature-discovery/ca/master.key + type: RSA + size: 4096 + owner: root + group: root + mode: 0600 + +- name: create signing request for master certificate + openssl_csr: + path: /etc/kubernetes/addons/node-feature-discovery/ca/master.csr + privatekey_path: /etc/kubernetes/addons/node-feature-discovery/ca/master.key + CN: nfd-master + subject_alt_name: + - "DNS:nfd-master" + - "DNS:nfd-master.node-feature-discovery.svc.{{ kubernetes.dns_domain | default('cluster.local') }}" + - "DNS:localhost" + key_usage: + - digitalSignature + key_usage_critical: yes + extended_key_usage: + - serverAuth + - clientAuth ## this cert is also used for health checks + extended_key_usage_critical: yes + basic_constraints: + - 'CA:FALSE' + basic_constraints_critical: yes + +- name: check if master certificate exists + stat: + path: /etc/kubernetes/addons/node-feature-discovery/ca/master.crt + register: node_feature_discovery_master_certificate_stat + +- name: check master certificate validity + when: node_feature_discovery_master_certificate_stat.stat.exists + openssl_certificate_info: + path: /etc/kubernetes/addons/node-feature-discovery/ca/master.crt + valid_at: + ten_years: '+3650d' + register: node_feature_discovery_master_certificate_info + +- name: create master certificate + openssl_certificate: + path: /etc/kubernetes/addons/node-feature-discovery/ca/master.crt + csr_path: /etc/kubernetes/addons/node-feature-discovery/ca/master.csr + provider: ownca + ownca_path: /etc/kubernetes/addons/node-feature-discovery/ca/crt.pem + ownca_privatekey_path: /etc/kubernetes/addons/node-feature-discovery/ca/key.pem + ownca_digest: sha256 + ownca_not_after: "+18250d" ## 50 years + force: "{{ node_feature_discovery_master_certificate_stat.stat.exists and (not node_feature_discovery_master_certificate_info.valid_at.ten_years) }}" diff --git a/roles/kubernetes/addons/node-feature-discovery/tasks/tls-worker.yml b/roles/kubernetes/addons/node-feature-discovery/tasks/tls-worker.yml new file mode 100644 index 00000000..888c0872 --- /dev/null +++ b/roles/kubernetes/addons/node-feature-discovery/tasks/tls-worker.yml @@ -0,0 +1,79 @@ +--- +- name: create certs directory for nfd-worker + file: + path: /etc/kubernetes/node-feature-discovery/certs + state: directory + owner: nobody + group: root + mode: 0500 + +- name: install CA certificate + copy: + content: "{{ node_feature_discovery_ca_certificate.content | b64decode }}" + dest: /etc/kubernetes/node-feature-discovery/certs/ca.crt + +- name: create private key for worker certificate + openssl_privatekey: + path: /etc/kubernetes/node-feature-discovery/certs/tls.key + type: RSA + size: 4096 + owner: nobody + group: root + mode: 0400 + +- name: create signing request for worker certificate + openssl_csr: + path: /etc/kubernetes/node-feature-discovery/certs/tls.csr + privatekey_path: /etc/kubernetes/node-feature-discovery/certs/tls.key + CN: "{{ kubernetes_node_name }}" + key_usage: + - digitalSignature + key_usage_critical: yes + extended_key_usage: + - clientAuth + extended_key_usage_critical: yes + basic_constraints: + - 'CA:FALSE' + basic_constraints_critical: yes + +- name: slurp CSR for worker certificate + slurp: + src: /etc/kubernetes/node-feature-discovery/certs/tls.csr + register: node_feature_discovery_worker_csr + +- name: check if worker certificate already exists + stat: + path: /etc/kubernetes/node-feature-discovery/certs/tls.crt + register: node_feature_discovery_worker_certificate_stat + +- name: read worker certificate validity + when: node_feature_discovery_worker_certificate_stat.stat.exists + openssl_certificate_info: + path: /etc/kubernetes/node-feature-discovery/certs/tls.crt + valid_at: + ten_years: '+3650d' + register: node_feature_discovery_worker_certificate_info + +- name: slurp existing worker certificate + when: node_feature_discovery_worker_certificate_stat.stat.exists + slurp: + src: /etc/kubernetes/node-feature-discovery/certs/tls.crt + register: node_feature_discovery_worker_certificate_current + +- name: generate worker certificate + delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + community.crypto.x509_certificate_pipe: + content: "{{ node_feature_discovery_worker_certificate_current.content | default('') | b64decode }}" + csr_content: "{{ node_feature_discovery_worker_csr.content | b64decode }}" + provider: ownca + ownca_path: /etc/kubernetes/addons/node-feature-discovery/ca/crt.pem + ownca_privatekey_path: /etc/kubernetes/addons/node-feature-discovery/ca/key.pem + ownca_digest: sha256 + ownca_not_after: "+18250d" ## 50 years + force: "{{ node_feature_discovery_worker_certificate_stat.stat.exists and (not node_feature_discovery_worker_certificate_info.valid_at.ten_years) }}" + register: node_feature_discovery_worker_cert + +- name: store worker certificate + copy: + content: "{{ node_feature_discovery_worker_cert.certificate }}" + dest: /etc/kubernetes/node-feature-discovery/certs/tls.crt diff --git a/roles/kubernetes/addons/node-feature-discovery/templates/config.0.11.2.yml.j2 b/roles/kubernetes/addons/node-feature-discovery/templates/config.0.11.2.yml.j2 new file mode 100644 index 00000000..7081c290 --- /dev/null +++ b/roles/kubernetes/addons/node-feature-discovery/templates/config.0.11.2.yml.j2 @@ -0,0 +1,710 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: node-feature-discovery +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null + name: nodefeaturerules.nfd.k8s-sigs.io +spec: + group: nfd.k8s-sigs.io + names: + kind: NodeFeatureRule + listKind: NodeFeatureRuleList + plural: nodefeaturerules + singular: nodefeaturerule + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: NodeFeatureRule resource specifies a configuration for feature-based + customization of node objects, such as node labeling. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: NodeFeatureRuleSpec describes a NodeFeatureRule. + properties: + rules: + description: Rules is a list of node customization rules. + items: + description: Rule defines a rule for node customization such as + labeling. + properties: + labels: + additionalProperties: + type: string + description: Labels to create if the rule matches. + type: object + labelsTemplate: + description: LabelsTemplate specifies a template to expand for + dynamically generating multiple labels. Data (after template + expansion) must be keys with an optional value ([=]) + separated by newlines. + type: string + matchAny: + description: MatchAny specifies a list of matchers one of which + must match. + items: + description: MatchAnyElem specifies one sub-matcher of MatchAny. + properties: + matchFeatures: + description: MatchFeatures specifies a set of matcher + terms all of which must match. + items: + description: FeatureMatcherTerm defines requirements + against one feature set. All requirements (specified + as MatchExpressions) are evaluated against each element + in the feature set. + properties: + feature: + type: string + matchExpressions: + additionalProperties: + description: "MatchExpression specifies an expression + to evaluate against a set of input values. It + contains an operator that is applied when matching + the input and an array of values that the operator + evaluates the input against. \n NB: CreateMatchExpression + or MustCreateMatchExpression() should be used + for creating new instances. NB: Validate() + must be called if Op or Value fields are modified + or if a new instance is created from scratch + without using the helper functions." + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: Value is the list of values that + the operand evaluates the input against. + Value should be empty if the operator is + Exists, DoesNotExist, IsTrue or IsFalse. + Value should contain exactly one element + if the operator is Gt or Lt and exactly + two elements if the operator is GtLt. In + other cases Value should contain at least + one element. + items: + type: string + type: array + required: + - op + type: object + description: MatchExpressionSet contains a set of + MatchExpressions, each of which is evaluated against + a set of input values. + type: object + required: + - feature + - matchExpressions + type: object + type: array + required: + - matchFeatures + type: object + type: array + matchFeatures: + description: MatchFeatures specifies a set of matcher terms + all of which must match. + items: + description: FeatureMatcherTerm defines requirements against + one feature set. All requirements (specified as MatchExpressions) + are evaluated against each element in the feature set. + properties: + feature: + type: string + matchExpressions: + additionalProperties: + description: "MatchExpression specifies an expression + to evaluate against a set of input values. It contains + an operator that is applied when matching the input + and an array of values that the operator evaluates + the input against. \n NB: CreateMatchExpression or + MustCreateMatchExpression() should be used for creating + new instances. NB: Validate() must be called if Op + or Value fields are modified or if a new instance + is created from scratch without using the helper functions." + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: Value is the list of values that the + operand evaluates the input against. Value should + be empty if the operator is Exists, DoesNotExist, + IsTrue or IsFalse. Value should contain exactly + one element if the operator is Gt or Lt and exactly + two elements if the operator is GtLt. In other + cases Value should contain at least one element. + items: + type: string + type: array + required: + - op + type: object + description: MatchExpressionSet contains a set of MatchExpressions, + each of which is evaluated against a set of input values. + type: object + required: + - feature + - matchExpressions + type: object + type: array + name: + description: Name of the rule. + type: string + vars: + additionalProperties: + type: string + description: Vars is the variables to store if the rule matches. + Variables do not directly inflict any changes in the node + object. However, they can be referenced from other rules enabling + more complex rule hierarchies, without exposing intermediary + output values as labels. + type: object + varsTemplate: + description: VarsTemplate specifies a template to expand for + dynamically generating multiple variables. Data (after template + expansion) must be keys with an optional value ([=]) + separated by newlines. + type: string + required: + - name + type: object + type: array + required: + - rules + type: object + required: + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: nfd-master + namespace: node-feature-discovery +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: nfd-master +rules: +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - patch + - update + - list +- apiGroups: + - topology.node.k8s.io + resources: + - noderesourcetopologies + verbs: + - create + - get + - update +- apiGroups: + - nfd.k8s-sigs.io + resources: + - nodefeaturerules + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: nfd-master +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: nfd-master +subjects: +- kind: ServiceAccount + name: nfd-master + namespace: node-feature-discovery +--- +apiVersion: v1 +data: + nfd-worker.conf: | + #core: + # labelWhiteList: + # noPublish: false + # sleepInterval: 60s + # featureSources: [all] + # labelSources: [all] + # klog: + # addDirHeader: false + # alsologtostderr: false + # logBacktraceAt: + # logtostderr: true + # skipHeaders: false + # stderrthreshold: 2 + # v: 0 + # vmodule: + ## NOTE: the following options are not dynamically run-time configurable + ## and require a nfd-worker restart to take effect after being changed + # logDir: + # logFile: + # logFileMaxSize: 1800 + # skipLogHeaders: false + #sources: + # cpu: + # cpuid: + ## NOTE: whitelist has priority over blacklist + # attributeBlacklist: + # - "BMI1" + # - "BMI2" + # - "CLMUL" + # - "CMOV" + # - "CX16" + # - "ERMS" + # - "F16C" + # - "HTT" + # - "LZCNT" + # - "MMX" + # - "MMXEXT" + # - "NX" + # - "POPCNT" + # - "RDRAND" + # - "RDSEED" + # - "RDTSCP" + # - "SGX" + # - "SSE" + # - "SSE2" + # - "SSE3" + # - "SSE4" + # - "SSE42" + # - "SSSE3" + # attributeWhitelist: + # kernel: + # kconfigFile: "/path/to/kconfig" + # configOpts: + # - "NO_HZ" + # - "X86" + # - "DMI" + # pci: + # deviceClassWhitelist: + # - "0200" + # - "03" + # - "12" + # deviceLabelFields: + # - "class" + # - "vendor" + # - "device" + # - "subsystem_vendor" + # - "subsystem_device" + # usb: + # deviceClassWhitelist: + # - "0e" + # - "ef" + # - "fe" + # - "ff" + # deviceLabelFields: + # - "class" + # - "vendor" + # - "device" + # custom: + # # The following feature demonstrates the capabilities of the matchFeatures + # - name: "my custom rule" + # labels: + # my-ng-feature: "true" + # # matchFeatures implements a logical AND over all matcher terms in the + # # list (i.e. all of the terms, or per-feature matchers, must match) + # matchFeatures: + # - feature: cpu.cpuid + # matchExpressions: + # AVX512F: {op: Exists} + # - feature: cpu.cstate + # matchExpressions: + # enabled: {op: IsTrue} + # - feature: cpu.pstate + # matchExpressions: + # no_turbo: {op: IsFalse} + # scaling_governor: {op: In, value: ["performance"]} + # - feature: cpu.rdt + # matchExpressions: + # RDTL3CA: {op: Exists} + # - feature: cpu.sst + # matchExpressions: + # bf.enabled: {op: IsTrue} + # - feature: cpu.topology + # matchExpressions: + # hardware_multithreading: {op: IsFalse} + # + # - feature: kernel.config + # matchExpressions: + # X86: {op: Exists} + # LSM: {op: InRegexp, value: ["apparmor"]} + # - feature: kernel.loadedmodule + # matchExpressions: + # e1000e: {op: Exists} + # - feature: kernel.selinux + # matchExpressions: + # enabled: {op: IsFalse} + # - feature: kernel.version + # matchExpressions: + # major: {op: In, value: ["5"]} + # minor: {op: Gt, value: ["10"]} + # + # - feature: storage.block + # matchExpressions: + # rotational: {op: In, value: ["0"]} + # dax: {op: In, value: ["0"]} + # + # - feature: network.device + # matchExpressions: + # operstate: {op: In, value: ["up"]} + # speed: {op: Gt, value: ["100"]} + # + # - feature: memory.numa + # matchExpressions: + # node_count: {op: Gt, value: ["2"]} + # - feature: memory.nv + # matchExpressions: + # devtype: {op: In, value: ["nd_dax"]} + # mode: {op: In, value: ["memory"]} + # + # - feature: system.osrelease + # matchExpressions: + # ID: {op: In, value: ["fedora", "centos"]} + # - feature: system.name + # matchExpressions: + # nodename: {op: InRegexp, value: ["^worker-X"]} + # + # - feature: local.label + # matchExpressions: + # custom-feature-knob: {op: Gt, value: ["100"]} + # + # # The following feature demonstrates the capabilities of the matchAny + # - name: "my matchAny rule" + # labels: + # my-ng-feature-2: "my-value" + # # matchAny implements a logical IF over all elements (sub-matchers) in + # # the list (i.e. at least one feature matcher must match) + # matchAny: + # - matchFeatures: + # - feature: kernel.loadedmodule + # matchExpressions: + # driver-module-X: {op: Exists} + # - feature: pci.device + # matchExpressions: + # vendor: {op: In, value: ["8086"]} + # class: {op: In, value: ["0200"]} + # - matchFeatures: + # - feature: kernel.loadedmodule + # matchExpressions: + # driver-module-Y: {op: Exists} + # - feature: usb.device + # matchExpressions: + # vendor: {op: In, value: ["8086"]} + # class: {op: In, value: ["02"]} + # + # # The following features demonstreate label templating capabilities + # - name: "my template rule" + # labelsTemplate: | + # {{ '{{' }} range .system.osrelease {{ '}}' }}my-system-feature.{{ '{{' }} .Name {{ '}}' }}={{ '{{' }} .Value {{ '}}' }} + # {{ '{{' }} end {{ '}}' }} + # matchFeatures: + # - feature: system.osrelease + # matchExpressions: + # ID: {op: InRegexp, value: ["^open.*"]} + # VERSION_ID.major: {op: In, value: ["13", "15"]} + # + # - name: "my template rule 2" + # labelsTemplate: | + # {{ '{{' }} range .pci.device {{ '}}' }}my-pci-device.{{ '{{' }} .class {{ '}}' }}-{{ '{{' }} .device {{ '}}' }}=with-cpuid + # {{ '{{' }} end {{ '}}' }} + # matchFeatures: + # - feature: pci.device + # matchExpressions: + # class: {op: InRegexp, value: ["^06"]} + # vendor: ["8086"] + # - feature: cpu.cpuid + # matchExpressions: + # AVX: {op: Exists} + # + # # The following examples demonstrate vars field and back-referencing + # # previous labels and vars + # - name: "my dummy kernel rule" + # labels: + # "my.kernel.feature": "true" + # matchFeatures: + # - feature: kernel.version + # matchExpressions: + # major: {op: Gt, value: ["2"]} + # + # - name: "my dummy rule with no labels" + # vars: + # "my.dummy.var": "1" + # matchFeatures: + # - feature: cpu.cpuid + # matchExpressions: {} + # + # - name: "my rule using backrefs" + # labels: + # "my.backref.feature": "true" + # matchFeatures: + # - feature: rule.matched + # matchExpressions: + # my.kernel.feature: {op: IsTrue} + # my.dummy.var: {op: Gt, value: ["0"]} + # +kind: ConfigMap +metadata: + name: nfd-worker-conf + namespace: node-feature-discovery +--- +apiVersion: v1 +kind: Service +metadata: + name: nfd-master + namespace: node-feature-discovery +spec: + ports: + - port: 8080 + protocol: TCP + selector: + app: nfd-master + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: nfd + name: nfd-master + namespace: node-feature-discovery +spec: + replicas: 1 + selector: + matchLabels: + app: nfd-master + template: + metadata: + labels: + app: nfd-master + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: node-role.kubernetes.io/master + operator: In + values: + - "" + weight: 1 + - preference: + matchExpressions: + - key: node-role.kubernetes.io/control-plane + operator: In + values: + - "" + weight: 1 + containers: + - args: + - "-ca-file=/etc/kubernetes/node-feature-discovery/certs/ca.crt" + - "-key-file=/etc/kubernetes/node-feature-discovery/certs/tls.key" + - "-cert-file=/etc/kubernetes/node-feature-discovery/certs/tls.crt" + - -verify-node-name + command: + - nfd-master + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + image: k8s.gcr.io/nfd/node-feature-discovery:v0.11.2 + imagePullPolicy: IfNotPresent + livenessProbe: + exec: + command: + - /usr/bin/grpc_health_probe + - -addr=:8080 + - -tls + - "-tls-ca-cert=/etc/kubernetes/node-feature-discovery/certs/ca.crt" + - "-tls-client-key=/etc/kubernetes/node-feature-discovery/certs/tls.key" + - "-tls-client-cert=/etc/kubernetes/node-feature-discovery/certs/tls.crt" + initialDelaySeconds: 10 + periodSeconds: 10 + name: nfd-master + readinessProbe: + exec: + command: + - /usr/bin/grpc_health_probe + - -addr=:8080 + - -tls + - "-tls-ca-cert=/etc/kubernetes/node-feature-discovery/certs/ca.crt" + - "-tls-client-key=/etc/kubernetes/node-feature-discovery/certs/tls.key" + - "-tls-client-cert=/etc/kubernetes/node-feature-discovery/certs/tls.crt" + failureThreshold: 10 + initialDelaySeconds: 5 + periodSeconds: 10 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/kubernetes/node-feature-discovery/certs/ + name: tls-certs + readOnly: true + serviceAccount: nfd-master + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Equal + value: "" + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane + operator: Equal + value: "" + volumes: + - name: tls-certs + secret: + secretName: nfd-master-cert +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app: nfd + name: nfd-worker + namespace: node-feature-discovery +spec: + selector: + matchLabels: + app: nfd-worker + template: + metadata: + labels: + app: nfd-worker + spec: + containers: + - args: + - -server=nfd-master:8080 + - "-ca-file=/etc/kubernetes/node-feature-discovery/certs/ca.crt" + - "-key-file=/etc/kubernetes/node-feature-discovery/certs/tls.key" + - "-cert-file=/etc/kubernetes/node-feature-discovery/certs/tls.crt" + command: + - nfd-worker + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + image: k8s.gcr.io/nfd/node-feature-discovery:v0.11.2 + imagePullPolicy: IfNotPresent + name: nfd-worker + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + volumeMounts: + - mountPath: /host-boot + name: host-boot + readOnly: true + - mountPath: /host-etc/os-release + name: host-os-release + readOnly: true + - mountPath: /host-sys + name: host-sys + readOnly: true + - mountPath: /host-usr/lib + name: host-usr-lib + readOnly: true + - mountPath: /etc/kubernetes/node-feature-discovery/source.d/ + name: source-d + readOnly: true + - mountPath: /etc/kubernetes/node-feature-discovery/features.d/ + name: features-d + readOnly: true + - mountPath: /etc/kubernetes/node-feature-discovery + name: nfd-worker-conf + readOnly: true + - mountPath: /etc/kubernetes/node-feature-discovery/certs/ + name: tls-certs + readOnly: true + dnsPolicy: ClusterFirstWithHostNet + volumes: + - hostPath: + path: /boot + name: host-boot + - hostPath: + path: /etc/os-release + name: host-os-release + - hostPath: + path: /sys + name: host-sys + - hostPath: + path: /usr/lib + name: host-usr-lib + - hostPath: + path: /etc/kubernetes/node-feature-discovery/source.d/ + name: source-d + - hostPath: + path: /etc/kubernetes/node-feature-discovery/features.d/ + name: features-d + - configMap: + name: nfd-worker-conf + name: nfd-worker-conf + - name: tls-certs + hostPath: + path: /etc/kubernetes/node-feature-discovery/certs diff --git a/roles/kubernetes/addons/node-feature-discovery/templates/kustomization.yml.j2 b/roles/kubernetes/addons/node-feature-discovery/templates/kustomization.yml.j2 new file mode 100644 index 00000000..b8b81411 --- /dev/null +++ b/roles/kubernetes/addons/node-feature-discovery/templates/kustomization.yml.j2 @@ -0,0 +1,14 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - config.yml + +secretGenerator: + - name: nfd-master-cert + namespace: node-feature-discovery + type: "kubernetes.io/tls" + files: + - ca.crt=ca/crt.pem + - tls.crt=ca/master.crt + - tls.key=ca/master.key -- cgit v1.2.3