Docker镜像和容器

    科技2022-08-11  128

    文章目录

    创建自己的Docker镜像commit已存在的container使用Dockerfile新建imageDockerfile语法梳理及最佳实践搭建私有的Docker仓库Dockerfile实战Docker容器操作容器资源的资源限制

    创建自己的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倍:

    Processed: 0.032, SQL: 8