开始使用 Kubernetes 和 OKD(一个以前称为 OpenShift Origin 的 Kubernetes 发行版)可能会让人望而生畏。 有许多概念和组件需要学习和理解。 本教程将引导您创建一个示例 Kubernetes cron 作业,该作业使用服务帐户和一个 Python 脚本来列出当前项目/命名空间中的所有 pod。 作业本身相对来说没什么用,但本教程介绍了 Kubernetes 和 OKD 基础设施的许多部分。 此外,Python 脚本是使用 OKD REST API 进行集群相关任务的一个很好的示例。
本教程涵盖了 Kubernetes/OKD 基础设施的几个部分,包括
- 服务帐户和令牌
- 基于角色的访问控制 (RBAC)
- 镜像流
- BuildConfig
- Source-to-image (S2I)
- 作业和 cron 作业(主要是后者)
- Kubernetes 的 Downward API
本教程的 Python 脚本和示例 OKD YAML 文件可以在 GitHub 上找到; 要使用它们,只需将 value: https://okd.host:port 行替换为 cronJob.yml 中您的 OKD 实例的主机名。
先决条件
所需软件
- 安装了默认 S2I 镜像流的 OKD 或 MiniShift 集群
- 集成的镜像注册表
可选软件(用于玩转 Python 脚本)
要安装模块,请运行
pip3 install --user openshift kubernetes
身份验证
Python 脚本将使用服务帐户 API 令牌来向 OKD 进行身份验证。 该脚本期望有一个指向 OKD 主机的环境变量,它将连接到该主机
HOST:要连接到的 OKD 主机(例如,https://okd.host:port)
OKD 还将需要为将运行 cron 作业 pod 的服务帐户自动创建令牌(请参阅下面的“设置如何使用环境变量和令牌”below)。
流程
设置此同步是一个很好的学习经验——因为您需要设置许多 Kubernetes 和 OKD 任务,所以您可以很好地了解它的各种功能。
一般流程是
- 创建一个新项目
- 创建一个包含 Python 脚本的 Git 存储库
- 创建一个服务帐户
- 授予服务帐户 RBAC 权限
- 设置如何使用环境变量和令牌
- 创建一个镜像流以接受 BuildConfig 创建的镜像
- 创建一个 BuildConfig 以将 Python 脚本转换为镜像/镜像流
- 构建镜像
- 创建 cron 作业
1. 创建一个新项目
在 OKD 中为此练习创建一个新项目
oc new-project py-cron
根据集群的设置方式,您可能需要请求集群管理员为您创建一个新项目。
2. 创建一个包含 Python 脚本的 Git 存储库
克隆或 fork 此存储库
https://github.com/clcollins/openshift-cronjob-example.git
您也可以在下面的代码示例中直接引用它。 这将作为存储库,从中拉取 Python 脚本并构建到最终运行的镜像中。
3. 创建一个服务帐户
服务帐户是一个非用户帐户,可以与 OKD 中的资源、权限等关联。 对于本练习,您必须创建一个服务帐户来运行包含 Python 脚本的 pod,通过令牌身份验证向 OKD API 进行身份验证,并进行 REST API 调用以列出所有 pod。
由于 Python 脚本将查询 OKD REST API 以获取命名空间中 pod 的列表,因此服务帐户将需要列出 pod 和命名空间的权限。 从技术上讲,项目中自动创建的默认服务帐户之一——system:serviceaccount:default:deployer——已经拥有这些权限。 但是,本练习将创建一个新的服务帐户来解释服务帐户创建和 RBAC 权限。
通过输入以下内容创建一个新的服务帐户
oc create serviceaccount py-cron
这将创建一个名为 py-cron 的服务帐户。(从技术上讲,它是 system:serviceaccounts:py-cron:py-cron,或“py-cron”命名空间中的“py-cron”服务帐户)。 该帐户自动接收两个 secret:一个 OKD API 令牌和 OKD 容器注册表的凭据。 API 令牌将在 Python 脚本中用于向 OKD 标识服务帐户以进行 REST API 调用。
与服务帐户关联的令牌可以使用以下命令查看
oc describe serviceaccount py-cron
4. 授予服务帐户 RBAC 权限
OKD 和 Kubernetes 使用 RBAC(基于角色的访问控制)来精细控制谁可以在复杂的集群中做什么。 在 RBAC 中
- 权限基于动词和资源(例如,创建组、删除 pod 等)
- 权限集被分组到角色或 ClusterRole 中,后者顾名思义是集群范围的。
- 角色和 ClusterRole 通过创建 RoleBinding 或 ClusterRoleBinding 与组和服务帐户(或者,如果您想完全错误地操作,则与个人用户)关联(或绑定到)。
- 组、服务帐户和用户可以绑定到多个角色。
对于本练习,在项目中创建一个角色,授予该角色列出 pod 和项目的权限,并将 py-cron 服务帐户绑定到该角色
oc create role pod-lister --verb=list --resource=pods,namespaces
oc policy add-role-to-user pod-lister --role-namespace=py-cron system:serviceaccounts:py-cron:py-cron
请注意,必须添加 --role-namespace=py-cron 以防止 OKD 查找 ClusterRole。
验证服务帐户是否已绑定到角色
oc get rolebinding | awk 'NR==1 || /^pod-lister/'
NAME ROLE USERS GROUPS SERVICE ACCOUNTS SUBJECTS
pod-lister py-cron/pod-lister py-cron
5. 设置如何使用环境变量和令牌
与服务帐户关联的令牌和各种环境变量在 Python 脚本中被引用为 py-cron API 令牌。
为 py-cron 服务帐户自动创建的 API 令牌由 OKD 挂载到服务帐户正在运行的任何 pod 中。 此令牌被挂载到 pod 中每个容器的特定路径
/var/run/secrets/kubernetes.io/serviceaccount/token
Python 脚本读取此文件并使用它向 OKD API 进行身份验证以管理组。
-
HOST 环境变量:HOST 环境变量在 cron 作业定义中指定,并包含格式为 https://okd.host:port 的 OKD API 主机名。
-
NAMESPACE 环境变量:NAMESPACE 环境变量在 cron 作业定义中引用,并使用 Kubernetes Downward API 动态填充变量,其中包含 cron 作业 pod 正在运行的项目的名称。
6. 创建一个镜像流
镜像流是镜像的集合,在本例中,由 BuildConfig 构建创建,并且是镜像和 Kubernetes 对象之间的抽象层,允许它们引用镜像流而不是直接引用镜像。
在可以将新构建的镜像推送到镜像流之前,该流必须已经存在。 创建新的空流的最简单方法是使用 oc 命令行命令
oc create imagestream py-cron
7. 创建 BuildConfig
BuildConfig 是整个构建过程的定义——获取输入参数和代码并将它们转换为镜像的行为。
本练习的 BuildConfig 将使用 source-to-image (S2I) 构建策略,使用 Red Hat 提供的 Python S2I 镜像,并将 Python 脚本添加到其中,其中 requirements.txt 被解析并安装这些模块。 这将生成一个最终的基于 Python 的镜像,其中包含脚本和运行它所需的 Python 模块。
BuildConfig 的重要部分是:.spec.output、.spec.source 和 .spec.strategy。
.spec.output
BuildConfig 的输出部分描述了如何处理构建的输出。 在这种情况下,BuildConfig 将生成的镜像输出为镜像流标签 (例如,py-cron:1.0),该标签可以在 deploymentConfig 中用于引用镜像。
这些可能是自解释的。
spec:
output:
to:
kind: ImageStreamTag
name: py-cron:1.0
.spec.source
BuildConfig 的源部分描述了构建的内容来自哪里。 在这种情况下,它引用了 Git 存储库,其中保存了 Python 脚本及其支持文件。
其中大多数也是自解释的。
spec:
source:
type: Git
git:
ref: master
uri: https://github.com/clcollins/openshift-cronjob-example.git
.spec.strategy
BuildConfig 的策略部分描述了要使用的构建策略,在本例中为源(即 S2I)策略。 .spec.strategy.sourceStrategy.from 部分定义了公共 Python 3.6 镜像流,该镜像流存在于默认 OpenShift 命名空间中,供任何人使用。 此镜像流包含 S2I 构建器镜像,这些镜像将 Python 代码作为输入,安装 requirements.txt 文件中列出的任何依赖项,然后输出一个包含代码和已安装需求的成品镜像。
strategy:
type: Source
sourceStrategy:
from:
kind: ImageStreamTag
name: python:3.6
namespace: openshift
此示例的完整 BuildConfig 看起来像下面的 YAML。 替换您的 Git 存储库并使用 oc 命令创建 BuildConfig
oc create -f <path.to.buildconfig.yaml>
YAML
---
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
labels:
app: py-cron
name: py-cron
spec:
output:
to:
kind: ImageStreamTag
name: py-cron:1.0
runPolicy: Serial
source:
type: Git
git:
ref: master
uri: https://github.com/clcollins/openshift-cronjob-example.git
strategy:
type: Source
sourceStrategy:
from:
kind: ImageStreamTag
name: python:3.6
namespace: openshift
8. 构建镜像
在大多数情况下,向 BuildConfig 添加 webhook 触发器以允许在每次将代码提交并推送到存储库时自动重建镜像会更有效率。 但是,对于本练习,每当需要更新镜像时,将手动启动镜像构建。
可以通过运行以下命令触发新的构建
oc start-build BuildConfig/py-cron
运行此命令会输出构建的名称; 例如
build.build.openshift.io/py-cron-1 started
可以通过观看日志来跟踪构建的进度
oc logs -f build.build.openshift.io/py-cron-1
构建完成后,镜像将被推送到 BuildConfig 的 .spec.output 部分中列出的镜像流。
9. 创建 cron 作业
Kubernetes cron 作业 对象定义了 cron 计划和行为,以及为运行实际同步而创建的 Kubernetes 作业。
cron 作业定义的重要部分是:.spec.concurrencyPolicy、.spec.schedule 和 .spec.JobTemplate.spec.template.spec.containers。
.spec.concurrencyPolicy
cron 作业规范的 concurrencyPolicy 字段是一个可选字段,用于指定如何处理此 cron 作业创建的作业的并发执行。 在本练习中,如果 cron 作业创建新作业,它将替换可能仍在运行的现有作业。
注意: 其他选项是允许并发(同时运行多个作业)或禁止并发(新作业将被跳过,直到正在运行的作业完成)。
.spec.schedule
cron 作业规范的 schedule 字段(毫不奇怪)是一个 Vixie cron 格式的计划。 在指定的时间,Kubernetes 将创建一个作业,如下面的 JobTemplate 规范中所定义。
spec:
schedule: "*/5 * * * *"
.spec.JobTemplate.spec.template.spec.containers
cron 作业规范包含一个 JobTemplate 规范和一个模板规范,后者又包含一个容器规范。 所有这些都遵循其类型的标准规范,即 .spec.containers 部分只是您可能在任何其他 pod 定义中找到的普通容器定义。
此示例的容器定义是一个直接的容器定义,它使用了上面讨论的环境变量。
唯一重要的部分是:
.spec.JobTemplate.spec.template.spec.containers.ServiceAccountName
此部分将先前创建的服务帐户 py-cron 设置为运行容器的帐户。 这将覆盖默认的 deployer 服务帐户。
py-cron 的完整 OKD cron 作业看起来像下面的 YAML。 替换 OKD 集群 API 的 URL,并使用以下 oc 命令创建 cron 作业:
oc create -f <path.to.cronjob.yaml>
YAML
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
labels:
app: py-cron
name: py-cron
spec:
concurrencyPolicy: Replace
failedJobsHistoryLimit: 1
JobTemplate:
metadata:
annotations:
alpha.image.policy.openshift.io/resolve-names: '*'
spec:
template:
spec:
containers:
- env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: HOST
value: https://okd.host:port
image: py-cron/py-cron:1.0
imagePullPolicy: Always
name: py-cron
ServiceAccountName: py-cron
restartPolicy: Never
schedule: "*/5 * * * *"
startingDeadlineSeconds: 600
successfulJobsHistoryLimit: 3
suspend: false
四处查看
创建 cron 作业后,可以使用 oc get cronjob 命令查看其组件。 这显示了 cron 作业的简要描述、其计划和上次运行时间,以及它是处于活动状态还是暂停状态
oc get cronjob py-cron
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
py-cron */5 * * * * False 0 1m 7d
如前所述,cron 作业创建 Kubernetes 作业以在计划时间过去时执行工作。 oc get jobs 命令列出了 cron 作业已创建的作业、所需的作业数(在本例中,每次运行仅一个作业)以及作业是否成功
oc get jobs
NAME DESIRED SUCCESSFUL AGE
py-cron-1544489700 1 1 10m
py-cron-1544489760 1 1 5m
py-cron-1544489820 1 1 30s
作业是 pod,可以使用 oc get pods 命令查看。 在此示例中,您可以看到作业 pod(以创建它们的作业命名,例如作业“py-cron-1544489760”创建了 pod“py-cron-1544489760-xl4vt”)。 还有构建 pod,或构建容器镜像的 pod,如上面的 BuildConfig 中所述。
oc get pods
NAME READY STATUS RESTARTS AGE
py-cron-1-build 0/1 Completed 0 7d
py-cron-1544489760-xl4vt 0/1 Completed 0 10m
py-cron-1544489820-zgfg8 0/1 Completed 0 5m
py-cron-1544489880-xvmsn 0/1 Completed 0 44s
py-cron-2-build 0/1 Completed 0 7d
py-cron-3-build 0/1 Completed 0 7d
最后,由于此示例只是一个连接到 OKD REST API 以获取有关项目中 pod 信息的 Python 脚本,因此可以使用 oc get logs 验证脚本是否正常工作,方法是从 pod 获取日志以查看写入标准输出的脚本的输出
oc logs py-cron-1544489880-xvmsn
---> Running application from Python script (app.py) ...
ResourceInstance[PodList]:
apiVersion: v1
items:
- metadata:
annotations: {openshift.io/build.name: py-cron-1, openshift.io/scc: privileged}
creationTimestamp: '2018-12-03T18:48:39Z'
labels: {openshift.io/build.name: py-cron-1}
name: py-cron-1-build
namespace: py-cron
ownerReferences:
- {apiVersion: build.openshift.io/v1, controller: true, kind: Build, name: py-cron-1,
uid: 0c9cf9a8-f72c-11e8-b217-005056a1038c}
<snip>
总结
本教程介绍了如何在 OKD(一个以前称为 OpenShift Origin 的 Kubernetes 发行版)中创建 Kubernetes cron 作业。 BuildConfig 描述了如何构建包含调用 OKD REST API 的 Python 脚本的容器镜像,并创建了一个镜像流来描述由构建构建的镜像的不同版本。 创建了一个服务帐户来运行容器,并创建了一个角色以允许服务帐户从 OKD REST API 获取 pod 信息。 RoleBinding 将角色与服务帐户关联起来。 最后,创建了一个 cron 作业以按指定的计划运行作业(包含 Python 脚本的容器)。
评论已关闭。