Skip to content

Commit

Permalink
NETOBSERV-395: Tls loki (netobserv#140)
Browse files Browse the repository at this point in the history
* Added loki-tls makefile targets

* Added loki tls configuration

* Update controllers/consoleplugin/consoleplugin_objects.go

Co-authored-by: Julien Pinsonneau <[email protected]>

Co-authored-by: Julien Pinsonneau <[email protected]>
  • Loading branch information
OlivierCazade and jpinsonneau authored Aug 2, 2022
1 parent 048b825 commit 54e3d69
Show file tree
Hide file tree
Showing 8 changed files with 321 additions and 45 deletions.
22 changes: 22 additions & 0 deletions .mk/development.mk
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,28 @@ ifeq (true, $(PORT_FWD))
@echo -e "\n===> loki endpoint is available on http://localhost:3100\n"
endif

.PHONY: undeploy-loki-tls
undeploy-loki-tls:
@echo -e "\n==> Undeploy tls loki"
kubectl config set-context --current --namespace=$(NAMESPACE)
curl -S -L https://raw.githubusercontent.com/netobserv/documents/main/examples/zero-click-loki/2-loki-tls.yaml | kubectl --ignore-not-found=true delete -f - || true
curl -S -L https://raw.githubusercontent.com/netobserv/documents/main/examples/zero-click-loki/1-storage.yaml | kubectl --ignore-not-found=true delete -f - || true
-pkill --oldest --full "3100:3100"

.PHONY: deploy-loki-tls
deploy-loki-tls:
@echo -e "\n==> Deploy tls loki"
kubectl create namespace $(NAMESPACE) --dry-run=client -o yaml | kubectl apply -f -
kubectl config set-context --current --namespace=$(NAMESPACE)
curl -S -L https://raw.githubusercontent.com/netobserv/documents/main/examples/zero-click-loki/1-storage.yaml | kubectl create -f - || true
curl -S -L https://raw.githubusercontent.com/netobserv/documents/main/examples/zero-click-loki/2-loki-tls.yaml | kubectl create -f - || true
kubectl wait --timeout=180s --for=condition=ready pod -l app=loki
-pkill --oldest --full "3100:3100"
ifeq (true, $(PORT_FWD))
-kubectl port-forward --address 0.0.0.0 svc/loki 3100:3100 2>&1 >/dev/null &
@echo -e "\n===> loki endpoint is available on http://localhost:3100\n"
endif

.PHONY: undeploy-loki
undeploy-loki: ## Undeploy loki.
@echo -e "\n==> Undeploy loki"
Expand Down
4 changes: 4 additions & 0 deletions api/v1alpha1/flowcollector_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,10 @@ type FlowCollectorLoki struct {
//+kubebuilder:default:={"app":"netobserv-flowcollector"}
// StaticLabels is a map of common labels to set on each flow
StaticLabels map[string]string `json:"staticLabels,omitempty"`

// TLS client configuration.
// +optional
TLS ClientTLS `json:"tls"`
}

// FlowCollectorConsolePlugin defines the desired ConsolePlugin state of FlowCollector
Expand Down
1 change: 1 addition & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 56 additions & 0 deletions config/crd/bases/flows.netobserv.io_flowcollectors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1630,6 +1630,62 @@ spec:
description: Timeout is the maximum time connection / request
limit A Timeout of zero means no timeout.
type: string
tls:
description: TLS client configuration.
properties:
caCert:
description: CA certificate reference
properties:
certFile:
description: Certificate file name within the ConfigMap
/ Secret
type: string
certKey:
description: Certificate private key file name within
the ConfigMap / Secret. Omit when the key is not necessary.
type: string
name:
description: Name of the ConfigMap or Secret containing
certificates
type: string
type:
description: 'Reference type: configmap or secret'
enum:
- configmap
- secret
type: string
type: object
enable:
default: false
description: Enable TLS
type: boolean
insecureSkipVerify:
default: false
description: Skip client-side verification of the server certificate
type: boolean
userCert:
description: User certificate reference
properties:
certFile:
description: Certificate file name within the ConfigMap
/ Secret
type: string
certKey:
description: Certificate private key file name within
the ConfigMap / Secret. Omit when the key is not necessary.
type: string
name:
description: Name of the ConfigMap or Secret containing
certificates
type: string
type:
description: 'Reference type: configmap or secret'
enum:
- configmap
- secret
type: string
type: object
type: object
url:
default: http://loki:3100/
description: URL is the address of an existing Loki service to
Expand Down
8 changes: 7 additions & 1 deletion config/samples/flows_v1alpha1_flowcollector.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,20 @@ spec:
certFile: user.crt
certKey: user.key
loki:
url: 'http://loki:3100/'
url: 'http://loki.network-observability.svc:3100/'
batchWait: 1s
batchSize: 102400
minBackoff: 1s
maxBackoff: 300s
maxRetries: 10
staticLabels:
app: netobserv-flowcollector
tls:
enable: false
caCert:
type: configmap
name: loki
certFile: service-ca.crt
consolePlugin:
register: true
image: 'quay.io/netobserv/network-observability-console-plugin:main'
Expand Down
92 changes: 53 additions & 39 deletions controllers/consoleplugin/consoleplugin_objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const configMapName = "console-plugin-config"
const configFile = "config.yaml"
const configVolume = "config-volume"
const configPath = "/opt/app-root/"
const lokiCerts = "loki-certs"

// PodConfigurationDigest is an annotation name to facilitate pod restart after
// any external configuration change
Expand Down Expand Up @@ -112,6 +113,55 @@ func buildArgs(desired *flowsv1alpha1.FlowCollectorConsolePlugin, desiredLoki *f
}

func (b *builder) podTemplate(cmDigest string) *corev1.PodTemplateSpec {
volumes := []corev1.Volume{{
Name: secretName,
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: secretName,
},
},
}, {
Name: configVolume,
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: configMapName,
},
},
},
},
}

volumeMounts := []corev1.VolumeMount{{
Name: secretName,
MountPath: "/var/serving-cert",
ReadOnly: true,
},
{
Name: configVolume,
MountPath: configPath,
ReadOnly: true,
}}

args := []string{
"-cert", "/var/serving-cert/tls.crt",
"-key", "/var/serving-cert/tls.key",
"-loki", querierURL(b.desiredLoki),
"-loki-labels", strings.Join(constants.LokiIndexFields, ","),
"-loki-tenant-id", b.desiredLoki.TenantID,
"-loki-skip-tls", "true",
"-loglevel", b.desired.LogLevel,
"-frontend-config", configPath + configFile}

if b.desiredLoki != nil && b.desiredLoki.TLS.Enable {
if b.desiredLoki.TLS.InsecureSkipVerify {
args = append(args, "-loki-skip-tls", "true")
} else {
helper.AppendCertVolumes(volumes, volumeMounts, &b.desiredLoki.TLS, lokiCerts)
args = append(args, "--loki-ca-path", helper.GetCACertPath(&b.desiredLoki.TLS, lokiCerts))
}
}

return &corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: b.labels,
Expand All @@ -125,46 +175,10 @@ func (b *builder) podTemplate(cmDigest string) *corev1.PodTemplateSpec {
Image: b.desired.Image,
ImagePullPolicy: corev1.PullPolicy(b.desired.ImagePullPolicy),
Resources: *b.desired.Resources.DeepCopy(),
VolumeMounts: []corev1.VolumeMount{{
Name: secretName,
MountPath: "/var/serving-cert",
ReadOnly: true,
},
{
Name: configVolume,
MountPath: configPath,
ReadOnly: true,
}},
Args: []string{
"-cert", "/var/serving-cert/tls.crt",
"-key", "/var/serving-cert/tls.key",
"-loki", querierURL(b.desiredLoki),
"-loki-labels", strings.Join(constants.LokiIndexFields, ","),
"-loki-tenant-id", b.desiredLoki.TenantID,
//TODO: add loki tls config https://issues.redhat.com/browse/NETOBSERV-309
"-loki-skip-tls", "true",
"-loglevel", b.desired.LogLevel,
"-frontend-config", configPath + configFile,
},
VolumeMounts: volumeMounts,
Args: args,
}},
Volumes: []corev1.Volume{{
Name: secretName,
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: secretName,
},
},
}, {
Name: configVolume,
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: configMapName,
},
},
},
},
},
Volumes: volumes,
ServiceAccountName: constants.PluginName,
},
}
Expand Down
24 changes: 19 additions & 5 deletions controllers/flowlogspipeline/flp_objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const configPath = "/etc/flowlogs-pipeline"
const configFile = "config.json"

const kafkaCerts = "kafka-certs"
const lokiCerts = "loki-certs"

const (
healthServiceName = "health"
Expand Down Expand Up @@ -179,6 +180,10 @@ func (b *builder) podTemplate(hostNetwork bool, configDigest string) corev1.PodT
volumes, volumeMounts = helper.AppendCertVolumes(volumes, volumeMounts, &b.desiredKafka.TLS, kafkaCerts)
}

if b.desiredLoki != nil && b.desiredLoki.TLS.Enable {
volumes, volumeMounts = helper.AppendCertVolumes(volumes, volumeMounts, &b.desiredLoki.TLS, lokiCerts)
}

container := corev1.Container{
Name: constants.FLPName + b.confKindSuffix,
Image: b.desired.Image,
Expand Down Expand Up @@ -356,11 +361,20 @@ func (b *builder) addTransformStages(stage *config.PipelineBuilderStage) {
lokiWrite.TimestampLabel = "TimeFlowEndMs"
lokiWrite.TimestampScale = "1ms"
lokiWrite.TenantID = b.desiredLoki.TenantID
//TODO: set proper tls config https://issues.redhat.com/browse/NETOBSERV-309
lokiWrite.ClientConfig = &promConfig.HTTPClientConfig{
TLSConfig: promConfig.TLSConfig{
InsecureSkipVerify: true,
},
if b.desiredLoki != nil && b.desiredLoki.TLS.Enable {
if b.desiredLoki.TLS.InsecureSkipVerify {
lokiWrite.ClientConfig = &promConfig.HTTPClientConfig{
TLSConfig: promConfig.TLSConfig{
InsecureSkipVerify: true,
},
}
} else {
lokiWrite.ClientConfig = &promConfig.HTTPClientConfig{
TLSConfig: promConfig.TLSConfig{
CAFile: helper.GetCACertPath(&b.desiredLoki.TLS, lokiCerts),
},
}
}
}
}
enrichedStage.WriteLoki("loki", lokiWrite)
Expand Down
Loading

0 comments on commit 54e3d69

Please sign in to comment.