25.1 docker简介
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,移植很方便;
docker由go语言编写,基于apache2.0协议发布基于linux kernel,要想在win下运行需要借助一个vm(虚拟机)来实现
官网 www.docker.com
docker从1.13x开始,版本分为社区版ce和企业版ee,并且基于年月的时间线形式,当前最新稳定版为17.09
参考
http://blog.csdn.net/chenhaifeng2016/article/details/68062414
Docker和传统的虚拟化比较:
Docker的优势:
启动非常快,秒级实现
资源利用率高,一台高配置服务器可以跑上千个docker容器
更快的交付和部署,一次创建和配置后,可以在任意地方运行
内核级别的虚拟化,不需要额外的hypevisor支持,会有更高的性能和效率
易迁移,平台依赖性不强
Docker核心概念:
25.2 安装docker
下载docker的repo源:
curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker.repo
yum安装:
yum install -y docker-ce
如果以上这种安装方式的速度比较慢的话,也可以直接下载rpm包: https://download.docker.com/linux/centos/7/x86_64/stable/Packages/
下载完之后也需要使用yum安装,
yum install -y docker-ce-xxxx.rpm
安装完成之后,启动docker
[root@server ~]# systemctl start docker [root@server ~]# ps aux |grep docker root 15799 1.0 5.1 469280 52052 ? Ssl 09:27 0:00 /usr/bin/dockerd -H unix:// root 15804 0.6 2.9 391232 30240 ? Ssl 09:27 0:00 containerd --config /var/run/docker/containerd/containerd.toml --log-level info root 15951 0.0 0.0 112720 984 pts/0 S+ 09:27 0:00 grep --color=auto docker
启动docker后,会自动生成一些iptables规则:
[root@server ~]# iptables -nvL [root@server ~]# iptables -nvL Chain INPUT (policy ACCEPT 55 packets, 3910 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 DOCKER-USER all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 DOCKER-ISOLATION-STAGE-1 all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 0 0 DOCKER all -- * docker0 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- docker0 docker0 0.0.0.0/0 0.0.0.0/0 Chain OUTPUT (policy ACCEPT 29 packets, 3108 bytes) pkts bytes target prot opt in out source destination Chain DOCKER (1 references) pkts bytes target prot opt in out source destination Chain DOCKER-ISOLATION-STAGE-1 (1 references) pkts bytes target prot opt in out source destination 0 0 DOCKER-ISOLATION-STAGE-2 all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 Chain DOCKER-ISOLATION-STAGE-2 (1 references) pkts bytes target prot opt in out source destination 0 0 DROP all -- * docker0 0.0.0.0/0 0.0.0.0/0 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 Chain DOCKER-USER (1 references) pkts bytes target prot opt in out source destination 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
保存docker的iptables规则;
[root@server ~]# service iptables save
对于iptables规则,因为重启docker服务,就会自动生成,没有必要保存,但是它涉及很多容器,因此docker一般为专用服务器;
25.3 镜像管理
docker pull centos//可以下载centos镜像,因是国外资源,速度很慢
配置docker加速器
(参考 http://blog.csdn.net/xlemonok/article/details/71403534) vi /etc/docker/daemon.json//加入如下内容 { "registry-mirrors": ["https://dhq9bx4f.mirror.aliyuncs.com"] }
说明:这个url为加速器地址,需要到阿里云申请
配置完加速器,重启docker服务,再次docker pull centos会快很多
查看本地的镜像:
[root@server ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 75835a67d134 7 weeks ago 200MB
REPOSITORY 仓库
TAG 标签,相当于给这个镜像标上一个版本,用于区分这是新版本还是旧版本,或者用于区分这是什么环境的版本,总是就是作为一个标识符的存在
IMAGE ID是这个镜像的唯一标识,用于区分系统中不同的镜像
CREATED ,什么时候创建的
SIZE,这个镜像的大小
docker search xxx //搜索镜像,其中xxx是关键词
docker tag centos test_centos //给镜像打标签
[root@server ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 75835a67d134 7 weeks ago 200MB test_centos latest 75835a67d134 7 weeks ago 200MB [root@server ~]# docker tag centos test_centos:181129 [root@server ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 75835a67d134 7 weeks ago 200MB test_centos 181129 75835a67d134 7 weeks ago 200MB test_centos latest 75835a67d134 7 weeks ago 200MB
把镜像启动为容器
[root@server ~]# docker run -itd centos 8e3ff98afc9e609a3448985497591a85a1d8b3e04fc59a3790b66015a5c9d791
注:
-i表示让容器的标准输入打开,-t表示分配一个伪终端,-d表示后台启动,要把-i -t -d 放到镜像名字前面
查看运行中的容器,加上-a选项后可以查看所有容器,包括未运行的
[root@server ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8e3ff98afc9e centos "/bin/bash" 20 seconds ago Up 19 seconds
删除指定镜像
[root@server ~]# docker rmi test_centos Untagged: test_centos:latest [root@server ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE test_centos 181129 75835a67d134 7 weeks ago 200MB centos latest 75835a67d134 7 weeks ago 200MB
其中后面的参数可以是tag,如果是tag时,实际上是删除该tag。当后面的参数为镜像ID时,则会彻底删除整个镜像,所有标签也会一同删除。
25.4 通过容器创建镜像
进入容器:其中xxxxx为容器id,这个id可以用docker ps查看,最后面的bash为进入容器后我们要执行的命令,这样就可以打开一个终端
[root@server ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8e3ff98afc9e centos "/bin/bash" 8 minutes ago Up 8 minutes lucid_agnesi [root@server ~]# docker exec -it 8e3ff98afc9e bash [root@8e3ff98afc9e /]# ls anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
进入到该容器中,我们做一些变更,比如安装一些东西,然后针对这个容器进行创建新的镜像;
在容器中执行 yum install -y net-tools,然后ctrl d退出容器
[root@8e3ff98afc9e /]# ifconfig bash: ifconfig: command not found [root@8e3ff98afc9e /]# yum install -y net-tools [root@8e3ff98afc9e /]# ifconfig eth0: flags=4163
mtu 1500 inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet) RX packets 9088 bytes 13679553 (13.0 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 4875 bytes 266676 (260.4 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@8e3ff98afc9e /]# exit
生成新镜像:
[root@server ~]# docker commit -m "install net-tools and vim" -a "author" 8e3ff98afc9e test_centos sha256:bbf77dba5c7caa08e82a5096763b9c8550baffe511ae830d06cca3149b73819d [root@server ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE test_centos latest bbf77dba5c7c 8 seconds ago 300MB centos latest 75835a67d134 7 weeks ago 200MB
注:
25.5 通过模板创建镜像
模版下载地址:https://download.openvz.org/template/precreated/
[root@server ~]# wget https://download.openvz.org/template/precreated/centos-7-x86_64-minimal.tar.gz
导入此模版; 命令格式:cat 模版 | docker import - 镜像名称
[root@server ~]# cat centos-7-x86_64-minimal.tar.gz | docker import - centos7 sha256:7333d87fdf66a3c8ae0c69e52d24f013dbf8406b1e76a2e9f2f20e13429c15cd [root@server ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos7 latest 7333d87fdf66 24 seconds ago 435MB test_centos latest bbf77dba5c7c 19 hours ago 300MB centos latest 75835a67d134 7 weeks ago 200MB
启动此镜像容器,并进入该容器中,查看内核信息:
[root@server ~]# docker run -itd centos7 bash 691cf8d0686f9c0aa60026384fa5829edac33113582a50e4d4366db2f2353afa [root@server ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 691cf8d0686f centos7 "bash" 21 seconds ago Up 19 seconds vigilant_heisenberg 8e3ff98afc9e centos "/bin/bash" 19 hours ago Up 19 hours lucid_agnesi [root@server ~]# docker exec -it 691cf8d0686f bash [root@691cf8d0686f /]# uname -a Linux 691cf8d0686f 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux [root@691cf8d0686f /]# exit exit [root@server ~]# uname -a Linux server 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
可以看到两者使用的Linux内核其实是同一个,除了主机名不同之外都是一样的,所以说docker是基于Linux内核的原因就在这。
导出镜像:
[root@server ~]#docker save -o test_centos7.tar centos7 [root@server ~]# du -sh test_centos7.tar 426M test_centos7.tar
注:
docker save : 将指定镜像保存成 tar 归档文件
-o :输出到的文件
test_centos7.tar :保存的镜像的名称;
centos7 :要被保存的镜像名称
恢复本地镜像:docker load --input test_centos7.tar 或者docker load < test_centos7.tar
[root@server ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
691cf8d0686f centos7 "bash" 19 minutes ago Up 19 minutes
vigilant_heisenberg
8e3ff98afc9e centos "/bin/bash" 20 hours ago Up 20 hours
lucid_agnesi
[root@server ~]# docker rm -f 691cf8d0686f //删除运行中centos7容器
691cf8d0686f
[root@server ~]# docker rmi 7333d87fdf66 //删除centos7镜像
Untagged: centos7:latest
Deleted: sha256:7333d87fdf66a3c8ae0c69e52d24f013dbf8406b1e76a2e9f2f20e13429c15cd
Deleted: sha256:788edba9eaa8ade63d8ba9d5747281c5da2b34b12a6c80f4dffd8ad9e05f68c1
[root@server ~]# docker load < test_centos7.tar //恢复centos7镜像
788edba9eaa8: Loading layer [==================================================>] 446.1MB/446.1MB
Loaded image: centos7:latest
可以把自己的镜像传到dockerhub官方网站上去,但前提是需要先注册一个用户;
[root@server ~]# docker push image_name
25.6 容器管理
容器的创建与启动
之前我们使用的docker run命令,相当于先create再start。比如:
[root@server ~]# docker run -it centos bash
[root@e29123e0745e /]# exit
直接可以进入容器了。要想退出可以使用exit命令或者ctrl+d组合键,退出后容器也就停止了。
后台运行容器:docker run -d
[root@server ~]# docker run -d centos bash
331ecaa237f00ff981a71440f0f97e4346dc27783ef6a1d4b6e70056b76aac10
停止容器:docker stop 容器id
[root@server ~]# docker stop 331ecaa237f0
–name 给容器自定义名字
[root@server ~]# docker run --name web -itd centos bash
47b36b89091d76c04c044889a4d201d618c2c3dc0079c532c0fdb9fb25ebf88a
[root@server ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
47b36b89091d centos "bash" 24 seconds ago Up 24 seconds
web
–rm:容器退出后直接删除
[root@server ~]# docker run --rm -itd centos bash -c "sleep 30"
f6c3c126ff765dc2d7ef7960c18884a9cbc233e28a40ce13688006cd6360bff2
获取容器的历史信息:docker logs 容器id
[root@server ~]# docker run -d centos bash -c "echo 123"
c09714c064cfbbd5e80f521f1350b183a4d62852fff0d01852e41d4b5982c381
[root@server ~]# docker logs c09714c
123
进入后台运行的容器:docker attach
[root@server ~]# docker attach web
[root@47b36b89091d /]#
此方法不太好,exit退出之后,容器也退出了。所以建议使用exec选项:
[root@server ~]# docker run -itd centos bash
6c37c9cf0dc29a7b05aa584af5b82124c22718caffd0d1caf2585cbd68671621
[root@server ~]# docker exec -it 6c37c9cf0 bash
[root@6c37c9cf0dc2 /]# exit
[root@server ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
6c37c9cf0dc2 centos "bash" About a minute ago Up About a minute
heuristic_lamport
删除容器:docker rm -f 容器id,-f强制删除
[root@server ~]# docker rm -f 6c37c9cf0dc2
6c37c9cf0dc2
[root@server ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
容器的导出:docker export 容器id > 文件名.tar
[root@server ~]# docker run -itd centos bash
bae6d610395d015a8661f6ce8c7262a62eac77202e633e7dde1c091c4f59cfc3
[root@server ~]# docker export bae6d610 > file.tar
容器的导入:cat 文件名 | docker import - 自定义的容器名
[root@server ~]# cat file.tar | docker import - test
sha256:5ff484fdca53345597cedd584c24bfdab858b692e710f8d9145da7cfa297fd28
[root@server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test latest 5ff484fdca53 16 seconds ago 200MB
centos7 latest 7333d87fdf66 7 days ago 435MB
test_centos latest bbf77dba5c7c 7 days ago 300MB
centos latest 75835a67d134 8 weeks ago 200MB
25.7 仓库管理
我们pull/push镜像时都是从docker的公共上pull/push的;在企业中需建立自己的私有仓库;
下载registry 镜像,registy为docker官方提供的一个镜像,我们可以用它来创建本地的docker私有仓库;
[root@server ~]# docker pull registry
Using default tag: latest
latest: Pulling from library/registry
d6a5679aa3cf: Pull complete
ad0eac849f8f: Pull complete
2261ba058a15: Pull complete
f296fda86f10: Pull complete
bcd4a541795b: Pull complete
Digest: sha256:5a156ff125e5a12ac7fdec2b90b7e2ae5120fa249cf62248337b6d04abc574c8
Status: Downloaded newer image for registry:latest
启动registry:
[root@server ~]# docker run -d -p 5000:5000 registry
b3f16635fe7135462f190d16bb83bf87b439ab9bef0d042a0e1a099f301cfb7a
[root@server ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
b3f16635fe71 registry "/entrypoint.sh /etc…" 20 seconds ago Up 19 seconds
0.0.0.0:5000->5000/tcp elastic_engelbart
bae6d610395d centos "bash" 14 minutes ago Up 14 minutes
competent_banach
以registry镜像启动容器,-p会把容器的端口映射到宿主机上,:左边为宿主机监听端口,:右边为容器监听端口,这个端口可以自定义。
访问:telnet访问/curl访问
telnet访问:telnet 127.0.0.1 5000
[root@server ~]# telnet 127.0.0.1 5000
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
curl访问:curl 127.0.0.1:5000/v2/_catalog
[root@server ~]# curl 127.0.0.1:5000/v2/_catalog
{"repositories":[]}
上传镜像到仓库:仓库为新建,为空。
先把要上传的镜像打标签:
[root@server ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE test latest 5ff484fdca53 21 minutes ago 200MB centos7 latest 7333d87fdf66 7 days ago 435MB test_centos latest bbf77dba5c7c 8 days ago 300MB centos latest 75835a67d134 8 weeks ago 200MB registry latest 2e2f252f3c88 2 months ago 33.3MB [root@server ~]# docker tag centos 192.168.222.114:5000/centos7 [root@server ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE test latest 5ff484fdca53 23 minutes ago 200MB centos7 latest 7333d87fdf66 7 days ago 435MB test_centos latest bbf77dba5c7c 8 days ago 300MB 192.168.222.114:5000/centos7 latest 75835a67d134 8 weeks ago 200MB centos latest 75835a67d134 8 weeks ago 200MB registry latest 2e2f252f3c88 2 months ago 33.3MB
上传:
[root@server ~]# docker push 192.168.222.114:5000/centos7 The push refers to repository [192.168.222.114:5000/centos7] Get https://192.168.222.114:5000/v2/: http: server gave HTTP response to HTTPS client
错误提示;修改配置文件/etc/docker/daemon.json ,添加私有仓库地址:“insecure-registries”:
["192.168.222.114:5000"]
[root@server ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com","https://dhq9bx4f.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.222.114:5000"]
}
重启docker,重新启动容器并推送(因为前面重启了docker,所以容器会停止,必须启动容器才能推送。)
[root@server ~]# systemctl restart docker [root@server ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b3f16635fe71 registry "/entrypoint.sh /etc…" 19 minutes ago Exited (2) 3 minutes ago elastic_engelbart [root@server ~]# docker start b3f16635fe71 b3f16635fe71 [root@server ~]# docker push 192.168.222.114:5000/centos7 The push refers to repository [192.168.222.114:5000/centos7] f972d139738d: Pushed latest: digest: sha256:dc29e2bcceac52af0f01300402f5e756cc8c44a310867f6b94f5f7271d4f3fec size: 529 [root@server ~]# curl 127.0.0.1:5000/v2/_catalog {"repositories":["centos7"]} [root@server ~]#
下载私有仓库的镜像:docker pull
[root@server ~]# docker pull 192.168.222.114:5000/centos7
25.8 数据管理
在容器里的数据,一旦容器停止或者删除,则数据就丢失了,因此可以挂载宿主机的目录到容器里面,这样就可以把容器的数据保存在宿主机了。
挂载本地目录到容器里:
[root@server ~]# mkdir /data //创建本地目录
[root@server ~]# mkdir /data/backup
[root@server ~]# docker run -tid -v /data/:/mydata centos bash //挂载目录
ee15d652cf2a217323ebd7a2b296e26669c561ec7e4c12838657db0a4850ca20
-v:指定挂载目录,:前面的是宿主机本地目录,:后面的是容器的目录,会自动创建,无需事先创建。
进入容器查看:
[root@server ~]# docker exec -it ee15d652c bash
[root@ee15d652cf2a /]# ls
anaconda-post.log dev home lib64 mnt opt root sbin sys usr
bin etc lib media mydata proc run srv tmp var
[root@ee15d652cf2a /]# ls /mydata/
backup
[root@ee15d652cf2a /]# mkdir /mydata/1.txt
本地查看:
[root@server ~]# ll /data
总用量 0
drwxr-xr-x. 2 root root 6 12月 25 14:35 1.txt
drwxr-xr-x. 2 root root 6 12月 25 14:28 backup
挂载数据卷:
挂载目录的时候,可以指定容器的name,如果不指定则会随机定义。可以使用docker ps查看,即最右侧一列。
[root@server ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
ee15d652cf2a centos "bash" 9 minutes ago Up 9 minutes
practical_panini
挂载:
[root@server ~]# docker run -itd --volumes-from practical_panini centos bash
92dd653bd11014cda33378125087026bad6b514a8d4aebb9d3cf537df8e2bdf5
进入容器查看:
[root@server ~]# docker exec -it 92dd653bd110 bash
[root@92dd653bd110 /]# ls /mydata/
1.txt backup
[root@92dd653bd110 /]#
这样使用centos镜像创建了新的容器,并且使用practical_panini容器的数据卷
定义数据卷容器:
有时候,我们需要多个容器之间相互共享数据,类似于linux里面的NFS,所以就可以搭建一个专门的数据卷容器,然后其他容器直接挂载该数据卷。
首先建立数据卷容器:
[root@server ~]# docker run -itd -v /mydata/ --name testvol centos bash
c80aa5e71d0ed105e036a8559897f955cc3fa55dd0370d12a64fad47c7b54084
[root@server ~]#
注意:这里的/mydata是容器里的目录,并非宿主机本地的目录。
然后让其他容器挂载该数据卷:
[root@server ~]# docker run -itd --volumes-from testvol centos bash
e952dd2c23dc7eb42d4c07944d9f80f77624478b33f4e052114705c7e27f278d
数据卷备份恢复:
备份:
宿主机创建一个本地备份目录
[root@server ~]# mkdir /data/backup_testvol
[root@server ~]#
创建一个容器:
首先是要testvol数据卷新开一个容器,同时还需把宿主机本地的/data/backup_testvol目录挂载到该容器的/backup目录中,然后再把/home目录的文件打包成data.tar文件放到/backup目录中。
[root@server ~]# docker run --volumes-from testvol -v /data/backup_testvol:/backup centos tar cvf
/backup/data.tar /home/
tar: Removing leading `/' from member names
/home/
[root@server ~]# ls /data/backup_testvol/
data.tar
[root@server ~]#
恢复:
先新建一个数据卷容器,再建一个新的容器并挂载该数据卷容器,然后把tar包解包。
创建新的数据卷容器(创建的数据卷目录名称必须和备份的数据卷名称一致);
[root@server ~]# docker run -itd -v /backup --name testvol2 centos bash
ead4594b3289d7761ad009cdfb876cca7fa0007045072830b8c75c949113217b
挂载数据卷新建容器并解包:
[root@server ~]# docker run -it --volumes-from testvol2 -v /data/backup_testvol/:/backup centos bash
[root@ce91be8330be /]# ls
anaconda-post.log bin etc lib media opt root sbin sys usr
backup dev home lib64 mnt proc run srv tmp var
[root@ce91be8330be /]# cd backup
[root@ce91be8330be backup]# tar xf data.tar
[root@ce91be8330be backup]# ls
data.tar home
25.10 docker网络模式
新建容器,进入并安装Nginx服务:
[root@server ~]# docker run -itd centos bash
7cb4aca3e46d45e651edb7824838992e891988a2b2f4626e4a3a463ca1997aa6
[root@server ~]# docker exec -it 7cb4aca3e46d bash
[root@7cb4aca3e46d /]# yum install -y epel-release
[root@7cb4aca3e46d /]# yum install -y nginx
退出容器,把容器导出为镜像:
[root@7cb4aca3e46d /]# exit
exit
[root@server ~]# docker commit -m "install nginx" -a "/data/backup/" 7cb4aca3e46d
centos_with_nginxsha256:16df4d1ec1964844d2ec4b459c477e398aad6916004d632fa7329a48ffa572ef
[root@server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos_with_nginx latest 16df4d1ec196 16 seconds ago 395MB
test latest 5ff484fdca53 2 weeks ago 200MB
centos7 latest 7333d87fdf66 3 weeks ago 435MB
test_centos latest bbf77dba5c7c 3 weeks ago 300MB
192.168.222.114:5000/centos7 latest 75835a67d134 2 months ago 200MB
centos latest 75835a67d134 2 months ago 200MB
registry latest 2e2f252f3c88 3 months ago 33.3MB
[root@server ~]#
使用刚才导出的镜像创建容器,做端口映射:(将宿主机的8088端口映射到容器的80端口)
[root@server ~]# docker run -itd -p 8088:80 centos_with_nginx bash
a302401d1bceb78f712cd9dd54f463b0b8ac970b47318661feb4db1c86d67108
[root@server ~]#
25.11 docker错误:operation not permitted
[root@a302401d1b /]# systemctl start nginx
Failed to get D-Bus connection: Operation not permitted
解决方法:
这是因为dbus-daemon没有启动。解法方法:启动容器时加上:–privileged -e “container=docker”,并且最后的命令bash改为/usr/sbin/init
先删除之前创建的容器之后再重新授权创建新容器,进入容器后可以启动服务。
[root@server ~]# docker rm -f a302401d1b
a302401d1b
[root@server ~]# docker run -itd --privileged -e "container=docker" -p 8088:80 centos_with_nginx
/usr/sbin/init
8cd77c948fa9ea8ab7510cfbc33627a112c9e780638967c03fb9e681de7d3ab4
[root@server ~]# docker exec -it 8cd77c948fa9ea bash
[root@8cd77c948fa9 /]# systemctl start nginx
[root@8cd77c948fa9 /]#
25.12 配置桥接网络
为了使用本地网络中的机器和docker容器更方便的通信,通常会有将docker容器配置到和主机同一网段的需求。只要将docker容器和宿主机的网卡桥连起来,再给docker容器配置ip即可
首先在宿主机上进入到网卡配置文件的目录下,并拷贝网卡配置文件:
[root@server ~]# cd /etc/sysconfig/network-scripts
[root@server network-scripts]# ls
ifcfg-ens33 ifdown-ipv6 ifdown-Team ifup-eth ifup-post ifup-tunnel
ifcfg-lo ifdown-isdn ifdown-TeamPort ifup-ippp ifup-ppp ifup-wireless
ifdown ifdown-post ifdown-tunnel ifup-ipv6 ifup-routes init.ipv6-global
ifdown-bnep ifdown-ppp ifup ifup-isdn ifup-sit network-functions
ifdown-eth ifdown-routes ifup-aliases ifup-plip ifup-Team network-functions-ipv6
ifdown-ippp ifdown-sit ifup-bnep ifup-plusb ifup-TeamPort
[root@server network-scripts]# cp ifcfg-ens33 ifcfg-br0
然后编辑拷贝的网卡配置文件:
[root@server /etc/sysconfig/network-scripts]# vim ifcfg-br0 TYPE=Bridge # 将Ethernet修改为Bridge,并将以下几个字段的值修改为br0 NAME=br0 DEVICE=br0
编辑宿主机的网卡配置文件,并重启网卡:
[root@server /etc/sysconfig/network-scripts]# vim ifcfg-ens33
# 将 UUID、DNS1、DNS2、IPADDR、PREFIX、GATEWAY 等字段都注释掉
BRIDGE=br0 # 然后在文件末尾加上这一句
[root@server /etc/sysconfig/network-scripts]# systemctl restart network
查看网卡IP信息:
[root@server ~]# ifconfig
br0: flags=4163 mtu 1500
inet 192.168.222.114 netmask 255.255.255.0 broadcast 192.168.222.255
inet6 fe80::e1a7:5a24:586c:589b prefixlen 64 scopeid 0x20
ether 00:0c:29:33:56:f0 txqueuelen 1000 (Ethernet)
RX packets 29 bytes 2624 (2.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 25 bytes 2426 (2.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4163 mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:47ff:fe36:883f prefixlen 64 scopeid 0x20
ether 02:42:47:36:88:3f txqueuelen 0 (Ethernet)
RX packets 16 bytes 13113 (12.8 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 28 bytes 3239 (3.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33: flags=4163 mtu 1500
ether 00:0c:29:33:56:f0 txqueuelen 1000 (Ethernet)
RX packets 1308 bytes 118918 (116.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 931 bytes 114688 (112.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
可以看到,br0已经被识别了,并且将原本是ens33网卡的ip分给了br0网卡,而且正常的情况下ens33是没有ip的。
安装pipework工具
先安装git,使用git下载pipework,将pipework命令放到/usr/local/bin目录中
[root@server ~]# yum install -y git
[root@server ~]# git clone https://github.com/jpetazzo/pipework
[root@server ~]# cd pipework/
[root@server pipework]# ls
docker-compose.yml doctoc LICENSE pipework pipework.spec README.md
[root@server pipework]# cp pipework /usr/local/bin/
[root@server pipework]#
使用centos_with_nginx镜像创建一个none模式的容器,使用pipework创建桥接;
pipework用法:pipework 桥连网卡名 容器id 自定义ip/掩码@网关
[root@server ~]# docker run -itd --net=none centos_with_nginx bash
20a4aeff0373a38967dd77c3d3a6d6b010e8ad88fa34b983ae753c619581e9cc
[root@server ~]# pipework br0 20a4aeff0 192.168.222.150/[email protected]
[root@server ~]# docker exec -it 20a4aeff0 bash
[root@20a4aeff0373 /]# ifconfig
bash: ifconfig: command not found
[root@20a4aeff0373 /]# yum install -y net-tools
[root@20a4aeff0373 /]# ifconfig
Dockerfile语法
格式 FROM 或者 ?FROM :,
比如:
FROM centos
FROM centos:latest
格式 ?MAINTAIN ?,
比如
MAINTAINER ?aming [email protected]
格式为 RUN ?或者 RUN [“executable”, “param1”, “param2”],
比如
RUN ?yum install ?httpd
RUN ["/bin/bash", "-c", "echo hello"]
CMD ["executable", "param1", "param2"] CMD command param1 param2 CMD ["param1", "param2"]
RUN和CMD看起来挺像,但是CMD用来指定容器启动时用到的命令,只能有一条。
比如
CMD ["/bin/bash", "/usr/local/nginx/sbin/nginx", "-c", "/usr/local/nginx/conf/nginx.conf"]
格式为 EXPOSE […] ,
比如
EXPOSE 22 80 8443
这个用来指定要映射出去的端口,比如容器内部我们启动了sshd和nginx,所以我们需要把22和80端口暴漏出去。这个需要配合-P(大写)来工作,也就是说在启动容器时,需要加上-P,让它自动分配。如果想指定具体的端口,也可以使用-p(小写)来指定。
格式 ENV ? ,
比如 ?
ENV PATH /usr/local/mysql/bin:$PATH
它主要是为后续的RUN指令提供一个环境变量,我们也可以定义一些自定义的变量
ENV MYSQL_version 5.6
格式 add
将本地的一个文件或目录拷贝到容器的某个目录里。 其中src为Dockerfile所在目录的相对路径,它也可以是一个url。
比如
ADD
格式同add
使用方法和add一样,不同的是,它不支持url
格式类似CMD
容器启动时要执行的命令,它和CMD很像,也是只有一条生效,如果写多个只有最后一条有效。和CMD不同是:CMD 是可以被 docker run 指令覆盖的,而ENTRYPOINT不能覆盖。
比如,容器名字为aming,我们在Dockerfile中指定如下CMD:
CMD?["/bin/echo",?"test"]
启动容器的命令是 ?docker run aming 这样会输出 test;假如启动容器的命令是 docker run -it?aming ?/bin/bash ?什么都不会输出
ENTRYPOINT不会被覆盖,而且会比CMD或者docker run指定的命令要靠前执行
ENTRYPOINT ["echo", "test"]
docker run -it aming ?123
则会输出 test ?123 ,这相当于要执行命令 ?echo test ?123?
格式 ?VOLUME ["/data"]
创建一个可以从本地主机或其他容器挂载的挂载点。
格式 USER daemon
指定运行容器的用户
格式 WORKDIR ?/path/to/workdir
为后续的RUN、CMD或者ENTRYPOINT指定工作目录
Dockerfile示例
创建Dockerfile,编辑内容如下:
vim dockerfile ## Set the base image to CentOS 基于centos镜像 FROM centos # File Author / Maintainer 作者信息 MAINTAINER test [email protected] # Install necessary tools 安装一些依赖的包 RUN yum install -y pcre-devel wget net-tools gcc zlib zlib-devel make openssl-devel # Install Nginx 安装nginx ADD http://nginx.org/download/nginx-1.12.1.tar.gz . # 添加nginx的压缩包到当前目录下 RUN http://nginx.org/download/nginx-1.12.1.tar.gz # 解包 RUN mkdir -p /usr/local/nginx # 创建nginx目录 RUN cd nginx-1.12.1 && ./configure --prefix=/usr/local/nginx && make && make install # 编译安装 RUN rm -fv /usr/local/nginx/conf/nginx.conf # 删除自带的nginx配置文件 ADD http://www.apelearn.com/study_v2/.nginx_conf /usr/local/nginx/conf/nginx.conf # 添加nginx配置文件 # Expose ports 开放80端口出来 EXPOSE 80 # Set the default command to execute when creating a new container 这里是因为防止服务启动后容器会停止的情况,所以需要多执行一句tail命令 ENTRYPOINT /usr/local/nginx/sbin/nginx && tail -f /etc/passwd
创建镜像:
docker build -t centos_nginx .
命令说明:
查看镜像并把容器的80端口映射到本地的81端口;
[root@server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
8c224a66685f 4 days ago 354MB
test latest 5ff484fdca53 4 weeks ago 200MB
centos7 latest 7333d87fdf66 5 weeks ago 435MB
test_centos latest bbf77dba5c7c 5 weeks ago 300MB
centos_nginx latest 75835a67d134 3 months ago 200MB
192.168.222.114:5000/centos7 latest 75835a67d134 3 months ago 200MB
centos latest 75835a67d134 3 months ago 200MB
registry latest 2e2f252f3c88 3 months ago 33.3MB
[root@server ~]# docker run -itd -p 81:80 centos_nginx bash
测试访问;
[root@server ~]# curl localhost:81
用docker compose部署服务
docker compose可以方便我们快捷高效地管理容器的启动、停止、重启等操作,它类似于linux下的shell脚本,基于yaml语法,在该文件里我们可以描述应用的架构,比如用什么镜像、数据卷、网络模式、监听端口等信息。我们可以在一个compose文件中定义一个多容器的应用(比如jumpserver),然后通过该compose来启动这个应用。
下载docker-compose然后放到/usr/local/bin/目录,添加可执行权限
[root@server ~]# curl -L https://github.com/docker/compose/releases/download/1.17.0-rc1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose [root@server ~]# chmod 755 /usr/local/bin/docker-compose
查看版本:
[root@server ~]# docker-compose version
docker-compose version 1.17.0-rc1, build a0f95af
docker-py version: 2.5.1
CPython version: 2.7.13
OpenSSL version: OpenSSL 1.0.1t 3 May 2016
注:Compose区分Version 1和Version 2(Compose 1.6.0+,Docker Engine 1.10.0+)。Version 2支持更多的指令。Version 1没有声明版本默认是"version 1"。Version 1将来会被弃用。
docker compose示例
编辑.yml文件:
[root@server ~]# vim docker-compose.yml
version: "2" # 使用Version 2
services: # 包含需要操作的容器
app1: # 容器的名称
image: centos_nginx # 指定基于哪个镜像
ports: # 指定映射的端口
- "8080:80"
networks: # 指定使用哪个网络模式
- "net1"
volumes: # 指定挂载的的目录
- /data/:/data
app2:
image: test_centos
networks:
- "net2"
volumes:
- /data/:/data1
entrypoint: tail -f /etc/passwd # 这一句是为了让这个容器不会被关闭
networks:
net1:
driver: bridge
net2:
driver: bridge
内容参考:https://coding.net/u/aminglinux/p/yuanke_centos7/git/blob/master/25docker/docker-compose.yml
启动:
[root@server ~]# docker-compose up -d # -d是丢到后台运行(可以启动两个容器)
Creating network "root_net2" with driver "bridge"
Creating network "root_net1" with driver "bridge"
Creating root_app2_1 ...
Creating root_app1_1 ...
Creating root_app2_1
Creating root_app1_1 ... done
查看命令的帮助文档:docker-compose --help
常用命令:
docker-compose语法的参考文档:http://www.web3.xin/index/article/182.html