中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

快速部署OpenShift應用

發布時間:2020-08-14 15:04:46 來源:網絡 閱讀:5579 作者:川川Jason 欄目:云計算

本文介紹了使用Service Catalog和OC命令部署OpenShift應用、部署基本概念和流程、擴展存儲、清理OpenShift對象等。以Angular 6集成Spring Boot 2,Spring Security,JWT和CORS中的Spring Boot和Angular項目為例,詳細講解了S2I和Pipeline兩種部署方式。

OKD版本3.11,Spring Boot項目源碼heroes-api,Angular項目源碼heroes-web。

初識OpenShift部署

Service Catalog

快速部署OpenShift應用
OpenShift初始安裝中含有一些樣例APP供大家學習使用。其中有Apache HTTP Server和Apache HTTP Server(httpd),這兩者有什么區別?分別點擊進入可以發現:
快速部署OpenShift應用
Apache HTTP Server使用template(template名字為httpd-example)部署方式。
快速部署OpenShift應用
Apache HTTP Server(httpd)使用builder image(image stream名字為httpd)部署方式。
Service Catalog樣例使用了template和builder image(image+source)兩種部署方式。進入Application Console中的openshift項目可查看template和image。
查看template,點擊Resources -> Other Resources -> Template:
快速部署OpenShift應用
查看Image Stream,點擊Builds -> Images:
快速部署OpenShift應用

其他部署方式
在Service Catalog中,除從Catalog直接選擇Item外,還提供了其他三種方式:
快速部署OpenShift應用
Deploy Image可以直接從image或image stream部署應用:
快速部署OpenShift應用
Import YAML / JSON 用來從YAML或JSON創建資源,比如image stream、template:
快速部署OpenShift應用
Select from Project 從指定的Project中選擇template來部署應用:
快速部署OpenShift應用

部署Apache HTTP Server

Apache HTTP Server的兩種部署方式本質上是相同的,Build策略均為S2I(Source-to-Image),使用S2I構建的Docker鏡像來部署應用。Source均使用Apache HTTP Server (httpd) S2I Sample Application,Docker基礎鏡像(builder image)均使用Apache HTTP Server Container Image。httpd-example template定義了整體部署流程并實現了參數化。
以下是httpd-example template中BuildConfig部分的定義:

- apiVersion: v1
  kind: BuildConfig
  metadata:
    annotations:
      description: Defines how to build the application
      template.alpha.openshift.io/wait-for-ready: 'true'
    name: '${NAME}'
  spec:
    output:
      to:
        kind: ImageStreamTag
        name: '${NAME}:latest'
    source:
      contextDir: '${CONTEXT_DIR}'
      git:
        ref: '${SOURCE_REPOSITORY_REF}'
        uri: '${SOURCE_REPOSITORY_URL}'
      type: Git
    strategy:
      sourceStrategy:
        from:
          kind: ImageStreamTag
          name: 'httpd:2.4'
          namespace: '${NAMESPACE}'
      type: Source
    triggers:
      - type: ImageChange
      - type: ConfigChange
      - github:
          secret: '${GITHUB_WEBHOOK_SECRET}'
        type: GitHub
      - generic:
          secret: '${GENERIC_WEBHOOK_SECRET}'
        type: Generic

參數定義及默認值:

parameters:
  - description: The name assigned to all of the frontend objects defined in this template.
    displayName: Name
    name: NAME
    required: true
    value: httpd-example
  - description: The OpenShift Namespace where the ImageStream resides.
    displayName: Namespace
    name: NAMESPACE
    required: true
    value: openshift
  - description: Maximum amount of memory the container can use.
    displayName: Memory Limit
    name: MEMORY_LIMIT
    required: true
    value: 512Mi
  - description: The URL of the repository with your application source code.
    displayName: Git Repository URL
    name: SOURCE_REPOSITORY_URL
    required: true
    value: 'https://github.com/openshift/httpd-ex.git'
  - description: >-
      Set this to a branch name, tag or other ref of your repository if you are
      not using the default branch.
    displayName: Git Reference
    name: SOURCE_REPOSITORY_REF
  - description: >-
      Set this to the relative path to your project if it is not in the root of
      your repository.
    displayName: Context Directory
    name: CONTEXT_DIR
  - description: >-
      The exposed hostname that will route to the httpd service, if left blank a
      value will be defaulted.
    displayName: Application Hostname
    name: APPLICATION_DOMAIN
...

我們先使用builder image方式部署Apache,來了解一下部署的整體流程:
快速部署OpenShift應用
點擊"advanced options",可以設置git branch、context、secret,自定義Route、Build Configuration、Deployment Configuration、Resource Limits等。此處填完基本內容后直接點擊Create,創建App,然后從成功頁面進入Project Overview:
快速部署OpenShift應用
部署過程中自動創建Service、Route、Build、Deployment、Image。進入Application Console的Applications和Builds可以查看詳細信息,其中會創建3個pod:httpd-1-build、http-1-deploy、httpd-1-xxxxx,部署完畢后http-1-deploy會自動刪除。
部署成功后,測試訪問Apache Server(Route定義的Hostname),頁面如下:
快速部署OpenShift應用
下面解釋一下涉及到的基本概念。

基本概念

Service(Kubernetes Service)
內部load balancer,用在OpenShift內部網絡中,可使用Service ClusterIP或Hostname訪問。

apiVersion: v1
kind: Service
metadata:
  annotations:
    openshift.io/generated-by: OpenShiftWebConsole
  creationTimestamp: '2019-03-26T02:12:50Z'
  labels:
    app: httpd
  name: httpd
  namespace: my-project
  resourceVersion: '3004428'
  selfLink: /api/v1/namespaces/my-project/services/httpd
  uid: a81c759f-4f6c-11e9-9a7d-02fa2ffc40e6
spec:
  clusterIP: 172.30.225.159
  ports:
    - name: 8080-tcp
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    deploymentconfig: httpd
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

其中,selector定義了查找container(pod)進行負載均衡的標簽。
Route
定義一個hostname來公開Service,以便外部客戶可以訪問Service,默認hostname為:[app-name]-[project-name].[openshift_master_default_subdomain]。
Build
構建App Image,使用S2I時即從builder image和Source Code來構建App Image。默認builder image和build配置變化時會重新build。

查看Builds -> httpd -> #1 的YAML文本,可以了解Build流程為FetchInputs -> Assemble -> CommitContainer -> PushImage:

...
status:
  completionTimestamp: '2019-03-26T02:13:30Z'
  config:
    kind: BuildConfig
    name: httpd
    namespace: my-project
  duration: 40000000000
  output:
    to:
      imageDigest: 'sha256:5c1f20f20baaa796f4518d11ded13c6fac33e7a377774cfec77aa1e6e6a7cbb2'
  outputDockerImageReference: 'docker-registry.default.svc:5000/my-project/httpd:latest'
  phase: Complete
  stages:
    - durationMilliseconds: 3434
      name: FetchInputs
      startTime: '2019-03-26T02:12:56Z'
      steps:
        - durationMilliseconds: 3434
          name: FetchGitSource
          startTime: '2019-03-26T02:12:56Z'
    - durationMilliseconds: 2127
      name: CommitContainer
      startTime: '2019-03-26T02:13:11Z'
      steps:
        - durationMilliseconds: 2127
          name: CommitContainer
          startTime: '2019-03-26T02:13:11Z'
    - durationMilliseconds: 3426
      name: Assemble
      startTime: '2019-03-26T02:13:10Z'
      steps:
        - durationMilliseconds: 3426
          name: AssembleBuildScripts
          startTime: '2019-03-26T02:13:10Z'
    - durationMilliseconds: 16143
      name: PushImage
      startTime: '2019-03-26T02:13:14Z'
      steps:
        - durationMilliseconds: 16143
          name: PushImage
          startTime: '2019-03-26T02:13:14Z'
  startTimestamp: '2019-03-26T02:12:50Z'

Build Strategy
OpenShift支持Source-to-Image、Docker、Pipeline、Custom四種Build Strategy。

strategy:
  sourceStrategy:
    from:
      kind: "ImageStreamTag"
      name: "builder-image:latest"
strategy:
  dockerStrategy:
    from:
      kind: "ImageStreamTag"
      name: "debian:latest"
spec:
  source:
    git:
      uri: "https://github.com/openshift/ruby-hello-world"
  strategy:
    jenkinsPipelineStrategy:
      jenkinsfilePath: some/repo/dir/filename
strategy:
  customStrategy:
    from:
      kind: "DockerImage"
      name: "openshift/sti-image-builder"

Deployment
部署App Image,Deployment包含三種對象:DeploymentConfig、ReplicationController、Pod。DeploymentConfig包含部署策略、image配置、環境變量等,ReplicationController包含復制相關信息。App Image和deployment配置變化時會自動重新Deploy。

進入Deployments -> httpd -> #1,編輯Replicas或調節pods數可以增刪pod:
快速部署OpenShift應用
Deployment Strategy
修改或升級App,即重新部署應用時的部署方式。部署配置(DeploymentConfig)支持三種策略:Rolling、Recreate、Custom。通過修改Route可以實現藍/綠部署、A/B部署。

  • Rolling 默認策略,當新版本Pod狀態變為Ready后才scale down老版本Pod,可能同時存在新老版本的Pod
  • Recreate 先終止所有Pod(Scale down the previous deployment to zero)再部署新Pod
  • Custom 自定義部署行為

ImageStream
OpenShift管理容器鏡像的方式,其中定義了dockerImageReference,ImageStream tag定義了同docker image各版本的映射關系。Build成功后會自動創建ImageStream。

apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
  annotations:
    openshift.io/generated-by: OpenShiftWebConsole
  creationTimestamp: '2019-03-26T02:12:50Z'
  generation: 1
  labels:
    app: httpd
  name: httpd
  namespace: my-project
  resourceVersion: '3004571'
  selfLink: /apis/image.openshift.io/v1/namespaces/my-project/imagestreams/httpd
  uid: a81b14bf-4f6c-11e9-9a7d-02fa2ffc40e6
spec:
  lookupPolicy:
    local: false
status:
  dockerImageRepository: 'docker-registry.default.svc:5000/my-project/httpd'
  tags:
    - items:
        - created: '2019-03-26T02:13:30Z'
          dockerImageReference: >-
            docker-registry.default.svc:5000/my-project/httpd@sha256:5c1f20f20baaa796f4518d11ded13c6fac33e7a377774cfec77aa1e6e6a7cbb2
          generation: 1
          image: >-
            sha256:5c1f20f20baaa796f4518d11ded13c6fac33e7a377774cfec77aa1e6e6a7cbb2
      tag: latest

Template
定義整體部署流程并實現參數化,包含Service、Route、ImageStream、BuildConfig、DeploymentConfig、parameters等部分。

了解了以上基本概念就很容易理解httpd-example template了,您可以自己部署測試,此處不再贅述。

OC Tool

使用oc new-app部署應用
繼續之前,先將以前創建的測試project刪除或新建一個project。

$ oc delete project my-project
$ oc new-project my-project

在Service Catalog一節我們提到了部署應用的三種方式:template、builder image(image+source)、image,對應的命令如下:

$ oc new-app httpd-example -p APPLICATION_DOMAIN=httpd-example.apps.itrunner.org
$ oc new-app openshift/httpd:2.4~https://github.com/openshift/httpd-ex.git --name=httpd-ex
$ oc new-app my-project/httpd-ex --name=httpd

說明:

  1. image+source的語法為[image]~[source]
  2. 第三種方式使用的image為第二種方式中生成的
  3. 后面兩種方式不會自動創建Route,需要手工創建:
$ oc expose service httpd-ex --name httpd-ex --hostname=httpd-ex.apps.itrunner.org
$ oc expose service httpd --name httpd --hostname=httpd.apps.itrunner.org

從JSON/YAML創建資源:

$ oc create -f <filename> -n <project>

使用oc命令還可以直接從source code創建應用,可以使用本地或遠程source code:

$ oc new-app /path/to/source/code
$ oc new-app https://github.com/sclorg/cakephp-ex

可以指定子目錄:

$ oc new-app https://github.com/sclorg/s2i-ruby-container.git --context-dir=2.0/test/puma-test-app

可以指定branch:

$ oc new-app https://github.com/openshift/ruby-hello-world.git#beta4

OpenShift自動檢測代碼根目錄或指定目錄,如果存在Dockerfile則使用Docker build策略,如果存在Jenkinsfile則使用Pipeline build策略,否則使用Source build策略(S2I)。

下面的例子使用了Source build策略:

$ oc new-app https://github.com/sclorg/cakephp-ex

使用Source build策略時,new-app通過檢測根目錄或指定目錄的文件來確定language builder:

Language Files
jee pom.xml
nodejs app.json, package .json
perl cpanfile, index.pl
php composer.json, index.php
python requirements.txt, setup.py
ruby Gemfile, Rakefile, config.ru
scala build.sbt
golang Godeps, main.go

然后根據語言,從OpenShift Server或Docker Hub Registry中查找與語言匹配的image。

也可以指定策略,如下:

$ oc new-app /home/user/code/myapp --strategy=docker

查看template和image stream
查看所有template和image stream:

$ oc new-app --list

單獨查看template或image stream:

$ oc get templates -n openshift
$ oc get imagestreams -n openshift

查看httpd-example template詳細信息:

$ oc describe template httpd-example -n openshift

查看httpd image stream詳細信息:

$ oc describe imagestream httpd -n openshift

查看httpd-example template的YAML定義:

$ oc new-app --search --template=httpd-example --output=yaml

從所有template、image stream、docker image中查找"httpd":

$  oc new-app --search httpd

再談Route

前面的例子Route使用的協議均為http,如何啟用https呢?
使用Web Console時,編輯route啟用Secure route即可:
快速部署OpenShift應用
TLS Termination有三種類型:edge、passthrough、reencrypt

  • edge 訪問route使用https協議,route到內部網絡為非加密的,如未配置證書則使用默認證書。
  • reencrypt 全部訪問路徑均是加密的
  • passthrough 加密通信直接發送到目標,route不需提供TLS Termination。

使用oc命令創建route:

$ oc create route edge httpd-ex --service httpd-ex --hostname httpd-ex.apps.itrunner.org --path / --insecure-policy Redirect -n my-project

S2I

Source-to-Image (S2I)是一個框架,可以容易地將應用程序源代碼作為輸入生成一個新的docker image。

使用S2I構建image,在裝配過程中可以執行大量復雜的操作,所有操作僅創建一個新的layer,加速了處理過程。S2I使得軟件開發工程師不必關心docker image的制作,僅負責編寫assemble、run等腳本,也可以防止開發工程師在image構建過程中執行任意yum安裝等不適宜的操作。S2I簡化了docker image的制作。

S2I需要以下三個基本要素:

  • builder image S2I以此image為基礎來構建新的image
  • Sources
  • S2I Scripts

在構建過程中,S2I先獲取sources和scripts,將其打包為tar文件后放入builder image中。在執行assemble script前,S2I解壓tar文件到io.openshift.s2i.destination指定的目錄,默認目錄為/tmp(分別解壓到/tmp/src、/tmp/scripts目錄)。
快速部署OpenShift應用

S2I Scripts

S2I Scripts可以位于以下位置,優先級從高到低:

  1. 在BuildConfig中指定位置
strategy:
  sourceStrategy:
    from:
      kind: "ImageStreamTag"
      name: "builder-image:latest"
    scripts: "http://somehost.com/scripts_directory"
  1. 應用程序源碼的.s2i/bin目錄
  2. 在builder image的Dockerfile中定義位置(在樣例Apache HTTP Server中使用了這種方式 )
LABEL io.openshift.s2i.scripts-url="image:///usr/libexec/s2i"

io.openshift.s2i.scripts-url和BuildConfig定義位置均可采用以下形式:

  • image:///path_to_scripts_dir - image的絕對路徑
  • file:///path_to_scripts_dir - host絕對或相對路徑
  • http(s)://path_to_scripts_dir - URL

S2I Scripts:

Script Description
assemble (required) 獲取源碼、編譯、打包。在增量編譯時,如果定義了save-artifacts,先恢復artifact
run (required) 運行應用
save-artifacts (optional) 收集依賴以便加速后續編譯,比如.m2
usage (optional) 顯示image使用幫助信息
test/run (optional) 檢查image能否正常工作

Example assemble script

#!/bin/bash

# restore build artifacts
if [ "$(ls /tmp/artifacts/ 2>/dev/null)" ]; then
    mv /tmp/artifacts/* $HOME/.
fi

# move the application source
mv /tmp/s2i/src $HOME/src

# build application artifacts
pushd ${HOME}
make all

# install the artifacts
make install
popd

Example run script

#!/bin/bash

# run the application
/opt/application/run.sh

Example save-artifacts script

#!/bin/bash

# Besides the tar command, all other output to standard out must 
# be surpressed.  Otherwise, the tar stream will be corrupted.
pushd ${HOME} >/dev/null
if [ -d deps ]; then
    # all deps contents to tar stream
    tar cf - deps
fi
popd >/dev/null

注意:save-artifacts只能有tar stream輸出,不能含有其它任何輸出。
Example usage script

#!/bin/bash

# inform the user how to use the image
cat <<EOF
This is a S2I sample builder image, to use it, install
https://github.com/openshift/source-to-image
EOF

S2I Tool

僅為學習S2I的基本知識和S2I Tool的使用,部署OpenShift應用時是不必安裝的。

安裝S2I Tool
下載S2I后解壓安裝:

# tar -xvf release.tar.gz .
# cp /path/to/s2i /usr/local/bin

S2I命令

create       創建生成builder image的基礎目錄結構
build         構建新的image
rebuild      重建image
usage       顯示image usage信息
version     顯示s2i version
completion  Generate completion for the s2i command (bash or zsh)

示例

  1. 使用s2i create創建目錄結構

s2i create語法:

s2i create <imageName> <destination> [flags]
$ s2i create ruby-centos7 ruby-centos7

執行以上命令生成的目錄結構如下:

ruby-centos7
├── Dockerfile
├── Makefile
├── README.md
├── s2i
│?? └── bin
│??     ├── assemble
│??     ├── run
│??     ├── save-artifacts
│??     └── usage
└── test
    ├── run
    └── test-app
        └── index.html
  1. 構建builder image
$ cd ruby-centos7
$ make build
  1. 構建App image

s2i build語法:

s2i build <source> <image> [<tag>] [flags]
# cd ruby-centos7
# s2i build test/test-app/ ruby-centos7 ruby-app
  1. 運行image
# docker run --rm -d -p 8080:8080 --name ruby-app ruby-app

增量構建與save-artifacts

Maven、Angular等項目編譯時需要下載其他依賴,為提高編譯速度,避免重復下載,S2I支持增量build。增量build依賴以前構建的image,image名字必須相同,且image中必須含有save-artifacts script。

增量build流程如下:

  1. S2I從以前構建的app image創建一個新的docker container
  2. S2I運行container中的save-artifacts將依賴打包為tar文件輸出到stdout
  3. S2I下載source與artifacts一起打包作為新image的輸入
  4. S2I啟動新container、運行assemble ...

artifacts默認解壓到/tmp/artifacts目錄中。

啟用增量構建

  • 使用s2i命令時增加參數--incremental=true:
# s2i build test/test-app/ ruby-centos7 ruby-app --incremental=true
  • 在OpenShift Web Console中修改BuildConfig,增加incremental: true,然后點擊Start Build。
strategy:
  type: "Source"
  sourceStrategy:
    from:
      kind: "ImageStreamTag"
      name: "incremental-image:latest" 
    incremental: true

部署Spring Boot App

Builder Image

Dockerfile

# heroes-api-centos7
FROM centos:latest

RUN yum -y update && yum clean all

# Set the labels that are used for OpenShift to describe the builder image.
LABEL maintainer="Sun Jingchuan <jason@163.com>" \
      io.k8s.description="Heroes API" \
      io.k8s.display-name="Heroes API" \
      io.openshift.expose-services="8080:http" \
      io.openshift.tags="spring-boot,heroes-api" \
      # this label tells s2i where to find its mandatory scripts(run, assemble, save-artifacts)
      # io.openshift.s2i.scripts-url="image:///usr/libexec/s2i" \
      io.openshift.s2i.scripts-url="image:///tmp/scripts" \
      io.openshift.s2i.destination="/tmp"

ENV JAVA_HOME=/usr/lib/jdk1.8.0_202 \
    MAVEN_HOME=/usr/lib/apache-maven-3.6.0 \
    APP_ROOT=/opt/heroes
ENV PATH=${JAVA_HOME}/bin:${MAVEN_HOME}/bin:${APP_ROOT}/bin:${PATH} HOME=${APP_ROOT}

# Include jdk and maven in lib
COPY lib /usr/lib
COPY bin ${APP_ROOT}/bin
# Copy the S2I scripts to /usr/libexec/s2i
# COPY .s2i/bin /usr/libexec/s2i

RUN chmod -R u+x ${APP_ROOT}/bin && \
    chgrp -R 0 ${APP_ROOT} && \
    chmod -R g=u ${APP_ROOT} /etc/passwd

USER 10001
WORKDIR ${APP_ROOT}

ENTRYPOINT [ "uid_entrypoint" ]

EXPOSE 8080

# Inform the user how to run this image.
# CMD ["/usr/libexec/s2i/usage"]

說明:

  1. lib目錄中存放了JDK和Maven
  2. 使用源碼中的S2I Scripts,builder image中不提供,但需定義io.openshift.s2i.scripts-url
  3. 默認,為了安全,OpenShift中只能使用User ID,不能使用用戶名,不能使用docker默認用戶root,因此要授予目錄適當權限。
  4. 源碼bin目錄中存放了用戶創建腳本uid_entrypoint,內容如下:
#!/bin/bash

if ! whoami &> /dev/null; then
  if [ -w /etc/passwd ]; then
    echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:${HOME}:/sbin/nologin" >> /etc/passwd
  fi
fi

exec "$@"

編譯builder image并上傳到Registry

# docker build -t heroes-api-centos7:v1.0.0 .
# docker tag heroes-api-centos7:v1.0.0 registry.itrunner.org/heroes-api-centos7:v1.0.0
# docker push registry.itrunner.org/heroes-api-centos7:v1.0.0

import image

$ oc import-image heroes-api-centos7:v1.0.0 -n heroes --confirm --insecure --from='registry.itrunner.org/heroes-api-centos7:v1.0.0'

導入命令中指定了參數-n heroes,image會導入heroes項目中。成功導入后可在項目的Builds -> Images中查看image,但在Service Catalog中仍不可見,需要修改Image Stream定義,增加annotations:

apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
  annotations:
    openshift.io/image.dockerRepositoryCheck: '2019-03-27T08:40:27Z'
  creationTimestamp: '2019-03-27T08:39:50Z'
  generation: 1
  name: heroes-api-centos7
  namespace: heroes
  resourceVersion: '3337267'
  selfLink: /apis/image.openshift.io/v1/namespaces/heroes/imagestreams/heroes-api-centos7
  uid: e280929e-506b-11e9-a2ec-0288bf58ecc2
spec:
  lookupPolicy:
    local: false
  tags:
    - annotations:
        description: build heroes-api on CentOS 7
        iconClass: icon-spring
        openshift.io/display-name: Heroes API
        openshift.io/provider-display-name: itrunner
        sampleRepo: 'https://github.com/sunjc/heroes-api.git'
        supports: itrunner
        tags: 'builder,java'
        version: '1.0.0'
      from:
        kind: DockerImage
        name: 'registry.itrunner.org/heroes-api-centos7:v1.0.0'
...

為了在Service Catalog中顯示,tags中必須含有“builder”。只有導入openshift項目的image才是全局可見的,否則僅在本項目Catalog可見。如未顯示請刷新頁面。

S2I Scripts

  1. assemble
#!/bin/bash -e

# restore build artifacts
if [ -d /tmp/artifacts/.m2 ]; then
    echo "restore build artifacts"
    mv /tmp/artifacts/.m2 $HOME/.
fi

# move the application source
mv /tmp/src $HOME/src

# build the application artifacts
pushd $HOME/src
mvn clean package -Pdev -Dmaven.test.skip=true
popd

# move the artifacts
mv $HOME/src/target/heroes-api-1.0.0.jar $HOME/
rm -rf $HOME/src
  1. run
#!/bin/bash

java -jar $HOME/heroes-api-1.0.0.jar
  1. save-artifacts
#!/bin/bash

# Besides the tar command, all other output to standard out must be surpressed.  Otherwise, the tar stream will be corrupted.
pushd ${HOME} >/dev/null
if [ -d .m2 ]; then
    # all .m2 contents to tar stream
    tar cf - .m2
fi
popd >/dev/null
  1. usage
#!/bin/bash

# inform the user how to use the image
cat <<EOF
This is a S2I sample builder image, to use it, install
https://github.com/openshift/source-to-image
EOF

部署

$ oc new-app heroes/heroes-api-centos7:v1.0.0~https://github.com/sunjc/heroes-api.git --name=heroes-api
$ oc expose service heroes-api --name heroes-api --hostname heroes.apps.itrunner.org --path /api -n heroes
或
$ oc create route edge heroes-api --service heroes-api --hostname heroes.apps.itrunner.org --path /api --insecure-policy Redirect -n heroes

說明:

  1. 如果使用私有git倉庫,new-app需要增加參數--source-secret=yoursecret。Secret可在Resources -> Secrets中配置。
  2. route的path配置為/api,不是根目錄,這樣可以防止外部用戶訪問api-docs、swagger-ui
  3. 為了內部用戶可以訪問api-docs、swagger-ui,給service增加externalIPs參數,指定一個或多個OpenShift Node地址,如下:
spec:
  clusterIP: 172.30.80.170
  externalIPs:
    - 10.188.12.116
  ports:
    - name: 8080-tcp
      port: 8080
      protocol: TCP
      targetPort: 8080

部署Angular App

Builder Image

Dockerfile

# heroes-web-centos7
FROM centos/httpd:latest

RUN yum -y update && \
    curl -sL https://rpm.nodesource.com/setup_10.x | bash - && yum -y install nodejs && \
    yum clean all && npm install -g @angular/cli@latest

# Set the labels that are used for OpenShift to describe the builder image.
LABEL maintainer="Sun Jingchuan <jason@163.com>" \
      io.k8s.description="Heroes Web" \
      io.k8s.display-name="Heroes Web" \
      io.openshift.expose-services="8080:http" \
      io.openshift.tags="angular,heroes-web" \
      # this label tells s2i where to find its mandatory scripts(run, assemble, save-artifacts)
      # io.openshift.s2i.scripts-url="image:///usr/libexec/s2i" \
      io.openshift.s2i.scripts-url="image:///tmp/scripts" \
      io.openshift.s2i.destination="/tmp"

ENV APP_ROOT=/opt/heroes
ENV PATH=${APP_ROOT}/bin:${PATH} HOME=${APP_ROOT} HTTPD_MAIN_CONF_PATH=/etc/httpd/conf

COPY bin ${APP_ROOT}/bin
# Copy the S2I scripts to /usr/libexec/s2i
# COPY .s2i/bin /usr/libexec/s2i

RUN chmod -R u+x ${APP_ROOT}/bin && \
    chgrp -R 0 ${APP_ROOT} && \
    chmod -R g=u ${APP_ROOT} /etc/passwd /var/www/html /run/httpd && \
    chown -R root:root /run/httpd /etc/httpd && \
    sed -i -e "s/^User apache/User default/" ${HTTPD_MAIN_CONF_PATH}/httpd.conf && \
    sed -i -e "s/^Group apache/Group root/" ${HTTPD_MAIN_CONF_PATH}/httpd.conf && \
    sed -i -e "s/^Listen 80/Listen 8080/" ${HTTPD_MAIN_CONF_PATH}/httpd.conf && \
    sed -ri " s!^(\s*CustomLog)\s+\S+!\1 |/usr/bin/cat!g; s!^(\s*ErrorLog)\s+\S+!\1 |/usr/bin/cat!g;" ${HTTPD_MAIN_CONF_PATH}/httpd.conf

USER 10001
WORKDIR ${APP_ROOT}

ENTRYPOINT [ "uid_entrypoint" ]

EXPOSE 8080

# Inform the user how to run this image.
# CMD ["/usr/libexec/s2i/usage"]

說明:

  1. 需要安裝nodejs、angular/cli
  2. httpd相關目錄要授予適當權限,需要修改httpd用戶、組、日志輸出、監聽端口

修改用戶后,不能再使用80端口,否則會報錯:permission denied: ah00072: make_sock: could not bind to address
編譯builder image并上傳到Registry

# docker build -t heroes-web-centos7:v1.0.0 .
# docker tag heroes-web-centos7:v1.0.0 registry.itrunner.org/heroes-web-centos7:v1.0.0
# docker push registry.itrunner.org/heroes-web-centos7:v1.0.0

import image

$ oc import-image heroes-web-centos7:v1.0.0 -n heroes --confirm --insecure --from='registry.itrunner.org/heroes-web-centos7:v1.0.0'

編輯ImageStream

$ oc edit is/heroes-web-centos7

增加如下annotations:

tags:
- annotations:
    description: build heroes-web on CentOS 7
    iconClass: icon-angularjs
    openshift.io/display-name: Heroes Web
    openshift.io/provider-display-name: itrunner
    sampleRepo: 'https://github.com/sunjc/heroes-web.git'
    supports: itrunner
    tags: builder,javascript
    version: 1.0.0
  from:
    kind: DockerImage
    name: 'registry.itrunner.org/heroes-web-centos7:v1.0.0'

S2I Scripts

  1. assemble
#!/bin/bash -e

# move the application source
mv /tmp/src $HOME/src

# restore build artifacts
if [ "$(ls /tmp/artifacts/ 2>/dev/null)" ]; then
    mv /tmp/artifacts/* $HOME/src
fi

# build the application artifacts
pushd $HOME/src
npm install
ng build --prod --base-href=/heroes/

# Install the artifacts
mv dist /var/www/html/heroes
mv node_modules $HOME/node_modules
popd

rm -rf $HOME/src
  1. run
#!/bin/bash

# run the application
exec httpd -D FOREGROUND $@
  1. save-artifacts
#!/bin/bash

# Besides the tar command, all other output to standard out must be surpressed.  Otherwise, the tar stream will be corrupted.
pushd ${HOME} >/dev/null
if [ -d node_modules ]; then
    # all node_modules contents to tar stream
    tar cf - node_modules
fi
popd >/dev/null
  1. usage
#!/bin/bash

# inform the user how to use the image
cat <<EOF
This is a S2I sample builder image, to use it, install
https://github.com/openshift/source-to-image
EOF

部署

$ oc new-app heroes/heroes-web-centos7:v1.0.0~https://github.com/sunjc/heroes-web.git --name=heroes-web
$ oc expose service heroes-web --name heroes-web --hostname heroes.apps.itrunner.org --path /heroes --port 8080-tcp -n heroes
或
$ oc create route edge heroes-web --service heroes-web --hostname heroes.apps.itrunner.org --path /heroes \
   --insecure-policy Redirect --port 8080-tcp -n heroes

Image管理

Internal Registry

前面的例子,我們使用了私有Docker Registry "registry.itrunner.org",先將base image上傳到私有Registry,然后再導入到OpenShift中。我們也可以直接使用OpenShift內部的Registry(安裝在default項目中),執行push、pull等操作。

為了訪問Internal Registry必須先執行docker login登錄Registry,需使用openshift用戶名(或email),使用有效的openshift token作為密碼。

  1. 登錄openshift獲取token
$ oc login https://openshift.itrunner.org:8443 -u jason --certificate-authority=/path/to/cert.crt
$ oc whoami -t
  1. 登錄Internal Registry
# docker login -u <user_name> -e <email_address> -p <token_value> <registry_server>:<port>

如在openshift節點內訪問Internal Registry,registry_server可以使用service hostname "docker-registry.default.svc",port為5000;如在外部訪問,registry_server則需使用route hostname,比如"docker-registry-default.apps.itrunner.org" ,docker-registry route的TLS Termination需配置為Re-encrypt。

# docker login -u jason -p xxxxxxxxxxx docker-registry-default.apps.itrunner.org
  1. Push Image
# docker tag heroes-web-centos7:v1.0.0 docker-registry-default.apps.itrunner.org/heroes/heroes-web-centos7:latest
# docker push docker-registry-default.apps.itrunner.org/heroes/heroes-web-centos7:latest

注意:tag格式必須為project/name
push成功后,openshift將自動創建image stream。

  1. Pull Image
# docker pull docker-registry-default.apps.itrunner.org/heroes/heroes-web-centos7:latest
  1. 查看Repository
$  curl -u jason:xxxxxxxxxx -kv https://docker-registry-default.apps.itrunner.org/v2/_catalog?n=100

用戶必須有list權限:

$ oc adm policy add-cluster-role-to-user registry-viewer user
  1. 查看image stream
$ oc get is -n heroes
NAME             DOCKER REPO                                                       TAGS            UPDATED
heroes-api           docker-registry.default.svc:5000/heroes/heroes-api           latest          7 days ago
heroes-api-centos7   docker-registry.default.svc:5000/heroes/heroes-api-centos7   v1.0.0          7 days ago
heroes-web           docker-registry.default.svc:5000/heroes/heroes-web           latest          7 days ago
heroes-web-centos7   docker-registry.default.svc:5000/heroes/heroes-web-centos7   latest,v1.0.0   19 hours ago

Image Stream

Image Stream是OpenShift管理容器鏡像的方式,其中定義了dockerImageReference,利用tag定義了同docker image各版本的映射關系。Image Stream本身不包含image data,image stream元數據與其他集群信息一起存儲在etcd實例中。
image stream更新后可以觸發build或deployment,如docker image已更新,但未更新image stream則不會觸發build或deployment。
image可以源自OpenShift Internal Registry、外部Registry(比如registry.redhat.io、docker.io、私有Registry)、OpenShift集群中的image stream。

apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
  annotations:
    openshift.io/image.dockerRepositoryCheck: '2019-04-09T05:59:17Z'
  creationTimestamp: '2019-04-01T08:02:37Z'
  generation: 2
  name: heroes-web-centos7
  namespace: heroes
  resourceVersion: '2145022'
  selfLink: >-
    /apis/image.openshift.io/v1/namespaces/heroes/imagestreams/heroes-web-centos7
  uid: 83deac8c-5454-11e9-af2b-02f23e935364
spec:
  lookupPolicy:
    local: false
  tags:
    - annotations:
        description: >-
          build heroes-web on CentOS 7. WARNING: By selecting this tag, your
          application will automatically update to use the latest version.
        iconClass: icon-angularjs
        openshift.io/display-name: Heroes Web (Latest)
        openshift.io/provider-display-name: itrunner
        sampleRepo: 'https://github.com/sunjc/heroes-web.git'
        supports: itrunner
        tags: 'builder,javascript'
      from:
        kind: DockerImage
        name: 'docker-registry.default.svc:5000/heroes/heroes-web-centos7:latest'
      generation: 2
      importPolicy: {}
      name: latest
      referencePolicy:
        type: Source
    - annotations:
        description: build heroes-web on CentOS 7
        iconClass: icon-angularjs
        openshift.io/display-name: Heroes Web 1.0.0
        openshift.io/provider-display-name: itrunner
        sampleRepo: 'https://github.com/sunjc/heroes-web.git'
        supports: itrunner
        tags: 'builder,javascript'
        version: 1.0.0
      from:
        kind: DockerImage
        name: 'registry.itrunner.org/heroes-web-centos7:v1.0.0'
      generation: 1
      importPolicy:
        insecure: true
      name: v1.0.0
      referencePolicy:
        type: Source
status:
  dockerImageRepository: 'docker-registry.default.svc:5000/heroes/heroes-web-centos7'
  tags:
    - items:
        - created: '2019-04-08T07:37:11Z'
          dockerImageReference: >-
            docker-registry.default.svc:5000/heroes/heroes-web-centos7@sha256:7e4126ec9ec0d4158d962936a38f255806731d33d6fe03b29d95d82759823fcd
          generation: 2
          image: >-
            sha256:7e4126ec9ec0d4158d962936a38f255806731d33d6fe03b29d95d82759823fcd
      tag: latest
    - items:
        - created: '2019-04-01T08:02:37Z'
          dockerImageReference: >-
            registry.itrunner.org/heroes-web-centos7@sha256:7e4126ec9ec0d4158d962936a38f255806731d33d6fe03b29d95d82759823fcd
          generation: 1
          image: >-
            sha256:7e4126ec9ec0d4158d962936a38f255806731d33d6fe03b29d95d82759823fcd
      tag: v1.0.0

Reference Policy
當使用從外部Registry導入的image時,"引用策略" 允許指定從何處提取image。有兩個選項:Local和Source:

  • Local 從OpenShift Internal Registry提取image
  • Source 直接從外部Registry提取image

查詢Image Stream信息

$ oc describe is/heroes-web-centos7
$ oc describe istag/heroes-web-centos7:latest

為外部Image添加tag

$ oc tag docker.io/openshift/base-centos7:latest base-centos7:latest

為Image Stream附加tag
給現有tag附加一個tag:

$ oc tag heroes-api-centos7:v1.0.0 heroes-api-centos7:latest

更新tag

$ oc tag heroes-api-centos7:v1.0.1 heroes-api-centos7:latest

說明:與附加tag不同,兩個tag都應存在
刪除tag

$ oc tag -d heroes-api-centos7:v1.0.0

$ oc delete istag/heroes-api-centos7:v1.0.0

刪除Image Stream

$ oc delete is base-centos7

定期更新tag
可以使用--scheduled:

$ oc tag docker.io/python:3.6.0 python:3.6 --scheduled

也可以在tag定義中設置importPolicy.scheduled為true:

apiVersion: v1
kind: ImageStream
metadata:
  name: python
spec:
  tags:
  - from:
      kind: DockerImage
      name: docker.io/python:3.6.0
    name: latest
    importPolicy:
      scheduled: true

周期默認為15分鐘。

Binary Build

Binary Build主要應用于測試和Jenkins pipeline場景。開發人員提交源碼前如果想先測試一下,可使用本地源碼來構建App Image。Binary Build不能自動觸發,只能手動執行。
Binary Build使用oc start-build命令,需要提供BuildConfig或存在的build,支持從幾種以下source來構建App Image:

  • --from-file 比如Dockerfile
  • --from-dir 本地目錄,start-build打包此目錄并上傳到openshift
  • --from-archive tar、tar.gz、zip等
  • --from-repo 本地源碼目錄,start-build打包最近commit的代碼并上傳到openshift

From a directory

$ oc start-build heroes-web --from-dir="." --follow
或
$ oc start-build --from-build=heroes-web-1 --from-dir="." --follow

From a Git repository

$ git commit -m "My changes"
$ oc start-build heroes-web --from-repo="." --follow

Jenkins Pipeline

...
stage("Build Image") {
  steps {
    dir('heroes-web/dist') {
      sh 'oc start-build heroes-web --from-dir . --follow'
    }
  }
}
...

Pipeline部署

Jenkins是廣泛應用的CI工具,大多數工程師都有使用經驗,更習慣使用Jenkins部署應用。使用Jenkins Pipeline部署OpenShift應用,不影響原有流程,可以正常執行測試、代碼質量檢查、編譯打包等操作,只需在部署時調用oc start-build。

安裝Jenkins

OpenShift提供了兩個Jenkins Template:jenkins-ephemeral、jenkins-persistent,一種使用瞬時存儲,一種使用持久存儲,兩者均使用jenkins image stream(docker.io/openshift/jenkins-2-centos7:v3.11)。jenkins image安裝了OpenShift Client、OpenShift Login、OpenShift Sync、Kubernetes、Kubernetes Credentialst等插件。安裝后既可以在OpenShift中運行Job,也可以在Jenkins中運行Job。

jenkins-persistent采用動態存儲配置,PVC默認名稱為jenkins(JENKINS_SERVICE_NAME):

- apiVersion: v1
  kind: PersistentVolumeClaim
  metadata:
    name: '${JENKINS_SERVICE_NAME}'
  spec:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: '${VOLUME_CAPACITY}'
    storageClassName: glusterfs-storage-block
- apiVersion: v1
  kind: DeploymentConfig
  metadata:
    annotations:
      template.alpha.openshift.io/wait-for-ready: 'true'
    name: '${JENKINS_SERVICE_NAME}'
  spec:
    ...
    template:
      metadata:
        labels:
          name: '${JENKINS_SERVICE_NAME}'
      spec:
        containers:
          - capabilities: {}
            ...
            volumeMounts:
              - mountPath: /var/lib/jenkins
                name: '${JENKINS_SERVICE_NAME}-data'
        ...
        volumes:
          - name: '${JENKINS_SERVICE_NAME}-data'
            persistentVolumeClaim:
              claimName: '${JENKINS_SERVICE_NAME}'

如使用GlusterFS需要先修改Template,指定storageClassName:

- apiVersion: v1
  kind: PersistentVolumeClaim
  metadata:
    name: '${JENKINS_SERVICE_NAME}'
  spec:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: '${VOLUME_CAPACITY}'
    storageClassName: glusterfs-storage-block

下面使用jenkins-persistent來安裝,命令如下:

$ oc project heroes
$ oc new-app jenkins-persistent -p VOLUME_CAPACITY=2Gi  -p MEMORY_LIMIT=2Gi
--> Deploying template "openshift/jenkins-persistent" to project heroes

     Jenkins
     ---------
     Jenkins service, with persistent storage.

     NOTE: You must have persistent volumes available in your cluster to use this template.

     A Jenkins service has been created in your project.  Log into Jenkins with your OpenShift account.  The tutorial at https://github.com/openshift/origin/blob/master/examples/jenkins/README.md contains more information about using this template.

     * With parameters:
        * Jenkins Service Name=jenkins
        * Jenkins JNLP Service Name=jenkins-jnlp
        * Enable OAuth in Jenkins=true
        * Memory Limit=2Gi
        * Volume Capacity=2Gi
        * Jenkins ImageStream Namespace=openshift
        * Disable memory intensive administrative monitors=false
        * Jenkins ImageStreamTag=jenkins:2
        * Fatal Error Log File=false

--> Creating resources ...
    route.route.openshift.io "jenkins" created
    persistentvolumeclaim "jenkins" created
    deploymentconfig.apps.openshift.io "jenkins" created
    serviceaccount "jenkins" created
    rolebinding.authorization.openshift.io "jenkins_edit" created
    service "jenkins-jnlp" created
    service "jenkins" created
--> Success
    Access your application via route 'jenkins-heroes.apps.itrunner.org'
    Run 'oc status' to view your app.

注意:如MEMORY_LIMIT配置低,則Jenkins Master節點架構為Linux (i386)。
查看存儲
安裝成功后,可以從安裝Jenkins的node查看存儲:

$  oc get pods -o wide
NAME              READY     STATUS      RESTARTS   AGE       IP            NODE                              NOMINATED NODE
jenkins-1-hw5q5   1/1       Running     0          5m        10.131.0.26   app2.itrunner.org   <none>
$ oc get pvc
NAME          STATUS        VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS              AGE
jenkins       Bound         pvc-bf3ff63d-6f1c-11e9-9dd9-02ef509f23d0   2Gi        RWO            glusterfs-storage   5m
# mount | grep pvc-bf3ff63d-6f1c-11e9-9dd9-02ef509f23d0
10.188.12.116:vol_0e157791c95b65a94011aed789d2037b on /var/lib/origin/openshift.local.volumes/pods/c12d7625-6f1c-11e9-ad9d-02499a450338/volumes/kubernetes.io~glusterfs/63d-6f1c-11e9-9dd9-02ef509f23d0 type fuse.glusterfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072)

# cd /var/lib/origin/openshift.local.volumes/pods/c12d7625-6f1c-11e9-ad9d-02499a450338/volumes/kubernetes.io~glusterfs/63d-6f1c-11e9-9dd9-02ef509f23d0

擴展存儲
當原配置的存儲容量不滿足需求時,可以擴展存儲。

  1. StorageClass的屬性allowVolumeExpansion必須設為true
$ oc edit sc/glusterfs-storage

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  creationTimestamp: 2019-04-28T02:58:06Z
  name: glusterfs-storage
  resourceVersion: "1903911"
  selfLink: /apis/storage.k8s.io/v1/storageclasses/glusterfs-storage
  uid: 723320e6-6961-11e9-b13d-02947d98b66e
parameters:
  resturl: http://heketi-storage.app-storage.svc:8080
  restuser: admin
  secretName: heketi-storage-admin-secret
  secretNamespace: app-storage
provisioner: kubernetes.io/glusterfs
reclaimPolicy: Delete
volumeBindingMode: Immediate

查看glusterfs-storage:

$ oc describe sc glusterfs-storage
Name:                  glusterfs-storage
IsDefaultClass:        No
Annotations:           <none>
Provisioner:           kubernetes.io/glusterfs
Parameters:            resturl=http://heketi-storage.app-storage.svc:8080,restuser=admin,secretName=heketi-storage-admin-secret,secretNamespace=app-storage
AllowVolumeExpansion:  True
MountOptions:          <none>
ReclaimPolicy:         Delete
VolumeBindingMode:     Immediate
Events:                <none>
  1. 更新PVC spec.resources.requests.storage
$ oc edit pvc/jenkins

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  annotations:
    openshift.io/generated-by: OpenShiftNewApp
    pv.kubernetes.io/bind-completed: "yes"
    pv.kubernetes.io/bound-by-controller: "yes"
    volume.beta.kubernetes.io/storage-provisioner: kubernetes.io/glusterfs
  creationTimestamp: 2019-05-05T10:01:26Z
  finalizers:
  - kubernetes.io/pvc-protection
  labels:
    app: jenkins-persistent
    template: jenkins-persistent-template
  name: jenkins
  namespace: heroes
  resourceVersion: "1904277"
  selfLink: /api/v1/namespaces/heroes/persistentvolumeclaims/jenkins
  uid: bf3ff63d-6f1c-11e9-9dd9-02ef509f23d0
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi
  storageClassName: glusterfs-storage
  volumeName: pvc-bf3ff63d-6f1c-11e9-9dd9-02ef509f23d0
...

安裝/更新插件
使用openshift用戶登錄jenkins。
快速部署OpenShift應用
進入系統管理 -> 插件管理,安裝/更新插件。為了編譯Angular需要安裝NodeJS插件(另一種選擇,可以使用node agent)。
配置全局工具

  1. JDK

快速部署OpenShift應用

  1. Maven

快速部署OpenShift應用

  1. NodeJS

快速部署OpenShift應用

首次調用時,Jenkins會自動安裝全局工具,pipeline配置如下:

tools {
  jdk 'jdk8'
  maven 'maven-3.6'
}
tools {
  nodejs 'nodejs-10.15'
}

創建配置文件
快速部署OpenShift應用

下面仍以部署Spring Boot和Angular工程為例介紹Pipeline的使用,開始之前請重建heroes project。

部署Spring Boot App

  1. 構建Builder Image

Jenkins負責編譯、打包,因此Builder Image不再需要Maven,修改如下:
Dockerfile

# jdk8-centos7
FROM centos:latest

RUN yum -y update && yum clean all

# Set the labels that are used for OpenShift to describe the builder image.
LABEL maintainer="Sun Jingchuan <jason@163.com>" \
      io.k8s.description="Oracle JDK 1.8.0_202 based on CentOS 7" \
      io.k8s.display-name="Oracle JDK 1.8.0_202" \
      io.openshift.expose-services="8080:http" \
      io.openshift.tags="jdk8"

ENV JAVA_HOME=/usr/lib/jdk1.8.0_202 \
    APP_ROOT=/opt/app-root
ENV PATH=${JAVA_HOME}/bin:${APP_ROOT}/bin:${PATH} HOME=${APP_ROOT}

COPY lib/jdk1.8.0_202 ${JAVA_HOME}
COPY bin ${APP_ROOT}/bin

RUN chmod -R u+x ${APP_ROOT}/bin && \
    chgrp -R 0 ${APP_ROOT} && \
    chmod -R g=u ${APP_ROOT} /etc/passwd

USER 10001
WORKDIR ${APP_ROOT}

ENTRYPOINT [ "uid_entrypoint" ]

EXPOSE 8080

編譯、上傳builder image
這次我們上傳到OpenShift Docker Registry,注意push前要先執行docker login。

# docker build -t jdk8-centos7 .
# docker tag jdk8-centos7:latest docker-registry-default.apps.itrunner.org/heroes/jdk8-centos7:latest
# docker push docker-registry-default.apps.itrunner.org/heroes/jdk8-centos7:latest
  1. 創建App Image Dockerfile

App Image以builder image為基礎,僅需拷貝Jenkins編譯好的jar,內容如下:
Dockerfile.app

# heroes-api
FROM heroes/jdk8-centos7:latest

COPY heroes-api-1.0.0.jar $HOME

CMD java -jar $HOME/heroes-api-1.0.0.jar
  1. 從Dockerfile創建BuildConfig
$ cat Dockerfile.app | oc new-build -D - --name heroes-api

執行后生成BuildConfig的部分內容如下:

spec:
  failedBuildsHistoryLimit: 5
  nodeSelector: null
  output:
    to:
      kind: ImageStreamTag
      name: 'heroes-api:latest'
  postCommit: {}
  resources: {}
  runPolicy: Serial
  source:
    dockerfile: "FROM heroes/jdk8-centos7:latest\r\n\r\nCOPY heroes-api-1.0.0.jar $HOME\r\n\r\nCMD java -jar $HOME/heroes-api-1.0.0.jar"
    type: Dockerfile
  strategy:
    dockerStrategy:
      from:
        kind: ImageStreamTag
        name: 'jdk8-centos7:latest'
    type: Docker

會自啟動build,但此時沒有jar導致build失敗,pipeline調用時才會傳入jar。

  1. 創建Pipeline BuildConfig

pipeline.yml

apiVersion: v1
kind: BuildConfig
metadata:
  name: heroes-api-pipeline
spec:
  strategy:
    jenkinsPipelineStrategy:
      jenkinsfile: |-
        pipeline {
          agent any
          tools {
            jdk 'jdk8'
            maven 'maven-3.6'
          }
          stages {
            stage("Clone Source") {
              steps {
                checkout([$class: 'GitSCM',
                  branches: [[name: '*/master']],
                  extensions: [
                    [$class: 'RelativeTargetDirectory', relativeTargetDir: 'heroes-api']
                  ],
                  userRemoteConfigs: [[url: 'https://github.com/sunjc/heroes-api.git']]
                ])
              }
            }
            stage("Build Backend") {
              steps {
                dir('heroes-api') {
                  sh 'mvn clean package -Pdev -Dmaven.test.skip=true'
                }
              }
            }
            stage("Build Image") {
              steps {
                dir('heroes-api/target') {
                  sh 'oc start-build heroes-api --from-dir . --follow'
                }
              }
            }
          }
        }
    type: JenkinsPipeline

Pipeline可以內嵌在BuildConfig內,也可以引用git中的Jenkinsfile(推薦):

apiVersion: v1
kind: BuildConfig
metadata:
  name: heroes-api-pipeline
spec:
  source:
    git:
      uri: "https://github.com/sunjc/heroes-api"
  strategy:
    jenkinsPipelineStrategy:
      jenkinsfilePath: Jenkinsfile
    type: JenkinsPipeline

創建pipeline:

$ oc create -f ./pipeline.yml

如果在項目中沒有安裝Jenkins,創建pipeline后將自動部署jenkins-ephemeral。

  1. 啟動pipeline
$ oc start-build heroes-api-pipeline

也可以在jenkins或Application Console -> Builds -> Pipelines中啟動。

  1. 部署App
$ oc new-app heroes-api
$ oc create route edge heroes-api --service heroes-api --hostname heroes.apps.itrunner.org --path /api --insecure-policy Redirect

部署Angular App

  1. 構建Builder Image

Dockerfile

# httpd-centos7
FROM centos/httpd:latest

RUN yum -y update && yum clean all

LABEL maintainer="Sun Jingchuan <jason@163.com>" \
      io.k8s.description="Apache Httpd 2.4" \
      io.k8s.display-name="Apache Httpd 2.4" \
      io.openshift.expose-services="8080:http" \
      io.openshift.tags="httpd"

ENV APP_ROOT=/opt/app-root
ENV PATH=${APP_ROOT}/bin:${PATH} HOME=${APP_ROOT} HTTPD_MAIN_CONF_PATH=/etc/httpd/conf

COPY bin ${APP_ROOT}/bin
COPY .s2i/bin/run ${APP_ROOT}/bin/run

RUN chmod -R u+x ${APP_ROOT}/bin && \
    chgrp -R 0 ${APP_ROOT} && \
    chmod -R g=u ${APP_ROOT} /etc/passwd /var/www/html /run/httpd && \
    chown -R root:root /run/httpd /etc/httpd && \
    sed -i -e "s/^User apache/User default/" ${HTTPD_MAIN_CONF_PATH}/httpd.conf && \
    sed -i -e "s/^Group apache/Group root/" ${HTTPD_MAIN_CONF_PATH}/httpd.conf && \
    sed -i -e "s/^Listen 80/Listen 8080/" ${HTTPD_MAIN_CONF_PATH}/httpd.conf && \
    sed -ri " s!^(\s*CustomLog)\s+\S+!\1 |/usr/bin/cat!g; s!^(\s*ErrorLog)\s+\S+!\1 |/usr/bin/cat!g;" ${HTTPD_MAIN_CONF_PATH}/httpd.conf

USER 10001
WORKDIR ${APP_ROOT}

ENTRYPOINT [ "uid_entrypoint" ]

EXPOSE 8080

編譯、上傳Builder Image

# docker build -t httpd-centos7 .
# docker tag httpd-centos7:latest docker-registry-default.apps.itrunner.org/heroes/httpd-centos7:latest
# docker push docker-registry-default.apps.itrunner.org/heroes/httpd-centos7:latest
  1. 創建App Image Dockerfile

Dockerfile.app

# heroes-web
FROM heroes/httpd-centos7:latest

COPY heroes /var/www/html/heroes

CMD $HOME/bin/run
  1. 從Dockerfile創建BuildConfig
$ cat Dockerfile.app | oc new-build -D - --name heroes-web

執行后將啟動build,此時沒有傳入內容導致build失敗。

  1. 創建Pipeline BuildConfig

pipeline.yml

apiVersion: v1
kind: BuildConfig
metadata:
  name: heroes-web-pipeline
spec:
  source:
    git:
      uri: "https://github.com/sunjc/heroes-web"
  strategy:
    jenkinsPipelineStrategy:
      jenkinsfilePath: Jenkinsfile
    type: JenkinsPipeline

Jenkinsfile

pipeline {
  agent any
  tools {
    nodejs 'nodejs-10.15'
  }
  stages {
    stage("Clone Source") {
      steps {
        checkout([$class: 'GitSCM',
          branches: [[name: '*/master']],
          extensions: [
            [$class: 'RelativeTargetDirectory', relativeTargetDir: 'heroes-web']
          ],
          userRemoteConfigs: [[url: 'https://github.com/sunjc/heroes-web']]
        ])
      }
    }
    stage("Build Angular") {
      steps {
        dir('heroes-web') {
          sh 'npm install'
          sh 'ng config -g cli.warnings.versionMismatch false'
          sh 'ng build --prod --base-href=/heroes/'
        }
      }
    }
    stage("Build Image") {
      steps {
        dir('heroes-web/dist') {
          sh 'oc start-build heroes-web --from-dir . --follow'
        }
      }
    }
  }
}

創建pipeline:

$ oc create -f ./pipeline.yml
  1. 啟動pipeline
$ oc start-build heroes-web-pipeline
  1. 部署App
$ oc new-app heroes-web
$  oc create route edge heroes-web --service heroes-web --hostname heroes.apps.itrunner.org --path /heroes \
   --insecure-policy Redirect --port 8080-tcp -n heroes

OpenShift DSL

OpenShift Jenkins image安裝了OpenShift Jenkins Client插件,支持使用OpenShift Domain Specific Language(DSL)定義pipeline。

def templatePath = 'https://raw.githubusercontent.com/openshift/nodejs-ex/master/openshift/templates/nodejs-mongodb.json' 
def templateName = 'nodejs-mongodb-example' 
pipeline {
  agent {
    node {
      label 'nodejs' 
    }
  }
  options {
    timeout(time: 20, unit: 'MINUTES') 
  }
  stages {
    stage('preamble') {
        steps {
            script {
                openshift.withCluster() {
                    openshift.withProject() {
                        echo "Using project: ${openshift.project()}"
                    }
                }
            }
        }
    }
    stage('cleanup') {
      steps {
        script {
            openshift.withCluster() {
                openshift.withProject() {
                  openshift.selector("all", [ template : templateName ]).delete() 
                  if (openshift.selector("secrets", templateName).exists()) { 
                    openshift.selector("secrets", templateName).delete()
                  }
                }
            }
        }
      }
    }
    stage('create') {
      steps {
        script {
            openshift.withCluster() {
                openshift.withProject() {
                  openshift.newApp(templatePath) 
                }
            }
        }
      }
    }
    stage('build') {
      steps {
        script {
            openshift.withCluster() {
                openshift.withProject() {
                  def builds = openshift.selector("bc", templateName).related('builds')
                  timeout(5) { 
                    builds.untilEach(1) {
                      return (it.object().status.phase == "Complete")
                    }
                  }
                }
            }
        }
      }
    }
    stage('deploy') {
      steps {
        script {
            openshift.withCluster() {
                openshift.withProject() {
                  def rm = openshift.selector("dc", templateName).rollout().latest()
                  timeout(5) { 
                    openshift.selector("dc", templateName).related('pods').untilEach(1) {
                      return (it.object().status.phase == "Running")
                    }
                  }
                }
            }
        }
      }
    }
    stage('tag') {
      steps {
        script {
            openshift.withCluster() {
                openshift.withProject() {
                  openshift.tag("${templateName}:latest", "${templateName}-staging:latest") 
                }
            }
        }
      }
    }
  }
}

具體請參考OpenShift Pipeline Builds

清理對象

隨著不斷的構建、部署應用,build、deployment、image等對象會逐漸增多,管理員應定期清理不再需要的對象。
OpenShift提供了oc adm prune命令來清理對象,支持auth、groups、builds、deployments、images等類型。

$ oc adm prune <object_type> <options>

Pruning builds

$ oc adm prune builds [<options>]
Option Description
--confirm Indicate that pruning should occur, instead of performing a dry-run
--orphans Prune all builds whose build config no longer exists, status is complete, failed, error, or canceled
--keep-complete=N Per build config, keep the last N builds whose status is complete. (default 5)
--keep-failed=N Per build config, keep the last N builds whose status is failed, error, or canceled (default 1)
--keep-younger-than=duration Do not prune any object that is younger than duration relative to the current time. (default 60m)
$ oc adm prune builds --orphans --keep-complete=5 --keep-failed=1 --keep-younger-than=60m --confirm

Pruning deployments

$ oc adm prune deployments [<options>]
Option Description
--confirm Indicate that pruning should occur, instead of performing a dry-run
--orphans Prune all deployments whose deployment config no longer exists, status is complete or failed, and replica count is zero
--keep-complete=N Per deployment config, keep the last N deployments whose status is complete and replica count is zero. (default 5)
--keep-failed=N Per deployment config, keep the last N deployments whose status is failed and replica count is zero. (default 1)
--keep-younger-than=duration Do not prune any object that is younger than duration relative to the current time. (default 60m) Valid units of measurement include nanoseconds (ns), microseconds (us), milliseconds (ms), seconds (s), minutes (m), and hours (h)
$ oc adm prune deployments --orphans --keep-complete=5 --keep-failed=1 --keep-younger-than=60m --confirm

Pruning images

$ oc adm prune images [<options>]

system:admin用戶不能執行清理image的操作,必須使用普通用戶登錄,且用戶必須有system:image-pruner角色。

$ oc login https://openshift.itrunner.org:8443 --token=xxxx
Option Description
--all Include images that were not pushed to the registry, but have been mirrored by pullthrough. This is on by default. To limit the pruning to images that were pushed to the integrated registry, pass --all=false
--certificate-authority The path to a certificate authority file to use when communicating with the OKD-managed registries. Defaults to the certificate authority data from the current user’s configuration file. If provided, secure connection will be initiated
--confirm Indicate that pruning should occur, instead of performing a dry-run. This requires a valid route to the integrated container image registry. If this command is run outside of the cluster network, the route needs to be provided using --registry-url
--force-insecure Use caution with this option. Allow an insecure connection to the Docker registry that is hosted via HTTP or has an invalid HTTPS certificate
--keep-tag-revisions=N For each image stream, keep up to at most N image revisions per tag. (default 3)
--keep-younger-than=duration Do not prune any image that is younger than duration relative to the current time. Do not prune any image that is referenced by any other object that is younger than duration relative to the current time. (default 60m)
--prune-over-size-limit Prune each image that exceeds the smallest limit defined in the same project. This flag cannot be combined with --keep-tag-revisions nor --keep-younger-than
--registry-url The address to use when contacting the registry. The command will attempt to use a cluster-internal URL determined from managed images and image streams. In case it fails (the registry cannot be resolved or reached), an alternative route that works needs to be provided using this flag. The registry host name may be prefixed by https:// or http:// which will enforce particular connection protocol
--prune-registry In conjunction with the conditions stipulated by the other options, this option controls whether the data in the registry corresponding to the OKD Image API Objects is pruned. By default, image pruning processes both the Image API Objects and corresponding data in the registry. This options is useful when you are only concerned with removing etcd content, possibly to reduce the number of image objects, but are not concerned with cleaning up registry storage; or intend to do that separately by Hard Pruning the Registry, possibly during an appropriate maintenance window for the registry

使用--keep-younger-than清理image,不會清理以下情況的image:

  • 創建時間在--keep-younger-than內的所有Pod
  • 創建時間在--keep-younger-than內的所有ImageStream
  • 正在運行的Pod
  • 狀態為pending的Pod
  • 所有replication controllers
  • 所有deployment configurations
  • 所有build configurations
  • 所有builds

使用--prune-over-size-limit清理超過指定Limit的image,不會清理以下情況的image:

  • 正在運行的Pod
  • 狀態為pending的Pod
  • 所有replication controllers
  • 所有deployment configurations
  • 所有build configurations
  • 所有builds

示例:

$ oc adm prune images --keep-tag-revisions=3 --keep-younger-than=60m --confirm

$ oc adm prune images --prune-over-size-limit --confirm

清理image后不會更新registry cache,為了清理cache可以重新部署registry:

$ oc rollout latest dc/docker-registry -n default

docker prune

docker相關prune命令:

# docker container prune
# docker image prune
# docker volume prune

慎用,會刪除openshift/origin-docker-builder、openshift/origin-deployer。
快速部署OpenShift應用

推薦文檔

潘曉華Michael - OpenShift

參考文檔

OKD Latest Documentation
source-to-image

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

化德县| 云南省| 正宁县| 云龙县| 嫩江县| 明光市| 牡丹江市| 准格尔旗| 山丹县| 云龙县| 卢氏县| 广灵县| 马尔康县| 隆回县| 庆安县| 新兴县| 阿拉善右旗| 丘北县| 红原县| 南澳县| 会东县| 玛曲县| 龙江县| 金塔县| 都安| 巨鹿县| 新竹市| 黎城县| 云梦县| 安庆市| 南昌县| 锡林郭勒盟| 肥城市| 七台河市| 乌拉特后旗| 邹城市| 台山市| 利辛县| 佳木斯市| 西宁市| 泰兴市|