文章目录
创建自己的Docker镜像
commit已存在的container
使用docker commit
命令在用已有的container生成新的image。
查看存在的container:
通过docker history
可以查看commit的内容:
- 使用这种方式生成新的image适用于非生产环境,因为这样可能会把一些隐秘的信息暴露,不安全。
使用Dockerfile新建image
-
建立存放Dockerfile文件的空目录:在执行build的时候可以把目录下 的文件打包到image中
-
进入该目录编写一个Dockerfile:
-
执行build命令:
[vagrant@bogon docker-centos]$ docker build -t zhouzy/centos-vim-new .
Dockerfile语法梳理及最佳实践
-
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"]
搭建私有的Docker仓库
-
在一台虚拟机上的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会报如下错误:
Dockerfile实战
注:从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容器操作
容器查看
# 查看运行中的容器
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倍: