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.
