以前一直不知道如何通过外部向Kubernetes进行通信,通过拉取Docker Hub上别人的Docker镜像部署到k8s自己也不知道该如何调用,Docker Hub上也很少有关于镜像的说明,于是查阅资料自己进行了从源代码-镜像构建-部署-外部访问的全流程。
实例应用的功能是从外部向k8s传入一个包含若干组数据的CSV文件,文件的数据包含0~5,6种分类,以及数据的内容,k8s中部署的应用对文件里的数据进行分类并统计,然后返回我结果。以下是代码:
Python源代码:
from flask import Flask, request, jsonify
import pandas as pd
from werkzeug.utils import secure_filename
import os
app = Flask(__name__)
UPLOAD_FOLDER = '/app/uploads'
ALLOWED_EXTENSIONS = {'csv'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return jsonify({'error': 'No file part'})
file = request.files['file']
if file.filename == '':
return jsonify({'error': 'No selected file'})
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(file_path)
counts = process_file(file_path)
return jsonify(counts)
return jsonify({'error': 'File type not allowed'})
def process_file(file_path):
data = pd.read_csv(file_path)
counts = data['Type'].value_counts().to_dict()
return counts
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8001)
Dockerfile:
Dockerfile直接保存成名为"Dockerfile"的文件在本地Python项目根目录即可
# 使用官方 Python 运行时作为基础镜像
FROM python:3.8-slim
# 设置工作目录
WORKDIR /app
# 创建上传目录
RUN mkdir /app/uploads && chown -R www-data:www-data /app/uploads
# 将当前目录内容复制到容器的 /app 目录
COPY . /app
# 使用 pip 命令安装任何需要的包
RUN pip install --no-cache-dir -r requirements.txt
# 对外暴露端口 8001
EXPOSE 8001
# 定义环境变量
ENV PORT 8001
# 运行 app.py 当容器启动时
CMD ["python", "./k8s_CSV_processor.py"]
生成“requirements.txt”文件:
可以使用“pipreqs”命令在本地Python项目根目录生成,pipreqs没有可能需要简单安装
pipreqs .
因为我使用的是minikube构建的集群,在生成Docker镜像时没有远程上传到Docker Hub而是选择本地部署,但是需要生成的镜像在minikube环境中,用以下命令可以进入minikube环境
eval $(minikube -p minikube docker-env)
然后使用下面的命令构建你的Docker镜像,名字需要自己指定
docker build -t <your-image-name> .
现在我们有了Docker镜像,还需要使用一个yaml文件将这个镜像部署在我们的k8s上,下面是一个实例的yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: csv-processor-deployment
spec:
replicas: 1
selector:
matchLabels:
app: csv-processor
template:
metadata:
labels:
app: csv-processor
spec:
containers:
- name: csv-processor
image: k8s-csv-processor:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8001
---
apiVersion: v1
kind: Service
metadata:
name: csv-processor-service
spec:
type: LoadBalancer
selector:
app: csv-processor
ports:
- protocol: TCP
port: 8001
targetPort: 8001
在这个yaml文件所在的文件夹使用命令,即可部署。
kubectl apply -f <你的文件名>.yaml
(此部署默认前提已经开启了minikube)
通过命令获取服务的IP和端口号,即可通过curl将准备好的CSV文件发送给部署在k8s上的应用,并获得返回值。