Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,能够把货物规整的摆放起来。而且各类各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么我就不须要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那我就能够用一艘大船把他们都运走。 docker就是相似的理念。如今都流行云计算了,云计算就比如大货轮。docker就是集装箱。 1.不一样的应用程序可能会有不一样的应用环境,好比.net开发的网站和php开发的网站依赖的软件就不同,若是把他们依赖的软件都安装在一个服务器上就要调试好久,并且很麻烦,还会形成一些冲突。好比IIS和Apache访问端口冲突。这个时候你就要隔离.net开发的网站和php开发的网站。常规来说,咱们能够在服务器上建立不一样的虚拟机在不一样的虚拟机上放置不一样的应用,可是虚拟机开销比较高。docker能够实现虚拟机隔离应用环境的功能,而且开销比虚拟机小,小就意味着省钱了。 2.你开发软件的时候用的是Ubuntu,可是运维管理的都是centos,运维在把你的软件从开发环境转移到生产环境的时候就会遇到一些Ubuntu转centos的问题,好比:有个特殊版本的数据库,只有Ubuntu支持,centos不支持,在转移的过程中运维就得想办法解决这样的问题。这时候要是有docker你就能够把开发环境直接封装转移给运维,运维直接部署你给他的docker就能够了。并且部署速度快。 3.在服务器负载方面,若是你单独开一个虚拟机,那么虚拟机会占用空闲内存的,docker部署的话,这些内存就会利用起来。 总之docker就是集装箱原理。php
Docker在开发与运维的世界中具备极大的吸引力,由于它能保持跨环境的一致性。在开发与发布的生命周期中,不一样的环境具备细微的不一样,这些差别多是因为不一样安装包的版本和依赖关系引发的。然而,Docker能够经过确保从开发到产品发布整个过程环境的一致性来解决这个问题。 Docker容器经过相关配置,保持容器内部全部的配置和依赖关系始终不变。最终,你能够在开发到产品发布的整个过程当中使用相同的容器来确保没有任何差别或者人工干预。 使用Docker,你还能够确保开发者不须要配置彻底相同的产品环境,他们能够在他们本身的系统上经过VirtualBox创建虚拟机来运行Docker容器。Docker的魅力在于它一样可让你在亚马逊EC2实例上运行相同的容器。若是你须要在一个产品发布周期中完成一次升级,你能够很容易地将须要变动的东西放到Docker容器中,测试它们,而且使你已经存在的容器执行相同的变动。这种灵活性就是使用Docker的一个主要好处。和标准部署与集成过程同样,Docker可让你构建、测试和发布镜像,这个镜像能够跨多个服务器进行部署。哪怕安装一个新的安全补丁,整个过程也是同样的。你能够安装补丁,而后测试它,而且将这个补丁发布到产品中。html
Docker容器能够在不一样的开发与产品发布生命周期中确保一致性,进而标准化你的环境。除此以外,Docker容器还能够像git仓库同样,可让你提交变动到Docker镜像中并经过不一样的版原本管理它们。设想若是你由于完成了一个组件的升级而致使你整个环境都损坏了,Docker可让你轻松地回滚到这个镜像的前一个版本。这整个过程能够在几分钟内完成,若是和虚拟机的备份或者镜像建立流程对比,那Docker算至关快的,它可让你快速地进行复制和实现冗余。此外,启动Docker就和运行一个进程同样快。java
Docker能够确保你的应用程序与资源是分隔开的。几个月前,Gartner发表了一篇报告,这份报告说明了运行Docker 容器进行资源隔离的效果和虚拟机(VM)管理程序同样的好,可是管理与控制方面还须要进行完善。咱们考虑这样一个场景,你在你的虚拟机中运行了不少应用程序,这些应用程序包括团队协做软件(例如Confluence)、问题追踪软件(例如JIRA)、集中身份管理系统(例如Crowd)等等。因为这些软件运行在不一样的端口上,因此你必须使用Apache或者Nginx来作反向代理。到目前为止,一切都很正常,可是随着你的环境向前推动,你须要在你现有的环境中配置一个内容管理系统(例如Alfresco)。这时候有个问题发生了,这个软件须要一个不一样版本的Apache Tomcat,为了知足这个需求,你只能将你现有的软件迁移到另外一个版本的Tomcat上,或者找到适合你现有Tomcat的内容管理系统(Alfresco)版本。对于上述场景,使用Docker就不用作这些事情了。Docker可以确保每一个容器都拥有本身的资源,而且和其余容器是隔离的。你能够用不一样的容器来运行使用不一样堆栈的应用程序。除此以外,若是你想在服务器上直接删除一些应用程序是比较困难的,由于这样可能引起依赖关系冲突。而Docker能够帮你确保应用程序被彻底清除,由于不一样的应用程序运行在不一样的容器上,若是你不在须要一款应用程序,那你能够简单地经过删除容器来删除这个应用程序,而且在你的宿主机操做系统上不会留下任何的临时文件或者配置文件。除了上述好处,Docker还能确保每一个应用程序只使用分配给它的资源(包括CPU、内存和磁盘空间)。一个特殊的软件将不会使用你所有的可用资源,要否则这将致使性能下降,甚至让其余应用程序彻底中止工做。node
如上所述,Gartner也认可Docker正在快速地发展。从安全角度来看,Docker确保运行在容器中的应用程序和其余容器中的应用程序是彻底分隔与隔离的,在通讯流量和管理上赋予你彻底的控制权。Docker容器不能窥视运行在其余容器中的进程。从体系结构角度来看,每一个容器只使用着本身的资源(从进程到网络堆栈)。做为紧固安全的一种手段,Docker将宿主机操做系统上的敏感挂载点(例如/proc和/sys)做为只读挂载点,而且使用一种写时复制系统来确保容器不能读取其余容器的数据。Docker也限制了宿主机操做系统上的一些系统调用,而且和SELinux与AppArmor一块儿运行的很好。此外,在Docker Hub上可使用的Docker镜像都经过数字签名来确保其可靠性。因为Docker容器是隔离的,而且资源是受限制的,因此即便你其中一个应用程序被黑,也不会影响运行在其它Docker容器上的应用程序。linux
Docker最大的好处之一就是可移植性。在过去的几年里,全部主流的云计算提供商,包括亚马逊AWS和谷歌的GCP,都将Docker融入到他们的平台并增长了各自的支持。Docker容器能运行在亚马逊的EC2实例、谷歌的GCP实例、Rackspace服务器或者VirtualBox这些提供主机操做系统的平台上。举例来讲,若是运行在亚马逊EC2实例上的Docker容器可以很容易地移植到其余几个平台上,好比说VirtualBox,而且达到相似的一致性和功能性,那这将容许你从基础设施层中抽象出来。除了AWS和GCP,Docker在其余不一样的IaaS提供商也运行的很是好,例如微软的Azure、OpenStack和能够被具备不一样配置的管理者所使用的Chef、Puppet、Ansible等。git
Docker Enterprise Edition (Docker EE) is designed for enterprise development and IT teams who build, ship, and run business critical applications in production at scale. Docker EE is integrated, certified, and supported to provide enterprises with the most secure container platform in the industry to modernize all applications. For more information about Docker EE, including purchasing options, see Docker Enterprise Edition. Docker Community Edition (Docker CE) is ideal for developers and small teams looking to get started with Docker and experimenting with container-based apps. Docker CE is available on many platforms, from desktop to cloud to server. Docker CE is available for macOS and Windows and provides a native experience to help you focus on learning Docker. You can build and share containers and automate the development pipeline all from a single environment. Docker CE has both stable and edge channels. Stable builds are released once per quarter and are supported for 4 months. Edge builds are released once per month, and are supported for that month only. If you subscribe to the Edge channel on Linux distributions, you should also subscribe to the Stable channel.github
官网总的安装手册:https://docs.docker.com/install/web
官网 CentOS 安装手册:https://docs.docker.com/install/linux/docker-ce/centos/正则表达式
目前也支持 Windows,特别是 Windows 10,直接官网一个安装包便可搞定。redis
Windows 10 的 Docker 安装说明:https://store.docker.com/editions/community/docker-ce-desktop-windows
我这里选择 Docker CE 版本:
CentOS 安装过程:
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum makecache fast
sudo yum install -y docker-ce
,大小:19M,速度很慢。查看配置文件位置:systemctl show --property=FragmentPath docker
启动 Docker:systemctl start docker.service
中止 Docker:systemctl stop docker.service
查看状态:systemctl status docker.service
运行 hello world 镜像:sudo docker run hello-world
Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 78445dd45222: Pull complete Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://cloud.docker.com/ For more examples and ideas, visit: https://docs.docker.com/engine/userguide/
https://ldhc17y9.mirror.aliyuncs.com
,因此下面文章你看到该地址都表示是这个专属地址,请记得本身更换本身的。vim /etc/docker/daemon.json
,增长以下内容:{
"registry-mirrors": ["https://ldhc17y9.mirror.aliyuncs.com"] }
sudo systemctl daemon-reload
sudo systemctl restart docker
namespace管理
中建立属于你本身的 namespace:https://cr.console.aliyun.com/#/namespace/index管理
进入查看仓库的更多详细信息,这里面有不少有用的信息,包括一个详细的操做指南,这份指南等下会用到。registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster
docker login registry.cn-shenzhen.aliyuncs.com 会让我输入 Username:阿里云邮箱 password:上文提到的--Registry登陆密码
docker pull registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster:[镜像版本号]
docker login docker tag [ImageId] registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster:[镜像版本号] docker push registry.cn-shenzhen.aliyuncs.com/youmeek/redis-to-cluster:[镜像版本号]
http://192.168.137.128
systemctl stop firewalld.service ; systemctl stop iptables.service
systemctl restart docker.service
/opt/setups
http://127.0.0.1:8080/youmeek
docker pull centos:6.8
,个人 IMAGE_ID 为:0cd976dc0a98
docker run -i -t -v /opt/setups:/opt 0cd976dc0a98 /bin/bash
-v:表示须要将本地宿主机的目录挂载到容器中对应的一个目录上,格式:-v <宿主机目录>:<容器目录>,因此此时对容器此目录的操做,也是等同于对宿主机的目录的操做
cp /opt/spring-boot-my-demo.jar /root
vi /root/spring-boot-run.sh
,脚本内容以下:#!/bin/bash source /etc/profile java -jar /root/spring-boot-my-demo.jar
chmod u+x /root/spring-boot-run.sh
docker ps -a
a5d544d9b6f9
,这个下面要用到docker commit a5d544d9b6f9 youmeek/springboot:0.1
docker images
,会发现多了一个 youmeek/springboot 新镜像,镜像 ID 为:7024f230fef9
docker run -d -p 38080:8080 --name=springBootJar --hostname=springBootJar 7024f230fef9 /root/spring-boot-run.sh
-d
:表示以“守护模式”执行 spring-boot-run.sh 脚本,此时 jar 中的 log 日志不会出如今输出终端上。-p
:表示宿主机与容器的端口映射,此时将容器内部的 8080 端口映射为宿主机的 38080 端口,这样就向外界暴露了 38080 端口,可经过 Docker 网桥来访问容器内部的 8080 端口了。--name
:表示给新实例容器取的名称,用一个有意义的名称命名便可docker ps -a
,能够知道咱们的新容器 ID:fd21ac056343
,名称为:springBootJar
docker logs -f fd21ac056343
,能够看到 jar 启动后的 log 输出内容http://192.168.137.128:38080/youmeek/
,能够看到 jar 应用的首页能够访问docker version
,查看docker版本docker info
,显示docker系统的信息docker pull
:从仓库下载镜像到本地
docker pull centos:latest
:获取 CentOS 默认版本镜像docker pull centos:7.3.1611
:获取 CentOS 7 镜像,下载大小 70M 左右,下面的操做基于此镜像docker pull centos:6.8
:获取 CentOS 6 镜像docker pull registry.cn-hangzhou.aliyuncs.com/chainone/centos7-jdk8
:获取别人作好的阿里云镜像docker push
:将一个镜像 push 到 registry 仓库中
docker push myapache:v1
docker search
:从 registry 仓库搜索镜像
docker search -s 3 centos
,参数 -s 数字
:表示筛选出收藏数(stars值)大于等于 3 的镜像docker login
:登陆到一个镜像仓库。默认登陆的是官网的仓库:https://hub.docker.com
sudo docker login --username=阿里云邮箱
docker login --username=23333212@qq.com registry.cn-shenzhen.aliyuncs.com
,你完整的登陆地址你须要访问:https://cr.console.aliyun.com/#/imageList,在你本身建立的仓库中去查看那份详细操做指南上的地址docker stats
:查看当前启动的容器各自占用的系统资源
bin docker stats --no-stream kafkadocker_kafka_1 kafkadocker_zookeeper_1
:查看指定容器的占用资源状况CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS 4532a9ee27b8 cloud-cadvisor 1.49% 53.28MiB / 3.702GiB 1.41% 13.5MB / 646MB 265MB / 0B 19 3895d5d50a5e kafkadocker_kafka_1 1.45% 1.24GiB / 3.702GiB 33.51% 145MB / 186MB 499MB / 724MB 128 1d1a6a7c48d8 kafkadocker_zookeeper_1 0.11% 70.85MiB / 3.702GiB 1.87% 55.8MB / 33.7MB 209MB / 1.22MB 23
docker images
:显示本地全部的镜像列表
docker images centos
:查看具体镜像状况docker rmi
:删除镜像,通常删除镜像前要先删除容器,否则若是镜像有被容器调用会报错
docker rmi 容器ID
:删除具体某一个镜像docker rmi 仓库:Tag
:删除具体某一个镜像docker rmi $(docker images -q)
,删除全部镜像docker rmi -f $(docker images -q)
,强制删除全部镜像docker rmi $(docker images | grep "vmware" | awk '{print $3}')
,批量删除带有 vmware 名称的镜像docker tag
:为镜像打上标签
docker tag -f ubuntu:14.04 ubuntu:latest
,-f 意思是强制覆盖docker rmi 仓库:Tag
,取消标签(若是是镜像的最后一个标签,则会删除这个镜像)docker build
:使用 Dockerfile 建立镜像(推荐)
docker build . --rm -t runoob/ubuntu:v1
,参数 -t
,表示:-tag,打标签docker build --no-cache . --rm -t runoob/ubuntu:v1
docker history
:显示生成一个镜像的历史命令,能够看出这个镜像的构建过程,包括:每一层镜像的 ID、指令docker save
:将一个镜像保存为一个 tar 包,带 layers 和 tag 信息(导出一个镜像)
docker save 镜像ID -o /opt/test.tar
docker load
:从一个 tar 包建立一个镜像(导入一个镜像)
docker load -i /opt/test.tar
docker run
,运行镜像
docker run -v /java_logs/:/opt/ -d -p 8080:80 --name=myDockerNameIsGitNavi --hostname=myDockerNameIsGitNavi -i -t 镜像ID /bin/bash
-i -t
分别表示保证容器中的 STDIN 开启,并分配一个伪 tty 终端进行交互,这两个是合着用。--name
是给容器起了一个名字(若是没有主动给名字,docker 会自动给你生成一个)容器的名称规则:大小写字母、数字、下划线、圆点、中横线,用正则表达式来表达就是:[a-zA-Z0-9_*-]-d
容器运行在后台。-p 8080:80
表示端口映射,将宿主机的8080端口转发到容器内的80端口。(若是是 -P 参数,则表示随机映射应该端口,通常用在测试的时候)-v /java_logs/:/opt/
表示目录挂载,/java_logs/ 是宿主机的目录,/opt/ 是容器目录docker run --rm --name=myDockerNameIsGitNavi --hostname=myDockerNameIsGitNavi -i -t centos /bin/bash
,--rm,表示退出即删除容器,通常用在作实验测试的时候docker run --restart=always -i -t centos /bin/bash
,--restart=always 表示中止后会自动重启docker run --restart=on-failure:5 -i -t centos /bin/bash
,--restart=on-failure:5 表示中止后会自动重启,最多重启 5 次docker exec
:对守护式的容器里面执行命令,方便对正在运行的容器进行维护、监控、管理
docker exec -i -t 容器ID /bin/bash
,进入正在运行的 docker 容器,并启动终端交互docker exec -d 容器ID touch /opt/test.txt
,已守护式的方式进入 docker 容器,并建立一个文件docker stop 容器ID
,中止容器
docker stop $(docker ps -a -q)
,中止全部容器docker stop $(docker ps -a -q) ; docker rm $(docker ps -a -q)
,中止全部容器,并删除全部容器docker kill $(docker ps -q) ; docker rm $(docker ps -a -q)
,中止全部容器,并删除全部容器docker start 容器ID
,从新启动已经中止的容器(从新启动,docker run 参数仍是保留以前的)docker restart 容器ID
,重启容器docker rm
,删除容器
docker rm 容器ID
,删除指定容器(该容器必须是中止的)docker rm -f 容器ID
,删除指定容器(该容器若是正在运行能够这样删除)docker rm $(docker ps -a -q)
,删除全部容器docker rm -f $(docker ps -a -q)
,强制删除全部容器docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm
删除老的(一周前建立)容器docker kill $(docker ps -q) ; docker rm $(docker ps -a -q) ; docker rmi $(docker images -q -a)
中止全部容器,删除全部容器,删除全部镜像docker commit
,把容器打成镜像
docker commit 容器ID gitnavi/docker-nodejs-test:0.1
docker commit -m="这是一个描述信息" --author="GitNavi" 容器ID gitnavi/docker-nodejs-test:0.1
docker diff 容器ID
:显示容器文件系统的先后变化--link
同一个宿主机下的不一样容器的链接:
docker run -it 镜像ID --link redis-name:myredis /bin/bash
redis-name
是容器名称myredis
是容器别名,其余容器链接它能够用这个别名来写入到本身的配置文件中docker cp /www/runoob 96f7f14e99ab:/www/
将主机 /www/runoob 目录拷贝到容器 96f7f14e99ab 的 /www 目录下docker cp /www/runoob 96f7f14e99ab:/www
将主机 /www/runoob 目录拷贝到容器 96f7f14e99ab 中,目录重命名为 www。docker cp 96f7f14e99ab:/www /tmp/
将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中。docker network ls
docker network create --subnet=172.19.0.0/16 net-redis-to-cluster
docker network connect net-redis-to-cluster my-redis-container
--network XXXXXX
常见几种模式
docker run -it 镜像ID --network=bridge /bin/bash
docker run -it 镜像ID --network=none /bin/bash
docker run -it 镜像ID --network=host /bin/bash
docker run -it 镜像ID --network=自定义名称 /bin/bash
docker ps
:列出当前全部 正在运行 的容器
docker ps -a
:列出全部的容器(包含历史,即运行过的容器)docker ps -l
:列出最近一次启动的containerdocker ps -q
:列出最近一次运行的container IDdocker ps -a -l
:列出最后一次运行的容器docker ps -n x
:显示最后 x 个容器,无论是正在运行或是已经中止的docker top 容器ID
:显示容器的进程信息docker events
:获得 docker 服务器的实时的事件docker logs -f 容器ID
:查看容器日志(若是一些容器不断重启,或是自动中止,能够这样看下)
docker logs 容器ID
,获取守护式容器的日志docker logs -f 容器ID
,不断监控容器日志,相似 tail -fdocker logs -ft 容器ID
,在 -f 的基础上又增长 -t 表示为每条日志加上时间戳,方便调试docker logs --tail 10 容器ID
,获取日志最后 10 行docker logs --tail 0 -f 容器ID
,跟踪某个容器的最新日志而没必要读取日志文件docker logs -f -t --since="2018-05-26" --tail=200 容器ID
根据某个时间读取日志docker logs -f -t --since="2018-05-26T11:13:40" --tail=200 容器ID
根据某个时间读取日志docker logs -f -t --since="2018-05-25T11:13:40" --until "2018-05-26T11:13:40" --tail=200 容器ID
根据某个时间读取日志docker logs --since 10m 容器ID
查看最近 10 分钟的日志
-f
: 表示查看实时日志-t
: 显示时间戳-since
: 显示某个开始时间的全部日志-tail=200
: 查看最后的 200 条日志docker wait
,阻塞到一个容器,直到容器中止运行docker export
,将容器整个文件系统导出为一个tar包,不带layers、tag等信息docker port
,显示容器的端口映射docker inspect 容器ID
:查看容器的全面信息,用 JSON 格式输出docker inspect network名称
:查看 network 信息,用 JSON 格式输出,包含使用该网络的容器有哪些docker system df
:相似于 Linux 上的 df 命令,用于查看 Docker 的磁盘使用状况
TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 6 6 1.049GB 0B (0%) Containers 7 4 10.25kB 0B (0%) Local Volumes 13 5 38.49GB 1.365MB (0%) Build Cache 0B 0B
获取容器中的 IP:docker inspect -f {{.NetworkSettings.IPAddress}} 容器ID 获取容器中的 IP:docker inspect -f {{.Volumes}} 容器ID 查看容器的挂载状况:docker inspect 容器ID | grep Mounts -A 10
[
{
"Id": "e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b", "Created": "2018-01-18T03:47:16.138180181Z", "Path": "docker-entrypoint.sh", "Args": [ "--auth" ], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 19952, "ExitCode": 0, "Error": "", "StartedAt": "2018-01-18T03:47:16.348568927Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:42aa46cfbd7a0d1101311defac39872b447b32295b40f9c99104ede5d02e9677", "ResolvConfPath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/resolv.conf", "HostnamePath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/hostname", "HostsPath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/hosts", "LogPath": "/var/lib/docker/containers/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b/e1dff77b99d9c8489e0a0ce68a19ec5ffe18cc5d8b8ec17086f7f7bea29aa09b-json.log", "Name": "/cas-mongo", "RestartCount": 0, "Driver": "overlay", "Platform": "linux", "MountLabel": "", "ProcessLabel": "", "AppArmorProfile": "", "ExecIDs": null, "HostConfig": { "Binds": [ "/data/mongo/db:/data/db" ], "ContainerIDFile": "", "LogConfig": { "Type": "json-file", "Config": {} }, "NetworkMode": "default", "PortBindings": { "27017/tcp": [ { "HostIp": "", "HostPort": "27017" } ] }, "RestartPolicy": { "Name": "always", "MaximumRetryCount": 0 }, "AutoRemove": false, "VolumeDriver": "", "VolumesFrom": null, "CapAdd": null, "CapDrop": null, "Dns": [], "DnsOptions": [], "DnsSearch": [],