一、仓库使用
1、docker官方仓库
1.1、注册
https://hub.docker.com
自由注册,邮件激活即可使用
1.2、命令使用
Docker pull/search/login/push/tag
示例:docker push chenhuajing/hankin:tagname
tag [镜像名:版本] [仓库]/[镜像名:版本]:标记本地镜像,将其归入某一仓库。
Push [仓库]/[镜像名:版本]: 推送镜像到仓库,需要登陆。
Search [镜像名]:在仓库中查询镜像,无法查询到tag版本。
Pull [镜像名:版本]:下载镜像到本地 。
Login:登陆仓库。
1)命令登陆dockerhub
2)再使用tag命令标记一个镜像,指定自己的仓库
命令:docker tag hello-world:latest chenhuajing/hello:1.0
3)使用push命令推送此镜像到仓库里
docker push chenhuajing/hello:1.0
4)打开查询自己仓库的镜像(hello为镜像名)
2、私有仓库
2.1、搭建
下载registry镜像:docker pull registry
可配置加速器加速下载
{"registry-mirrors": ["https://registry.docker-cn.com","http://hub-mirror.c.163.com"]}
2.2、启动
命令:docker run -d --name reg3 -p 5000:5000 registry
[root@localhost ~]# docker run -d --name reg3 -p 5000:5000 registry
28bf2994438a81de107188360cec86dcaf75f1983233ba9c77471ab6f22bf439
可以通过docker ps查看我们创建的仓库registry。
然后可以通过restful接口查看仓库中的镜像(当前仓库是空的)
命令:curl http://192.168.30.166:5000/v2/_catalog
2.3、配置http传输
私服默认只能使用https,需要配置开放http
vim /etc/docker/daemon.json
配置完毕重启下docker服务:
systemctl daemon-reload
systemctl restart docker
2.4、私服仓库推送镜像
1)首先标记本地镜像hello-word,将其归入仓库192.168.30.166:5000/hello版本为1.0
命令:docker tag hello-world 192.168.30.166:5000/hello:1.0
2)将标记好的镜像hello推送到仓库
docker push 192.168.30.166:5000/hello
3)查询镜像:
curl http://192.168.30.166:5000/v2/_catalog
4)查询hello版本:
curl http://192.168.30.166:5000/v2/hello/tags/list
3、commit镜像并上传仓库
创建一个centos容器,启动后自动进入此容器:
命令:docker run -it --name cent centos /bin/bash
inspect[容器名]:查看容器配置元数据
exec -it [容器名] /bin/bash:进入容器环境中交互操作
命令:docker exec -it cent /bin/bash
3.1、容器内安装nginx服务:
1)添加一下nginx源:
rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
yum search nginx ## 搜索一下看看
yum install nginx -y ## 安装
2)启动nginx服务
启动命令:
whereis nginx
查看centos的IP地址为:172.17.0.3/16
ctrl +P+Q退出容器,在主机环境内校验nginx请求,正常得到欢迎页
3.2、commit服务为一个nginx镜像
现在要将cent容器提交成为一个镜像,命令如下:
docker commit cent cent-ng:v1
可看到得到了新的镜像cent-ng:v1
3.3、启动此nginx镜像
1)使用新建的镜像创建容器,并进入查看,发现已安装有nginx,但并未启动
命令:docker run -it --name ng cent-ng:v1 /bin/bash
这里我们手动启动nginx:/usr/sbin/nginx
备注:Nginx常用命令:
启停命令:如果不指定,默认为NGINX_HOME/conf/nginx.conf
./nginx -c /usr/local/nginx/conf/nginx.conf
./nginx -s stop ## 停止
./nginx -s quit ## 退出
./nginx -s reload ## 重新加载nginx.conf
在主机方校验,nginx欢迎页面出现。
2)现在我们希望启动容器时,直接启动nginx服务,怎么做?
命令:docker run -d --name ngx3 cent-ng:v1 /usr/sbin/nginx -g "daemon off;"
[root@localhost local]# docker run -d --name ngx3 cent-ng:v1 /usr/sbin/nginx -g "daemon off;"
36a2e8a9771982900fec52ade1ba2e98bdf5584864a2c0e33279e9f429d0c410
查看ngx3的信息:IP为:172.17.0.5
可看到,容器内nginx服务也已正常运行:
ps:
后面运行的命令都是容器命令,由于nginx命令没有设置到path中,所以全路径启动;
而nginx -g这个参数是指可以在外面添加指令到nginx的配置文件中;
daemon off是指nginx服务不运行在后端,而是在前台运行(container中的服务必须运行在前台)。
3.4、commit创建镜像方式的本质
原容器与commit后的镜像,在文件系统上并无区别。只是把容器层原来的可写属性,置成了只读。于是变成了一个不可改的镜像。
二、数据管理
docker容器运行,产生一些数据/文件/等等持久化的东西,不应该放在容器内部。应当以挂载的形式存在主机文件系统中。
1、docker的文件系统
镜像与容器读写层,通过联合文件系统,组成系统文件视角。
容器服务运行中,一定会生成数据。
容器只是运行态的服务器,是瞬时的,不承载数据的持久功能。
2、volume文件挂载的探究
1)volume参数创建容器数据卷
命令:docker run --name data -v /opt/data -it centos /bin/bash
2)我们通过docker inspect data查看容器元数据,可看到挂载信息:
查询结果如下:
"Mounts": [ {
"Type": "volume",
"Name": "023a93637bf8f13114d382dda72bca827b469a85a99e291ecd07066179cbf927",
"Source": "/var/lib/docker/volumes/023a93637bf8f13114d382dda72bca827b469a85a99e291ecd07066179cbf927/_data",
"Destination": "/opt/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
备注:
Source:宿主机对应的位置023a93637bf8f13114d382dda72bca827b469a85a99e291ecd07066179cbf927
Destination:-v指定的目录
3)在data容器端添加一个文件a123,输入内容123456
回主机目录查看,果然存在此文件:
位置:/var/lib/docker/volumes/023a93637bf8f13114d382dda72bca827b469a85a99e291ecd07066179cbf927/_data
4)在主机方添加一个文件456:
echo 456 > /var/lib/docker/volumes/023a93637bf8f13114d382dda72bca827b469a85a99e291ecd07066179cbf927/_data/456
回容器里查看,果然也同步增加了此文件:
5)指定主机目录方式挂载文件
格式:-v path1:path2
如下命令,容器方会自动增加一个data目录
命令:docker run --name ce2 -v /opt/data:/data -it centos /bin/bash
宿主机方,同样自动增加一个/opt/data目录。
3、volumes-from引用数据卷
新启一容器,引入上一步的data容器目录:
命令:docker run -it --rm --volumes-from data --name app centos /bin/bash
自动得到同一个目录,内容与data容器里挂载一样:
4、备份/恢复数据卷
备份:
docker run --rm --volumes-from data -v $(pwd):/backup centos tar cvf /backup/data.tar /opt/data
恢复:
docker run --rm --volumes-from data -v $(pwd):/backup centos tar xvf /backup/data.tar -C /
释义:
docker run --rm:启动一个新的容器,执行完毕删除。
--volumes-from data:data容器中挂载卷。
-v $(pwd):/backup:挂载当前目录到容器中为backup。
cvf /backup/data.tar /opt/data:备份/opt/data目录(即卷中所有的数据)为data.tar。
xvf /backup/data.tar -C /:解压data.tar 到根目录/ ,因tar归档中已包含了/opt/data路径。
5、删除数据卷:
docker rm -v data
三、Dockerfile使用
1、dockerfile方式创建容器
1.1、创建Dockerfile文件(文件位置/root/dockerfile/cmd/)
最简单的dockerfile内容如下:
[root@localhost cmd]# cat Dockerfile
FROM centos
#CMD echo "hello cmd"
CMD ["/bin/bash", "-c", "echo 'hello cmd!'"]
1.2、创建镜像
命令:docker build -t cmd .
使用此镜像运行一个容器:
[root@localhost cmd]# docker run -it cmd
hello cmd!
2、dockerfile基本要素
3、dockerfile指令
3.1、FROM:
FROM {base镜像}
必须放在Dockerfile的第一行,表示从哪个baseimage开始构建
docker run -it --name centOS -v /home/hankin/data:/data centos
volumes-from使用
docker run -it --name centOs1 --volumes-from dataos centos
3.2、MAINTAINER:
可选的,用来标识image作者的地方。
3.3、RUN
RUN都是启动一个容器、执行命令、然后提交存储层文件变更。
第一层 RUN command1 的执行仅仅是当前进程,一个内存上的变化而已,其结果不会造成任何文件。
而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。而如果需要将两条命令或者多条命令联合起来执行需要加上&&。
如:cd /usr/local/src && wget xxxxxxx
3.4、CMD:
CMD的作用是作为执行container时候的默认行为(容器默认的启动命令)。
当运行container的时候声明了command,则不再用image中的CMD默认所定义的命令。
一个Dockerfile中只能有一个有效的CMD,当定义多个CMD的时候,只有最后一个才会起作用。
3.5、EXPOSE
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在Dockerfile中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
3.6、entrypoint:
entrypoint的作用是,把整个container变成可执行的文件,且不能够通过替换CMD的方法来改变创建container的方式,但是可以通过参数传递的方法影响到container内部。每个Dockerfile只能够包含一个entrypoint,多个entrypoint只有最后一个有效。当定义了entrypoint以后,CMD只能够作为参数进行传递。
3.7、ADD & COPY:
把host上的文件或者目录复制到image中(能够进行自动解压压缩包)。
3.8、ENV:
用来设置环境变量,后续的RUN可以使用它所创建的环境变量。
3.9、WORKDIR:
用来指定当前工作目录(或者称为当前目录) 。
3.10、USER:
运行RUN指令的用户。
3.11、VOLUME:
用来创建一个在image之外的mount point。
例如:挂载主机文件目录到容器内
docker run -dit -v /root/hankin_dir/:/pdir --name cent centos
四、nginx镜像制作实战
1、nginx镜像制作
1.1、编译/安装nginx
mkdir一个目录,在此目录内下载nginx源码包:
wget http://nginx.org/download/nginx-1.13.2.tar.gz
并创建一个Dockerfile文件,文件内制作一系列nginx的编译安装流程,内容如文件:
其中,每一个RUN就是增加一个镜像层文件,一层层的RUN命令最终形成一系列镜像层。
运行build指令(注意最后的.代表当前路径),制作镜像。
命令:docker build -t cent-ngx1 .
我们查看一下这个镜像的层次历史:
可看到,此镜像层基本与dockerfile文件的RUN是一一对应的
1.2、使用制作的nginx镜像,创建一个容器
因为镜像无前台命令,因此必须指定启动命令:
命令:docker run -d --name ngx1 cent-ngx1 /usr/local/nginx/sbin/nginx -g "daemon off;"
1.3、为镜像指定环境变量,挂载目录,默认启动命令
在上一版镜像的基础上,我们新加配置:
查看dockerfile文件:
vim /root/dockerfile/nginx2/Dockerfile
# base image
FROM cent-ngx1:latest ## 前一个镜像的基础上
ENV PATH /usr/local/nginx/sbin:$PATH ## 直接可以认识nginx命令
CMD ["/bin/bash", "-c", "nginx -g 'daemon off;'"] ## 容器启动时,默认起这个命令
通过这个dockerfile我们build一个新的容器cent-ngx2
执行:docker build -t cent-ngx2 .
查看镜像的历史,可看到比ngx2的镜像多了几个层:
Ngx2的镜像创建容器,已经不需要再指定cmd命令了
可执行命令自行校验:
docker run -d --name ng2 cent-ngx2
2、docker容器的主业
docker理念里,容器启动时,应当为它指定主业是什么,如nginx容器主业就是nginx代理服务,tomcat容器就是web服务等等。
1)容器创建时,必须指定主业任务,如不指定,则容器无事可干立即退出。
2)在dockerfile打包镜像时,可以使用cmd命令来指定一个默认的主业,如下:
3)既然镜像里是默认主业,即意味着创建容器时,可以覆盖此默认命令,如下:
命令:docker run -d --name test 3b6acb4b6bd8 echo “hello”
注意:3b6acb4b6bd8为镜像v3的镜像ID。
2.1、推荐的ENTRYPOINT方式
1)镜像本身应该有稳定的主业,应当指定后即不能更改用途,于是引入ENTRYPOINT
2)使用ENTRYPOINT,字义即容器入口,它不能被run中cmd覆盖,如下例:
[root@localhost nginx3]# cat Dockerfile
# base image
FROM cent-ngx2:latest
ENV PATH /usr/local/nginx/sbin:$PATH
ENTRYPOINT ["nginx"] ## 指定入口命令为nginx服务
CMD ["-g","daemon off;"] ## 指定nginx命令参数
执行命令:
docker build -t nginx:v3 .
docker run -d --name ngx3 nginx:v3
以后使用nginx:v3这个镜像时,只能做nginx服务来使用啦。
2.2、手动打包springboot镜像
我们需要对业务项目打包发布,一样需要制作成为业务镜像,供运维使用,下面讲述springboot的制作过程:
1)将springboot打好的jar包上传
2)在同级目录下,创建Dockerfile文件,内容如下:
3)dockerfile打包业务镜像
命令:docker build -t member:v1 .
4)启动镜像,即得到业务运行:
docker run -d -p 8090:8090 --name member member:v1
5)浏览器打开页面校验:http://192.168.30.166:8090/
3、maven源码打包用法
更多的情况,我们是直接在运维环境里,上传源码,直接maven打包jar,然后再进一步打包成镜像,与手动打包过程类似。如果环境中没有安装maven,请手动安装,脚本如下:
yum install -y yum-utils device-mapper-persistent-data lvm2
# yum-config-manager --add-repo http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo
# yum-config-manager --enable epel-apache-maven
// 安装maven
# yum install -y apache-maven
1)上传原码到docker环境中(一般是git/svn直接拉取源码)
2)maven打包
mvn clean package
生成的jar在同级target目录下:
3)执行docker命令生成镜像
dockerfile文件内容:
命令创建镜像:
docker build -t member .
3.1、maven插件打包
前面打springboot包的方式,需要手动上传项目jar或者源码到服务器(违和感很强),这对于开发人员日常发布开发环境项目,极为不便。下面演示一个maven插件:docker-maven-plugin用法,来打通环境。
前提条件:
- 需要我们windows上安装docker服务。
- 需要docker服务配置http仓库接口,windows上docker服务配置如下(传统配置模式无权限修改文件)。
本地环境配置:
- windows上安装docker-toolbox,傻瓜安装即可。
- 打开Docker Quickstart Terminal终端,等待初始始化完成后。
- 输入docker-machine env命令,返回docker服务的api接口和证书位置,如下:
sed -i "s|EXTRA_ARGS='|EXTRA_ARGS='--registry-mirror=https://registry.docker-cn.com |g" /var/lib/boot2docker/profile
- 输入docker-machine ssh命令,进入sh环境中,配置http仓库路径
修改文件配置(当前用户是docker不是root,要sudo提升至root):
vi /var/lib/boot2docker/profile
- 修改完成,保存。重启docker服务
sudo /etc/init.d/docker restart
3.2、项目环境配置maven插件
在我们的工程pom中加入docker-maven-plugin插件的配置,如下
1)其中,imageName配置镜像的全路径名,即指定私库的名称
2)dockerHost和dockerCertPath对应配置上一步中docker的api和证书值
3.3、打包运行
以idea为例,整个项目装配完成,只需要操作maven的一二三步骤,即直接镜像进入仓库,整个过程毫无违和感。
若使用的不是idea工具,可直接使用maven命令,一句完成打包,如下:
3.4、校验镜像仓库结果
至此,我们的服务器环境,已经可以直接运行docker run 镜像得到结果了。