OpenShift - เริ่มต้นใช้งาน

OpenShift ประกอบด้วยค่ามัธยฐานสองประเภทในการสร้างและปรับใช้แอปพลิเคชันโดย GUI หรือ CLI ในบทนี้เราจะใช้ CLI เพื่อสร้างแอปพลิเคชันใหม่ เราจะใช้ไคลเอนต์ OC เพื่อสื่อสารกับสภาพแวดล้อม OpenShift

การสร้างแอปพลิเคชันใหม่

ใน OpenShift มีสามวิธีในการสร้างแอปพลิเคชันใหม่

  • จากซอร์สโค้ด
  • จากรูปภาพ
  • จากเทมเพลต

จากซอร์สโค้ด

เมื่อเราพยายามสร้างแอปพลิเคชันจากซอร์สโค้ด OpenShift จะค้นหาไฟล์ Docker ที่ควรอยู่ใน repo ซึ่งกำหนดขั้นตอนการสร้างแอปพลิเคชัน เราจะใช้ oc new-app เพื่อสร้างแอปพลิเคชัน

สิ่งแรกที่ควรคำนึงถึงในขณะที่ใช้ repo คือควรชี้ไปที่จุดเริ่มต้นใน repo จากที่ OpenShift จะดึงรหัสและสร้างขึ้น

หาก repo ถูกโคลนบนเครื่อง Docker ที่ติดตั้งไคลเอนต์ OC และผู้ใช้อยู่ในไดเร็กทอรีเดียวกันก็สามารถสร้างได้โดยใช้คำสั่งต่อไปนี้

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

ต่อไปนี้เป็นตัวอย่างของการพยายามสร้างจาก repo ระยะไกลสำหรับสาขาเฉพาะ

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

ที่นี่ test1 เป็นสาขาที่เราพยายามสร้างแอปพลิเคชันใหม่ใน OpenShift

เมื่อระบุไฟล์ Docker ในที่เก็บเราจำเป็นต้องกำหนดกลยุทธ์การสร้างดังที่แสดงด้านล่าง

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

จากรูปภาพ

ในขณะที่สร้างแอปพลิเคชันโดยใช้รูปภาพรูปภาพจะปรากฏในเซิร์ฟเวอร์ Docker ในเครื่องในที่เก็บ Docker ที่โฮสต์ภายในหรือบนฮับ Docker สิ่งเดียวที่ผู้ใช้ต้องแน่ใจคือเขาสามารถเข้าถึงเพื่อดึงภาพจากฮับได้โดยไม่มีปัญหาใด ๆ

OpenShift มีความสามารถในการกำหนดแหล่งที่มาที่ใช้ไม่ว่าจะเป็นอิมเมจ Docker หรือสตรีมต้นทาง อย่างไรก็ตามหากผู้ใช้ต้องการเขาสามารถระบุได้อย่างชัดเจนว่าเป็นสตรีมรูปภาพหรืออิมเมจ Docker

$ oc new-app - - docker-image tomcat

การใช้สตรีมรูปภาพ -

$ oc new-app tomcat:v1

จากเทมเพลต

สามารถใช้เทมเพลตสำหรับการสร้างแอปพลิเคชันใหม่ อาจเป็นเทมเพลตที่มีอยู่แล้วหรือสร้างเทมเพลตใหม่

ไฟล์ yaml ต่อไปนี้เป็นเทมเพลตที่สามารถใช้สำหรับการปรับใช้

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>

พัฒนาและปรับใช้โปรแกรมประยุกต์บนเว็บ

การพัฒนาแอปพลิเคชันใหม่ใน OpenShift

ในการสร้างแอปพลิเคชันใหม่ใน OpenShift เราต้องเขียนโค้ดแอปพลิเคชันใหม่และสร้างโดยใช้คำสั่งสร้าง OpenShift OC ตามที่กล่าวไว้เรามีหลายวิธีในการสร้างภาพใหม่ ที่นี่เราจะใช้เทมเพลตเพื่อสร้างแอปพลิเคชัน เทมเพลตนี้จะสร้างแอปพลิเคชันใหม่เมื่อรันด้วยคำสั่ง oc new-app

เทมเพลตต่อไปนี้จะสร้างขึ้น - แอปพลิเคชันส่วนหน้าสองรายการและฐานข้อมูลเดียว นอกจากนั้นจะสร้างบริการใหม่สองบริการและแอปพลิเคชันเหล่านั้นจะถูกปรับใช้กับคลัสเตอร์ OpenShift ในขณะที่สร้างและปรับใช้แอปพลิเคชันในขั้นต้นเราต้องสร้างเนมสเปซใน OpenShift และปรับใช้แอปพลิเคชันภายใต้เนมสเปซนั้น

Create a new namespace

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

เทมเพลต

{
   "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"
      }
   }
},

คำจำกัดความของวัตถุ

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

{
   "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

{
   "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

{
   "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

"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

{
   "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

{
   "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 เมื่อเสร็จแล้ว

เราต้องเรียกใช้คำสั่งต่อไปนี้เพื่อสร้างแอปพลิเคชัน

$ 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.

หากเราต้องการตรวจสอบบิลด์สามารถทำได้โดยใช้ -

$ oc get builds

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

เราสามารถตรวจสอบแอปพลิเคชันที่ปรับใช้บน OpenShift โดยใช้ -

$ 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

เราสามารถตรวจสอบได้ว่ามีการสร้างบริการแอปพลิเคชันตามข้อกำหนดของบริการโดยใช้หรือไม่

$ 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