Openshift 简明教程

OpenShift - Getting Started

OpenShift 包含两种媒体可以创建和部署应用程序,即 GUI 或 CLI。在本章中,我们将使用 CLI 创建一个新应用程序。我们将使用 OC 客户端与 OpenShift 环境进行通信。

OpenShift consists of two types of medians to create and deploy applications, either by GUI or by CLI. In this chapter, we would be using CLI to create a new application. We would be using OC client to communicate with the OpenShift environment.

Creating a New Application

在 OpenShift 中,有三种创建新应用程序的方法。

In OpenShift, there are three methods of creating a new application.

  1. From a source code

  2. From an image

  3. From a template

From a Source Code

当我们尝试从源代码创建应用程序时,OpenShift 会查找 repo 内应该存在的 Docker 文件,该文件定义应用程序构建流程。我们将使用 oc new-app 创建该应用程序。

When we try to create an application from the source code, OpenShift looks for a Docker file that should be present inside the repo, which defines the application build flow. We will use oc new-app to create an application.

使用 repo 时,首要记住的一件事是,它应该指向 repo 中的一个来源,OpenShift 将从中拉取代码并对其进行构建。

First thing to keep in mind while using a repo is that , it should point to a origin in the repo from where OpenShift will pull the code and build it.

如果 repo 已在安装了 OC 客户端的 Docker 机器上克隆,且用户位于同一目录中,那么可以使用以下命令创建它。

If the repo is cloned on the Docker machine where OC client is installed and the user is inside the same directory, then it can be created using the following command.

$ oc new-app . <Hear. Denotes current working directory>

以下是一个尝试从远程 repo 构建特定分支的示例。

Following is an example of trying to build from remote repo for a specific branch.

$ oc new-app https://github.com/openshift/Testing-deployment.git#test1

此处,test1 是我们要从中尝试在 OpenShift 中创建一个新应用程序的分支。

Here, test1 is the branch from where we are trying to create a new application in OpenShift.

在 repo 中指定 Docker 文件时,我们需要定义构建策略,如下所示。

When specifying a Docker file in the repository, we need to define the build strategy as shown below.

$ oc new-app OpenShift/OpenShift-test~https://github.com/openshift/Testingdeployment.git

From an Image

使用映像构建应用程序时,这些映像存在于本地 Docker 服务器、内部托管的 Docker repo 或 Docker 中心中。用户需要确保的一件事是没有问题地从中心拉取映像。

While building an application using images, the images are present in the local Docker server, in the in-house hosted Docker repository, or on the Docker hub. The only thing that a user needs to make sure is, he has the access to pull images from the hub without any issue.

OpenShift 具有确定所用来源(Docker 映像或源流)的能力。但是,如果用户需要,他可以明确定义是映像流还是 Docker 映像。

OpenShift has the capability to determine the source used, whether it is a Docker image or a source stream. However, if the user wishes he can explicitly define whether it is an image stream or a Docker image.

$ oc new-app - - docker-image tomcat

使用映像流 −

Using an image stream −

$ oc new-app tomcat:v1

From a Template

模板可以用于创建新应用程序。它可以是已存在的模板或创建一个新模板。

Templates can be used for the creation of a new application. It can be an already existing template or creating a new template.

以下 yaml 文件基本上是一个可用于部署的模板。

Following yaml file is basically a template that can be used for deployment.

apiVersion: v1
kind: Template
metadata:
   name: <Name of template>
   annotations:
      description: <Description of Tag>
      iconClass: "icon-redis"
      tags: <Tages of image>
objects:
   - apiVersion: v1
   kind: Pod
   metadata:
      name: <Object Specification>
spec:
   containers:
      image: <Image Name>
      name: master
      ports:
      - containerPort: <Container port number>
         protocol: <Protocol>
labels:
   redis: <Communication Type>

Develop and Deploy a Web Application

Developing a New Application in OpenShift

为了在 OpenShift 中创建一个新应用程序,我们必须编写一个新的应用程序代码并使用 OpenShift OC 构建命令对其进行构建。如前所述,我们有多种方式可以创建一个新映像。此处,我们将使用模板构建应用程序。当使用 oc new-app 命令运行时,此模板将构建新应用程序。

In order to create a new application in OpenShift, we have to write a new application code and build it using OpenShift OC build commands. As discussed, we have multiple ways of creating a new image. Here, we will be using a template to build the application. This template will build a new application when run with oc new-app command.

以下模板将创建 − 两个前端应用程序和一个数据库。除此之外,它还将创建两个新服务,并且这些应用程序将部署到 OpenShift 集群。在构建和部署应用程序时,我们首先需要在 OpenShift 中创建一个名称空间,并在此名称空间下部署应用程序。

The following template will create − Two front-end applications and one database. Along with that, it will create two new services and those applications will get deployed to OpenShift cluster. While building and deploying an application, initially we need to create a namespace in OpenShift and deploy the application under that namespace.

Create a new namespace

Create a new namespace

$ oc new-project openshift-test --display-name = "OpenShift 3 Sample" --
description = "This is an example project to demonstrate OpenShift v3"

Template

{
   "kind": "Template",
   "apiVersion": "v1",
   "metadata": {
      "name": "openshift-helloworld-sample",
      "creationTimestamp": null,
         "annotations": {
         "description": "This example shows how to create a simple openshift
         application in openshift origin v3",
         "iconClass": "icon-openshift",
         "tags": "instant-app,openshift,mysql"
      }
   }
},

Object Definitions

Secret definition in a template

Secret definition in a template

"objects": [
{
   "kind": "Secret",
   "apiVersion": "v1",
   "metadata": {"name": "dbsecret"},
   "stringData" : {
      "mysql-user" : "${MYSQL_USER}",
      "mysql-password" : "${MYSQL_PASSWORD}"
   }
},

Service definition in a template

Service definition in a template

{
   "kind": "Service",
   "apiVersion": "v1",
   "metadata": {
      "name": "frontend",
      "creationTimestamp": null
   },
   "spec": {
      "ports": [
         {
            "name": "web",
            "protocol": "TCP",
            "port": 5432,
            "targetPort": 8080,
            "nodePort": 0
         }
      ],
      "selector": {"name": "frontend"},
      "type": "ClusterIP",
      "sessionAffinity": "None"
   },
   "status": {
      "loadBalancer": {}
   }
},

Route definition in a template

Route definition in a template

{
   "kind": "Route",
   "apiVersion": "v1",
   "metadata": {
      "name": "route-edge",
      "creationTimestamp": null,
      "annotations": {
         "template.openshift.io/expose-uri": "http://{.spec.host}{.spec.path}"
      }
   },
   "spec": {
      "host": "www.example.com",
      "to": {
         "kind": "Service",
         "name": "frontend"
      },
      "tls": {
         "termination": "edge"
      }
   },
   "status": {}
},
{
   "kind": "ImageStream",
   "apiVersion": "v1",
   "metadata": {
      "name": "origin-openshift-sample",
      "creationTimestamp": null
   },
   "spec": {},
   "status": {
      "dockerImageRepository": ""
   }
},
{
   "kind": "ImageStream",
   "apiVersion": "v1",
   "metadata": {
      "name": "openshift-22-ubuntu7",
      "creationTimestamp": null
   },
   "spec": {
      "dockerImageRepository": "ubuntu/openshift-22-ubuntu7"
   },
   "status": {
      "dockerImageRepository": ""
   }
},

Build config definition in a template

Build config definition in a template

{
   "kind": "BuildConfig",
   "apiVersion": "v1",
   "metadata": {
      "name": "openshift-sample-build",
      "creationTimestamp": null,
      "labels": {name": "openshift-sample-build"}
   },
   "spec": {
      "triggers": [
         { "type": "GitHub",
            "github": {
            "secret": "secret101" }
         },
         {
            "type": "Generic",
            "generic": {
               "secret": "secret101",
               "allowEnv": true }
         },
         {
            "type": "ImageChange",
            "imageChange": {}
         },
         { "type": "ConfigChange”}
      ],
      "source": {
         "type": "Git",
         "git": {
            "uri": https://github.com/openshift/openshift-hello-world.git }
      },
      "strategy": {
         "type": "Docker",
         "dockerStrategy": {
            "from": {
               "kind": "ImageStreamTag",
               "name": "openshift-22-ubuntu7:latest”
            },
            "env": [
               {
                  "name": "EXAMPLE",
                  "value": "sample-app"
               }
            ]
         }
      },
      "output": {
         "to": {
            "kind": "ImageStreamTag",
            "name": "origin-openshift-sample:latest"
         }
      },
      "postCommit": {
         "args": ["bundle", "exec", "rake", "test"]
      },
      "status": {
         "lastVersion": 0
      }
   }
},

Deployment config in a template

Deployment config in a template

"status": {
   "lastVersion": 0
}
{
   "kind": "DeploymentConfig",
   "apiVersion": "v1",
   "metadata": {
      "name": "frontend",
      "creationTimestamp": null
   }
},
"spec": {
   "strategy": {
      "type": "Rolling",
      "rollingParams": {
         "updatePeriodSeconds": 1,
         "intervalSeconds": 1,
         "timeoutSeconds": 120,
         "pre": {
            "failurePolicy": "Abort",
            "execNewPod": {
               "command": [
                  "/bin/true"
               ],
               "env": [
                  {
                     "name": "CUSTOM_VAR1",
                     "value": "custom_value1"
                  }
               ]
            }
         }
      }
   }
}
"triggers": [
   {
      "type": "ImageChange",
      "imageChangeParams": {
         "automatic": true,
         "containerNames": [
            "openshift-helloworld"
         ],
         "from": {
            "kind": "ImageStreamTag",
            "name": "origin-openshift-sample:latest"
         }
      }
   },
   {
      "type": "ConfigChange"
   }
],
"replicas": 2,
"selector": {
   "name": "frontend"
},
"template": {
   "metadata": {
      "creationTimestamp": null,
      "labels": {
         "name": "frontend"
      }
   },
   "spec": {
      "containers": [
         {
            "name": "openshift-helloworld",
            "image": "origin-openshift-sample",
            "ports": [
               {
                  "containerPort": 8080,
                  "protocol": "TCP”
               }
            ],
            "env": [
               {
                  "name": "MYSQL_USER",
                  "valueFrom": {
                     "secretKeyRef" : {
                        "name" : "dbsecret",
                        "key" : "mysql-user"
                     }
                  }
               },
               {
                  "name": "MYSQL_PASSWORD",
                  "valueFrom": {
                     "secretKeyRef" : {
                        "name" : "dbsecret",
                        "key" : "mysql-password"
                     }
                  }
               },
               {
                  "name": "MYSQL_DATABASE",
                  "value": "${MYSQL_DATABASE}"
               }
            ],
            "resources": {},
            "terminationMessagePath": "/dev/termination-log",
            "imagePullPolicy": "IfNotPresent",
            "securityContext": {
               "capabilities": {},
               "privileged": false
            }
         }
      ],
      "restartPolicy": "Always",
      "dnsPolicy": "ClusterFirst"
   },
   "status": {}
},

Service definition in a template

Service definition in a template

{
   "kind": "Service",
   "apiVersion": "v1",
   "metadata": {
      "name": "database",
      "creationTimestamp": null
   },
   "spec": {
   "ports": [
      {
         "name": "db",
         "protocol": "TCP",
         "port": 5434,
         "targetPort": 3306,
         "nodePort": 0
      }
   ],
   "selector": {
      "name": "database
   },
   "type": "ClusterIP",
   "sessionAffinity": "None" },
   "status": {
      "loadBalancer": {}
   }
},

Deployment config definition in a template

Deployment config definition in a template

{
   "kind": "DeploymentConfig",
   "apiVersion": "v1",
   "metadata": {
      "name": "database",
      "creationTimestamp": null
   },
   "spec": {
      "strategy": {
         "type": "Recreate",
         "resources": {}
      },
      "triggers": [
         {
            "type": "ConfigChange"
         }
      ],
      "replicas": 1,
      "selector": {"name": "database"},
      "template": {
         "metadata": {
            "creationTimestamp": null,
            "labels": {"name": "database"}
         },
         "template": {
            "metadata": {
               "creationTimestamp": null,
               "labels": {
                  "name": "database"
               }
            },
            "spec": {
               "containers": [
                  {
                     "name": "openshift-helloworld-database",
                     "image": "ubuntu/mysql-57-ubuntu7:latest",
                     "ports": [
                        {
                           "containerPort": 3306,
                           "protocol": "TCP"
                        }
                     ],
                     "env": [
                        {
                           "name": "MYSQL_USER",
                           "valueFrom": {
                              "secretKeyRef" : {
                                 "name" : "dbsecret",
                                 "key" : "mysql-user"
                              }
                           }
                        },
                        {
                           "name": "MYSQL_PASSWORD",
                           "valueFrom": {
                              "secretKeyRef" : {
                                 "name" : "dbsecret",
                                 "key" : "mysql-password"
                              }
                           }
                        },
                        {
                           "name": "MYSQL_DATABASE",
                           "value": "${MYSQL_DATABASE}"
                        }
                     ],
                     "resources": {},
                     "volumeMounts": [
                        {
                           "name": "openshift-helloworld-data",
                           "mountPath": "/var/lib/mysql/data"
                        }
                     ],
                     "terminationMessagePath": "/dev/termination-log",
                     "imagePullPolicy": "Always",
                     "securityContext": {
                        "capabilities": {},
                        "privileged": false
                     }
                  }
               ],
               "volumes": [
                  {
                     "name": "openshift-helloworld-data",
                     "emptyDir": {"medium": ""}
                  }
               ],
               "restartPolicy": "Always",
               "dnsPolicy": "ClusterFirst”
            }
         }
      },
      "status": {}
   },
   "parameters": [
      {
         "name": "MYSQL_USER",
         "description": "database username",
         "generate": "expression",
         "from": "user[A-Z0-9]{3}",
         "required": true
      },
      {
         "name": "MYSQL_PASSWORD",
         "description": "database password",
         "generate": "expression",
         "from": "[a-zA-Z0-9]{8}",
         "required": true
      },
      {
         "name": "MYSQL_DATABASE",
         "description": "database name",
         "value": "root",
         "required": true
      }
   ],
   "labels": {
      "template": "application-template-dockerbuild"
   }
}

上面的模板文件需要一次编译。我们需要先将所有内容复制到单个文件中,完成后将其命名为 yaml 文件。

The above template file needs to be compiled at once. We need to first copy all the content into a single file and name it as a yaml file once done.

我们需要运行以下命令来创建应用程序。

We need to run the following command to create the application.

$ oc new-app application-template-stibuild.json
--> Deploying template openshift-helloworld-sample for "application-template-stibuild.json"

   openshift-helloworld-sample
   ---------
   This example shows how to create a simple ruby application in openshift origin v3
   * With parameters:
      * MYSQL_USER = userPJJ # generated
      * MYSQL_PASSWORD = cJHNK3se # generated
      * MYSQL_DATABASE = root

--> Creating resources with label app = ruby-helloworld-sample ...
   service "frontend" created
   route "route-edge" created
   imagestream "origin-ruby-sample" created
   imagestream "ruby-22-centos7" created
   buildconfig "ruby-sample-build" created
   deploymentconfig "frontend" created
   service "database" created
   deploymentconfig "database" created

--> Success
   Build scheduled, use 'oc logs -f bc/ruby-sample-build' to track its progress.
   Run 'oc status' to view your app.

如果我们希望监控构建,则可以使用以下命令

If we wish to monitor the build, it can be done using −

$ oc get builds

NAME                        TYPE      FROM          STATUS     STARTED         DURATION
openshift-sample-build-1    Source   Git@bd94cbb    Running    7 seconds ago   7s

我们可以在 OpenShift 上使用以下命令检查已部署的应用程序

We can check the deployed applications on OpenShift using −

$ oc get pods
NAME                            READY   STATUS      RESTARTS   AGE
database-1-le4wx                1/1     Running     0          1m
frontend-1-e572n                1/1     Running     0          27s
frontend-1-votq4                1/1     Running     0          31s
opeshift-sample-build-1-build   0/1     Completed   0          1m

我们可以使用以下命令检查应用程序服务是否按照服务定义创建的

We can check if the application services are created as per the service definition using

$ oc get services
NAME        CLUSTER-IP      EXTERNAL-IP     PORT(S)      SELECTOR          AGE
database    172.30.80.39    <none>         5434/TCP     name=database      1m
frontend    172.30.17.4     <none>         5432/TCP     name=frontend      1m