Docker是基于Go语言实现的开源容器项目,Docker让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何接口,Docker诞生于2013年年初,最初发起者是dotCloud公司.Docker自开源后受到广泛的关注和讨论,目前已有多个相关项目(包括Docker三剑客、Kubernetes等),逐渐形成了围绕Docker容器的生态体系,由于Docker在业界造成的影响力实在太大,dotCloud公司后来也直接改名为Docker Inc,并专注于Docker相关技术和产品的开发.

Docker持久化处理

生产环境中使用Docker的过程中,往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,这必然涉及容器的数据管理操作,容器管理中主要有两种方式,数据卷(Data Volumes),数据卷容器(Data Volume Containers),本小结将首先介绍如何在容器内创建数据卷,并且把本地的目录或文件挂载到容器内的数据卷中.接下来,会介绍如何使用数据卷容器在容器和主机、容器和容器之间共享数据,并实现数据的备份和恢复.

◆数据卷◆

数据卷是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器,类似于Linux中的mount操作.

数据卷可以提供很多有用的特性,如下所示:

● 数据卷可以在容器之间共享和重用,容器间传递数据将变得高效方便.

● 对数据卷内数据的修改会立马生效,无论是容器内操作还是本地操作.

● 对数据卷的更新不会影响镜像,解耦了应用和数据.

● 卷会一直存在,直到没有容器使用,可以安全地卸载它.

挂载一个本地目录作为数据卷:

1.在本地主机创建一个目录,并写入一些数据,来模拟本地数据.

[root@localhost ~]# mkdir /data
[root@localhost ~]# echo "hello mkdirs.com" > /data/index.html

2.开启容器,并让容器读取本地的/data目录.

[root@localhost ~]# docker run -d -p 8080:80 --name MyWeb -v /data:/usr/local/apache2/htdocs httpd:latest
2882b3edda42fe153a897d3dc21f73835eb57c14019b5e810066c34e0eda4c0c [参数解释] -d #以守护进程运行
-p #将容器中的80口,映射到本地主机的8080
--name #指定一个容器名称
-v #上面指的是,将本地/data目录挂载得到容器中的/usr/local目录中.
-P #是将容器服务暴露的端口,是自动映射到本地主机的临时端口. [root@localhost ~]# curl 127.0.0.1:8080
hello mkdirs.com

◆数据卷容器◆

如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器.数据卷容器也是一个容器,但是它的目的是专门用来提供数据卷供其他容器挂载.

1.首先,创建一个数据卷容器dbdata,并在容器中创建一个数据卷/dbdata的目录.

[root@localhost ~]# docker run -itd -v /usr/local/apache2/htdocs --name dbdata centos:latest
1bc16a7978db7db83a4a107bf2fe1c4c42c4c7fffa7dd92372a6aacb68ccfdd0 [root@localhost ~]# docker exec -it dbdata /bin/bash
[root@1bc16a7978db /]# echo "hello mkdirs.com" > /usr/local/apache2/htdocs/index.html
[root@1bc16a7978db /]# ls -lh /usr/local/apache2/htdocs/index.html
total 4.0K
-rw-r--r-- 1 root root 17 Dec 15 11:37 index.html [root@1bc16a7978db /]# exit

2.然后,可以在其他容器中使用--volumes-from来挂载dbdata容器中的数据卷,例如创建db1和db2两个容器,并从dbdata容器挂载数据卷.

[root@localhost ~]# docker run -d -p 801:80 --volumes-from dbdata --name db1 httpd:latest
123e75f38947f3294ac77a08bf4380f311d09cc176b576c61499139d75b35db3 [root@localhost ~]# docker run -d -p 802:80 --volumes-from dbdata --name db2 httpd:latest
a4e0f8016af6b89e31a637b1482b0849dcea26e4004298def4abce44c84d6dd6

3.分别访问两个不同的端口,会发现网页展现效果是一样的,也就是说,db1和db2共享了dbdata容器里指定文件的内容.

[root@localhost ~]# netstat -antp |grep 801
tcp6 0 0 :::801 :::* LISTEN 3998/docker-proxy
[root@localhost ~]# netstat -antp |grep 802
tcp6 0 0 :::802 :::* LISTEN 4157/docker-proxy [root@localhost ~]# curl 127.0.0.1:801
hello mkdirs.com
[root@localhost ~]# curl 127.0.0.1:802
hello mkdirs.com

使用--volumes-from参数所挂载数据卷的容器自身并不需要保持在运行状态,如果删除了挂载的容器(包括dbdata、db1和db2),数据卷并不会被自动删除.如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时显式使用docker rm -v命令来指定同时删除关联的容器.

◆容器备份恢复◆

数据备份: 使用下面的命令来备份dbdata数据卷容器内的数据卷,并把它备份到当前目录下.

[root@localhost ~]# docker run --volumes-from dbdata -v $(pwd):/backup --name workers centos:latest tar -czvf /backup/backup.tar /usr/local/apache2/htdocs

tar: Removing leading `/' from member names
/usr/local/apache2/htdocs/
/usr/local/apache2/htdocs/index.html
[root@localhost ~]# ls
backup.tar

这个命令稍微有点复杂,具体分析一下,首先利用centos镜像创建了一个容器workers.使用--volumes-from dbdata参数来让workers容器挂载dbdata容器的数据卷(即dbdata数据卷),使用-v $(pwd):/backup参数来挂载本地的当前目录到workers容器的/backup目录.workers容器启动后,使用了tar -czvf/backup/backup.tar /usr/local/apache2/htdocs命令来将/usr/local/apache2/htdocs下内容备份为容器内的/backup/backup.tar,即宿主主机当前目录下的backup.tar.

数据恢复: 如果要将数据恢复到一个容器,可以按照下面的步骤操作.

1.首先创建一个带有数据卷的容器dbdata_backup.

[root@localhost ~]# docker run -itd -v /usr/local/apache2/htdocs --name dbdata_backup centos:latest /bin/bash
a207d887bfa07cc0e1737efb197950cac3b2c5647391348b1b8fa8b873c58667

2.然后创建另一个新的容器,挂载dbdata2的容器,并使用untar解压备份文件到所挂载的容器卷中.

[root@localhost ~]# docker run --volumes-from dbdata_backup -v $(pwd):/backup busybox tar -xzvf /backup/backup.tar

usr/local/apache2/htdocs/
usr/local/apache2/htdocs/index.html

本小结介绍了通过数据卷和数据卷容器对容器内数据进行共享、备份和恢复等操作,通过这些机制,即使容器在运行中出现故障,用户也不必担心数据发生丢失,只需要快速地重新创建容器即可.

Docker端口映射

在实践中,经常会碰到需要多个服务组件容器共同协作的情况,这往往需要多个容器之间有能够互相访问到对方的服务,Docker提供了两个很方便的功能来满足服务访问的基本需求:一个是允许映射容器内应用的服务端口到本地宿主主机,另一个是互联机制实现多个容器间通过容器名来快速访问,下面我们来分别介绍一下吧.

◆从外部访问容器应用◆

随机分配端口: 当容器中运行一些网络应用,要让外部访问这些应用时,可以通过-P-p参数来指定端口映射.当使用-P(大写的)标记时,Docker会随机映射一个49000~49900的端口到内部容器开放的网络端口.

[root@localhost ~]# docker run -d -P --name myweb httpd:latest
afb211e832c16c80822632fe0864838781cee2132993f93cde8c915e242f9df5 [root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
afb211e832c1 httpd:latest "httpd-foreground" 3 seconds ago Up 2 seconds 0.0.0.0:32768->80/tcp myweb

指定分配端口: 当我们使用-p(小写的)可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器.

[root@localhost ~]# docker run -d -p 8080:80 --name myweb1 httpd:latest
b47f6131dea02c8cd22a75049e97c28cc4bb25bc6bf5cd36645c1ccb4210554e #上面说明,将容器的80端口,映射到本地的8080 [root@localhost ~]# curl 127.0.0.1.8080
<html><body><h1>It works!</h1></body></html>

◆映射所有接口地址◆

映射指定端口: 格式将容器的80端口映射到本机的80端口.

[root@localhost ~]# docker run -d -p 80:80 --name myweb2 httpd:latest
9c3d0f8ad0bbfa75cc6534f93f959192316125a2776a2c909c71dc9dfb5a8b79 [root@localhost ~]# curl 127.0.0.1
<html><body><h1>It works!</h1></body></html>

映射多个端口: 多次使用-p标记可以绑定多个端口.

[root@localhost ~]# docker run -d -p 8080:80 -p 1000:21 --name myweb3 httpd:latest
097ceb68128b58195c990dff720e39ca1717809cc2019d3f31466dee6fd32aec [root@localhost ~]# netstat -antp |grep "8080"
tcp6 0 0 :::8080 :::* LISTEN 2306/docker-proxy
[root@localhost ~]# netstat -antp |grep "1000"
tcp6 0 0 :::1000 :::* LISTEN 2317/docker-proxy

◆映射到指定地址◆

映射到指定地址的指定端口: 将容器中的80端口映射到本地指定IP地址上去.

[root@localhost ~]# ifconfig ens32:0 192.168.1.10 netmask 255.255.255.0
[root@localhost ~]# ifconfig ens32:0
ens32:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.10 netmask 255.255.255.0 broadcast 192.168.1.255
ether 00:0c:29:1e:14:e2 txqueuelen 1000 (Ethernet) [root@localhost ~]# docker run -d -p 192.168.1.10:8080:80 --name myweb_port httpd:latest
7385faa5d476cb37dd7d201cd0ec939501c9bdb23ec1c8239245c30d2be9abe7 [root@localhost ~]# netstat -antp |grep "8080"
tcp 0 0 192.168.1.10:8080 0.0.0.0:* LISTEN 2585/docker-proxy [root@localhost ~]# curl 192.168.1.10:8080
<html><body><h1>It works!</h1></body></html>

映射到指定地址的任意端口: :本地主机会自动分配一个端口,绑定到容器的80口.

[root@localhost ~]# docker run -d -p 192.168.1.10::80 --name myweb_port1 httpd:latest
7a5a105ae0827aaff68864a28b5f9b8a9592af3551f7deca564ea2d6d5a249b3 [root@localhost ~]# netstat -antp |grep "80"
tcp 0 0 192.168.1.10:8080 0.0.0.0:* LISTEN 2585/docker-proxy #还可以使用udp标记来指定udp端口
[root@localhost ~]# docker run -d -p 192.168.1.10:5000:5000/udp --name myweb_udp httpd:latest
b9cc6333a63109a70a1d2e645b1ff5046988b472dea3bb4f4d010f1478951adf [root@localhost ~]# netstat -an |grep "5000"
udp 0 0 192.168.1.10:5000 0.0.0.0:*

## Docker容器互联

容器的互联(linking)是一种让多个容器中应用进行快速交互的方式,它会在源和接收容器之间创建连接关系,接收容器可以通过容器名快速访问到源容器,而不用指定具体的IP地址.

1.使用--link参数可以让容器之间安全地进行交互,下面先创建一个新的MySQL数据库容器.

[root@localhost ~]# docker run -d --name mysqldb mysql:latest
c1770a69ed29944466ce013c42ac2a0391651c88381e41be05308eab80458390

2.然后创建一个新的web容器,并将它连接到MySQL容器,使之能够通信.

[root@localhost ~]# docker run -d -P --name web --link mysqldb:mysqldb httpd:latest
8b2bfcbbe00f6966c511fdbbbc16e40736ab8d6aa89d229e224f38d12c4643df

此时,mysqldb容器和web容器建立互联关系,--link参数的格式为--link name:alias,其中name是要连接的容器名称,alias是这个连接的别名.

Docker相当于在两个互联的容器之间创建了一个虚机通道,而且不用映射它们的端口到宿主主机上.在启动mysqldb容器的时候并没有使用-p和-P标记,从而避免了暴露数据库服务端口到外部网络上.

拓展与实战例子

◆Apache◆

Apache是世界使用排名第一的Web服务器软件,它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一.它快速、可靠并且可通过简单的API扩充,将Perl/Python等解释器编译到服务器中.

1.拉取镜像,并在本地创建一个测试页.

[root@localhost ~]# docker pull httpd:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest 2a51bb06dc8b 4 weeks ago 132MB [root@localhost ~]# mkdir /web
[root@localhost ~]# echo "hello world" > /web/index.html

2.运行http容器,并访问测试.

[root@localhost ~]# docker run -d -p 8080:80 --name MyWeb -v /web:/usr/local/apache2/htdocs httpd:latest
[root@localhost ~]# curl 127.0.0.1:8080
hello world

◆GitLab◆

Gitlab是一款非常强大的开源源码管理系统.它支持基于Git的源码管理、代码评审、issue跟踪、活动管理、wiki页面,持续集成和测试等功能.基于Gitlab,用户可以自己搭建一套类似Github的开发协同平台.

1.安装并启动postgresql.

[root@localhost ~]# docker pull sameersbn/postgresql:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sameersbn/postgresql latest 3c0142eb3992 5 months ago 204MB [root@localhost ~]# docker run --name gitlab_postgresql -d \
--env 'DB_NAME=gitlab' \
--env 'DB_USER=gitlab' --env 'DB_PASS=gitlab' \
sameersbn/postgresql:latest

2.安装redis.

[root@localhost ~]# docker pull sameersbn/redis:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sameersbn/redis latest ad607f019b8c 4 months ago 84.8MB
sameersbn/postgresql latest 3c0142eb3992 5 months ago 204MB [root@localhost ~]# docker run --name gitlab_redis -itd sameersbn/redis:latest

3.安装GitLab.

[root@localhost ~]# docker pull sameersbn/gitlab:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sameersbn/gitlab latest 336fe9c19d92 6 days ago 1.96GB
sameersbn/redis latest ad607f019b8c 4 months ago 84.8MB
sameersbn/postgresql latest 3c0142eb3992 5 months ago 204MB [root@localhost ~]# docker run --name gitlab -d sameersbn/gitlab \
--link gitlab_postgresql:postgresql --link gitlab_redis:redis \
--publish 10022:22 --publish 10080:80 \
--env 'GITLAB_PORT=10080' --env 'GITLAB_SSH_PORT=10022' \
--env 'GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alpha-numeric-string' \
sameersbn/gitlab:latest

◆WordPress◆

WordPress是使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站.也可以把WordPress当作一个内容管理系统(CMS)来使用,WordPress逐步演化成一款内容管理系统软件,它是使用PHP语言和MySQL数据库开发的.用户可以在支持PHP和MySQL数据库的服务器上使用自己的博客.

1.首先安装一个MariaDB数据库,并配置好初始密码.

[root@localhost ~]# docker pull mariadb:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mariadb latest b468922dbbd7 3 weeks ago 366MB [root@localhost ~]# docker run --name MyDataBase --env MYSQL_ROOT_PASSWORD=example -d mariadb:latest

2.拉取WordPress镜像,并运行,将容器内的80口映射到宿主机的8080口上.

[root@localhost ~]# docker pull wordpress:latest
[root@localhost ~]# docker run --name MyWordPress --link MyDataBase:MariaDB -p 8080:80 -d wordpress:latest

参考文献:《Docker技术入门与实战》《Docker基础与实战》

Docker 数据卷与容器互联的更多相关文章

  1. Docker 数据卷容器

    如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器. 数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的. 首先,创建一个命名的数据卷容器 dbdata: $ sud ...

  2. docker 数据卷和docker数据卷容器以及数据卷的备份和还原

    一:数据卷 1.什么是数据卷 数据卷是通过特殊设计的目录,可以绕过联合文件系统,为一个或者多个容器提供服务,数据卷是在docker宿主机当中,数据卷可以是文件也可以是文件夹. 2.特点 1.数据卷在容 ...

  3. 聊聊Docker数据卷和数据卷容器

    当程序在容器运行的时候,特别是需要与其他容器中的程序或容器外部程序进行沟通交流,这时需要进行数据交换,作为常用的两种沟通数据的方式,网络通信与文件读写是需要提供给程序的支持, [数据卷] 文件是数据持 ...

  4. Docker数据卷容器备份、恢复

    1.备份数据卷容器 使用数据卷来备份数据,通过指定本地的一个文件路径,对应到容器中的路径,运行tar命令将重要的文件打包备份. $ cd /home/xm6f/dev $ docker run --v ...

  5. Docker 数据卷和数据卷容器

    1.本节课主要讲解如何在Docker内部及容器之间管理数据.容器中管理数据主要有两种方式:数据卷(Data volumes)数据卷容器(Data volume containers) 2.数据卷:是一 ...

  6. 实例解析Docker数据卷+数据卷容器+flocker数据共享+DockerHub操作

    Docker内部数据管理和Docker之间的数据共享为数据卷和数据卷容器,实例解析1.将本地的文件作为容器的数据卷,2.数据卷flocker插件实现容器集群(或者Docker Swarm)的数据共享3 ...

  7. Docker数据卷和数据卷容器

    是什么 数据卷设计的目的,在于数据的永久化,他完全独立于容器的生存周期,因此,Docker不会在容器删除时删除其挂载的数据卷,也不会存在类似的垃圾收集机制对容器引用的数据卷进行处理.类似我们Redis ...

  8. 『现学现忘』Docker基础 — 33、Docker数据卷容器的说明与共享数据原理

    目录 1.数据卷容器的说明 2.数据卷容器共享数据原理 3.总结 4.练习:MySQL实现数据共享 1.数据卷容器的说明 (1)什么是数据卷容器 一个容器中已经创建好的数据卷,其它容器通过这个容器实现 ...

  9. Docker数据持久化与容器迁移

    上节讲到当容器运行期间产生的数据是不会在写镜像里面的,重新用此镜像启动新的容器就会初始化镜像,会加一个全新的读写入层来保存数据.如果想做到数据持久化,Docker提供数据卷(Data volume)或 ...

随机推荐

  1. 批量插入数据@Insert

    // 批量插入数据 @Insert("<script>" + "insert into index_kline (currency_id, currency, ...

  2. cmake 工具使用

    cmake_minimum_required(VERSION 3.5)#cmake版本 project( DisplayImage )#项目名称 find_package( OpenCV REQUIR ...

  3. leetcode题目5.最长回文子串(中等)

    题目描述: 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad"输出: "bab"注意: ...

  4. System.Runtime.CompilerServices.Unsafe

    System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime.CompilerServices.Un ...

  5. Django入门------常见问题

    项目启动后仅本机可访问 1.修改 Django项目中的settings.py中的 ALLOWED_HOSTS 的值为 ['*']# 准许那些地址访问,* 表示任意地址ALLOWED_HOSTS = [ ...

  6. WOE1-Feature Selection 相关:一个计算WOE和Information Value的python工具

    python信用评分卡建模(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_ca ...

  7. MIL/SIL/PIL/HIL/VIL

    MIL:Model in the loop 模型在环,对模型在模型的开发环境下(如SIMULINK)进行仿真,通过输入一系列的测试用例,验证模型是否满足设计的功能需求.验证控制算法模型是否准确地实现了 ...

  8. Systemd 指令

    Systemd 指令 原文:http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html 一.由来 历史上,Linux 的 ...

  9. ubuntu14.04+安卓7.1(全志源码)+openjdk-8编译

    题记:编译花了将近4小时,所以编译源码是很费时的哦,可以在编译的时候可以学习其他的知识 编译环境准备 软件:WorkStation10 系统:ubuntu14.04 内存:8G 处理器:4个 磁盘大小 ...

  10. layui 数据表格复选框实现单选功能

    //点击选中(单选)//单击行勾选checkbox事件 $(document).on("click",".layui-table-body table.layui-tab ...