Docker出现已经有很长的时间了,期间版本也进行了很多的变化,不同的版本一些命令的差异,功能差异在开始之前我们需要额外注意Docker的版本号.
由于CentOS 6.X系统版本问题只能运行Docker 1.7,CentOS7以及以上的版本支持更高Docker版本.
读者可以采取升级系统版本的方式安装更高版本的Docker,但是这样做的话具有较高的风险,确保机器已经备份.
所以Docker系列文章采取Docker的版本为1.7.虽然比较老缺失了一些新的特性,但是总体而言基本满足了一些业务场景的需要.
Docker 安装
升级内核
使用uname -sr
查看自己的内核版本,如果低于Docker指定版本3.10,那么需要升级.
请阅览Linux 内核升级步骤文章.
源安装
确保我们安装了epel源与elrepo源
(ELRepo)[https://elrepo.org/tiki/tiki-index.php]
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm
(EPEL)[https://fedoraproject.org/wiki/EPEL]
yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
安装docker
sudo yum -y install docker-io
运行测试
sudo docker run hello-world
....
Hello from Docker!
This message shows that your installation appears to be working correctly.
..
当看到上述输出说明我们可以正常运行.
我们可以通过如下命令检查相关的container与images.
执行docker命令时,docker 后面可以跟随一个containerID或者是Container的名称
docker ps -all #默认只是展示运行的container,展示全部需要加入-all参数
docker images #展示已经下载的镜像
docker restart #重启一个镜像名称
Docker容器操作
定义Dockerfile
Dockerfile 定义了容器中的配置,例如,端口映射关系,磁盘驱动等等.
先从一个官方的示例开始:
首先需要准备三个文件:
1.app.py 实际提供服务python代码文件
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
@app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
2.Dockerfile 定义一个安装的配置文件
# 选取官方Python镜像作为父镜像
FROM python:2.7-slim
# 设置工作目录
WORKDIR /app
# 复制当前目录的内容到/app目录
ADD . /app
#执行安装requirements中的Python所需的依赖文件
RUN pip install --trusted-host pypi.python.org -r requirements.txt
#暴露80端口
EXPOSE 80
#定义环境变量
ENV NAME World
# 当容器启动时运行如下命令
CMD ["python", "app.py"]
3.requirements.txt 指定app.py所需的依赖包
Flask
Redis
构建APP
构建镜像,-t打tag, -f指定Dockerfile,最后指定构建的路径
sudo docker build -t pt -f ./Dockerfile .
sudo docker images #显示所有的构建镜像
运行APP
-p暴露端口宿主机4000的端口对应容器80的端口
sudo docker run -p 4000:80 pt
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
10.0.128.3 - - [27/Jun/2018 09:05:04] "GET / HTTP/1.1" 200 -
10.0.128.3 - - [27/Jun/2018 09:05:05] "GET /favicon.ico HTTP/1.1" 404 -
为镜像打标记
推荐为镜像tag的格式:
sudo docker tag image username/repository:tag
所以我们需要为镜像打入tag
sudo docker tag pt coderliu/test:test
推送镜像
我们可以推送镜像到Registry,Registry就是一组仓库的集合,一个仓库(repository)就是一组镜像(image)的集合.
Docker官方提供了DockerHub用于存储我们的仓库,与GitHub类似,但是DockerHub不存储代码.
在推送镜像之前我们需要确保登录了DockerHub的账户.使用如下命令进行登录.
sudo docker login
推送镜像至DockerHub.
sudo docker push coderliu/test:test
执行run命令,docker会自动拉取镜像.
docker run -p 4000:80 coderliu/test:test
容器数据管理
Data Volume
- Volume在容器初始化的时候被创建
- Volume可以被多个容器重用和共享
- Volume独立存在,当容器被删除以后Volume还是会被保存
定位容器当中的Volume
sudo docker inspect
"Volumes": {
"/webapp": "/var/lib/docker/volumes/fac362...80535"
},
"VolumesRW": {
"/webapp": true
}
挂载宿主机的目录到容器
将当前的目录的test目录挂载到容器中/test目录.如果挂载目录中的内容发生变化我们可以在相应的挂载容器内检测变化.
sudo docker run -v ./test:/test ubuntu
除此之外我们可以单独建一个Volume容器,然后其他容器可以引用依赖的Volume.
sudo docker create -v /test --name u1 ubuntu
sudo docker run --vloume-from u1 --name u2 ubuntu #u2实际引用是u1的volume
sudo docker run --vloume-from u2 --name u3 ubuntu # u3实际引用是u1的volume
通过上述内容我们可以实现容器内容的迁移或者备份.
Docker网络管理
创建一个容器并映射端口到宿主机
当运行容器的时候-P可以指定端口的映射规则,-P HOST_PORT:CONTAINER_PORT.默认映射到随机的短暂端口范围.
sudo docker run -d -P pt python app.py
容器之间的连接
容器之间通信依赖容器的名称, 所有要在创建容器间通信时要使用--name
指定容器的名称.
首先创建一个名为pt
的容器
sudo docker run -d --name pt pt python app.py
然后使用–link连接第一个名为pt的容器, --link <name or id>:alias
alias是连接的名称
sudo docker run -t -i --rm --link pt --name web training/webapp /bin/bash
这样web容器就可以和pt容器在不暴露任何端口的情况下进行通信.
这时env会发生改变,会多出如下的配置:
PT_NAME=/web/pt
PT_PORT_80_TCP=tcp://172.17.0.13:80
PT_PORT_80_TCP_PORT=80
PT_PORT_80_TCP_ADDR=172.17.0.13
PT_PORT=tcp://172.17.0.13:80
这些配置主要是用于容器当中的应用去获取这些配置信息,但需要注意当源容器(pt)重启后这些变量不会自动更新.
/etc/hosts文件也会发生改变,主要是路由的相关设置.
$ cat /etc/hosts
...
172.17.0.28 pt 99df4bcd9072
我们会看到容器的名称以及容器ID映射到了真实的IP,这里如果设置了alisa也会映射到对应的IP.
与环境变量不同的是当源容器重启后host会自动进行更新.
2
2
1
2
2
2