subdomains standard google features engine compute classes change app google-app-engine continuous-integration continuous-deployment gitlab-ci continuous-delivery

standard - Integración/implementación/entrega continua en Google App Engine, ¿demasiado arriesgado?



google app engine memory limit (1)

Recientemente, hemos configurado la integración / implementación / entrega continua de una aplicación web de nodejs en Google App Engine. El servidor CI (GitLabCI) ejecuta la instalación, compilación, pruebas e implementación de dependencias para la integración / producción dependiendo de la rama (desarrollo / maestro).

En el día de hoy, los únicos errores que enfrentamos fue durante el paso de dependencias, por lo que no nos importó mucho. Pero ayer (21/10/16), hubo una interrupción del servicio de DNS a gran escala y la tubería falló en el medio del paso de despliegue, rompiendo el producto . Simplemente volver a ejecutar la tubería ha hecho el trabajo, pero el problema puede reproducirse en cualquier momento.

Mis preguntas son:

  • ¿Cómo podemos manejar este tipo de problemas de red, en el proceso de implementación continua?
  • ¿La implementación continua en Google App Engine es realmente una buena idea?
  • Si es así, ¿cuál es el método de implementación de App Engine? No encuentro ningún documento relevante al respecto ...

Por el momento solo tenemos dos versiones "dev" y "prod" que se actualizan después de los commits, pero en momentos aleatorios pude observar comportamientos extraños.

Cualquier respuesta / sugerencia / retroalimentación es muy bienvenida!

Ejemplo de stacktrace sobre los problemas de red de los que estoy hablando:

DEBUG: Error sending result: ''MetadataServerException(HTTPError(),)''. Reason: ''PicklingError("Can''t pickle <type ''cStringIO.StringO''>: attribute lookup cStringIO.StringO failed",)'' Traceback (most recent call last): File "/google-cloud-sdk/lib/googlecloudsdk/calliope/cli.py", line 733, in Execute resources = args.calliope_command.Run(cli=self, args=args) File "/google-cloud-sdk/lib/googlecloudsdk/calliope/backend.py", line 1630, in Run resources = command_instance.Run(args) File "/google-cloud-sdk/lib/surface/app/deploy.py", line 53, in Run return deploy_util.RunDeploy(self, args) File "/google-cloud-sdk/lib/googlecloudsdk/command_lib/app/deploy_util.py", line 387, in RunDeploy all_services) File "/google-cloud-sdk/lib/googlecloudsdk/command_lib/app/deploy_util.py", line 247, in Deploy manifest = _UploadFiles(service, code_bucket_ref) File "/google-cloud-sdk/lib/googlecloudsdk/command_lib/app/deploy_util.py", line 115, in _UploadFiles service, code_bucket_ref) File "/google-cloud-sdk/lib/googlecloudsdk/api_lib/app/deploy_app_command_util.py", line 277, in CopyFilesToCodeBucketNoGsUtil _UploadFiles(files_to_upload, bucket_ref) File "/google-cloud-sdk/lib/googlecloudsdk/api_lib/app/deploy_app_command_util.py", line 219, in _UploadFiles results = pool.map(_UploadFile, tasks) File "/usr/lib/python2.7/multiprocessing/pool.py", line 251, in map return self.map_async(func, iterable, chunksize).get() File "/usr/lib/python2.7/multiprocessing/pool.py", line 558, in get raise self._value MaybeEncodingError: Error sending result: ''MetadataServerException(HTTPError(),)''. Reason: ''PicklingError("Can''t pickle <type ''cStringIO.StringO''>: attribute lookup cStringIO.StringO failed",)'' DEBUG: Exception captured in Error Traceback (most recent call last): File "/google-cloud-sdk/lib/googlecloudsdk/core/metrics.py", line 411, in Wrapper return func(*args, **kwds) TypeError: Error() takes exactly 3 arguments (1 given) ERROR: gcloud crashed (MaybeEncodingError): Error sending result: ''MetadataServerException(HTTPError(),)''. Reason: ''PicklingError("Can''t pickle <type ''cStringIO.StringO''>: attribute lookup cStringIO.StringO failed",)'' Traceback (most recent call last): File "/google-cloud-sdk/lib/gcloud.py", line 65, in <module> main() File "/google-cloud-sdk/lib/gcloud.py", line 61, in main sys.exit(googlecloudsdk.gcloud_main.main()) File "/google-cloud-sdk/lib/googlecloudsdk/gcloud_main.py", line 145, in main crash_handling.HandleGcloudCrash(err) File "/google-cloud-sdk/lib/googlecloudsdk/command_lib/crash_handling.py", line 107, in HandleGcloudCrash _ReportError(err) File "/google-cloud-sdk/lib/googlecloudsdk/command_lib/crash_handling.py", line 86, in _ReportError util.ErrorReporting().ReportEvent(error_message=stacktrace, File "/google-cloud-sdk/lib/googlecloudsdk/api_lib/error_reporting/util.py", line 28, in __init__ self._API_NAME, self._API_VERSION) File "/google-cloud-sdk/lib/googlecloudsdk/core/apis.py", line 254, in GetClientInstance http_client = http.Http() File "/google-cloud-sdk/lib/googlecloudsdk/core/credentials/http.py", line 60, in Http creds = store.Load() File "/google-cloud-sdk/lib/googlecloudsdk/core/credentials/store.py", line 282, in Load if account in c_gce.Metadata().Accounts(): File "/google-cloud-sdk/lib/googlecloudsdk/core/credentials/gce.py", line 122, in Accounts gce_read.GOOGLE_GCE_METADATA_ACCOUNTS_URI + ''/'') File "/google-cloud-sdk/lib/googlecloudsdk/core/util/retry.py", line 160, in TryFunc return func(*args, **kwargs), None File "/google-cloud-sdk/lib/googlecloudsdk/core/credentials/gce.py", line 45, in _ReadNoProxyWithCleanFailures raise MetadataServerException(e) googlecloudsdk.core.credentials.gce.MetadataServerException: HTTP Error 503: Service Unavailable DEBUG: Uploading [/builds/apps/webapp/lib/jinja2/defaults.pyc] to [151c77b4e5bdd2c38b6a2bf914fffa3a6ffa71a6] INFO: Uploading [/builds/apps/webapp/lib/jinja2/defaults.pyc] to [151c77b4e5bdd2c38b6a2bf914fffa3a6ffa71a6] INFO: Refreshing access_token


¿Bueno malo? Subjetivo - por lo tanto fuera de tema para SO. Asumir que la pregunta es cómo hacer que la implementación continua sea confiable :)

Bueno, el problema es que está utilizando versiones de aplicaciones como sus entornos de CI, lo que significa que no puede evitar roturas debido a que una versión específica es mala. Solo puede esperar recuperarse lo más rápido posible al volver a implementar la versión (cuando finaliza la interrupción), esto puede automatizarse.

No debe tener su sitio de producción ejecutándose directamente fuera de la versión sobrescrita por la canalización de production CI, de lo contrario corre el riesgo de interrupción del sitio en una implementación incorrecta. En su lugar, podría usar una versión nueva / única para cada ejecución de la canalización de production CI y solo después de que se complete con éxito, finalmente cambiará el tráfico del sitio a su versión utilizando el flujo descrito a continuación (que también se puede utilizar dentro de las canalizaciones de CI si se utilizan diferentes aplicaciones en lugar de versiones de aplicaciones como entornos de CI)

Desde la implementación de su programa :

Por defecto, el comando de despliegue genera automáticamente una nueva ID de versión cada vez que lo usa y enrutará cualquier tráfico a la nueva versión.

Para anular este comportamiento, puede especificar la ID de versión con el indicador de versión:

gcloud app deploy --version myID

También puede especificar no enviar todo el tráfico a la nueva versión inmediatamente con el indicador --no-promote:

gcloud app deploy --no-promote

Por lo tanto, asegúrese de nunca implementar una versión y hacer que esa versión sea el destino de tráfico predeterminado en el mismo paso (posiblemente no atómica si se maneja desde el lado del cliente). Especialmente para la aplicación de producción. En lugar:

De esta manera, la única operación crítica es el cambio de tráfico, que (con suerte) es una operación atómica que tiene éxito o se revierte por completo en el lado GAE (si no es un error GAE). Si este paso falla, la aplicación debería seguir funcionando con la versión anterior.

Por supuesto, esto supone que los problemas de red solo se encuentran entre usted y GAE, si también están afectando las operaciones internas de GAE, todas las apuestas están canceladas (pero aquellos en los que confío deberían resolverse bastante oportunamente).