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

operator: Fix live tail of logs not working on OpenShift-based clusters #6443

Merged
merged 1 commit into from
Jul 12, 2022
Merged
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
2 changes: 2 additions & 0 deletions operator/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Main

- [6646](https://github.com/grafana/loki/pull/6646) **periklis**: Update Loki operand to v2.6.0
- [6443](https://github.com/grafana/loki/pull/6443) **aminesnow**: Fix live tail of logs not working on OpenShift-based clusters
- [6646](https://github.com/grafana/loki/pull/6646) **periklis**: Update Loki operand to v2.6.0
- [6594](https://github.com/grafana/loki/pull/6594) **xperimental**: Disable client certificate authentication on gateway
- [6551](https://github.com/grafana/loki/pull/6561) **periklis**: Add operator docs for object storage
Expand Down
4 changes: 2 additions & 2 deletions operator/internal/manifests/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ func BuildGateway(opts Options) ([]client.Object, error) {

if opts.Stack.Tenants != nil {
mode := opts.Stack.Tenants.Mode
if err := configureDeploymentForMode(dpl, mode, opts.Gates, opts.Name, opts.Namespace); err != nil {
if err := configureGatewayDeploymentForMode(dpl, mode, opts.Gates, opts.Name, opts.Namespace); err != nil {
return nil, err
}

if err := configureServiceForMode(&svc.Spec, mode); err != nil {
if err := configureGatewayServiceForMode(&svc.Spec, mode); err != nil {
return nil, err
}

Expand Down
6 changes: 3 additions & 3 deletions operator/internal/manifests/gateway_tenants.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func ApplyGatewayDefaultOptions(opts *Options) error {
return nil
}

func configureDeploymentForMode(d *appsv1.Deployment, mode lokiv1.ModeType, fg configv1.FeatureGates, stackName, stackNs string) error {
func configureGatewayDeploymentForMode(d *appsv1.Deployment, mode lokiv1.ModeType, fg configv1.FeatureGates, stackName, stackNs string) error {
switch mode {
case lokiv1.Static, lokiv1.Dynamic:
return nil // nothing to configure
Expand Down Expand Up @@ -85,7 +85,7 @@ func configureDeploymentForMode(d *appsv1.Deployment, mode lokiv1.ModeType, fg c
return nil
}

func configureServiceForMode(s *corev1.ServiceSpec, mode lokiv1.ModeType) error {
func configureGatewayServiceForMode(s *corev1.ServiceSpec, mode lokiv1.ModeType) error {
switch mode {
case lokiv1.Static, lokiv1.Dynamic:
return nil // nothing to configure
Expand Down Expand Up @@ -134,7 +134,7 @@ func configureGatewayObjsForMode(objs []client.Object, opts Options) []client.Ob
return objs
}

func configureServiceMonitorForMode(sm *monitoringv1.ServiceMonitor, mode lokiv1.ModeType, fg configv1.FeatureGates) error {
func configureGatewayServiceMonitorForMode(sm *monitoringv1.ServiceMonitor, mode lokiv1.ModeType, fg configv1.FeatureGates) error {
switch mode {
case lokiv1.Static, lokiv1.Dynamic:
return nil // nothing to configure
Expand Down
6 changes: 3 additions & 3 deletions operator/internal/manifests/gateway_tenants_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ func TestConfigureDeploymentForMode(t *testing.T) {
tc := tc
t.Run(tc.desc, func(t *testing.T) {
t.Parallel()
err := configureDeploymentForMode(tc.dpl, tc.mode, tc.featureGates, tc.stackName, tc.stackNs)
err := configureGatewayDeploymentForMode(tc.dpl, tc.mode, tc.featureGates, "test", "test-ns")
require.NoError(t, err)
require.Equal(t, tc.want, tc.dpl)
})
Expand Down Expand Up @@ -781,7 +781,7 @@ func TestConfigureServiceForMode(t *testing.T) {
tc := tc
t.Run(tc.desc, func(t *testing.T) {
t.Parallel()
err := configureServiceForMode(tc.svc, tc.mode)
err := configureGatewayServiceForMode(tc.svc, tc.mode)
require.NoError(t, err)
require.Equal(t, tc.want, tc.svc)
})
Expand Down Expand Up @@ -876,7 +876,7 @@ func TestConfigureServiceMonitorForMode(t *testing.T) {
tc := tc
t.Run(tc.desc, func(t *testing.T) {
t.Parallel()
err := configureServiceMonitorForMode(tc.sm, tc.mode, tc.featureGates)
err := configureGatewayServiceMonitorForMode(tc.sm, tc.mode, tc.featureGates)
require.NoError(t, err)
require.Equal(t, tc.want, tc.sm)
})
Expand Down
56 changes: 56 additions & 0 deletions operator/internal/manifests/openshift/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,59 @@ func ConfigureGatewayServiceMonitor(sm *monitoringv1.ServiceMonitor, withTLS boo

return nil
}

// ConfigureQueryFrontendDeployment configures use of TLS when enabled.
func ConfigureQueryFrontendDeployment(
d *appsv1.Deployment,
proxyURL string,
qfContainerName string,
caBundleVolumeName, caDir, caFile string,
) error {
var qfIdx int
for i, c := range d.Spec.Template.Spec.Containers {
if c.Name == qfContainerName {
qfIdx = i
break
}
}

containerSpec := corev1.Container{
Args: []string{
fmt.Sprintf("-frontend.tail-proxy-url=%s", proxyURL),
fmt.Sprintf("-frontend.tail-tls-config.tls-ca-path=%s/%s", caDir, caFile),
},
VolumeMounts: []corev1.VolumeMount{
{
Name: caBundleVolumeName,
ReadOnly: true,
MountPath: caDir,
},
},
}

p := corev1.PodSpec{
Volumes: []corev1.Volume{
{
Name: caBundleVolumeName,
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
DefaultMode: &defaultConfigMapMode,
LocalObjectReference: corev1.LocalObjectReference{
Name: caBundleVolumeName,
},
},
},
},
},
}

if err := mergo.Merge(&d.Spec.Template.Spec.Containers[qfIdx], containerSpec, mergo.WithAppendSlice); err != nil {
return kverrors.Wrap(err, "failed to add tls config args")
}

if err := mergo.Merge(&d.Spec.Template.Spec, p, mergo.WithAppendSlice); err != nil {
return kverrors.Wrap(err, "failed to add tls volumes")
}

return nil
}
29 changes: 27 additions & 2 deletions operator/internal/manifests/query-frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"fmt"
"path"

lokiv1 "github.com/grafana/loki/operator/apis/loki/v1"
"github.com/grafana/loki/operator/internal/manifests/internal/config"
"github.com/grafana/loki/operator/internal/manifests/openshift"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -29,6 +31,13 @@ func BuildQueryFrontend(opts Options) ([]client.Object, error) {
}
}

if opts.Stack.Tenants != nil {
mode := opts.Stack.Tenants.Mode
if err := configureQueryFrontendDeploymentForMode(deployment, mode, &opts); err != nil {
return nil, err
}
}

return []client.Object{
deployment,
NewQueryFrontendGRPCService(opts),
Expand All @@ -55,7 +64,7 @@ func NewQueryFrontendDeployment(opts Options) *appsv1.Deployment {
Containers: []corev1.Container{
{
Image: opts.Image,
Name: "loki-query-frontend",
Name: lokiFrontendContainerName,
Resources: corev1.ResourceRequirements{
Limits: opts.ResourceRequirements.QueryFrontend.Limits,
Requests: opts.ResourceRequirements.QueryFrontend.Requests,
Expand Down Expand Up @@ -136,7 +145,7 @@ func NewQueryFrontendDeployment(opts Options) *appsv1.Deployment {
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("loki-query-frontend-%s", opts.Name),
Name: fmt.Sprintf("%s-%s", lokiFrontendContainerName, opts.Name),
Labels: labels.Merge(l, GossipLabels()),
Annotations: a,
},
Expand Down Expand Up @@ -217,3 +226,19 @@ func configureQueryFrontendGRPCServicePKI(deployment *appsv1.Deployment, stackNa
serviceName := serviceNameQueryFrontendGRPC(stackName)
return configureGRPCServicePKI(&deployment.Spec.Template.Spec, serviceName)
}

func configureQueryFrontendDeploymentForMode(deployment *appsv1.Deployment, mode lokiv1.ModeType, opts *Options) error {
switch mode {
case lokiv1.Static, lokiv1.Dynamic:
return nil // nothing to configure
case lokiv1.OpenshiftLogging:
url := fmt.Sprintf("https://%s:%d", fqdn(serviceNameQuerierHTTP(opts.Name), opts.Namespace), httpPort)
caBundleName := signingCABundleName(opts.Name)

if opts.Gates.ServiceMonitorTLSEndpoints {
return openshift.ConfigureQueryFrontendDeployment(deployment, url, lokiFrontendContainerName, caBundleName, caBundleDir, caFile)
}
}

return nil
}
122 changes: 118 additions & 4 deletions operator/internal/manifests/query-frontend_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package manifests_test
package manifests

import (
"testing"

v1 "github.com/grafana/loki/operator/apis/config/v1"
lokiv1 "github.com/grafana/loki/operator/apis/loki/v1"
"github.com/grafana/loki/operator/internal/manifests"
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
)

func TestNewQueryFrontendDeployment_SelectorMatchesLabels(t *testing.T) {
ss := manifests.NewQueryFrontendDeployment(manifests.Options{
ss := NewQueryFrontendDeployment(Options{
Name: "abcd",
Namespace: "efgh",
Stack: lokiv1.LokiStackSpec{
Expand All @@ -28,7 +30,7 @@ func TestNewQueryFrontendDeployment_SelectorMatchesLabels(t *testing.T) {
}

func TestNewQueryFrontendDeployment_HasTemplateConfigHashAnnotation(t *testing.T) {
ss := manifests.NewQueryFrontendDeployment(manifests.Options{
ss := NewQueryFrontendDeployment(Options{
Name: "abcd",
Namespace: "efgh",
ConfigSHA1: "deadbeef",
Expand All @@ -45,3 +47,115 @@ func TestNewQueryFrontendDeployment_HasTemplateConfigHashAnnotation(t *testing.T
require.Contains(t, annotations, expected)
require.Equal(t, annotations[expected], "deadbeef")
}

func TestConfigureQueryFrontendDeploymentForMode(t *testing.T) {
type tt struct {
desc string
opts *Options
dpl *appsv1.Deployment
want *appsv1.Deployment
}

tc := []tt{
{
desc: "static mode",
opts: &Options{
Stack: lokiv1.LokiStackSpec{
Tenants: &lokiv1.TenantsSpec{
Mode: lokiv1.Static,
},
},
},
dpl: &appsv1.Deployment{},
want: &appsv1.Deployment{},
},
{
desc: "dynamic mode",
opts: &Options{
Stack: lokiv1.LokiStackSpec{
Tenants: &lokiv1.TenantsSpec{
Mode: lokiv1.Dynamic,
},
},
},
dpl: &appsv1.Deployment{},
want: &appsv1.Deployment{},
},
{
desc: "openshift-logging mode",
opts: &Options{
Name: "test",
Namespace: "test-ns",
Stack: lokiv1.LokiStackSpec{
Tenants: &lokiv1.TenantsSpec{
Mode: lokiv1.OpenshiftLogging,
},
},
Gates: v1.FeatureGates{
ServiceMonitorTLSEndpoints: true,
},
},
dpl: &appsv1.Deployment{
Spec: appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Args: []string{
"-target=query-frontend",
},
},
},
},
},
},
},
want: &appsv1.Deployment{
Spec: appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Args: []string{
"-target=query-frontend",
"-frontend.tail-proxy-url=https://test-querier-http.test-ns.svc.cluster.local:3100",
"-frontend.tail-tls-config.tls-ca-path=/var/run/ca/service-ca.crt",
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "test-ca-bundle",
ReadOnly: true,
MountPath: "/var/run/ca",
},
},
},
},
Volumes: []corev1.Volume{
{
Name: "test-ca-bundle",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
DefaultMode: &defaultConfigMapMode,
LocalObjectReference: corev1.LocalObjectReference{
Name: "test-ca-bundle",
},
},
},
},
},
},
},
},
},
},
}
for _, tc := range tc {
tc := tc
t.Run(tc.desc, func(t *testing.T) {
t.Parallel()
err := configureQueryFrontendDeploymentForMode(tc.dpl, tc.opts.Stack.Tenants.Mode, tc.opts)
require.NoError(t, err)
require.Equal(t, tc.want, tc.dpl)
})
}
}
2 changes: 1 addition & 1 deletion operator/internal/manifests/service_monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func NewGatewayServiceMonitor(opts Options) *monitoringv1.ServiceMonitor {
sm := newServiceMonitor(opts.Namespace, serviceMonitorName, l, gwEndpoint)

if opts.Stack.Tenants != nil {
if err := configureServiceMonitorForMode(sm, opts.Stack.Tenants.Mode, opts.Gates); err != nil {
if err := configureGatewayServiceMonitorForMode(sm, opts.Stack.Tenants.Mode, opts.Gates); err != nil {
return sm
}
}
Expand Down
2 changes: 2 additions & 0 deletions operator/internal/manifests/var.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const (
lokiLivenessPath = "/loki/api/v1/status/buildinfo"
lokiReadinessPath = "/ready"

lokiFrontendContainerName = "loki-query-frontend"

gatewayContainerName = "gateway"
gatewayHTTPPort = 8080
gatewayInternalPort = 8081
Expand Down