Skip to content

Commit 369f311

Browse files
authored
Merge pull request #33 from marklogic/release/ea2
2 parents 55c1477 + 77c5588 commit 369f311

35 files changed

+22127
-9272
lines changed

Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ endif
5151
OPERATOR_SDK_VERSION ?= v1.34.2
5252

5353
# Image URL to use all building/pushing image targets
54-
IMG ?= ml-marklogic-operator-dev.bed-artifactory.bedford.progress.com/marklogic-kubernetes-operator:0.0.1
54+
IMG ?= ml-marklogic-operator-dev.bed-artifactory.bedford.progress.com/marklogic-kubernetes-operator:1.0.0-ea2
5555
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
5656
ENVTEST_K8S_VERSION = 1.28.3
5757

@@ -152,7 +152,7 @@ run: manifests generate fmt vet ## Run a controller from your host.
152152
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
153153
.PHONY: docker-build
154154
docker-build: ## Build docker image with the manager.
155-
$(CONTAINER_TOOL) build -t ${IMG} .
155+
$(CONTAINER_TOOL) build --platform="linux/amd64" -t ${IMG} .
156156

157157
.PHONY: docker-push
158158
docker-push: ## Push docker image with the manager.
@@ -183,7 +183,7 @@ endif
183183

184184
.PHONY: install
185185
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
186-
$(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f -
186+
$(KUSTOMIZE) build config/crd | $(KUBECTL) apply --server-side -f -
187187

188188
.PHONY: uninstall
189189
uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
@@ -192,7 +192,7 @@ uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified
192192
.PHONY: deploy
193193
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
194194
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
195-
$(KUSTOMIZE) build config/default | $(KUBECTL) apply -f -
195+
$(KUSTOMIZE) build config/default | $(KUBECTL) apply --server-side -f -
196196

197197
.PHONY: undeploy
198198
undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.

README.md

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ helm repo update
2828
```
2929
3. Install the Helm Chart for MarkLogic Operator:
3030
```sh
31-
helm upgrade marklogic-operator marklogic-private/marklogic-operator --version=1.0.0-ea1 --install --namespace marklogic-operator-system --create-namespace
31+
helm upgrade marklogic-operator marklogic-private/marklogic-operator --version=1.0.0-ea2 --install --namespace marklogic-operator-system --create-namespace
3232
```
3333
4. Check the Operator Pod and make sure it is in Running state:
3434
```sh
@@ -69,4 +69,52 @@ helm upgrade marklogic-operator ./charts/marklogic-operator --install --namespac
6969
Once MarkLogic Operator is installed, go to config/samples folder and pick one sample file to deploy. For example, to deploy marklogic single group, use the following script:
7070
```sh
7171
kubectl apply -f marklogicgroup.yaml
72-
```
72+
```
73+
74+
### Configure HAProxy Load Balancer
75+
HAProxy is provided as a load balancer configured to support cookie-based session affinity and multi-statement transactions. These configurations are needed by some MarkLogic client applications, like mlcp. HAProxy is recommended for production workloads.
76+
77+
#### Enable the HAProxy Load Balancer
78+
The HAProxy Load Balancer is disabled by default. To enable it, provide the following configuration in the crd yaml file to be used for cluster creation:
79+
```
80+
haproxy:
81+
enabled: true
82+
```
83+
#### Configuration
84+
HAProxy can be configured for cluster. To setup the access for default App Servers for 8000, 8001 and 8002, uncomment the appServer seciton in marklogicgroup.yaml.
85+
```
86+
appServers:
87+
- name: "app-service"
88+
port: 8000
89+
path: "/console"
90+
- name: "admin"
91+
port: 8001
92+
path: "/adminUI"
93+
- name: "manage"
94+
port: 8002
95+
path: "/manage"
96+
```
97+
Ports can be configured for additional app servers. For example, to add port 8010 for HTTP load balancing, add this configuration to the marklogicgroup.yaml file appServer section:
98+
```
99+
- name: my-app-1
100+
port: 8010
101+
targetPort: 8010
102+
```
103+
#### Access HA Proxy
104+
The HAProxy can be accessed from a service with the name of marklogic-haproxy.
105+
106+
#### External access
107+
By default, HAProxy is configured to provide access within the Kubernetes cluster. However, HAProxy can provide external access by setting the service type in the marklogicgroup.yaml file:
108+
```
109+
haproxy:
110+
service:
111+
type: LoadBalancer
112+
```
113+
114+
> [!WARNING]
115+
> Please note, by setting the haproxy service type to LoadBalancer, the MarkLogic endpoint is exposed to the public internet. Because of this, networkPolicy should be set to limit the sources that can visit MarkLogic.
116+
117+
## Known Issues and Limitations
118+
119+
1. The latest released version of fluent/fluent-bit:3.1.1 has known high and critical security vulnerabilities. If you decide to enable the log collection feature, choose and deploy the fluent-bit or an alternate image with no vulnerabilities as per your requirements.
120+
2. Known Issues and Limitations for the MarkLogic Server Docker image can be viewed using the link: https://github.com/marklogic/marklogic-docker?tab=readme-ov-file#Known-Issues-and-Limitations.

api/v1alpha1/common_types.go

Lines changed: 110 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package v1alpha1
22

33
import (
44
corev1 "k8s.io/api/core/v1"
5+
networkingv1 "k8s.io/api/networking/v1"
6+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
57
)
68

79
type ContainerProbe struct {
@@ -20,8 +22,9 @@ type ContainerProbe struct {
2022

2123
// Storage is the inteface to add pvc and pv support in marklogic
2224
type Storage struct {
23-
Size string `json:"size,omitempty"`
24-
VolumeMount VolumeMountWrapper `json:"volumeMount,omitempty"`
25+
Size string `json:"size,omitempty"`
26+
VolumeMount VolumeMountWrapper `json:"volumeMount,omitempty"`
27+
StorageClass string `json:"storageClass,omitempty"`
2528
}
2629

2730
type HugePages struct {
@@ -30,6 +33,13 @@ type HugePages struct {
3033
MountPath string `json:"mountPath,omitempty"`
3134
}
3235

36+
type Service struct {
37+
// +kubebuilder:default:= ClusterIP
38+
Type corev1.ServiceType `json:"type,omitempty"`
39+
AdditionalPorts []corev1.ServicePort `json:"additionalPorts,omitempty"`
40+
Annotations map[string]string `json:"annotations,omitempty"`
41+
}
42+
3343
type VolumeMountWrapper struct {
3444
Volume []corev1.Volume `json:"volume,omitempty"`
3545
MountPath []corev1.VolumeMount `json:"mountPath,omitempty"`
@@ -40,3 +50,101 @@ type AdminAuth struct {
4050
AdminPassword *string `json:"adminPassword,omitempty"`
4151
WalletPassword *string `json:"walletPassword,omitempty"`
4252
}
53+
54+
type LogCollection struct {
55+
Enabled bool `json:"enabled,omitempty"`
56+
Image string `json:"image,omitempty"`
57+
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
58+
Files LogFilesConfig `json:"files,omitempty"`
59+
Outputs string `json:"outputs,omitempty"`
60+
}
61+
62+
type LogFilesConfig struct {
63+
ErrorLogs bool `json:"errorLogs,omitempty"`
64+
AccessLogs bool `json:"accessLogs,omitempty"`
65+
RequestLogs bool `json:"requestLogs,omitempty"`
66+
CrashLogs bool `json:"crashLogs,omitempty"`
67+
AuditLogs bool `json:"auditLogs,omitempty"`
68+
}
69+
70+
type NetworkPolicy struct {
71+
Enabled bool `json:"enabled,omitempty"`
72+
PolicyTypes []networkingv1.PolicyType `json:"policyTypes,omitempty"`
73+
PodSelector metav1.LabelSelector `json:"podSelector,omitempty"`
74+
Ingress []networkingv1.NetworkPolicyIngressRule `json:"ingress,omitempty"`
75+
Egress []networkingv1.NetworkPolicyEgressRule `json:"egress,omitempty"`
76+
}
77+
type HAProxy struct {
78+
Enabled bool `json:"enabled,omitempty"`
79+
// +kubebuilder:default:="haproxytech/haproxy-alpine:3.1"
80+
Image string `json:"image"`
81+
// +kubebuilder:default:=1
82+
ReplicaCount int32 `json:"replicas,omitempty"`
83+
// +kubebuilder:default:=80
84+
FrontendPort int32 `json:"frontendPort,omitempty"`
85+
// +kubebuilder:default:={{name: "AppServices", type: "http", port: 8000, targetPort: 8000, path: "/console"}, {name: "Admin", type: "http", port: 8001, targetPort: 8001, path: "/adminUI"}, {name: "Manage", type: "http", port: 8002, targetPort: 8002, path: "/manage"}}
86+
AppServers []AppServers `json:"appServers,omitempty"`
87+
// +kubebuilder:default:=true
88+
PathBasedRouting bool `json:"pathBasedRouting,omitempty"`
89+
RestartWhenUpgrade bool `json:"restartWhenUpgrade,omitempty"`
90+
// +kubebuilder:default:={type: ClusterIP}
91+
Service ServiceForHAProxy `json:"service,omitempty"`
92+
// +kubebuilder:default:={enabled: false}
93+
TcpPorts Tcpports `json:"tcpPorts,omitempty"`
94+
// +kubebuilder:default:={client: 600, connect: 600, server: 600}
95+
Timeout Timeout `json:"timeout,omitempty"`
96+
// +kubebuilder:default:={enabled: false, secretName: "", certFileName: ""}
97+
Tls *TlsForHAProxy `json:"tls,omitempty"`
98+
// +kubebuilder:default:={enabled: false, port: 1024, auth: {enabled: false, username: "", password: ""}}
99+
Stats Stats `json:"stats,omitempty"`
100+
Resources corev1.ResourceList `json:"resources,omitempty"`
101+
Affinity *corev1.Affinity `json:"affinity,omitempty"`
102+
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
103+
}
104+
105+
type AppServers struct {
106+
Name string `json:"name,omitempty"`
107+
Type string `json:"type,omitempty"`
108+
Port int32 `json:"port,omitempty"`
109+
TargetPort int32 `json:"targetPort,omitempty"`
110+
Path string `json:"path,omitempty"`
111+
}
112+
113+
type Stats struct {
114+
Enabled bool `json:"enabled,omitempty"`
115+
Port int32 `json:"port,omitempty"`
116+
Auth StatsAuth `json:"auth,omitempty"`
117+
}
118+
119+
type StatsAuth struct {
120+
Enabled bool `json:"enabled,omitempty"`
121+
Username string `json:"username,omitempty"`
122+
Password string `json:"password,omitempty"`
123+
}
124+
125+
type ServiceForHAProxy struct {
126+
Type corev1.ServiceType `json:"type,omitempty"`
127+
}
128+
129+
type Tcpports struct {
130+
Enabled bool `json:"enabled,omitempty"`
131+
Ports []TcpPort `json:"ports,omitempty"`
132+
}
133+
134+
type TcpPort struct {
135+
Port int32 `json:"port,omitempty"`
136+
Name string `json:"name,omitempty"`
137+
Type string `json:"type,omitempty"`
138+
}
139+
140+
type Timeout struct {
141+
Client int32 `json:"client,omitempty"`
142+
Connect int32 `json:"connect,omitempty"`
143+
Server int32 `json:"server,omitempty"`
144+
}
145+
146+
type TlsForHAProxy struct {
147+
Enabled bool `json:"enabled,omitempty"`
148+
SecretName string `json:"secretName,omitempty"`
149+
CertFileName string `json:"certFileName,omitempty"`
150+
}

api/v1alpha1/marklogiccluster_types.go

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package v1alpha1
1818

1919
import (
20+
appsv1 "k8s.io/api/apps/v1"
21+
corev1 "k8s.io/api/core/v1"
2022
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2123
)
2224

@@ -28,13 +30,58 @@ type MarklogicClusterSpec struct {
2830
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
2931
// Important: Run "make" to regenerate code after modifying this file
3032

31-
// Foo is an example field of MarklogicCluster. Edit marklogiccluster_types.go to remove/update
33+
// +kubebuilder:default:="cluster.local"
34+
ClusterDomain string `json:"clusterDomain,omitempty"`
35+
36+
// +kubebuilder:default:="progressofficial/marklogic-db:11.3.0-ubi-rootless"
37+
Image string `json:"image"`
38+
// +kubebuilder:default:="IfNotPresent"
39+
ImagePullPolicy string `json:"imagePullPolicy,omitempty"`
40+
ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
41+
42+
Auth *AdminAuth `json:"auth,omitempty"`
43+
Storage *Storage `json:"storage,omitempty"`
44+
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
45+
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
46+
// +kubebuilder:validation:Enum=OnDelete;RollingUpdate
47+
// +kubebuilder:default:="OnDelete"
48+
UpdateStrategy appsv1.StatefulSetUpdateStrategyType `json:"updateStrategy,omitempty"`
49+
NetworkPolicy NetworkPolicy `json:"networkPolicy,omitempty"`
50+
PodSecurityContext *corev1.PodSecurityContext `json:"podSecurityContext,omitempty"`
51+
ContainerSecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"`
52+
53+
Affinity *corev1.Affinity `json:"affinity,omitempty"`
54+
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
55+
TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`
56+
PriorityClassName string `json:"priorityClassName,omitempty"`
57+
License *License `json:"license,omitempty"`
58+
EnableConverters bool `json:"enableConverters,omitempty"`
59+
// +kubebuilder:default:={enabled: false, mountPath: "/dev/hugepages"}
60+
HugePages *HugePages `json:"hugePages,omitempty"`
61+
// +kubebuilder:default:={enabled: false, image: "fluent/fluent-bit:3.1.1", resources: {requests: {cpu: "100m", memory: "200Mi"}, limits: {cpu: "200m", memory: "500Mi"}}, files: {errorLogs: true, accessLogs: true, requestLogs: true}, outputs: "stdout"}
62+
LogCollection *LogCollection `json:"logCollection,omitempty"`
63+
64+
HAProxy HAProxy `json:"haproxy,omitempty"`
65+
3266
MarkLogicGroups []*MarklogicGroups `json:"markLogicGroups,omitempty"`
3367
}
3468

3569
type MarklogicGroups struct {
36-
*MarklogicGroupSpec `json:"spec,omitempty"`
37-
IsBootstrap bool `json:"isBootstrap,omitempty"`
70+
Replicas *int32 `json:"replicas,omitempty"`
71+
Name string `json:"name,omitempty"`
72+
Image string `json:"image,omitempty"`
73+
ImagePullPolicy string `json:"imagePullPolicy,omitempty"`
74+
ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
75+
Storage *Storage `json:"storage,omitempty"`
76+
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
77+
Affinity *corev1.Affinity `json:"affinity,omitempty"`
78+
TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`
79+
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
80+
PriorityClassName string `json:"priorityClassName,omitempty"`
81+
HugePages *HugePages `json:"hugePages,omitempty"`
82+
LogCollection *LogCollection `json:"logCollection,omitempty"`
83+
HAProxy *HAProxy `json:"haproxy,omitempty"`
84+
IsBootstrap bool `json:"isBootstrap,omitempty"`
3885
}
3986

4087
// MarklogicClusterStatus defines the observed state of MarklogicCluster

api/v1alpha1/marklogicgroup_types.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package v1alpha1
1919
import (
2020
appsv1 "k8s.io/api/apps/v1"
2121
corev1 "k8s.io/api/core/v1"
22-
networkingv1 "k8s.io/api/networking/v1"
2322
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2423
)
2524

@@ -47,10 +46,12 @@ type MarklogicGroupSpec struct {
4746
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
4847
// +kubebuilder:validation:Enum=OnDelete;RollingUpdate
4948
// +kubebuilder:default:="OnDelete"
50-
UpdateStrategy appsv1.StatefulSetUpdateStrategyType `json:"updateStrategy,omitempty"`
51-
NetworkPolicy *networkingv1.NetworkPolicy `json:"networkPolicy,omitempty"`
52-
PodSecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"`
53-
ContainerSecurityContext *corev1.SecurityContext `json:"containerSecurityContext,omitempty"`
49+
UpdateStrategy appsv1.StatefulSetUpdateStrategyType `json:"updateStrategy,omitempty"`
50+
NetworkPolicy NetworkPolicy `json:"networkPolicy,omitempty"`
51+
// +kubebuilder:default:={fsGroup: 2, fsGroupChangePolicy: "OnRootMismatch"}
52+
PodSecurityContext *corev1.PodSecurityContext `json:"podSecurityContext,omitempty"`
53+
// +kubebuilder:default:={runAsUser: 1000, runAsNonRoot: true, allowPrivilegeEscalation: false}
54+
ContainerSecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"`
5455

5556
Affinity *corev1.Affinity `json:"affinity,omitempty"`
5657
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
@@ -65,14 +66,20 @@ type MarklogicGroupSpec struct {
6566
// +kubebuilder:default:={enabled: false, initialDelaySeconds: 10, timeoutSeconds: 5, periodSeconds: 30, successThreshold: 1, failureThreshold: 3}
6667
ReadinessProbe ContainerProbe `json:"readinessProbe,omitempty"`
6768

69+
// +kubebuilder:default:={enabled: false, image: "fluent/fluent-bit:3.1.1", resources: {requests: {cpu: "100m", memory: "200Mi"}, limits: {cpu: "200m", memory: "500Mi"}}, files: {errorLogs: true, accessLogs: true, requestLogs: true}, outputs: "stdout"}
70+
LogCollection *LogCollection `json:"logCollection,omitempty"`
71+
6872
// +kubebuilder:default:={name: "Default", enableXdqpSsl: true}
69-
GroupConfig GroupConfig `json:"groupConfig,omitempty"`
70-
License *License `json:"license,omitempty"`
71-
EnableConverters bool `json:"enableConverters,omitempty"`
73+
GroupConfig *GroupConfig `json:"groupConfig,omitempty"`
74+
License *License `json:"license,omitempty"`
75+
EnableConverters bool `json:"enableConverters,omitempty"`
7276

7377
BootstrapHost string `json:"bootstrapHost,omitempty"`
7478

7579
DoNotDelete *bool `json:"doNotDelete,omitempty"`
80+
81+
Service Service `json:"service,omitempty"`
82+
PathBasedRouting bool `json:"pathBasedRouting,omitempty"`
7683
}
7784

7885
// InternalState defines the observed state of MarklogicGroup

0 commit comments

Comments
 (0)