Docker常用命令与构建中遇到的问题
最近在忙微服务和数据系统的容器化,所以又重温了一遍docker网络与基本操作并成功实现docker化。为了提高查找命令的效率,所以总结了dockerfile编写中常用的命令。
docker安装
检查系统环境
检查当前设备是否具备安装docker的配置要求:
$ curl https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh > check-config.sh
$ sh ./check-config.sh
该脚本只在linux上使用,MacOS不能使用(MacOS使用docker可以直接安装,依赖配置都是已经有的)
安装docker
安装步骤就不重复说明了,直接按照菜鸟教程敲一遍就行了,最近刚部署一个服务器,亲测可用。地址:https://www.runoob.com/docker/centos-docker-install.html
但上面操作后有个问题,安装docker后默认是root权限才可以运行的。
docker守护进程启动的时候,会默认赋予名为docker的用户组读写Unix socket的权限,因此只要创建docker用户组,并将当前用户加入到docker用户组中,那么当前用户就有权限访问Unix socket了,也就可以执行docker相关命令。
非root用户使用docker的配置步骤:
sudo groupadd docker #添加docker用户组
sudo gpasswd -a $USER docker #将登陆用户加入到docker用户组中
newgrp docker #更新用户组
docker info #查看docker信息
另外,如果使用aws的Amazon linux2的话,最好直接使用aws的官方方法,原因请看这里:https://aws.amazon.com/cn/amazon-linux-2/release-notes/
在之前部署的时候,首先手动增加了docker-ce的源,然后再使用aws的方法安装docker时,就导致安装过程一直缺少依赖,所以当ec2的AMIId在20200207或者更新的版本,一定不要混合使用两种安装方法。
aws安装docker的方法请看这里:
https://docs.aws.amazon.com/zh_cn/AmazonECS/latest/developerguide/docker-basics.html
docker常用操作
更多命令可以参考官方文档:https://docs.docker.com/install/
或者更接地气一些,菜鸟文档:https://www.runoob.com/docker/docker-tutorial.html
容器操作
- 查看运行容器
// 加上-a查看所有容器
docker ps
- 进入容器(其中字符串为容器ID)
docker exec -it d27bd3008ad9 /bin/bash
- 启动容器
// 启动容器并以bash形式进入
docker run -p 9000:9000 -it --name server-api-docker server-api:1.0.0 /bin/bash
// 启动容器并在后台运行
docker run -p 9000:9000 -itd --name server-api-docker server-api:1.0.0 /bin/bash
// 启动容器并在后台运行,并传入指定参数(相当于创建dockerfile的ENV)
docker run -p 9000:9000 -d --name server-api-docker -e project_name="server-api" server-api:1.0.0
// 启动容器并在后台运行,并指定所在网络
docker run -p 9000:9000 -d --name server-api-docker --network test-net server-api:1.0.0
// 启动容器,并指定路径映射
docker run -p 9000:9000 -itd --name fps-api-dev --network fps-dev -e project_name="server-api" -v /Users/xiaohui/offer_java/test_docker/logs:/docker/logs server-api:1.0.0 /bin/bash
// 启动容器,指定host网络并指定路径映射
docker run -itd --name fps-api-dev --network host -e project_name="server-api" -v /Users/xiaohui/offer_java/test_docker/logs:/docker/logs server-api:1.0.0 /bin/bash
- 停用全部运行中的容器
// stop可以换成start、restart
docker stop $(docker ps -q)
- 停用所有容器并删除所有容器
docker stop $(docker ps -q) && docker rm $(docker ps -aq)
- 查看docker信息(其中字符串为容器ID)
docker inspect 75d882
docker top 75d882
镜像操作
- 拉取镜像
// tag在docker hub上查找,如果不设置tag,会下载最新版本
docker pull ubuntu:14.04
- 搜索镜像
docker search httpd
- 查看本地所有镜像
// docker image ls 效果也一样
docker images
- 删除镜像
docker rmi hello-world
- 创建镜像
// 方法1:从已经创建的容器中更新镜像,并且提交这个镜像
docker run -t -i ubuntu:15.10 /bin/bash
...进入镜像更新文件
exit
docker commit -m="提交的描述信息" -a="作者" e218edb1 xiaohui/ubuntu:v1
// 方法2:使用dockerfile来创建镜像。--build-arg相当于新建ENV
docker build -t server-api:1.0.0 -f ./server-api.dockerfile --build-arg project_name=server-api .
- 设置镜像标签
docker tag 860c279d2 xiaohui/centos:dev
互联操作
- 新建docker网络
// -d 指定docker网络类型。test-net是网络名词
docker network create -d bridge test-net
日志操作
- 查看指定时间后的日志,只显示最后100行:
docker logs -f -t --since="2018-02-08" --tail=100 CONTAINER_ID
- 查看最近30分钟的日志:
docker logs --since 30m CONTAINER_ID
- 查看某时间之后的日志:
docker logs -t --since="2018-02-08T13:23:37" CONTAINER_ID
- 查看某时间段日志:
docker logs -t --since="2018-02-08T13:23:37" --until "2018-02-09T12:23:37" CONTAINER_ID
docker通信遇到的问题
不同情况互相访问的方法
容器或应用在一台宿主机上
- 容器A访问容器B
这种情况使用自定义bridge网络,这样容器A访问容器B,直接使用容器名称即可。
- 容器内访问容器外应用
容器中的应用使用"localhost"或"127.0.0.1"是loopback地址,会局限在容器内。
docker默认启动一个bridge网络(docker0),如果启动的容器没有指定自定义的网络,docker会在docker0中选取一个未被使用的IP赋给容器(通过ip route查询)。
- 容器外应用访问容器A
容器内应用要想开放访问,容器需要使用host网络,或者使用bridge网络,将端口映射到宿主机的端口,这么做了以后,就可以像访问本地应用一样访问容器应用了。
容器或应用不在一台宿主机上
- 机器A容器访问机器B本地应用
直接访问,没有什么特殊,机器A容器中访问机器B的IP地址和应用的端口即可。
- 机器A本地应用/容器访问机器B容器
只要机器B中的容器使用host网络或者将端口映射到宿主机(机器B)端口,就可以通过宿主机IP加端口访问。
MacOS开启路由转发功能
项目中数据库采用域名形式,容器中的tomcat想要访问数据库,结果在mbp本地起服显示无法连接数据库,所以查询了一番,需要开启宿主机的路由转发功能,所以只列举了MacOS的开启方式,linux系统解决方案类似。
MacOS执行下面命令即可:
sudo sysctl -w net.inet.ip.forwarding=1
这种做法将在机器下次重启后失效,如果想要永久保存,编辑文件/etc/sysctl.conf,配置下面变量:
net.inet.ip.forwarding=1
FAQ
dockerfile与docker-compose的区别
dockerfile
dockerfile的作用是从无到有的构建镜像。它包含安装运行所需的环境、程序代码等。这个创建过程就是使用 dockerfile 来完成的。
docker-compose
docker-compose是编排容器的。例如,你有一个php镜像,一个mysql镜像,一个nginx镜像。如果没有docker-compose,那么每次启动的时候,你需要敲各个容器的启动参数,环境变量,容器命名,指定不同容器的链接参数等等一系列的操作,相当繁琐。而用了docker-composer之后,你就可以把这些命令一次性写在docker-composer.yml文件中,以后每次启动这一整个环境(含3个容器)的时候,只需要"docker-composer up"命令就可以了。
docker-compose的安装步骤:
sudo curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose # 从github下载二进制文件
sudo chmod +x /usr/local/bin/docker-compose #修改docker-compose权限
docker-compose version #查看docker-compose信息
最后,限于笔者经验水平有限,欢迎读者就文中的观点提出宝贵的建议和意见。如果想获得更多的学习资源或者想和更多的是技术爱好者一起交流,可以关注我的公众号『全菜工程师小辉』后台回复关键词领取学习资料、进入后端技术交流群和程序员副业群。同时也可以加入程序员副业群Q群:735764906 一起交流。
哎呀,如果我的名片丢了。微信搜索“全菜工程师小辉”,依然可以找到我