GeoNode / geonode

GeoNode is an open source platform that facilitates the creation, sharing, and collaborative use of geospatial data.
https://geonode.org/
Other
1.43k stars 1.12k forks source link

Openshift / kubernetes deployment geonode #11388

Closed rkhandha closed 1 year ago

rkhandha commented 1 year ago

Expected Behavior

Geonode to start normally and connect to geoserver and geonode postgresql db. I think this issue may be related to environment variable.

Actual Behavior

Container startup process is stuck at invoke update Below is the debug log from invoke -d update $ /usr/bin/python3 /usr/local/bin/invoke -d update invoke.program.parse_collection: No default namespace provided, trying to load one from disk invoke.loader.find: FilesystemLoader find starting at '/usr/src/geonode' invoke.loader.find: Found module: ModuleSpec(name='tasks', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7fc01a323e80>, origin='/usr/src/geonode/tasks.py') /usr/lib/python3/dist-packages/paramiko/transport.py:236: CryptographyDeprecationWarning: Blowfish has been deprecated "class": algorithms.Blowfish, invoke.config._load_file: Didn't see any /usr/src/geonode/invoke.yaml, skipping. invoke.config._load_file: Didn't see any /usr/src/geonode/invoke.yml, skipping. invoke.config._load_file: Didn't see any /usr/src/geonode/invoke.json, skipping. invoke.config.merge: Merging config sources in order onto new empty _config... invoke.config.merge: Defaults: {'run': {'asynchronous': False, 'disown': False, 'dry': False, 'echo': False, 'echo_stdin': None, 'encoding': None, 'env': {}, 'err_stream': None, 'fallback': True, 'hide': None, 'in_stream': None, 'out_stream': None, 'echo_format': '\x1b[1;37m{command}\x1b[0m', 'pty': False, 'replace_env': False, 'shell': '/bin/bash', 'warn': False, 'watchers': []}, 'runners': {'local': <class 'invoke.runners.Local'>}, 'sudo': {'password': None, 'prompt': '[sudo] password: ', 'user': None}, 'tasks': {'auto_dash_names': True, 'collection_name': 'tasks', 'dedupe': True, 'executor_class': None, 'ignore_unknown_help': False, 'search_root': None}, 'timeouts': {'command': None}} invoke.config.merge: Collection-driven: {} invoke.config._merge_file: System-wide config file (/etc/invoke.py): {} invoke.config._merge_file: Per-user config file (/root/.invoke.py): {} invoke.config._merge_file: Per-project config file (/usr/src/geonode/invoke.py): {} invoke.config.merge: Environment variable config: {} invoke.config._merge_file: Runtime config file has not been loaded yet, skipping invoke.config.merge: Overrides: {} invoke.config.merge: Modifications: {} invoke.config.merge: Deletions: {} invoke.parser.init: Adding <parser/Context 'waitfordbs'> invoke.parser.init: Adding <parser/Context 'waitforgeoserver'> invoke.parser.init: Adding <parser/Context 'update'> invoke.parser.init: Adding <parser/Context 'migrations'> invoke.parser.init: Adding <parser/Context 'statics'> invoke.parser.init: Adding <parser/Context 'prepare'> invoke.parser.init: Adding <parser/Context 'fixtures'> invoke.parser.init: Adding <parser/Context 'collectstatic'> invoke.parser.init: Adding <parser/Context 'geoserverfixture'> invoke.parser.init: Adding <parser/Context 'monitoringfixture'> invoke.parser.init: Adding <parser/Context 'updategeoip'> invoke.parser.init: Adding <parser/Context 'updateadmin'> invoke.parser.init: Adding <parser/Context 'collectmetrics'> invoke.parser.init: Adding <parser/Context 'initialized'> invoke.program.parse_tasks: Parsing tasks against <Collection 'tasks': collectmetrics, collectstatic, fixtures, geoserverfixture, initialized, migrations, monitoringfixture, prepare, statics, update, updateadmin, updategeoip, waitfordbs, waitforgeoserver> invoke.parser.init: Initialized with context: <parser/Context: {'command-timeout': <Argument: command-timeout (T) [int]>, 'complete': <Argument: complete [bool]>, 'config': <Argument: config (f)>, 'debug': <Argument: debug (d) [bool]>, 'dry': <Argument: dry (R) [bool]>, 'echo': <Argument: echo (e) [bool]>, 'help': <Argument: help (h) ?>, 'hide': , 'list': <Argument: list (l) ?>, 'list-depth': <Argument: list-depth (D) [int]>, 'list-format': <Argument: list-format (F)>, 'print-completion-script': , 'prompt-for-sudo-password': <Argument: prompt-for-sudo-password [bool]>, 'pty': <Argument: pty (p) [bool]>, 'version': <Argument: version (V) [bool]>, 'warn-only': <Argument: warn-only (w) [bool]>, 'write-pyc': <Argument: write-pyc [bool]>, 'collection': <Argument: collection (c)>, 'no-dedupe': <Argument: no-dedupe [bool]>, 'search-root': <Argument: search-root (r)>}> invoke.parser.init: Available contexts: {'waitfordbs': <parser/Context 'waitfordbs'>, 'waitforgeoserver': <parser/Context 'waitforgeoserver'>, 'update': <parser/Context 'update'>, 'migrations': <parser/Context 'migrations'>, 'statics': <parser/Context 'statics'>, 'prepare': <parser/Context 'prepare'>, 'fixtures': <parser/Context 'fixtures'>, 'collectstatic': <parser/Context 'collectstatic'>, 'geoserverfixture': <parser/Context 'geoserverfixture'>, 'monitoringfixture': <parser/Context 'monitoringfixture'>, 'updategeoip': <parser/Context 'updategeoip'>, 'updateadmin': <parser/Context 'updateadmin'>, 'collectmetrics': <parser/Context 'collectmetrics'>, 'initialized': <parser/Context 'initialized'>} invoke.parser.complete_context: Wrapping up context None invoke.parser.parse_argv: Starting argv: ['update'] invoke.parser.handle: Handling token: 'update' invoke.parser.changing_state: ParseMachine: 'context' => 'context' invoke.parser.complete_context: Wrapping up context None invoke.parser.switch_to_context: Moving to context 'update' invoke.parser.switch_to_context: Context args: {} invoke.parser.switch_to_context: Context flags: {} invoke.parser.switch_to_context: Context inverse_flags: {} invoke.parser.changing_state: ParseMachine: 'context' => 'end' invoke.parser.complete_context: Wrapping up context 'update' invoke.program.parse_tasks: Resulting task contexts: [<parser/Context 'update'>] invoke.config.merge: Merging config sources in order onto new empty _config... invoke.config.merge: Defaults: {'run': {'asynchronous': False, 'disown': False, 'dry': False, 'echo': False, 'echo_stdin': None, 'encoding': None, 'env': {}, 'err_stream': None, 'fallback': True, 'hide': None, 'in_stream': None, 'out_stream': None, 'echo_format': '\x1b[1;37m{command}\x1b[0m', 'pty': False, 'replace_env': False, 'shell': '/bin/bash', 'warn': False, 'watchers': []}, 'runners': {'local': <class 'invoke.runners.Local'>}, 'sudo': {'password': None, 'prompt': '[sudo] password: ', 'user': None}, 'tasks': {'auto_dash_names': True, 'collection_name': 'tasks', 'dedupe': True, 'executor_class': None, 'ignore_unknown_help': False, 'search_root': None}, 'timeouts': {'command': None}} invoke.config.merge: Collection-driven: {} invoke.config._merge_file: System-wide config file (/etc/invoke.py): {} invoke.config._merge_file: Per-user config file (/root/.invoke.py): {} invoke.config._merge_file: Per-project config file (/usr/src/geonode/invoke.py): {} invoke.config.merge: Environment variable config: {} invoke.config._merge_file: Runtime config file has not been loaded yet, skipping invoke.config.merge: Overrides: {'run': {}, 'tasks': {}, 'sudo': {}, 'timeouts': {}} invoke.config.merge: Modifications: {} invoke.config.merge: Deletions: {} invoke.executor.execute: Examining top level tasks [<parser/Context 'update'>] invoke.executor.execute: Tasks (now Calls) with kwargs: [<Call 'update', args: (), kwargs: {}>] invoke.executor.expand_calls: Expanding task-call <Call 'update', args: (), kwargs: {}> invoke.executor.dedupe: Deduplicating tasks... invoke.executor.dedupe: <Call 'update', args: (), kwargs: {}>: no duplicates found, ok invoke.executor.execute: Executing <Call 'update', args: (), kwargs: {}> invoke.config.load_collection: Loading collection configuration invoke.config.merge: Merging config sources in order onto new empty _config... invoke.config.merge: Defaults: {'run': {'asynchronous': False, 'disown': False, 'dry': False, 'echo': False, 'echo_stdin': None, 'encoding': None, 'env': {}, 'err_stream': None, 'fallback': True, 'hide': None, 'in_stream': None, 'out_stream': None, 'echo_format': '\x1b[1;37m{command}\x1b[0m', 'pty': False, 'replace_env': False, 'shell': '/bin/bash', 'warn': False, 'watchers': []}, 'runners': {'local': <class 'invoke.runners.Local'>}, 'sudo': {'password': None, 'prompt': '[sudo] password: ', 'user': None}, 'tasks': {'auto_dash_names': True, 'collection_name': 'tasks', 'dedupe': True, 'executor_class': None, 'ignore_unknown_help': False, 'search_root': None}, 'timeouts': {'command': None}} invoke.config.merge: Collection-driven: {} invoke.config._merge_file: System-wide config file (/etc/invoke.py): {} invoke.config._merge_file: Per-user config file (/root/.invoke.py): {} invoke.config._merge_file: Per-project config file (/usr/src/geonode/invoke.py): {} invoke.config.merge: Environment variable config: {} invoke.config._merge_file: Runtime config file has not been loaded yet, skipping invoke.config.merge: Overrides: {'run': {}, 'tasks': {}, 'sudo': {}, 'timeouts': {}} invoke.config.merge: Modifications: {} invoke.config.merge: Deletions: {} invoke.config.load_shell_env: Running pre-merge for shell env loading... invoke.config.merge: Merging config sources in order onto new empty _config... invoke.config.merge: Defaults: {'run': {'asynchronous': False, 'disown': False, 'dry': False, 'echo': False, 'echo_stdin': None, 'encoding': None, 'env': {}, 'err_stream': None, 'fallback': True, 'hide': None, 'in_stream': None, 'out_stream': None, 'echo_format': '\x1b[1;37m{command}\x1b[0m', 'pty': False, 'replace_env': False, 'shell': '/bin/bash', 'warn': False, 'watchers': []}, 'runners': {'local': <class 'invoke.runners.Local'>}, 'sudo': {'password': None, 'prompt': '[sudo] password: ', 'user': None}, 'tasks': {'auto_dash_names': True, 'collection_name': 'tasks', 'dedupe': True, 'executor_class': None, 'ignore_unknown_help': False, 'search_root': None}, 'timeouts': {'command': None}} invoke.config.merge: Collection-driven: {} invoke.config._merge_file: System-wide config file (/etc/invoke.py): {} invoke.config._merge_file: Per-user config file (/root/.invoke.py): {} invoke.config._merge_file: Per-project config file (/usr/src/geonode/invoke.py): {} invoke.config.merge: Environment variable config: {} invoke.config._merge_file: Runtime config file has not been loaded yet, skipping invoke.config.merge: Overrides: {'run': {}, 'tasks': {}, 'sudo': {}, 'timeouts': {}} invoke.config.merge: Modifications: {} invoke.config.merge: Deletions: {} invoke.config.load_shellenv: Done with pre-merge. invoke.env.load: Scanning for env vars according to prefix: 'INVOKE', mapping: {'RUN_ASYNCHRONOUS': ['run', 'asynchronous'], 'RUN_DISOWN': ['run', 'disown'], 'RUN_DRY': ['run', 'dry'], 'RUN_ECHO': ['run', 'echo'], 'RUN_ECHO_STDIN': ['run', 'echo_stdin'], 'RUN_ENCODING': ['run', 'encoding'], 'RUN_ERR_STREAM': ['run', 'err_stream'], 'RUN_FALLBACK': ['run', 'fallback'], 'RUN_HIDE': ['run', 'hide'], 'RUN_IN_STREAM': ['run', 'in_stream'], 'RUN_OUT_STREAM': ['run', 'out_stream'], 'RUN_ECHO_FORMAT': ['run', 'echo_format'], 'RUN_PTY': ['run', 'pty'], 'RUN_REPLACE_ENV': ['run', 'replace_env'], 'RUN_SHELL': ['run', 'shell'], 'RUN_WARN': ['run', 'warn'], 'RUN_WATCHERS': ['run', 'watchers'], 'RUNNERS_LOCAL': ['runners', 'local'], 'SUDO_PASSWORD': ['sudo', 'password'], 'SUDO_PROMPT': ['sudo', 'prompt'], 'SUDO_USER': ['sudo', 'user'], 'TASKS_AUTO_DASH_NAMES': ['tasks', 'auto_dash_names'], 'TASKS_COLLECTION_NAME': ['tasks', 'collection_name'], 'TASKS_DEDUPE': ['tasks', 'dedupe'], 'TASKS_EXECUTOR_CLASS': ['tasks', 'executor_class'], 'TASKS_IGNORE_UNKNOWN_HELP': ['tasks', 'ignore_unknown_help'], 'TASKS_SEARCH_ROOT': ['tasks', 'search_root'], 'TIMEOUTS_COMMAND': ['timeouts', 'command']} invoke.env.load: Obtained env var config: {} invoke.config.load_shell_env: Loaded shell environment, triggering final merge invoke.config.merge: Merging config sources in order onto new empty _config... invoke.config.merge: Defaults: {'run': {'asynchronous': False, 'disown': False, 'dry': False, 'echo': False, 'echo_stdin': None, 'encoding': None, 'env': {}, 'err_stream': None, 'fallback': True, 'hide': None, 'in_stream': None, 'out_stream': None, 'echo_format': '\x1b[1;37m{command}\x1b[0m', 'pty': False, 'replace_env': False, 'shell': '/bin/bash', 'warn': False, 'watchers': []}, 'runners': {'local': <class 'invoke.runners.Local'>}, 'sudo': {'password': None, 'prompt': '[sudo] password: ', 'user': None}, 'tasks': {'auto_dash_names': True, 'collection_name': 'tasks', 'dedupe': True, 'executor_class': None, 'ignore_unknown_help': False, 'search_root': None}, 'timeouts': {'command': None}} invoke.config.merge: Collection-driven: {} invoke.config._merge_file: System-wide config file (/etc/invoke.py): {} invoke.config._merge_file: Per-user config file (/root/.invoke.py): {} invoke.config._merge_file: Per-project config file (/usr/src/geonode/invoke.py): {} invoke.config.merge: Environment variable config: {} invoke.config._merge_file: Runtime config file has not been loaded yet, skipping invoke.config.merge: Overrides: {'run': {}, 'tasks': {}, 'sudo': {}, 'timeouts': {}} invoke.config.merge: Modifications: {} invoke.config.merge: Deletions: {} invoke.executor.execute: Finished loading collection & shell env configs *setting env*** KUBERNETES_SERVICE_PORT_HTTPS=443 ASYNC_SIGNALS=False KUBERNETES_SERVICE_PORT=443 OGC_REQUEST_POOL_CONNECTIONS=10 DATABASE_URL=postgis://geonode:geonode@egomapdev-pgdb-pp07.app.xxx.xxx:5432/geonode OGC_REQUEST_MAX_RETRIES=1 ADMIN_USERNAME=admin API_LOCKDOWN=False HOSTNAME=geonode-0 AUTO_ASSIGN_REGISTERED_MEMBERS_TO_REGISTERED_MEMBERS_GROUP_NAME=True ENABLE_JSONP=true POSTGRES_PASSWORD=xxxx CENTRALIZED_DASHBOARD_ENABLED=False GEOSERVER_CORS_ALLOWED_ORIGINS= AVATAR_GRAVATAR_SSL=False ALLOWED_HOSTS=['django', ''] NSS_SDB_USE_CACHE=no DOCKERGEOSERVER_SERVICE_HOST=172.30.148.247 PUBLIC_PORT=8080 FAVORITE_ENABLED=True DOCKERGEOSERVER_PORT_8080_TCP_PROTO=tcp C_FORCE_ROOT=1 PX_647874667201627979_SERVER_PORT_2049_TCP_PROTO=tcp PX_647874667201627979_SERVER_PORT_2049_TCP_PORT=2049 EXIF_ENABLED=True COMPOSE_PROJECT_NAME=geonode RESOLVER=127.0.0.11 PX_248891589900815714_SERVER_SERVICE_HOST=172.30.105.110 PWD=/usr/src/geonode GEOSERVER_CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,HEAD,OPTIONS OGC_REQUEST_TIMEOUT=30 GEOSERVER_CORS_ALLOWED_HEADERS= STATIC_ROOT=/mnt/volumes/statics/static/ GEONODE_DB_CONN_MAX_AGE=0 HOME=/root HTTP_PORT=8000 KUBERNETES_PORT_443_TCP=tcp://172.30.0.1:443 DEFAULT_BACKEND_DATASTORE=datastore RESOURCE_PUBLISHING=False CLIENT_RESULTS_LIMIT=5 SECRET_KEY=myv-y4#7j-dp-__@j#*3z@!y24fz8%^z2v6atuy4bo9vqr1_a ADMIN_PASSWORD=admin IS_FIRST_START=true DOCKERGEOSERVER_PORT_8080_TCP_PORT=8080 GEONODE_DATABASE_SCHEMA=public DJANGO_SETTINGS_MODULE=geonode.settings GEOSERVER_JAVA_OPTS=-Djava.awt.headless=true -Xms2G -Xmx4G -Dgwc.context.suffix=gwc -XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=/var/log/jvm.log -XX:PerfDataSamplingInterval=500 -XX:SoftRefLRUPolicyMSPerMB=36000 -XX:-UseGCOverheadLimit -XX:+UseConcMarkSweepGC -XX:ParallelGCThreads=4 -Dfile.encoding=UTF8 -Djavax.servlet.request.encoding=UTF-8 -Djavax.servlet.response.encoding=UTF-8 -Duser.timezone=GMT -Dorg.geotools.shapefile.datetime=false -DGS-SHAPEFILE-CHARSET=UTF-8 -DGEOSERVER_CSRF_DISABLED=true -DPRINT_BASE_URL=http://geoserver:8080/geoserver/pdf -DALLOW_ENV_PARAMETRIZATION=true -Xbootclasspath/a:/usr/local/tomcat/webapps/geoserver/WEB-INF/lib/marlin-0.9.3-Unsafe.jar -Dsun.java2d.renderer=org.marlin.pisces.MarlinRenderingEngine DOCKERGEOSERVER_PORT_8080_TCP=tcp://172.30.148.247:8080 SITEURL=http://localhost:8000/ GEONODE_LB_HOST_IP=geonode OAUTH2_CLIENT_ID=Jrchz2oPY3akmzndmgUTYrs9gczlgoV20YPSvqaV API_LIMIT_PER_PAGE=1000 GEOSERVER_LOCATION=http://localhost:8000/geoserver TERM=xterm GEONODE_GEODATABASE_SCHEMA=public HTTP_HOST=localhost GEONODE_INSTANCE_NAME=geonode EMAIL_ENABLE=False LETSENCRYPT_MODE=disabled DOCKERGEOSERVER_PORT=tcp://172.30.148.247:8080 SHLVL=0 HTTPS_PORT=8443 OGC_REQUEST_POOL_MAXSIZE=10 POSTGRES_USER='password' GEODATABASE_URL=postgis://geonode:geonode@egomapdev-pgdb-pp07.app.ford.com:5432/geonode_data HTTPS_PROXY=https://internet.ford.com HTTP_PROXY=http://internet.ford.com KUBERNETES_PORT_443_TCP_PROTO=tcp QGIS_SERVER_SVC_PORT_5555_TCP_PORT=5555 GEONODE_GEODATABASE_PASSWORD=geonode IS_CELERY=False GEONODE_DATABASE_PASSWORD=geonode DATABASE_HOST=egomapdev-pgdb-pp07.app.ford.com KUBERNETES_PORT_443_TCP_ADDR=172.30.0.1 GEOSERVER_PUBLIC_LOCATION=http://localhost:8000/geoserver LC_CTYPE=C.UTF-8 GEONODE_DB_CONN_TOUT=5 CREATE_LAYER=True GEOSERVER_ADMIN_PASSWORD=geoserver INVOKE_LOG_STDOUT=true GEOSERVER_CORS_ENABLED=True FEATURESERV_PORT_9000_TCP_PORT=9000 KUBERNETES_SERVICE_HOST=172.30.0.1 KUBERNETES_PORT=tcp://172.30.0.1:443 KUBERNETES_PORT_443_TCP_PORT=443 GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY=mapstore GEONODE_GEODATABASE=geonode_data OGC_REQUEST_BACKOFF_FACTOR=0.3 FORCE_REINIT=False GEOSERVER_ADMIN_USER=admin GEONODE_DATABASE=geonode PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin DOCKERGEOSERVER_SERVICE_PORT=8080 DOCKERGEOSERVER_PORT_8080_TCP_ADDR=172.30.148.247 MONITORING_ENABLED=False GEONODE_LB_PORT=8000 CORS_ALLOW_ALL_ORIGINS=True DOCKER_API_VERSION=1.24 DOCKER_ENV=production GEOSERVER_WEB_UI_LOCATION=http://localhost:8000/geoserver POSTGRESQL_MAX_CONNECTIONS=200 DEBUG=True OAUTH2_CLIENT_SECRET=rCnp5txobUo83EpQEblM8fVj3QT5zb5qRfxNsuPzCqZaiRyIoxM4jdgMiZKFfePBHYXCLd7B8NlkfDBY9HKeIQPcy5Cp08KQNpRHQbjpLItDHv12GvkSeXp6OxaUETv3 SESSION_EXPIRED_CONTROLENABLED=True =/usr/bin/env Public Hostname or IP is geonode Public PORT is 8000

Steps to Reproduce the Problem

  1. create pvc
  2. configmap with .env variable mount this in statefulset geonode deployment
  3. Deploy statefulset
  4. you see the pod is running ps -ef in the pod shows below processes 5.1002820+ 1 0 0 13:55 ? 00:00:00 /bin/bash /usr/src/geonode/entrypoint.sh uwsgi --ini /usr/src/geonode/uwsgi 1002820+ 27 1 1 13:55 ? 00:00:00 /usr/bin/python3 /usr/local/bin/invoke update 1002820+ 31 0 1 13:55 pts/0 00:00:00 sh -i -c TERM=xterm sh 1002820+ 37 31 0 13:55 pts/0 00:00:00 sh 1002820+ 38 37 0 13:56 pts/0 00:00:00 ps -ef

Specifications

giohappy commented 1 year ago

@rkhandha at the moment there's no official support for deploying GeoNode on k8s and OpenShift. It would be great if we could share any experience on the topic and reach a consensus for a basic shared setup. If you have something to share and something that could be done in GeoNode, feel free to open a GNIP

It's really hard to understand what's going on with your setup if it depends on GeoNode or your deployment. I would close it unless you have more details.

rkhandha commented 1 year ago

Thank you for response, I have figured out some of the issues, they are related to .env file and running the container as nonroot. If you have document that has detail information on .env and their dependency on the process that run and you could share it that would be great. I looked at https://docs.geonode.org/en/master/basic/settings/index.html did not have the details that would give dependency information. For e.g. if the pod name is not geonode then this failure occurs, so it failed when I created the statefull deployment. I am still getting some other errors, so still not working. I will check with my client if I can share this information once I have ironed out all the errors. Thank you again for all your help.

rkhandha commented 1 year ago

This was fixed my new image that was pushed in Docker hub. DIGEST:sha256:2ad5922d35a4442bac1a9c9b917596c8195f7c70a8dd5ead17117c4af3457f5c