Skip to content
This repository has been archived by the owner on Nov 29, 2024. It is now read-only.

Commit

Permalink
add Istion labels for Services and Deployments
Browse files Browse the repository at this point in the history
  • Loading branch information
leoporoli committed Oct 16, 2024
1 parent 7c10b56 commit 96dbf66
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 71 deletions.
90 changes: 22 additions & 68 deletions ci/obd-demo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@ kind: Deployment
metadata:
name: cartservice-v1
labels:
app: cartservice
version: v1
app.kubernetes.io/name: cartservice
spec:
selector:
matchLabels:
app: cartservice
version: v1
app.kubernetes.io/name: cartservice
template:
metadata:
labels:
app: cartservice
version: v1
app.kubernetes.io/name: cartservice
spec:
terminationGracePeriodSeconds: 5
containers:
Expand Down Expand Up @@ -66,14 +63,13 @@ kind: Service
metadata:
name: cartservice
labels:
app: cartservice
version: v1
app.kubernetes.io/name: cartservice
annotations:
kardinal.dev.service/dependencies: "postgres:tcp"
spec:
type: ClusterIP
selector:
app: cartservice
app.kubernetes.io/name: cartservice
ports:
- name: http
port: 8090
Expand All @@ -86,18 +82,15 @@ kind: Deployment
metadata:
name: frontend-v1
labels:
app: frontend
version: v1
app.kubernetes.io/name: frontend
spec:
selector:
matchLabels:
app: frontend
version: v1
app.kubernetes.io/name: frontend
template:
metadata:
labels:
app: frontend
version: v1
app.kubernetes.io/name: frontend
annotations:
sidecar.istio.io/rewriteAppHTTPProbers: "true"
spec:
Expand Down Expand Up @@ -139,20 +132,14 @@ kind: Service
metadata:
name: frontend
labels:
app: frontend
version: v1
app.kubernetes.io/name: frontend
annotations:
kardinal.dev.service/dependencies: "productcatalogservice:http,cartservice:http"
kardinal.dev.service/plugins: |
- name: https://github.com/kurtosis-tech/free-currency-api-plugin.git
type: external
servicename: free-currency-api
args:
api_key: fca_live_VKZlykCWEiFcpBHnw74pzd4vLi04q1h9JySbVHDF
kardinal.dev.service/plugins: "jsdelivr-api"
spec:
type: ClusterIP
selector:
app: frontend
app.kubernetes.io/name: frontend
ports:
- name: http
port: 80
Expand All @@ -166,19 +153,16 @@ kind: Deployment
metadata:
name: postgres-v1
labels:
app: postgres
version: v1
app.kubernetes.io/name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
version: v1
app.kubernetes.io/name: postgres
template:
metadata:
labels:
app: postgres
version: v1
app.kubernetes.io/name: postgres
spec:
containers:
- name: postgres
Expand Down Expand Up @@ -206,36 +190,10 @@ kind: Service
metadata:
name: postgres
labels:
app: postgres
version: v1
app.kubernetes.io/name: postgres
annotations:
kardinal.dev.service/stateful: "true"
kardinal.dev.service/plugins: |
- name: github.com/kurtosis-tech/postgres-seed-plugin
args:
seed_script: |
-- create the table
CREATE TABLE IF NOT EXISTS public.items(
id bigserial PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE,
updated_at TIMESTAMP WITH TIME ZONE,
deleted_at TIMESTAMP WITH TIME ZONE,
user_id TEXT,
product_id TEXT,
quantity INTEGER
);
INSERT INTO public.items (id, created_at, updated_at, deleted_at, user_id, product_id, quantity)
VALUES (1, '2024-08-02 13:02:07.656104 +00:00', '2024-08-02 13:02:07.656104 +00:00', null, '0494c5e0-dde0-48fa-a6d8-f7962f5476bf', '66VCHSJNUP', 1);
INSERT INTO public.items (id, created_at, updated_at, deleted_at, user_id, product_id, quantity)
VALUES (2, '2024-08-02 13:02:10.891407 +00:00', '2024-08-02 13:02:10.891407 +00:00', null, '0494c5e0-dde0-48fa-a6d8-f7962f5476bf', '2ZYFJ3GM2N', 1);
-- Set the sequence to the correct value after inserting records
SELECT setval('public.items_id_seq', (SELECT MAX(id) FROM public.items));
db_name: "cart"
db_user: "postgresuser"
db_password: "postgrespass"
kardinal.dev.service/plugins: "postgres-seed-plugin"

spec:
type: ClusterIP
Expand All @@ -245,26 +203,23 @@ spec:
targetPort: 5432
protocol: TCP
selector:
app: postgres
app.kubernetes.io/name: postgres

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: productcatalogservice-v1
labels:
app: productcatalogservice
version: v1
app.kubernetes.io/name: productcatalogservice
spec:
selector:
matchLabels:
app: productcatalogservice
version: v1
app.kubernetes.io/name: productcatalogservice
template:
metadata:
labels:
app: productcatalogservice
version: v1
app.kubernetes.io/name: productcatalogservice
spec:
terminationGracePeriodSeconds: 5
containers:
Expand Down Expand Up @@ -299,12 +254,11 @@ kind: Service
metadata:
name: productcatalogservice
labels:
app: productcatalogservice
version: v1
app.kubernetes.io/name: productcatalogservice
spec:
type: ClusterIP
selector:
app: productcatalogservice
app.kubernetes.io/name: productcatalogservice
ports:
- name: http
port: 8070
Expand Down
73 changes: 72 additions & 1 deletion kardinal/reconciler/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package reconciler

import (
"context"

"github.com/brunoga/deep"
"github.com/kurtosis-tech/stacktrace"
"github.com/sirupsen/logrus"
Expand All @@ -11,6 +10,20 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
)

const (
// Thi is a common label used in several applications and recommended by Kubernetes: https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/
appNameKubernetesLabelKey = "app.kubernetes.io/name"
appLabelKey = "app"
versionLabelKey = "version"
defaultVersionLabelValue = "baseline"
)

type labeledResources interface {
GetLabels() map[string]string
SetLabels(labels map[string]string)
GetName() string
}

func Reconcile(ctx context.Context, cl client.Client) error {
logrus.Info("Reconciling")

Expand All @@ -20,6 +33,11 @@ func Reconcile(ctx context.Context, cl client.Client) error {
if err != nil {
return stacktrace.Propagate(err, "An error occurred retrieving the list of resources")
}

if err := reconcileIstioLabelsForBaselineServicesAndDeployments(ctx, cl, clusterResources); err != nil {
return stacktrace.Propagate(err, "An error occurred reconciling the Istio labels")
}

// Generate base cluster topology
logrus.Info("Generate base cluster topology")
baseClusterTopology, err := topology.NewClusterTopologyFromResources(clusterResources)
Expand Down Expand Up @@ -95,3 +113,56 @@ func Reconcile(ctx context.Context, cl client.Client) error {

return nil
}

// OPERATOR-TODO make sure to execute this again once we connect the operator to listen to k8s Deployments and Services events
// OPERATOR-TODO there is another approach we could take, if it doesn't works for all use cases, which is to use MutatingAdmissionWebHooks
// related info for this here: https://book.kubebuilder.io/cronjob-tutorial/webhook-implementation and particularly this https://book.kubebuilder.io/reference/webhook-for-core-types
// for creating and webhook for these core types.
func reconcileIstioLabelsForBaselineServicesAndDeployments(ctx context.Context, cl client.Client, clusterResources *resources.Resources) error {
for _, namespace := range clusterResources.Namespaces {
for _, service := range namespace.Services {
ensureIstioLabelsForResource(service)
if err := cl.Update(ctx, service); err != nil {
return stacktrace.Propagate(err, "An error occurred adding Istio labels to service '%s'", service.GetName())
}
}

for _, deployment := range namespace.Deployments {
ensureIstioLabelsForResource(deployment)
if err := cl.Update(ctx, deployment); err != nil {
return stacktrace.Propagate(err, "An error occurred adding Istio labels to deployment '%s'", deployment.GetName())
}
}
}
return nil
}

func ensureIstioLabelsForResource(resource labeledResources) error {

labels := resource.GetLabels()
if labels == nil {
labels = map[string]string{}
}

// The 'app' label
_, ok := labels[appLabelKey]
if !ok {
appNameKubernetesLabelValue, ok := labels[appNameKubernetesLabelKey]
if ok {
labels[appLabelKey] = appNameKubernetesLabelValue
} else {
labels[appLabelKey] = resource.GetName()
}
}

// The 'version' label
// OPERATOR-TODO how are we going to handle when a non-managed resource already has the "version" label and
// this value is different from the value needed for managing the baseline traffic
_, ok = labels[versionLabelKey]
if !ok {
labels[versionLabelKey] = defaultVersionLabelValue
}
resource.SetLabels(labels)

return nil
}
2 changes: 0 additions & 2 deletions kardinal/resources/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,6 @@ func ApplyServiceResources(ctx context.Context, clusterResources *Resources, clu
}
}
}
// OPERATOR-TODO: Set app and version labels on non-managed service if not already set.
// Those labels are required by Istio.
}
}
}
Expand Down

0 comments on commit 96dbf66

Please sign in to comment.