文章背景:本地有个centos服务器用于各类python脚本的定期任务执行,考虑这些脚本含有敏感信息,放在这个服务器不太安全,而且这台服务器还承载其他业务的功能,混用资源不合适,所以想把这些定期任务迁移出来,放到K8S集群运行。
任务信息:
设计思路:将每个Python脚本及其运行环境打包为标准化容器镜像,这些脚本中的模块都需要按照现有的版本进行固化,防止有意外问题,保留原服务器的PATH和LANG设置,避免环境差异导致的问题,然后把这个镜像上传到私有仓库以供拉取,编写一些Kubernetes原生CronJob与现有K8s集群无缝集成,存储方面使用K8S集群的nfs存储类,用于日志的持久化,另外因为脚本会生成一些其他临时信息需要被留存读取,在yaml中挂载节点的本地目录,这方面是因为想整点花活,不然就也使用存储类了。
迁移项目目录结构:
python/
├── Dockerfile # Docker镜像构建文件
├── requirements.txt # Python依赖列表
├── packages/ # 本地Python包目录
├── scripts/ # 所有Python脚本
│ ├── check.py # 各类脚本名,仅举例部分
│ ├── autonetxj.py
└── kubernetes/
├── cronjob.yaml
└── pvc.yaml # 持久化存储配置
准备工作:
1.按照上方的目录结构,手动创建对应的目录及各空文件先。
2.把所有需要迁移的脚本任务脚本源文件拷贝到scripts/
目录。
3.切换到这个python/
目录,获取当前Python环境的所有已安装包输出到requirements.txt
,也可以自行录入。
pip freeze > requirements.txt
4.切换到这个python/
目录,使用命令下载各类模块安装包到packages/
目录
#批量下载
pip download -r requirements.txt -d ./packages
#单个下载示例
pip download numpy==1.19.5 -d ./packages
开始实施:
1.切换到这个python/
目录,编写镜像构建文件
vi Dockerfile
Dockerfile代码信息:
# 使用官方Python 3.6.8镜像(Debian Buster基础)
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/python:3.6
# 安装语言包并配置UTF-8
RUN apt-get update && apt-get install -y locales && \
sed -i 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
locale-gen en_US.UTF-8
# 创建zabbix用户,我有的脚本是与zabbix系统联动所有此处需要
RUN groupadd -g 10787 zabbix && \
useradd -u 10787 -g zabbix -s /bin/bash zabbix
# 安装系统依赖:gcc(编译Python包)、ODBC驱动、MSSQL工具
RUN apt-get update && apt-get install -y \
gcc \
unixodbc-dev \
gnupg2 \
curl
# 强制更新ODBC驱动配置(支持TLS 1.2)此处是因为我有的脚本需要连数据库
RUN curl -sSL https://packages.microsoft.com/keys/microsoft.asc | apt-key add - && \
echo "deb [arch=amd64] https://packages.microsoft.com/debian/10/prod buster main" > /etc/apt/sources.list.d/mssql.list && \
apt-get update && ACCEPT_EULA=Y apt-get install -y msodbcsql17 mssql-tools openssl && \
echo "[openssl]" > /etc/ssl/openssl.cnf && \
echo "default_bits = 4096" >> /etc/ssl/openssl.cnf && \
echo "MinProtocol = TLSv1.2" >> /etc/ssl/openssl.cnf && \
echo "CipherString = DEFAULT:@SECLEVEL=1" >> /etc/ssl/openssl.cnf
# 设置中国时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone
# 复制文件到镜像
WORKDIR /app
COPY requirements.txt .
COPY packages/ ./packages/
COPY scripts/ ./scripts/
# 安装Python依赖
RUN pip install --no-index --find-links=./packages -r requirements.txt
# 创建日志目录并设置权限(root用户运行)
RUN mkdir -p /var/log/app && chmod 777 /var/log/app
# 配置环境变量(包含MSSQL工具路径)
ENV PATH="/opt/mssql-tools/bin:${PATH}" \
LANG=en_US.UTF-8 \
LC_ALL=en_US.UTF-8
# 保持root用户运行
USER root
2.构建及上传Docker镜像到私有仓库
# 切换到python/目录构建镜像
docker build -t python-scripts:3.6.8-v1 .
# 测试镜像是否可以正常运行,我镜像中有的脚本需要使用home目录,所以-v
docker run -it --rm -v /home:/home myregistry/python-scripts:3.6.8-v1 bash
# 给这个基础镜像打标签
docker tag c105d8d46380 registry.cn-hangzhou.aliyuncs.com/lik8s/other:python-scripts-3.6.8-v1
# 上传镜像到私有仓库
docker push registry.cn-hangzhou.aliyuncs.com/lik8s/other:python-scripts-3.6.8-v1
3.把这些文件全部拷贝到K8S集群的任意节点,K8S相关的yaml在后续编写,目前是空文件
4.编写持久化存储配置 (pvc.yaml)和CronJob配置(cronjob.yaml)
pvc.yaml
配置内容(使用bg-k8s-nfsdata的存储类,限额10G):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: scripts-data
namespace: python-cronjob
spec:
accessModes:
- ReadWriteMany
storageClassName: bg-k8s-nfsdata
resources:
requests:
storage: 10Gi
cronjob.yaml
配置内容(私有仓库地址,挂载home目录,设置定期执行,日志分类):
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: check-script
namespace: python-cronjob
spec:
schedule: "*/3 * * * *"
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
containers:
- name: check
image: registry.cn-hangzhou.aliyuncs.com/lik8s/other:python-scripts-3.6.8-v1
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- "mkdir -p /var/log/app/check && python3 /app/scripts/check >> /var/log/app/check/check.log 2>&1"
volumeMounts:
- name: host-home
mountPath: /home
- name: scripts-data
mountPath: /var/log/app/check
subPath: check
volumes:
- name: host-home
hostPath:
path: /home
type: Directory
- name: scripts-data
persistentVolumeClaim:
claimName: scripts-data
restartPolicy: OnFailure
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: autonetxj-script
namespace: python-cronjob
spec:
schedule: "5 8 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: autonetxj
image: registry.cn-hangzhou.aliyuncs.com/lik8s/other:python-scripts-3.6.8-v1
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- "mkdir -p /var/log/app/autonetxj && python3 /app/scripts/autonetxj >> /var/log/app/autonetxj/autonetxj.log 2>&1"
volumeMounts:
- name: host-home
mountPath: /home
- name: scripts-data
mountPath: /var/log/app/autonetxj
subPath: autonetxj
volumes:
- name: host-home
hostPath:
path: /home
type: Directory
- name: scripts-data
persistentVolumeClaim:
claimName: scripts-data
restartPolicy: OnFailure
---
5.部署服务
# 切换到yaml文件所在的目录,执行部署命令
kubectl apply -f pvc-scripts.yaml
kubectl apply -f cronjobs.yaml
# 如果运行不正常可以删除改一下脚本再执行部署
kubectl delete -f cronjobs.yaml
# 可以查看是否正常的命令
kubectl get pod -A
kubectl describe pod 名称
日志目录:
最终效果图: