EX. 任务背景
近期接到一个需求是在一个高性能服务器上,模拟启动多个待测试客户端的场景,但这个客户端程序有点特殊,设置了守护模式
,并且需要管理员权限会监控系统的/dev/mem
节点,单个环境中只能启动一个。
当前的测试方式:
无奈目前的方式是利用VM技术,在服务器上启动多个虚拟机,每个虚拟机里按照一个客户端,但这样的效果极其效率低下,无法满足需求。
尝试使用的技术:
直接用VM虚拟机开销太大了,那么在一个服务器中,直接使用docker镜像,启动多个镜像的方式,或许可以有效,对于网络来说,docker其实本身会将多个容器进行网络管理,并且MAC地址也会进行分配。只要制作好一个带有待测客户端的docker镜像,那么整体上来说问题就解决了。这个方式,实际上比VM虚拟机来说,开销会小很多,因为实际上整体占用的空间只会比待测客户端多个占用的稍微多一点,而不会是N个虚拟机环境。那么下面开干吧。
A. 先在服务器中安装一个centos7的虚拟机,这个虚拟机是为了安装docker的运行环境
在CentOS系统中安装Docker的步骤如下(适用于 CentOS 7 或更高版本):
- 卸载旧版本(如有)
sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
- 安装依赖工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
- 添加Docker官方仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
- 安装Docker引擎
sudo yum install -y docker-ce docker-ce-cli containerd.io
- 启动Docker服务并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker
- 验证安装是否成功
sudo docker run hello-world
如果看到 Hello from Docker! 的输出,说明安装成功。
- (可选)配置非root用户运行Docker
将当前用户加入 docker 用户组,避免每次使用 sudo:
sudo usermod -aG docker $USER
newgrp docker # 立即生效或重新登录系统
其他注意事项
• CentOS 8 用户:如果遇到依赖问题,可能需要启用 PowerTools 仓库:
sudo dnf config-manager --set-enabled PowerTools
• 镜像加速:国内用户可配置Docker镜像加速器(如阿里云、腾讯云等)。
如果遇到问题,请检查网络连接或参考 Docker官方文档。
B. 再在centos7的虚拟机中使用docker开始制作
先熟悉几个命令
docker ps # 查看当前运行的容器
docker ps -a # 查看所有容器
docker images # 查看镜像
docker run # 运行容器
docker exec # 进入容器
docker stop # 停止容器
docker rmi $(docker images -q) # 删除所有镜像
docker rm -f $(docker ps -a -q) # 强制删除所有容器
接着就是制作镜像了,我们要保证在制作镜像的当前目录下有一个Dockerfile
文件,这个文件是用来制作镜像的。另外还需要一个start
文件,这个文件是用来启动容器的。最后我们还要有一个安装包文件,这个文件是直接从平台下载的离线安装包。一般是叫类似这样的名字linux_agent_setup_wojiubugaosuni.tar.gz
有了这三个文件后,我们就可以在当前目录下运行这个命令了
docker build --no-cache -t my-app .
这个命令的意思是,我们要制作镜像是基于当前目录下的Dockerfile
文件制作的。–no-cache是指我们要制作镜像的时候,不要使用缓存,这样可以保证我们制作的镜像是最新的。-t是指我们要制作镜像的时候,要给镜像起一个名字,这个名字是my-app
。
这里附加上我们的Dockerfile
文件的内容
# 使用CentOS 7存档镜像
FROM docker.m.daocloud.io/centos:7# 设置维护者信息(可选)
LABEL maintainer="adamxiao@wojiubuhaosuni.com"# 切换为 root 用户
USER root# 修复镜像源问题 (使用验证过的归档配置)
RUN sed -i 's|^mirrorlist=|#mirrorlist=|g' /etc/yum.repos.d/CentOS-* && \sed -i 's|^#baseurl=http://mirror.centos.org|baseurl=https://vault.centos.org|g' /etc/yum.repos.d/CentOS-*# 创建目标目录
RUN mkdir -p /app# 将本地的tar.gz压缩包添加到镜像中(自动解压)
COPY linux_agent_setup_wojiubugaosuni.tar.gz /app/
ADD start /app/# 设置工作目录
WORKDIR /app# 安装必要的解压工具
RUN yum clean all && \yum makecache
RUN yum install -y tar gzip which sudo && \yum clean all# 确保脚本可执行并立即执行安装
RUN cd /app && \
tar --no-same-permissions --no-same-owner -zxvf linux_agent_setup_wojiubugaosuni.tar.gz && chmod +x install.sh && ./install.sh
# 确保启动脚本能执行
RUN chmod +x /app/start# 设置容器启动时的默认命令(可根据需要调整)
CMD ["sh", "/app/start"]
由于centos7不再维护了,所以官方源更新会报错,直接用root运行以下指令可以解决问题,本质是换到了缓存源上。
sed -i 's|^mirrorlist=|#mirrorlist=|g' /etc/yum.repos.d/CentOS-* && \sed -i 's|^#baseurl=http://mirror.centos.org|baseurl=https://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
C. 制作镜像完成后,我们就可以运行容器了
由于我们已经制作完成了镜像,所以我们只需要运行容器即可。制作之前我们查查看镜像是不是做好了。
(base) adamxiao@ljj$docker images [5/05/25| 9:41下午]
REPOSITORY TAG IMAGE ID CREATED SIZE
my-app latest 956b04bd5dea 8 minutes ago 1.11GB
可以看到我们的镜像已经做好了,我们只需要运行容器即可。
(base) adamxiao@ljj$ docker run -itd --name cdg my-app
这个命令我们稍微讲解一下,-itd是指我们运行容器的方式,-i是指我们运行容器的方式,-t是指我们运行容器的方式,-d是指我们运行容器的方式,–name是指我们运行容器的名称,my-app是指我们运行容器的镜像名称。
这里一定要注意,我们后续要启动多个镜像,每个容器的名字一定不要一样,这个名字虽然只是一个代号,但一定不要是一个名字
我们可以使用docker ps命令查看容器是否运行成功。
(base) adamxiao@ljj$docker ps [5/05/25| 9:42下午]
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c4a9fe08e07d my-app "/bin/bash -i" 7 minutes ago Up 7 minutes cdg
看到了有一个容器起来了,说明我们是已经成功了。
后面我们可以写一个批量启动5个容器的脚本
# !/bin/bash# 定义镜像名称image_name="my-app"# 定义容器名称前缀container_name_prefix="jiubushuo"# 定义要启动的容器数量num_containers=5# 循环启动容器, 这里新增memory和cpu的限制,并且restart设置为on-failure,这样如果容器崩溃了,会自动重启。后续对于内存的限制可以酌情调节for (( i=1; i<=$num_containers; i++ ))
docontainer_name="${container_name_prefix}${i}"echo "Starting container: $container_name"docker run -itd \--memory=100m \--memory-swap=1g \--privileged=true \--cpus="0.25" \--restart=on-failure \--name $container_name $image_name
done
保存为start_containers.sh
文件,然后运行:
bash start_containers.sh
让我们来看看5个容器是不是都启动好了,我们可以使用docker ps命令查看容器是否运行成功。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
df7465563479 my-app "sh /app/start" 3 seconds ago Up 1 second jiubushuo5
d38a99720511 my-app "sh /app/start" 3 seconds ago Up 2 seconds jiubushuo4
69304f1b213a my-app "sh /app/start" 3 seconds ago Up 2 seconds jiubushuo3
ea1d717052fa my-app "sh /app/start" 4 seconds ago Up 3 seconds jiubushuo2
b2da0190729f my-app "sh /app/start" 4 seconds ago Up 3 seconds jiubushuo1
容器都启动好了,没问题了。
D. 最后我们可以使用docker exec命令进入容器,然后查看客户端运行情况
我们可以使用docker exec命令进入容器,然后查看客户端运行情况。
(base) adamxiao@ljj$docker exec -it jiubushuo1 /bin/bash
进入容器后,我们可以使用ps -aux 查看我们的客户端是否正常运行。
[root@b2da0190729f app]# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 3480 2276 pts/0 Ss 15:50 0:00 sh /app/start
root 19 0.7 0.8 2876872 68152 pts/0 Sl 15:50 0:00 /usr/local/agent_service
root 26 0.0 0.0 3740 2604 pts/0 S+ 15:50 0:00 /bin/bash -i
root 57 0.0 0.1 22368 15428 pts/0 S 15:50 0:00 /usr/local/agent_daemon
root 186 0.3 0.0 3740 2688 pts/1 Ss 15:51 0:00 /bin/bash
root 200 0.0 0.0 7812 2984 pts/1 R+ 15:51 0:00 ps -aux
可以看到我们的客户端目前正常运行。
我们使用exit命令退出容器。
exit
SOMETHING TODO
其实待测客户端当时因为特权原因,在docker环境中使用的不太好,但是研发并不想进一步调试了,所以这件事情作罢了。但理论上给docker启动的时候,增加--privileged=true
是能解决这个问题的,可惜后面没环境能测试这个事儿了。