7 files changed
+180
-16
No files matched your search
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Monitoring
|
||||
title: EdgeFS Monitoring
|
||||
weight: 48
|
||||
indent: true
|
||||
---
|
||||
|
||||
# Monitoring
|
||||
# EdgeFS Monitoring
|
||||
|
||||
Each Rook EdgeFS cluster has some built in metrics collectors/exporters for monitoring with [Prometheus](https://prometheus.io/).
|
||||
If you do not have Prometheus running, follow the steps below to enable monitoring of Rook. If your cluster already
|
||||
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: EdgeFS User Interface
|
||||
weight: 49
|
||||
indent: true
|
||||
---
|
||||
|
||||
# EdgeFS Dashboard and User Interface
|
||||
|
||||
EdgeFS comes with built-in local cluster Dashboard and User Interface.
|
||||
|
||||
The dashboard is a very helpful tool to give you an overview of the status of your cluster, including overall health,
|
||||
status of the corosync quorum, status of the VDEVs, and other EdgeFS services.
|
||||
|
||||

|
||||
|
||||
Rook EdgeFS Operator enables the dashboard by default.
|
||||
A K8s service will be created to expose HTTP/S ports inside the cluster.
|
||||
|
||||
This example shows what ports was configured for EdgeFS right after successful cluster deployment:
|
||||
```bash
|
||||
# kubectl get svc -n rook-edgefs
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
rook-edgefs-restapi NodePort 10.105.177.93 <none> 8881:32135/TCP,8080:31363/TCP,4443:31485/TCP 3h14m
|
||||
rook-edgefs-ui NodePort 10.97.70.209 <none> 3000:32048/TCP,3443:30273/TCP 3h14m
|
||||
rook-edgefs-mgr NodePort 10.108.199.1 <none> 6789:31370/TCP 3h14m
|
||||
```
|
||||
|
||||
The `rook-edgefs-restapi` service is used for the [Prometheus metrics](edgefs-monitoring.md) scrape and REST API endpoints.
|
||||
REST API endpoint is used by Console and Graphical UIs. It exposing ClusterIPs with HTTP ports 8080 and 4443(SSL). NodePort(s) for external access automatically pre-created.
|
||||
|
||||
The `rook-edgefs-ui` service is used to expose browser based User Interface ports.
|
||||
Using NodePort you will be able to connect to the dashboard by direct node IP and provided port number, in this example at `http://NODEIP:32048`.
|
||||
|
||||
The `rook-edgefs-mgr` service is for gRPC communication between the [EdgeFS CSI Provisioner](edgefs-si.md), REST API and services. It exposes cluster internal port 6789.
|
||||
|
||||
## Dynamic EdgeFS Service CRD editing
|
||||
|
||||
One of the very useful features of EdgeFS Dashboard is Dynamic Service CRD editing UI. Ability to edit CRDs via intuitive graphical inteface can simplify on-going EdgeFS cluster management drastically. For instance, below picture demostrantes how NFS CRD service can be dynamically edited, exports can be added or removed:
|
||||
|
||||

|
||||
|
||||
EdgeFS UI renders user requests and sends them to the REST API where service CRD is constructed, validated and executed. Certain parameters can only be updated within a cluster service definition itself, and as such this UI blends the two, thus providing simplified management functionality.
|
||||
|
||||
### Credentials
|
||||
|
||||
After you connect to the dashboard you will need to login for secure access. Rook EdgeFS operator creates a default user named
|
||||
`admin` and password `edgefs`. It can be changed later via `neadm system passwd` command executed within `mgr` pod.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 123 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 117 KiB |
@@ -18,6 +18,9 @@ rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps", "endpoints"]
|
||||
verbs: [ "get", "list", "watch", "create", "update", "delete" ]
|
||||
- apiGroups: ["edgefs.rook.io"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: [ "get", "list" ]
|
||||
|
||||
@@ -38,11 +38,15 @@ var logger = capnslog.NewPackageLogger("github.com/rook/rook", "edgefs-op-mgr")
|
||||
|
||||
const (
|
||||
appName = "rook-edgefs-mgr"
|
||||
restapiSvcName = "rook-edgefs-restapi"
|
||||
uiSvcName = "rook-edgefs-ui"
|
||||
defaultServiceAccountName = "rook-edgefs-cluster"
|
||||
defaultGrpcPort = 6789
|
||||
defaultRestPort = 8080
|
||||
defaultRestSPort = 4443
|
||||
defaultMetricsPort = 8881
|
||||
defaultUiPort = 3000
|
||||
defaultUiSPort = 3443
|
||||
|
||||
/* Volumes definitions */
|
||||
dataVolumeName = "edgefs-datadir"
|
||||
@@ -121,14 +125,36 @@ func (c *Cluster) Start(rookImage string) error {
|
||||
}
|
||||
|
||||
// create the mgr service
|
||||
service := c.makeMgrService(appName)
|
||||
if _, err := c.context.Clientset.CoreV1().Services(c.Namespace).Create(service); err != nil {
|
||||
mgrService := c.makeMgrService(appName)
|
||||
if _, err := c.context.Clientset.CoreV1().Services(c.Namespace).Create(mgrService); err != nil {
|
||||
if !errors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("failed to create mgr service. %+v", err)
|
||||
}
|
||||
logger.Infof("mgr mgr service already exists")
|
||||
logger.Infof("mgr service already exists")
|
||||
} else {
|
||||
logger.Infof("mgr mgr service started")
|
||||
logger.Infof("mgr service started")
|
||||
}
|
||||
|
||||
// create the restapi service
|
||||
restapiService := c.makeRestapiService(restapiSvcName)
|
||||
if _, err := c.context.Clientset.CoreV1().Services(c.Namespace).Create(restapiService); err != nil {
|
||||
if !errors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("failed to create restapi service. %+v", err)
|
||||
}
|
||||
logger.Infof("restapi service already exists")
|
||||
} else {
|
||||
logger.Infof("restapi service started")
|
||||
}
|
||||
|
||||
// create the ui/dashboard service
|
||||
uiService := c.makeUiService(uiSvcName)
|
||||
if _, err := c.context.Clientset.CoreV1().Services(c.Namespace).Create(uiService); err != nil {
|
||||
if !errors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("failed to create ui service. %+v", err)
|
||||
}
|
||||
logger.Infof("ui service already exists")
|
||||
} else {
|
||||
logger.Infof("ui service started")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -144,25 +170,45 @@ func (c *Cluster) makeMgrService(name string) *v1.Service {
|
||||
},
|
||||
Spec: v1.ServiceSpec{
|
||||
Selector: labels,
|
||||
Type: v1.ServiceTypeClusterIP,
|
||||
Type: v1.ServiceTypeNodePort,
|
||||
Ports: []v1.ServicePort{
|
||||
{
|
||||
Name: "mgr",
|
||||
Port: int32(defaultGrpcPort),
|
||||
Protocol: v1.ProtocolTCP,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
k8sutil.SetOwnerRef(c.context.Clientset, c.Namespace, &svc.ObjectMeta, &c.ownerRef)
|
||||
return svc
|
||||
}
|
||||
|
||||
func (c *Cluster) makeRestapiService(name string) *v1.Service {
|
||||
labels := c.getLabels()
|
||||
svc := &v1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: c.Namespace,
|
||||
Labels: labels,
|
||||
},
|
||||
Spec: v1.ServiceSpec{
|
||||
Selector: labels,
|
||||
Type: v1.ServiceTypeNodePort,
|
||||
Ports: []v1.ServicePort{
|
||||
{
|
||||
Name: "http-metrics",
|
||||
Port: int32(defaultMetricsPort),
|
||||
Protocol: v1.ProtocolTCP,
|
||||
},
|
||||
{
|
||||
Name: "http-mgmt",
|
||||
Name: "http-restapi",
|
||||
Port: int32(defaultRestPort),
|
||||
Protocol: v1.ProtocolTCP,
|
||||
},
|
||||
{
|
||||
Name: "https-mgmt",
|
||||
Name: "https-restapi",
|
||||
Port: int32(defaultRestSPort),
|
||||
Protocol: v1.ProtocolTCP,
|
||||
},
|
||||
@@ -174,6 +220,36 @@ func (c *Cluster) makeMgrService(name string) *v1.Service {
|
||||
return svc
|
||||
}
|
||||
|
||||
func (c *Cluster) makeUiService(name string) *v1.Service {
|
||||
labels := c.getLabels()
|
||||
svc := &v1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: c.Namespace,
|
||||
Labels: labels,
|
||||
},
|
||||
Spec: v1.ServiceSpec{
|
||||
Selector: labels,
|
||||
Type: v1.ServiceTypeNodePort,
|
||||
Ports: []v1.ServicePort{
|
||||
{
|
||||
Name: "http-ui",
|
||||
Port: int32(defaultUiPort),
|
||||
Protocol: v1.ProtocolTCP,
|
||||
},
|
||||
{
|
||||
Name: "https-ui",
|
||||
Port: int32(defaultUiSPort),
|
||||
Protocol: v1.ProtocolTCP,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
k8sutil.SetOwnerRef(c.context.Clientset, c.Namespace, &svc.ObjectMeta, &c.ownerRef)
|
||||
return svc
|
||||
}
|
||||
|
||||
func (c *Cluster) makeDeployment(name, clusterName, rookImage string, replicas int32) *extensions.Deployment {
|
||||
|
||||
volumes := []v1.Volume{}
|
||||
@@ -215,12 +291,13 @@ func (c *Cluster) makeDeployment(name, clusterName, rookImage string, replicas i
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ServiceAccountName: c.serviceAccount,
|
||||
Containers: []v1.Container{c.mgmtContainer(name, "edgefs/edgefs-restapi:"+rookImageVer), c.mgrContainer("grpc", rookImage)},
|
||||
RestartPolicy: v1.RestartPolicyAlways,
|
||||
Volumes: volumes,
|
||||
HostIPC: true,
|
||||
HostNetwork: isHostNetworkDefined(c.HostNetworkSpec),
|
||||
NodeSelector: map[string]string{c.Namespace: "cluster"},
|
||||
Containers: []v1.Container{c.mgmtContainer(name, "edgefs/edgefs-restapi:"+rookImageVer),
|
||||
c.mgrContainer("grpc", rookImage), c.uiContainer("ui", "edgefs/edgefs-ui:"+rookImageVer)},
|
||||
RestartPolicy: v1.RestartPolicyAlways,
|
||||
Volumes: volumes,
|
||||
HostIPC: true,
|
||||
HostNetwork: isHostNetworkDefined(c.HostNetworkSpec),
|
||||
NodeSelector: map[string]string{c.Namespace: "cluster"},
|
||||
},
|
||||
}
|
||||
if isHostNetworkDefined(c.HostNetworkSpec) {
|
||||
@@ -239,6 +316,43 @@ func (c *Cluster) makeDeployment(name, clusterName, rookImage string, replicas i
|
||||
return d
|
||||
}
|
||||
|
||||
func (c *Cluster) uiContainer(name string, containerImage string) v1.Container {
|
||||
|
||||
runAsUser := int64(0)
|
||||
readOnlyRootFilesystem := false
|
||||
securityContext := &v1.SecurityContext{
|
||||
RunAsUser: &runAsUser,
|
||||
ReadOnlyRootFilesystem: &readOnlyRootFilesystem,
|
||||
}
|
||||
|
||||
return v1.Container{
|
||||
Name: name,
|
||||
Image: containerImage,
|
||||
ImagePullPolicy: v1.PullAlways,
|
||||
Args: []string{},
|
||||
Env: []v1.EnvVar{
|
||||
{
|
||||
Name: "API_ENDPOINT",
|
||||
Value: "http://0.0.0.0:8080",
|
||||
},
|
||||
},
|
||||
SecurityContext: securityContext,
|
||||
Resources: c.resources,
|
||||
Ports: []v1.ContainerPort{
|
||||
{
|
||||
Name: "http-ui",
|
||||
ContainerPort: int32(defaultUiPort),
|
||||
Protocol: v1.ProtocolTCP,
|
||||
},
|
||||
{
|
||||
Name: "https-ui",
|
||||
ContainerPort: int32(defaultUiSPort),
|
||||
Protocol: v1.ProtocolTCP,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cluster) mgmtContainer(name string, containerImage string) v1.Container {
|
||||
|
||||
runAsUser := int64(0)
|
||||
|
||||
@@ -117,7 +117,7 @@ func TestServiceSpec(t *testing.T) {
|
||||
s := c.makeMgrService("rook-edgefs-mgr")
|
||||
assert.NotNil(t, s)
|
||||
assert.Equal(t, "rook-edgefs-mgr", s.Name)
|
||||
assert.Equal(t, 4, len(s.Spec.Ports))
|
||||
assert.Equal(t, 1, len(s.Spec.Ports))
|
||||
}
|
||||
|
||||
func TestHostNetwork(t *testing.T) {
|
||||
|
||||
Reference in new issue
Block a user