docker深入
docker深入
来源:尚硅谷教程
docker在线操作:https://labs.play-with-docker.com/
docker解决了运行环境和配置问题软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。
镜像(Image):Docker镜像(Image)就是一个只读的模板。镜像可以用来创建Docker容器,一个镜像可以创建很多容器。
容器(container):docker利用容器(Container)独立运行的一个或一组应用。容器是用镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
仓库(Repository):是集中存放镜像文件的场所。仓库(Repository)和仓库注册服务器(Registry)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为公开仓库和私有仓库两种,最大的公开仓库是Docker Hub,存放了数里庞大的镜像供用户下载。国内的公开仓库包括阿里云、网易云等。
具体参见中文官网。
安装需要注意的是centos6和centos7安装方式有些差异,需要注意。
# centos7安装完docker后 # 查看版本 docker version # 启动docker进程 sudo systemctl start docker # 停止docker sudo systemctl stop docker
2、在镜像中心-镜像加速器中获取自己ide镜像地址,按照上面的操作指示在自己系统设置即可。
(1)docker有着比虚拟机更少的抽象层。由亍docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
(2)docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个docker容器只需要几秒钟。
docker version
docker info
docker help
# 列出本地的镜像 docker images [options] # 列出本地镜像,含中间镜像层 docker images -a # 只显示镜像ID docker images -q # 显示镜像ID,包含中间镜像层的ID docker images -qa # 显示摘要信息 docker images --digests # 显示完整的镜像信息,不要截断输出 docker images --no-trunc
# 从docekr hub上搜索镜像 docker search [options] imagename # 例如 docker search tomcat # 搜索点赞数超过三十的该镜像 docker search -s 30 tomcat # 显示完整镜像信息 docker search -s 30 --no-trunc tomcat # 只列出automated build类型的镜像 docker search --automated tomcat
# 没写版本号,自动拉取最新版 docker pull imagename # 等价于docker pull imagename:latest
# 删除镜像,如果没写版本,默认删除lastest。 docker rmi imagename 不能删除一个已经创建容器的镜像。 docker run hello-world docker rmi hello-world # 报错信息可看到hello-world镜像分为了两层,要删除hello-world镜像时,报错提示无法删除,因为它被其他层引用着。 Error response from daemon: conflict: unable to remove repository reference "hello-world" (must force) - container ee20158ca82c is using its referenced image fce289e99eb9 # 强制删除该镜像,删单个 docker rmi -f imagename # 删除多个 docker rmi -f imagename1 imagename2 ... # 删除全部,使用类似java EL表达式,使用$(执行的子命令) docker rmi -f $(docker images -q)
docker history imageid
# docker可以run镜像名或镜像id docker run [options] image [command][arg...] options说明(常用): --name="容器的新名字":为容器指定一个名字 -d:以后台进程的方式运行容器,并返回容器id,也即启动守护式容器; -i:以交互模式运行容器,通常与-t同时使用 -t:为容器重新分配一个伪输入终端,通常与-i同时使用 -P:随机端口映射 -p:指定端口映射,有以下四种格式 ip:hostPort:condatinerPort ip::containerPort hostPortLcontainerPort containerPort # 当使用-it时会一直保持着容器的启动可以防止容器运行完即停止
# -i 和-t可合一起启动 docker run -it centos # 使用exit退出伪终端并关闭容器 # Ctrl+P+Q 退出伪终端进入宿主机,但不关闭容器。
docker ps [options] options 参数说明(常用): -a:列出当前所有正在运行的容器+历史上运行过的容器 -l:显示最近创建的容器 -n:显示最近n个创建的容器 docker ps -n 4 -q:静默模式,只显示容器编号 --no-trunc: 不截断输出
docker start containername/containerid
docker restart containername/containerid
# 慢慢的停止 docker stop containername/containerid # 强制关闭,迅猛粗暴 docker kill -f containername/containerid
docker rm containername/containerid # 删除所有 docker rm $(docker ps -qa) # 将|之前命令查出来的结果传递到xargs命令的后面 docker pa -a -q|xargs docker rm
# 守护进程启动容器 docker run -d imagename
如下图,使用守护进程的模式去运行centos,执行docker run后确确实实返回给了我们一个容器ID,说明我们启动成功了,但是使用docker ps却查看不到这个容器的信息。这是为何?
既然查不到这个容器在运行,那就说明这个容器已经退出了,它确实短暂的存在过,但是一瞬间就退出了。
# 查看容器日志 docker logs -f -t --tail 容器ID -t 时加入时间戳 -f 跟随最新的日志打印 --tail 数字显示最后多少条
# 查看容器内运行的进程 docker top 容器ID
# 查看容器内部细节,返回的时json对象 docker inspect 容器ID
# 进入正在运行的容器并以命令行交互,上面我们使用exit或Ctrl P Q退出容器内的交互环境 # 如果是使用Ctrl P Q退出,我们并没有关闭容器,那我们怎么再次进入?两种方式 1、docker exec -it 容器ID bashShell #例如: exec可以直接在容器外操作容器里面的内容 docker exec -it c9ef60079a8a ls -a #例如: exec还可以使用这种方式达到和aeeach一样的效果,就是进入容器内操作里面的内容 docker exec -it c9ef60079a8a /bin/bash 2、 docker attach 容器ID 两者区别: attach:直接进入容器启动命令的终端,不会启动新的进程。 exec:是在容器内打开新的终端,并且可以启动新的进程。
# 从容器内拷贝文件到主机上 docker cp 容器ID:容器内路径 目的主机路径
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统被称为UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
平时我们安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M??
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。
以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载
比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
这一层通常被称作“容器层”,“容器层”之下的都叫”镜像层”。
docker commit提交容器副本使之成为一个新的镜像。
啥是容器副本?比方说你从镜像库里拉取了一个标准版的tomcat镜像,然后你对该镜像启动的tomcat容器做了一些修改或者配置,此时此刻,你修改的这个tomcat容器并不是原来标准的tomcat镜像启动的容器了,而是标准tomcat容器的一个副本容器。
# 如果没写标签名,默认为latest docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
思维导图中的按照的tomcat是tomcat7,因为如果你默认安装tomcat8或其以上是没有webapps目录的,也就是即使你启动了8080端口的tomcat也看不到任何页面:
docker pull tomcat:7-jre7
将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。为了能保存数据在docker中我们使用卷。
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名 # 案例:如果目录不存在,docker会自己建立。将容器上的数据和宿主机上的数据绑定在一起。 docker run -it -v /hostVolumeData:/containerVolumeData centos
docker inspect 561f321d20cc
我在宿主机上的和容器绑定的文件夹里创建一个新的文件后,发现容器内和宿主机绑定的文件夹下也出现了这个文件。
在容器内的该test.txt文件夹里写点东西,发现宿主机里该文件的内容和容器内文件内容一致。
停止容器后,主机新增一个log日志文件,再次start该容器,发现和主机绑定的文件夹又是同步的。
# 设置容器内对该文件夹里的内容只有读权限 docker run -it -v /hostVolumeData:/containerVolumeData:ro image
VOLUME["/dataVolumeContainer1","/dataVolumeContainer2",...] # 出于可移植和分享的考虑,用-v主机目录:容器目录这种方法不能直接在Dockerfilet中实现。 # 由于宿主机目录是依赖指定宿主机的,并不能保证在所有宿主机上都存在这样的特定目录。 # 比方说在windows和linux上文件夹的结构并不相同,linux没有C盘一说,所有如果你使用 # -v那种绑定的形式,可能在windows上就会出错。所以docker提供了在dockerfile里使用 #VOLUME的方式去创建文件,且使用默认的方式[windows的就在某个目录创建文件关联,linux也一样]关联宿主机文件。
# volume test FROM centos # 表示要构建的这个镜像依赖于centos父镜像 VOLUME ["/dataVolumeC1","/dataVolumeC2"] CMD echo "finished,build volume!" CMD /bin/bash # 在run该镜像后直接进入bash
docker build -f /dockerfile/Dockerfile -t liuwei/centos . # -f 表示指定构建的dockerfile文件位置 # -t 表示镜像名 # .表示在当前目录生成镜像文件
docker inspect 109fe5b3ed45
Docker挂载主机目录Docker访问出现cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个–privileged=true参数即可
命名的容器挂载数据卷,其他容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。
docker run --name="con1" -it liuwei/centos # 此时此刻这个容器是已经挂载了两个数据卷的
docker run --name="con2" -it --volumes-from con1 liuwei/centos docker run --name="con3" -it --volumes-from con1 liuwei/centos
4、分别进入con2、con3发现在卷里都出现了刚才con1创建的文件。con2创建log2.txt,con3创建log3.txt,查看con1也含有这些文件。
docker rm -f con1
6、再次进入con2、con3发现挂载卷还存在,里面的文件都存在。
容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
1、docker从基础镜像运行一个容器。【scratch是一切镜像的祖先,相当于java里的object类】
3、执行类似docker commit的操作提交一个新的镜像层。
5、执行dockerfile中的下一条指令直到所有指令都执行完成。
ENV MY_PATH /usr/test
这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面定义了环境变量前缀一样;也可以在其他指令中直接使用这些环境变量。比如:WORKDIR:$MY_PATH
将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置
COPY src dest COPY ["src","dest"]
指定一个容器启动时要运行的命令。他和RUN命令后面加参数格式类似。
Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换。
指定一个容器启动时要运行的命令,ENTERPOINT的目的和CMD一样,都是在指定容器启动程序及参数。
当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发。
在Dockerfile文件中CMD和ENTRYPOINT都可以给容器设置启动参数,二者采用的方式是追加的方式,但CMD只要最后一个才生效。
比如说:在centos镜像的dockerfile文件里如下:
FROM scratch ADD centos-7-x86_64-docker.tar.xz / LABEL org.label-schema.schema-version="1.0" \ org.label-schema.name="CentOS Base Image" \ org.label-schema.vendor="CentOS" \ org.label-schema.license="GPLv2" \ org.label-schema.build-date="20191001" CMD ["/bin/bash"]
docker run -it centos ls -a
那就相当于我们在dockerfile文件最后追加了 ls -a
FROM scratch ADD centos-7-x86_64-docker.tar.xz / LABEL org.label-schema.schema-version="1.0" \ org.label-schema.name="CentOS Base Image" \ org.label-schema.vendor="CentOS" \ org.label-schema.license="GPLv2" \ org.label-schema.build-date="20191001" CMD ["/bin/bash"] CMD ls -a
又由于CMD指定的命令只有最后一个生效,所有centos容器并没有被启动!!!
ENTRYPOINT ["/bin/bash"]
docker run -it centos ls -a
ENTRYPOINT ["/bin/bash"] ENTRYPOINT ["ls -a"] # 也就如下: ENTRYPOINT ["/bin/bash","ls -a"]
启动最初始的centos镜像,使用vim命令创建打开一个文件,发现精简版的centos不支持该命令,那我们自定义一个支持vim命令的镜像。
FROM centos MAINTAINER liuwei<1111111@qq.com> # 设置镜像维护者 ENV HOME_PATH /home # 设置变量 WORKDIR $HOME_PATH # 设置容器启动后进入的落脚点 CMD echo \'install vim\' RUN yum -y install vim # 安装vim CMD echo \'install vim over!\' EXPOSE 80 CMD /bin/bash
docker build -f /dockerfile/dockerfile2 -t vim/centos .
docker run vim/centos # vim可以使用
docker history imageid
1、tomcat的运行依赖于jdk,所以我们要先把这两个tar.gz包down下来
wget http://download.oracle.com/otn-pub/java/jdk/8u171-b11/512cd62ec5174c3487ac17c61aaa89e8/jdk-8u171-linux-x64.tar.gz
wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.53/bin/apache-tomcat-8.5.53.tar.gz
FROM centos MAINTAINER liuwei<111111@qq.com> ENV HOME_PATH /home/liuwei WORKDIR $HOME_PATH COPY copy.txt /usr/local/copy_container.txt RUN yum -y install vim # 在加之前你要先解压以下看看默认解压后的文件名是啥,因为下一步要用到 # 把java和tomcat添加到容器 ADD OpenJDK8U-jdk_x64_linux_openj9_8u242b08_openj9-0.18.1.tar.gz /usr/local/ ADD apache-tomcat-8.5.53.tar.gz /usr/local/ # 配置环境变量 ENV JAVA_HOME /usr/local/jdk8u242-b08 ENV CLASS_PATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.53 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin # 容器运行时监听的端口 EXPOSE 8080 # 启动时运行tomcat # ENTRYPOINT ["/usr/local/apache-tomcat-8.5.53/bin/startup.sh"] # CMD ["/usr/local/apache-tomcat-8.5.53/bin/catalina.sh","run"] # 启动tomcat并将日志实时输入到log目录下的.out文件里 CMD /usr/local/apache-tomcat-8.5.53/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.53/logs/catalina.out
docker run -d -p 8080:8080 mytomcat:1.1 # 上面启动方式不好的地方: # 1:启动看不到启动日志,如果出错了咋办,而且我就想以后台进程方式启动 # 2:我既然启动tomcat肯定是要部署项目,我部署咋部署? # 解决以上问题: docker run -d -p 8080:8080 \ -v /usr/local/tomcat8/logs/:/usr/local/apache-tomcat-8.5.53/logs/ \ -v /usr/local/webapps/:/usr/local/apache-tomcat-8.5.53/webapps/ \ mytomcat:1.1 # 如上我们使用两个数据卷文件夹绑定在宿主机上,既可以查看tomcat日志,又 # 可以在宿主机上直接部署项目。 # 经过我的尝试发现并不行,我直接不挂数据卷能运行,挂数据卷容器启动后访问不了页面。 # 没办法我只好用以配置的方式去尝试一下 # 在Dockerfile里在环境变量之前加了VOLUME VOLUME ["/usr/local/apache-tomcat-8.5.53/logs/","/usr/local/apache-tomcat-8.5.53/webapps/"] # 重新构建,run,成功访问!
接下来就是把项目放到宿主机和容器绑定的webapps文件夹下了
# 查看挂载生成的随机位置 docker inspect 0a87d24975dc # 进入 cd /var/lib/docker/volumes/1b15be4a96b0a72c7d1d57e49a065c60763dd30da3b6886a7dd107c85b2598f8/_data # 创建项目文件 mkdir test # 创建web.xml,在创建index.jsp
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>test</display-name> </web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> -----------welcome------------ <%="i am in docker tomcat self "%> <br> <br> <% System.out.println("=============docker tomcat self");%> </body> </html>
访问http://localhost:8080/test/index.jsp,ok
我们稍微修改index.jsp在刷新看看是否同步,ok也没问题。
docker pull mysql:5.6 # 安装docker hub mysql官网描述,该启动方式外部访问不到,没暴露对外端口 docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag # 常用配置 docker run --name your_mysql_name \ -v /home/liuwei/mysql_conf/:/etc/mysql/conf.d \ -v /home/liuwei/mysql_log/:/logs \ -v /home/liuwei/mysql_data/:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=your_mysql_root_pwd \ -d -p 3306:3306 mysql:tag # 如上配置你可以在你的mysql_conf文件夹下创建my.cnf配置文件,他将同步到容器内,重启mysql容器 # 后会加载这个配置文件。 # 例如,我在mysql_conf/my.cnf里配置: [mysqld] default-time-zone = \'+8:00\' # docker restart mysql_container_id # show variables like \'%time_zone%\';
# 备份表结构及数据 docker exec myql服务容器ID sh -c \' exec mysqldump --all-databases -uroot -p"123456" \' > /zzyyuse/all-databases.sql
docker pull redis docker run --name docker-redis \ -v /home/liuwei/redis_data:/data \ -v /home/liuwei/redis_conf:/usr/local/etc/redis/redis.conf \ -d -p 6379:6379 redis:tag redis-server /usr/local/etc/redis/redis.conf --appendonly yes
# 在redis_conf新建redis.conf,具体配置参见数据库redis # 测试连接redis docker exec -it ac30dc29bb52 redis-cli 127.0.0.1:6379> ping PONG
在阿里云创建自己的仓库,然后按照阿里云生成的命令提交即可。
docker login --username=yourname docker_hub_host:ip docker logout docker镜像仓库 docker login --username=admin --password=\'123456\' 10.1.15.111:5000 docker logout 10.1.15.111:5000
Alpine Linux非常是和容器的使用,因为它小巧,功能完备,非常适合作为容器的基础镜像。
解决方案详情参见:https://blog.csdn.net/weixin_39198406/article/details/90675645
1、在使用python:3.6-alpine作为基础镜像勾选镜像时,安装mysqlclient出错,说找不到mysql-config文件,
RUN sed -i \'s/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g\' /etc/apk/repositories RUN apk add gcc freetype-dev RUN apk add gfortran musl-dev g++ libgcc libquadmath musl libgfortran RUN apk add lapack-dev RUN apk add --no-cache mariadb-dev build-base
# 查看python里的pip支持的文件名和时间线 >>> import pip._internal.pep425tags >>> print(pip._internal.pep425tags.get_supported()) [<cp36-cp36m-win_amd64 @ 1625898767816>, <cp36-abi3-win_amd64 @ 1625898767944>, <cp36-none-win_amd64 @ 1625898768072>, <cp35-abi3-win_amd64 @ 1625898768200>, <cp34-abi3-win_amd64 @ 1625 898768328>, <cp33-abi3-win_amd64 @ 1625898768520>, <cp32-abi3-win_amd64 @ 1625898768648>, <py36-none-win_amd64 @ 1625898768840>, <py3-none-win_amd64 @ 1625898768968>, <py35-none-win_amd 64 @ 1625898769096>, <py34-none-win_amd64 @ 1625898769224>, <py33-none-win_amd64 @ 1625898769352>, <py32-none-win_amd64 @ 1625898769480>, <py31-none-win_amd64 @ 1625898769608>, <py30-no ne-win_amd64 @ 1625898769736>, <cp36-none-any @ 1625898769864>, <py36-none-any @ 1625898769928>, <py3-none-any @ 1625898769992>, <py35-none-any @ 1625898768392>, <py34-none-any @ 162589 8770056>, <py33-none-any @ 1625898770120>, <py32-none-any @ 1625898770184>, <py31-none-any @ 1625898770248>, <py30-none-any @ 1625898770312>] # python版本-系统版本 @ 毫秒级时间 import time >>> time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(1625898769)) \'2021-07-10 14:32:49\'
ERROR: Could not find a version that satisfies the requirement tensorflow==1.13.1 (from -r requirements.txt (line 11)) (from versions: none) ERROR: No matching distribution found for tensorflow==1.13.1 (from -r requirements.txt (line 11))
原因是alpine安装的python包有要求,不能以manylinux_x86_x64的结尾格式),而你从网上下载的包里如果只有以系统后缀的该包,就会导致下载不被允许。所以这种情况下,推荐使用离线安装的方式,将你下载下来的那些以系统后缀命名的包改成none-any结尾即可。
https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.13.1-cp36-cp36m-linux_x86_64.whl
https://www.cnblogs.com/embedded-linux/p/12078154.html
# 查看docker磁盘占用 docker system df # 清理:删除关闭的容器、无用的数据卷和网络,以及无tag镜像 docker system prune # 清理更加彻底:将没有容器使用的Docker镜像都删掉【慎用】 docker system prune -a
在linux遇到的问题中,我的docker容器曾把磁盘写爆了。当时目录文件就是在/var/lib/docker中。这个目录包含了docker的所有相关文件,包括镜像、容器等。
[root@localhost lib.linux-x86_64-3.6]# docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 26 0 10.48GB 10.48GB (100%) Containers 0 0 0B 0B Local Volumes 12 0 250.9MB 250.9MB (100%) Build Cache 0 0 0B 0B [root@localhost lib.linux-x86_64-3.6]# du -hs /var/lib/docker/ 11G /var/lib/docker/ [root@localhost lib.linux-x86_64-3.6]# cd /var/lib/docker/ & du ... 80 ./network/files 80 ./network 0 ./swarm 16 ./builder 0 ./buildkit/content/ingest 0 ./buildkit/content 0 ./buildkit/executor 56 ./buildkit 0 ./tmp 0 ./runtimes 11230224
# 容器日志清0设置 truncate -s 0 /var/lib/docker/containers/a376aa694b22ee497f6fc9f7d15d943de91c853284f8f10 # 容器日志清0只是暂时办法,不管它的话它还会涨上去的,解决办法 # vim /etc/docker/daemon.json { "log-driver":"json-file", "log-opts": {"max-size":"500m", "max-file":"3"} } # max-size:一个容器日志大小上限是500M # max-file,意味着一个容器有三个日志,分别是id+.json,id+1.json,id+2.json # 记得重启docker