Docker 容器网络:C++ 客户端 — 服务器应用程序。

一、说明

        在下面的文章中, 将向您概述 docker 容器之间的通信。docker 通信的验证将通过运行 C++ 客户端-服务器应用程序和标准“ping”命令来执行。将构建并运行两个单独的 Docker 映像。
        由于我会关注 docker 网络方面,因此不会提供 C++ 详细信息。有一个文件和易于理解的程序。我还假设读者了解 docker 的主要概念。在本文中,我不会穷尽 docker 网络的完整概念。为了进一步学习,我建议使用文档,可以在此处找到。

        简单来说,Docker 概念是一个开放平台,允许软件工程师在容器的帮助下开发、集成和运行应用程序,并根据 Dockerfile 中的规范进行构建。
Docker 开发策略使用户能够将应用程序与基础设施分离,有效利用资源并按构建和计划交付应用程序。

        首先,我将解释并为您提供有关通信两个 docker 映像的完整信息,这些映像可以部署在一台主机上(这种类型的 docker 网络通信将使用 docker BRIDGE)。
其次,我将展示 docker 概念OVERLAY NETWORK,其中 docker 映像将部署在单独的主机(和单独的网络)上。
        通信方法将由同一客户端 — 服务器 C++ 应用程序或命令 ping 进行验证。
请注意,网络配置(在下一篇文章中描述)必须被视为一个简单的示例。通常,在每种情况下,网络架构都可以以不同的方式组织并连接许多不同的容器。
我还验证了云中的覆盖网络,将云 Linode 服务器上的主机与我的本地计算机连接起来(本文中未描述,因为我必须发布所有 IP 地址)。

二、Docker 中的桥接网络

2.1 网络构建

        考虑下图,请注意,当连接在一台 Host上运行的容器时,会使用这种类型的通信。在我们的示例中,我们将在一个容器中运行 C++ 客户端,在另一个容器中运行 C++ 服务器(本文中包含的程序)。通过支持 docker 桥(通信管道)可以实现容器之间的通信,该桥可以关联为内部 ETH 网络(仅适用于在同一主机上运行的映像)。
        您可以根据 Dockerfile 构建容器(一个用于客户端,一个用于服务器)。在检查容器通信时,您需要启动第一个服务器(运行服务器容器)。服务器将等待客户端,您从第二个容器启动客户端。
        客户端向服务器发送 0-100 之间的随机数。服务器收集从客户端发送的接收信息并(作为字符串)添加:3.1415 并将包重新发送到客户端。
        以下示例(docker 图像和 C++ 文件管理器)代表了我对软件和硬件的具体设置。您必须(或不必)更改客户端中的 IP 地址。我使用的端口是5555(你可以根据自己的喜好调整)。

按作者

2.2 客户端C++

// Client inspired by GeeksforGeeks#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>
#include <string.h>
#include <iostream>
#include <stdlib.h>
#include <time.h>#define PORT 5555int main()
{int sock = 0, valread;struct sockaddr_in serv_addr;srand(time(NULL));char buffer[1024] = {0};if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0){std::cout << "Socket creation error" << std::endl;return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(PORT);if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) //LOCAL//if(inet_pton(AF_INET, "172.17.0.2", &serv_addr.sin_addr)<=0)  //CLIENT DOES NOT RUN IS CONTAINER//if(inet_pton(AF_INET, "172.21.0.1", &serv_addr.sin_addr)<=0) //CONTAINER//if(inet_pton(AF_INET, "10.0.9.1", &serv_addr.sin_addr)<=0) //OVERLAY{std::cout << "Address is invalid ... " << std::endl;return -1;}if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){std::cout << "Connection Failed. Try again! ..." << std::endl;return -1;}int number = rand() % 100;std::cout << "check : " << number << std::endl;std::string str = std::to_string(number);char *cstr = &str[0];send(sock, cstr, strlen(cstr), 0);std::cout << "Message sent " << std::endl;valread = read(sock, buffer, 1024);std::cout << buffer << std::endl;return 0;
}

Dockerfile 客户端

FROM ubuntu:bionic #pull ubuntu
FROM gcc:latest #pull gcc
#just in case,  you can install gcc and cmake
#RUN apt-get update && apt-get -y install build-essentials gcc cmake
ADD . /usr/src # add (copy) all from local folder to /usr/src
WORKDIR /usr/src
EXPOSE 5555
RUN g++ medium_client.cpp -o medium_client
# comment this and un - comment other if you would like to run your # program manually from shell
CMD ["./medium_client"] 
#CMD ["/bin/bash"]

在终端(构建容器)上执行以下命令。

sudo docker build . -t client:1

2.3 服务器C++

// Server side C/C++ program to demonstrate Socket programming
// Server - inspired by GeeksforGeeks
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string>
#include <string.h>#define PORT 5555int main()
{int server_fd, new_socket, valread;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);char buffer[1024] = {0};if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0){std::cout << "socket failed" << std::endl;exit(EXIT_FAILURE);}if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,&opt, sizeof(opt))){std::cout << "socket failed" << std::endl;exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);if (bind(server_fd, (struct sockaddr *)&address,sizeof(address)) < 0){std::cout << "bind failed" << std::endl;exit(EXIT_FAILURE);}if (listen(server_fd, 3) < 0){std::cout << "listen" << std::endl;exit(EXIT_FAILURE);}if ((new_socket = accept(server_fd, (struct sockaddr *)&address,(socklen_t *)&addrlen)) < 0){std::cout << "accept" << std::endl;exit(EXIT_FAILURE);}double pi = 3.1415;std::string str1 = "server => ";std::string str2 = std::to_string(pi);valread = read(new_socket, buffer, 1024);std::cout << buffer << std::endl;std::string str = str1 + " : " + str2 + " and " + buffer;char *cstr = &str[0];send(new_socket, cstr, strlen(cstr), 0);std::cout << "Message hass been sent!" << std::endl;return 0;
}

服务器 Dockerfile

FROM ubuntu:bionic
FROM gcc:latest
ADD . /usr/src
WORKDIR /usr/src
EXPOSE 5555
RUN g++ medium_server.cpp -o medium_server
# comment this and un - comment other if you would like to run your # program manually from shell
CMD ["./medium_server"] 
#CMD ["/bin/bash"]

在终端上执行以下命令(构建容器)。

sudo docker build . -t server:1

执行以下命令创建桥接并检查通信。我假设您在容器(客户端和服务器)之前构建。

// inspect available docker networks (here is my setup) - see bridge is running as default
sudo docker network ls

        接下来,您需要检查您的网桥并捕获网桥(容器)的 IP 地址。子网网络是您的服务器 cpp 程序内部需要的网络。如果您有其他的,请更改并重新运行容器构建。

        现在你需要创建自己的网络(bridge是一个提供者)并指定你的名字,这里我使用home_net。

sudo docker network create –-driver bridge home_net
// confirm creation running again
sudo docker network ls

        您的网络已创建,但为了为容器提供通信,两个容器都必须连接(到网络)。执行以下命令以运行容器并附加到您的网络 home_net。
请注意,您应该为 /bin/bash 构建两个容器(请参阅 Dockerfile 中的注释),以便首先使用命令行运行容器(而不运行构建容器时已编译的程序)。

sudo docker run -it -p 5555:5555 --network=home_net server:1

接下来再次检查您的网络。查看您的容器已连接到您的网络。

sudo docker network inspect home_net

        对其他容器执行相同操作。

sudo docker run -it  --network=home_net client:1

        并检查(运行以下命令)。

sudo docker network inspect home_net

        现在您的两个容器正在运行并连接到您的网络。

        现在,执行以下命令(在正在运行的容器中)。从服务器启动表单。

./server_medium # container with server
./client_medium # container with client

        现在您可以看到容器之间的一些通信。

三、Docker 中的覆盖网络

        当您想要运行的 docker 容器位于不同的物理位置(在不同的物理主机上运行)时,您仍然可以将容器连接到其他容器。这里我们将在 Docker 中使用覆盖网络概念。
您可以想象,docker 容器可以与桥接通信类似,跨独立的虚拟网络(称为覆盖网络)发送和接收信息。
        这意味着我们可以为容器构建私有虚拟网络,并且可以完全透明地交互。请考虑下图。在此示例中,我们可以重用图像和 C++ 客户端-服务器应用程序(IP 地址必须相应更改)。
        请注意,在这两种情况下(桥接网络和覆盖网络),容器之间的通信也可以通过运行命令来验证:ping <host_IP_address>。对于当前网络(覆盖网络)将执行此类测试。然而,作者也在这种类型的 docker 架构中运行 C++ 应用程序(客户端 - 服务器)。当主机服务器部署在云端(Linode服务器)时,也验证了有关应用程序的验证。

        对于这两种情况(桥接、覆盖),您有 4 种可能的选择来运行您的应用程序(取决于客户端的“位置”)。
        在构建客户端映像之前,请考虑以下需要为medium_client.cpp 提供的IP 地址规范。

//CLIENT AND SERVER RUN LOCAL (NOT IN CONTAINERS)
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
//CLIENT DOES NOT RUN IN CONTAINER. SERVER IN CONTAINER
//if(inet_pton(AF_INET, "172.17.0.2", &serv_addr.sin_addr)<=0)
//BRIDGE COMMUNICATION
//if(inet_pton(AF_INET, "172.21.0.1", &serv_addr.sin_addr)<=0)
//OVERLAY COMMUNICATION
//if(inet_pton(AF_INET, "10.0.9.1", &serv_addr.sin_addr)<=0)

        使用覆盖网络的容器之间的通信将通过命令 ping 进行验证,但是正如我之前提到的,之前的 C++ 应用程序也可以工作。

        运行以下命令(#Host 1 和 #Host 2)

3.1 主机1

        首先使用主机 1 网络的 IP 地址初始化网络管理器。

sudo docker swarm init --advertise-addr 192.168.0.101

就我而言,我收到的输出如下。

3.2 主机1(内部主持人)

        复制并运行命令:

docker swarm join --token SWMTKN-1-4pmk157a83i2nungc6jdtmh7vp4ujqich1pho141kox1dzxeiu-c6usd1wik2kl6p3ot7fhx4pd1 192.168.0.101:2377

        您应该收到如下信息。

3.2  #主机1(其它)

        运行以下命令并验证 swarm 管理器(上图之一显示了 swarm 和网桥)

sudo docker network ls

        现在创建覆盖网络,这里我们的名字是overnet

sudo docker network create -d overlay overnet

        检查您创建的网络。验证身份等

sudo docker network inspect overnet

        拉取两个 Ubuntu 映像(副本),激活网络并创建一个新服务 myservice。以下命令还发送 # Host 2 的图像

sudo docker service create --name myservice --network overnet --replicas 2 ubuntu sleep

        运行以下命令确认您已完成的操作。

sudo docker service ls                
sudo docker service ps myservice

        现在确认您是否正确创建了覆盖网络并且两个容器都已连接。# 主机 1 的 IP 地址为 10.0.1.4。
        运行命令

sudo docker network inspect overnet

3.3 主机2

        运行相同的操作(我不显示图像,因为它与上面类似)。该主机收到地址IP 10.0.1.5

sudo docker network inspect overnet

3.4 #主机1和#主机2

运行以下命令来安装“ping 命令”。

apt-get update && apt-get install -y iputils-ping

在 #Host 1 和 2 上运行命令来捕获容器名称

sudo docker ps

并连接到 docker shell 以运行 ping

sudo docker exec -it 94835734987 sh
ping 10.0.1.5 # from host 1
ping 10.0.1.4 # from host 2

感谢您的阅读。

四、参考资源 

凡本文遇到的代码资源可在下述地址下:

Networking overview | Docker Docs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2777964.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode-第15题-三叔之和

1.题目描述 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组…

1899_野火FreeRTOS教程阅读笔记_任务创建

1899_野火FreeRTOS教程阅读笔记_任务创建 全部学习汇总&#xff1a; g_FreeRTOS: FreeRTOS学习笔记 (gitee.com) 关于这部分&#xff0c;从一般前后台程序到RTOS的任务描述了很多。但是我觉得这本书的这部分描述没有描述到关键的信息点。其实&#xff0c;RTOS存在的一个主要的目…

MySQL篇----第八篇

系列文章目录 文章目录 系列文章目录前言一、存储过程优化思路二、触发器(一段能自动执行的程序)三、数据库并发策略四、MySQL 中有哪几种锁?五、MySQL 中有哪些不同的表格?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳…

创建自己的系统创富法则,做个轻松赚钱的甩手掌柜

一、教程描述 本套系统创富教程&#xff0c;大小744.80M&#xff0c;共有28个文件。 二、教程目录 01.走遍全球四十多个国家&#xff0c;我才发现赚钱的本质如此雷同.mp4 02.靠工资技术赚钱太慢&#xff0c;想赚到自己的第一个一百万的方法是&#xff1f;.mp4 03.不服暴发…

CSP-202112-2-序列查询新解

CSP-202112-2-序列查询新解 【70分思路】 【暴力枚举】按照题目思路遍历一遍f(x)和g(x)&#xff0c;计算error(A)&#xff0c;时间复杂度为O(N)&#xff0c;时间超限。 #include <iostream> using namespace std; int main() {long long n, N, sum 0;cin >> n …

【c++基础】骑士的金币(coin)(NOIP2015)

说明 国王将金币作为奖励&#xff0c;发放给忠诚的骑士。第一天&#xff0c;骑士收到一枚金币&#xff1b;之后两天&#xff08;第二天和第三天&#xff09;里&#xff0c;每天收到两枚金币&#xff1b;之后三天&#xff08;第四、五、六天&#xff09;里&#xff0c;每天收到…

微软 CMU - Tag-LLM:将通用大语言模型改用于专业领域

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 论文地址&#xff1a;https://arxiv.org/abs/2402.05140 Github 地址&#xff1a;https://github.com/sjunhongshen/Tag-LLM 大语言模型&#xff08…

ChatGPT高效提问—prompt常见用法

ChatGPT高效提问—prompt常见用法 1.1 角色扮演 ​ prompt最为常见的用法是ChatGPT进行角色扮演。通常我们在和ChatGPT对话时&#xff0c;最常用的方式是一问一答&#xff0c;把ChatGPT当作一个单纯的“陪聊者”。而当我们通过prompt为ChatGPT赋予角色属性后&#xff0c;即使…

SpringIOC之support模块PropertySourcesPlaceholderConfigurer

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

LeetCode Python - 6.Z字形变换

文章目录 题目答案运行结果 题目 将一个给定字符串 s 根据给定的行数 numRows &#xff0c;以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 “PAYPALISHIRING” 行数为 3 时&#xff0c;排列如下&#xff1a; P A H N A P L S I I G Y I R 之后&#xff0c;你的输…

STM32 FSMC (Flexible static memory controller) 灵活静态内存控制器介绍

文章目录 1. 介绍FSMC2. FSMC特点3. Block示意图4. AHB接口4.1 Supported memories and transactionsGeneral transaction rulesConfiguration registers 5. 外部设备地址映射5.1 NOR/PSRAM地址映射将NOR Flash/PSRAM的支持进行封装 5.2 NAND/PC Card地址映射 1. 介绍FSMC 说到…

【正在更新】从零开始认识语音识别:DNN-HMM混合系统语音识别(ASR)模型原理

摘要 | Abstract TO-BE-FILLED 前言 | Introduction 近期想深入了解HMM隐马尔可夫模型和DNN-HMM混合模型&#xff0c;但是尽管网络上有许多关于DNN-HMM的介绍&#xff0c;如李宏毅教授的《深度学习人类语言处理》[1]&#xff0c;一些博主的语音识别系列文章[2]&#xff0c;斯坦…

4核8g服务器能支持多少人访问?- 腾讯云

腾讯云轻量4核8G12M轻量应用服务器支持多少人同时在线&#xff1f;通用型-4核8G-180G-2000G&#xff0c;2000GB月流量&#xff0c;系统盘为180GB SSD盘&#xff0c;12M公网带宽&#xff0c;下载速度峰值为1536KB/s&#xff0c;即1.5M/秒&#xff0c;假设网站内页平均大小为60KB…

机器学习系列——(十八)K-means聚类

引言 在众多机器学习技术中&#xff0c;K-means聚类以其简洁高效著称&#xff0c;成为了数据分析师和算法工程师手中的利器。无论是在市场细分、社交网络分析&#xff0c;还是图像处理等领域&#xff0c;K-means都扮演着至关重要的角色。本文旨在深入解析K-means聚类的原理、实…

Sodinokibi(REvil)黑客组织发起大规模供应链攻击

前言 Sodinokibi勒索病毒黑客组织获取了远程管理解决方案提供商Kaseya基础设施的访问权限&#xff0c;并使用VSA软件的恶意升级执行程序在企业网络上部署Sodinokibi(REvil)勒索病毒&#xff0c;据报道该事件已经影响了全球数千家公司&#xff0c;相关受害者发布的信息&#xf…

WWW 2024 | 时间序列(Time Series)和时空数据(Spatial-Temporal)论文总结

WWW 2024已经放榜&#xff0c;本次会议共提交了2008篇文章&#xff0c;research tracks共录用约400多篇论文&#xff0c;录用率为20.2%。本次会议将于2024年5月13日-17日在新加坡举办。 本文总结了WWW 2024有关时间序列&#xff08;Time Series&#xff09;和时空数据&#xf…

编译环境搭建及基础实验

1.VS code安装 Linux 版本安装 把资料盘里的安装包.deb拷贝到Ubuntu中&#xff0c; 使用如下命令安装&#xff1a; 软件图标都在目录/usr/share/applications 中&#xff0c;如图路径 复制到桌面中 Visual Studio Code 插件的安装 我们需要按照的插件有下面几个&#xff1a;…

【后端高频面试题--Mybatis篇】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;后端高频面试题 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 后端高频面试题--Mybatis篇 什么是Mybatis&#xff1f;Mybatis的优缺点&#xff1f;Mybatis的特点…

Netty源码系列 之 HashedWheelTimer源码

Netty优化方案 之前总结NioEventLoop以及其他内容时&#xff0c;已经总结了Netty许多优化的设计方案。 1.Selector的优化 (1) 为epoll空转问题提供了解决思路&#xff0c;虽然并没有从根本上解决epoll空转问题&#xff0c;但是使用一个计数器的方式可以减少空转所带来的性能…

BestEdrOfTheMarket:一个针对AVEDR绕过的训练学习环境

关于BestEdrOfTheMarket BestEdrOfTheMarket是一个针对AV/EDR绕过的训练学习环境&#xff0c;广大研究人员和信息安全爱好者可以使用该项目研究和学习跟AV和EDR绕过相关的技术知识。 支持绕过的防御技术 1、多层API钩子&#xff1b; 2、SSH钩子&#xff1b; 3、IAT钩子&#x…