SkillAgentSearch skills...

Devops

基于 python 3.9.13 + django 2.2.16 + channels 2.4.0 + celery 5.2.7 + ansible 2.9.14 + paramiko 2.6.0 + AdminLTE-3.0.0 实现的运维 devops 管理系统。

Install / Use

/learn @leffss/Devops
About this skill

Quality Score

0/100

Category

Operations

Supported Platforms

Universal

README

devops

基于 python 3.9.13 + django 2.2.16 + channels 2.4.0 + celery 5.2.7 + ansible 2.9.14 + AdminLTE-3.0.0 实现的运维 devops 管理系统。具体见 screenshots 文件夹中的效果预览图。 本人为运维工程师,非专业开发,项目各个功能模块都是现学现用,可能有的地方暂时没有考虑合理和性能的问题。

功能

看图。

预览

效果 效果 效果 效果 效果 效果 效果 效果 效果 效果 效果 效果 效果 效果 效果 效果 效果 效果 效果 效果 效果 效果 效果

部署安装

kubernetes(k8s) 集群部署

适合有 k8s 集群安装部署维护经验的同学,大概步骤:

  1. 准备完整 k8s 集群

  2. 根据根目录 Dockerfile 与 Dockerfile-nginx 文件打包镜像到集群 node 节点

  3. 替换 k8s-deploy/settings.py 文件配置到 devops/settings.py

  4. 根据 k8s 集群实际情况修改所有 yaml 参数配置

  5. 依次 kubectl apply 目录 01-mysql 、02-redis、03-guacd、04-init-job

  6. kubectl apply 目录 k8s-deploy 下所有 yaml 文件

全部服务启动正常后访问 ingress 设置域名

此部署方式在本人 k8s v1.19.9 集群上测试正常,不保证其他版本兼容性。且只做测试用。

物理机安装

环境:Centos 7.5,python 3.7.9,docker 1.13.1,项目目录为 /home/workspace/devops

1. 安装依赖

yum install -y epel-release
yum install -y gcc sshpass python3-devel mysql-devel
  • ansible 连接插件 connection 使用 ssh 模式(还可以使用 paramiko 等模式)并且密码连接主机时需要使用 sshpass
  • python3-devel 与 mysql-devel 为 mysqlclient 库的依赖
  • 不建议使用 pymysql 代替 mysqlclient ,因为 pymysql 为纯 python 编写的库,性能较低

2. 安装 mysql(docker 方式)

docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 mysql:5.7.31

# 创建数据库并授权
docker exec -it mysql /bin/bash
mysql -uroot -p
create database devops default character set utf8mb4 collate utf8mb4_unicode_ci;
grant all privileges on devops.* to 'devops'@'%' identified by '123456';
flush privileges;

3. 安装 redis(docker 方式)

docker run --name redis-server -p 6379:6379 -d redis:6.0.8
  • channels、缓存、celery以及 session 支持所需,必须

4. 安装 guacd(docker 方式)

docker run --name guacd -e GUACD_LOG_LEVEL=info -v /home/workspace/devops/media/guacd:/fs -p 4822:4822 -d guacamole/guacd:1.1.0
  • rdp 与 vnc 连接支持所需,非必须
  • rdp 必须设置为允许运行任意版本远程桌面的计算机连接(较不安全)(L)才能连接,也就说目前暂不支持 nla 登陆方式
  • -v /home/workspace/devops/media/guacd:/fs 挂载磁盘,用于远程挂载文件系统实现上传和下载文件

5. 安装 python 依赖库

# 创建python虚拟环境
python -m venv venv

# 加载python虚拟环境,特别注意:后面的步骤均在此虚拟环境下运行
source venv/bin/activate

# 安装相关库
pip3 install -i https://mirrors.aliyun.com/pypi/simple -r requirements.txt
  • -i 指定阿里源,速度飞起

6. 修改 devops/settings.py 配置

相关配置均有注释,根据实际情况修改。默认数据库使用的是 sqlite3,如果需要使用 mysql,方法如下:

修改 devops/settings.py 中的 DATABASES 配置为:

DATABASES = {
    'default': {
        #'ENGINE': 'django.db.backends.mysql',
        'ENGINE': 'db_pool.mysql',     # db_pool.mysql 重写了 django 官方 mysql 连接库实现了真正的连接池
        'NAME': 'devops',
        'USER':'devops',
        'PASSWORD':'devops',
        'HOST':'127.0.0.1',
        'PORT':'3306',
        # 'CONN_MAX_AGE': 600,    # 如果使用 db_pool.mysql 绝对不能设置此参数,否则会造成使用连接后不会快速释放到连接池,从而造成连接池阻塞
        # 数据库连接池大小,mysql 总连接数大小为:连接池大小 * 服务进程数
        'DB_POOL_SIZE': 3,     # 默认 5 个
        'OPTIONS': {
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
         },
    }
}
  • 相关数据库(不需创建表)与账号必须事先在 mysql 数据库中创建好并授权。

7. 迁移数据库

# 删除可能存在的开发环境遗留数据
sh delete_makemigrations.sh
rm -f db.sqlite3

# 数据库迁移,创建表
python3 manage.py makemigrations
python3 manage.py migrate

8. 初始化数据

python3 manage.py loaddata initial_data.json
python3 init.py
  • initial_data.json 为权限数据
  • init.py 创建超级管理员 admin 以及部分测试数据,可根据实际情况修改

9. 启动相关服务

rm -rf logs/*

export PYTHONOPTIMIZE=1		# 解决 celery 不允许创建子进程的问题

nohup celery -A devops worker -l info -c 5 --max-tasks-per-child 200 --prefetch-multiplier 10 --pidfile logs/celery_worker.pid > logs/celery_worker.log 2>&1 &

nohup celery -A devops beat -l info --pidfile logs/celery_beat.pid > logs/celery_beat.log 2>&1 &

nohup python3 manage.py sshd > logs/sshd.log 2>&1 &

nohup daphne -b 0.0.0.0 -p 8001 --access-log=logs/daphne_access.log devops.asgi:application > logs/daphne.log 2>&1 &

nohup gunicorn -c gunicorn.py devops.wsgi:application > logs/gunicorn.log 2>&1 &
  • gunicorn 处理 http 请求,监听 8000 端口
  • daphne 处理 websocket 请求,监听 8001 端口
  • sshd 为 ssh 代理服务器,监听 2222 端口,提供调用 securecrt、xshell、putty 以及 winscp 客户端支持,非必须
  • celery 后台任务处理进程,export PYTHONOPTIMIZE=1 此环境变量非常重要,不设置无法后台运行 ansible api
  • celery_beat 定时任务处理进程,读取 devops/settings.py 中设置的 CELERY_BEAT_SCHEDULE 定时任务,详见 v1.8.8 升级日志
  • 需要停止时 kill 相应的进程,然后删除 logs 目录下所有的 pid 文件即可

10. 配置 nginx 前端代理

yum install -y nginx
  • 为了方便,就不编译安装,直接 yum 安装,版本为 nginx-1.20.1-9.el7.x86_64

修改 nginx 配置 /etc/nginx/nginx.conf 如下:

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

# base on nginx-1.20.1-9.el7.x86_64

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log error;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
    accept_mutex on;
    use epoll;
}
http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$server_name" $server_port';

    # 日志不立即写入磁盘,提高性能
    access_log  /var/log/nginx/access.log  main buffer=32k flush=1m;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   30;
    types_hash_max_size 2048;
    server_tokens  off;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    gzip on;
    gzip_min_length 2k;
    gzip_comp_level 4;
    gzip_types text/css text/xml image/gif image/jpeg application/javascript application/rss+xml text/plain image/png image/tiff image/x-icon image/x-ms-bmp image/svg+xml application/json;
    gzip_vary on;
    gzip_buffers 4 16k;
    # gzip_http_version 1.0;

	upstream wsgi-backend {
		ip_hash;
		server 127.0.0.1:8000 max_fails=3 fail_timeout=0;
	}

	upstream asgi-backend {
		ip_hash;
		server 127.0.0.1:8001 max_fails=3 fail_timeout=0;
	}

	server {
        listen 80 default_server;
		listen [::]:80 default_server;
		server_name  _;
		client_max_body_size 30m;
		add_header X-Frame-Options "DENY";
		
		location ~* ^/(media|static) {
			root /home/workspace/devops;   # 此目录根据实际情况修改
			# expires 30d;
			if ($request_filename ~* .*\.(css|js|gif|jpg|jpeg|png|bmp|swf|svg)$)
			{
				expires 7d;
			}
		}

		location /ws {
			try_files $uri @proxy_to_ws;
		}

		location @proxy_to_ws {
			proxy_pass http://asgi-backend;
			proxy_http_version 1.1;
			proxy_set_header Upgrade $http_upgrade;
			proxy_set_header Connection "upgrade";
			proxy_redirect off;
			proxy_set_header Host $host;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Forwarded-Proto $scheme;
			proxy_set_header X-Forwarded-Port $server_port;
			proxy_set_header X-Forwarded-Host $server_name;
			proxy_intercept_errors on;
			recursive_error_pages on;
		}

		location / {
			try_files $uri @proxy_to_app;
		}

		location @proxy_to_app {
			proxy_pass http://wsgi-backend;
			proxy_http_version 1.1;
			proxy_redirect off;
			proxy_set_header Host $host;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header X-Forwarded-Proto $scheme;
			proxy_set_header X-Forwarded-Port $server_port;
			proxy_set_header X-Forwarded-Host $server_name;
			proxy_intercept_errors on;
			recursive_error_pages on;
		}

		location = /favicon.ico {
				 access_log off;    #关闭正常访问日志
		}

		error_page 404 /404.html;
		location = /404.html {
			root   /usr/share/nginx/html;
			if ( $request_uri ~ ^/favicon\.ico$ ) {    #关闭favicon.ico 404错误日志
				access_log off;
			}
		}

		error_page 500 502 503 504 /50x.html;
		location = /50x.html {
			root   /usr/share/nginx/html;
		}
	}
}
  • 建议生产环境使用 https 方式,并开启 http2 与 Brotli 压缩(一种比 gzip 更好的压缩方案),具体方法不表, 可以参考根目录下的 make_nginx.shnginx.conf

启动 nginx:

systemctl start nginx
  • 启动前建议先检查下配置是否正确:nginx -t

11. 访问首页:http://127.0.0.1

初始超级管理员:

账号: admin 密码:123456

已知问题或者不足

  1. 代码的质量以我现在的眼光来看都太差了,但是这个项目的初衷也只是学习而已,也就没有动力重构优化了。

  2. web 终端(包括 webssh,webtelnet)在使用 chrome 浏览器打开时,很大机率会出现一片空白无法显示 xterm.js 终端的情况。 解决方法是改变一下 chrome 窗口大小就好了,在 firefox 下也有无此问题,但出现的机率小一些,具体原因未知。

  3. 关于使用 vue 做前后端分离,这肯定是以后的趋势,但是由于个人时间精力的问题,只能是慢慢来吧。

  4. 数据权限是有一点小问题的,在某些特定的情况下会越权,细心的同学可以在代码中发现。

  5. webssh 使用 zmodem 上传下载还有很多可以优化的地方,可以参考我的 go 项目 gowebssh

  6. webrdp 下载文件也还可以优化。

升级日志

ver2.2.5

修正优化物理机部署步骤;

redismultibeat 新增 RedisBeatManager 类(beat 任务管理),并修正动态修改 beat 任务无效问题;

升级部分依赖:

  • celery 4.4.7 到 5.2.7;
  • eventlet 0.23.0 到 0.33.1;
  • greenlet 0.4.16 到 1.1.2;
  • gevent 1.4.0 到 21.12.0;

ver2.2.4

新增 k8s 集群部署方式;

ver2.2.3

修复部分 linux 发行版 webssh 使用 sz 无法连续下载文件的问题;

ver2.2.2

优化 supervisord 日志输出配置;

修正 ‘日志审计 - 操作日志’ 中无法按类型排序的问题;

ver2.2.1

新增 celery beat 定时任务自动清除数据库历史数据,详见 devops/settings.py 相关设置;

ver2.2.0

升级 webguacamole,支持设置 AD 域账号以及设置多种验证方式(any、rdp、tls、nla、nla-ext);

升级部分依赖:

  • celery 4.3.0 到 4.4.7;
  • channel 2.2.0 到 2.4.0;
  • channel-redis 2.4.0 到 3.1.0;
  • daphne 2.3.0 到 2.5.0;
  • pyasn1 0.4.3 到 0.4.8;
  • cryptography 2.7 到 2.8;
  • gunicorn 20.0.3 到 20.0.4;
  • supervisor 4.1.0 到 4.2.1;
  • redis 3.3.11 到 3.5.3;
  • django-redis 4.10.0 到 4.12.1;
  • requests==2.22.0 到 2.24.0;
  • jsonpickle 1.2 到 1.4.1;
  • gssapi==1.6.2 到 1.6.9;
  • django-cachalot 2.3.1 到 2.3.2;
  • ansible 2.9.2 到 2.9.14;

ver2.1.1

修正 greenlet 与 gunicorn

Related Skills

View on GitHub
GitHub Stars363
CategoryOperations
Updated3d ago
Forks147

Languages

JavaScript

Security Score

100/100

Audited on Mar 23, 2026

No findings