Python应用 OpenShift部署实战

[TOC]

概述

这次的实战目标如下:

将已有的python示例程序部署到OpenShift上. 为此, 需要做的事情有:

  1. 对原有python示例程序做优化和调整, 使得可以部署到OpenShift上.
  2. 基于OpenShift上自带模板(templates: openshift上的一种CI/CD全流程定义) - Django + PostgreSQL 进行修改生成新的模板.
  3. 基于新的模板, 填入python示例程序的git地址, 自动进行: 构建(build), 部署(deployment)和对外服务(service, route). 查看部署结果.

OpenShift简介

OpenShift v3(开源版本叫做: okd)是一个PAAS(平台及服务)系统,旨在尽可能准确地公开底层Docker格式的容器镜像和Kubernetes 理念,并着重于开发人员轻松组合应用程序。例如,安装Ruby,推送代码并添加MySQL。

OpenShift基于Docker和Kubernetes, 并针对以下方面进行了开发和优化:

  • CI/CD 流程(基于jenkins的pipeline, S2I等)
  • UI界面
  • 安全加固(如容器内使用非root用户等)
  • 监控功能(基于EFK技术栈的日志监控和基于Prometheus的metrics监控等)
  • 提供更安全 经过RedHat认证的基础镜像/模板等.(包括: java, python等运行时, mysql, mongo等db, apache, wildfly等中间件, jenkins等CI/CD, elasticsearch, kibana等监控镜像)

:notebook:

OpenShift有多个产品线, 包括:

  • 开源版

    • okd (The Origin Community Distribution of Kubernetes that powers Red Hat OpenShift.)
  • 商业版

    • OpenShift Online
    • OpenShift Delicated
    • OpenShift Container Platform

Python示例程序简介

这是一个Django项目 - Learning Log(《Python编程:从入门到实践》的教学案例),数据库可以基于sqlite或Postgresql.

:notebook:

这个应用的功能如下:

  • 这是一个名为"学习笔记"的Web应用程序, 让用户能够记录感兴趣的主题, 并在学习每个主题的过程中添加日志条目.
  • "学习笔记"的主页对这个网站进行描述, 并邀请用户注册或登陆.
    用户登陆后, 就可以创建新主题/添加新条目以及阅读既有的条目.

实战步骤

python示例程序修改

:notebook:

针对Django应用需要修改的代码其实不多, 都集中在settings.py 中.

  1. 删除heroku部署的相关代码: https://github.com/east4ming/learning_log/commit/1119c62d33766538601a711a4473f0ab64dd8f3e

  2. Django settings.py 文件修改内容:

    1. 修改ALLOW_HOSTS* (配置为*, 表示允许所有hosts, 如果不配置, OpenShift自动分配的域名和地址会无法访问python示例程序): https://github.com/east4ming/learning_log/commit/534c1283eb9c430c1739d71ce0984cee6c776d04

    2. DJANGO SECRET 改为通过系统变量(os.getenv方式)获取 (OpenShift的原模板 Django + PostgreSQL 包含这一变量): https://github.com/east4ming/learning_log/commit/dd6695db345c333f1d193261fef3a35a2b926c97

    3. 修改DATABASES相关代码, 改为兼容sqlite和postgresql. https://github.com/east4ming/learning_log/commit/5dceef61b999cfe0abc45ed371f487c2e428a4c6 新增的database.py (settings.pyDATABASES部分调用该文件)代码如下:

      import os
      
      from django.conf import settings
      
      engines = {
          'sqlite': 'django.db.backends.sqlite3',
          'postgresql': 'django.db.backends.postgresql_psycopg2',
      }
      
      
      def config():
          service_name = os.getenv('DATABASE_SERVICE_NAME', '').upper().replace('-',
                                                                                '_')
          if service_name:
              engine = engines.get(os.getenv('DATABASE_ENGINE'), engines['sqlite'])
          else:
              engine = engines['sqlite']
          name = os.getenv('DATABASE_NAME')
          if not name and engine == engines['sqlite']:
              name = os.path.join(settings.BASE_DIR, 'db.sqlite3')
          return {
              'ENGINE': engine,
              'NAME': name,
              'USER': os.getenv('DATABASE_USER'),
              'PASSWORD': os.getenv('DATABASE_PASSWORD'),
              'HOST': os.getenv('{}_SERVICE_HOST'.format(service_name)),
              'PORT': os.getenv('{}_SERVICE_PORT'.format(service_name)),
          }
      
  3. (可选) 添加OpenShift相关脚本,变量: https://github.com/east4ming/learning_log/commit/095a59973bc6a6c5886f3debf56dde16e4ef2f96

    1. conf/reload.py 用于APP_CONFIG 变量, 可以调整WSGI相关配置.
    2. openshift/scripts/run-in-container.sh 用于在openshift的部署容器中较为方便地运行一些命令(如创建超级用户等)(不用该脚本, 直接进行容器用shell命令行也是一样的效果)

针对OpenShift 模板Django + PostgreSQL进行修改生成新模板

:notebook:

关于 OpenShift Templates(模板)的说明, 请参见: https://docs.openshift.com/container-platform/3.11/dev_guide/dev_tutorials/quickstarts.html

模板简介

模板由一组服务(service),构建配置(build config)和部署配置(deployment config)构成。模板引用必要的镜像和源存储库来构建和部署应用程序。

顺便简单介绍一下模板编写时的相关参数:

简单模板示例:

apiVersion: v1
kind: Template
metadata:
  name: redis-template
  annotations:
    description: "Description"
    iconClass: "icon-redis"
    tags: "database,nosql"
objects:
- apiVersion: v1
  kind: Pod
  metadata:
    name: redis-master
  spec:
    containers:
    - env:
      - name: REDIS_PASSWORD
        value: ${REDIS_PASSWORD}
      image: dockerfile/redis
      name: master
      ports:
      - containerPort: 6379
        protocol: TCP
parameters:
- description: Password used for Redis authentication
  from: '[A-Z0-9]{8}'
  generate: expression
  name: REDIS_PASSWORD
labels:
  redis: master

描述

模板描述告知用户模板的功能,并帮助他们在Web控制台中搜索时找到它。模板名称之外的其他元数据是可选的,但有用。除了一般描述性信息之外,元数据还包括一组标签(label)。有用的标签包括模板与之相关的语言的名称(例如, javaphpruby等)。

见上文代码片段的 metadata部分.

标签

模板可以包含一组 标签。这些标签将添加到实例化模板时创建的每个对象。以这种方式定义标签使用户可以轻松查找和管理从特定模板创建的所有对象。

见上文代码片段的 labels部分.

参数

参数允许值由用户提供或在实例化模板时生成。然后,只要引用参数,该值就会被替换。可以在对象列表字段的任何字段中定义引用。这对于生成随机密码或允许用户提供自定义模板所需的主机名或其他特定于用户的值非常有用。可以通过两种方式引用参数:

  • 通过在模板中的任何字符串字段中以${PARAMETER_NAME}形式放置值来作为字符串值。
  • 作为json / yaml值,通过在${{PARAMETER_NAME}}格式中放置值代替模板中的任何字段。

见上文代码片段的 parameters部分.

对象列表

模板的主要部分是在实例化模板时将创建的对象列表。这可以是任何 有效的API对象,例如 BuildConfigDeploymentConfigService等。该对象将被精确地创建为这里所定义,和在之前的创建取代的任何参数值。这些对象的定义可以引用先前定义的参数.

见上文代码片段的 objects部分.

修改模板并导入

:notebook:

针对python的官方quickstart模板有3个:

  • django (1个pod, 数据库使用sqlite)
  • django + postgresql (2个pod, 数据库使用postgresql, 但是数据库数据没有持久化)
  • django + postgresql persistent (2个pod, 数据库使用postgresql, 数据库数据进行持久化)

本次使用第三个, 源模板链接:django-postgresql-persistent.json

顺便说明一下, 模板文件几百行, 看起来挺吓人的, 但是实际上大部分都是自动生成的. 可以通过CLI等工具生成, 或者对现成的模板做微调.

修改后的模板django-postgresql-persistent.json. 部分说明:

  1. 本次模板共创建了以下几类对象:
    1. Secret - 密钥对象(存储加密信息, 本例中存储: 数据库用户名和密码, django secret key)
    2. Service - 服务(容器内端口对外暴露并提供负载均衡). 这个模板有2个:
      1. django应用的Service
      2. postgresql数据库的Service (提供给django使用)
    3. Route - 路由(对外暴露提供服务, 通常是域名)
    4. ImageStream - 镜像流(OpenShift特有, 定义如何构建该应用, 包含: 代码库地址, 基础镜像等信息)
    5. DeploymentConfig - 部署配置(包含: pod数量及重启策略, 可用性探针, 运行时环境变量, 资源闲置等信息)
      1. django 应用的DC
      2. postgresql 数据库的DC
    6. PersistentVolumeClaim - 持久性存储声明(包含: 存储大小/读写的声明)
  2. 新增内容:
    1. 新增env和参数:ENABLE_PIPENV (这个参数基础镜像就有, 这儿列出来设置为true使之生效)
  3. 修改内容:
    1. 根据自己的代码仓库信息, 对参数的默认值做了部分修改. (可选, 不修改也行, 填的时候手动填写也可以)
      1. git仓库相关信息
      2. pip index url信息(只有使用pip方式才生效, 因为我用的是pipenv方式, 实际上没生效) - 改为阿里的源.
      3. 基础镜像从python3.5改为了3.6(没啥影响, 只因为我本地用的比较新)
    2. 对Django pod的可用性探针 - readinessProbelivenessProbe进行了修改, 改为了自己的测试URI(就是/), 另外超时时间放长一点.
  4. 修改完之后, 导入该模板到OpenShift: oc create -f .\openshift\templates\django-postgresql-persistent.json(也可以通过UI导入: Catalog → Custom Add → Import YAML/JSON)

构建 部署并验证应用

  1. 在OpenShift 的 Catalog页面点击新导入的模板 - Learning Log. 如下图:

    OpenShift Catalog
  1. 点击Next:

    OpenShift Template Info
  1. 填写相关的配置信息:

    OpenShift Template Conf
OpenShift Template Conf
  1. 点击Create. 会自动创建django-psql-persistent应用. 此时, OpenShift会进行如下的动作:

    1. 创建PVC

    2. 创建Secret

    3. 创建Build 流程, 我是之前有部分代码有问题, 或者连不上pipenv的源, 构建了4次才成功. (构建也是会启动一个专门的构建容器, 构建成功后输出一个构建后部署的镜像, 同时构建镜像自动销毁). 对于: python pipenv django, build流程大致如下:

      1. 下载pipenv及相关依赖包(如virtualenv等)
      2. pipenv根据Pipfile.lock安装应用所需依赖包
      3. Django执行static文件移动和数据库migrate.
      4. 推送build完成的镜像到镜像库
      OpenShift
  1. Deployment部署应用, 包括: postgresql和django应用镜像. (pod那个圈是蓝色就是成功了)

    OpenShift Template Deploy
  1. 最终部署成功后, 在OpenShift上的Overview显示如下:
OpenShift Overview
  1. 通过上图的URL访问: http://django-psql-persistent-learning-log.192.168.2.6.nip.io/

    OpenShift Learning Log

更多细节展示:
容器的环境变量:

OpenShift Pod Env

容器的日志:

OpenShift Pod Logs

容器的终端:

OpenShift Pod Terminal

应用的services:

OpenShift Services

应用的route:

OpenShift Route

:thinking:感悟

K8S概念就很复杂了, OpenShift又在这上面添加了很多新概念, 比如: build, S2I, ImageStream ... 真的不容易理解.

还有就是其实开发人员需要频繁调试, 修改代码, 每次修改都得走一遍CI/CD流程. 真的挺耗时的.

目前OpenShift这种容器平台还是需要进一步提升易用性, 毕竟, 开发人员更多精力的是要放在写代码上, 构建部署越便捷越简单越好.

道阻且长啊.

参考资料

s2i-python-container readme

OpenShift 官方python模板quickstart

Django settings

OpenShift 官方文档

OpenShift 快速开始: Django

Python S2I镜像

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349