OpenShift Create an Application from a Docker Image
Internal
Overview
A Docker image repository URL can be provided to oc new-app to create an application based on that image.
oc new-app <docker-repository-URL>
Example:
oc new-app docker.io/sonatype/nexus3:latest
This is roughly what happens during the application creation process:
Primitives
The utility creates an image stream, a deployment configuration and a service in the current project, and associate all of them with a single application by annotating them with the "app=<application-name>" label, where the application name is inferred from - and equal to - the name of the image repository given as argument.
1. Image Stream. The image stream name is set to the application name, and the object is associated with the application by the "app=<app-name> label.
apiVersion: v1 kind: ImageStream metadata: labels: app: nexus3 name: nexus3 spec: lookupPolicy: local: false tags: name: latest from: kind: DockerImage name: docker.io/sonatype/nexus3:latest referencePolicy: type: Source
2. Deployment Configuration The deployment configuration defines a selector that applied over pods, returns the number of pods that should match the replica count. It also defines a "rolling" deployment strategy by default. You may want to change that after the application primitives are first created. The deployment configuration includes the labels applied to the pod and pod's specification. The pod will consist of one container, which will be instantiated from the image specified as argument.
OpenShift performs an introspection of the image metadata and extracts the ports that should be exposed and the Docker data volumes needed, which are declaratively associated with persistent volumes:
"Id": "sha256:0b6b1bc88ccb767d128d87002d164ca1bd90ca0b7775aed3864504dcf8f968d8", "Config": { ... "ExposedPorts": { "8081/tcp": {} }, ... "Volumes": { "/nexus-data": {} }, ... }
By default, the deployment configuration declares an "emptyDir" volume, which is a temporary directory whose content will be lost upon pod recycling, so this is probably something you may want to change.
Finally, the deployment configuration contains metadata that says the redeployment will be attempted on configuration change and image change.
apiVersion: v1 kind: DeploymentConfig metadata: name: nexus3 labels: app: nexus3 spec: selector: app: nexus3 deploymentconfig: nexus3 strategy: type: Rolling rollingParams: ... activeDeadlineSeconds: 21600 template: metadata: labels: app: nexus3 deploymentconfig: nexus3 spec: containers: - name: nexus3 image: docker.io/sonatype/nexus3@sha256:1b1a581c76bf2a43112d4eea0077a73aadf234bb34a7b56f76fd5f3c1634dcaf imagePullPolicy: Always ports: - containerPort: 8081 protocol: TCP volumeMounts: - name: nexus3-volume-1 mountPath: /nexus-data dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler terminationGracePeriodSeconds: 30 volumes: - name: nexus3-volume-1 emptyDir: {} test: false triggers: - type: ConfigChange - type: ImageChange imageChangeParams: automatic: true containerNames: - nexus3 from: kind: ImageStreamTag name: nexus3:latest namespace: production-nexus
3. Service
apiVersion: v1 kind: Service metadata: name: nexus3 labels: app: nexus3 spec: clusterIP: 172.30.73.18 ports: - name: 8081-tcp port: 8081 protocol: TCP targetPort: 8081 selector: app: nexus3 deploymentconfig: nexus3 sessionAffinity: None type: ClusterIP
Post-Creation Operations
Simply creating the application triggers a deployment, while the application is not ready yet to be deployed, so we disable the automatic deployment and drop what has already been deployed:
oc rollout pause dc nexus3 oc delete rc <rc-name>
Deleting the replication controller will also terminate the pod it started.
Change the Deployment Strategy
oc patch dc nexus3 --patch='{ "spec": { "strategy": { "type": "Recreate" }}}'
Don't I need to also change configuration?
Attach a Valid Persistence Volume
For this to work, a 2Gi or more persistent volume must be already provisioned and available.
Create the persistent volume claim:
echo "apiVersion: v1 kind: PersistentVolumeClaim metadata: name: production-nexus-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 2Gi" | oc create -f -
If an appropriate persistent volume exists, it will be immediately bound after the persistent volume claim creation.
Modify the deployment configuration to use the persistent volume claim:
oc set volumes dc/nexus3 --remove --name=nexus3-volume-1
oc set volumes dc/nexus3 --add --name=nexus-data --mount-path=/nexus-data/ --type persistentVolumeClaim --claim-name=production-nexus-pvc
Setup Resources
oc set resources dc/nexus3 --limits=memory=2Gi --requests=memory=1Gi
Setup the Readiness and Liveness Probes
oc set probe dc/nexus3 --readiness \ --failure-threshold 3 --initial-delay-seconds 120 \ --get-url=http://:8081/repository/maven-public/
oc set probe dc/nexus3 --liveness \ --failure-threshold 3 --initial-delay-seconds 120 \ -- echo ok
Expose the Service
oc expose service nexus3 --hostname=maven.apps.openshift.novaordis.io
Resume Rollout
oc rollout resume dc nexus3
Example
For more details on how to deploy a production-ready Nexus instance starting with oc new-app <nexus-image-url>, go to: