使用docker commit命令在用已有的container生成新的image。
查看存在的container:
通过docker history可以查看commit的内容:
使用这种方式生成新的image适用于非生产环境,因为这样可能会把一些隐秘的信息暴露,不安全。建立存放Dockerfile文件的空目录:在执行build的时候可以把目录下 的文件打包到image中
进入该目录编写一个Dockerfile:
执行build命令:
[vagrant@bogon docker-centos]$ docker build -t zhouzy/centos-vim-new .FROM
用来构造image, 如果构造的image在本地已存在,会在已存在的image上构造,如果不存在就会从官方拉取。
尽量使用官方的image作为base image。
LABEL
定义了image的Metadata,相当于对image的注释。
RUN
在窗口执行的命令。
在Dockerfile中每一行RUN语句都是一层构建(下一层是在上一层的基础上构建的),为了避免无用分层,合并多条命令成一行。
为了美观,复杂的RUN用反斜线换行。
WORKDIR
当前工作目录,相当于cd到目录中。
但是WORKDIR可以创建不存在的目录并进入,如果连续使用多个WORKDIR会在上个工作目录下继续(创建)cd进下个目录:
# 如: WORKDIR /root WORKDIR test RUN pwd # 输出结果为/root/test在使用WORKDIR时尽量使用绝对目录。
当需要进入工作目录的时候用WORKDIR,不要用RUN cd.
ADD and COPY
添加build时指定的目录下的文件到构建的image的指定目录下。
如:
ADD hello / # 将可执行文件hello添加到image的根目录下 ADD test.tar.gz / # 添加到根目录并解压 WORKDIR /root ADD hello test/ # 添加到/root/test/下 WORKDIR /root COPY hello test/ # 添加到/root/test/下ADD除了COPY还有额外功能(解压),如果只是添加不需要解压的话使用COPY。
添加远程文件/目录使用curl或者wget。
ENV
设置常量:
ENV MYSQL_VERSION 5.6 # 设置常量 RUN apt-get install -y mysql-server= "{MYSQL_VERSION}"VOLUME and EXPOSE
存储和网络
CMD
设置容器启动后默认执行的命令和参数。
如果docker run指定了其它命令,CMD命令会被忽略。
如果定义了多个CMD,只有最后一个会执行。
ENTRYPOINT
设置容器启动时运行的命令。
让容器以应用程序或者服务的形式运行。
不会被忽略,一定会执行。
最佳实践:写一个shell脚本作为entrypoint:
COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] EXPOSE 27017 CMD ["mongod"]在一台虚拟机上的5000端口上运行registry:
[root@vagrant1 ~]# docker run -d -p 5000:5000 --restart always --name registry registry查看是否运行成功:
[root@vagrant1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9ff4d7efa4ce registry "/entrypoint.sh /etc…" About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp registry在另一台虚拟机上push镜像:
首先要确保可以ping通registry机的5000端口:
[vagrant@vagrant2 hello-world]$ telnet 192.168.1.21 5000 Trying 192.168.1.21... Connected to 192.168.1.21. Escape character is '^]'.然后创建一个image:image名字格式如下,斜线前边要为仓库的ip加端口:
创建/etc/docker/daemon.json文件,添加如下内容,意思就是将私有仓库的主机设置为信任主机:
{ "insecure-registries":["192.168.1.21:5000"] }修改/lib/systemd/system/docker.service 文件,增加环境变量文件,每次启动docker时都会读取这个文件中的配置:
重启docker服务:
sudo systemctl daemon-reload sudo systemctl restart docker执行push命令:
docker push 192.168.1.21:5000/hello-world显示如下表示push成功:
私有仓库是没有web界面的,但是可以通过registry 官方的api查看push内容:
http://192.168.1.21:5000/v2/_catalog此时我们就可以使用pull来从私有仓库下载这个镜像了:
需要注意的是如果没有执行上边的第3和第4两步pull会报如下错误:
注:从docker官方pull一个镜像的时候会非常慢,可以使用阿里云镜像加速,加速教程链接。
将一个简单的flask 程序部署到docker中:
创建app.py文件(源代码)
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return "hello docker" if __name__ == '__main__': app.run(host="0.0.0.0", port=6000)创建Dockerfile文件
创建Dockerfile文件主要包括三大步:
准备源代码运行环境复制源代码至镜像中进入工作空间执行启动命令 # 准备源代码运行环境 FROM python:2.7 LABEL "maintainer=zzy<1417098555@qq.com>" RUN pip install flask # 复制源代码至镜像/app/目录下 COPY app.py /app/ # 进入工作空间并执行启动命令 WORKDIR /app EXPOSE 6000 # flask启动时使用的6000端口所以要暴露6000端口 CMD ["python", "app.py"]执行build命令
docker build -t port=6000/flask-demo .运行容器
注意6000端口是Dockerfile中暴露出给主机的端口,这里是将镜像中的6000端口映射到主机的8888端口上。
docker run -p 8888:6000 --name flask-demo port=6000/flask-demo可以通过docker port flask-demo查看端口映射:
在主机的浏览器上输入ip地址查看:
前台运行显示的6000端口是docker容器的6000端口,而不是主机的6000端口,在浏览器中要输入映射后的端口,也就是第4步查看到的端口映射:
build一个常驻命令行的工具
Dockerfile 使用ENTRYPOINT加CMD的形式来build一个可以输入参数的命令行工具:
FROM ubuntu RUN apt-get update && apt-get install -y stress ENTRYPOINT ["/usr/bin/stress"] CMD []不带参数时:
带参数时:
容器查看
# 查看运行中的容器 docker ps # 查看所有容器,包括停止的容器 docker container ls -a docker ps -a启停容器
docker stop container_ID docker start container_ID # 启动所有容器 docker start $(docker ps -a | awk '{ print $1}' | tail -n +2) docker start $(docker ps -aq) # 停止所有容器 docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2) docker stop $(docker ps -aq)删除容器
docker rm container_ID # 删除所有容器 docker rm $(docker ps -a | awk '{ print $1}' | tail -n +2) docker rm $(docker ps -aq) # 删除所有镜像 docker rmi $(docker images | awk '{print $3}' |tail -n +2) docker rmi $(docker image ls -aq)进入容器
docker attach conrainer_ID
进入后使用exit 退出,退出后容器也停止运行
exec 命令
终端交互式进入容器:docker exec -it 243c32535da7 /bin/bash
这样进入容器在退出后,容器不会终止。
导入和导出容器
导出容器:
docker export d7ace3adf194 > flask-demo.tar[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aDfc4IuK-1601876336076)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1601802841164.png)]
导入容器快照
cat flask-demo.tar | docker import - test/flask-demo:v1查看日志
docker logs -f bf08b7f2cd89查看容器的进程
docker top flask-demo查看容器详情
docker inspect flask-demo执行docker run 命令的时候可以指定参数:
指定CPU占用权重:
-c, --cpu-shares int CPU shares (relative weight)限定占用内存大小:
-m, --memory bytes Memory limit限定内存
[vagrant@vagrant1 ubuntu-stress]$ docker run --memory=200M zzy/ubuntu-stress --vm 1 --verbose使用--memory参数来限定运行内存大小,如果限定交换内存的话,交换内存默认和运行内存一样大小。
zzy/ubuntu-stress为压力测试的一个镜像,--vm 1表示分配一个worker测试,--verbose表示打印出测试过程。
可以看到实际最大内存是400M。
压力测试使用参数--vm-bytes 500M指定运行内存为500M超过我们限定的400M就会报错:
限定CPU使用权重
分配CPU权重为10的压力测试程序:
[vagrant@vagrant1 ubuntu-stress]$ docker run --cpu-shares=10 --name=cpu_shares_10 zzy/ubuntu-stress --cpu 1分配CPU权重为5的压力测试程序:
[vagrant@vagrant1 root]$ docker run --cpu-shares=5 --name=cpu_shares_5 zzy/ubuntu-stress --cpu 1查看CPU占用情况:权重为10的基本上是权重为5的程序占用CPU的2倍: