从命名上就知道这是一篇简单粗暴的
docker
新手入门教程, 为何要简单粗暴? 我认为有自学能力的人帮他入门就够了, 不能自学的一时半会儿也教不会, 不符合入门教程的初衷, 建议出门左拐去找找视频教程...html
强烈推荐使用 Docker for Mac
或 Docker for Windows
, 这两个工具已经将 Kitematic
和 docker-compose
集成好了, 至于这两个工具是作什么的我们后面再说, win10
版本须要专业版的, 否则开启不了Hyper-V
, win7
就别想了,不支持...nginx
怎么安装在 阿里云镜像容器服务 里面都说的很清楚了, 连国内镜像源都给你安排好了, 我们就进入下一话题git
PS: 若是是 CentOS 6 的就须要升级一下系统内核了, centOS6.5 安装docker, 毕竟都
8102
年了, docker 又是个比较新的东西, 对于稍微久一点的系统的支持就不那么友好github
安装完环境以后就启动一个镜像开开眼儿redis
docker run -d -p 8080:80 --name local_nginx nginx
复制代码
而后访问 http://localhost:8080/
就能看到 nginx
的初始界面了 docker
中间发生了什么呢?ubuntu
docker run
运行镜像的起手式, 详情查看 docker run --help
-d
启动 docker
守护进程-p 8080:80
将本地的 8080
端口绑定到容器的 80
端口上--name local_nginx
分配一个容器名, 不写的话会默认分配要给, 不过这个仍是颇有用的nginx
指定运行的镜像名,若是没有指定标签则默认是 latest
, 这里实际上是启动nginx:latest
镜像如今能够查看一下本机都在运行着什么镜像centos
PS D:\docker_study> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6732fa239270 nginx "nginx -g 'daemon of…" 18 minutes ago Up 18 minutes 0.0.0.0:8080->80/tcp local_nginx
复制代码
docker ps
只能看到正在运行中的容器, 想看到所有的就是 docker ps -a
bash
进入这个容器的命令:网络
docker exec -it 6732fa239270 /bin/bash
#或
docker exec -it local_nginx /bin/bash
复制代码
解释一下:
docker exec
在容器中执行命令-i
保持stdin打开-t
分配一个伪终端(tty)6732fa239270 或 local_nginx
这里你也发现了, 能够是经过 CONTAINER ID
也能够是 NAMES
这里的 CONTAINER ID
分为128位长ID和32位短ID, 不过做用都是同样的/bin/bash
运行容器中的 /bin/bash
脚本进入容器中感受其实和进入一个虚拟机同样, 可是容器和虚拟机有点区别, 这个咱们下一小节会讲到
关闭容器
docker stop 6732fa239270 或 local_nginx
复制代码
以前咱们使用 VirtualBox
装虚拟机的时候有装盘镜像, 可是启动后就是一个个的虚拟机了, 不过在 docker 中和虚拟机仍是有点区别
就拿上图来讲, container
就是镜像的实例化, image
是容器的底层支撑, 其实他们的关系用代码中的类Class
来比喻是最合适的:
简单的说 Container 就是 Image 的儿子, 模样和 Image 预想的同样, 可是 Container 运行以后会发生一些改变, 并且这种改变是能够保存的
7-11补充: 这位大佬讲的 image 和 虚拟机 以前的很清晰 -> 宋宝华:Docker 最初的2小时(Docker从入门到入门), 不过推荐是先敲几个实际的例子运行一下再看, 工具先跑起来再去了解它嘛!
我们先不说构建镜像的事儿(那是下一章的话题), 这里先了解一下 docker run
命令中比较经常使用的参数:
-it
创建一个可在终端交互的容器好比:
docker run -it --name local_nginx nginx:latest /bin/bash
# 或
docker exec -it local_nginx bin/bash
复制代码
-p
用于宿主机和容器的端口绑定绑定多个端口就设置多个映射
docker run -d -p 8088:80 -p 4433:443 nginx:latest
# 或 不写本地端口, docker 将帮你自动分配
docker run -d -p :80 -p :443 nginx:latest
# 或 加上 ip 就绑本地指定的 ip
docker run -d -p 127.0.0.1:8088:80 -p :443 nginx:latest
# 或 照样不写本地端口就随机分配
docker run -d -p 127.0.0.1::80 -p :443 nginx:latest
复制代码
经过 docker ps
能够看一下上面两行命令的执行状态
➜ test docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
57f65b46bd87 nginx:latest "nginx -g 'daemon of…" 1 second ago Up 3 seconds 0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp happy_zhukovsky
0c035ebabe44 nginx:latest "nginx -g 'daemon of…" About a minute ago Up About a minute 0.0.0.0:8088->80/tcp, 0.0.0.0:4433->443/tcp ecstatic_haibt
复制代码
-v
将宿主机的卷挂载到容器中的指定目录docker run -d -p 8088:80 -v /Users/gpf/Documents/docker_study/docker_test/www/:/usr/share/nginx/html/ nginx:latest
复制代码
这里本地的目录要写绝对路径, 否则会报错, 这样一来, 本地的/Users/gpf/Documents/docker_study/docker_test/www/
就是容器中的/usr/share/nginx/html/
, 就能够本地更改代码, 而后容器中运行
-d
后台运行想查看日志的话就 docker logs [containerID]
就行
docker exec
执行 docker 容器中的命令一般就是用来进入容器中搞七搞八的
docker exec -it 57f65b46bd87 /bin/bash
# 或
docker exsec -it local_nginx /bin/bash
复制代码
这里注意两点:
containerID
在不少状况下均可以用 container Name
来代替, 不少状况是等价的/bin/bash
不是必须这么填, 而是执行的容器中的脚本, 若是你的镜像是 alpine
版的就是 sh
, 由于这个版本中就没有 bash 这个命令docker ps
容器的运行状态docker stop [containerID 或 name]
中止容器目前版本也增长了 docker container stop [containerID 或 name]
其实做用是同样的, 不过 docker container
命令底下还有不少别的命令, docker 给各模块的命令作了细分
docker rm [containerID 或 name]
删除指定未运行的容器, 一个或多个docker rm 6dee0a9b5232 582f708af9d3
复制代码
docker rmi [imageID 或 tag]
删除宿主机指定的镜像这里要注意若是这个镜像还有容器在使用就不能删除掉, 这个时候要先把对应的容器删掉才行 删除指定镜像的容器
docker stop $(docker ps | grep '这里写imageName' | awk '{ print $1}')
docker rm $(docker ps | grep '这里写imageName' | awk '{ print $1}')
复制代码
删除临时构建的镜像
docker rmi $(docker images | grep '<none>' | awk '{ print $3}')
复制代码
这一手仍是慎用,一些状况下可形成 rm -rf /*
的效果
#移除全部未使用的镜像
docker image prune
#移除全部未运行的容器
docker container prune
#移除全部未使用的本地卷
docker volume prune
...
复制代码
PS: 由于有这一手, 因此能够看出官方的态度, 他们貌似也许可能没准大概差很少不建议把容器当成虚拟机同样把全部的东西都堆在一个镜像里面, 那样搞不止构建出来的镜像臃肿, 并且维护性移植性不好, 从目前网上的 docker 镜像资源来讲, 基础镜像 alpine > debian > ubuntu > centos, 优先使用最小的基础构建, 而后整个 image 只为一个服务而构建, 好比 redis 镜像里只要 redis, 没有什么 MySQL, memcache 什么的, 多个独立的 service 才组成一个 APP, 里面各个组件替换的话不用考虑其余组件的环境依赖什么的, 固然, 这个也是看业务的实际须要, 不能为了拆分而拆分, 在这之间能找到最合适本身的才是工具给咱们带来的便利
docker network
容器之间的互联若是只是在一个容器里搞来搞去就真的是虚拟机了, docker 的强大之处就是它内部维护一个网络, 处在相同网络的容器是能够互通的
# 新建一个 docker 网络, -d bridge 是指定网络模式, 当前是桥接网络
docker network create -d bridge nginx_swarm
# 启动两个 nginx 容器, 分别命名 nginx_swarm_a nginx_swarm_b , 二者都加入了 nginx_swarm 这个网络 --rm 是当容器中止后自动删除
docker run -it --rm --name nginx_swarm_a --network nginx_swarm nginx /bin/bash
docker run -it --rm --name nginx_swarm_b --network nginx_swarm nginx /bin/bash
复制代码
注意, 咱们并没把接口暴露出去, 如今随便在一个容器中 ping
另外一个容器
# 这是在 nginx_swarm_a 中
# 没有 ping 命令的先装一个 ping
# apt-get update && apt-get install -y iputils-ping
root@73d04107780f:/# ping -c 3 nginx_swarm_b
PING nginx_swarm_b (172.18.0.3) 56(84) bytes of data.
64 bytes from nginx_swarm_b.nginx_swarm (172.18.0.3): icmp_seq=1 ttl=64 time=0.084 ms
64 bytes from nginx_swarm_b.nginx_swarm (172.18.0.3): icmp_seq=2 ttl=64 time=0.161 ms
64 bytes from nginx_swarm_b.nginx_swarm (172.18.0.3): icmp_seq=3 ttl=64 time=0.146 ms
--- nginx_swarm_b ping statistics ---
复制代码
docker 能自动的把 server name 转换成 ip, 咱们只须要标明请求的是哪一个容器, 而不是还要记住它的 ip 地址(固然 ip 地址也能设置)
弄明白如下几点启动一个容器应该是没什么问题了:
docker run -v xx:xx
或者 docker create volume ...
用独立的卷来保存network
下的容器才能经过容器明互相访问参考资料: Docker — 从入门到实践 nginx 官方镜像