Openshift上的S2I和应用容器化方法:Openshift开发系列第一篇

在Openshift上部署应用php

oc new-app 命令可经过单个 URL 参数(最简单的形式)指向 Git 存储库或容器镜像。它会访问这个 URL,以肯定如今是否要解释该参数并执行构建或部署。oc new-app 命令作出的决定可能与您的指望不符。例如:若是 Git 存储库同时包含 Dockerfile 和 index.php 文件,那么该存储库会被用做 Dockerfile 构建仍是 PHP S2I 构建的输入?若是 Git 存储库包含以 PHP 为目标的源代码,并且您的 OpenShift 集群包含适用于 PHP 5.6 和 7.0 的 S2I 构建器镜像,则应使用哪一个版本?
为了应对上述和其余状况,oc new-app 命令提供了不少选项:html

图片

oc new-app 命令建立的资源oc new-app 命令可向当前项目添加如下资源,以支持构建和部署应用:node

  • 用于从源代码或 Dockerfile 构建应用容器镜像的构建配置。python

  • 指向内部注册表中的已生成镜像或指向外部注册表中的现有镜像的镜像流。git

  • 会使用镜像流做为输入来建立应用 Pod 的部署配置。github

  • 适用于应用容器镜像已公开的全部端口的服务。若是应用容器镜像没有声明任何公开端口,则不会建立任何服务。docker

试验1:使用S2I部署应用

这个应用以 JavaScript 编写,且使用 Node.js 运行时。它是一个基于 Express 框架的“hello, world”应用。express

您应根据如下要求构建应用并将其部署至 OpenShift 集群:apache

  • 用于 OpenShift 的应用名为 hello。该应用应该能从如下位置访问:http://hello.apps.lab.example.com。npm

  • 包含应用源的 Git 存储库为:http://services.lab.example.com/nodejs-helloworld。

  • 构建应用所需的 Npm 模块可从如下位置获取:http://services.lab.example.com:8081/nexus/content/groups/nodejs。

  • 使用 npm_config_registry 环境变量将这一信息传输至 Node.js 的 S2I 构建器镜像。

  • python -m json.tool filename.json 命令可用于识别 JSON 文件中的语法错误。

[student@workstation ~]$ oc new-app --name hello \ --build-env npm_config_registry=\http://services.lab.example.com:8081/nexus/content/groups/nodejs \ http://services.lab.example.com/nodejs-helloworld

使用 npm_config_registry 环境变量将这一信息传输至 Node.js 的 S2I 构建器镜像

包含应用源的 Git 存储库为:http://services.lab.example.com/nodejs-helloworld。构建应用所需的 Npm 模块可从如下位置获取:http://services.lab.example.com:8081/nexus/content/groups/nodejs。使用 npm_config_registry 环境变量将这一信息传输至 Node.js 的 S2I 构建器镜像。

Node.js 构建器镜像不会指出 package.json 源文件中的具体错误位置。

将应用源克隆到 student 用户的主文件夹:

使用文本编辑器打开 package.json 源文件,并查找语法错误。如下列出的部份内容显示 "express" 密钥后面缺乏冒号 (:):

图片
图片

公开应用供外部访问:
图片

使用 curl 命令向应用发送 HTTP 请求。它应该会返回“hello, world”消息:

图片

应用容器化方法

OpenShift 中的基本部署单元是 container image 或仅 image。容器镜像由应用以及运行应用所需的全部依赖关系(共享库、运行时环境、解释器等)组成。根据您计划在 OpenShift 集群上部署和运行的应用类型来建立容器镜像的多种方法:

  1. 容器镜像:在 OpenShift 外部构建的容器镜像能够直接部署在 OpenShift 集群上。在您已将应用打包为容器镜像的状况下,此方法颇有用。若是第三方供应商已向您提供了通过认证且受支持的容器镜像,则也可以使用此方法。您能够将第三方供应商构建的镜像部署至 OpenShift 集群。

  2. Dockerfile:在某些状况下,您会得到用于构建应用容器镜像的 Dockerfile。在这种状况下,您还可考虑使用其余选项:

  • 您能够对该 Dockerfile 进行自定义,构建新的镜像以知足您的应用需求。若是更改幅度不大,并且您不想在镜像中添加过多的层,则建议使用此选项。

  • 您可使用提供的容器镜像做为父级建立新的 Dockerfile,并自定义基本镜像以知足您的应用需求。若是要建立具备更多自定义项的新子镜像,而且从父镜像继承图层,则建议使用此选项。

  1. Source-to-Image (S2I) 构建器镜像:S2I 构建器镜像包含基础操做系统库、编译器和解释器、运行时、框架和 Source-to-Image 工具。使用此方法构建应用时,OpenShift 将应用源代码和构建器镜像结合,以建立可在 OpenShift 集群上部署的可当即运行的容器镜像。对于开发人员而言,此方法具备多个优势,这也是在 OpenShift 集群上构建新应用以供部署的首选方式。

根据您的应用需求,您能够经过多种方式来使用 S2I 构建器镜像:红帽提供了多种受支持的 S2I 构建器镜像,以用于构建各种应用。红帽建议您尽可能使用标准 S2I 构建器镜像。S2I 构建器镜像与普通容器镜像相似,但前者包含额外的元数据、脚本和工具。您可使用 Dockerfiles 基于红帽提供的父构建器镜像来建立子镜像。若是红帽提供的 S2I 构建器镜像都不符合您的应用需求,则您能够构建本身的自定义 S2I 构建器镜像。

S2I 构建器镜像S2I 构建器镜像是一种特殊形式的容器镜像,它会生成并输出应用容器镜像。构建器镜像包含应用所基于的基础操做系统库、语言运行时、框架和库,以及各类 Source-to-Image 工具和实用程序。例如,若是想要部署到 OpenShift 的应用是用 PHP 编写的,则可以使用 PHP 构建器镜像来生成应用容器镜像。您要提供存储应用源代码的 Git 存储库的位置,而后 OpenShift 会将该源代码与基础构建器镜像进行整合,以生成要部署到 OpenShift 的容器镜像。所生成的应用容器镜像包含某一版本的红帽企业 Linux、一个 PHP 运行时和相应的应用。构建器镜像是一种很是便捷的机制。采用该机制时,无需建立 Dockerfile,便可轻松快速地从代码生成可运行的容器。

使用容器镜像虽然 Source-to-Image 构建是构建应用并将其部署至 OpenShift 的首选方式,但在某些状况下您须要部署外部构建的应用。例如,某些供应商会提供已通过全面认证且可直接运行的受支持容器镜像。在这种状况下,OpenShift 支持部署预构建的容器镜像。oc new-app 命令能够提供多种灵活方式,以向 OpenShift 集群部署容器镜像。最简单的方法就是,经过公共注册表(如 docker.io)或私有注册表(您所在企业内部托管的注册表)获取预构建的 docker 镜像,而后向 oc new-app 命令提供该镜像的位置。接着,OpenShift 会提取该镜像并将其部署至 OpenShift 集群,就像部署在 OpenShift 中构建的任何其余镜像同样。

建立 S2I 构建器镜像

S2I 构建器镜像可经过多种选项来建立:

从头开始建立您本身的 S2I 构建器镜像。若是您的应用没法使用 S2I 构建器镜像按原样提供的 RHCC,则可构建自定义 S2I 构建器镜像,以经过自定义构建流程来知足您的应用需求。

OpenShift 提供了 s2i 命令行工具,帮助您启动用于建立自定义 S2I 构建器镜像的构建环境。它包含在 RHSCL YUM 存储库 (rhel-server-rhscl-7-eus-rpms) 的 source-to-image 软件包中。

对现有 S2I 构建器镜像进行派生。无需从头开始建立。您可使用适用于 RHCC 中的现有构建器镜像的 Dockerfile(可从 https://github.com/sclorg/?q=s2i获取),而后再对其进行自定义以知足您的需求。

对现有 S2I 构建器镜像进行扩展。您还能够建立子镜像,而后向现有构建器镜像添加内容或替换其中的内容,从而对现有的构建器镜像进行扩展。

试验2: 使用 OpenShift 来从 Dockerfile 中构建和部署 Apache HTTP 服务器容器。

查看 Apache HTTP 服务器父 Dockerfile。

FROM registry.lab.example.com:5000/rhel7:7.3 1

MAINTAINER Red Hat Training <training@redhat.com>

# Generic labels
LABEL Component="httpd" \ 2
     Name="do288/httpd-parent" \
     Version="1.0" \
     Release="1"

# Labels consumed by OpenShift
LABEL io.k8s.description="A basic Apache HTTP Server image with ONBUILD instructions" \ 3
     io.k8s.display-name="Apache HTTP Server parent image" \
      io.openshift.expose-services="80:http" \
     io.openshift.tags="apache, httpd"

# DocumentRoot for Apache
ENV DOCROOT=/var/www/html \4
\
   LOG_PATH=/var/log/httpd

# Need this for installing Apache from cla***oom yum repo
ADD training.repo /etc/yum.repos.d/training.repo

RUN   yum install -y --setopt=tsflags=nodocs --noplugins httpd && \ 5
     yum clean all --noplugins -y && \
      echo "Hello from the httpd-parent container!" > ${HOME}/index.html

# Allows child images to inject their own content into DocumentRoot
ONBUILD COPY src/ ${DOCROOT}/ 6

EXPOSE 80

# This stuff is needed to ensure a clean start
RUN rm -rf /run/httpd && mkdir /run/httpd

# Run as the root user
USER root 7

# Launch apache daemon
CMD /usr/sbin/apachectl -DFOREGROUND

构建并部署 Apache HTTP 服务器子镜像:

oc new-app --name hello
http://services.lab.example.com/container-build
--insecure-registry

命令行将会完成以下操做:

  • OpenShift 从 oc new-app 命令提供的 URL 克隆 Git 存储库。

  • Git 存储库根上的 Dockerfile 会自动识别,并启动 Docker 构建进程。

  • 父 Dockerfile 中的 ONBUILD 指令会触发子 index.html 文件的复制,其会覆盖父索引页。

  • 最后,构建的镜像会推送到 OpenShift 内部注册表。

查看构建日志

Cloning "http://services.lab.example.com/container-build" ... 1
        Commit: 32494325ace534486841c085da0cbc55c05ae33c (Initial commit)
        Author: root <root@foundation0.ilt.example.com>
        Date:   Sun Oct 15 12:07:05 2017 -0400
Pulling image registry.lab.example.com:5000/do288/httpd-parent@sha256:853d59eca... 2
...
Pulled 5/6 layers, 85% complete
Pulled 6/6 layers, 100% complete
Extracting
Step 1 : FROM registry.lab.example.com:5000/do288/httpd-parent@sha256:853d59eca...
# Executing 1 build trigger... 3
Step 1 : COPY src/ ${DOCROOT}/
...
Successfully built c8a37064e3e9
Pushing image docker-registry.default.svc:5000/container-build/hello:latest ... 4
...
Pushed 7/7 layers, 100% complete
Push successful

查看 Pod 没法启动的缘由:

因为 OpenShift 使用随机 userid 运行容器,低于 1024 的端口是特权端口,只能以 root 身份运行。
OpenShift 用于运行容器的随机 userid 不具备在 /var/log/httpd(RHEL 7 上的 Apache HTTP 服务器的默认日志文件位置)中读写日志文件的权限。

配置 OpenShift 以容许容器做为 Dockerfile 的 USER 指令中配置的用户运行。此方法不须要对 Dockerfile 进行任何更改。为应用建立新的服务账户

oc create serviceaccount apacheuser

将 anyuid SCC 添加到服务账户:

oc adm policy add-scc-to-user anyuid -z apacheuser

将 serviceAccountName 属性添加到 spec.template.spec 部分(terminationGracePeriodSeconds 属性下面),而后保存文件:

前一个 oc edit 命令触发了新的部署。等待新 Pod 就绪并在运行。查看应用 Pod 的状态:

图片

使用路由公开应用供外部访问:
图片

相关文章
相关标签/搜索