docker入门与实践
参考Docker — 从入门到实践,记录学习docker过程中常用命令和Dokcerfile编写。
一.安装docker
目前手头只有两种测试环境。
mac安装 docker
brew cask install docker
(树莓派)debain安装docker
//脚本安装最新版本 wget -qO- https://get.docker.com/ | sh
二.基本概念
镜像
Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
容器
容器是镜像运行时的实体。
仓库
一个集中的存储、分发镜像的服务,Docker Registry 支持共有和私有。
三.操作容器和镜像
docker版本
docker version
列出镜像
docker images
拉取镜像
docker pull ubuntu //拉取ubuntu 最新版本
删除镜像
docker rmi ubuntu
运行容器
docker run -i -t ubuntu /bin/bash 参数说明: -i 保证容器中的STDIN是开启的 -t 分配一个伪tty终端
容器命名
docker run --name ubuntu170210 -i -t ubuntu /bin/bash
重新启动已经停止的容器
docker start ubuntu
附着在容器上
docker attach ubuntu
创建守护式容器
docker run --name ubuntu170210 -d ubuntu /bin/sh -c "while true;do echo hello world;sleep 1;done"
停止守护式进程
docker stop ubuntu
自动重启容器
docker run --restart=always --name ubuntu170210 -d ubuntu /bin/sh -c "while true;do echo hello world;sleep 1;done" 参数说明 --restart=always 无论容器退出代码是什么,docker都会重启该容器 --restart=on-failure:5 如果退出代码非0是,才自动重启。5为自动重启次数,最多重启5次
容器日志
docker logs ubuntu
查看容器进程
docker top ubuntu
在容器内部运行进程
docker exec -d ubuntu touch /opt/test 参数说明: -d 表明要在后台运行一个后台进程
查看容器更多信息
docker inspect ubuntu docker inspect ubuntu --format='{{.Name}} {{.State.Running}}' 参数说明: --format 支持go语言模版,可以通过模版获取参数值
查看容器信息(ps)
docker ps命令可以查看容器的CONTAINER ID、NAME、IMAGE NAME、端口开启及绑定、容器启动后执行的COMMNAD。经常通过ps来找到CONTAINER_ID。 docker ps 默认显示当前正在运行中的container docker ps -a 查看包括已经停止的所有容器 docker ps -l 显示最新启动的一个容器(包括已停止的)
删除容器
docker rm ubuntu
删除所有停止的容器
docker rm $(docker ps -a -q)
查看镜像构建过程
docker history ubuntu
容器的导入和导出
docker export 容器id > ubuntu.tar cat ubuntu.tar | docker import - test/ubuntu:v1.0 docker import http://gophper.com/ubuntu.tar test/ubuntu //指定url来导入
四.编写Dockerfile
注意:简化RUN执行的次数。每一个指令都会建立一层镜像并把运行时不需要的东西装入镜像,如编译环境,更新数据包等。编写dockerfile 不是在写 shell,通过 && 进行指令合并,减少构建层数 + 镜像构建
docker build [选项] <上下文路径/URL/->
- FROM指定基础镜像
RUN执行命令
分为两种
shell格式: RUN <命令> exec格式: RUN ["可执行文件","参数1","参数2"]
CMD命令
指定容器启动时要运行的命令。
ENTRYPOINT命令
与CMD命令类似。docker run命令会覆盖cmd指令,而 ENTRYPOINT 指令 不容易被覆盖。
COPY命令
格式
COPY <源路径>...<目标路径> COPY ["<源路径>",..."<目标路径>"]
EXPOSE
生命运行时容器提供服务的端口。
WORKDIR
指定工作目录,可以通过-w参数在运行时覆盖工作目录
docker run -ti -w /var/log ubuntu pwd
ENV
镜像构建过程中设定环境变量
ENV GOPATH /opt/environment
同时可以用-e标志传递环境变量
docker run -ti -e "GOPATH=/opt/environment2" ubuntu env
USER
指定镜像以什么用户去执行。docker run命令可以通过-u覆盖指令设定值。默认用户为root
USER nginx //设定容器以nginx用户执行 //其他表现形式 USER user:group USER uid USER uid:gid USER user:gid USER uid:group USER user
VOLUME
基于镜像给创建的容器添加卷,一个卷可以存在于一个或者多个容器内的特定目录。
通过-v参数指定卷的源目录和容器里的目的目录。两个目录通过:分割。如果目的目录不存在,docker自动创建一个。 在目的目录后添加rw或ro指定目的目录的读写状态
docker run -d -p 80 --name website -v $PWD/website:/var/www/html/website:ro jamtur01/nginx nginx
ADD
将构建环境下的文件和目录复制到镜像中。ADD 命令使得构建缓存无效。添加文件还活着目录后,后续指令不能使用构建缓存。
ADD /etc/sshd.conf /etc/sshd.conf ADD http://gophper.com/golang.tar.gz /opt/environment/golang.tar.gz //支持url ADD golang.tar.gz /opt/environment/ 如果为合法归档文件的源文件,会自动解压。如果已经存在的文件和目录不会被覆盖。
ONBUILD
为镜像添加触发器。当镜像被用作其他镜像的基础镜像时,镜像中的触发器将会被执行。
ONBUILD ADD . /app/src ONBUILD RUN cd /app/src && make
五.数据卷
数据卷(在mac下提示手动添加共享目录)
docker run -it -P --name web -v /opt/tmp:/opt/tmp:rw ubuntu
六.使用网络
端口映射
映射所有接口地址
使用 hostPort:containerPort 格式本地的 5000 端口映射到容器的 5000 端口,可以执行
$ sudo docker run -d -p 5000:5000 training/webapp python app.py
此时默认会绑定本地所有接口上的所有地址。
映射到指定地址的指定端口
可以使用 ip:hostPort:containerPort 格式指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1
$ sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
映射到指定地址的任意端口
使用 ip::containerPort 绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口。
$ sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py
还可以使用 udp 标记来指定 udp 端口
$ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
查看映射端口配置
使用 docker port 来查看当前映射的端口配置,也可以查看到绑定的地址
$ docker port nostalgic_morse 5000 127.0.0.1:49155.
注意:
容器有自己的内部网络和 ip 地址(使用 docker inspect 可以获取所有的变量,Docker 还可以有一个可变的网络配置。) -p 标记可以多次使用来绑定多个端口 例如
$ sudo docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py
容器互联
–link 参数让容器之间安全的进行交互。
Docker 在两个互联的容器之间创建了一个安全隧道,而且不用映射它们的端口到宿主主机上。在启动 db 容器的时候并没有使用 -p 和 -P 标记,从而避免了暴露数据库端口到外部网络上。
1.首先创建一个数据库容器
docker run -d --name db
2.然后创建一个新的web容器,并将它连接到db容器
docker run -d -P --name web --link db:db training/webapp python app.py
Docker 通过 2 种方式为容器公开连接信息:
- 环境变量
- 更新 /etc/hosts 文件
2017-07-20 追加
上传镜像到私有库
docker tag 7328f6f8b418 127.0.0.1:5000/alpine docker push 127.0.0.1:5000/alpine docker pull 127.0.0.1:5000/alpine
2017-07-25 追加
In docker for mac
If you can remove all images/containers then:
Stop Docker.
docker rm $(docker ps -a -q)
docker rmi $(docker images -q)
docker volume rm $(docker volume ls |awk '{print $2}')
rm -rf ~/Library/Containers/com.docker.docker/Data/*
Start Docker, you have yours GB back.