Skip to content

Commit

Permalink
Use more targeted NetworkPolicies (#25)
Browse files Browse the repository at this point in the history
In #4, we added a NetworkPolicy. The intent was to prevent the Redis
and/or Sentinel pods from differing RedisFailovers from joining up with
one another (See:
spotahome#550). These policies
have proven to be too coarsely grained. We end up deploying supplemental
NetworkPolicies to allow ingress traffic.

This change narrows the scope of the NetworkPolicies manged by the
operator. One policy allows traffic to the Redis node pods ONLY on the
redis port and monitoring port for traffic originating from within the
namespace. The other policy allows traffic to the Sentinel pods ONLY on
the sentinel port for traffic originating from within the namespace. All
other traffic to these pods will be dropped.

Connections to the HAProxy pods - IE access to the redis master node -
will now be allowed by default. This achieves the goals of #4 and allows
us to stop littering additional NetworkPolicies to allow external
communication with a Redis instance.
  • Loading branch information
indiebrain authored Dec 14, 2023
1 parent 1ae4e40 commit a971847
Show file tree
Hide file tree
Showing 9 changed files with 605 additions and 46 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Check [releases](https://github.com/spotahome/redis-operator/releases) section f

## Unreleased

- [Use finer grained NetworkPolicies](https://github.com/powerhome/redis-operator/pull/25)
- [Fix PodDisruptionBudget deprecation warnings on kube 1.21+](https://github.com/powerhome/redis-operator/pull/19)

## [v1.1.0-rc.3] - 2022-01-19
Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION := v1.3.0-rc0
VERSION := v1.7.1-rc1

# Name of this service/application
SERVICE_NAME := redis-operator
Expand Down Expand Up @@ -31,11 +31,11 @@ BRANCH=$(shell git rev-parse --abbrev-ref HEAD)

TAG := $(GITTAG)
ifneq ($(COMMIT), $(GITTAG_COMMIT))
TAG := $(COMMIT)
TAG := $(COMMIT)
endif

ifneq ($(shell git status --porcelain),)
TAG := $(TAG)-dirty
TAG := $(TAG)-dirty
endif


Expand Down
42 changes: 28 additions & 14 deletions mocks/operator/redisfailover/service/RedisFailoverClient.go

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

5 changes: 4 additions & 1 deletion operator/redisfailover/ensurer.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ func (w *RedisFailoverHandler) Ensure(rf *redisfailoverv1.RedisFailover, labels
}

if !(len(rf.Spec.NetworkPolicyNsList) == 0) {
if err := w.rfService.EnsureNetworkPolicy(rf, labels, or); err != nil {
if err := w.rfService.EnsureRedisNetworkPolicy(rf, labels, or); err != nil {
return err
}
if err := w.rfService.EnsureSentinelNetworkPolicy(rf, labels, or); err != nil {
return err
}
}
Expand Down
19 changes: 14 additions & 5 deletions operator/redisfailover/service/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ type RedisFailoverClient interface {
EnsureHAProxyConfigmap(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
EnsureHAProxyService(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
EnsureRedisHeadlessService(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
EnsureNetworkPolicy(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
EnsureRedisNetworkPolicy(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
EnsureSentinelNetworkPolicy(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
EnsureSentinelService(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
EnsureSentinelConfigMap(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
EnsureSentinelDeployment(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error
Expand Down Expand Up @@ -80,11 +81,19 @@ func generateComponentLabel(componentType string) map[string]string {
}
}

// EnsureNetworkPolicy makes sure the network policy exists
func (r *RedisFailoverKubeClient) EnsureNetworkPolicy(rf *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error {
svc := generateNetworkPolicy(rf, labels, ownerRefs)
// EnsureRedisNetworkPolicy makes sure the redis network policy exists
func (r *RedisFailoverKubeClient) EnsureRedisNetworkPolicy(rf *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error {
svc := generateRedisNetworkPolicy(rf, labels, ownerRefs)
err := r.K8SService.CreateOrUpdateNetworkPolicy(rf.Namespace, svc)
r.setEnsureOperationMetrics(svc.Namespace, svc.Name, "NetworkPolicy", rf.Name, err)
r.setEnsureOperationMetrics(svc.Namespace, svc.Name, "EnsureRedisNetworkPolicy", rf.Name, err)
return err
}

// EnsureSentinelNetworkPolicy makes sure the redis network policy exists
func (r *RedisFailoverKubeClient) EnsureSentinelNetworkPolicy(rf *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error {
svc := generateSentinelNetworkPolicy(rf, labels, ownerRefs)
err := r.K8SService.CreateOrUpdateNetworkPolicy(rf.Namespace, svc)
r.setEnsureOperationMetrics(svc.Namespace, svc.Name, "EnsureSentinelNetworkPolicy", rf.Name, err)
return err
}

Expand Down
29 changes: 15 additions & 14 deletions operator/redisfailover/service/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,21 @@ const (
)

const (
baseName = "rf"
sentinelName = "s"
sentinelRoleName = "sentinel"
sentinelConfigFileName = "sentinel.conf"
redisConfigFileName = "redis.conf"
redisName = "r"
redisMasterName = "rm"
redisSlaveName = "rs"
redisShutdownName = "r-s"
redisReadinessName = "r-readiness"
redisRoleName = "redis"
appLabel = "redis-failover"
hostnameTopologyKey = "kubernetes.io/hostname"
networkPolicyName = "network-policy"
baseName = "rf"
sentinelName = "s"
sentinelRoleName = "sentinel"
sentinelConfigFileName = "sentinel.conf"
sentinelNetworkPolicyName = "s-np"
redisConfigFileName = "redis.conf"
redisName = "r"
redisNetworkPolicyName = "r-np"
redisMasterName = "rm"
redisSlaveName = "rs"
redisShutdownName = "r-s"
redisReadinessName = "r-readiness"
redisRoleName = "redis"
appLabel = "redis-failover"
hostnameTopologyKey = "kubernetes.io/hostname"
)

const (
Expand Down
66 changes: 60 additions & 6 deletions operator/redisfailover/service/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,16 +281,15 @@ func generateHAProxyService(rf *redisfailoverv1.RedisFailover, labels map[string
}
}

func generateNetworkPolicy(rf *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) *np.NetworkPolicy {
name := GetNetworkPolicyName(rf)
func generateRedisNetworkPolicy(rf *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) *np.NetworkPolicy {
name := GetRedisNetworkPolicyName(rf)
namespace := rf.Namespace

networkPolicyNsList := rf.Spec.NetworkPolicyNsList

selectorLabels := generateSelectorLabels(networkPolicyName, rf.Name)
selectorLabels := generateSelectorLabels(redisRoleName, rf.Name)
labels = util.MergeLabels(labels, selectorLabels)

sentinelTargetPort := intstr.FromInt(int(rf.Spec.Sentinel.Port))
metricsTargetPort := intstr.FromInt(9121)
redisTargetPort := intstr.FromInt(int(rf.Spec.Redis.Port))

Expand All @@ -313,7 +312,59 @@ func generateNetworkPolicy(rf *redisfailoverv1.RedisFailover, labels map[string]
Port: &redisTargetPort,
}, np.NetworkPolicyPort{
Port: &metricsTargetPort,
}, np.NetworkPolicyPort{
})

return &np.NetworkPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: labels,
OwnerReferences: ownerRefs,
},
Spec: np.NetworkPolicySpec{
PodSelector: metav1.LabelSelector{
MatchLabels: util.MergeLabels(
map[string]string{"redisfailovers.databases.spotahome.com/name": rf.Name},
generateComponentLabel("redis"),
),
},
Ingress: []np.NetworkPolicyIngressRule{
np.NetworkPolicyIngressRule{
From: peers,
Ports: ports,
},
},
},
}
}

func generateSentinelNetworkPolicy(rf *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) *np.NetworkPolicy {
name := GetSentinelNetworkPolicyName(rf)
namespace := rf.Namespace

networkPolicyNsList := rf.Spec.NetworkPolicyNsList

selectorLabels := generateSelectorLabels(sentinelRoleName, rf.Name)
labels = util.MergeLabels(labels, selectorLabels)

sentinelTargetPort := intstr.FromInt(int(rf.Spec.Sentinel.Port))

peers := []np.NetworkPolicyPeer{}

for _, inputPeer := range networkPolicyNsList {

labelKey := inputPeer.MatchLabelKey
labelValue := inputPeer.MatchLabelValue

peers = append(peers, np.NetworkPolicyPeer{
NamespaceSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{labelKey: labelValue},
},
})
}

ports := make([]np.NetworkPolicyPort, 0)
ports = append(ports, np.NetworkPolicyPort{
Port: &sentinelTargetPort,
})

Expand All @@ -326,7 +377,10 @@ func generateNetworkPolicy(rf *redisfailoverv1.RedisFailover, labels map[string]
},
Spec: np.NetworkPolicySpec{
PodSelector: metav1.LabelSelector{
MatchLabels: map[string]string{"redisfailovers.databases.spotahome.com/name": rf.Name},
MatchLabels: util.MergeLabels(
map[string]string{"redisfailovers.databases.spotahome.com/name": rf.Name},
generateComponentLabel("sentinel"),
),
},
Ingress: []np.NetworkPolicyIngressRule{
np.NetworkPolicyIngressRule{
Expand Down
Loading

0 comments on commit a971847

Please sign in to comment.