Docker 入门学习
29 Mar 2017Docker 的基本概念:
- 镜像(Image)
- 容器(Container)
- 仓库(Repository)
用户权限
sudo groupadd docker # 增加 docker 用户组
sudo gpasswd -a ${USER} docker # 当前用户加入 docker
sudo service docker restart # 重启 docker
镜像
Docker Hub 仓库下载一个 Ubuntu 14.04 操作系统的镜像
docker pull ubuntu:14.04
docker pull dl.dockerpool.com:5000/ubuntu:12.04 #指定服务器地址
列出镜像
docker images
通过镜像启动容器
docker run -t -i training/sinatra /bin/bash
修改容器,提交更新后的副本
docker commit -m 'Added json gem' -a 'Docker Newbee' 44ced85d1270 andrew/sinatra:v2
-m 用来指定提交的说明信息 -a 指定更新的用户信息 44ced85d1270 是容器的 ID andrew/sinatra:v2 是仓库名以及 tag 信息
移除镜像
docker rmi training/sinatra
清理所有未打标签的镜像
docker rmi $(docker images -q -f "dangling=true")
# docker rmi $(docker images --quiet --filter "dangling=true" # 完整命令
不能连接 https://index.docker.io
docker-machine restart default # Restart the environment
eval $(docker-machine env default) # Refresh your environment settings
利用 Dockerfile 来创建镜像
容器
docker run -t -i ubuntu:14.04 /bin/bash
-t
选项让 Docker 分配一个伪终端(pseudo-tty)并绑定到容器的标准输入 上
-i
则让容器的标准输入保持打开
当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:
- 检查本地是否存在指定的镜像,不存在就从公有仓库下载
- 利用镜像创建并启动一个容器 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池配置一个 ip 地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
$ docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo
会在后台运行并不会把输出的结果(STDOUT)打印到宿主机上面(输出结果 可以用 docker logs
查看)
进入容器
1 bashrc_docker
wget -P ~ https://github.com/yeasy/docker_practice/raw/master/_local/.bashrc_docker;
echo "[ -f ~/.bashrc_docker ] && . ~/.bashrc_docker" >> ~/.bashrc; source ~/.bashrc
docker-enter <容器id>
2 nsenter
$ docker inspect -f {{.State.Pid}} b62a42c75ce2 25234
nsenter –target 25234 –mount –uts –ipc –net –pid
3 exec, 这个简单好用
$ docker exec -it 316f9f5ee7c9 /bin/bash
root@316f9f5ee7c9:/srv/rorapps/rmovie# bash --login
导出容器
docker export
导出容器快照到本地文件
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7691a814370e ubuntu:14.04 "/bin/bash" 36 hours ago Exited (0) 21 hours ago test
$ docker export 7691a814370e > ubuntu.tar
导入容器
使用 docker import
从容器快照文件中再导入为镜像
$ cat ubuntu.tar | docker import - test/ubuntu:v1.0
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
test/ubuntu v1.0 9d37a6082e97 About a minute ago 171.3 MB
清除容器
清理所有处于终止状态的容器
docker rm $(docker ps -a -q)
删除容器
docker rm
来删除一个处于终止状态的容器
网络配置
网络端口映射
docker run -d -p 127.0.0.1::5000 training/webapp python app.py
绑定端口 5000 容器动态端口,并且让 localhost 访问
仓库
仓库(Repository)是集中存放镜像的地方
登录
可以通过执行 docker login
命令来输入用户名、密码和邮箱来完成注册和登录。 注册成功后,本地用户目录的 .dockercfg
中将保存用户的认证信息。
基本操作
docker search centos # 搜索镜像
docker pull centos # 下载官方镜像到本地
docker push andrewzhyl/rmovie_base:v1 # 上传镜像到公共仓库 Docker Hub
docker tag IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG] # 标记镜像,复制一份
数据管理
容器中管理数据主要有两种方式:
- 数据卷(Data volumes)
- 数据卷容器(Data volume containers)
数据卷
删除数据卷
- 数据卷是被设计用来持久化数据的,它的生命周期独立于容器
- 删除容器的时候使用
docker rm -v
才会删除数据卷,不然不会删除 - Docker 挂载数据卷的默认权限是读写,用户也可以通过 :ro 指定为只读
$ docker run -d -P --name web -v /src/webapp:/opt/webapp:ro
training/webapp python app.py
挂载一个主机目录作为数据卷
docker run -itd -P --name web -v /home/zhangyulong/rmovie_dev/gems:/srv/rorapps/gems rmovie_dev:v1 /bin/bash
挂在主机的 gems 作为 rmovie_dev 的数据卷
查看数据卷的具体信息
在主机里使用以下命令可以查看指定容器的信息:
docker inspect web
"Mounts": [
{
"Source": "/home/zhangyulong/rmovie_dev/gems",
"Destination": "/srv/rorapps/gems",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
挂载一个本地主机文件作为数据卷
-v 标记也可以从主机挂载单个文件到容器中
$docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
这样就可以记录在容器输入过的命令了。
数据卷容器
持续更新的数据需要在容器之间共享,最好创建数据卷容器
创建 dbdata 数据卷容器
docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres
使用 –volumes-from 来挂载 dbdata 容器中的数据卷
docker run -d --volumes-from dbdata --name db1 training/postgres
然后用 docker inspect db1
查看容器信息
"Mounts": [
{
"Name": "04d67060f52ffb5d7604d90f0e453f347dc7b002414a5c3283adf33be9a99d5c",
"Source": "/var/lib/docker/volumes/04d67060f52ffb5d7604d90f0e453f347dc7b002414a5c3283adf33be9a99d5c/_data",
"Destination": "/dbdata",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
使用 –volumes-from 参数所挂载数据卷的容器自己并不需要保持在运行状态
使用网络
Docker 允许通过外部访问容器或容器互联的方式来提供网络服务。
外部访问容器
使用 -P 标记时,Docker 会随机映射一个 49000~49900
的端口到内部容器开放的网络端口。
本地主机的 49155
被映射到了容器的 5000
端口。此时访问本机的 49155
端口即可访问容器内 5000
端口
$ docker run -d -P training/webapp python app.py
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse
查看日志:
docker logs -f condescending_goldwasser
映射所有接口地址
使用 hostPort:containerPort
格式本地的 5433 端口映射到容器的 5432 端口,可以执行:
docker run -it -p 5433:5432 --name rmovie_db_dev rmovie_db_dev:9.4
映射到指定地址的指定端口
可以使用 ip:hostPort:containerPort
格式指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1:
docker run -it -p 127.0.0.1:5433:5432 --name rmovie_db_dev rmovie_db_dev:9.4
映射到指定地址的任意端口
使用 ip::containerPort 绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口。
docker run -it -p 127.0.0.1::5432 --name rmovie_db_dev rmovie_db_dev:9.4
还可以使用 udp 标记来指定 udp 端口:
$ docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
查看端口映射
docker port 来查看当前映射的端口配置:
docker port condescending_goldwasser 5432
0.0.0.0:5433
- 容器有自己的内部网络和 ip 地址(使用
docker inspect
可以获取所有的变量,Docker 还可以有一个可变的网络配置。) -p
标记可以多次使用来绑定多个端口
容器互联
- 容器的连接(linking)系统是除了端口映射外,另一种跟容器中应用交互的方式。
- 该系统会在源和接收容器之间创建一个隧道,接收容器可以看到源容器指定的信息。
自定义容器命名
--name
标记可以为容器自定义命名:
docker run -itd -p 5433:5432 --name rmovie_db_dev rmovie_db_dev:9.4
docker inspect 来查看容器的名字:
docker inspect -f “{{ .Name }}” aed84ee21bde
创建一个数据容器,通过 -v 制定主机目录挂载到:
docker run -v /home/zhangyulong/pgdata:/data --name dbdata postgres:9.4 echo "Data-only container for postgres"
- 容器的名称是唯一的
- 在执行 docker run 的时候如果添加 –rm 标记,则容器在终止后会立刻删除
- 注意,–rm 和 -d 参数不能同时使用。
容器互联
常用命令
docker rmi $(docker images -q -f "dangling=true")
docker rm $(docker ps -a -q)