目录
1. 运行一个centos 容器中运行 /sbin/init
2. 使用docker commit 命令将该容器保存为镜像“test1”
5. 使用docker history 命令查看镜像构建历史
1. 编辑一个dockerfile 文件,存放于/root/df 目录下
2. 使用docker build 命令用文件 dockerfile 构建一个镜像,并将镜像命名为 tests
Linux 操作系统由内核空间和用户空间构成
① kernel:Linux系统内核(/boot/vmlinuz-*)
② rootfs(根文件系统): Linux系统中的用户空间文件系统。
rootfs 是一个操作系统所包含的文件、配置和目录,但并不包括操作系统kernel
1. 容器镜像是容器的模板,容器时镜像的运行实例,runtime根据容器镜像创建容器
2. 容器镜像挂载在容器根目录下,是为容器中的应用提供隔离后执行环境的文件系统
① 容器镜像打包了整个操作系统的文件和目录(rootfs),当然也包括应用本身。即, 应用及其运行所需的所有依赖,都在被封装在容器镜像中。
保证了本地环境和云端环境的高度一致
3. 容器镜像采用分层结构:
① 所有容器共享宿主机Kernel,并且不能修改宿主机Kernel。即,容器运行过程中使用 容器镜像里的文件,使用宿主机OS上的Kernel
1. scratch 空镜像
① 从 scratch 构建,不依赖其它镜像
- scratch 本身是个空镜像
② 其他镜像可在base 镜像上进行扩展,创建新的镜像
2. 最常用的 base 镜像是各 Linux 发行版的 Docker镜像,如 ubuntu、centos等
1. Docker 镜像中引入层 layer 的概念。镜像制作过程中的每一步操作,都会生成一个新的镜像层
2. 容器由若干只读镜像层和最上面的一个可写容器层构成
① 分层结构使镜像共享、容器创建、分发非常高效
3. 使用 docker image inspect ubuntu 命令查看 ubuntu 镜像分层结构,回显如下
1. UnionFS 主要功能是将多个不同位置的目录联合挂载(union mount)到同一个目录下
① 每一个镜像层都是Linux 操作系统文件与目录的一部分。在使用镜像时,docker 会 将所有的镜像层联合挂载到一个统一的挂载点上,表现为一个完整的Linux 操作系统 供容器使用
# docker images #查看本地镜像 # docker history alpine:latest #查看镜像制作历史 # docker pull ubuntu #从镜像仓库拉取镜像 ubuntu # docker image inspect ubuntu:latest #查看镜像相关信息 # docker run -itd ubuntu #使用镜像运行容器 # docker ps #查看运行中的容器 # docker exec -it dreamy_carson ls / #查看容器根目录
1. 对容器的增、删、改、查操作:
操作 具体执行 创建文件 新文件只能被添加在容器层中 删除文件 依据容器分层结构由上往下依次查找。找到后,在容器层中记录该删除操作
具体实现是,UnionFS会在容器层创建一个"whiteout 文件",
将被删除的文件"遮挡"起来
修改文件 依据容器分层结构由上往下依次查找。
找到后,将镜像层中的数据复制到容器层进行修改,
修改后的数据保存在容器层中。
(copy-on-write)
读取文件 依据容器分层结构由上往下依次查找
1. docker commit 命令:可将一个运行中的容器保存为镜像。其运行过程可总结如下:
① 运行一个容器
② 修改容器内容
③ 将容器保存为镜像
docker命令提供了bash-complete的脚本,在执行该命令时,敲tab可以自动补全参数
/usr/share/bash-completion/completions/docker
# apt-get install bash-completion # source /usr/share/bash-completion/completions/docker #执行后出现如下问题 # docker pbash: _get_comp_words_by_ref: command not found bash: [: : integer expression expected bash: [: : integer expression expected bash: [: : integer expression expected q^C '/usr/share/bash-completion/bash_completion 该文件中有上面缺少的命令' # source /usr/share/bash-completion/bash_completion #此时就可正常进行docker子命令的补全
# docker run -itd --privileged centos /sbin/init #centos不加--privileged没有权限修改 # docker ps #查看状态容器已经运行 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 736eae62b647 centos "/sbin/init" 45 seconds ago Up 44 seconds inspiring_boyd # docker exec -it 736e /bin/bash #进入容器 [root@736eae62b647 /]# yum -y install httpd #安装web服务 Failed to set locale, defaulting to C.UTF-8 CentOS Linux 8 - AppStream 73 B/s | 38 B 00:00 Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist '提示仓库源有问题' [root@736eae62b647 /]# rm -rf /etc/yum.repos.d/CentOS-Linux-* [root@736eae62b647 /]# cat /etc/redhat-release #查看当前版本 CentOS Linux release 8.4.2105 [root@736eae62b647 /]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo #可以去阿里上查找对应版本https://developer.aliyun.com/mirror/ [root@736eae62b647 /]# yum repolist #查看仓库是否架子啊 Failed to set locale, defaulting to C.UTF-8 repo id repo name AppStream CentOS-8.5.2111 - AppStream - mirrors.aliyun.com base CentOS-8.5.2111 - Base - mirrors.aliyun.com extras CentOS-8.5.2111 - Extras - mirrors.aliyun.com [root@736eae62b647 /]# yum -y install httpd #再次安装即可 [root@736eae62b647 /]# echo "hello world" > /var/www/html/index.html [root@736eae62b647 /]# systemctl enable --now httpd [root@736eae62b647 /]# curl localhost #web服务正常开启 hello world [root@736eae62b647 /]# exit #退出容器 # docker ps #查看运行的容器状态 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 736eae62b647 centos "/sbin/init" 27 minutes ago Up 27 minutes inspiring_boyd
# docker commit inspiring_boyd test1 #将运行的容器做成镜像 sha256:18828b81510de014ea66b1ad3b505ba774fbc74ad2b25aa9168c584efced6924
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE test1 latest 18828b81510d 41 seconds ago 280MB
# docker run -itd --privileged test1 /sbin/init # docker exec -it interesting_vaughan /bin/bash #进入容器 [root@09bf75ca5019 /]# curl localhost #测试服务正常 hello world
对比镜像test1与centos,test1 比 centos 多了一个镜像层
1. 文件指令集,描述如何自动创建 Docker 镜像
① 是包含若干指令的文本文件,可以通过这些指令创建出 docker image
② 文件中的指令执行后,会创建一个个新的镜像层
③ 文件中的注释以 “#” 开始
④ 一般由 4 部分组成
2. build context: 为镜像构建提供所需的文件或目录
指令 作用 命令格式 FROM 指定base镜像 FROM <image>:<tag> MAINTAINER 注明镜像的作者 MAINTAINER <name> RUN 运行指定的命令 RUN <command> ADD 将文件从build context 复制到镜像中 ADD [--chown=<user>:<group>]<src>...<dest> COPY 将文件从build context复制到镜像中 COPY [--chown=<user>:<group>]<src>...<dest> ENV 设置环境变量 ENV <key><value> EXPOSE 指定容器中的应用监听的端口 EXPOSE <port> [<port>/<protocol>...] USER 设置启动容器的用户 USER <user>[:<group>] CMD 设置在容器启动时运行指定的脚本或命令 CMD command param1 param2 ENTRYPOINT 指定的是一个可执行的脚本或者程序的路径 ENTRYPOINT command param1 param2 VOLUME 将文件或目录声明为volume,挂载到容器中 VOLUME ["/data"] WORKDIR 设置镜像的当前工作目录 WORKDIR /path/to/workdir
参考资料: Dockerfile reference | Docker Documentation
~# mkdir df ~# cd /root/df ~/df# echo haha > index.html ~/df# vim vim dockerfile FROM httpd #指定镜像 COPY index.html / #将文件拷贝到镜像的根目录下 RUN echo haha #运行一条命令
~/df# docker build -t tests . #-t指定镜像名 .为在当前目录中寻找dockerfile文件 Sending build context to Docker daemon 3.072kB Step 1/3 : FROM httpd ---> a981c8992512 Step 2/3 : COPY index.html / ---> 9f026a199a7d Step 3/3 : RUN echo haha ---> Running in 553668509bac haha Removing intermediate container 553668509bac ---> 3a9e4e5ee1bf Successfully built 3a9e4e5ee1bf Successfully tagged tests:latest
1. Docker 会缓存已有镜像的镜像层,构建或下载镜像时,如果某镜像层已存在,则直接使用无须重新创建或下载
2. 编译 dockerfile 文件,增加在末尾声明作者的指令
~/df# vim dockerfile FROM httpd COPY index.html / RUN echo haha MAINTAINER *_花非人陌_* #增加作者信息3. 重新执行 docker build 构建镜像,新镜像命名为 tests2
~/df# docker build -t tests2 . #重新建立镜像 Sending build context to Docker daemon 3.072kB Step 1/4 : FROM httpd ---> a981c8992512 Step 2/4 : COPY index.html / ---> 'Using cache' #使用了缓存 ---> 9f026a199a7d Step 3/4 : RUN echo haha ---> Using cache ---> 3a9e4e5ee1bf Step 4/4 : MAINTAINER *_花非人陌_* ---> Running in 4f9ac93f1eb8 Removing intermediate container 4f9ac93f1eb8 ---> 0bc362ff7331 Successfully built 0bc362ff7331 Successfully tagged tests2:latest4. 若交换dockerfile 文件中命令执行顺序,虽然在逻辑上这种改动对镜像的内容没有影响,但由于分层的结构特性,Docker 必须重建受影响的镜像层
~/df# vim dockerfile FROM httpd MAINTAINER *_花非人陌_* COPY index.html / RUN echo haha5. 重新构建镜像test3,每一步均生成新的镜像层,未使用到 cache
~/df# docker build -t tests2 . Sending build context to Docker daemon 3.072kB Step 1/4 : FROM httpd ---> a981c8992512 Step 2/4 : MAINTAINER *_花非人陌_* ---> Running in 2ab77293ccd7 Removing intermediate container 2ab77293ccd7 ---> f1822a01898b Step 3/4 : COPY index.html / ---> 3e7d474f3185 Step 4/4 : RUN echo haha ---> Running in 9dacd7052d95 haha Removing intermediate container 9dacd7052d95 ---> 456098bfd852 Successfully built 456098bfd852 Successfully tagged tests2:latest
镜像名称格式
① image name = repository:tag
② tag 一般用于描述镜像版本。若未指定tag,则默认为“latest”
1. Registry 是存放容器镜像的仓库,用户可进行镜像下载和访问,分为公有和私有两类
2. 公有镜像仓库
① Docker Hub 是 Docker 公司为公众提供的托管 Registry Docker Hub
② Quay.io 现为 Red Hat 下的公共托管 Registry Quay
③ https://www.aliyun.com
④ catalog.redhat.com
3. 私有仓库
① 企业可以用 Docker Registry 构建私有的 Registry
- Registry 本身是一个开源项目,可以用于搭建私有 Registry
② Harbor,企业免费
③ quay,收费
1. Docker Hub 是目前世界上最大的容器镜像仓库,由Docker公司维护。
上面有Docker公司提供的镜像,及大量用户上传的镜像
1. 使用“registry” 镜像构建本地镜像仓库。registry 是 docker hub 上维护的镜像,其服务端 口是5000。 -v 参数将宿主机的/root/myregistry 目录映射到容器的 /var/lib/registry目录,用于存放镜像数据
root@k8s-master:~# mkdir /root/myregistry root@k8s-master:~# docker pull registry #下载registry镜像 ~# docker inspect registry | grep -A 1 Volume #查看容器数据挂载点 "Volumes": { "/var/lib/registry": {} -- "Volumes": { "/var/lib/registry": {} root@k8s-master:~# docker run -d -p 1000:5000 -v /root/myregistry:/var/lib/registry registry #运行容器 # docker ps #查看容器是否运行 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 45fa5baba5e8 registry "/entrypoint.sh /etc…" About a minute ago Up About a minute 0.0.0.0:1000->5000/tcp, :::1000->5000/tcp epic_heyrovsky2. 使用docker tag 命令修改镜像名称,使其符合registry上的格式要求。
若要将镜像上传到registry,镜像名称需要符合其命名格式要求:
[Registry-host]:[port]/[username]/[repository:tag]
root@k8s-master:~# docker images #查看镜像 REPOSITORY TAG IMAGE ID CREATED SIZE tests2 latest 456098bfd852 2 hours ago 145MB root@k8s-master:~# docker tag tests2:latest 192.168.5.100:1000/tests2:tests23. 上传容器镜像到私有 Registry
# docker push 192.168.5.100:1000/tests2:tests2 #默认无法推送成功 The push refers to repository [192.168.5.100:1000/tests2] Get "https://192.168.5.100:1000/v2/": http: server gave HTTP response to HTTPS client '默认无法推送,因为当前为https'4. 在Linux下,若使用如“192.168.73.137:1000” 这样的内网地址作为私有仓库地址,则需要 在/etc/docker/daemon.json 中写入如下内容(如果文件不存在需新建该文件),
然后重启Docker服务
root@k8s-master:~# vim /etc/docker/daemon.json #编辑docker配置文件 }, "registry-mirrors": ["https://docker.nju.edu.cn/"], "insecure-registries": ["192.168.5.100:1000"] #意思是不用证书服务地址和端口 } root@k8s-master:~# systemctl daemon-reload #重新加载配置 root@k8s-master:~# systemctl restart docker #重启docker服务 root@k8s-master:~# docker start epic_heyrovsky #启动容器 # ss -tunlp | grep 1000 #查看端口是否被监听,确保可以正常服务 tcp LISTEN 0 4096 0.0.0.0:1000 0.0.0.0:* users:(("docker-proxy",pid=1448928,fd=4)) tcp LISTEN 0 4096 [::]:1000 [::]:* users:(("docker-proxy",pid=1448934,fd=4)) '再次push成功,192.168.5.100:1000就是仓库地址' root@k8s-master:~# docker push 192.168.5.100:1000/tests2:tests2 #上传镜像 The push refers to repository [192.168.5.100:1000/tests2] 462d767129cf: Pushed 01597d537f57: Pushed c7c38e3c39ad: Pushed c672c6903747: Pushed 34e2a1369fc5: Pushed 6485bed63627: Pushed tests2: digest: sha256:6fad1afe9b257abc84994bb30ab12d3b63b44cbd6518c6a8b16a89507387daa0 size: 1573 # curl 192.168.5.100:1000/v2/_catalog #访问后镜像已正常上传 {"repositories":["test2"]} # curl http://192.168.147.102:1000/v2/test2/tags/list #查看镜像标签 # docker-registry-cli
将镜像分成了多层,放置在了不同目录当中
root@k8s-master:~# tree /root/myregistry/ /root/myregistry/ └── docker └── registry └── v2 ├── blobs │ └── sha256 │ ├── 15 │ │ └── 152876b0d24a5561415915c652dceeb3bcd5080dc24c3994e77343a81f64b9f1 │ │ └── data │ ├── 45 │ │ └── 456098bfd852c3b85b0e7756273f8bbc085660225389066c6e9d7e0171ef8928 │ │ └── data │ ├── 6b │ │ └── 6b29c2b62286e254216da297b4066a4bb79b918bc02811ba954bd7b8fd51360b │ │ └── data │ ├── 6c │ │ └── 6cc0f1e2dfdc6eb221cb7ad6e25e84544f19c87767e429a7ea683dfa5cbb257b │ │ └── data │ ├── 6f │ │ └── 6fad1afe9b257abc84994bb30ab12d3b63b44cbd6518c6a8b16a89507387daa0 │ │ └── data │ ├── 7a │ │ └── 7a6db449b51b92eac5c81cdbd82917785343f1664b2be57b22337b0a40c5b29d │ │ └── data │ ├── b4 │ │ └── b4effd428409f1da4dc8c896afb9818ef1ba24be5e7e5e3d86dea650ac3ed8bc │ │ └── data │ └── c2 │ └── c2123effa3fcb96c62bf4d891147aef09029d429321bfb4c6a535fa3ca7e13d6 │ └── data └── repositories └── tests2 ├── _layers │ └── sha256 │ ├── 152876b0d24a5561415915c652dceeb3bcd5080dc24c3994e77343a81f64b9f1 │ │ └── link │ ├── 456098bfd852c3b85b0e7756273f8bbc085660225389066c6e9d7e0171ef8928 │ │ └── link │ ├── 6b29c2b62286e254216da297b4066a4bb79b918bc02811ba954bd7b8fd51360b │ │ └── link │ ├── 6cc0f1e2dfdc6eb221cb7ad6e25e84544f19c87767e429a7ea683dfa5cbb257b │ │ └── link │ ├── 7a6db449b51b92eac5c81cdbd82917785343f1664b2be57b22337b0a40c5b29d │ │ └── link │ ├── b4effd428409f1da4dc8c896afb9818ef1ba24be5e7e5e3d86dea650ac3ed8bc │ │ └── link │ └── c2123effa3fcb96c62bf4d891147aef09029d429321bfb4c6a535fa3ca7e13d6 │ └── link ├── _manifests │ ├── revisions │ │ └── sha256 │ │ └── 6fad1afe9b257abc84994bb30ab12d3b63b44cbd6518c6a8b16a89507387daa0 │ │ └── link │ └── tags │ └── tests2 │ ├── current │ │ └── link │ └── index │ └── sha256 │ └── 6fad1afe9b257abc84994bb30ab12d3b63b44cbd6518c6a8b16a89507387daa0 │ └── link └── _uploads
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
我正在尝试使用docker运行一个Rails应用程序。通过github的sshurl安装的gem很少,如下所示:Gemfilegem'swagger-docs',:git=>'git@github.com:xyz/swagger-docs.git',:branch=>'my_branch'我在docker中添加了keys,它能够克隆所需的repo并从git安装gem。DockerfileRUNmkdir-p/root/.sshCOPY./id_rsa/root/.ssh/id_rsaRUNchmod700/root/.ssh/id_rsaRUNssh-keygen-f/root/.ss
我在Heroku上构建了一个必须在Docker容器内运行的RoR应用程序。为此,我使用officialDockerfile.因为它在Heroku中很常见,所以我需要一些附加组件才能使这个应用程序完全运行。在生产中,变量DATABASE_URL在我的应用程序中可用。但是,如果我尝试其他一些使用环境变量(在我的例子中是Mailtrap)的加载项,变量不会在运行时复制到实例中。所以我的问题很简单:如何让docker实例在Heroku上执行时知道环境变量?您可能会问,我已经知道我们可以在docker-compose.yml中指定一个environment指令。我想避免这种情况,以便能够通过项目
我在开发和生产中都使用docker,真正困扰我的一件事是docker缓存的简单性。我的ruby应用程序需要bundleinstall来安装依赖项,因此我从以下Dockerfile开始:添加GemfileGemfile添加Gemfile.lockGemfile.lock运行bundleinstall--path/root/bundle所有依赖项都被缓存,并且在我添加新gem之前效果很好。即使我添加的gem只有0.5MB,从头开始安装所有应用程序gem仍然需要10-15分钟。由于依赖项文件夹的大小(大约300MB),然后再花10分钟来部署它。我在node_modules和npm上遇到了
开门见山|拉取镜像dockerpullelasticsearch:7.16.1|配置存放的目录#存放配置文件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/config#存放数据的文件夹mkdir-p/opt/docker/elasticsearch/node-1/data#存放运行日志的文件夹mkdir-p/opt/docker/elasticsearch/node-1/log#存放IK分词插件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/plugins若你使用了moba,直接右键新建即可如上图所示依次类推创建
测试环境对于任何一个软件公司来讲,都是核心基础组件之一。转转的测试环境伴随着转转的发展也从单一的几套环境发展成现在的任意的docker动态环境+docker稳定环境环境体系。期间环境系统不断的演进,去适应转转集群扩张、新业务的扩展,走了一些弯路,但最终我们将系统升级到了我们认为的终极方案。下面我们介绍一下转转环境的演进和最终的解决方案。1测试环境演进1.1单体环境 转转在2017年成立之初,5台64G内存的机器,搭建5个完整的测试环境。就满足了转转的日常所需。一台分给开发,几台分给测试。通过沟通协调就能解决多分支并行开发下冲突问题。1.2动态环境+稳定环境 随着微服务化的进
1.现象服务重启后,通过dockerstart方式无法启动实例,报出错误:Errorresponsefromdaemon:errorcreatingoverlaymountto/var/lib/docker/overlay2/xxx/merged:nosuchfileordirectorydockersave导出镜像也报出2.网上各种尝试摸索无效果修改daemon.json中的storage-driver为overlay,重启无效果。禁用selinux,临时或永久方式都无效果。修改/etc/docker/daemon.json中的storage-driver为overlay2,无效果。修改/l
homeassistant久仰大名,据说可以一统各大物联网平台的设备,家里各平台的设备都有一点,控制起来很不方便,于是乎我也来尝尝~homeassistant官网https://www.home-assistant.io/HACShttps://github.com/hacs/integration准备1.Linux系统(Window)其实也类似2.安装好dockerdocker安装homeassistant官方有几个版本可供选择,安装方式可以:直接刷HA的系统,也可以用Docker安装,还可以直接安装在物理机上,具体区别如下:我采用的是Docker进行安装,也就是Container,从上图也
文章目录前言一、迁移步骤前言Docker安装的东西多了或者目录分配大小未提前规划好,就容易出现磁盘空间不足的问题,可以采用软链接的方式迁移数据目录空间。一、迁移步骤要使用软连接的方式修改Docker数据存储目录,需要执行以下步骤:1、使用systemctlstopdocker命令停止Docker服务;2、创建文件夹:mkdir/home/docker(/home/docker为新磁盘目录名);3、移动/var/lib/docker/目录到新目录中:mv/var/lib/docker/*/home/docker;4、使用rm-rf/var/lib/docker命令删除原有的Docker数据目录;
一、Docker介绍Docker中⽂社区⽂档:https://www.docker.org.cn/index.html Docker是⼀个开源的软件部署解决⽅案。 Docker也是轻量级的应⽤容器框架。 Docker可以打包、发布、运⾏任何的应⽤。 Docker就像⼀个盒⼦,⾥⾯可以装很多物件,如果需要某些物件,可以直接将该盒⼦拿⾛,⽽不需要从该盒⼦中⼀件⼀件的取。 Docker是⼀个客户端-服务端(C/S)架构程序。客户端只需要向服务端发出请求,服务端处理完请求后会返回结果。Docker包括三个基本概念:镜像(Image) Docker的镜像概念类似于虚拟机⾥的镜像,是⼀个只读的