Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use image stream in deploy configuration for OpenShift

I want my deploy configuration to use an image that was the output of a build configuration.

I am currently using something like this:

- apiVersion: v1
  kind: DeploymentConfig
  metadata:
    annotations:
      openshift.io/generated-by: OpenShiftNewApp
    creationTimestamp: null
    labels:
      app: myapp
    name: myapp
  spec:
    replicas: 1
    selector:
      app: myapp
      deploymentconfig: myapp
    strategy:
      resources: {}
    template:
      metadata:
        annotations:
          openshift.io/container.myapp.image.entrypoint: '["python3"]'
          openshift.io/generated-by: OpenShiftNewApp
        creationTimestamp: null
        labels:
          app: myapp
          deploymentconfig: myapp
      spec:
        containers:
        - name: myapp
          image: 123.123.123.123/myproject/myapp-staging:latest
          resources: {}
          command:
            - scripts/start_server.sh
          ports:
            - containerPort: 8000
    test: false
    triggers: []
  status: {}

I had to hard-code the integrated docker registry's IP address; otherwise Kubernetes/OpenShift is not able to find the image to pull down. I would like to not hard-code the integrated docker registry's IP address, and instead use something like this:

- apiVersion: v1
  kind: DeploymentConfig
  metadata:
    annotations:
      openshift.io/generated-by: OpenShiftNewApp
    creationTimestamp: null
    labels:
      app: myapp
    name: myapp
  spec:
    replicas: 1
    selector:
      app: myapp
      deploymentconfig: myapp
    strategy:
      resources: {}
    template:
      metadata:
        annotations:
          openshift.io/container.myapp.image.entrypoint: '["python3"]'
          openshift.io/generated-by: OpenShiftNewApp
        creationTimestamp: null
        labels:
          app: myapp
          deploymentconfig: myapp
      spec:
        containers:
        - name: myapp
          from:
            kind: "ImageStreamTag"
            name: "myapp-staging:latest"
          resources: {}
          command:
            - scripts/start_server.sh
          ports:
            - containerPort: 8000
    test: false
    triggers: []
  status: {}

But this causes Kubernetes/OpenShift to complain with:

The DeploymentConfig "myapp" is invalid.
spec.template.spec.containers[0].image: required value

How can I specify the output of a build configuration as the image to use in a deploy configuration?

Thank you for your time!

Also, oddly enough, if I link the deploy configuration to the build configuration with a trigger, Kubernetes/OpenShift knows to look in the integrated docker for the image:

- apiVersion: v1
  kind: DeploymentConfig
  metadata:
    annotations:
      openshift.io/generated-by: OpenShiftNewApp
    creationTimestamp: null
    labels:
      app: myapp-staging
    name: myapp-staging
  spec:
    replicas: 1
    selector:
      app: myapp-staging
      deploymentconfig: myapp-staging
    strategy:
      resources: {}
    template:
      metadata:
        annotations:
          openshift.io/container.myapp.image.entrypoint: '["python3"]'
          openshift.io/generated-by: OpenShiftNewApp
        creationTimestamp: null
        labels:
          app: myapp-staging
          deploymentconfig: myapp-staging
      spec:
        containers:
        - name: myapp-staging
          image: myapp-staging:latest
          resources: {}
          command:
            - scripts/start_server.sh
          ports:
            - containerPort: 8000
    test: false
    triggers:
    - type: "ImageChange"
      imageChangeParams:
        automatic: true
        containerNames:
        - myapp-staging
        from:
          kind: ImageStreamTag
          name: myapp-staging:latest
  status: {}

But I don't want the automated triggering...

Update 1 (11/21/2016): Configuring the trigger but having the trigger disabled (hence manually triggering the deploy), still left the deployment unable to find the image:

$ oc describe pod myapp-1-oodr5
Name:                   myapp-1-oodr5
Namespace:              myproject
Security Policy:        restricted
Node:                   node.url/123.123.123.123
Start Time:             Mon, 21 Nov 2016 09:20:26 -1000
Labels:                 app=myapp
                        deployment=myapp-1
                        deploymentconfig=myapp
Status:                 Pending
IP:                     123.123.123.123
Controllers:            ReplicationController/myapp-1
Containers:
  myapp:
    Container ID:
    Image:              myapp-staging:latest
    Image ID:
    Port:               8000/TCP
    Command:
      scripts/start_server.sh
    State:              Waiting
      Reason:           ImagePullBackOff
    Ready:              False
    Restart Count:      0
    Volume Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-goe98 (ro)
    Environment Variables:
      ALLOWED_HOSTS:    myapp-myproject.url
Conditions:
  Type          Status
  Ready         False 
Volumes:
  default-token-goe98:
    Type:       Secret (a volume populated by a Secret)
    SecretName: default-token-goe98
QoS Tier:       BestEffort
Events:
  FirstSeen     LastSeen        Count   From                                    SubobjectPath                           Type            Reason          Message
  ---------     --------        -----   ----                                    -------------                           --------        ------          -------
  42s           42s             1       {scheduler }                                                                                    Scheduled       Successfully assigned myapp-1-oodr5 to node.url
  40s           40s             1       {kubelet node.url}  implicitly required container POD                       Pulled          Container image "openshift3/ose-pod:v3.1.1.7" already present on machine
  40s           40s             1       {kubelet node.url}  implicitly required container POD                       Created         Created with docker id d3318e880e4a
  40s           40s             1       {kubelet node.url}  implicitly required container POD                       Started         Started with docker id d3318e880e4a
  40s           24s             2       {kubelet node.url}  spec.containers{myapp}                            Pulling         pulling image "myapp-staging:latest"
  38s           23s             2       {kubelet node.url}  spec.containers{myapp}                            Failed          Failed to pull image "myapp-staging:latest": Error: image library/myapp-staging:latest not found
  35s           15s             2       {kubelet node.url}  spec.containers{myapp}                            Back-off        Back-off pulling image "myapp-staging:latest"

Update 2 (08/23/2017): In case, this helps others, here's a summary of the solution.

triggers:    
- type: "ImageChange"
  imageChangeParams:
    automatic: true # this is required to link the build and deployment
    containerNames:
    - myapp-staging
    from:
      kind: ImageStreamTag
      name: myapp-staging:latest

With the trigger and automatic set to true, the deployment should use the build's image in the internal registry.

The other comments relating to making the build not trigger a deploy relates to a separate requirement of wanting to manually deploy images from the internal registry. Here's more information about that portion:

The build needs to trigger the deployment at least once before automatic is set to false. So far a while, I was:

  1. setting automatic to true
  2. initiate a build and deploy
  3. after deployment finishes, manually change automatic to false
  4. manually, trigger a deployment later (though I did not verify if this deployed the older, out-of-date image or not)

I was initially trying to use this manual deployment as a way for a non-developer to go into the web console and make deployments. But this requirement has since been removed, so having build trigger deployments each time works just fine for us now. Builds can build at different branches and then tag the images differently. Deployments can then just use the appropriately tagged images.

Hope that helps!

like image 481
Zhao Li Avatar asked Nov 14 '16 21:11

Zhao Li


People also ask

What is image stream in OpenShift?

An image stream and its associated tags provide an abstraction for referencing container images from within OpenShift Container Platform. The image stream and its tags allow you to see what images are available and ensure that you are using the specific image you need even if the image in the repository changes.

Can you use Docker images in OpenShift?

The first thing is to actually get OpenShift up and running and get a development environment setup in which we can simply push Docker images to it without having to use any of the Source-2-Image or OpenShift build mechanisms.

How do I deploy an application using OpenShift?

There are two easy ways to deploy an OpenShift Application. Using Console: You can directly deploy the website using the Graphical User Interface of OpenShift with just a few clicks. Using CLI: OpenShift also provides a Command Line Interface where with few commands, you can deploy an Application.


1 Answers

Are you constructing the resource definitions by hand?

It would be easier to use oc new-build and then oc new-app if you really need to set this up as two steps for some reason. If you just want to setup the build and deployment in one go, just use oc new-app.

For example, to setup build and deployment in one go use:

oc new-app --name myapp <repository-url>

To do it in two steps use:

oc new-build --name myapp <repository-url>
oc new-app myapp

If you still rather use hand created resources, at least use the single step variant with the --dry-run -o yaml options to see what it would create for the image stream, plus build and deployment configuration. That way you can learn from it how to do it. The bit you currently have missing is an image stream.

BTW. It looks a bit suspicious that you have the entry point set to python3. That is highly unusual. What are you trying to do as right now it looks like you may be trying to do something in a way which may not work with how OpenShift works. OpenShift is mainly about long running processes and not for doing single docker run. You can do the latter, but not how you are currently doing it.

like image 176
Graham Dumpleton Avatar answered Oct 19 '22 19:10

Graham Dumpleton