公共PyPi仓库上我们平时工作中经常使用的,可以解决我们大部分情况下分发包的需求。但公司的项目往往需要搭建一个私有的PyPi仓库来保证代码安全,以及防止私密信息无意泄漏。
本篇文章展示了在aws eks(即k8s)上搭建一个私有PyPi仓库的完整过程,并且编写一个demo包走完上传安装的流程。
pypiserver
pypiserver库,pypi的服务器实现,通过pip install pypiserver
安装。直接pypi-server
便可以启动起来,详细的参数参考 pypiserver文档, 常用参数:
- -P /pypi-server/auth/.htpasswd 该参数指定的apache htpasswd file,包含用来验证的用户名密码
- a update,download,list 逗号分隔,指定需要验证的动作
- p 端口号,默认8080 ./packages 指定包存储位置,可以指定多个目录
pypi-server -v -P /pypi-server/auth/.htpasswd -a update,download,list ./packages
其中.htpasswd是htpasswd -b -c /pypi-server/auth/.htpasswd user pass
生成
使用PyPi仓库
Demo包
创建setup.py文件
import setuptools
setuptools.setup(
name="demo",
version="0.0.1",
packages=setuptools.find_packages(),
)
另外创建一个demo.py文件
def demo():
print("this is a demo")
打包上传
python setup.py check
检测文件是否正确
python setup.py sdist
打包
twine upload -r kube dist/*
上传打包好的文件
其中kube可以直接使用http://user:pass@127.0.0.1:8080
, 或者交互式输入密码。
也可以在cat ~/.pypirc
文件中配置:
[distutils]
index-servers =
kube
[kube]
repository = http://127.0.0.1:8080
username = user
password = pass
浏览器打开http://127.0.0.1:8080,便可以看到刚才上传的包文件。
Kubernetes搭建
Dockerfile
FROM python:3.8-alpine
RUN apk update update \
&& apk add apache2-utils \
&& apk add bash \
&& mkdir /pypi-server
WORKDIR /pypi-server
RUN mkdir packages && mkdir auth
RUN python3 -m pip install pypiserver passlib
COPY ./docker_entry.sh /pypi-server
RUN chmod +rx ./docker_entry.sh
ENTRYPOINT ["/pypi-server/docker_entry.sh"]
EXPOSE 8080
同目录文件docker_entry.sh
#!/bin/bash
htpasswd -b -c /pypi-server/auth/.htpasswd $PYPI_USER $PYPI_PASS
pypi-server -v -P /pypi-server/auth/.htpasswd -a update,download,list ./packages
执行如下步骤:
1 docker build -t pypiserver . 编译镜像
2 docker tag pypiserver:latest user/pypiserver:v0.0.1
3 docker push user/pypiserver:v0.0.1 推送镜像到官方仓库
deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: pypiserver
labels:
app: pypiserver
spec:
// ...
spec:
nodeSelector:
标签对,因为使用hostPath来持久化,所以必须使用nodeSelector,指定pod所在主机
containers:
- name: pypiserver
image: user/pypiserver:v0.0.1
imagePullPolicy: Always
env:
- name: PYPI_USER
value: user
- name: PYPI_PASS
value: pass
volumeMounts:
- mountPath: '/pypi-server/packages'
name: pypi-packages
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 200m
memory: 512Mi
volumes:
- name: pypi-packages
hostPath:
path: /data/
secrets
用户名密码可以走secrets spec,对应yaml文件
apiVersion: v1
kind: Secret
metadata:
name: pypisecret
type: Opaque
stringData:
username: user
password: pass
简短说明
- PYPI_USER|PYPI_PASS这两个环境变量,参考
docker_entry.sh
文件,是用来生成htpasswd文件 - 由于pod或者说容器重新启动后,上传的包就不存在了,所以必须持久化,这里为了简单是用了 hostPath,可以根据自己情况选择具体持久化类型
gitlab上搭建
gitlab本身是具有各种语言共享库的功能:
Composer
Conan
Go
Maven
NPM
NuGet
PyPI
Generic packages
使用起来也很简单,只需要创建验证信息即可:
- 创建个人Token,scope设置为api
- 设置 ~/.pypirc:
[gitlab]
repository = https://gitlab.example.com/api/v4/projects/<project_id>/packages/pypi # https://gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypi
username = <your_personal_access_token_name>
password = <your_personal_access_token>
- 使用twine发布
python3 -m twine upload --repository gitlab dist/*