Skip to main content

在 K8S 中部署 vsftp 为业务提供上传支持

容器镜像选择

DockerHub 有一个 1000万以上 pull 量的 vsftpd 服务,该容器镜像实现了一个vsftpd服务器,具有以下特点:

  • Centos 7 基础镜像。
  • vsftpd 3.0
  • 虚拟用户
  • 被动模式
  • 记录到文件或STDOUT。

configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
name: demo-vsftpd-conf
namespace: demo
data:
vsftpd.conf: |
# Run in the foreground to keep the container running:
background=NO

# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
anonymous_enable=NO

# Uncomment this to allow local users to log in.
local_enable=YES

## Enable virtual users
guest_enable=YES

## Virtual users will use the same permissions as anonymous
virtual_use_local_privs=YES

# Uncomment this to enable any form of FTP write command.
write_enable=YES

## PAM file name
pam_service_name=vsftpd_virtual

## Home Directory for virtual users
user_sub_token=$USER
# 修改默认的 ftp 上传家目录
local_root=/data/appfile/upload_file

# You may specify an explicit list of local users to chroot() to their home
# directory. If chroot_local_user is YES, then this list becomes a list of
# users to NOT chroot().
chroot_local_user=YES

# Workaround chroot check.
# See https://www.benscobie.com/fixing-500-oops-vsftpd-refusing-to-run-with-writable-root-inside-chroot/
# and http://serverfault.com/questions/362619/why-is-the-chroot-local-user-of-vsftpd-insecure
allow_writeable_chroot=YES

## Hide ids from user
hide_ids=YES

## Enable logging
xferlog_enable=YES
xferlog_file=/var/log/vsftpd/vsftpd.log

## Enable active mode
port_enable=YES
connect_from_port_20=YES
ftp_data_port=20

## Disable seccomp filter sanboxing
seccomp_sandbox=NO

### Variables set at container runtime
pasv_address=169.254.1.1

# 开启被动端口
pasv_enable=true
pasv_max_port=30032
pasv_min_port=30022
pasv_addr_resolve=NO

# 设置文件权限 0777
file_open_mode=0777
local_umask=000
xferlog_std_format=NO
reverse_lookup_enable=YES
pasv_promiscuous=NO
port_promiscuous=NO

configmapvsftpd.conf 进行配置保存,通过挂在卷的形式挂载到容器的资源对象中。

deployment.yaml

需要提前准备好动态存储卷供给: PVC ftp-data

apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-ftp-server
namespace: demo
spec:
replicas: 1
selector:
matchLabels:
app: demo-ftp-server
template:
metadata:
labels:
app: demo-ftp-server
spec:
containers:
- name: demo-ftp-server
image: fauria/vsftpd
ports:
- containerPort: 21

# 30022 ~ 30032 为被动端口
- containerPort: 30022
- containerPort: 30023
- containerPort: 30024
- containerPort: 30025
- containerPort: 30026
- containerPort: 30027
- containerPort: 30028
- containerPort: 30029
- containerPort: 30030
- containerPort: 30031
- containerPort: 30032
env:

# 初始化一个用户
- name: FTP_USER
value: "admin"
- name: FTP_PASS
value: "admin"
resources:
requests:
cpu: 0.1
memory: 100Mi
limits:
cpu: 0.1
memory: 100Mi
volumeMounts:
- mountPath: /data
name: ftp-data
- mountPath: /etc/vsftpd/vsftpd.conf
name: vsftpd-config
subPath: vsftpd.conf


# 分别对 pvc configmap 进行挂载
volumes:
- name: ftp-data
persistentVolumeClaim:
claimName: ftp-data
- name: vsftpd-config
configMap:
name: demo-vsftpd-conf

service.yaml

将管理端口21 ,被动端口 30022~30032 以 NodePort 的形式进行暴露

apiVersion: v1
kind: Service
metadata:
name: demo-ftp-server
namespace: demo
spec:
type: NodePort
ports:
- name: ftp
port: 21
targetPort: 21
nodePort: 30021
- name: pasv-port-30022
port: 30022
targetPort: 30022
nodePort: 30022
- name: pasv-port-30023
port: 30023
targetPort: 30023
nodePort: 30023
- name: pasv-port-30024
port: 30024
targetPort: 30024
nodePort: 30024
- name: pasv-port-30025
port: 30025
targetPort: 30025
nodePort: 30025
- name: pasv-port-30026
port: 30026
targetPort: 30026
nodePort: 30026
- name: pasv-port-30027
port: 30027
targetPort: 30027
nodePort: 30027
- name: pasv-port-30028
port: 30028
targetPort: 30028
nodePort: 30028
- name: pasv-port-30029
port: 30029
targetPort: 30029
nodePort: 30029
- name: pasv-port-30030
port: 30030
targetPort: 30030
nodePort: 30030
- name: pasv-port-30031
port: 30031
targetPort: 30031
nodePort: 30031
- name: pasv-port-30032
port: 30032
targetPort: 30032
nodePort: 30032
selector:
app: demo-ftp-server

客户端连接

客户端通过 ftp://NodePort:30021 进行连接。

参考文档