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

Run Envoy Gateway like DaemonSet #3092

Merged
merged 1 commit into from
Apr 20, 2024
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
13 changes: 11 additions & 2 deletions api/v1alpha1/envoyproxy_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,20 @@ func (r *EnvoyProxyProvider) GetEnvoyProxyKubeProvider() *EnvoyProxyKubernetesPr
return r.Kubernetes
}

if r.Kubernetes.EnvoyDeployment == nil {
// if EnvoyDeployment and EnvoyDaemonSet are both nil, use EnvoyDeployment
if r.Kubernetes.EnvoyDeployment == nil && r.Kubernetes.EnvoyDaemonSet == nil {
r.Kubernetes.EnvoyDeployment = DefaultKubernetesDeployment(DefaultEnvoyProxyImage)
}

r.Kubernetes.EnvoyDeployment.defaultKubernetesDeploymentSpec(DefaultEnvoyProxyImage)
// if use EnvoyDeployment, set default values
if r.Kubernetes.EnvoyDeployment != nil {
r.Kubernetes.EnvoyDeployment.defaultKubernetesDeploymentSpec(DefaultEnvoyProxyImage)
}

// if use EnvoyDaemonSet, set default values
if r.Kubernetes.EnvoyDaemonSet != nil {
r.Kubernetes.EnvoyDaemonSet.defaultKubernetesDaemonSetSpec(DefaultEnvoyProxyImage)
}

if r.Kubernetes.EnvoyService == nil {
r.Kubernetes.EnvoyService = DefaultKubernetesService()
Expand Down
9 changes: 9 additions & 0 deletions api/v1alpha1/envoyproxy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ type ShutdownConfig struct {
MinDrainDuration *metav1.Duration `json:"minDrainDuration,omitempty"`
}

// +kubebuilder:validation:XValidation:rule="((has(self.envoyDeployment) && !has(self.envoyDaemonSet)) || (!has(self.envoyDeployment) && has(self.envoyDaemonSet))) || (!has(self.envoyDeployment) && !has(self.envoyDaemonSet))",message="only one of envoyDeployment or envoyDaemonSet can be specified"
// +kubebuilder:validation:XValidation:rule="((has(self.envoyHpa) && !has(self.envoyDaemonSet)) || (!has(self.envoyHpa) && has(self.envoyDaemonSet))) || (!has(self.envoyHpa) && !has(self.envoyDaemonSet))",message="cannot use envoyHpa if envoyDaemonSet is used"
//
// EnvoyProxyKubernetesProvider defines configuration for the Kubernetes resource
// provider.
type EnvoyProxyKubernetesProvider struct {
Expand All @@ -228,6 +231,12 @@ type EnvoyProxyKubernetesProvider struct {
// +optional
EnvoyDeployment *KubernetesDeploymentSpec `json:"envoyDeployment,omitempty"`

// EnvoyDaemonSet defines the desired state of the Envoy daemonset resource.
// Disabled by default, a deployment resource is used instead to provision the Envoy Proxy fleet
//
// +optional
EnvoyDaemonSet *KubernetesDaemonSetSpec `json:"envoyDaemonSet,omitempty"`

// EnvoyService defines the desired state of the Envoy service resource.
// If unspecified, default settings for the managed Envoy service resource
// are applied.
Expand Down
75 changes: 75 additions & 0 deletions api/v1alpha1/kubernetes_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ func DefaultKubernetesDeploymentStrategy() *appv1.DeploymentStrategy {
}
}

// DefaultKubernetesDaemonSetStrategy returns the default daemonset strategy settings.
func DefaultKubernetesDaemonSetStrategy() *appv1.DaemonSetUpdateStrategy {
return &appv1.DaemonSetUpdateStrategy{
Type: appv1.RollingUpdateDaemonSetStrategyType,
}
}

// DefaultKubernetesContainerImage returns the default envoyproxy image.
func DefaultKubernetesContainerImage(image string) *string {
return ptr.To(image)
Expand All @@ -38,6 +45,15 @@ func DefaultKubernetesDeployment(image string) *KubernetesDeploymentSpec {
}
}

// DefaultKubernetesDaemonSet returns a new DefaultKubernetesDaemonSet with default settings.
func DefaultKubernetesDaemonSet(image string) *KubernetesDaemonSetSpec {
return &KubernetesDaemonSetSpec{
Strategy: DefaultKubernetesDaemonSetStrategy(),
Pod: DefaultKubernetesPod(),
Container: DefaultKubernetesContainer(image),
}
}

// DefaultKubernetesPod returns a new KubernetesPodSpec with default settings.
func DefaultKubernetesPod() *KubernetesPodSpec {
return &KubernetesPodSpec{}
Expand Down Expand Up @@ -110,6 +126,29 @@ func (deployment *KubernetesDeploymentSpec) defaultKubernetesDeploymentSpec(imag
}
}

// defaultKubernetesDaemonSetSpec fill a default KubernetesDaemonSetSpec if unspecified.
func (daemonset *KubernetesDaemonSetSpec) defaultKubernetesDaemonSetSpec(image string) {
if daemonset.Strategy == nil {
daemonset.Strategy = DefaultKubernetesDaemonSetStrategy()
}

if daemonset.Pod == nil {
daemonset.Pod = DefaultKubernetesPod()
}

if daemonset.Container == nil {
daemonset.Container = DefaultKubernetesContainer(image)
}

if daemonset.Container.Resources == nil {
daemonset.Container.Resources = DefaultResourceRequirements()
}

if daemonset.Container.Image == nil {
daemonset.Container.Image = DefaultKubernetesContainerImage(image)
}
}

// setDefault fill a default HorizontalPodAutoscalerSpec if unspecified
func (hpa *KubernetesHorizontalPodAutoscalerSpec) setDefault() {
if len(hpa.Metrics) == 0 {
Expand Down Expand Up @@ -153,6 +192,42 @@ func (deployment *KubernetesDeploymentSpec) ApplyMergePatch(old *appv1.Deploymen
return &patchedDeployment, nil
}

// ApplyMergePatch applies a merge patch to a daemonset based on the merge type
func (daemonset *KubernetesDaemonSetSpec) ApplyMergePatch(old *appv1.DaemonSet) (*appv1.DaemonSet, error) {
if daemonset.Patch == nil {
return old, nil
}

var patchedJSON []byte
var err error

// Serialize the current daemonset to JSON
originalJSON, err := json.Marshal(old)
if err != nil {
return nil, fmt.Errorf("error marshaling original daemonset: %w", err)
}

switch {
case daemonset.Patch.Type == nil || *daemonset.Patch.Type == StrategicMerge:
patchedJSON, err = strategicpatch.StrategicMergePatch(originalJSON, daemonset.Patch.Value.Raw, appv1.DaemonSet{})
case *daemonset.Patch.Type == JSONMerge:
patchedJSON, err = jsonpatch.MergePatch(originalJSON, daemonset.Patch.Value.Raw)
default:
return nil, fmt.Errorf("unsupported merge type: %s", *daemonset.Patch.Type)
}
if err != nil {
return nil, fmt.Errorf("error applying merge patch: %w", err)
}

// Deserialize the patched JSON into a new daemonset object
var patchedDaemonSet appv1.DaemonSet
if err := json.Unmarshal(patchedJSON, &patchedDaemonSet); err != nil {
return nil, fmt.Errorf("error unmarshaling patched daemonset: %w", err)
}

return &patchedDaemonSet, nil
}

// ApplyMergePatch applies a merge patch to a service based on the merge type
func (service *KubernetesServiceSpec) ApplyMergePatch(old *corev1.Service) (*corev1.Service, error) {
if service.Patch == nil {
Expand Down
22 changes: 22 additions & 0 deletions api/v1alpha1/shared_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,28 @@ type KubernetesDeploymentSpec struct {
// TODO: Expose config as use cases are better understood, e.g. labels.
}

// KubernetesDaemonsetSpec defines the desired state of the Kubernetes daemonset resource.
type KubernetesDaemonSetSpec struct {
// Patch defines how to perform the patch operation to daemonset
//
// +optional
Patch *KubernetesPatchSpec `json:"patch,omitempty"`

// The daemonset strategy to use to replace existing pods with new ones.
// +optional
Strategy *appv1.DaemonSetUpdateStrategy `json:"strategy,omitempty"`

// Pod defines the desired specification of pod.
//
// +optional
Pod *KubernetesPodSpec `json:"pod,omitempty"`

// Container defines the desired specification of main container.
//
// +optional
Container *KubernetesContainerSpec `json:"container,omitempty"`
}

// KubernetesPodSpec defines the desired state of the Kubernetes pod resource.
type KubernetesPodSpec struct {
// Annotations are the annotations that should be appended to the pods.
Expand Down
40 changes: 40 additions & 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.

Loading
Loading