Java, Openshift, Spring Boot

What are Deployments in context of OpenShift ?

Often time we see or hear that it is deployment time and we are going to deploy our code in DEV or TEST or PRODUCTION environments. This applies to all sorts of platform, since we are talking about OpenShift (Open source container application platform that allows us to deploy applications) I will write about what does deployment mean on OpenShift and brief overview of how this is made possible using OpenShift’s unique Configuration platform.

OpenShift Deployments are done using a pre-defined template format usually in the form of configuration files (some-template.yml). They are recommended to be defined using three core separate API Objects.

  1. A deployment configuration (a template for running applications), which describes the desired state of a particular component of the application as a pod template.
  • One or more replication controllers, which contain a point-in-time record of the state of a deployment configuration as a pod template.
  • One or more pods, which represent an instance of a particular version of an application.

Note: These three above will be explained with the sample deploy-demo-template.yml configuration.

Users do not need to manipulate replication controllers or pods owned by deployment configurations because OpenShift structure ensures changes to deployment configurations are propagated appropriately. If the existing deployment strategies are not suited for your use case, then you can create a custom strategy.

One of the bigger advantage of creating a deployment configuration is that a replication controller is created representing the corresponding deployment configuration’s pod template. If the deployment configuration changes, a new replication controller is created with the latest pod template.

Other thing that makes OpenShift deployment different from rest of them is the deployment process that runs to scale down the old replication controller and scale up the new replication controller. Instances of your application are automatically added and removed from both service load balancers and routers as they are created.

SampleFor declaration annotated with $ and all CAPS read the key-value called “parameters” that has description on what are they doing on this Deploy Template. For Deployment specific check on kind: DeploymentConfig key-value on this sample below.

deploy-demo-template.yml

---
kind: Template
apiVersion: v1
metadata:
  name: "${COMPONENT_NAME}"
  annotations:
    OpenShift.io/display-name: Java S2I
    description: Deploys an uber jar of Your Application
    tags: Your Display Name,java,java8,maven,fat-jar,uber-jar,s2i,openjdk
    iconClass: icon-openjdk
    template.OpenShift.io/long-description: This template defines resources needed
      to develop a Java application, including a build configuration and application
      deployment configuration.  It does not include a database.
    template.OpenShift.io/provider-display-name: Your Display Name
    template.OpenShift.io/documentation-url: http://somerepo.Your Display Name.com:9080/somerepo/Your Display NameProd/TBD/_git/OpenShift-base-templates?path=%2Fs2i-templates
    template.OpenShift.io/support-url: https://sample.demo.Your Display Name.com/sites/TBD/SAMPLE/OpenShift/SitePages/Home.aspx
message: 'The following service(s) have been created in your project: ${COMPONENT_NAME}.'
labels:
  app: "${COMPONENT_NAME}"
  template: openjdk18-OpenShift-Your Display Name
objects:
  - kind: Service
    apiVersion: v1
    metadata:
      name: "${COMPONENT_NAME}"
      labels:
        component: "${COMPONENT_NAME}"
      annotations:
        description: Exposes and load balances the application pods
    spec:
      ports:
        - name: web
          port: 9080
          targetPort: 9080
      selector:
        name: "${COMPONENT_NAME}"
  - apiVersion: v1
    kind: DeploymentConfig
    metadata:
      name: "${COMPONENT_NAME}"
      annotations:
        description: Defines how to deploy the application server
      labels:
        component: "${COMPONENT_NAME}"
    spec:
      strategy:
        type: Rolling
        resources:
          requests:
            cpu: "100m"
            memory: "500Mi"
          limits:
            cpu: "100m"
            memory: "500Mi"
      triggers:
        - type: ImageChange
          imageChangeParams:
            automatic: false
            containerNames:
              - "${COMPONENT_NAME}"
            from:
              kind: ImageStreamTag
              name: "${COMPONENT_NAME}:${IMAGE_TAG}"
      replicas: "${{NUM_REPLICAS}}"
      selector:
        name: "${COMPONENT_NAME}"
      template:
        metadata:
          labels:
            name: "${COMPONENT_NAME}"
          name: "${COMPONENT_NAME}"
        spec:
          nodeSelector:
            fuse-license: "${FUSE_LICENSE}"
          containers:
            - name: "${COMPONENT_NAME}"
              image: "docker-registry.default.svc:5000/${IMAGE_NAMESPACE}/${COMPONENT_NAME}:${IMAGE_TAG}"
              ports:
                - containerPort: 9080
              readinessProbe:
                httpGet:
                  path: "/actuator/health"
                  port: 9090
                initialDelaySeconds: "${{READINESS_DELAY}}"
                failureThreshold: "${{READINESS_FAILURE_THRESHOLD}}"
                periodSeconds: "${{READINESS_PERIOD_SECONDS}}"
                timeoutSeconds: 10
              livenessProbe:
                httpGet:
                  path: "/actuator/health"
                  port: 9090
                initialDelaySeconds: "${{LIVENESS_DELAY}}"
                failureThreshold: "${{LIVENESS_FAILURE_THRESHOLD}}"
                periodSeconds: "${{LIVENESS_PERIOD_SECONDS}}"
                timeoutSeconds: 10
              envFrom:
                - configMapRef:
                    name: "datacenter-configs"
                    optional: true
              env:
                - name: SPRING_CONFIG_LOCATION
                  value: "/your/config-location/"
                - name: SPRING_PROFILES_ACTIVE
                  value: "OpenShift"
                - name: BC_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: encryption-secret
                      key: BC_PASSWORD
                - name: APM_ENABLED
                  value: 'true'
                - name: APP_POD_NAME
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.name
                - name: APP_POD_NAMESPACE
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.namespace
                - name: _JAVA_OPTIONS
                  value: "-Xms${MIN_HEAP_SIZE} -Xmx${MAX_HEAP_SIZE}"
                - name: MESSAGETYPES_JSON_FILE_LOCATION
                  value: "/your/config-location/messagetypes.json"
              resources:
                requests:
                  cpu: "${DEPLOY_CPU_REQUEST}"
                  memory: "${DEPLOY_MEM_REQUEST}"
                limits:
                  cpu: "${DEPLOY_CPU_LIMIT}"
                  memory: "${DEPLOY_MEM_LIMIT}"
              volumeMounts:
                - mountPath: "/your/config-location/"
                  name: "${SERVICE_PREFIX}-volume"
          volumes:
            - name: "${SERVICE_PREFIX}-volume"
              projected:
                sources:
                  - configMap:
                      name: "${SERVICE_PREFIX}-configs"
                  - configMap:
                      name: "connection-configs"

parameters:
  - name: SERVICE_PREFIX
    displayName: Name
    description: The prefix of the service, the name of the service without the '-service' suffix.
    required: true
    value: ''
  - name: COMPONENT_NAME
    displayName: Name
    description: The name assigned to all of the frontend objects defined in this template.
    required: true
    value: ''
  - name: APPLICATION_DOMAIN
    displayName: Application Hostname
    description: The exposed hostname that will route to the Java service, if left blank
      a value will be defaulted.
    value: ''
  - name: SOURCE_REPOSITORY_URL
    displayName: Git Repository URL
    description: The URL of the repository with your application source code.
    required: true
    value: ''
  - name: SOURCE_REPOSITORY_REF
    displayName: Git Reference
    description: Set this to a branch name, tag or other ref of your repository if you
      are not using the default branch.
    value: ''
  - name: CONTEXT_DIR
    displayName: Context Directory
    description: Set this to the relative path to your project if it is not in the root
      of your repository.
    value: ''
  - name: LIVENESS_DELAY
    value: '120'
    description: Intial amount of time in seconds to wait to perform a liveness check.
    required: true
  - name: READINESS_DELAY
    value: '60'
    description: Intial amount of time in seconds to wait to perform a readiness check.
    required: true
  - name: DEPLOY_CPU_REQUEST
    description: The requested CPU for a deploy.
    value: 100m
    required: true
  - name: DEPLOY_MEM_REQUEST
    description: The requested memory for a deploy
    value: 1000Mi
    required: true
  - name: DEPLOY_CPU_LIMIT
    description: The limit of CPU to allow for a deploy
    value: 500m
    required: true
  - name: DEPLOY_MEM_LIMIT
    description: The limit of memory to allow for a deploy
    value: 1000Mi
    required: true
  - name: NUM_REPLICAS
    description: The number of replicas
    value: '1'
    required: true
  - name: READINESS_PERIOD_SECONDS
    description: Once the application is ready, how often should OpenShift verify the
      application is still ready? (In seconds)
    value: '10'
    required: true
  - name: LIVENESS_PERIOD_SECONDS
    description: Once the application is Live, how often should OpenShift verify the
      application is still live? (In seconds)
    value: '10'
    required: true
  - name: READINESS_FAILURE_THRESHOLD
    description: How many times can the application fail a readiness check before telling
      OpenShift it's no longer ready
    value: '3'
    required: true
  - name: LIVENESS_FAILURE_THRESHOLD
    description: Once the application is Live, how many times can the liveness check fail before killing the pod
    value: '3'
    required: true
  - name: MIN_HEAP_SIZE
    description: Minimum heap size of JVM for this service
    value: '500m'
    required: true
  - name: MAX_HEAP_SIZE
    description: Maximum heap size of JVM for this service
    value: '1200m'
  - name: FUSE_LICENSE
    description: Whether or not this pod should be scheduled on an OpenShift host with FUSE
    value: 'true'
    required: true
  - name: IMAGE_NAMESPACE
    description: The namespace that holds the image of this service
    required: true
  - name: IMAGE_TAG
    description: Version of the image this deployment should use
    required: true
    value: 'latest'
  - name: CONFIG_FOLDER
    description: the folder relative to /your/config-location/ to find the config map
    required: false

You can use this above template and start testing your deployments.

For full and detailed examples please follow the official website of Red Hat OpenShift .

Leave a Reply