Repository: m3db/m3db-operator
Pull request #202 (2020-02-24 02:22:40)

[api] Add support for hostNetwork
This is to address the proposal as https://github.com/m3db/m3db-operator/issues/201

In this PR, we enabled m3dbCluster CRD able to pass [HostNetwork](https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces) and [DnsPolicy](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy) to the stateful sets for m3db nodes to boost network performance in some k8s environment. 

I already tested in our environment that the big network improvement for m3db nodes as well as the performance improvement of the whole cluster due to this. Note: All these two configs are not set by default so that for the environment can not benefit from hostNetwork setting, it is a no-op. 


claassistantio: [![CLA assistant check](https://cla-assistant.io/pull/badge/not_signed)](https://cla-assistant.io/m3db/m3db-operator?pullRequest=202) <br/>Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our [Contributor License Agreement](https://cla-assistant.io/m3db/m3db-operator?pullRequest=202) before we can accept your contribution.<br/><sub>You have signed the CLA already but the status is still pending? Let us [recheck](https://cla-assistant.io/check/m3db/m3db-operator?pullRequest=202) it.</sub>
codecov[bot]: # [Codecov](https://codecov.io/gh/m3db/m3db-operator/pull/202?src=pr&el=h1) Report
> Merging [#202](https://codecov.io/gh/m3db/m3db-operator/pull/202?src=pr&el=desc) into [master](https://codecov.io/gh/m3db/m3db-operator/commit/e83a5943bbb5246711cf5182c553e83579722a37?src=pr&el=desc) will **decrease** coverage by `0.07%`.
> The diff coverage is `100%`.


[![Impacted file tree graph](https://codecov.io/gh/m3db/m3db-operator/pull/202/graphs/tree.svg?width=650&token=jtHDyWhsto&height=150&src=pr)](https://codecov.io/gh/m3db/m3db-operator/pull/202?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #202      +/-   ##
==========================================
- Coverage   75.33%   75.26%   -0.08%     
==========================================
  Files          30       30              
  Lines        2092     2094       +2     
==========================================
  Hits         1576     1576              
- Misses        390      391       +1     
- Partials      126      127       +1
```


------

[Continue to review full report at Codecov](https://codecov.io/gh/m3db/m3db-operator/pull/202?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/m3db/m3db-operator/pull/202?src=pr&el=footer). Last update [e83a594...8ee8009](https://codecov.io/gh/m3db/m3db-operator/pull/202?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

schallert: Thank you for the contribution, @yuecong! I made a few tweaks to tests and updated the docs, but this worked in my test environment. Please let me know if you have any issues with it.

Patch:
diff --git a/docs/api.md b/docs/api.md
index 0cc566a..de116f9 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -60,6 +60,8 @@ ClusterSpec defines the desired state for a M3 cluster to be converge to.
 | tolerations | Tolerations sets the tolerations that will be applied to all M3DB pods. | []corev1.Toleration | false |
 | priorityClassName | PriorityClassName sets the priority class for all M3DB pods. | string | false |
 | nodeEndpointFormat | NodeEndpointFormat allows overriding of the endpoint used for a node in the M3DB placement. Defaults to \"{{ .PodName }}.{{ .M3DBService }}:{{ .Port }}\". Useful if access to the cluster from other namespaces is desired. See \"Node Endpoint\" docs for full variables available. | string | false |
+| hostNetwork | HostNetwork indicates whether M3DB pods should run in the same network namespace as the node its on. This option should be used sparingly due to security concerns outlined in the linked documentation. https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces | bool | false |
+| dnsPolicy | DNSPolicy allows the user to set the pod's DNSPolicy. This is often used in conjunction with HostNetwork.+optional | *corev1.DNSPolicy | false |
 
 [Back to TOC](#table-of-contents)
 
diff --git a/pkg/apis/m3dboperator/v1alpha1/cluster.go b/pkg/apis/m3dboperator/v1alpha1/cluster.go
index 8bddf36..303339b 100644
--- a/pkg/apis/m3dboperator/v1alpha1/cluster.go
+++ b/pkg/apis/m3dboperator/v1alpha1/cluster.go
@@ -265,6 +265,18 @@ type ClusterSpec struct {
 	// Endpoint" docs for full variables available.
 	// +optional
 	NodeEndpointFormat string `json:"nodeEndpointFormat,omitempty"`
+
+	// HostNetwork indicates whether M3DB pods should run in the same network
+	// namespace as the node its on. This option should be used sparingly due to
+	// security concerns outlined in the linked documentation.
+	// https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces
+	// +optional
+	HostNetwork bool `json:"hostNetwork,omitEmpty"`
+
+	// DNSPolicy allows the user to set the pod's DNSPolicy. This is often used in
+	// conjunction with HostNetwork.+optional
+	// +optional
+	DNSPolicy *corev1.DNSPolicy `json:"dnsPolicy,omitEmpty"`
 }
 
 // NodeAffinityTerm represents a node label and a set of label values, any of
diff --git a/pkg/apis/m3dboperator/v1alpha1/openapi_generated.go b/pkg/apis/m3dboperator/v1alpha1/openapi_generated.go
index 922e37b..8bd7fc7 100644
--- a/pkg/apis/m3dboperator/v1alpha1/openapi_generated.go
+++ b/pkg/apis/m3dboperator/v1alpha1/openapi_generated.go
@@ -344,6 +344,20 @@ func schema_pkg_apis_m3dboperator_v1alpha1_ClusterSpec(ref common.ReferenceCallb
 				Description: "ClusterSpec defines the desired state for a M3 cluster to be converge to.",
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
+					"HostNetwork": {
+						SchemaProps: spec.SchemaProps{
+							Description: "HostNetwork indicates whether M3DB pods should run in the same network namespace as the node its on. This option should be used sparingly due to security concerns outlined in the linked documentation. https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces",
+							Type:        []string{"boolean"},
+							Format:      "",
+						},
+					},
+					"DNSPolicy": {
+						SchemaProps: spec.SchemaProps{
+							Description: "DNSPolicy allows the user to set the pod's DNSPolicy.",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
 					"image": {
 						SchemaProps: spec.SchemaProps{
 							Description: "Image specifies which docker image to use with the cluster",
diff --git a/pkg/apis/m3dboperator/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/m3dboperator/v1alpha1/zz_generated.deepcopy.go
index 531412e..132934b 100644
--- a/pkg/apis/m3dboperator/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/m3dboperator/v1alpha1/zz_generated.deepcopy.go
@@ -48,6 +48,11 @@ func (in *ClusterCondition) DeepCopy() *ClusterCondition {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
 	*out = *in
+	if in.DNSPolicy != nil {
+		in, out := &in.DNSPolicy, &out.DNSPolicy
+		*out = new(v1.DNSPolicy)
+		**out = **in
+	}
 	if in.IsolationGroups != nil {
 		in, out := &in.IsolationGroups, &out.IsolationGroups
 		*out = make([]IsolationGroup, len(*in))
diff --git a/pkg/k8sops/m3db/generators.go b/pkg/k8sops/m3db/generators.go
index 412147f..1c166ff 100644
--- a/pkg/k8sops/m3db/generators.go
+++ b/pkg/k8sops/m3db/generators.go
@@ -154,6 +154,10 @@ func GenerateStatefulSet(
 	m3dbContainer.Ports = generateContainerPorts(cluster)
 	statefulSet.Spec.Template.Spec.Affinity = affinity
 	statefulSet.Spec.Template.Spec.Tolerations = cluster.Spec.Tolerations
+	statefulSet.Spec.Template.Spec.HostNetwork = cluster.Spec.HostNetwork
+	if cluster.Spec.DNSPolicy != nil {
+		statefulSet.Spec.Template.Spec.DNSPolicy = *cluster.Spec.DNSPolicy
+	}
 
 	// Set owner ref so sts will be GC'd when the cluster is deleted
 	clusterRef := GenerateOwnerRef(cluster)


Test patch:
diff --git a/pkg/k8sops/m3db/generators_test.go b/pkg/k8sops/m3db/generators_test.go
index 09497de..42397e6 100644
--- a/pkg/k8sops/m3db/generators_test.go
+++ b/pkg/k8sops/m3db/generators_test.go
@@ -451,6 +451,21 @@ func TestGenerateStatefulSet(t *testing.T) {
 		diff, _ := messagediff.PrettyDiff(ss, newSS)
 		t.Log(diff)
 	}
+
+	fixture = getFixture("testM3DBCluster.yaml", t)
+	fixture.Spec.HostNetwork = true
+	fixture.Spec.DNSPolicy = (*v1.DNSPolicy)(pointer.StringPtr(string(v1.DNSClusterFirstWithHostNet)))
+
+	ss = baseSS.DeepCopy()
+	ss.Spec.Template.Spec.HostNetwork = true
+	ss.Spec.Template.Spec.DNSPolicy = v1.DNSClusterFirstWithHostNet
+	newSS, err = GenerateStatefulSet(fixture, isolationGroup, *instanceAmount)
+	assert.NoError(t, err)
+	assert.NotNil(t, newSS)
+	if !assert.Equal(t, ss, newSS) {
+		diff, _ := messagediff.PrettyDiff(ss, newSS)
+		t.Log(diff)
+	}
 }
 
 func TestGenerateM3DBService(t *testing.T) {