qt通过http调用创建docker容器

首先需要在 linux 服务器部署 docker 服务,此类文章网上很多,可以参考 如何在 Ubuntu 20.04 上安装和使用 Docker 或者 ubuntu安装docker,安装完成后如果还想通过 http 正常调用,还需在 docker.service 文件中配置 -H tcp://0.0.0.0:2375

bash 复制代码
root@ros:/lib/systemd/system# pwd
/lib/systemd/system
root@ros:/lib/systemd/system# cat docker.service | grep ExecStart
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sock

再重启 docker 后,可通过 netstat命令查看服务是否正常开启。

bash 复制代码
root@ros:~# netstat -ntlp | grep docker
tcp6       0      0 :::2375          :::*             LISTEN      3283/dockerd

http 可调用的 api 可参考文档 Docker Engine API,本文主要实现 create container api 的调用。在调用之前,得确保服务器已经有载入镜像,可通过 docker images 指令查看:

bash 复制代码
root@ros:~# docker images 
REPOSITORY        TAG       IMAGE ID       CREATED      SIZE
test_image        tag1     20259e2caff6   2 days ago   5.17GB

这样就可以在参数中指定镜像创建容器:

cpp 复制代码
QJsonObject container_param;
container_param["Image"] = "test_image:tag1";

如果想设置容器的环境变量,可以给 env 传参:

cpp 复制代码
QJsonArray env;
QString env_id = QString("identifier=%1").arg(id);    // 设置业务上的唯一标识
QString env_zone = QString("TZ=Asia/Shanghai");    // 设置时区
env.append(env_id);
env.append(env_zone);
container_param["Env"] = env;

如果希望容器启动时执行特定脚本,可通过 cmd 参数:

cpp 复制代码
QJsonArray cmd;
cmd.append("/test.sh");
container_param["Cmd"] = cmd;

如果希望容器和宿主机做路径映射,可利用 hostconfig 下的 binds 参数:

cpp 复制代码
QJsonObject binds;
QJsonArray path;
QString task_path = QString("/usr/local/src:/home/lucas/src");
path.append(task_path);
QString log_path = QString("/opt/test/log:/home/lucas/log");
path.append(log_path);
binds["Binds"] = path;
container_param["HostConfig"] = binds;

这样,在容器内部的 /home/lucas/log 目录下的任何改动,宿主机的 /opt/test/log 目录也会同步更新。即使容器已销毁,日志仍然可在宿主机查看。

还有些标准输入输出、终端开启的相关参数可根据业务需要适当配置:

cpp 复制代码
container_param["AttachStdin"] = false;
container_param["AttachStdout"] = true;
container_param["AttachStderr"] = true;
container_param["Tty"] = true;
container_param["OpenStdin"] = true;

待需要参数都已赋值,最后可调用 create container api 开始创建容器:

cpp 复制代码
QJsonDocument doc(container_param);
QByteArray post_data = doc.toJson();

// url: http://127.0.0.1:2375/containers/create
QNetworkReply *reply = httpPost(url, post_data);

其中 httpPost() 方法可封装如下:

cpp 复制代码
QNetworkReply *HttpHelper::httpPost(const QString url, const QString post_data)
{
    QNetworkRequest request;
    request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
    request.setUrl(QUrl::fromUserInput(url));

    QNetworkReply *network_reply = m_networkMgr.post(request, post_data.toUtf8());
    QEventLoop event_loop;
    QObject::connect(network_reply, SIGNAL(finished()), &event_loop, SLOT(quit()));
    event_loop.exec();

    return network_reply;
}

如果正常,接口最终会返回一个 json 串,解析后可拿到 container id

bash 复制代码
{"Id":"0354238a43a38abfa2bf906a909ecedd411778c82fa017bf1b833b55ed2f3b50","Warnings":[]}

之后就可以调用 start container api 来启动容器:

bash 复制代码
http://127.0.0.1:2375/containers/0354238a43a3/start

这点也可通过在宿主机执行 docker ps 指令来进行验证。以上,欢迎交流~

相关推荐
奇树谦9 小时前
QT|windwos桌面端应用程序开发,当连接多个显示器的时候,如何获取屏幕编号?
开发语言·qt
athink_cn10 小时前
HTTP/2新型漏洞“MadeYouReset“曝光:可发动大规模DoS攻击
网络·网络协议·安全·http·网络安全
Agome9910 小时前
Docker之自定义jkd镜像上传阿里云
阿里云·docker·容器
无能百分百10 小时前
阿里云服务器ECS安装Docker(CentOS 7.x)
docker
Franklin12 小时前
Python界面设计【QT-creator基础编程 - 01】如何让不同分辨率图像自动匹配graphicsView的窗口大小
开发语言·python·qt
郝学胜-神的一滴13 小时前
深入理解QFlags:Qt中的位标志管理工具
开发语言·c++·qt·程序人生
deeper_wind14 小时前
k8s-单主机Master集群部署+单个pod部署lnmp论坛服务(小白的“升级打怪”成长之路)
云原生·容器·kubernetes
看到我,请让我去学习16 小时前
Qt— 布局综合项目(Splitter,Stacked,Dock)
开发语言·qt
创想未来CTF16 小时前
Qt同步处理业务并禁用按钮
qt
zhenshanrenhao17 小时前
#买硬盘欲安装k8s记
云原生·容器·kubernetes