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.

Read More

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *