课程目标: 1、什么是虚拟化 2、docker介绍 3、docker版本以及安装 4、docker架构 5、docker镜像操作 6、docker容器操作
在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种 实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结 构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资 源的新虚拟部份是不受现有资源的架设方式,地域或物理组态所限制。一般所指的虚拟 化资源包括计算能力和资料存储。
在实际的生产环境中,虚拟化技术主要用来解决高性能的物理硬件产能过剩和老的旧的 硬件产能过低的重组重用,透明化底层物理硬件,从而最大化的利用物理硬件 物理资 源的充分利用虚拟化技术种类很多,例如:软件虚拟化、硬件虚拟化、内存虚拟化、网络虚拟化、桌面虚拟化、服务虚拟化、虚拟机等等。
在全虚拟化的虚拟平台中,GuestOS并不知道自己是一台虚拟机,它会认为自己就是运 行在计算机物理硬件设备上的HostOS。因为全虚拟化的VMM会将一个OS所能够操作的 CPU、内存、外设等物理设备逻辑抽象成为虚拟CPU、虚拟内存、虚拟外设等虚拟设备 后,再交由GuestOS来操作使用。这样的GuestOS会将底层硬件平台视为自己所有的, 但是实际上,这些都是VMM为GuestOS制造了这种假象。
操作系统层虚拟化是指通过划分一个宿主操作系统的特定部分,产生一个个隔离的操作 执行环境。操作系统层的虚拟化是操作系统内核直接提供的虚报化,虚拟出的操作系统 之间共享底层宿主操作系统内核和底层的硬件资源。操作系统虚拟化的关键点在于将操 作系统与上层应用隔离开,将对操作系统资源的访问进行虚报化,使上层应用觉得自己 独占操作系统。
平台虚拟化表现为在一个给定的硬件平台上宿主机创造一个模拟的计算机环境虚拟机提 供给客户机。客户机软件对于用户应用程序没有限制;许多宿主机允许运行真实的操作系 统。客户机就好像直接运行在计算机硬件上,伴随着几个明显的警告。虚拟机对硬件资 源(如网络,显示器,键盘,硬盘)的访问被统一管理在一个比处理器和系统内存更有限制 性的层次上。客户软件经常被限制访问计算机周边设备,或者被限制在较低的设备性能 上,这取决于宿主机硬件访问策略设定。
Hypervisor是一种运行在物理服务器和操作系统之间的中间软件层,可允许多个操作系统 和应用共享一套基础物理硬件,因此也可以看作是虚拟环境中的“元”操作系统,它可以协 调访问服务器上的所有物理设备和虚拟机,也叫虚拟机监视器(Virtual Machine Monitor,VMM)。Hypervisor是所有虚拟化技术的核心。当服务器启动并执行 Hypervisor时,它会给每一台虚拟机分配适量的内存、CPU、网络和磁盘,并加载所有 虚拟机的客户操作系统。 Hypervisor是所有虚拟化技术的核心,软硬件架构和管理更高效、更灵活,硬件的效能 能够更好地发挥出来。常见的产品有:VMware、KVM、Xen等等。
在计算机的世界中,容器拥有一段漫长且传奇的历史。容器与管理程序虚拟化 (hypervisor virtualization,HV)有所不同,管理程序虚拟化通过中间层将一台或者多 台独立的机器虚拟运行与物理硬件之上,而容器则是直接运行在操作系统内核之上的用 户空间。因此,容器虚拟化也被称为“操作系统级虚拟化”,容器技术可以让多个独立的用 户空间运行在同一台宿主机上。
由于 “客居”于操作系统,容器只能运行与底层宿主机相同或者相似的操作系统,这看起来 并不是非常灵活。例如:可以在Ubuntu服务中运行Redhat Enterprise Linux,但无法再 Ubuntu服务器上运行Microsoft Windows。 相对于彻底隔离的管理程序虚拟化,容器被认为是不安全的。而反对这一观点的人则认 为,由于虚拟容器所虚拟的是一个完整的操作系统,这无疑增大了攻击范围,而且还要 考虑管理程序层潜在的暴露风险。 尽管有诸多局限性,容器还是被广泛部署于各种各样的应用场合。在超大规模的多租户 服务部署、轻量级沙盒以及对安全要求不太高的隔离环境中,容器技术非常流行。最常 见的一个例子就是“权限隔离监牢”(chroot jail),它创建一个隔离的目录环境来运行进 程。如果权限隔离监牢正在运行的进程被入侵者攻破,入侵者便会发现自己“身陷囹圄”, 因为权限不足被困在容器所创建的目录中,无法对宿主机进一步破坏。 最新的容器技术引入了OpenVZ、Solaris Zones以及Linux容器(LXC)。使用这些新技 术,容器不在仅仅是一个单纯的运行环境。在自己的权限类内,容器更像是一个完整的 宿主机。容器和宿主机之间的隔离更加彻底,容器有独立的网络和存储栈,还拥有自己 的资源管理能力,使得同一台宿主机中的多个容器可以友好的共存。 容器被认为是精益技术,因为容器需要的开销有限。和传统虚拟化以及半虚拟化相比, 容器不需要模拟层(emulation layer)和管理层(hypervisor layer),而是使用操作系 统的系统调用接口。这降低了运行单个容器所需的开销,也使得宿主机中可以运行更多 的容器。 尽管有着光辉的历史,容器仍未得到广泛的认可。一个很重要的原因就是容器技术的复 杂性:容器本身就比较复杂,不易安装,管理和自动化也很困难。而Docker就是为了改 变这一切而生的。
Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production. Docker 是一个开发,运输和运行应用程序的开放平台。 Docker使您可以将应用程序与基 础架构分离,以便快速交付软件。 使用Docker,您可以像管理应用程序一样管理基础架 构(OS)。 通过利用Docker的方法快速发送,测试和部署代码,您可以显着减少编写代 码和在生产中运行代码之间的延迟。(代码改了)
容器提供了隔离性,结论是,容器可以为各种测试提供很好的沙盒环境。并且,容器本 身就具有“标准性”的特征,非常适合为服务创建构建块。Docker的一些应用场景如下:
加速本地开发和构建流程,使其更加高效、更加轻量化。本地开发人员可以构建、运 行并分享Docker容器。容器可以在开发环境中构建,然后轻松的提交到测试环境 中,并最终进入生产环境。 开发人员与运维人员进行职责的逻辑分离
能够让独立的服务或应用程序在不同的环境中,得到相同的运行结果。这一点在面向 服务的架构和重度依赖微型服务的部署由其实用。
用 Docker创建隔离的环境来进行测试。例如,用Jenkins CI这样的持续集成工具启动 一个用于测试的容器。(持续化集成 war 实际部署:jenkins持续化集成 Jenkins+git )
Docker 可以让开发者先在本机上构建一个复杂的程序或架构来进行测试,而不是一 开始就在生产环境部署、测试。
构建一个多用户的平台即服务( PaaS)基础设施
为开发、测试提供一个轻量级的独立的沙盒环境
提供软件即服务( SaaS)应用程序,例如Memcached即服务
高性能、超大规模的宿主机部署(可以很多容器)
沙盒:在计算机安全领域,沙盒(英语:sandbox,又译为沙箱)是一种安全机制,为运行 中的程序提供的隔离环境。通常是作为一些来源不可信、具破坏力或无法判定程序意图的程 序提供实验之用。
Docker借鉴了标准集装箱的概念。标准集装箱将货物运往世界各地,Dock将这个模型运 用到自己的设计中,唯一不同的是:集装箱运输货物,而Docker运输软件、应用程序。 和集装箱一样,Docker在执行上述操作时,并不关心容器中到底装了什么,它不管是 web服务器,还是数据库,或者是应用程序服务器什么的。所有的容器都按照相同的方 式将内容“装载”进去。 Docker也不关心你要把容器运到何方:我们可以在自己的笔记本中构建容器,上传到 Registry,然后下载到一个物理的或者虚拟的服务器来测试,在把容器部署到具体的主机 中。像标准集装箱一样,Docker容器方便替换,可以叠加,易于分发,并且尽量通用。
物理机:一栋楼一户人家独立地基,独立花园
虚拟机:一栋楼包含多套房一套房一户人家,共享地基,共享花园,独立卫生间、厨房和宽带
容器:最大化的利用资源。
一栋楼包含多套房一套房一户人家,共享地基,共享花园,独立卫生间、厨房和宽带
通过上面这三张抽象图,我们大概可以通过类比概括出: 容器虚拟化的是操作系统而不 是硬件,容器之间是共享同一套操作系统资源的。虚拟机技术是虚拟出一套硬件后,在 其上运行一个完整操作系统。 容器和虚拟机具有相似的资源隔离和分配优势,但功能有所不同,因为容器虚拟化的是 操作系统,而不是硬件,因此容器更容易移植,效率也更高。 容器在Linux上本机运行,并与其他容器共享主机的内核。 它运行一个独立的进程,不占 用任何其他可执行文件的内存,使其轻量级。相比之下,虚拟机(VM)运行一个完整 的“客户”操作系统,通过虚拟机管理程序对主机资源进行虚拟访问。 通常,VM提供的环 境比大多数应用程序需要的资源更多。
容器是一个应用层抽象,用于将代码和依赖资源打包在一起。 多个容器可以在同一 台机器上运行,共享操作系统内核,但各自作为独立的进程在用户空间中运行 。与 虚拟机相比, 容器占用的空间较少(容器镜像大小通常只有几十兆),瞬间就能完 成启动 。
虚拟机( VM)是一个物理硬件层抽象,用于将一台服务器变成多台服务器。 管理程 序允许多个VM在一台机器上运行。每个VM都包含一整套操作系统、一个或多个应 用、必要的二进制文件和库资源,因此占用大量空间。而且VM启动也十分缓慢 。
https://www.docker.com/
Docker CE 在 17.03 版本之前叫 Docker Engine, Docker Engine 的版本号范围: 0.1.0 ~ 1.13.1 在 2017 年 3 月 2 日, docker 团队宣布企业版 Docker Enterprise Edition ( EE ) 发布. 为 了一致, 免费的 Docker Engine 改名为 Docker Community Edition ( CE ), 并且采用基于 时间的版本号方案. 就在这一天, Docker EE 和 Docker CE 的 17.03 版本发布, 这也是第一 个采用新的版本号方案的版本. Docker CE/EE 每个季度发布一次 季度版本, 也就是说每年会发布 4 个季度版本, 17.03, 17.06, 17.09, 17.12 就是 2017 年的 4 个季度版本的版本号, 同时 Docker CE 每个月还会 发布一个 EDGE 版本,比如 17.04, 17.05, 17.07, 17.08, 17.10, 17.11 ...... Docker CE 季度版本自发布后会有 4 个月的维护期. 在基于时间的发布方案中,版本号格式为: YY.MM.,YY.MM 代表年月,patch 代表补丁 号,从 0 开始,在季度版本 (如 17.03) 的维护期内,bug 修复相关的更新会以 patch 递 增的方式发布, 比如 17.03.0 -> 17.03.1 -> 17.03.2
Docker is available in two editions:
Community Edition (CE) :社区版
Enterprise Edition (EE) :企业版
Docker Community Edition (CE) is ideal for individual developers and small teams looking to get started with Docker and experimenting with container-based apps. Docker Enterprise Edition (EE) is designed for enterprise development and IT teams who build, ship, and run business critical applications in production at scale.
docker对Ubuntu的支持是最好的,因此本次学习的过程中我们在Ubuntu下安装docker ce版本。如果是 CentOS:安装docker 建议7.x及以上版本。 Docker支持在多种平台上使用,包括Mac、Windows、Cloud以及Linux系统上等。由于 Docker是基于Ubuntu发布的,所以官方更推荐在Ubuntu上使用Docker,开发者也可以 根据自己的实际开发环境选择合适的开发。在不同的平台上安装Docker必须满足不同的 先决条件。本次选择在Ubuntu16.04版本上使用Docker。
[安装链接地址] https://docs.docker.com/install/linux/docker-ce/centos/
一、卸载旧版本 较旧的Docker版本称为docker或docker-engine。如果已安装这些程序,请卸载它们以及相关的依赖项。 $ sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine 二、安装Docker Engine-Community 安装方式:使用存储库安装 大多数用户会设置Docker的存储库并从中进行安装,以简化安装和升级任务。这是推荐的方法。 在新主机上首次安装Docker Engine-Community之前,需要设置Docker存储库。之后,您可以从存储库安装和更新Docker。 (1)设置存储库: 1、安装所需的软件包。yum-utils提供了yum-config-manager 效用,并device-mapper-persistent-data和lvm2由需要 devicemapper存储驱动程序。 $ sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2 2、使用以下命令来设置稳定的存储库。 $ sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo (2)启用每晚或测试存储库(可选): $ sudo yum-config-manager --enable docker-ce-nightly $ sudo yum-config-manager --enable docker-ce-test --启用测试通道 $ sudo yum-config-manager --disable docker-ce-nightly (3)安装Docker Engine-Community: 1、$ sudo yum install docker-ce docker-ce-cli containerd.io 如果提示您接受GPG密钥,请验证指纹是否匹配 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35,如果是,则接受它。 2、要安装特定版本的Docker Engine-Community,请在存储库中列出可用版本,然后选择并安装 a、此示例按版本号(从高到低)对结果进行排序 $ yum list docker-ce --showduplicates | sort -r [root@docker1 ~]# yum list docker-ce --showduplicates | sort -r 已加载插件:fastestmirror 已安装的软件包 可安装的软件包 * updates: mirror.jdcloud.com Loading mirror speeds from cached hostfile * extras: mirrors.aliyun.com docker-ce.x86_64 3:19.03.5-3.el7 docker-ce-test docker-ce.x86_64 3:19.03.5-3.el7 docker-ce-stable docker-ce.x86_64 3:19.03.5-3.el7 @docker-ce-stable docker-ce.x86_64 3:19.03.5-2.1.rc1.el7 docker-ce-test docker-ce.x86_64 3:19.03.5-1.2.beta2.el7 docker-ce-test b、通过其完全合格的软件包名称安装特定版本,该软件包名称是软件包名称(docker-ce)加上版本字符串(第二列),从第一个冒号(:)一直到第一个连字符,并用连字符(-)分隔。例如,docker-ce-18.09.1。 $ sudo yum install docker-ce-docker-ce-cli- containerd.io 3、启动Docker $ sudo systemctl start docker 4、通过运行hello-world 映像来验证是否正确安装了Docker Engine-Community 。 $ sudo docker run hello-world
查看帮助文档 docker --help 查看docker详细信息 docker info 查看docker版本 docker ‐‐version/version(c/s架构 server:docker engine架构) 启动/停止/重启docker: sudo systemctl start/stop/restart docker Ubuntu:开机自动启动 CentOS:手动启动 开机启动:systemctl enable docker 查看docker运行状态 sudo sytemctl status docker
Docker uses a client-server architecture. The Docker client talks to the Docker daemon, which does the heavy lifting of building, running, and distributing your Docker containers. The Docker client and daemon can run on the same system, or you can connect a Docker client to a remote Docker daemon. The Docker client and daemon communicate using a REST API, over UNIX sockets or a network interface. (Docker使用客户端 - 服务器架构。 Docker客户端与Docker守护进 程通信,后者负责构建,运行和分发Docker容器。 Docker客户端和守护程序可以在同一 系统上运行,也可以将Docker客户端连接到远程Docker守护程序。 Docker客户端和守 护程序使用REST API,通过UNIX套接字或网络接口进行通信。)
The Docker daemon ( dockerd ) listens for Docker API requests and manages Docker objects such as images, containers, networks, and volumes. A daemon can also communicate with other daemons to manage Docker services. (Docker守护程 序(dockerd)侦听Docker API请求并管理Docker对象,如图像,容器,网络和卷。 守 护程序还可以与其他守护程序通信以管理Docker服务。)
The Docker client ( docker ) is the primary way that many Docker users interact with Docker. When you use commands such as docker run , the client sends these commands to dockerd , which carries them out. The docker command uses the Docker API. The Docker client can communicate with more than one daemon. (Docker客户端(docker)是许多Docker用户与Docker交互的主要方式。 当您使用诸如 docker run之类的命令时,客户端会将这些命令发送到dockerd,后者将其执行。 docker命令使用Docker API。 Docker客户端可以与多个守护进程通信。)
A Docker registry stores Docker images. Docker Hub is a public registry that anyone can use, and Docker is configured to look for images on Docker Hub by default. You can even run your own private registry. If you use Docker Datacenter (DDC), it includes Docker Trusted Registry (DTR). When you use the docker pull or docker run commands, the required images are pulled from your configured registry. When you use the docker push command, your image is pushed to your configured registry.(Docker注册表存储 Docker镜像。 Docker Hub是任何人都可以使用的公共注册中心,Docker配置为默认在 Docker Hub上查找图像。 您甚至可以运行自己的私人注册表。 如果您使用Docker Datacenter(DDC),它包括Docker Trusted Registry(DTR)。使用docker pull或 docker run命令时,将从配置的注册表中提取所需的映像。 使用docker push命令时, 图像将被推送到配置的注册表。)
Docker 镜像是容器的基础。镜像是一个有序集合,其中包含根文件系统更改和在容器运 行时中使用的相应执行参数。镜像通常 包含堆叠在彼此之上的联合分层文件系统。镜像 没有状态并且始终不会发生更改。 当运行容器时,使用的镜像如果在本地中不存在, docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。
docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello‐world latest fce289e99eb9 5 months ago 1.84kB 这些镜像都是存储在Docker宿主机的/var/lib/docker目录下。
REPOSITORY :表示镜像的仓库源
TAG :镜像的标签(版本),同一仓库源可以有多个 TAG,代表这个仓库源的不同 个版本,如ubuntu仓库源里,有15.10、14.04等多个不同的版本。
IMAGE ID :镜像ID
CREATED :镜像创建时间
SIZE :镜像大小
[root@docker1 ~]# docker search centos NAME DESCRIPTION STARS OFFICIAL AUTOMATED centos The official build of CentOS. 5685 [OK] ansible/centos7-ansible Ansible on Centos7 125 [OK] jdeathe/centos-ssh OpenSSH / Supervisor / EPEL/IUS/SCL Repos - … 114 [OK] consol/centos-xfce-vnc Centos container with "headless" VNC session… 100 [OK] centos/mysql-57-centos7 MySQL 5.7 SQL database server 64 imagine10255/centos6-lnmp-php56 centos6-lnmp-php56 57 [OK] tutum/centos Simple CentOS docker image with SSH access 44 centos/postgresql-96-centos7 PostgreSQL is an advanced Object-Relational … 39 kinogmt/centos-ssh CentOS with SSH 29 [OK] pivotaldata/centos-gpdb-dev CentOS image for GPDB development. Tag names… 10 guyton/centos6 From official centos6 container with full up… 9 [OK] nathonfowlie/centos-jre Latest CentOS image with the JRE pre-install… 8 [OK] drecom/centos-ruby centos ruby 6 [OK] darksheer/centos Base Centos Image -- Updated hourly 3 [OK] mamohr/centos-java Oracle Java 8 Docker image based on Centos 7 3 [OK] pivotaldata/centos Base centos, freshened up a little with a Do… 3 pivotaldata/centos-mingw Using the mingw toolchain to cross-compile t… 2 miko2u/centos6 CentOS6 日本語環境 2 [OK] pivotaldata/centos-gcc-toolchain CentOS with a toolchain, but unaffiliated wi… 2 indigo/centos-maven Vanilla CentOS 7 with Oracle Java Developmen… 1 [OK] mcnaughton/centos-base centos base image 1 [OK] blacklabelops/centos CentOS Base Image! Built and Updates Daily! 1 [OK] pivotaldata/centos6.8-dev CentosOS 6.8 image for GPDB development 0 pivotaldata/centos7-dev CentosOS 7 image for GPDB development 0 smartentry/centos centos with smartentry 0 [OK]
NAME :镜像仓库源的名称
DESCRIPTION:镜像的描述
starts:用户评价,反应一个镜像的受欢迎程度
OFFICIAL:是否docker官方发布
auto commit:自动构建,表示该镜像由Docker Hub自动构建流程创建的
docker pull 镜像名称[:version]
Docker镜像首页,包括官方镜像和其它公开镜像。Docker Hub上最受欢迎的10大镜像 (通过Docker registry API获取不了镜像被pull的个数,只能通过镜像的stars数量,来衡 量镜像的流行度。毫无疑问,拥有最高stars数量的库都是官方库。国情的原因,国内下 载 Docker HUB 官方的相关镜像比较慢,可以使用国内(docker.io)的一些镜像加速 器,镜像保持和官方一致,关键是速度块,推荐使用。
配置镜像加速器:
PS:配置镜像加速器(参考该网站具体的文档操作) ‐ 阿里云(先加入阿里云开发者平台:https://dev.aliyun.com) ‐ docker中国加速器(https://www.docker‐cn.com) ‐ USTC加速器(https://lug.ustc.edu.cn/wiki/ ) 真正的公共服务(无需任何操 作) ‐ daocloud、网易蜂巢加速器:略 步骤: sudo vim /etc/docker/daemon.json 配置内容: { "registry‐mirrors": ["https://cs913o6k.mirror.aliyuncs.com"] } sudo systemctl daemon‐reload sudo systemctl restart docker
Error1:在拉取镜像时候,出现如下错误,可以配置镜像加速器
Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
1、删除一个镜像 docker rmi 镜像名称/id 2、删除多个镜像 docker rmi 镜像名称1/id1 镜像名称2/id2 ... 3、删除所有镜像 docker rmi `docker images ‐q`
容器是 docker 镜像的运行时实例。
docker run [options] image command [ARG...] options选项: ‐i、‐t、‐d、‐‐name ‐i:交互式容器 ‐t:tty,终端 ‐d:后台运行,并且打印容器id sh /usr/local/tomcat7/bin/startup.sh(shell脚本 #/bin/bash py rb lua) Linux:根的进程:/bin/bash tree /xxx /yyy eg:创建的容器名称不能重复 创建交互式容器:创建后进去容器 docker run -i -t --name=c1 centos /bin/bash 交互式容器省写 docker run -it --name c2 centos /bin/bash 创建守护式容器:后台运行,创建后打印id,并未进去容器 docker run -itd --name c3 centos /bin/bash
方式一: docker attach 容器名称/id (ps:exit,容器停止) eg:docker attach u3 方式二: docker exec ‐it 容器名称/id /bin/bash (ps:exit,容器不会停止) eg:docker exec ‐it c3 /bin/bash
docker ps:查看正在运行的容器 docker ps ‐a:查看运行过的容器(历史) docker ps ‐l:最后一次运行的容器 docker attach 容器
docker start 容器名称/id docker stop 容器名称/id
查看容器/镜像全部信息: docker inspect 容器/镜像 查看容器/镜像部分信息: docker inspect ‐f='{{.NetworkSettings.IPAddress}}' 容器/镜像 ‐f:可通过‐‐format代替
删除一个容器: docker rm 容器名称/id 删除多个容器: docker rm 容器名称1/id1 容器名称2/id2 ... 删除所有容器 docker rm `docker ps ‐a ‐q` PS:无法删除正在运行的容器
docker logs 容器名称/id
如果我们需要将文件拷贝到容器内可以使用cp命令
docker cp 需要拷贝的文件或目录 容器名称:容器目录 例如:docker cp 1.txt c2:/root
也可以将文件从容器内拷贝出来
docker cp 容器名称:容器目录 需要拷贝的文件或目录 例如:docker cp c2:/root/2.txt /root
我们可以在创建容器的时候,将宿主机的目录与容器内的目录进行映射,这样我们就可 以通过修改宿主机某个目录的文件从而去影响容器。 创建容器 添加-v参数 后边为 宿主机目录:容器目录
docker run ‐id ‐‐name=c4 ‐v /opt/:/usr/local/myhtml centos
如果你共享的是多级的目录,可能会出现权限不足的提示
permission denied
这是因为 CentOS7中的安全模块selinux把权限禁掉了,我们需要添加参数 -- privileged=true 来解决挂载的目录没有权限的问题
docker run ‐id ‐‐privileged=true ‐‐name=c4 ‐v /opt/:/usr/local/myhtml centos
docker官方和个人发布的镜像由于版本等各种原因,漏洞较多,已统计Docker Hub超过 30%的官方镜像包含高危漏洞。此外,由于网络等原因也会造成docker pull下载镜像的 速度很慢。基于这种情况,我们可以手动定制docker系统镜像。构建镜像的方式有两 种:
使用 docker commit命令
使用 docker build和Dockerfile文件
7.1.1 制作步骤
docker commit:提交一个正在运行的容器为一个新的镜像 本例:制作一个tomcat镜像,制作步骤: 1、拉取一个基础镜像(其始就是OS) docker pull centos 2、创建一个交互式容器 docker run ‐it ‐‐name=mycentos centos:latest docker run -it --name mycentos centos /bin/bash 3、软件上传:将宿主机Tomact、jdk上传到容器中 yum -y install lrzsz docker cp apache-tomcat-7.0.47.tar.gz mycentos:/root/ docker cp jdk-8u161-linux-x64.tar.gz mycentos:/root/ 4、在容器中安装jdk (yum install java‐1.7.0‐openjdk) tar ‐zxvf jdk‐8u161‐linux‐x64.tar.gz ‐C /usr/local/ 编辑/etc/profile文件,(vi /etc/profile,之后刷新source /etc/profile, 验证java -version)添加如下内容: JAVA_HOME=/usr/local/jdk1.8.0_161 export PATH=$JAVA_HOME/bin:$PATH 5、在容器中安装tomcat tar ‐zxvf apache‐tomcat‐7.0.47.tar.gz ‐C /usr/local/ 编辑tomcat/bin/setclsspath.sh文件,添加如下内容: export JAVA_HOME=/usr/local/jdk1.8.0_161 export JRE_HOME=/usr/local/jdk1.8.0_161/jre 6、启动tamcat,查看是否安装成功 /usr/local/apache-tomcat-7.0.47/bin/startup.sh 7、将正在运行的容器提交为一个新的镜像 docker commit mycentos mytomcat
7.1.2 端口映射
docker run ‐itd ‐‐name=t1 ‐p 8888:8080 mytomcat /bin/bash docker exec t1 /usr/local/apache‐tomcat‐7.0.47/bin/startup.sh 或者docker exec -it t1 /bin/bash /usr/local/apache‐tomcat‐7.0.47/bin/startup.sh
通过宿主机访问:http://ip:port
注意:尽量手敲,复制终端可能不识别,报各种错误
7.1.4 容器/镜像打包
镜像打包: 1、镜像打包: docker save ‐o /root/tomcat7.tar mytomcat 2、将打包的镜像上传到其他服务器 scp tomcat7.tar 其他服务器ip:/root 3、导入镜像 docker load ‐i /root/tomcat7.tar 容器打包: 1、容器打包 docker export ‐o /root/t1.tar t1 2、导入容器 docker import t1.tar mytomcat:latest
Dockerfile使用基本的基于DSL语法的指令来构建一个Docker镜像,之后使用docker builder命令基于该Dockerfile中的指令构建一个新的镜像。
7.2.1 DSL语法
DSL语法: 1)FROM(指定基础image) 构建指令,必须指定且需要在Dockerfile其他指令的前面。后续的指令都依赖于该指令指定 的image。FROM指令指定的基础image可以是官方远程仓库中的,也可以位于本地仓库。 FROM命令告诉docker我们构建的镜像是以哪个(发行版)镜像为基础的。第一条指令必须是 FROM指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM 指 令。 该指令有两种格式: FROM指定基础image为该image的最后修改的版本。或者: FROM : 指定基础image为该image的一个tag版本。 RUN后面接要执行的命令,比如,我们想在镜像中安装vim,只需在Dockfile中写入 RUN yum install ‐y vim 2)MAINTAINER(用来指定镜像创建者信息) 构建指令,用于将image的制作者相关的信息写入到image中。当我们对该image执行docker inspect命令时,输出中有相应的字段记录该信息。 格式: MAINTAINER 3)RUN(安装软件用) 构建指令,RUN可以运行任何被基础image支持的命令。如基础image选择了ubuntu,那么软 件管理部分只能使用ubuntu的命令。 该指令有两种格式: RUN RUN ["executable", "param1", "param2" ... ] 4)CMD(设置container启动时执行的操作) 设置指令,用于container启动时指定的操作。该操作可以是执行自定义脚本,也可以是执 行系统命令。该指令只能在文件中存在一次,如果有多个,则只执行最后一条。 该指令有三种格式: CMD ["executable","param1","param2"] CMD command param1 param2 当Dockerfile指定了ENTRYPOINT,那么使用下面的格式: CMD ["param1","param2"] 其中: ENTRYPOINT指定的是一个可执行的脚本或者程序的路径,该指定的脚本或者程序将会以 param1和param2作为参数执行。 所以如果CMD指令使用上面的形式,那么Dockerfile中必须要有配套的ENTRYPOINT。 5)ENTRYPOINT(设置container启动时执行的操作) 设置指令,指定容器启动时执行的命令,可以多次设置,但是只有最后一个有效。 两种格式: ENTRYPOINT ["executable", "param1", "param2"] ENTRYPOINT command param1 param2 该指令的使用分为两种情况,一种是独自使用,另一种和CMD指令配合使用。 当独自使用时,如果你还使用了CMD命令且CMD是一个完整的可执行的命令,那么CMD指令和 ENTRYPOINT会互相覆盖,只有最后一个CMD或者ENTRYPOINT有效。 # CMD指令将不会被执行,只有ENTRYPOINT指令被执行 CMD echo “Hello, World!” ENTRYPOINT ls ‐l 另一种用法和CMD指令配合使用来指定ENTRYPOINT的默认参数,这时CMD指令不是一个完整 的可执行命令,仅仅是参数部分; ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数。 FROM ubuntu CMD ["‐l"] ENTRYPOINT ["/usr/bin/ls"] 6)USER(设置container容器的用户) 设置指令,设置启动容器的用户,默认是root用户。 # 指定memcached的运行用户 ENTRYPOINT ["memcached"] USER daemon 或者 ENTRYPOINT ["memcached", "‐u", "daemon"] 7)EXPOSE(指定容器需要映射到宿主机器的端口) 设置指令,该指令会将容器中的端口映射成宿主机器中的某个端口。当你需要访问容器的时 候,可以不是用容器的IP地址而是使用宿主机器的IP地址和映射后的端口。 要完成整个操作需要两个步骤,首先在Dockerfile使用EXPOSE设置需要映射的容器端口, 然后在运行容器的时候指定‐p选项加上EXPOSE设置的端口,这样EXPOSE设置的端口号会被 随机映射成宿主机器中的一个端口号。 也可以指定需要映射到宿主机器的那个端口,这时要确保宿主机器上的端口号没有被使用。 EXPOSE指令可以一次设置多个端口号,相应的运行容器的时候,可以配套的多次使用‐p选 项。 格式: EXPOSE [ ...] # 映射一个端口 EXPOSE port1 # 相应的运行容器使用的命令 docker run ‐p port1 image # 映射多个端口 EXPOSE port1 port2 port3 # 相应的运行容器使用的命令 docker run ‐p port1 ‐p port2 ‐p port3 image # 还可以指定需要映射到宿主机器上的某个端口号 docker run ‐p host_port1:port1 ‐p host_port2:port2 ‐p host_port3:port3 image 端口映射是docker比较重要的一个功能,原因在于我们每次运行容器的时候容器的IP地址不 能指定而是在桥接网卡的地址范围内随机生成的。 宿主机器的IP地址是固定的,我们可以将容器的端口的映射到宿主机器上的一个端口,免去 每次访问容器中的某个服务时都要查看容器的IP的地址。 对于一个运行的容器,可以使用docker port加上容器中需要映射的端口和容器的ID来查看 该端口号在宿主机器上的映射端口。 8)ENV(用于设置环境变量) 主要用于设置容器运行时的环境变量 格式: ENV 设置了后,后续的RUN命令都可以使用,container启动后,可以通过docker inspect查看 这个环境变量,也可以通过在docker run ‐‐env key=value时设置或修改环境变量。 假如你安装了JAVA程序,需要设置JAVA_HOME,那么可以在Dockerfile中这样写: ENV JAVA_HOME /path/to/java/dirent 9)ADD(从src复制文件到container的dest路径) 主要用于将宿主机中的文件添加到镜像中 构建指令,所有拷贝到container中的文件和文件夹权限为0755,uid和gid为0;如果是一 个目录,那么会将该目录下的所有文件添加到container中,不包括目录; 如果文件是可识别的压缩格式,则docker会帮忙解压缩(注意压缩格式);如果 是文 件且 中不使用斜杠结束,则会将 视为文件, 的内容会写入 ; 如果 是文件且 中使用斜杠结束,则会 文件拷贝到 目录下。 格式: ADD 是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的 文件url; 是container中的绝对路径 10)VOLUME(指定挂载点)) 设置指令,使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用, 也可以共享给其他容器使用。我们知道容器使用的是AUFS, 这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。当容器中的应用有持 久化数据的需求时可以在Dockerfile中使用该指令。 格式: VOLUME [" "] 例如: FROM base VOLUME ["/tmp/data"] 运行通过该Dockerfile生成image的容器,/tmp/data目录中的数据在容器关闭后,里面的 数据还存在。 例如另一个容器也有持久化数据的需求,且想使用上面容器共享的/tmp/data目录,那么可 以运行下面的命令启动一个容器: docker run ‐t ‐i ‐rm ‐volumes‐from container1 image2 bash 其中:container1为第一个容器的ID,image2为第二个容器运行image的名字。 1.2.2 案例 11)WORKDIR(切换目录) 设置指令,可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效。 格式: WORKDIR /path/to/workdir # 在/p1/p2下执行vim a.txt WORKDIR /p1 WORKDIR p2 RUN vim a.txt 12)ONBUILD(在子镜像中执行) 格式: ONBUILD ONBUILD 指定的命令在构建镜像时并不执行,而是在它的子镜像中执行。
7.2.2 案例
通过dockerfile构建镜像步骤: 1、创建一个目录 2、在目录下创建Dockerfile文件以及其他文件 3、通过docker build构建镜像 4、通过构建的镜像启动容器 栗子: 1、创建一个目录:/usr/local/rw_test 2、编辑Dockerfile文件,vim Dockerfile 3、编辑内容如下 #pull down centos image FROM docker.io/centos MAINTAINER ruanwen [email protected] #install nginx RUN yum install ‐y pcre pcre‐devel openssl openssl‐devel gcc gcc+ wget vim net‐tools RUN useradd www ‐M ‐s /sbin/nologin RUN cd /usr/local/src && wget http://nginx.org/download/nginx‐ 1.8.0.tar.gz && tar ‐zxvf nginx‐1.8.0.tar.gz RUN cd /usr/local/src/nginx‐1.8.0 && ./configure ‐‐ prefix=/usr/local/nginx ‐‐user=www ‐‐group=www ‐‐with‐ http_stub_status_module ‐‐with‐http_ssl_module && make && make install ENTRYPOINT /usr/local/nginx/sbin/nginx && tail ‐f /usr/local/nginx/logs/access.log 4、在rw_test目录下构建镜像: docker build ‐t rw_nginx ‐‐rm=true . ‐t 表示选择指定生成镜像的用户名,仓库名和tag ‐‐rm=true 表示指定在生成镜像过程中删除中间产生的临时容器。 注意:上面构建命令中最后的.符号不要漏了,表示使用当前目录下的Dockerfile构建镜像 5、测试 docker run ‐ti ‐d ‐‐name test_nginx ‐p 8899:80 rw_nginx /bin/bash docker exec test_nginx /bin/bash 通过浏览器访问:http://ip:8899
Docker仓库(Repository)类似与代码仓库,是Docker集中存放镜像文件的地方。
1、打开https://hub.docker.com/ 2、注册账号:略 3、创建仓库(Create Repository):略 4、设置镜像标签 docker tag local‐image:tagname new‐repo:tagname(设置tag) eg:docker tag hello‐world:latest 108001509033/test‐hello‐world:v1 docker tag hello-world:latest eadela/hello-world:v1 5、登录docker hub docker login(回车,输入账号以及密码) 6、推送镜像 docker push new‐repo:tagname eg:docker push 108001509033/test‐hello‐world:v1 docker push eadela/hello-world:v1
Error response from daemon: manifest for hello-world:v1 not found: manifest unknown: manifest unknown 加登陆账号昵称
Error: No such image: eadela_docker_test/hello-world 加标签
denied: requested access to the resource is denied 在镜像前加登陆名
略:参考官方文档。
步骤: 1、创建阿里云账号 2、创建命名空间 3、创建镜像仓库 4、操作指南 $ sudo docker login ‐‐username=[账号名称] registry.cn‐ hangzhou.aliyuncs.com $ sudo docker tag [ImageId] registry.cn‐ hangzhou.aliyuncs.com/360buy/portal:[镜像版本号] $ sudo docker push registry.cn‐hangzhou.aliyuncs.com/360buy/portal:[镜像版 本号]
8.3.1 构建私有仓库
1、启动Docker Registry,使用Docker官方提供的Registry镜像就可以搭建本地私有镜像 仓库,具体指令如下。 $ docker run ‐d \ ‐p 5000:5000 \ ‐‐restart=always \ ‐‐name registry \ ‐v /mnt/registry:/var/lib/registry \ registry:2 指令参数说明: ‐d:表示在后台运行该容器; ‐p 5000:5000:表示将私有镜像仓库容器内部默认暴露的5000端口映射到宿主机的5000端 口 ‐‐restart=always:表示容器启动后自动启动本地私有镜像仓库 ‐‐name registry:表示为生成的容器命名为registry ‐v /mnt/registry:/var/lib/registry:表示将容器内的默认存储位 置/var/lib/registry中的数据挂载到宿主机的/mnt/registry目录下,这样当容器销毁 后,在容器中/var/lib/registry目录下的数据会自动备份到宿主机指定目录 小提示: Docker Registry目前有v1和v2两个版本,v2版本并不是v1版本的简单升级,而是在很多 功能上都有了改进和优化。v1版本使用的是Python开发的,而v2版本是用go语言开发的; v1版本本地镜像仓库容器中数据默认挂载点是/tmp/registry,而v2版本的本地镜像仓库容 器中数据默认挂载点是/var/lib/registry 2、重命名镜像,之前推送镜像时,都是默认推送到远程镜像仓库,而本次是将指定镜像推送 到本地私有镜像仓库。由于推送到本地私有镜像仓库的镜像名必须符合“仓库IP:端口 号/repository”的形式,因此需要按照要求修改镜像名称,具体操作指令如下。 $ docker tag hello‐world:latest localhost:5000/myhellodocker 3、推送镜像,本地私有镜像仓库搭建并启动完成,同时要推送的镜像也已经准备就绪后,就 可以将指定镜像推送到本地私有镜像仓库了,具体操作指令如下 $ docker push localhost:5000/myhellodocker 4、查看本地仓库镜像 http://localhost:5000/v2/myhellodocker/tags/list (注意:使用该地址时注意镜 像名称) http://192.168.9.23:5000/v2/myhellodocker/tags/list 由于做了目录挂载,因此可以在本地的该目录下查看: /mnt/registry/docker/registry/v2/repositories 推送:不需要(不安全)
8.3.2 配置私有仓库认证
一、配置私有仓库认证 1、查看Docker Registry私有仓库搭建所在服务器地址:ifconfig 例如:服务器地址为:192.168.200.141 2、生成自签名证书(在home目录下执行上述指令后) 要确保Docker Registry本地镜像仓库的安全性,还需要一个安全认证证书,来保证其他 Docker机器不能随意访问该机器上的Docker Registry本地镜像仓库,所以需要在搭建 Docker Registry本地镜像仓库的Docker主机上先生成自签名证书(如果已购买证书就无需 生成),具体操作指令如下。 $ mkdir registry && cd registry && mkdir certs && cd certs $ openssl req ‐x509 ‐days 3650 ‐subj '/CN=192.168.200.162:5000/' \ ‐nodes ‐newkey rsa:2048 ‐keyout domain.key ‐out domain.crt 指令参数说明: ‐x509:x509是一个自签发证书的格式 ‐days 3650:表示证书有效期 192.168.197.141:5000:表示具体部署Docker Registry本地镜像仓库的地址和端口 rsa:2048:是证书算法长度 domain.key和domain.crt:就是生成的证书文件 3、生成用户名和密码 在Docker Registry本地镜像仓库所在的Docker主机上生成自签名证书后,为了确保 Docker机器与该Docker Registry本地镜像仓库的交互,还需要生成一个连接认证的用户名 和密码,使其他Docker用户只有通过用户名和密码登录后才允许连接到Docker Registry本 地镜像仓库 $ cd .. && mkdir auth $ docker run ‐‐entrypoint htpasswd registry:2 ‐Bbn ruanwen 123456 > auth/htpasswd 4、启动Docker Registry本地镜像仓库服务(将之前创建的容器删除) $ docker run ‐d \ ‐p 5000:5000 \ ‐‐restart=always \ ‐‐name registry \ ‐v /mnt/registry:/var/lib/registry \ ‐v `pwd`/auth:/auth \ ‐e "REGISTRY_AUTH=htpasswd" \ ‐e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ ‐e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ ‐v `pwd`/certs:/certs \ ‐e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ ‐e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ registry:2 5、配置Docker Registry访问接口 完成Docker Registry本地镜像仓库服务启动后,还需要在搭建了Docker Registry本地镜 像仓库所在的Docker主机上配置供其他Docker机器访问的接口,具体指令如下: $ sudo mkdir ‐p /etc/docker/certs.d/192.168.200.162:5000 $ sudo cp certs/domain.crt /etc/docker/certs.d/192.168.200.162:5000 6、Docker Registry私有仓库使用登记 在Docker机器终端使用sudo vim /etc/docker/daemon.json命令编辑daemon.json文 件,在该文件中添加如下内容 {"insecure‐registries":["192.168.200.162:5000"]} 7、重启并加载docker配置文件 $ sudo /etc/init.d/docker restart 二、验证测试 1、装备镜像 $ docker tag hello‐world:latest 192.168.200.162:5000/myhelloworld 2、推送镜像 $ docker push 192.168.200.141:5000/myhelloworld 送过程中出现错误,信息提示为:no basic auth credentials(即没有通过身份验 证),所以无法进行推送,这也就说明身份验证的配置有效。要想成功推送,需要先登录成 功后再推送 3、登录Docker Registry镜像仓库 $ docker login 192.168.200.162:5000 4、再次推送 $ docker push 192.168.200.139:5000/myhelloworld 5、结果验证 由于做了目录挂载,因此可以在本地的该目录下查看: /mnt/registry/docker/registry/v2/repositories
docker run -d \ -p 5000:5000 \ --restart=always \ --name registry \ -v /mnt/registry:/var/lib/registry \ -v `pwd` /auth:/auth \ -e "REGISTRY_AUTH=htpasswd" \ -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ -v `pwd` /certs:/certs \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ registry:2
docker: invalid reference format. See 'docker run --help'. 网上方法: 1 docker镜像的名字中不能包含大写字母,改成小写 2 docker run –p 8080:80 –d nginx 符号错误 “-” 其实为"-"
1、查看docker网络:
docker network ls
Docker中默认的三种网络分别为bridge、host和none,其中名为bridge的网络就是默认 的bridge驱动网络,也是容器创建时默认的网络管理方式,配置后可以与宿主机通信从 而实现与互联网通信功能,而host和none属于无网络,容器添加到这两个网络时不能与 外界网络通信。 这里介绍的三种网络bridge、host和none都是在非集群环境下Docker提供的默认网络, 而在Docker Swarm集群环境下,除了这三种默认网络外,Docker还提供了 docker_gwbridge和ingress两种默认网络。
[root@docker1 ~]# ifconfig docker0: flags=4099mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 inet6 fe80::42:84ff:fe38:1e99 prefixlen 64 scopeid 0x20 ether 02:42:84:38:1e:99 txqueuelen 0 (Ethernet) RX packets 97 bytes 10346 (10.1 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 110 bytes 15781 (15.4 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
2 、查看容器使用的网络情况:
docker network inspect bridge
虽然 Docker提供的默认网络的使用比较简单,但是为了保证各容器中应用的安全性,在 实际开发中更推荐使用自定义的网络进行容器管理。在Docker中,可以自定义bridge网 络、overlay网络,也可以创建network plugin(网络插件)或者远程网络以实现容器网 络的完全定制和控制。
9.2.1 网络类型
Bridge networks (桥接网络):
为了保证容器的安全性,我们可以使用基于bridge的驱动创建新的bridge网络,这种 基于bridge驱动的自定义网络可以较好的实现容器隔离。需要说明的是,这种用户自 定义的基于bridge驱动的网络对于单主机的小型网络环境管理是一个不错的选择,但 是对于大型的网络环境管理(如集群)就需要考虑使用自定义overlay集群网络。
Overlay network in swarm mode (Swarm集群中的覆盖网络)
在Docker Swarm集群环境下可以创建基于overlay驱动的自定义网络。为了保证安 全性,Swarm集群使自定义的overlay网络只适用于需要服务的群集中的节点,而不 会对外部其他服务或者Docker主机开放。
Custom network plugins (定制网络插件)
如果前面几种自定义网络都无法满足需求时,就可以使用Docker提供的插件来自定 义网络驱动插件。自定义网络插件会在Docker进程所在主机上作为另一个运行的进 程。自定义网络驱动插件与其他插件遵循相同的限制和安装规则,所有插件都使用 Docker提供的插件API,并且有一个包含安装、启动、停止和激活的生命周期。由于 自定义网络插件使用较少,所以只需了解即可。
9.2.2 自定义网络
1、docker network create ‐‐driver bridge isolated_nw 创建一个基于bridge驱动的名称为isolated_nw的网络。其中‐‐driver(可简写为‐d)用 于指定网络驱动类型,isolated_nw就是新创建的网络名称。需要说明的是,‐‐driver bridge可以省略,省略时Docker会默认使用基于bridge驱动来创建新的网络。 2、docker run ‐itd ‐‐name=nwtest ‐‐network=isolated_nw busybox 会创建一个名为nwtest的容器,指令中的‐‐network参数指定了该容器的网络连接为自定义 的isolated_nw。通过docker inspect nwtest指令可以查看启动后的容器详情,来核查 其网络管理方式. 3、docker network connect bridge nwtest 会为容器nwtest另添加一种默认的bridge网络管理方式。再次使用docker inspect nwtest指令查看该容器网络详情 4、docker network disconnect isolated_nw nwtest 断开网络连接的指令与连接网络的指令类似,在使用时也需要指定网络名称和容器名称 5、docker network rm isolated_nw 移除名称为isolated_nw的自定义网络。当网络移除成功后,会返回网络名称。
1、创建两个使用默认的bridge网络的容器
docker run ‐itd ‐‐name=c1 busybox docker run ‐itd ‐‐name=c2 busybox
2、创建一个使用自定义的isolated_nw网络(需要预先创建)的容器
docker network create ‐‐driver bridge isolated_nw docker run ‐‐network=isolated_nw ‐itd ‐‐name=c3 busybox
3、为container2容器新增一个自定义的isolated_nw网络连接
docker network connect isolated_nw c2
C1:172.17.0.3 【bridge】 C2:172.17.0.4 和 172.19.0.3 【bridge、isolated_nw】
C3 :172.19.0.2【isolated_nw】
4、C1、C2、C3网络分配情况如下:
5 、测试容器间通信:分别登录C1、C2、C3容器,通过ping命令判断是否通信。
进入容器docker attach c1 退出容器快捷键 ctrl + q + P ping ‐w 4 ip地址
6 、结论
不同容器之间想要相互通信必须在同一个网络环境下;使用默认bridge网络管理的容器可以 使用容器IP进行通信,但无法使用容器名称进行通信;而使用自定义网络管理的容器则可以 使用容器IP进行通信
Swarm这个项目名称特别贴切。在Wiki的解释中,Swarm behavior是指动物的群集行 为。比如我们常见的蜂群,鱼群,秋天往南飞的雁群都可以称作Swarm behavior。 Swarm项目正是这样,通过把多个Docker Engine聚集在一起,形成一个大的docker- engine,对外提供容器的集群服务。同时这个集群对外提供Swarm API(命令,docker engine的命令),用户可以像使用Docker Engine一样使用Docker集群。
Swarm 是Docker公司在2014年12月初发布的容器管理工具,和Swarm一起发布的 Docker管理工具还有Machine以及Compose。Swarm是一套较为简单的工具,用以管理 Docker集群,使得Docker集群暴露给用户时相当于一个虚拟的整体。Swarm将一群 Docker宿主机变成一个单一的,虚拟的主机。Swarm使用标准的Docker API接口作为其 前端访问入口,换言之,各种形式的Docker Client(docker client in Go, docker_py, docker等)均可以直接与Swarm通信。Swarm几乎全部用Go语言来完成开发,Swarm0.2 版本增加了一个新的策略来调度集群中的容器,使得在可用的节点上传播它们,以及支 持更多的 Docker命令以及集群驱动。Swarm deamon只是一个调度器(Scheduler)加 路由器(router),Swarm自己不运行容器,它只是接受docker客户端发送过来的请求, 调度适合的节点来运行容器,这意味着,即使Swarm由于某些原因挂掉了,集群中的节 点也会照常运行,当Swarm重新恢复运行之后,它会收集重建集群信息。
docker swarm特点: 1) 对外以Docker API接口呈现,这样带来的好处是,如果现有系统使用Docker Engine, 则可以平滑将Docker Engine切到Swarm上,无需改动现有系统。 2) Swarm对用户来说,之前使用Docker的经验可以继承过来。非常容易上手,学习成本 和二次开发成本都比较低。同时Swarm本身专注于Docker集群管理,非常轻量,占用资 源也非常少。简单说,就是插件化机制,Swarm中的各个模块都抽象出了API,可以根据 自己一些特点进行定制实现。 3) Swarm自身对Docker命令参数支持的比较完善,Swarm目前与Docker是同步发布 的。Docker的新功能,都会第一时间在Swarm中体现。
Swarm作为一个管理Docker集群的工具,首先需要将其部署起来,可以单独将Swarm部 署于一个节点。另外,自然需要一个Docker集群,集群上每一个节点均安装有Docker。
相关术语:
Swarm Manager :集群的管理工具,通过swarm manager管理多个节点。
Node :是已加入到swarm的Docker引擎的实例 。
manager nodes :也就是管理节点 ,执行集群的管理功能,维护集群的状态, 选举一个leader节点去执 行调度任务
worker nodes ,也就是工作节点 ,接收和执行任务。参与容器集群负载调度, 仅用于承载task
一个服务是工作节点上执行任务的定义。创建一个服务,指定了容器所使用的镜像和 容器运行的命令。service是运行在worker nodes上的task的描述,service的描述包 括使用哪个docker 镜像,以及在使用该镜像的容器中执行什么命令。
task 任务:一个任务包含了一个容器及其运行的命令。task是service的执行实体, task启动docker容器并在容器中执行任务
搭建步骤: 1、环境准备: 1.1、准备三台已近安装docker engine的centos/Ubuntu系统主机(docker版本必须在 1.12以上的版本,老版本不支持swarm) 1.2、docker容器主机的ip地址固定,集群中所有工作节点必须能访问该管理节点 1.3、集群管理节点必须使用相应的协议并且保证端口可用 集群管理通信:TCP,端口2377 节点通信:TCP和UDP,端口7946 覆盖型网络(docker网络):UDP,端口4789 overlay驱动 说明:三台容器主机的ip地址分别为: 192.168.200.162(管理节点) 192.168.200.163(工作节点) 192.168.200.158(工作节点) 主机名称分别为:manager1、work1以及work2 vim /etc/hostname (修改完成后需要重启) 2、创建docker swarm 2.1、在manager1机器上创建docker swarm集群 docker swarm init ‐‐advertise‐addr 192.168.200.162 (‐‐advertise‐addr将该IP地址的机器设置为集群管理节点;如果是单节点,无需该参 数) 2.2、查看管理节点集群信息: docker node ls 3、向docker swarm中添加工作节点:在两个工作节点中分别执行如下命令,ip地址是 manager节点的 3.1、添加两个work节点 docker swarm join ‐‐token xxx 192.168.200.138:2377 (worker1) docker swarm join ‐‐token xxx 192.168.200.138:2377 (worker2) (‐‐token xxx:向指定集群中加入工作节点的认证信息,xxx认证信息是在创建docker swarm时产生的) 3.2、继续查看管理节点集群信息与之前的区别 docker node ls 4、在docker swarm中部署服务 在Docker Swarm集群中部署服务时,既可以使用Docker Hub上自带的镜像来启动服务,也 可以使用自己通Dockerfile构建的镜像来启动服务。如果使用自己通过Dockerfile构建的 镜像来启动服务那么必须先将镜像推送到Docker Hub中心仓库。为了方便读者的学习,这里 以使用Docker Hub上自带的alpine镜像为例来部署集群服务 4.1、部署服务 docker service create ‐‐replicas 1 ‐‐name helloworld alpine ping docker.com docker service create指令:用于在Swarm集群中创建一个基于alpine镜像的服务 ‐‐replicas参数:指定了该服务只有一个副本实例 ‐‐name参数:指定创建成功后的服务名称为helloworld ping docker.com指令:表示服务启动后执行的命令 5.查看docker swarm集群中的服务 查看服务列表:docker service ls 查看部署具体服务的详细信息:docker service inspect 服务名称 查看服务在集群节点上的分配以及运行情况:docker service ps 服务名称 6、修改副本数量 在manager1上,更改服务副本的数量(创建的副本会随机分配到不同的节点) docker service scale helloworld=5 7、删除服务(在管理节点) docker service rm 服务名称 8、访问服务 8.1、查看集群环境下的网络列表:docker network ls 8.2、在manager1上创建一overlay为驱动的网络(默认使用的网络连接ingress) docker network create ‐d=overlay my‐multi‐host‐network 8.3、在集群管理节点manager1上部署一个nginx服务 docker service create \ ‐‐network my‐multi‐host‐network \ ‐‐name my‐web \ ‐p 8080:80 \ ‐‐replicas 2 \ nginx 8.3、在管理节点查看服务的运行情况: docker service ps my‐web 8.4、访问测试
根据前面所学的知识可知,想要使用Docker部署应用,就要先在应用中编写Dockerfile 文件来构建镜像。同样,在微服务项目中,我们也需要为每一个服务编写Dockerfile文件 来构建镜像。构建完成后,就可以根据每一个镜像使用docker run或者docker service create命令创建并启动容器,这样我们就可以访问容器中的服务了。 微服务架构中:涉及的服务数量巨多。 虽然使用上述方式可以部署微服务项目,但考虑到微服务项目可能有多个子服务组成, 并且每个服务启动过程中都需要配置额外的参数(如-e配置环境变量、--network指定网 络、磁盘挂载等等)。这种情况下,每次更新微服务后,都要手动运行指令来重新启动 容器,这就显得相当麻烦了。针对这种多服务部署的情况,Docker提供了Docker Compose编排工具来对多服务应用进行统一部署。Compose是Docker的服务编排工 具,主要用来构建基于Docker的复杂应用,Compose 通过一个配置文件来管理多个 Docker容器,非常适合组合使用多个容器进行开发的场景。 通过该编排工具,可以使用yml(或yaml)文件来配置应用程序服务,然后只需要一条简 单的服务部署指令就可以从配置中创建并启动所有服务。
安装docker compose
1、环境要求:Docker Compose是依赖于Docker引擎的,所以在安装Docker Compose之前 要确保机器上已经安装了Docker。https://github.com/docker/compose/releases (查看docker compose版本) 2、下载docker‐compose工具 curl ‐L https://github.com/docker/compose/releases/download/1.24.0/docker‐ compose‐`uname ‐s`‐`uname ‐m` ‐o /usr/local/bin/docker‐compose 3、设置docker compose可执行文件权限 chmod +x /usr/local/bin/docker‐compose r:read w:write x:ex 4、查看docker compose版本 docker‐compose ‐‐version PS:卸载docker compose sudo rm /usr/local/bin/docker‐compose
11.3.1 例子
步骤:分为三步(在创建的一个空目录下执行) 1、编写Dockerfile文件(为每个服务构建需要的镜像,方便迁移‐不是必须的) 2、编写docker‐compose.yml文件(编写部署服务相关指令) 3、运行docker‐compose up(启动yml文件中服务) 案例: 1、准备:两个镜像(本次演示就不通过Dockerfile构建了) docker pull mysql:5.7 docker pull wordpress 2、需要新建一个空白目录,例如rwtest。新建一个docker‐compose.yml,编辑该文件: version: '3' services: db: image: mysql:5.7 volumes: - db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: wordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest ports: - "8001:80" restart: alwayls environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress volumes: db_data: 该文件中内容:新建db和wordpress容器。等同于: docker run ‐‐name db ‐e MYSQL_ROOT_PASSWORD=123456 ‐d mysql docker run ‐‐name some‐wordpress ‐‐link db:mysql ‐p 8002:80 ‐d wordpress 3、启动docker compose docker‐compose up 4、浏览器访问:http://192.168.9.23:8001 5、停止/重启服务:docker‐compose stop/restart
注意:键值对冒号后要有空格
1 version: '3' 2 services: 3 web: 4 image: id/imagename:lable 5 restart: on‐failure 6 container_name: my‐web‐container 7 ports: 8 ‐ 8080:8080 9 networks: 10 ‐ example‐net 11 depends_on: 12 ‐ db 13 deploy: 14 replicas: 2 15 restart_policy: 16 condition: on‐failure 17 db: 18 image: mysql:5.6 19 restart: on‐failure 20 container_name: my‐mysql‐container 21 ports: 22 ‐ 3306:3306 23 volumes: 24 ‐ example‐mysql:/var/lib/mysql 25 networks: 26 ‐ example‐net 27 environment: 28 MYSQL_ROOT_PASSWORD: root 29 MYSQL_DATABASE: mysql_database 30 deploy: 31 replicas: 1 32 restart_policy: 33 condition: on‐failure 34 placement: 35 constraints: [node.role == manager] 36 networks: 37 example‐net: 38 volumes: 39 example‐mysql:
version :version通常在一个docker-compose.yml文件的最顶部,用来表示文件内 容的约束版本(类似于XML文件约束)(版本越高,支持的指令越多)
services 用来声明服务,在services下的所有同缩进的应用名称都代表一个服务,如 上面示例中的web和db。在进行多服务部署的时候,有多少个服务需要同时部署, 就需要在services参数下面声明并配置多少个服务
image :容器启动需要依赖的镜像(如果本地没有会自动pull)
restart :服务重启策略
restart: "no" # 服务默认值为no,即服务失败后没有任何动作
restart: always # 表示服务会一直重新启动
restart: on-failure # 表示服务提示失败错误后会重新启动
restart: unless-stopped # 表示只有服务在停止后才会重启
container_name :指定容器名称
ports :指定服务向外暴露的端口
networks :指定容器使用的网络
depends_on :服务依赖决定了服务的依赖关系,如示例中的web依赖db,所以 db服务会先于web服务启动,但并不表示db服务完全启动成功后才启动web服 务,它只决定启动的先后顺序而已
deploy :deploy参数是Docker Compose针对Swarm集群部署提供的,子参数 专门用于指定与服务部署和运行相关的配置
replicas :表示服务实例的副本数量
restart_policy :estart_policy参数同前面介绍的restart类似,都是用来配置 服务重启策略的,只是该属性配置在deploy参数下,并只在集群环境下生 效。该参数包含多个子属性及属性值
condition: on-failure # 表示服务重启的条件,值有none、on-failure和 any
delay: 5s # 表示重启服务之间等待时间,默认为0
max_attempts: 3 # 表示失败后尝试重启的次数
window: 120s # 表示等待多久来确定服务是否启动成功
placement :placement用来配置指定位置的约束,当服务在Swarm集群环 境下部署时会随机分配到管理节点和其他工作节点上。在上述示例中由于将 mysql数据挂载到了本机example-mysql数据卷中,所以使用了placement 的子参数constraints: [node.role == manager]指定该服务只在manager管 理节点上运行 :
environment 用于配置服务启动时需要的环境变量。如上述示例中 MYSQL_ROOT_PASSWORD表示数据库root用户的密码,MYSQL_DATABASE表 示数据库启动后自动创建的数据库。
networks :用于配置服务网络
volumes :目录挂载,上述示例中是将mysql数据挂载到本地example-mysql数据卷 中,如果该数据卷不存在,服务启动时也会默认创建
其他配置可参考:https://docs.docker.com/compose/compose-file/
当 Docker 部署规模逐步变大后,可视化监控容器环境的性能和健康状态将会变得越来越 重要。 Docker的图形化管理工具,提供状态显示面板、应用模板快速部署、容器镜像网 络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控 制台操作、Swarm集群和服务等集中管理和操作、登录用户管理和控制等功能。常用工 具如下: 1、docker UI(local) 2、shipyard(停止维护了) 3、portainer 4、daocloud
12.2.1 docker UI
安装docker UI
1、拉取docker UI镜像 docker pull uifd/ui‐for‐docker 2、创建容器 docker run ‐d ‐p 9000:9000 ‐‐privileged ‐v /var/run/docker.sock:/var/run/docker.sock uifd/ui‐for‐docker
优点:
支持容器管理
支持镜像管理
基于 docker api,自身也是一个容器。
稳定性高
可动态显示显示容器之间关系图
容器管理,增加端口映射,增加系统变量、映射目录等
缺点:
没有登录验证,因为没有登录体系,目前解决办法是,只开放本地访问,或者通 过TLS来对权限进行控制。
无法分配某容器给某用户。
不支持多主机。
1、拉取docker UI镜像 docker pull uifd/ui‐for‐docker 2、创建容器 docker run ‐d ‐p 9000:9000 ‐‐privileged ‐v /var/run/docker.sock:/var/run/docker.sock uifd/ui‐for‐docker
不支持集群 swarm等
功能少
12.2.2 portainer
12.2.2.1 安装portainer
docker run ‐d ‐p 9001:9000 ‐v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
12.2.2.2 挂载远程节点(修改远程节点配置)
1、编辑该文件 vim /lib/systemd/system/docker.service 2、删除配置文件中内容 ExecStart=/usr/bin/dockerd xxx(删除这部分内容) 3、在daemon.json文件中添加如下内容:所有服务器都可以访问 "hosts":["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"] 4、重启docker systemctl daemon‐reload systemctl restart docker
优点
支持容器管理、镜像管理
轻量级,消耗资源少
基于docker api,安全性高,可指定docker api端口,支持TLS证书认证。
支持权限分配
支持集群
缺点
功能不够强大。
容器创建后,无法通过后台增加端口。
12.2.3 daocloud
执行该命令: curl ‐sSL https://get.daocloud.io/daomonit/install.sh | sh ‐s 24a7c865945f25697fe9255dad8e54eb431d785b
优点:
支持镜像管理、容器管理。
支持控制台命令
容器资源消耗监控
支持集群可以随意增加节点
中文平台
镜像下载
容器扩容、管理
缺点
管理平台无法部署到本地服务器
部分高级功能收费