Docker 也是作为我的第二技能栈之一,除了 Go 语言,Docker 是我最喜欢的第二技能栈了,值得一提的是,Docker 是 Go 语言编写的。现在很多公司已经全面实现项目部署的容器化,这也是未来发展的一个方向,所以我也会在这里推一些关于 Docker 的文章。
Docker-ce 使用前的一些设置
设置 Docker 版本镜像仓库,从而可以轻松完成安装和升级任务:
$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2
添加 Docker 源,始终需要使用 table 镜像仓库进行更新 Docker 版本:
$ sudo yum-config-manager \ --add-repo https://download.docker.com/linux/centos/docker-ce.repo
安装 Docker:
$ sudo yum install docker-ce
启动 Docker:
$ sudo systemctl start docker
使用镜像
拉取镜像
在 Docker hub 上已经有很多现成的镜像了,只需要执行 docker pull 命令就可以拉取到本地:
$ docker pull tomcat
就这样,简单的一条命令就把 tomcat 运行环境的镜像 pull 到本地了,这里没有选取 tomcat 的版本,默认是 latest,关于命令的详细用法,在这里就不详细展开了。
查看本地镜像列表:
$ docker images
运行镜像
拉取镜像后,那么我们试着运行一下镜像,并试着在里面执行 echo 语句:
$ docker run -i -t d23bdf5b1b1b echo "hello world"
注:关于 Dockerfile 制作镜像的教程后面再单独一篇写。
操作容器
运行容器
前面写了运行镜像并执行 echo 输出语句的演示,不过在输出之后,容器就立马停止运行了,那是因为容器运行到的必要条件就是容器里面有进程在,如果没进程了,那么容器就会自动关闭,所以我们需要在容器启动的时候就让它运行进程:
$ docker run -d -p 3306:3306 5709795eeffa /usr/sbin/service mysql start
其中 -d 后台运行,-p 是绑定宿主机与容器端口,后面的地址是容器启动时候执行的命令,就这样一条指令,就可以是 mysql 容器启动成功并运行 mysql,并且与宿主机的 3306 端口映射。
使用 docker ps 列出运行着的容器列表:
$ docker ps
常用的一些参数如下:
•-a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;•-d: 后台运行容器,并返回容器ID;•-i: 以交互模式运行容器,通常与 -t 同时使用;•-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;•--name="nginx-lb": 为容器指定一个名称;•--dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;•--dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;•-h "mars": 指定容器的hostname;•-e username="ritchie": 设置环境变量;•--env-file=[]: 从指定文件读入环境变量;•--cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;•-m :设置容器使用内存最大值;•--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;•--link=[]: 添加链接到另一个容器;•--expose=[]: 开放一个端口或一组端口;
查看容器信息
$ docker docker inspect <容器名称或ID>
[ { "Id": "41d0411f1798494e1c4360afbda4fb536288ba47ae36931951a5aae0624d2c71", "Created": "2017-11-27T12:49:46.56681993Z", "Path": "catalina.sh", "Args": [ "run" ], ... "HostConfig": { "Binds": [ "/opt/public/install/apache-tomcat-8.5.23/webapps/:/usr/local/tomcat/webapps" ], ... "Mounts": [ { "Source": "/opt/public/install/apache-tomcat-8.5.23/webapps", "Destination": "/usr/local/tomcat/webapps", "Mode": "", "RW": true, "Propagation": "rprivate" } ], ... ]
其中 Mounts 字段的内容就是数据卷挂载信息了,下面会说到。
终止容器
$ docker stop <容器名字或id>
但这种方式并没有彻底把容器销毁,下次可以用 docker start 启动,并恢复之前的状态,如果想彻底删除容器,可以使用
$ docker rm <容器名字或id>
进出容器
进入容器有多种方法,这里推荐使用 docker attach 和 docker exec 命令
$ docker exec -i -t mynginx /bin/bash
进入 mynginx 容器内,开启终端。
那么这时候如果退出容器呢
ctrl+d 退出容器且关闭, docker ps 查看无ctrl+p+q 退出容器但不关闭, docker ps 查看有
数据管理
当容器关闭后,里面产生的数据就没了,重新用镜像 run,又是一个崭新的容器,又回到初始化了,那么我们如何保存数据呢,着时候我们可以使用数据卷挂载到容器内。
数据卷
创建数据卷:
$ docker volume create my-vol
查看数据卷列表:
$ docker volume ls
你还可以查看这个数据卷的详细信息:
$ docker volume inspect my-vol
将数据卷挂载到容器内:
$ sudo docker run -d -v my-vol:/var/my-vol -P 5709795eeffa
挂载宿主机目录
同时也可以将宿主机目录直接挂载到容器中:
$ sudo docker run -d -v /Users/zhangchenghui/Documents/webapps/:/usr/local/tomcat/webapps -p 8080:8080 11df4b40749f
-v 意思是挂载目录,将宿主机目录 /Users/zhangchenghui/Documents/webapps/ 挂载到容器内目录 /usr/local/tomcat/webapps。
数据卷容器
创建一个数据卷容器:
$ sudo docker run -it -v /data --name myvolumes
然后可以在其他容器中使用 —volumes-from 来挂 myvolumes 容器中的数据卷:
$ sudo docker run -i -t --volumes-from myvolumes --name db1 $ sudo docker run -i -t --volumes-from myvolumes --name db2
这时候,容器 db1 和 db2 挂载一个数据卷到相同的 /data 目录,且三个容器任何一方在该目录下的修改,其他容器都能看到。
实践
现在用 ngnix + docker 来部署 一个 WEB 服务:
配置nginx
upstream tomcat_server { server localhost:8080 weight=10; } server { listen 80; server_name www.pcluo.com; include /etc/nginx/default.d/*.conf; location /seckill { proxy_pass http://tomcat_server; #root html; index index.jsp index.html index.htm; } }
nginx 监听 80 端口,当接收到 /seckill 请求时,被负载均衡转发到本机 8080 端口,也就是该项目监听的端口。
Docker部署
拉取 tomcat 镜像:
$ docker pull tomcat
创建 tomcat 容器,将宿主机项目的目录挂载到 tomcat 目录下,并将容器 8080 端口绑定到宿主机 8080 端口上:
$ sudo docker run -d -v /Users/zhangchenghui/Documents/webapps/:/usr/local/tomcat/webapps -p 8080:8080 11df4b40749f
查看运行中的容器:
$ docker ps
成功访问: