Main Author: Jim White
Copyright 2016-17, Dell, Inc.
This project contains the Dockerfile and other files needed to create the Docker image for the EdgeX Foundry MongoDB container.
Owner: Core/Support WG
Main Author: Jim White
Copyright 2016-17, Dell, Inc.
This project contains the Dockerfile and other files needed to create the Docker image for the EdgeX Foundry MongoDB container.
Update the damn VERSION file
The current edgex-mongo-launch.sh script has this loop:
docker-edgex-mongo/bin/edgex-mongo-launch.sh
Lines 20 to 23 in b7b6e5f
which would be easier to maintain and handle error conditions if it was in the Go code instead.
Also the current script still suffers from #8, so if we put this into the Go code we implement a sensible, configurable timeout in Go much easier than in shell.
I found out the hard way while working on my edgex core snap that launch-edgex-mongo.sh can loop forever, and thus if hooked up to a native init script (eg. a systemd service) and the right conditions occur (ie. mongod fails to actually start), this script can cause a system hang.
The loop in this script should implement some sort of max retry limit, and then error out if triggered.
Also as an aside, the startup scripts in this repo are an example of edgex logic bound tightly to a specific deployment technology. For my snap [1], I had to extract the launch and initialization scripts from this repository.
[1] https://github.com/tonyespy/edgex-core-snap/blob/master/snap/snapcraft.yaml#L185
While starting the mongo instance from inside my edgexfoundry-core snap on an Ubuntu 16.04 desktop system, I see the following warnings output in syslog:
Jan 27 10:38:49 tex1 edgexfoundry-core.mongod[19510]: 2018-01-27T10:38:49.832-0500 I STORAGE [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
Jan 27 10:38:49 tex1 edgexfoundry-core.mongod[19510]: 2018-01-27T10:38:49.832-0500 I STORAGE [initandlisten] ** See http://dochub.mongodb.org/core/prodnotes-filesystem
Jan 27 10:38:49 tex1 edgexfoundry-core.mongod[19510]: 2018-01-27T10:38:49.976-0500 W STORAGE [initandlisten] Detected configuration for non-active storage engine mmapv1 when current storage engine is wiredTiger
[initandlisten] ** WARNING: Access control is not enabled for the database.
Jan 27 10:38:49 tex1 edgexfoundry-core.mongod[19510]: 2018-01-27T10:38:49.976-0500 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
I haven't yet verified that the same warnings are produced when running mongo inside a docker container on the same OS, but would be surprised if the same warnings weren't seen there as well.
Note, my core snap is currently building all of the services using the Barcelona release, and I'm using my own version of the launch-mongo script:
https://github.com/tonyespy/edgex-core-snap/blob/service-ordering-test/bin/start-mongo.sh
The current mongo service is using old version of go-mod-secrets and does not have the token-refresh feature. We should update the version of go-mod-secrets to v0.0.17 to make mongo service token automatically refreshed when running in secure mode.
The current version will not refresh the Vault token automatically, hence will be expired if not using v0.0.17+ of go-mod-secrets.
We need a version file in this project so that we can roll the version.
Current number of CVE's found in the image based on the mongo:4.0-xenial image is 72 (40 high, 29 medium, 3 low).
Per Snyk, we can reduce the risk by using the mongo:4.2.0-bionic image.
Do not start mongo container with user 'mongodb', because this user does not have permissions to read secrets from Vault secret storage
Release: Barcelona (0.2.x)
The script launch-edgex-mongo.sh has a sleep after mongo is started to delay loading the initial mongo configuration. The sleep is there to let mongo settle after start-up before loading the ocnfig. The problem is that given the right conditions, the sleep could be too short.
Replacing the sleep with a loop which instead attempts to interact with mongo to determine whether or not it's ready would be a better approach.
Following on issue #33
If security is enabled, the bootstrapping application should obtain its list of secret credentials from Vault through the go-mod-core-security client and then populate Mongo accordingly. Initialization of relevant schema information will happen as regardless of security enablement, however credentials will differ.
With the current implementation:
All this entails long bootstrapping time until mongo database become usable for the other microservices.
In addition there is a problem with the token refreshment (see the exchanged comments of here)
To address the problems above, edgex-mongo go application needs to be a single shot service. Once all credentials are provisioned there is not need to re-prevision them again on each restart.
The proposal is to distinguish the bootstrapping case from the non-bootstrapping case by creating hidden file at the end of edgex-mongo execution. The existance of this file will make the difference in the bootstrapping cases.
The logic to initialize the export-client credentials and collection in mongo was omitted from the Edinburgh image. Please correct.
The current docker container doesn't properly reap child processes or forward signals properly, the usual solution for this is to use an init script such as dumb-init
to launch the script.
@bnevis-i has examples if needed
1.1.0 is the version number of fuiji
With the addition of the DB to support store and forward in the app-functions-sdk we need to create DB, initialize the credentials and indexes for the application-service
DB.
edgex-go's usage of the SecretConfig struct is just that it inherits from go-mod-secrets struct:
We should do the same here so that we don't need to track all the details of go-mod-secrets here, we can just upgrade the version of go-mod-secrets used to build docker-edgex-mongo.
That would mean changes to the SecretStoreInfo struct here:
docker-edgex-mongo/internal/pkg/config.go
Lines 55 to 63 in a0f6261
Update docker-edgex-mongo to reflect the changes done by PR edgexfoundry/go-mod-secrets#31
inspired by issue edgexfoundry/go-mod-secrets#26
The SecretConfig struct retains its Path variable, that provides the base searching path for vault, meanwhile the SecretClient interface changed its signature to
GetSecrets(path string, keys ...string) (map[string]string, error)
This path, if provided, will be attached to the base searching path - thus each microservice will be able to read secrets from different paths (under their base search path)
The ARM64 Dockerfile needs to be updated to use Mongo 4.x to bring it to parity with the x86_64 Dockerfile.
For issue EdgeX-Go #1286 we are adding functionality for Mongo to delete all readings associated with a specified device. Adding an index will allow this operation to be more effective by not performing a full scan on the collection.
Currently when this container boots, a shell script uses init_mongo.js
to initialize access credentials, collections, indexes and so forth for the Mongo database. For the Fuji release, we would like to replace this with an actual Go application. The initial work on this application to establish parity with the init_mongo.js script can be found here in the holding area.
This issue is for moving that application into this repo in a suitable location, such as a /cmd directory. The Go application should be built into an executable as part of the Dockerfile and placed into the destination image along with Mongo. When the container boots, Mongo must come up first then the application needs to be run just as happens today.
Integration verification testing with edgex-go should also be done since that has not yet occurred with the code from the holding area.
In the following change, we added mongod --smallfiles --bind_ip_all
in launch-edgex-mongo.sh
2c86e5e
docker-edgex-mongo/launch-edgex-mongo.sh
Line 20 in 2c86e5e
However, arm64 is still using Mongo v3.4.7, and it can't recognize --bind_ip_all
, so the following error occurs
00:11:55 MongoDB shell version v3.4.7
00:11:55 Error parsing command line: unrecognised option '--bind_ip_all'
00:11:55 try 'mongod --help' for more information
Add new rule in the make file for building ARM images.
Once the rule is added we could directly execute:
~/docker-edgex-mongo$ make edgex-docker-arm
instead of executing the long command:
ubuntu:~/docker-edgex-mongo$ docker build -f cmd/Dockerfile.aarch64 -t edgexfoundry/docker-edgex-mongo:dev .
Take a look on #48 (comment)
The following files need to be updated:
Dockerfile.build
go.mod
remove env variable EDGEX_SECURITY_SECRET_STORE_DEFAULT from Docker config file
Would it be worth using the mongo image based on alpine?
This would reduce disk size from 370MB to 110 MB since it does not have the Debian OS additional footprint.
I am not aware of a mongo:alpine in the official repo but this one seems quite used https://hub.docker.com/r/mvertes/alpine-mongo/
I have been investigating a performance issue related to EdgeX. Long story short, there needs to be an index on the uuid field of the reading collection in core-data, which should probably happen in this file.
The problem I experienced was adding a new event was taking over 1.5s after my reading collection had grown to over 600,000 events. As a result, my device service built up a processing delay of several hours. Mongo was using 100% CPU & over 1.5GB of RAM. The profiler revealed that it was constantly scanning the entire reading table to search for single uuid
s. As the table was very large, this scan required a lot of resources, resulting in the delay. I eventually traced this table scan to this line.
The process flow starts when core-data receives an HTTP request to add a new event:
addNewEvent
dbClient.AddEvent
FromContract
ReadingToDBRef
readingById
to search for the uuidI used Robo 3T to add an index for uuid
. I don't know a lot about mongo, but I took a guess that making it sparse
with a ttl
of 10s made sense, since the code was looking it up immediately. In roughly 3 minutes, mongo's resource usage dropped to <1% & ~80MB RAM. It added over 100,000 new readings in that time, and from that point adding a new event (including HTTP traffic) is in the 1ms range. It's been running over the weekend without issue, and is approaching 1 million readings.
The setup instructions at https://docs.edgexfoundry.org/Ch-GettingStartedGoDevelopers.html say to do the following to set up MongoDB under Linux for developers:
wget https://github.com/edgexfoundry/docker-edgex-mongo/raw/master/init_mongo.js
sudo -u mongodb mongo < init_mongo.js
Unfortunately, init_mongo.js
no longer seems to exist. Either it should be replaced or the instructions should be updated.
Mongo no longer supported.
I'm trying to integrate this with the snap, but the process isn't able to setup mongo successfully AFAICT. It's not clear to me what user is missing the username since they all seem to be defined in Credentials.*.Username
Sep 12 16:13:36 systemd[1]: Starting Service for snap application edgexfoundry.mongo-worker...
Sep 12 16:13:36 edgexfoundry.mongo-worker[6250]: + MAX_TRIES=10
Sep 12 16:13:36 edgexfoundry.mongo-worker[6250]: + num_tries=0
Sep 12 16:13:36 edgexfoundry.mongo-worker[6250]: + cd /var/snap/edgexfoundry/x1/config/edgex-mongo
Sep 12 16:13:36 edgexfoundry.mongo-worker[6250]: + /snap/edgexfoundry/x1/bin/edgex-mongo
Sep 12 16:13:37 edgexfoundry.mongo-worker[6250]: level=ERROR ts=2019-09-12T21:13:37.225320692Z app=edgex-mongo source=logger.go:105 msg="logTarget cannot be blank, using stdout only"
Sep 12 16:13:37 edgexfoundry.mongo-worker[6250]: level=INFO ts=2019-09-12T21:13:37.22540887Z app=edgex-mongo source=main.go:32 msg="starting edgex-mongo process ..."
Sep 12 16:13:37 edgexfoundry.mongo-worker[6250]: level=INFO ts=2019-09-12T21:13:37.225421313Z app=edgex-mongo source=config.go:34 msg="loading the configuration from: res/security/configuration.toml"
Sep 12 16:13:37 edgexfoundry.mongo-worker[6250]: level=ERROR ts=2019-09-12T21:13:37.225650519Z app=edgex-mongo source=logger.go:105 msg="logTarget cannot be blank, using stdout only"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=INFO ts=2019-09-12T21:13:39.279625613Z app=edgex-mongo source=client.go:45 msg="Settting up admin database"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=ERROR ts=2019-09-12T21:13:39.279723419Z app=edgex-mongo source=client.go:60 msg="Error during execution: user has no Username"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=INFO ts=2019-09-12T21:13:39.280159609Z app=edgex-mongo source=client.go:45 msg="Settting up exportclient database"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=ERROR ts=2019-09-12T21:13:39.280205777Z app=edgex-mongo source=client.go:60 msg="Error during execution: user has no Username"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=INFO ts=2019-09-12T21:13:39.301624295Z app=edgex-mongo source=client.go:45 msg="Settting up authorization database"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=ERROR ts=2019-09-12T21:13:39.301685561Z app=edgex-mongo source=client.go:60 msg="Error during execution: user has no Username"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=INFO ts=2019-09-12T21:13:39.301697133Z app=edgex-mongo source=client.go:45 msg="Settting up rules_engine_db database"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=ERROR ts=2019-09-12T21:13:39.301706311Z app=edgex-mongo source=client.go:60 msg="Error during execution: user has no Username"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=INFO ts=2019-09-12T21:13:39.301715228Z app=edgex-mongo source=client.go:45 msg="Settting up metadata database"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=ERROR ts=2019-09-12T21:13:39.301723644Z app=edgex-mongo source=client.go:60 msg="Error during execution: user has no Username"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=INFO ts=2019-09-12T21:13:39.547744535Z app=edgex-mongo source=client.go:45 msg="Settting up coredata database"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=ERROR ts=2019-09-12T21:13:39.547802075Z app=edgex-mongo source=client.go:60 msg="Error during execution: user has no Username"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=INFO ts=2019-09-12T21:13:39.636566137Z app=edgex-mongo source=client.go:45 msg="Settting up notifications database"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=ERROR ts=2019-09-12T21:13:39.636611082Z app=edgex-mongo source=client.go:60 msg="Error during execution: user has no Username"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=INFO ts=2019-09-12T21:13:39.714028673Z app=edgex-mongo source=client.go:45 msg="Settting up scheduler database"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=ERROR ts=2019-09-12T21:13:39.714086103Z app=edgex-mongo source=client.go:60 msg="Error during execution: user has no Username"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=INFO ts=2019-09-12T21:13:39.774037426Z app=edgex-mongo source=client.go:45 msg="Settting up logging database"
Sep 12 16:13:39 edgexfoundry.mongo-worker[6250]: level=ERROR ts=2019-09-12T21:13:39.774095536Z app=edgex-mongo source=client.go:60 msg="Error during execution: user has no Username"
Sep 12 16:13:39 systemd[1]: snap.edgexfoundry.mongo-worker.service: Succeeded.
I'm using the default config files from the repository, reproduced here for clarity:
#################################################################################
# Copyright 2019 VMWare.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing permissions and limitations under
# the License.
#
#################################################################################
# This is a TOML config file for edgex-mongo init service.
[Writable]
LogLevel = "INFO"
[Service]
BootTimeout = 30000
[Mongo]
Host = 'localhost'
Port = 27017
Timeout = 5000
[Credentials]
[Credentials.authorization]
Username = "admin"
Password = "password"
[Credentials.admin]
Username = "admin"
Password = "password"
[Credentials.metadata]
Username = "meta"
Password = "password"
[Credentials.coredata]
Username = "core"
Password = "password"
[Credentials.rules_engine_db]
Username = "rules_engine_user"
Password = "password"
[Credentials.notifications]
Username = "notifications"
Password = "password"
[Credentials.scheduler]
Username = "scheduler"
Password = "password"
[Credentials.logging]
Username = "logging"
Password = "password"
[Credentials.exportclient]
Username = "exportclient"
Password = "password"
#################################################################################
# Copyright 2019 VMWare.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing permissions and limitations under
# the License.
#
#################################################################################
# This is a TOML config file for edgex-mongo init service.
[Writable]
LogLevel = "INFO"
[Service]
BootTimeout = 30000
[SecretStore]
Server = "localhost"
Port = 8200
HealthCheckPath = "v1/sys/health"
DBStem = "v1/secret/database"
TokenPath = "res/resp-init.json"
CACertPath = "res/EdgeXFoundryCA/EdgeXFoundryCA.pem"
SNIS = ["edgex-vault"]
[Mongo]
Host = 'localhost'
Port = 27017
Timeout = 5000
The Go bootstrapping application referred to in issue #32 needs to be aware of whether or not it's running in a context where security is enabled (the default) or disabled. It might make sense to do this via environment variables set in the relevant docker-compose file. Proposed environment variable would be EDGEX_SECURITY=ON
. The absence of the variable would mean security is disabled. NOTE: This is currently a proposal I'm soliciting feedback on via Slack.
Would suggest for this issue to just implement the security branching logic for now. When security is ostensibly enabled, put some content into Mongo that you can verify the relevant initialization has run.
The scheduler entries for the mongo db indexing is referencing an incorrect field.
Field needs to be "name" not "slug".
Update references for previous versions of Go to 1.13 in the following files
Edgex-go docker compose uses this projects contents when creating the docker mongo image.
Need to add the new service entries in the mongo init_mongo.js to support the container permissions from the support-scheduler micro service.
Currently, mongo database is started by mongod --bind_ip_all &
(see edgex-mongo-launch.sh).
Because the authentication is not explicitly enabled (by setting it in mongod.conf
file , or using --auth
parameter), mongo comes without access control.
Once mongo is started, edgex-mongo app creates User for each service. Each User has privileges to manipulate the data in specific database (exp, user "meta" could access only "metadata" database and etc)
Nevertheless,the existence of all these users, restriction free control could be taken over the entire database if the client do not provide any credentials at all.
The Dockerfile.aarch64
needs to be upgraded as well to use Mongo 4.2 as we just did for x86_64
. I'll tag @cloudxxx8 as well on this as his team has an easy way to test the changes.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.