背景:由于slurm的server和client的版本只兼容相差一个版本,导致宿主机跟docker容器始终存在版本兼容的问题,现在的设计是,由docker容器执行slurm的时候直接利用ssh连接宿主机,从而让两个环境slurm始终保持一致。
一、宿主机的准备工作
1.生成ssh的公钥和私钥
ssh-keygen -t rsa
一路回车下去,不用设置密码,最后生成的公钥私钥在~/.ssh/目录下:
2.在当前目录把公钥(也就是id_rsa.pub)文件放入authorized_keys里,目的是实现无密码登陆(底下会贴原理图):
cat id_dsa.pub >> authorized_keys
3.这个私钥是要传入进docker的,因为这是一套密钥,只有保证是一套密钥,才能实现ssh的连接。贴个原理图:
二、docker镜像制作
1.基础镜像我选的是alpine的python2.7,要安装Prometheus,openssh,paramiko等等...
下面是dockerfile:
FROM python:2.7-alpine as builder
# construct the virtualenv
ADD requirements.txt requirements.txt
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk --no-cache add alpine-sdk libffi-dev libressl-dev openssh-server && \
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple virtualenv && \
virtualenv /.venv
# installing libs
ADD requirements.txt requirements.txt
RUN /.venv/bin/pip install -r requirements.txt -f file:///lib_cache -i https://pypi.tuna.tsinghua.edu.cn/simple
# second stage
FROM python:2.7-alpine
ARG GIT_COMMIT=unspecified
LABEL git_commit=$GIT_COMMIT
COPY --from=builder /.venv /.venv
COPY --chown=root:root src /deploy/
#COPY entrypoint.sh /entrypoint.sh
ADD ./src /s_export
# add back the dependencies
# dockerhub.azk8s.cn
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
find /.venv/ -name *.so | \
xargs scanelf -n | \
awk 'NR>1 {print $2}' | \
tr ',' '\n' | \
sort | \
uniq | grep -v libpython | \
while read so; do echo so:$so; done | \
xargs apk --no-cache add sshpass openssh-client
CMD /.venv/bin/python /s_export/export.py
这个就是我之前的dockerfile实例改了一些地方,要注意的是整个环境都是在/.venv环境下配置的,所以最后CMD的时候要带上地址/.venv/bin/
。requirements
,这些都是paramiko自带的一些依赖:
bcrypt==3.1.7
cffi==1.13.1
cryptography==2.8
enum34==1.1.6
ipaddress==1.0.23
paramiko==2.6.0
prometheus-client==0.4.1
pyasn1==0.4.5
pycparser==2.19
PyNaCl==1.3.0
six==1.12.0
- paramiko里真正起作用的连接是:
client = SSHClient.connect(
hostname='127.0.0.1',
port=22,
username=USERNAME,
key_path='/home/fastone/.ssh/id_rsa'
)
注意:这里由于我是打算用docker run
的 --network host
起容器的,所以这里的hostname为127.0.0.1
,key_path是我写死的路径,到时候会-v
把宿主机的私钥映射到这个目录,username
就是你宿主机的用户名,到时可以通过-e
设置环境变量。
paramiko的使用可以参考我之前的文章:paramiko
注:不使用paramiko的小伙伴直接跳过这一步,镜像制作完成之后进入容器ssh连接宿主机就可以了。
3.运行容器。
镜像build完成之后:
这里的python
是我宿主机的用户名,这里不是填宿主机的hostname!
后面把私钥映射进去。
docker run -it --name sp_3 --network host -e USERTNAME='python' -v /home/python/.ssh/id_rsa:/home/fastone/.ssh/id_rsa xxxx(你的镜像名):latest
不使用paramiko的小伙伴,dockerfile最后一句不要加。docker起来容器之后docker exec
进入容器:
ssh 用户名@120.0.0.1
就行了。
以上!!