Openshift. Desplegar una imagen a partir de una plantilla.
Hablando de despliegues en openshift, ya vimos en esta entrada la forma de desplegar una imagen por linea de comandos.
En ese caso una vez desplegada la imagen con el comando new-app, que se apoya en s2i, íbamos lanzando comandos para aplicar variables de entorno, exponer el servicio, etc…
Todo esto se puede simplificar con el uso de plantillas. Las plantillas nos permiten desplegar una imagen y definir toda su configuración asociada en un solo paso.
La mejor forma de crear una plantilla, es exportarla a partir de un despliegue existente. El comando a utilizar es oc export, al que le indicaremos los componentes que queremos exportar y que lo haga como plantilla:
oc export dc,secret,pvc,cm,svc,route,limits --selector=app=mi-despliegue -o yaml --as-template=mi-namespace > nombre-plantilla.yml
En el comando anterior le estamos diciendo que exporte el despliegue «mi-despliegue» en formato yaml, como plantilla y que los elementos a incluir en la plantilla son el Deployment Config, los secretos, los persistent volumes, el config map, servicio, rutas y limites de recursos. El resultado es algo similar a esto:
apiVersion: v1 kind: Template metadata: name: -nombre-namespace- objects: apiVersion: v1 kind: Service metadata: annotations: openshift.io/generated-by: OpenShiftNewApp labels: app: mi-despliegue name: mi-despliegue spec: ports: name: 8080-tcp port: 8080 protocol: TCP targetPort: 8080 name: 8443-tcp port: 8443 protocol: TCP targetPort: 8443 name: 8778-tcp port: 8778 protocol: TCP targetPort: 8778 selector: app: mi-despliegue deploymentconfig: mi-despliegue-dc sessionAffinity: None type: ClusterIP status: loadBalancer: {} apiVersion: v1 kind: DeploymentConfig metadata: annotations: openshift.io/generated-by: OpenShiftNewApp generation: 3 labels: app: mi-despliegue name: mi-despliegue spec: replicas: 2 revisionHistoryLimit: 10 selector: app: mi-despliegue deploymentconfig: mi-despliegue-dc strategy: activeDeadlineSeconds: 21600 resources: {} rollingParams: intervalSeconds: 1 maxSurge: 25% maxUnavailable: 25% timeoutSeconds: 600 updatePeriodSeconds: 1 type: Rolling template: metadata: annotations: openshift.io/generated-by: OpenShiftNewApp creationTimestamp: null labels: app: mi-despliegue deploymentconfig: mi-despliegue-dc spec: containers: - env: - name: GC_MAX_METASPACE_SIZE value: "250" - name: JAVA_INITIAL_MEM_RATIO value: "100" - name: JAVA_MAX_MEM_RATIO value: "75" - name: com_sun_xml_bind_v2_bytecode_ClassTailor_noOptimize value: "true" - name: spring.main.banner-mode value: "off" - name: spring_profiles_active value: openshift - name: spring_jmx_enabled value: "true" - name: management_endpoints_jmx_exposure_include value: '*' - name: management_endpoints_jmx_exposure_exclude - name: SERVER_SERVLET_CONTEXT_PATH value: / image: docker-registry.default.svc:5000/-namespace-/mi-despliegue-imagen imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /actuator/health port: 8080 scheme: HTTP initialDelaySeconds: 120 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 3 name: container-mi-despliegue ports: - containerPort: 8080 protocol: TCP - containerPort: 8443 protocol: TCP - containerPort: 8778 name: jolokia protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /actuator/health port: 8080 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 3 resources: limits: cpu: 250m memory: 512Mi requests: cpu: 100m memory: 256Mi terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /data/config name: my-config dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 volumes: - configMap: defaultMode: 420 name: my-config name: my-config test: false triggers: type: ConfigChange imageChangeParams: automatic: true containerNames: container-mi-despliegue from: kind: ImageStreamTag name: mi-despliegue-imagen:etiqueta namespace: acoc-inte-bck lastTriggeredImage: docker-registry.default.svc:5000/-namespace-/mi-despliegue-imagen@sha256:37f36e7c5e1198d1e72d86f9bde93647cee316c9e39e9703b13588ab0fbd9c09 type: ImageChange status: availableReplicas: 0 latestVersion: 0 observedGeneration: 0 replicas: 0 unavailableReplicas: 0 updatedReplicas: 0 apiVersion: v1 kind: Route metadata: annotations: openshift.io/host.generated: "true" creationTimestamp: null labels: app: mi-despliegue name: mi-despliegue spec: host: mi-despliegue.-dominioopenshift- port: targetPort: 8080-tcp to: kind: Service name: mi-despliegue-svc weight: 100 wildcardPolicy: None status: ingress: conditions: lastTransitionTime: 2019-07-22T11:48:35Z status: "True" type: Admitted host: mi-despliegue.-dominioopenshift- routerName: router wildcardPolicy: None
Con esto tenemos la información solicitada volcada en el fichero nombre-plantilla.yml.
En el siguiente paso vamos a añadir variables a nuestra plantilla, que después le pasaremos como parámetros al procesarla. El formato es ${NOMBRE_VARIABLE}. En nuestro ejemplo, pondremos una variable ${NOMBRE_APLICACION} en lugar de mi-despliegue.
apiVersion: v1 kind: Template metadata: name: -nombre-namespace- objects: apiVersion: v1 kind: Service metadata: annotations: openshift.io/generated-by: OpenShiftNewApp labels: app: ${APPLICATION_NAME} name: ${APPLICATION_NAME} spec: ports: name: 8080-tcp port: 8080 protocol: TCP targetPort: 8080 name: 8443-tcp port: 8443 protocol: TCP targetPort: 8443 name: 8778-tcp port: 8778 protocol: TCP targetPort: 8778 selector: app: ${APPLICATION_NAME} deploymentconfig: ${APPLICATION_NAME}-dc sessionAffinity: None type: ClusterIP status: loadBalancer: {} apiVersion: v1 kind: DeploymentConfig metadata: annotations: openshift.io/generated-by: OpenShiftNewApp generation: 3 labels: app: ${APPLICATION_NAME} name: ${APPLICATION_NAME} spec: replicas: 2 revisionHistoryLimit: 10 selector: app: ${APPLICATION_NAME} deploymentconfig: ${APPLICATION_NAME}-dc strategy: activeDeadlineSeconds: 21600 resources: {} rollingParams: intervalSeconds: 1 maxSurge: 25% maxUnavailable: 25% timeoutSeconds: 600 updatePeriodSeconds: 1 type: Rolling template: metadata: annotations: openshift.io/generated-by: OpenShiftNewApp creationTimestamp: null labels: app: ${APPLICATION_NAME} deploymentconfig: ${APPLICATION_NAME}-dc spec: containers: - env: - name: ${GC_MAX_METASPACE_SIZE} value: "250" - name: ${JAVA_INITIAL_MEM_RATIO} value: "100" - name: ${JAVA_MAX_MEM_RATIO} value: "75" - name: com_sun_xml_bind_v2_bytecode_ClassTailor_noOptimize value: "true" - name: spring.main.banner-mode value: "off" - name: spring_profiles_active value: openshift - name: spring_jmx_enabled value: "true" - name: management_endpoints_jmx_exposure_include value: '*' - name: management_endpoints_jmx_exposure_exclude - name: ${SERVER_SERVLET_CONTEXT_PATH} value: / image: docker-registry.default.svc:5000/-namespace-/${APPLICATION_NAME}-imagen imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /actuator/health port: 8080 scheme: HTTP initialDelaySeconds: 120 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 3 name: container-${APPLICATION_NAME} ports: - containerPort: 8080 protocol: TCP - containerPort: 8443 protocol: TCP - containerPort: 8778 name: jolokia protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /actuator/health port: 8080 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 3 resources: limits: cpu: 250m memory: 512Mi requests: cpu: 100m memory: 256Mi terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /data/config name: my-config dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 volumes: - configMap: defaultMode: 420 name: my-config name: my-config test: false triggers: type: ConfigChange imageChangeParams: automatic: true containerNames: container-${APPLICATION_NAME} from: kind: ImageStreamTag name: ${APPLICATION_NAME}-imagen:etiqueta namespace: acoc-inte-bck lastTriggeredImage: docker-registry.default.svc:5000/-namespace-/${APPLICATION_NAME}-imagen@sha256:37f36e7c5e1198d1e72d86f9bde93647cee316c9e39e9703b13588ab0fbd9c09 type: ImageChange status: availableReplicas: 0 latestVersion: 0 observedGeneration: 0 replicas: 0 unavailableReplicas: 0 updatedReplicas: 0 apiVersion: v1 kind: Route metadata: annotations: openshift.io/host.generated: "true" creationTimestamp: null labels: app: ${APPLICATION_NAME} name: ${APPLICATION_NAME} spec: host: ${APPLICATION_NAME}.-dominioopenshift- port: targetPort: 8080-tcp to: kind: Service name: ${APPLICATION_NAME}-svc weight: 100 wildcardPolicy: None status: ingress: conditions: lastTransitionTime: 2019-07-22T11:48:35Z status: "True" type: Admitted host: ${APPLICATION_NAME}.-dominioopenshift- routerName: router wildcardPolicy: None
Por último añadimos a la plantilla los parámetros que puede recibir, en nuestro caso, el nombre de la aplicación, el context path de nuestra aplicación, y algunos parámetros para la maquina virtual de java:
parameters: - description: The name for the application. name: APPLICATION_NAME required: true - description: Maximun metaspace size for jvm name: GC_MAX_METASPACE_SIZE required: true value: '250' - description: Ratio of -Xms. 100 to set mx and ms to the same name: JAVA_INITIAL_MEM_RATIO required: true value: '100' - description: Ratio of -Xmx with whole container mem. name: JAVA_MAX_MEM_RATIO required: true value: '75' - description: Application Context Path name: SERVER_SERVLET_CONTEXT_PATH required: true value: /
Suponiendo que hemos mantenido el nombre del fichero, para realizar un nuevo despliegue, ahora solo habría que ejecutar el siguiente comando. Con la opción -p podemos pasarle valores a los parámetros de la plantilla, si no pasamos alguno, tomará el valor por defecto, si existe:
oc process -f nombre-plantilla.yml -p APPLICATION_NAME=mi-aplicacion-desde-plantilla | oc create -f -
Esto es todo por hoy.