写在前面


  • 因为参加考试,会陆续分享一些 OpenShift 的笔记
  • 博文内容为安装完 OpenShift, 利用 OpenShift 引擎部署一个镜像应用和一个 S2I 流程部署应用 Demo
  • 学习环境为 openshift v3 的版本,有些旧
  • 这里如果专门学习 openshift ,建议学习 v4 版本
  • 理解不足小伙伴帮忙指正

傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。--------王小波


OpenShift 提供了 Web 控制台,通过图形界面,用户可以完成一些操作。但是个人觉得,不经常用,控制台还真不怎么好用, 好在 OpenShift 还提供了一系列命令行工具。

oc OpenShift 中一个重要的命令行客户端。OpenShift Web 控制台能完成的事情,通过 oc 命令也能完成。在进行自动化及重复性的操作时,命令行工具比图形界面更加高效。

可以尝试执行 oc version 命令查看 OpenShift 的集群版本信息,测试 oc 命令是否正常工作。

┌──[root@192.168.26.16]-[~]
└─$oc version
oc v3.11.0+0cbc58b
kubernetes v1.11.0+d4cacc0
features: Basic-Auth GSSAPI Kerberos SPNEGO

Server https://127.0.0.1:8443
kubernetes v1.11.0+d4cacc0

当前版本为 3.11 的版本

因为oc命令是带有权限管控的,所以在使用 oc 命令进行实际的操作前,需要先通过 oc 1ogin 命令登录,当然,如何使用了 kubeconfig 文件就不需要了

┌──[root@192.168.26.16]-[~]
└─$oc login -u developer
Logged into "https://127.0.0.1:8443" as "developer" using existing credentials.

You have access to the following projects and can switch between them with 'oc project <projectname>':

    hello-world
  * myproject

Using project "myproject".

配置oc命令补全

┌──[root@192.168.26.16]-[~]
└─$cat /etc/profile
# /etc/profile

# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc

# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.

source <(oc completion bash)
....
┌──[root@192.168.26.16]-[~]
└─$source /etc/profile

openshift 的上游开源版本现在叫 OKD, 所以在下文中也称 OKD ,不在说明

OKD 的项目是一个完整的 CICD 流水线的项目。相对于 K8s , okd 做了很多,整合了整个流水线, 当然没有可比性,OKD 作为 Kubernetes 的社区发行版,针对持续应用程序开发和多租户部署进行很多优化。

下面我们通过两个 Demo 来简单认识一下 OKD

  • 第一个是类似 K8s 的一个 deploy 部署,只有CD,但是涉及的资源对象都会自动完成创建,在不用插件的 K8s 中,这些都是需要人工处理
  • 第二个是一个结合 自动化流程工具S2I(Source to lmage) 的一个 CICD 的 Demo

镜像项目构建

通过 oc new-project 命令创建一个新项目 he11o-world-oc

┌──[root@192.168.26.16]-[~]
└─$oc new-project hello-world-oc
Now using project "hello-world-oc" on server "https://127.0.0.1:8443".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app centos/ruby-25-centos7~https://github.com/sclorg/ruby-ex.git

to build a new example application in Ruby.

OKD 中的的项目 Project 是基于 K8s 中的 命名空间的,在创建一个 项目的同时,会生成一个同名的命名空间。

┌──[root@vms16.liruilongs.github.io]-[~]
└─$oc get project
NAME             DISPLAY NAME   STATUS
hello-world-oc                  Active
myproject        My Project     Active
┌──[root@vms16.liruilongs.github.io]-[~]
└─$oc login -u system:admin
┌──[root@vms16.liruilongs.github.io]-[~]
└─$oc get ns | grep hello
hello-world-oc                  Active    4m

假设我们已经走过了 CI 的过程,现在拥有一个包含应用的打好的镜像 openshift/hello-openshift ,拉取镜像

┌──[root@192.168.26.16]-[~]
└─$docker pull openshift/hello-openshift
Using default tag: latest
latest: Pulling from openshift/hello-openshift
Digest: sha256:aaea76ff622d2f8bcb32e538e7b3cd0ef6d291953f3e7c9f556c1ba5baf47e2e
Status: Downloaded newer image for openshift/hello-openshift:latest
docker.io/openshift/hello-openshift:latest

在命令行可以通过 oc new-app 命令方便地部署 DockerHub 等 Docker 镜像仓库的镜像。

下面的命令中, oc new-app 后面紧跟的 为镜像名字。如果涉及源码的话,需要指定 ~源码地址的方式, 通过 --name podName 指定 应用名称 名字

OKD 中应用的概念和和传统的应用概念相关,当前应用的所有的 API 资源都会打上 app=appname 的标签

通过 oc new-app openshift/hello-openshift 创建的应用,OKD 会自动的创建一些应用相关的 API 资源对象,这些资源包括 OKD 所特有的和原生的 k8s API 对象。

┌──[root@192.168.26.16]-[~]
└─$oc new-app openshift/hello-openshift
--> Found Docker image 7af3297 (4 years old) from Docker Hub for "openshift/hello-openshift"

    * An image stream tag will be created as "hello-openshift:latest" that will track this image
    * This image will be deployed in deployment config "hello-openshift"
    * Ports 8080/tcp, 8888/tcp will be load balanced by service "hello-openshift"
      * Other containers can access this service through the hostname "hello-openshift"

--> Creating resources ...
    imagestream.image.openshift.io "hello-openshift" created
    deploymentconfig.apps.openshift.io "hello-openshift" created
    service "hello-openshift" created
--> Success
    Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
     'oc expose svc/hello-openshift'
    Run 'oc status' to view your app.
┌──[root@192.168.26.16]-[~]
└─$

用构建日志可以看到,我们只提供了镜像,其他的 API 资源都是自动生成的。

  • 从Docker Hub 找到镜像,用于 openshift/hello-openshift”
  • 创建 Image Stream为 hello-openshift:latest 使之指向最新的镜像
  • 创建 Deployment Config 为 hello-openshift,
  • 创建 Replication Controller 为 hello-openshift-1
  • 创建 Service ,且 8080/tcp, 8888/tcp 端口将被服务"hello-openshift"负载均衡
  • 其他容器可以通过主机名"hello-openshift"访问此服务
  • 希望外部访问可以通过 'oc expose svc/hello-openshift' 创建 routehello.openshift 供外部访问。

简单说明一下,这里的

  • Image Stream 是 okd 所特有的,用于描述 一组带版本的镜像。
  • Deployment Config 也是 okd 特有,用于描述,pod 部署的版本,回滚,以及副本,相对于原生的 deployment,多了滚动升级相关配置,可以说 dc 是用来描述 deploy 的,就像 通过 deploy 来描述 pod 一样。

通过下面的命令可以看到生成的全部资源

┌──[root@vms16.liruilongs.github.io]-[~]
└─$oc get all
NAME                          READY     STATUS    RESTARTS   AGE
pod/hello-openshift-1-xx2q4   1/1       Running   3          183d

NAME                                      DESIRED   CURRENT   READY     AGE
replicationcontroller/hello-openshift-1   1         1         1         183d

NAME                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
service/hello-openshift   ClusterIP   172.30.166.53   <none>        8080/TCP,8888/TCP   183d

NAME                                                 REVISION   DESIRED   CURRENT   TRIGGERED BY
deploymentconfig.apps.openshift.io/hello-openshift   1          1         1         config,image(hello-openshift:latest)

NAME                                             DOCKER REPO                                 TAGS      UPDATED
imagestream.image.openshift.io/hello-openshift   172.30.1.1:5000/myproject/hello-openshift   latest    6 months ago

NAME                                       HOST/PORT         PATH      SERVICES          PORT       TERMINATION   WILDCARD
route.route.openshift.io/hello-openshift   hello.openshift             hello-openshift   8080-tcp                 None
┌──[root@vms16.liruilongs.github.io]-[~]
└─$

S2I 工具项目构建

作为一个面向应用的平台,OpenShift 提供了 S2I(Source to Image) 的流程,使得企业内容器的构建变得标准化和自动化,从而提高了软件从开发到+上线的效率。

OpenShift:关于OpenShift(OKD)通过命令行的方式部署镜像以及S2I流程Demo_centos

一个典型的 S2I 流程包含了以下几个步骤。

  1. 用户输入源代码仓库的地址。
  2. 用户选择 S2I 构建的基础镜像(又称为 Builder 镜像)。Builder镜像中包含了操作系统、编程语言、框架等应用所需的软件及配置。OpenShift默认提供了多种编程语言的Builder镜像,如Java、PHP、Ruby、Python、Perl等。用户也可以根据自身需求定制自己的Builder镜像,并发布到服务目录中供用户选用。
  3. 用户或系统触发 S2I 构建。OpenShift 将实例化S2I构建执行器。
  4. S2I 构建执行器将从用户指定的代码仓库下载源代码。
  5. S2I 构建执行器实例化Builder镜像。代码将会被注入Builder镜像中。
  6. Builder 镜像将根据预定义的逻辑执行 源代码的编译、构建并完成部署
  7. S2I 构建执行器将完成操作的 Builder 镜像并生成新的 Docker镜像
  8. S2I 构建执行器将新的镜像推送到 OpenShift 内部的 镜像仓库。
  9. S2I 构建执行器更新该次构建相关的 Image Stream 信息。

S2I构建完成后,根据用户定义的部署逻辑,OpenShit 将把镜像实例化部署到集群中。

下面我们看 Demo, 创建一个新的项目

┌──[root@vms16.liruilongs.github.io]-[~]
└─$oc new-project  cicd-demo
Now using project "cicd-demo" on server "https://127.0.0.1:8443".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app centos/ruby-25-centos7~https://github.com/sclorg/ruby-ex.git

to build a new example application in Ruby.

以给出的 Demo 为例,,通过 oc new-app 创建一个应用

oc new-app centos/ruby-25-centos7~https://github.com/sclorg/ruby-ex.git

这里指定

  • Builder 基础镜像为: centos/ruby-25-centos7
  • 源码地址为: https://github.com/sclorg/ruby-ex.git

部署项目,可以看到相关资源对象会自动创建

┌──[root@vms16.liruilongs.github.io]-[~]
└─$oc new-app centos/ruby-25-centos7~https://github.com/sclorg/ruby-ex.git
--> Found Docker image e96bd99 (18 months old) from Docker Hub for "centos/ruby-25-centos7"

    Ruby 2.5
    --------
    Ruby 2.5 available as container is a base platform for building and running various Ruby 2.5 applications and frameworks. Ruby is the interpreted scripting language for quick and easy object-oriented programming. It has many features to process text files and to do system management tasks (as in Perl). It is simple, straight-forward, and extensible.

    Tags: builder, ruby, ruby25, rh-ruby25

    * An image stream tag will be created as "ruby-25-centos7:latest" that will track the source image
    * A source build using source code from https://github.com/sclorg/ruby-ex.git will be created
      * The resulting image will be pushed to image stream tag "ruby-ex:latest"
      * Every time "ruby-25-centos7:latest" changes a new build will be triggered
    * This image will be deployed in deployment config "ruby-ex"
    * Port 8080/tcp will be load balanced by service "ruby-ex"
      * Other containers can access this service through the hostname "ruby-ex"

--> Creating resources ...
    imagestream.image.openshift.io "ruby-25-centos7" created
    imagestream.image.openshift.io "ruby-ex" created
    buildconfig.build.openshift.io "ruby-ex" created
    deploymentconfig.apps.openshift.io "ruby-ex" created
    service "ruby-ex" created
--> Success
    Build scheduled, use 'oc logs -f bc/ruby-ex' to track its progress.
    Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
     'oc expose svc/ruby-ex'
    Run 'oc status' to view your app.

使用 S2I 的方式创建应用,同样会需要作为一个 SVC 外部访问需要通过 Route 发布出去。

┌──[root@vms16.liruilongs.github.io]-[~]
└─$oc expose svc/ruby-ex
route.route.openshift.io/ruby-ex exposed

创建好之后就可以通过路由访问了

这里小伙伴可能会有一个疑问,openshift 如何把源码放到基础镜像里面? 如果存在需要编译的源码是如何处理的。

使用默认的 assemble 脚本

为了将源代码放入构建镜像中,OpenShift使用了S2I(Source-to-Image)构建策略。这种策略允许将源代码与构建镜像的基础镜像结合在一起,以创建一个新的镜像。在这种情况下,基础镜像是“centos/ruby-25-centos7”,源代码位于“https://github.com/sclorg/ruby-ex.git”

在执行 “oc new-app” 命令时,OpenShift 会自动检测源代码的类型,并选择适当的 S2I 构建器。在这种情况下,OpenShift 将选择 Ruby S2I构建器,该构建器将源代码与基础镜像结合在一起,以创建一个新的镜像。

具体来说,OpenShift将使用以下命令将源代码放入构建镜像中

s2i build https://github.com/sclorg/ruby-ex.git centos/ruby-25-centos7 my-ruby-app

这将使用Ruby S2I构建器将源代码与基础镜像结合在一起,并将结果保存为名为“my-ruby-app”的新镜像。这个新镜像可以用来部署应用程序。

S2Iassemble 脚本是用来将源代码编译成可执行文件并将其放入容器中的。在这种情况下,Ruby S2I 构建器将使用默认的assemble脚本,该脚本将执行以下操作:

#!/bin/bash

set -e

# Add application sources
cp -Rf /tmp/src/. /opt/app-root/src

# Install the dependencies
if [ -e /opt/app-root/src/Gemfile ]; then
  cd /opt/app-root/src
  bundle install --path=vendor/bundle
fi

# Run the build script
if [ -e /opt/app-root/src/build.sh ]; then
  cd /opt/app-root/src
  /bin/bash build.sh
fi

# Fix permissions
chown -Rf 1001:0 /opt/app-root
chmod -Rf g+rw /opt/app-root

exec "$@"

这个脚本将源代码复制到容器中,并安装任何必要的依赖项。然后,它将运行任何构建脚本(如果有的话),并修复文件权限。最后,它将执行容器的默认命令。

通过 Dockerfile 的方式

在 OpenShift 中,还可以使用类似的方法创建一个构建配置,该配置引用 Dockerfile。类似传统的结合方式,以下是一个示例构建配置:

apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
  name: myapp
spec:
  source:
    git:
      uri: https://github.com/myuser/myapp.git
    contextDir: path/to/source/code
  strategy:
    dockerStrategy:
      dockerfilePath: Dockerfile
  output:
    to:
      kind: ImageStreamTag
      name: myapp:latest
FROM base-image:tag
ADD path/to/source/code /app+

此构建配置引用 Git 存储库中的源代码,并将 path/to/source/code 目录指定为上下文目录。它还引用 Dockerfile 并指定输出镜像名称和标签。

博文部分内容参考

© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知,这是一个开源项目,如果你认可它,不要吝啬星星哦 😃


《开源容器云OpenShift:构建基于Kubernetes的企业应用云平台》

《OKD 3.9 DO280 Red Hat OpenShift Administration I》