用sftp在K8S管理OSS

2022/7/10 k8sDevops

这篇笔记是转载的我们组长写的 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
1
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
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

这个配置项会被挂载到/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
1
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
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).
image.png

这个问题是因为 ossfs-and-bindmount.sh  无执行权限造成的,上面配置文件的这部分

volumes:
  - configMap:
  # sftp.d 下面的脚本必须有可执行权限
  defaultMode: 0755
  name: sftp.d
  name: volume-sftp-d
1
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  里指定的账号和密码,可以登录

Last Updated: 2022/8/30 下午6:11:52