之前介绍过一个灵活多变功能强大的开源CMDB系统,设计精巧,可玩性高,经过一段时间的深度使用,发现了许多可取之处,无论是构建系统内部的资产管理数据库,还是学习它的设计方式都有不少的可取之处,接下来我准备写一系列的文章来系统的介绍一下它,从使用到设计,全面深入了解下
这个系列第一篇就从部署开始,详细介绍下VECMDB的安装、启动、访问以及系统的详细管理方式和常见错误的处理等
在开始之前你只需要准备一台主机,Linux或MacOS系统,只要能安装docker即可。以下操作环境基于CentOS7
1.更新系统包
yum update -y
2.安装必要的依赖
yum install -y yum-utils
3.添加 Docker 的官方存储库
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
4.安装 Docker 引擎
yum install -y docker-ce docker-ce-cli containerd.io
5.启动 Docker 并将其设置为开机启动
systemctl start docker
systemctl enable docker
1.安装 Docker Compose 插件
yum install -y docker-compose-plugin
2.验证 Docker Compose 是否安装成功
docker compose version
yum install git
1.创建项目目录
mkdir /data
cd /data
2.拉项目代码并启动
git clone https://github.com/veops/cmdb.git
cd cmdb/
docker compose up -d
浏览器打开,输入http://ip:8000
访问,默认账号密码分别为:
通过以上内容可以简单方便的部署起来VECMDB服务,但我们不仅要知其然还要知其所以然,以下这部分将会详细的讲解下CMDB的启动方式及各个服务,以及一些简单的排错方法,能更深入的了解VECMDB服务
Docker-Compose是一个用于定义和运行多容器Docker应用程序的工具。通过一个名为docker-compose.yml
的YAML文件,用户可以配置应用程序所需的所有服务。然后,只需一个命令就可以创建并启动这些服务。VECMDB是通过Docker-Compose做服务管理的,那首先我们就需要详细的了解下VECMDB的docker-compose.yml
配置文件,配置文件位于仓库的根目录,内容如下:
services: # 第一部分为服务定义
cmdb-db: # 定义了一个名为cmdb-db的服务
image: registry.cn-hangzhou.aliyuncs.com/veops/cmdb-db:2.3 # 镜像地址,MySQL数据库容器
container_name: cmdb-db # 容器名称为cmdb-db
env_file: # 从当前目录下的.env文件中加载环境变量
- .env
environment: # 环境变量配置
TZ: Asia/Shanghai # 配置时区为Asia/Shanghai
volumes: # 挂载三个卷
- db-data:/var/lib/mysql # 第一个卷为db-data,用来持久化MySQL数据
- ./docs/mysqld.cnf:/etc/mysql/conf.d/mysqld.cnf # 本地配置文件mysqld.cnf挂载到MySQL配置目录
- ./docs/cmdb.sql:/docker-entrypoint-initdb.d/cmdb.sql # 初始化SQL文件cmdb.sql挂载到MySQL容器的初始化目录
healthcheck: # 健康命令检查,检查MySQL服务是否正常
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-p$MYSQL_ROOT_PASSWORD"] # 健康检查命令,检查MySQL服务是否正常
interval: 10s
timeout: 5s
retries: 5
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci # 设置MySQL字符集和排序规则
networks: # 网络配置,使用名字为new的自定义网络,同时设置别名为mysql
new:
aliases:
- mysql
ports: # 端口配置,将宿主机的23306端口映射到容器的3306端口
- '23306:3306'
cmdb-cache: # 定义一个名为cmdb-cache的服务
image: registry.cn-hangzhou.aliyuncs.com/veops/cmdb-cache:2.3 # 镜像地址,Redis缓存容器
container_name: cmdb-cache # 容器名称为cmdb-cache
environment: # 环境变量配置
TZ: Asia/Shanghai # 配置时区为Asia/Shanghai
volumes: # 挂载一个卷
- cache-data:/data # 卷为cache-data,用来持久化Redis数据
healthcheck: # 健康检查命令,检查Redis服务是否正常
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks: # 网络配置,使用名字为new的自定义网络,同时设置别名为redis
new:
aliases:
- redis
cmdb-api: # 定义一个名为cmdb-api的服务
image: registry.cn-hangzhou.aliyuncs.com/veops/cmdb-api:2.4.5 # 镜像地址,CMDB API容器
container_name: cmdb-api # 容器名称为cmdb-api
env_file: # 从当前目录下的.env文件中加载环境变量
- .env
environment: # 环境变量配置
TZ: Asia/Shanghai # 配置时区为Asia/Shanghai
WAIT_HOSTS: cmdb-db:3306, cmdb-cache:6379 # 配置WAIT_HOSTS用来等待cmdb-db和cmdb-cache服务健康后再启动
depends_on: # 定义依赖关系
cmdb-db: # 确保cmdb-db服务启动健康后再启动
condition: service_healthy
cmdb-cache: # 确保cmdb-cache服务启动健康后再启动
condition: service_healthy
command: # 多行启动命令
- /bin/sh
- -c
- |
sed -i "s#USE_ACL = False#USE_ACL = True#g" settings.py # 修改settings.py中的USE_ACL为True
/wait # 使用/wait脚本等待服务依赖启动
flask db-setup # 初始化数据库
flask common-check-new-columns # 检查数据库新列
gunicorn --workers=4 autoapp:app -b 0.0.0.0:5000 -D # 启动gunicorn服务
celery -A celery_worker.celery worker -E -Q one_cmdb_async --autoscale=4,1 --logfile=one_cmdb_async.log -D # 启动celery服务,队列one_cmdb_async
celery -A celery_worker.celery worker -E -Q acl_async --logfile=one_acl_async.log --autoscale=2,1 -D # 启动celery服务,队列acl_async
nohup flask cmdb-trigger > trigger.log 2>&1 &
flask cmdb-init-cache
flask cmdb-init-acl
flask init-import-user-from-acl
flask init-department
flask cmdb-counter > counter.log 2>&1 # 执行一系列的flash命令用来初始化系统
healthcheck: # 健康检查命令,检查API服务是否启动正常
timeout: 3s
interval: 5s
retries: 10
test: "ps aux|grep -v grep|grep -v '1 root'|grep gunicorn || exit 1"
networks: # 网络配置,使用名字为new的自定义网络,同时设置别名为cmdb-api
new:
aliases:
- cmdb-api
cmdb-ui: # 定义一个名为cmdb-ui的服务
image: registry.cn-hangzhou.aliyuncs.com/veops/cmdb-ui:2.4.5 # 镜像地址,CMDB UI容器
container_name: cmdb-ui # 容器名称为cmdb-api
depends_on: # 定义依赖关系
- cmdb-api # 确保cmdb-api服务启动成功后再启动
condition: service_healthy
environment: # 环境变量配置
TZ: Asia/Shanghai # 配置时区为Asia/Shanghai
CMDB_API_HOST: cmdb-api:5000 # CMDB_API_HOST指向到cmdb-api服务的地址
NGINX_PORT: 80 # 设置NGINX的端口为80
volumes: # 挂载一个卷
- ./docs/nginx.cmdb.conf.example:/etc/nginx/conf.d/nginx.cmdb.conf.example # 挂载本地的nginx配置文件
command: # 多行启动命令
- /bin/sh
- -c
- |
envsubst '$$CMDB_API_HOST $$NGINX_PORT' < /etc/nginx/conf.d/nginx.cmdb.conf.example > /etc/nginx/conf.d/cmdb.conf # 使用envsubst替换nginx配置文件中的环境变量
nginx -g 'daemon off;' # 启动nginx,使用daemon off模式,前台运行
networks: # 网络配置,使用名字为new的自定义网络
- new
ports: # 端口配置,将宿主机的8000端口映射到容器的80端口
- "8000:80"
volumes: # 第二部分为卷定义
db-data: # 定义一个db-data本地卷,用来持久化MySQL数据,cmdb-db容器使用
driver: local
name: cmdb_db-data
cache-data: # 定一个cache-data本地卷,用来持久化Redis数据,cmdb-cache容器使用
driver: local
name: cmdb_cache-data
networks: # 第三部分为网络定义
new: # 定义一个new桥接网络,用于各服务之间通信
driver: bridge
name: cmdb_network
总结以下就是启动了四个容器,分别是MySQL、Reids、后端API和前端UI,后端API启动前需要MySQL和Reids启动成功,而前端UI启动前需要后端API启动成功。定义了一个公共的网络保证四个容器之间可以互相通信,同时还定义了两个本地卷,保证MySQL和Reids数据的持久化,以确保容器在重启之后数据也不会丢失,对系统升级也十分友好
数据是持久化在宿主机上的本地卷里,本地卷的查看可以直接执行volume
命令,例如查看MySQL的本地卷,就可以用如下命令:
# docker volume inspect cmdb_db-data
[
{
"CreatedAt": "2024-06-03T17:59:36+08:00",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "cmdb",
"com.docker.compose.version": "2.27.0",
"com.docker.compose.volume": "db-data"
},
"Mountpoint": "/var/lib/docker/volumes/cmdb_db-data/_data",
"Name": "cmdb_db-data",
"Options": null,
"Scope": "local"
}
]
其中Mountpoint
就是数据在宿主机本地的挂载点,可以直接查看其中的数据
# ls /var/lib/docker/volumes/cmdb_db-data/_data/
auto.cnf ca-key.pem ca.pem client-cert.pem client-key.pem cmdb ib_buffer_pool ib_logfile0 ib_logfile1 ibdata1 ibtmp1 mysql performance_schema private_key.pem public_key.pem server-cert.pem server-key.pem sys
而Redis持久化在本地的数据也同样可以通过以上的方法查看
# docker volume inspect cmdb_cache-data
[
{
"CreatedAt": "2024-06-03T17:59:36+08:00",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "cmdb",
"com.docker.compose.version": "2.27.0",
"com.docker.compose.volume": "cache-data"
},
"Mountpoint": "/var/lib/docker/volumes/cmdb_cache-data/_data",
"Name": "cmdb_cache-data",
"Options": null,
"Scope": "local"
}
]
#
# ls /var/lib/docker/volumes/cmdb_cache-data/_data/
dump.rdb
只有一个rdb数据文件。如果你在部署时遇到数据方面的问题,可以通过以上方法来查看本地的数据,或是直接命令行进入MySQL或者Reids去检查数据,当然更多的时候可能是数据初始化问题,所以更为有效的方法或许是使用如下命令重启docker-compose服务
# 关闭docker compose服务
# docker compose down
# 启动docker compose服务
# docker compose up -d
# 可选:查看docker compose服务状态
# docker compose ps
# 可选:检查docker compose容器日志
# docker compose logs
docker-compose服务启动后,可以通过network
命令查看Docker的网络列表
# docker network ls
NETWORK ID NAME DRIVER SCOPE
17ec43fa34f8 bridge bridge local
5dd2f0dd8033 cmdb_network bridge local
75376eee7d8b host host local
deb75486f151 none null local
此时能看到一个名为cmdb_network
的网络,如果你遇到了网络连通性问题,例如API连不上数据库等等,可以通过network
命令查看网络的详细信息
# docker network inspect cmdb_network
[
{
"Name": "cmdb_network",
"Id": "5dd2f0dd8033f7c99d4a8e5371356b41e087c71eb9f35c4fdacaccdfa280e3d1",
"Created": "2024-06-12T13:42:35.923873631+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"176d8a248ecde36d46205e03ff19879cd2a6c6325e3e8622ca48033ae55a0e5b": {
"Name": "cmdb-api",
"EndpointID": "0619481c0a6241b445ea6daead002c39f82aae56ba77390b67d73779d56c7221",
"MacAddress": "02:42:ac:13:00:04",
"IPv4Address": "172.19.0.4/16",
"IPv6Address": ""
},
"3387071f980e26a399350f8a6fda0587edccb25319ec040945896228671616c4": {
"Name": "cmdb-db",
"EndpointID": "234d64c1858fb5933defe84b13aaf071426324959f0331abec4e1dd29c4c1a09",
"MacAddress": "02:42:ac:13:00:03",
"IPv4Address": "172.19.0.3/16",
"IPv6Address": ""
},
"a2df35da575fa289b4b2cc3dd0d7370c1003a47fe84b894a41751adef4d56dd4": {
"Name": "cmdb-ui",
"EndpointID": "a403699251326f92e391b4aa38f9d80cf14153053e4f2307d133b4ff9f167182",
"MacAddress": "02:42:ac:13:00:05",
"IPv4Address": "172.19.0.5/16",
"IPv6Address": ""
},
"aaf5d23ee24bd9719f9231369649fceac7a1fe8bb1bb9421ca12f35c3faade49": {
"Name": "cmdb-cache",
"EndpointID": "efe4eff06148e463a8b9a1af0ef15e81701e0bec39f9cfa25fb9613005b32148",
"MacAddress": "02:42:ac:13:00:02",
"IPv4Address": "172.19.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.docker.compose.network": "new",
"com.docker.compose.project": "cmdb",
"com.docker.compose.version": "2.27.0"
}
}
]
这里输出了网络的详细信息,包括网络的配置、连接到该网络到容器等等,其中的Containers
字段就记录了所有连接到此网络到容器,正常情况下会有四个,包含cmdb-db
、cmdb-cache
、cmdb-api
和cmdb-ui
,它们都被分配了合适的IP地址
如果以上都没有问题,那就可以通过docker命令查看到容器的状态都正常
# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
cmdb-api registry.cn-hangzhou.aliyuncs.com/veops/cmdb-api:2.4.5 "/bin/sh -c 'sed -i …" cmdb-api 10 minutes ago Up 10 minutes
cmdb-cache registry.cn-hangzhou.aliyuncs.com/veops/cmdb-cache:2.3 "docker-entrypoint.s…" cmdb-cache 10 minutes ago Up 10 minutes (healthy) 6379/tcp
cmdb-db registry.cn-hangzhou.aliyuncs.com/veops/cmdb-db:2.3 "docker-entrypoint.s…" cmdb-db 10 minutes ago Up 10 minutes (healthy) 33060/tcp, 0.0.0.0:23306->3306/tcp, :::23306->3306/tcp
cmdb-ui registry.cn-hangzhou.aliyuncs.com/veops/cmdb-ui:2.4.5 "/docker-entrypoint.…" cmdb-ui 10 minutes ago Up 10 minutes 0.0.0.0:8000->80/tcp, :::8000->80/tcp
最后就可以正常通过Web访问部署的CMDB服务了
前文的docker-compose.yml
配置文件中有配置从代码根目录下加载.env
文件内容作为环境变量,.env
文件主要记录了MySQL数据库配置信息,如下:
MYSQL_ROOT_PASSWORD='123456'
MYSQL_HOST='mysql'
MYSQL_PORT=3306
MYSQL_USER='cmdb'
MYSQL_DATABASE='cmdb'
MYSQL_PASSWORD='123456'
可以看到默认的账号密码比较简单,如果我们想要修改的话,最好在第一次初始化之前就修改.env
文件里的配置,这样的话在系统初始化时就会设置成新设置的账号密码,以提高系统安全性
若你已经初始化了系统,还想要再修改账号密码的话,那就只能进入MySQL数据库进行修改了,同时修改过之后也要同时修改.env
配置文件里的相关配置
数据库的配置记录在.env
配置文件中,先检查数据库配置和环境变量是否正确,其次确认数据库服务正常启动并能接受连接
# docker exec -it cmdb-db mysql -u root -p$MYSQL_ROOT_PASSWORD
最后检查自定义网络是否正常,通过之前给的network
命令
检查Redis服务是否正常运行并能接受连接
# docker exec -it cmdb-cache redis-cli ping
其次也是检查自定义网络状态
先检查以来的MySQL和Reids服务是否正常,然后检查是否能正常连通MySQL和Redis
# docker exec -it cmdb-api /bin/sh -c "ping cmdb-db"
# docker exec -it cmdb-api /bin/sh -c "ping cmdb-cache"
如果正常则检查API服务容器状态
# docker compose ps | grep cmdb-api
容器状态正常则检查gunicorn服务是否正常
# docker exec -it cmdb-api /bin/sh -c "ps aux|grep -v grep|grep -v '1 root'|grep gunicorn"
最后查看日志是否有报错
# docker compose logs cmdb-api
先确认依赖的API容器状态正常,然后检查依赖的API服务日志无报错,再然后检查是否能正常连通API容器
# docker exec -it cmdb-ui /bin/sh -c "ping cmdb-api"
如果都没有问题,则查看UI服务容器状态
# docker compose ps | grep cmdb-ui
最后查看nginx配置及容器日志是否有报错
# docker exec -it cmdb-ui /bin/sh -c "cd /etc/init.d && nginx -t"
# docker compose logs cmdb-ui
对于成熟的开源项目,只要不是刚刚更新的新版本,那大概率都已经经过了许多用户的实际验证,项目本身出现问题的概率较低,如果我们遇到错误先考虑自己的环境及配置,按照以上解决思路,大概率能找到问题并解决。如果不行的话那就重启下docker-compose服务,还不行的话就重装吧