Docker出来很久很久了,显而易见的很多公司、个人都在使用它,但是我一直没有用它.......大概率是我这水平好像用不上😂😂😂。平常Linux就是直接用lnmp安装脚本、window直接装phpstudy,对于PHP来说,也不算很麻烦。难得一个空闲的周末,总得跟随一下时代潮流.....冲........!
参考资料
https://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html
软件开发最大的麻烦事之一,就是环境配置。用户计算机的环境都不相同,你怎么知道自家的软件,能在那些机器跑起来?
用户必须保证两件事:操作系统的设置,各种库和组件的安装。只有它们都正确,软件才能运行。举例来说,安装一个 Python 应用,计算机必须有 Python 引擎,还必须有各种依赖,可能还要配置环境变量。
如果某些老旧的模块与当前环境不兼容,那就麻烦了。开发者常常会说:"它在我的机器可以跑了"(It works on my machine),言下之意就是,其他机器很可能跑不了。
环境配置如此麻烦,换一台机器,就要重来一次,旷日费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。
虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在 Windows 系统里面运行 Linux 系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。
虽然用户可以通过虚拟机还原软件的原始环境。但是,这个方案有几个缺点。
由于虚拟机存在这些缺点,Linux 发展出了另一种虚拟化技术:Linux 容器(Linux Containers,缩写为 LXC)。
Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。
由于容器是进程级别的,相比虚拟机有很多优势。
总之,容器有点像轻量级的虚拟机,能够提供虚拟化的环境,但是成本开销小得多。
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。
Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。
总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
Linux Namespace(Linux 命名空间)是 Linux 内核(Kernel)提供的功能,它可以隔离一系列的系统资源,如 PID(进程 ID,Process ID)、User ID、Network、文件系统等。
Linux Namespace是在当前运行的系统环境中创建(隔离)另一个进程的运行环境出来,并在此运行环境中将一些必要的系统全局资源进行【虚拟化】。进程可以运行在指定的namespace中,因此,namespace中的每个进程都认为自己拥有所有这些虚拟化的全局资源。
Docker 容器本质依旧是一个进程,多个 Docker 容器运行时,如果其中一个 Docker 进程占用大量 CPU 和内存就会导致其他 Docker 进程响应缓慢,为了避免这种情况,可以通过 Linux Cgroups 技术对资源进行限制。
Linux Cgroups(Linux Contorl Groups,简称 Cgroups)可以对一组进程及这些进程的子进程进行资源限制、控制和统计的能力,其中包括 CPU、内存、存储、网络、设备访问权限等,通过 Cgroups 可以很轻松的限制某个进程的资源占用并且统计该进程的实时使用情况。
Cgroups 由 3 个组件构成,分别是 cgroup(控制组)、subsystem(子系统)以及 hierarchy(层级树),3 者相互协同作用。
Docker 镜像是一种分层结构,每一层构建在其他层之上,从而实现增量增加内容的功能。
Union File System(简称,UnionFS),它是为 Linux 系统设计的将其他文件系统联合到一个联合挂载点的文件系统服务。UnionFS 使用 branch(分支)将不同文件系统的文件和目录透明地叠加覆盖,形成一个单一一致的文件系统,此外 UnionFS 使用写时复制(Copy on Write,简称,CoW)技术来提高合并后文件系统的资源利用。
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。Docker 容器通过 Docker 镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类。
官方文档
Docker Engine:https://docs.docker.com/engine/,Docker核心
Docker Desktop:https://docs.docker.com/desktop/,可视化操作。
Docker Composer:https://docs.docker.com/compose/,编排容器。
拓展
Window Linux子系统:https://docs.microsoft.com/zh-cn/windows/dev-environment/
官方文档上有详细的说明,这里以centos7.6作为操作实例。(https://docs.docker.com/engine/install/centos/)
官方建议如果安装过旧版本,先卸载后安装。旧版docker-engine现在被称为docker-ce.
# 这个可以理解为字符串换行连接符
$ sudo yum remove docker docker-client docker-client-latest docker-common
docker-latest docker-latest-logrotate docker-logrotate docker-engine
然后配置yum仓库源,命令行开始:
# 安装yum-utils,一般都有装
$ yum install -y yum-utils
# 配置仓库源
$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
开始安装最新版本的 Docker Engine、containerd 和 Docker Compose
yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
此命令会安装 Docker,但不会启动 Docker。它还会创建一个 docker组,但是默认情况下它不会将任何用户添加到该组中。
安装完成,查看docker版本信息,命令如下:
$ docker version
# 或者
$ docker info
启动docker ,命令如下:
# service 命令的用法
$ sudo service docker start
# systemctl 命令的用法
$ sudo systemctl start docker
# 测试安装是否正常
$ docker run hello-world
提示
docker --help 、docker command --help,查看命令的功能说明
Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码,运行时(一个程序在运行或者在被执行的依赖)、库,环境变量和配置文件。其实也可以理解为一个文件目录
image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。举例来说,你可以在 Ubuntu 的 image 基础上,往里面加入 Apache 服务器,形成你的 image。
image 文件是通用的,一台机器的 image 文件拷贝到另一台机器,照样可以使用。一般来说,为了节省时间,我们应该尽量使用别人制作好的 image 文件,而不是自己制作。即使要定制,也应该基于别人的 image 文件进行加工,而不是从零开始制作。
为了方便共享,image 文件制作完成后,可以上传到网上的仓库。Docker 的官方仓库 Docker Hub 是最重要、最常用的 image 仓库。此外,出售自己制作的 image 文件也是可以的。
相关参考
https://blog.csdn.net/sinat_33087001/article/details/123029844
添加镜像仓库之后下载镜像时会先从镜像仓库进行下载;
以centos为例,编辑/etc/docker/daemon.json文件;
{
"registry-mirrors": ["https://alzgoonw.mirror.aliyuncs.com"]
}
然后重启docker:
# 重载配置
$ systemctl daemon-reload
# 重启docker
$ systemctl restart docker
# 查看docker信息
$ docker info
登陆到一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub(https://hub.docker.com/)
# 登录,不指定地址,默认为官方仓库
$ docker login -u 用户名 -p 密码
# 退出指定仓库的登录
$ docker logout [OPTIONS] [SERVER]
我们可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/
我们也可以使用 docker search 命令来搜索镜像。比如我们需要一个 openresty的镜像来作为我们的 web 服务。我们可以通过 docker search 命令搜索 openresty来寻找适合我们的镜像。
[root@VM-0-11-centos ~]# docker search Openresty
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
openresty/openresty OpenResty Official Docker Images - a dynamic… 370 [OK]
ficusio/openresty Minimalist OpenResty image 22 [OK]
3scale/openresty Latest Openresty with redis and some handy p… 16 [OK]
# 拉取指定的镜像(name为上方镜像仓库源名称)
# -a :拉取所有 tagged 镜像
# name可以是一个在仓库存在的镜像名,也可以是代表镜像的一个远程地址
$ docker pull [OPTIONS] NAME[:TAG|@DIGEST]
用于将本地的镜像上传到镜像仓库,要先登陆到镜像仓库。
# docker push [OPTIONS] NAME[:TAG]
# 上传本地镜像myapache:v1到镜像仓库中。
$ docker push myapache:v1
# OPTIONS --disable-content-trust :忽略镜像的校验,默认开启
向指定远程仓库推送镜像
# 在本地登录到远程仓库:
$ docker login --username=[用户名] -p=[密码] 远程ip:端口
# 给本地镜像打标签, [远程ip:端口/自定义路径/*]:[版本号] 就是:[标签名:版本号]
$ docker tag [镜像id:标签] [远程ip:端口/自定义路径/*]:[版本号]
# 推送
$ docker push [远程ip:端口/自定义路径/*]:[版本号]
实际操作:
$ docker tag hello-world daocloud.io/zter/hello-world:v1
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 9 weeks ago 1.84 kB
hello-world v1 fce289e99eb9 9 weeks ago 1.84 kB
hello-world v2 fce289e99eb9 9 weeks ago 1.84 kB
daocloud.io/zter/hello-world v1 fce289e99eb9 9 weeks ago 1.84 kB
$ docker push daocloud.io/zter/hello-world:v1
The push refers to a repository [daocloud.io/zter/hello-world]
af0b15c8625b: Pushed
v1: digest: sha256:39bbd4a41b5d3b164632d3b4a295c0db31139992a8fe985f949dac7ccff7aa54 size: 524
docker images [OPTIONS] [REPOSITORY[:TAG]]
OPTIONS说明:
[root@VM-0-11-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 9 months ago 13.3kB
# 删除指定镜像
$ docker rmi name
$ docker history [OPTIONS] IMAGE
OPTIONS说明:
# 查看本地镜像nice/ubuntu:v3的创建历史。
$ docker history nice/ubuntu:v3
$ docker save [OPTIONS] IMAGE [IMAGE...]
OPTIONS 说明:
# 将镜像 runoob/ubuntu:v3 生成 my_ubuntu_v3.tar 文档
$ docker save -o my_ubuntu_v3.tar runoob/ubuntu:v3
经过测试,导出镜像可以,导出容器不行
导入使用 docker save 命令导出的镜像。
$ docker load [OPTIONS]
OPTIONS 说明:
标记本地镜像,将其归入某一仓库。
$ docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
$ docker tag IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
# 创建一个容器,类似 docker run -d 命令
$ docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
docker create 创建的容器并未实际启动,还需要执行 docker start 命令或 docker run 命令以启动容器。docker create 命令常用于在启动容器之前进行必要的设置。 参数类似run。
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
bridge
使用 docker daemon 指定的网桥;host
容器使用主机的网络;container:NAME_or_ID
使用其他容器的网路,共享 IP 和 PORT 等网络资源;none
容器使用自己的网络(类似- -network=bridge),但是不进行配置。示例:
docker run -idt -v /:/home/lnmp --network host centos:centos7 /bin/bash
COMMAND、ARG...
代表容器运行之后,要执行的命令行命令和参数
# 运行容器,并进入bash
$ docker run -it nginx:latest /bin/bash
$ docker start [OPTIONS] CONTAINER [CONTAINER...]
Options:
$ docker stop [OPTIONS] CONTAINER [CONTAINER...]
Options:
$ docker restart contanier
$ docker kill container
docker rm [OPTIONS] CONTAINER [CONTAINER...]
Option参数:
暂停、恢复容器内的进程的运行。
$ docker pause CONTAINER [CONTAINER...]
$ docker unpause CONTAINER [CONTAINER...]
docker exec 用于在一个运行中的容器内执行command。
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
OPTIONS说明:
# 在指定容器打开一个bash环境的交互式终端
$ docker exec -i -t mynginx /bin/bash
$ docker ps [OPTIONS]
OPTIONS说明:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
容器运行时不一定有/bin/bash终端来交互执行top命令,而且容器还不一定有top命令,可以使用docker top来实现查看container中正在运行的进程
$ docker top CONTAINER [ps OPTIONS]
关联容器的标准输入、标准输出、错误输出到容器到本机
$ docker attach [OPTIONS] CONTAINER
options 说明
阻塞容器运行,直到容器停止运行,同时输出退出的状态码,通过状态码判断容器的退出状态。
$ docker wait CONTAINER [CONTAINER...]
docker port 命令可以用于列出指定的 Docker容器 的端口映射,或者将容器里的端口映射到宿主机。该命令后面的 CONTAINER 可以是容器Id,或者是容器名。
$ docker port [OPTIONS] CONTAINER [PRIVATE_PORT[/PROTO]]
$ docker port mysql
$ docker port mysql 3306/tcp
$ docker inspect [OPTIONS] NAME|ID [NAME|ID...]
OPTIONS说明:
$ docker rename CONTAINER NEW_NAME
docker stats 命令可以用于动态显示 Docker容器 的资源消耗情况,包括:CPU、内存、网络I/O。docker stats命令也可以指定已停止的容器,但是不会返回任何信息。
docker stats [options] [container...]
OPTIONS参数:
docker update [OPTIONS] CONTAINER [CONTAINER...]
OPTIONS说明:
将 Docker容器 里的文件系统作为一个 tar 归档文件导出。docker export 命令后面的 CONTAINER 可以是容器Id,或者是容器名。
$ docker export [OPTIONS] CONTAINER
OPTIONS说明:
用于导入export导出的镜像归档文件。
$ docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
$ docker images nicen/ubuntu:v4
参考
https://blog.csdn.net/JineD/article/details/118761569
从文件的角度来说,打包容器仅仅会打包容器的当前状态(类似服务器快照),会丢弃所有的历史记录和元数据信息。而打包镜像则是导出完整的历史记录和元信息。
从服务器获取实时事件
docker events [OPTIONS]
OPTIONS说明:
打印出指定的 Docker镜像 的历史版本信息。
docker history [OPTIONS] IMAGE
OPTIONS说明:
获取容器运行时输出的日志信息
docker logs [OPTIONS] CONTAINER
docker commit 命令用于根据 Docker容器 的更改创建一个新的 Dokcer镜像。该命令后面的 CONTAINER 可以是容器Id,或者是容器名。
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS说明:
# 从容器复制到宿主机
$ docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
# 从宿主机复制到容器
$ docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
OPTIONS说明:
命令说明
docker diff 命令用于比较一个 Docker容器 不同版本提交的文件差异。该命令后面的 CONTAINER 可以是容器Id,或者是容器名。
docker diff命令会列出 3 种容器内文件状态变化(A - Add, D - Delete, C - Change )的列表清单。
$ docker diff CONTAINER
docker build 命令可以用来使用 Dockerfile 创建镜像。
$ docker build [OPTIONS] PATH | URL | -
相关文档:https://www.runoob.com/docker/docker-build-command.html、https://www.runoob.com/docker/docker-dockerfile.html
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
原文
https://blog.csdn.net/qq_42418169/article/details/119102917
容器网络实质上也是由Docker为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作系统的网络环境中独立出来,形成容器自有的网络设备、IP协议栈、端口套接字、IP路由表、防火墙等等与网络相关的模块。
Docker网络中有三个核心概念:沙盒(Sandbox)、网络(Network)、端点(Endpoint)。
这三者形成Docker网络核心模型,也就是容器网络模型(Container Network Model)。
容器网络模型为容器引擎提供了一套标准的网络对接范式,Docker中,实现这套范式的是Docker所封装的libnetwork模块。
Docker官方提供了五种Docker网络驱动,分别是:Bridge Driver、Host Driver、Overlay Driver、MacLan Driver、None Driver。Bridge和 Overlay在开发中使用频率较高。
当你安装Docker时,它会自动创建三个网络。你可以使用docker network ls命令列出这些网络:
C:UsersAdmin>docker network ls
NETWORK ID NAME DRIVER SCOPE
ff3025b2bb75 bridge bridge local
4db4c96b8fad host host local
075e1e639650 none null local
Docker内置这三个网络,运行容器时,你可以在run运行容器时使用--network
标志来指定容器应连接到哪个网络。
不指定network时,默认将容器连接到bridge网络。
相当于Vmware中的桥接模式,与宿主机在同一个网络中,但没有独立IP地址。
Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。
一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
相当于Vmware中的Nat模式,容器使用独立network Namespace,并连接到docker0虚拟网卡(默认模式)。通过docker0网桥以及Iptables nat表配置与宿主机通信;bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。
Docker 默认的 bridge 网络是不支持通过 Docker DNS 服务进行域名解析的,自定义桥接网络是可以的。
当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。
虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。接下来就要为容器分配IP了,Docker会从RFC1918所定义的私有IP网段中,选择一个和宿主机不同的IP地址和子网分配给docker0,连接到docker0的容器就从这个子网中选择一个未占用的IP使用。
如一般Docker会使用172.17.0.0/16这个网段,并将172.17.0.1/16分配给docker0网桥(在主机上使用ifconfig命令是可以看到docker0的,可以认为它是网桥的管理接口,在宿主机上作为一块虚拟网卡使用)。单机环境下的网络拓扑如下,主机地址为10.10.0.186/24。
Docker完成以上网络配置的过程大致是这样的:
Overlay网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式。这样不但能够充分利用成熟的IP路由协议进程数据分发;而且在Overlay技术中采用扩展的隔离标识位数,能够突破VLAN的4000数量限制支持高达16M的用户,并在必要时可将广播流量转化为组播流量,避免广播数据泛滥。
因此,Overlay网络实际上是目前最主流的容器跨节点数据传输和路由方案。
要想使用Docker原生Overlay网络,需要满足下列任意条件
docker network inspect # 根据网络的ID展示网络的详细信息
docker network ls # 展示所有的网络,以列表形式
docker network create # 创建一个自定义网络
docker network connect # 连接一个容器到指定网络上
docker network disconnect # 让一个容器从指定网络上断开
docker network prune # 删除所有未使用的网络
docker network rm # 根据网络的ID,删除一个或多个网络
Docker Machine 是 Docker 官方提供的一个工具,它可以帮助我们在远程的机器上安装 Docker,或者在虚拟机 host 上直接安装虚拟机并在虚拟机中安装 Docker。我们还可以通过 docker-machine 命令来管理这些虚拟机和 Docker。
Docker Machine