Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat integrate spiffe #1434

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ JEKYLL_OPTS := -d '$(SITE_DESTDIR)' $(if $(SITE_BASEURL),-b '$(SITE_BASEURL)',)

VERSION := $(shell git describe --tags --dirty --always)

IMAGE_REGISTRY ?= registry.k8s.io/nfd
IMAGE_REGISTRY ?= ahmedgrati
IMAGE_TAG_NAME ?= $(VERSION)
IMAGE_EXTRA_TAG_NAMES ?=

Expand Down Expand Up @@ -120,21 +120,21 @@ deploy: yamls
templates:
@# Need to prepend each line in the sample config with spaces in order to
@# fit correctly in the configmap spec.
@sed s'/^/ /' deployment/components/worker-config/nfd-worker.conf.example > nfd-worker.conf.tmp
@sed s'/^/ /' deployment/components/master-config/nfd-master.conf.example > nfd-master.conf.tmp
@sed s'/^/ /' deployment/components/topology-updater-config/nfd-topology-updater.conf.example > nfd-topology-updater.conf.tmp
@gsed s'/^/ /' deployment/components/worker-config/nfd-worker.conf.example > nfd-worker.conf.tmp
@gsed s'/^/ /' deployment/components/master-config/nfd-master.conf.example > nfd-master.conf.tmp
@gsed s'/^/ /' deployment/components/topology-updater-config/nfd-topology-updater.conf.example > nfd-topology-updater.conf.tmp
@# The sed magic below replaces the block of text between the lines with start and end markers
@start=NFD-MASTER-CONF-START-DO-NOT-REMOVE; \
end=NFD-MASTER-CONF-END-DO-NOT-REMOVE; \
sed -e "/$$start/,/$$end/{ /$$start/{ p; r nfd-master.conf.tmp" \
gsed -e "/$$start/,/$$end/{ /$$start/{ p; r nfd-master.conf.tmp" \
-e "}; /$$end/p; d }" -i deployment/helm/node-feature-discovery/values.yaml
@start=NFD-WORKER-CONF-START-DO-NOT-REMOVE; \
end=NFD-WORKER-CONF-END-DO-NOT-REMOVE; \
sed -e "/$$start/,/$$end/{ /$$start/{ p; r nfd-worker.conf.tmp" \
gsed -e "/$$start/,/$$end/{ /$$start/{ p; r nfd-worker.conf.tmp" \
-e "}; /$$end/p; d }" -i deployment/helm/node-feature-discovery/values.yaml
@start=NFD-TOPOLOGY-UPDATER-CONF-START-DO-NOT-REMOVE; \
end=NFD-TOPOLOGY-UPDATER-CONF-END-DO-NOT-REMOVE; \
sed -e "/$$start/,/$$end/{ /$$start/{ p; r nfd-topology-updater.conf.tmp" \
gsed -e "/$$start/,/$$end/{ /$$start/{ p; r nfd-topology-updater.conf.tmp" \
-e "}; /$$end/p; d }" -i deployment/helm/node-feature-discovery/values.yaml
@rm nfd-master.conf.tmp
@rm nfd-worker.conf.tmp
Expand Down
5 changes: 4 additions & 1 deletion cmd/nfd-master/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ func main() {
args.Overrides.ResyncPeriod = overrides.ResyncPeriod
case "nfd-api-parallelism":
args.Overrides.NfdApiParallelism = overrides.NfdApiParallelism
case "enable-spiffe":
args.Overrides.EnableSpiffe = overrides.EnableSpiffe
case "enable-nodefeature-api":
klog.InfoS("-enable-nodefeature-api is deprecated, will be removed in a future release along with the deprecated gRPC API")
case "ca-file":
Expand Down Expand Up @@ -181,6 +183,7 @@ func initFlags(flagset *flag.FlagSet) (*master.Args, *master.ConfigOverrideArgs)
"It has an effect when the NodeFeature API has been enabled (with -enable-nodefeature-api).")
overrides.NfdApiParallelism = flagset.Int("nfd-api-parallelism", 10, "Defines the maximum number of goroutines responsible of updating nodes. "+
"Can be used for the throttling mechanism. It has effect only when -enable-nodefeature-api has been set.")

overrides.EnableSpiffe = flagset.Bool("enable-spiffe", false,
"Enables the Spiffe signature verification of created CRDs. This is still an EXPERIMENTAL feature.")
return args, overrides
}
4 changes: 4 additions & 0 deletions cmd/nfd-worker/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ func parseArgs(flags *flag.FlagSet, osArgs ...string) *worker.Args {
args.Overrides.FeatureSources = overrides.FeatureSources
case "label-sources":
args.Overrides.LabelSources = overrides.LabelSources
case "enable-spiffe":
args.Overrides.EnableSpiffe = overrides.EnableSpiffe
}
})

Expand Down Expand Up @@ -158,6 +160,8 @@ func initFlags(flagset *flag.FlagSet) (*worker.Args, *worker.ConfigOverrideArgs)
flagset.Var(overrides.LabelSources, "label-sources",
"Comma separated list of label sources. Special value 'all' enables all sources. "+
"Prefix the source name with '-' to disable it.")
overrides.EnableSpiffe = flagset.Bool("enable-spiffe", false,
"Enables the Spiffe signature verification of created CRDs. This is still an EXPERIMENTAL feature.")

return args, overrides
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# denyLabelNs: ["denied.ns.io","denied.kubernetes.io"]
# resourceLabels: ["vendor-1.com/feature-1","vendor-2.io/feature-2"]
# enableTaints: false
# enableSpiffe: true
# labelWhiteList: "foo"
# resyncPeriod: "2h"
# klog:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# labelWhiteList:
# noPublish: false
# sleepInterval: 60s
# enableSpiffe: true
# featureSources: [all]
# labelSources: [all]
# klog:
Expand Down
14 changes: 14 additions & 0 deletions deployment/helm/node-feature-discovery/templates/master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,21 @@ spec:
- "-key-file=/etc/kubernetes/node-feature-discovery/certs/tls.key"
- "-cert-file=/etc/kubernetes/node-feature-discovery/certs/tls.crt"
{{- end }}
{{- if .Values.spiffe.enable }}
- "-enable-spiffe"
{{- end }}
- "-metrics={{ .Values.master.metricsPort | default "8081" }}"
volumeMounts:
{{- if .Values.tls.enable }}
- name: nfd-master-cert
mountPath: "/etc/kubernetes/node-feature-discovery/certs"
readOnly: true
{{- end }}
{{- if .Values.spiffe.enable }}
- name: spire-agent-socket
mountPath: /run/spire/sockets
readOnly: true
{{- end }}
- name: nfd-master-conf
mountPath: "/etc/kubernetes/node-feature-discovery"
readOnly: true
Expand All @@ -124,6 +132,12 @@ spec:
secret:
secretName: nfd-master-cert
{{- end }}
{{- if .Values.spiffe.enable }}
- name: spire-agent-socket
hostPath:
path: /run/spire/sockets
type: Directory
{{- end }}
- name: nfd-master-conf
configMap:
name: {{ include "node-feature-discovery.fullname" . }}-master-conf
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Required cluster role to allow spire-agent to query k8s API server
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: spire-agent-cluster-role
rules:
- apiGroups: [""]
resources: ["pods","nodes","nodes/proxy"]
verbs: ["get"]

---
# Binds above cluster role to spire-agent service account
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: spire-agent-cluster-role-binding
subjects:
- kind: ServiceAccount
name: spire-agent
namespace: {{ include "node-feature-discovery.namespace" . }}
roleRef:
kind: ClusterRole
name: spire-agent-cluster-role
apiGroup: rbac.authorization.k8s.io
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{{- if .Values.spiffe.enable }}
apiVersion: v1
kind: ConfigMap
metadata:
name: spire-agent
data:
agent.conf: |
agent {
data_dir = "/run/spire"
log_level = "DEBUG"
server_address = "spire-server"
server_port = "8081"
socket_path = "/run/spire/sockets/agent.sock"
trust_bundle_path = "/run/spire/bundle/bundle.crt"
trust_domain = "nfd.com"
}

plugins {
NodeAttestor "k8s_sat" {
plugin_data {
cluster = "nfd"
}
}

KeyManager "memory" {
plugin_data {
}
}

WorkloadAttestor "k8s" {
plugin_data {
skip_kubelet_verification = true
node_name_env = "MY_NODE_NAME"
}
}

WorkloadAttestor "unix" {
plugin_data {
}
}
}

health_checks {
listener_enabled = true
bind_address = "0.0.0.0"
bind_port = "8080"
live_path = "/live"
ready_path = "/ready"
}
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{{- if .Values.spiffe.enable }}
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: spire-agent
labels:
app: spire-agent
spec:
selector:
matchLabels:
app: spire-agent
template:
metadata:
labels:
app: spire-agent
spec:
hostPID: true
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
serviceAccountName: spire-agent
initContainers:
- name: init
# This is a small image with wait-for-it, choose whatever image
# you prefer that waits for a service to be up. This image is built
# from https://github.com/lqhl/wait-for-it
image: cgr.dev/chainguard/wait-for-it
args: ["-t", "30", "spire-server:8081"]
containers:
- name: spire-agent
image: ghcr.io/spiffe/spire-agent:1.5.1
args: ["-config", "/run/spire/config/agent.conf"]
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: status.podIP
volumeMounts:
- name: spire-config
mountPath: /run/spire/config
readOnly: true
- name: spire-bundle
mountPath: /run/spire/bundle
- name: spire-agent-socket
mountPath: /run/spire/sockets
readOnly: false
volumes:
- name: spire-config
configMap:
name: spire-agent
- name: spire-bundle
configMap:
name: spire-bundle
- name: spire-agent-socket
hostPath:
path: /run/spire/sockets
type: DirectoryOrCreate
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{{- if .Values.spiffe.enable }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: spire-agent
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{{- if .Values.spiffe.enable }}
apiVersion: v1
kind: ConfigMap
metadata:
name: spire-bundle
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{{- if .Values.spiffe.enable }}
# Role (namespace scoped) to be able to push certificate bundles to a configmap
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: spire-server-configmap-role
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["patch", "get", "list"]
---
# Binds above role to spire-server service account
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: spire-server-configmap-role-binding
namespace: {{ include "node-feature-discovery.namespace" . }}
subjects:
- kind: ServiceAccount
name: spire-server
namespace: {{ include "node-feature-discovery.namespace" . }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: spire-server-configmap-role
---
# ClusterRole to allow spire-server node attestor to query Token Review API
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: spire-server-trust-role
rules:
- apiGroups: ["authentication.k8s.io"]
resources: ["tokenreviews"]
verbs: ["create"]
---
# Binds above cluster role to spire-server service account
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: spire-server-trust-role-binding
subjects:
- kind: ServiceAccount
name: spire-server
namespace: {{ include "node-feature-discovery.namespace" . }}
roleRef:
kind: ClusterRole
name: spire-server-trust-role
apiGroup: rbac.authorization.k8s.io
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{{- if .Values.spiffe.enable }}
apiVersion: v1
kind: ConfigMap
metadata:
name: spire-server
data:
server.conf: |
server {
bind_address = "0.0.0.0"
bind_port = "8081"
socket_path = "/tmp/spire-server/private/api.sock"
trust_domain = "nfd.com"
data_dir = "/run/spire/data"
log_level = "DEBUG"
#AWS requires the use of RSA. EC cryptography is not supported
ca_key_type = "rsa-2048"

ca_subject = {
country = ["US"],
organization = ["SPIFFE"],
common_name = "nfd.com",
}
}

plugins {
DataStore "sql" {
plugin_data {
database_type = "sqlite3"
connection_string = "/run/spire/data/datastore.sqlite3"
}
}

NodeAttestor "k8s_sat" {
plugin_data {
clusters = {
"nfd" = {
use_token_review_api_validation = true
service_account_allow_list = ["{{ include "node-feature-discovery.namespace" . }}:spire-agent"]
}
}
}
}

KeyManager "disk" {
plugin_data {
keys_path = "/run/spire/data/keys.json"
}
}

Notifier "k8sbundle" {
plugin_data {
namespace = "{{ include "node-feature-discovery.namespace" . }}"
}
}
}

health_checks {
listener_enabled = true
bind_address = "0.0.0.0"
bind_port = "8080"
live_path = "/live"
ready_path = "/ready"
}
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{{- if .Values.spiffe.enable }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: spire-server
{{- end }}
Loading