这篇笔记是转载的我们组长写的 K8s 相关文章、仅用于个人学习。
本篇教程是教你如何用 rishiqing/sftp (opens new window) 这个 docker 镜像在 k8s 集群里搭建一个 sftp 服务器,同时基于这个 sftp 服务器里提供的 ossfs,来实现 sftp 管理阿里云的 OSS 的目的,这个镜像的 Dockerfile 在这里 https://github.com/rishiqing/dockerfile (opens new window),这个镜像是基于 https://hub.docker.com/r/atmoz/sftp (opens new window) 构建的
# 准备
新建一个命名空间,或者用已有的命名空间,我这里用的是 front
# 新建配置项
在这个命名空间下新建几个配置项,这个在下面启动 Deployment 的时候会用到
# sftp-users
apiVersion: v1
data:
# 这里还可以配置uid和gid,可以参考 https://hub.docker.com/r/atmoz/sftp 的配置方法
users.conf: 'username:123456:::upload'
kind: ConfigMap
metadata:
name: sftp-users
namespace: front
2
3
4
5
6
7
8
这个配置项里的 users.conf 是用来配置 sftp 的可访问账号,以及该账号的工作目录,像我上面这个配置,账号信息就是:
账号: username
密码: 123456
工作目录: /home/username/upload
这个 users.conf
最终会被挂载到 /etc/sftp/users.conf
# sftp.d
apiVersion: v1
data:
ossfs-and-bindmount.sh: |-
#! /bin/bash
# 这个脚本会在sftp服务启动的时候自动执行
# 只要是放在sftp.d下面的可执行脚本,都会在sftp启动的时候自动执行
# oss的基本配置
oss_dir="/tingkelai-front-oss"
oss_bucket="tingkelai-front"
# 挂载的时候, endpoint最好用内网地址,如果用外网,一是速度慢,二是很容易造成上传到oss的文件的content-type无法被正确设置.
oss_endpoint="http://oss-cn-hangzhou-internal.aliyuncs.com"
function bindmount() {
mkdir -p "$1"
chmod 777 -R "$1"
mkdir -p "$2"
mount --bind $3 "$1" "$2"
}
mkdir -p $oss_dir
# 在这里执行oss的挂载,必须提前在passwd-ossfs里配置相关的bucket以及秘钥
ossfs $oss_bucket $oss_dir -ourl=$oss_endpoint -oallow_other
# /home/username/upload 对应着sftp用户自己的工作目录
# 我们在这里用mount 把 $oss_dir/test 给挂载到 /home/username/upload 目录
# 这样就能实现用户用sftp处理文件的时候,实际上是在 $oss_dir/test 里处理文件,也即在oss里处理文件
bindmount $oss_dir/test /home/username/upload
kind: ConfigMap
metadata:
name: sftp.d
namespace: front
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
这个配置项会被挂载到/etc/sftp.d 文件夹,这个文件夹下面的所有可执行文件,会在 sftp 服务启动的时候自动执行.
这个配置项下面的 ossfs-and-bindmount.sh
就是一个可执行文件,用来挂载 oss 到对应的文件夹,同时把 sftp 用户的工作目录绑定到 oss 挂载的文件夹。具体 ossfs-and-bindmount.sh
这个文件做了什么,可以看里面的注释,写得很清楚.
# passwd-ossfs
apiVersion: v1
data:
passwd-ossfs: "bucket_name:accessKey:secretKey"
kind: ConfigMap
metadata:
name: passwd-ossfs
namespace: front
2
3
4
5
6
7
这个配置项下面的 passwd-ossfs
是用来存放 oss 对应 bucket 的访问秘钥的,具体参考 https://github.com/aliyun/ossfs (opens new window),可获得更加详细的说明. 这个文件会被挂载到 /etc/passwd-ossfs
文件上,同时必须注意这个文件的权限必须是 640,这个在 Deployment 的配置文件里需要把 defaultMode
设置为 0640
# 配置 Deployment
在 front 命名空间下启动一个 Deployment,配置文件如下:
apiVersion: apps/v1beta2
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: '5'
creationTimestamp: '2019-07-16T12:50:57Z'
generation: 5
labels:
app: sftp
name: sftp
namespace: front
resourceVersion: '33968155'
selfLink: /apis/apps/v1beta2/namespaces/front/deployments/sftp
uid: 5b055a01-a7c8-11e9-85aa-00163e13030d
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: sftp
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: sftp
spec:
containers:
- image: 'rishiqing/sftp:0.0.1'
imagePullPolicy: Always
name: sftp
resources:
requests:
cpu: 250m
memory: 128Mi
securityContext:
capabilities:
add:
- ALL
privileged: true
procMount: Default
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /etc/sftp.d
name: volume-sftp-d
- mountPath: /etc/sftp/users.conf
name: volume-sftp-users
subPath: users.conf
- mountPath: /etc/passwd-ossfs
name: volume-passwd-ossfs
subPath: passwd-ossfs
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- configMap:
# sftp.d 下面的脚本必须有可执行权限
defaultMode: 0755
name: sftp.d
name: volume-sftp-d
- configMap:
defaultMode: 0755
name: sftp-users
name: volume-sftp-users
- configMap:
# 这里需要注意, passwd-ossfs文件的权限必须是 640
defaultMode: 0640
name: passwd-ossfs
name: volume-passwd-ossfs
status:
availableReplicas: 1
conditions:
- lastTransitionTime: '2019-07-16T13:24:48Z'
lastUpdateTime: '2019-07-16T13:24:48Z'
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: 'True'
type: Available
- lastTransitionTime: '2019-07-16T12:50:57Z'
lastUpdateTime: '2019-07-16T13:24:48Z'
message: ReplicaSet "sftp-676749cf4d" has successfully progressed.
reason: NewReplicaSetAvailable
status: 'True'
type: Progressing
observedGeneration: 5
readyReplicas: 1
replicas: 1
updatedReplicas: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# 注意 1:
Deployment 启动之后,可能会报:
[/entrypoint] Could not run /etc/sftp.d/ossfs-and-bindmount.sh, because it's missing execute permission (+x).
这个问题是因为 ossfs-and-bindmount.sh
无执行权限造成的,上面配置文件的这部分
volumes:
- configMap:
# sftp.d 下面的脚本必须有可执行权限
defaultMode: 0755
name: sftp.d
name: volume-sftp-d
2
3
4
5
6
其中的 defaultMode
值为 0755,就默认有执行权限,加上这个值,就不会报上面的错了
# 注意 2:
还有就是需要注意 securityContext
,以及它下面的配置,,这部分是为了让 docker 获得主机的一些能力,比如 mount,如果不加这个,就无法执行 mount,那么 ossfs-and-bindmount.sh
里的 bindmount 方法就无法正常执行
Deployment 启动之后,如果一切正常,你可以进入到 pod 里,就可以在 /tingkelai-front-oss
文件夹下看到 oss 里的文件夹和文件了
# 对外暴露服务
sftp 会监听 22 端口,可以用 K8S 提供的 NodePort 等,进行正常的端口暴露即可,暴露之后,用 FileZilla
等 ftp 客户端,用上面在 users.conf
里指定的账号和密码,可以登录