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
是能解決這個問題的,可惜后面沒環境能測試這個事兒了。