docker 操作概念图
对应概念
镜像:就类似于我们用虚拟机,创建虚拟机前要下载的系统镜像文件,比如iso文件、img文件等等这样一些镜像文件。通俗来说就是为容器用来创建容器的
容器:它可以类比成正在运行中的一个虚拟机。
tar文件:tar文件就类似于vm使用时的vmdk文件,它可以将镜像直接保存成一个tar文件,然后怎样给别人然后别人通过load指令,重新加载成一个镜像,然后通过run指令就可以起来一个正在运行中的容器了。
Dockerfile:Dockerfile相当于一个配置文件,通过写“如何构建”的步骤,来指定一个镜像是如何构建的。通过docker build指令可以将dockerfile构建成一个镜像。
仓库(Repository):仓库中保存了很多的镜像,包括一些共有的第三方已经做好的镜像比如ubuntu镜像nginx镜像mysql镜像tomcat镜像等等。我们可以通过docker poll指令下载这些镜像到本地。当然也可以把这些镜像通过push上传上去。
docker总述 通过以上这些技术的组合,最后的结果就是,绝大部分应用,开发者都可以通过docker build创建镜像,通过docker push上传镜像,用户通过docker pull下载镜像,用docker run运行应用。用户不需要再去关心如何搭建环境,如何安装,如何解决不同发行版的库冲突——而且通常不会需要消耗更多的硬件资源,不会明显降低性能。这就是其他答主所说的标准化、集装箱的原因所在。
Docker基础命令操作 查看docker相关信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@docker01 ~]# docker version Client: Version: 17.12.0-ce API version: 1.35 Go version: go1.9.2 Git commit: c97c6d6 Built: Wed Dec 27 20:10:14 2017 OS/Arch: linux/amd64 Server: Engine: Version: 17.12.0-ce API version: 1.35 (minimum version 1.12) Go version: go1.9.2 Git commit: c97c6d6 Built: Wed Dec 27 20:12:46 2017 OS/Arch: linux/amd64 Experimental: false
配置docker镜像加速
1 2 3 4 vi /etc/docker/daemon.json { "registry-mirrors": ["https://registry.docker-cn.com"] }
启动第一个容器 1 2 3 4 5 6 7 8 9 10 [root@docker01 ~]# docker run -d -p 80:80 nginx Unable to find image 'nginx:latest' locally latest: Pulling from library/nginx e7bb522d92ff: Pull complete 6edc05228666: Pull complete cd866a17e81f: Pull complete Digest: sha256:285b49d42c703fdf257d1e2422765c4ba9d3e37768d6ea83d7fe2043dad6e63d Status: Downloaded newer image for nginx:latest 8d8f81da12b5c10af6ba1a5d07f4abc041cb95b01f3d632c3d638922800b0b4d # 容器启动后,在浏览器进行访问测试
参数说明
Docker镜像生命周期
Docker镜像相关操作 搜索官方仓库镜像 1 2 3 4 [root@docker01 ~]# docker search centos NAME DESCRIPTION STARS OFFICIAL AUTOMATED centos The official build of CentOS. 3992 [OK] ansible/centos7-ansible Ansible on Centos7 105 [OK]
列表说明
获取镜像 根据镜像名称拉取镜像
1 2 3 4 [root@docker01 ~]# docker pull centos Using default tag: latest latest: Pulling from library/centos af4b0a2388c6: Downloading 34.65MB/73.67MB
查看当前主机镜像列表
1 2 3 4 [root@docker01 ~]# docker image list REPOSITORY TAG IMAGE ID CREATED SIZE centos latest ff426288ea90 3 weeks ago 207MB nginx latest 3f8a4339aadd 5 weeks ago 108MB
拉第三方镜像方法
1 docker pull index.tenxcloud.com/tenxcloud/httpd
导出镜像 1 2 3 4 5 6 [root@docker01 ~]# docker image list REPOSITORY TAG IMAGE ID CREATED SIZE centos latest ff426288ea90 3 weeks ago 207MB nginx latest 3f8a4339aadd 5 weeks ago 108MB # 导出 [root@docker01 ~]# docker image save centos > docker-centos.tar.gz
删除镜像 1 2 3 4 [root@docker01 ~]# docker image rm centos:latest [root@docker01 ~]# docker image list REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 3f8a4339aadd 5 weeks ago 108MB
导入镜像 1 2 3 4 5 6 7 [root@docker01 ~]# docker image load -i docker-centos.tar.gz e15afa4858b6: Loading layer 215.8MB/215.8MB Loaded image: centos:latest [root@docker01 ~]# docker image list REPOSITORY TAG IMAGE ID CREATED SIZE centos latest ff426288ea90 3 weeks ago 207MB nginx latest 3f8a4339aadd 5 weeks ago 108MB
查看镜像的详细信息 1 [root@docker01 ~]# docker image inspect centos
容器的日常管理 容器的起/停 最简单的运行一个容器
1 [root@docker01 ~]# docker run nginx
创建容器,两步走(不常用)
1 2 3 4 [root@docker01 ~]# docker create centos:latest /bin/bash bb7f32368ecf0492adb59e20032ab2e6cf6a563a0e6751e58930ee5f7aaef204 [root@docker01 ~]# docker start stupefied_nobel stupefied_nobel
快速启动容器方法
1 [root@docker01 ~]# docker run centos:latest /usr/bin/sleep 20;
容器内的第一个进程必须一直处于运行的状态,否则这个容器,就会处于退出状态!
查看正在运行的容器
1 2 3 4 5 [root@docker01 ~]# docker container ls 或 [root@docker01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8708e93fd767 nginx "nginx -g 'daemon of…" 6 seconds ago Up 4 seconds 80/tcp keen_lewin
查看你容器详细信息/ip
1 [root@docker01 ~]# docker container inspect 容器名称/id
查看你所有容器(包括未运行的)
1 2 3 4 5 [root@docker01 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8708e93fd767 nginx "nginx -g 'daemon of…" 4 minutes ago Exited (0) 59 seconds ago keen_lewin f9f3e6af7508 nginx "nginx -g 'daemon of…" 5 minutes ago Exited (0) 5 minutes ago optimistic_haibt 8d8f81da12b5 nginx "nginx -g 'daemon of…" 3 hours ago Exited (0) 3 hours ago lucid_bohr
停止容器
1 2 3 4 [root@docker01 ~]# docker stop 容器名称/id 或 [root@docker01 ~]# docker container kill 容器名称/id
进入容器方法 启动时进去方法
1 2 3 [root@docker01 ~]# docker run -it #参数:-it 可交互终端 [root@docker01 ~]# docker run -it nginx:latest /bin/bash root@79241093859e:/#
退出/离开容器
启动后进入容器的方法
启动一个docker
1 2 3 4 5 [root@docker01 ~]# docker run -it centos:latest [root@1bf0f43c4d2f /]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 15:47 pts/0 00:00:00 /bin/bash root 13 1 0 15:47 pts/0 00:00:00 ps -ef
attach进入容器,使用pts/0 ,会让所用通过此方法进如放入用户看到同样的操作。
1 2 3 4 5 [root@docker01 ~]# docker attach 1bf0f43c4d2f [root@1bf0f43c4d2f /]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 15:47 pts/0 00:00:00 /bin/bash root 14 1 0 15:49 pts/0 00:00:00 ps -ef
自命名启动一个容器 –name
1 2 3 4 5 [root@docker01 ~]# docker attach 1bf0f43c4d2f [root@1bf0f43c4d2f /]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 15:47 pts/0 00:00:00 /bin/bash root 14 1 0 15:49 pts/0 00:00:00 ps -ef
exec 进入容器方法(推荐使用)
1 2 3 4 5 6 7 [root@docker01 ~]# docker exec -it clsn1 /bin/bash [root@b20fa75b4b40 /]# 重新分配一个终端 [root@b20fa75b4b40 /]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 16:11 pts/0 00:00:00 /bin/bash root 13 0 0 16:14 pts/1 00:00:00 /bin/bash root 26 13 0 16:14 pts/1 00:00:00 ps -ef
删除所有容器 1 2 [root@docker01 ~]# docker rm -f `docker ps -a -q` # -f 强制删除
启动时进行端口映射 -p参数端口映射
1 2 [root@docker01 ~]# docker run -d -p 8888:80 nginx:latest 287bec5c60263166c03e1fc5b0b8262fe76507be3dfae4ce5cd2ee2d1e8a89a9
不同指定映射方法
随机映射
1 docker run -P (大P)# 需要镜像支持
Docker 数据卷的管理 挂载时创建卷 挂载卷
1 2 [root@docker01 ~]# docker run -d -p 80:80 -v /data:/usr/share/nginx/html nginx:latest 079786c1e297b5c5031e7a841160c74e91d4ad06516505043c60dbb78a259d09
容器内站点目录: /usr/share/nginx/html
在宿主机写入数据,查看
1 2 3 [root@docker01 ~]# echo "http://www.nmtui.com" >/data/index.html [root@docker01 ~]# curl 10.0.0.100 http://www.nmtui.com
设置共享卷,使用同一个卷启动一个新的容器
1 2 3 4 [root@docker01 ~]# docker run -d -p 8080:80 -v /data:/usr/share/nginx/html nginx:latest 351f0bd78d273604bd0971b186979aa0f3cbf45247274493d2490527babb4e42 [root@docker01 ~]# curl 10.0.0.100:8080 http://www.nmtui.com
查看卷列表
1 2 [root@docker01 ~]# docker volume ls DRIVER VOLUME NAME
创建卷后挂载 创建一个卷
1 2 3 4 5 [root@docker01 ~]# docker volume create f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521 [root@docker01 ~]# docker volume ls DRIVER VOLUME NAME local f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521
指定卷名
1 2 3 4 [root@docker01 ~]# docker volume ls DRIVER VOLUME NAME local clsn local f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521
查看卷路径
1 2 3 4 5 6 7 8 9 10 11 12 [root@docker01 ~]# docker volume inspect clsn [ { "CreatedAt": "2018-02-01T00:39:25+08:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/clsn/_data", "Name": "clsn", "Options": {}, "Scope": "local" } ]
使用卷创建
1 2 3 4 5 6 [root@docker01 ~]# docker run -d -p 9000:80 -v clsn:/usr/share/nginx/html nginx:latest 1434559cff996162da7ce71820ed8f5937fb7c02113bbc84e965845c219d3503 # 宿主机测试 [root@docker01 ~]# echo 'blog.nmtui.com' >/var/lib/docker/volumes/clsn/_data/index.html [root@docker01 ~]# curl 10.0.0.100:9000 blog.nmtui.com
设置卷
1 2 [root@docker01 ~]# docker run -d -P --volumes-from 079786c1e297 nginx:latest b54b9c9930b417ab3257c6e4a8280b54fae57043c0b76b9dc60b4788e92369fb
查看使用的端口
1 2 3 4 5 6 7 8 9 10 11 12 [root@docker01 ~]# netstat -lntup Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1400/sshd tcp 0 0 10.0.0.100:2375 0.0.0.0:* LISTEN 26218/dockerd tcp6 0 0 :::9000 :::* LISTEN 32015/docker-proxy tcp6 0 0 :::8080 :::* LISTEN 31853/docker-proxy tcp6 0 0 :::80 :::* LISTEN 31752/docker-proxy tcp6 0 0 :::22 :::* LISTEN 1400/sshd tcp6 0 0 :::32769 :::* LISTEN 32300/docker-proxy [root@docker01 ~]# curl 10.0.0.100:32769 http://www.nmtui.com
手动将容器保存为镜像 本次是基于docker官方centos 6.8 镜像创建
官方镜像列表:
https://hub.docker.com/explore/
启动一个centos6.8的镜像
1 2 3 4 5 6 [root@docker01 ~]# docker pull centos:6.8 [root@docker01 ~]# docker run -it -p 1022:22 centos:6.8 /bin/bash # 在容器种安装sshd服务,并修改系统密码 [root@582051b2b92b ~]# yum install openssh-server -y [root@582051b2b92b ~]# echo "root:123456" |chpasswd [root@582051b2b92b ~]# /etc/init.d/sshd start
启动完成后镜像ssh连接测试
将容器提交为镜像
1 [root@docker01 ~]# docker commit brave_mcclintock centos6-ssh
使用新的镜像启动容器
1 2 [root@docker01 ~]# docker run -d -p 1122:22 centos6-ssh:latest /usr/sbin/sshd -D 5b8161fda2a9f2c39c196c67e2eb9274977e7723fe51c4f08a0190217ae93094
在容器安装httpd服务
1 [root@5b8161fda2a9 /]# yum install httpd -y
编写启动脚本脚本
1 2 3 4 5 6 [root@5b8161fda2a9 /]# cat init.sh #!/bin/bash /etc/init.d/httpd start /usr/sbin/sshd -D [root@5b8161fda2a9 /]# chmod +x init.sh # 注意执行权限
再次提交为新的镜像
1 2 [root@docker01 ~]# docker commit 5b8161fda2a9 centos6-httpd sha256:705d67a786cac040800b8485cf046fd57b1828b805c515377fc3e9cea3a481c1
启动镜像,做好端口映射。并在浏览器中测试访问
1 2 [root@docker01 ~]# docker run -d -p 1222:22 -p 80:80 centos6-httpd /init.sh 46fa6a06644e31701dc019fb3a8c3b6ef008d4c2c10d46662a97664f838d8c2c
Dockerfile自动构建docker镜像 官方构建dockerffile文件参考
https://github.com/CentOS/CentOS-Dockerfiles
Dockerfile指令集 dockerfile主要组成部分:
基础镜像信息 FROM centos:6.8
制作镜像操作指令RUN yum insatll openssh-server -y
容器启动时执行指令 CMD [“/bin/bash”]
dockerfile常用指令:
FROM 这个镜像的妈妈是谁?(指定基础镜像)
MAINTAINER 告诉别人,谁负责养它?(指定维护者信息,可以没有)
RUN 你想让它干啥(在命令前面加上RUN即可)
ADD 给它点创业资金(COPY文件,会自动解压)
WORKDIR 我是cd,今天刚化了妆(设置当前工作目录)
VOLUME 给它一个存放行李的地方(设置卷,挂载主机目录)
EXPOSE 它要打开的门是啥(指定对外的端口)
CMD 奔跑吧,兄弟!(指定容器启动后的要干的事情)
dockerfile其他指令:
COPY 复制文件
ENV 环境变量
ENTRYPOINT 容器启动后执行的命令
创建一个Dockerfile 创建第一个Dockerfile文件
1 2 3 4 5 6 7 8 9 # 创建目录 [root@docker01 base]# cd /opt/base # 创建Dcokerfile文件,注意大小写 [root@docker01 base]# vim Dockerfile FROM centos:6.8 RUN yum install openssh-server -y RUN echo "root:123456" |chpasswd RUN /etc/init.d/sshd start CMD ["/usr/sbin/sshd","-D"]
构建docker镜像
1 2 [root@docker01 base]# docker image build -t centos6.8-ssh . -t 为镜像标签打标签 . 表示当前路径
使用自构建的镜像启动
1 2 [root@docker01 base]# docker run -d -p 2022:22 centos6.8-ssh-b dc3027d3c15dac881e8e2aeff80724216f3ac725f142daa66484f7cb5d074e7a
使用Dcokerfile安装kodexplorer Dockerfile文件内容
1 2 3 4 5 6 7 8 FROM centos:6.8 RUN yum install wget unzip php php-gd php-mbstring -y && yum clean all # 设置工作目录,之后的操作都在这个目录中 WORKDIR /var/www/html/ RUN wget -c http://static.kodcloud.com/update/download/kodexplorer4.25.zip RUN unzip kodexplorer4.25.zip && rm -f kodexplorer4.25.zip RUN chown -R apache.apache . CMD ["/usr/sbin/apachectl","-D","FOREGROUND"]
更多的Dockerfile可以参考官方方法。
Docker中的镜像分层 参考文档:
http://www.maiziedu.com/wiki/cloud/dockerimage/
Docker 支持通过扩展现有镜像,创建新的镜像。实际上,Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。
从上图可以看到,新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。
Docker 镜像为什么分层 镜像分层最大的一个好处就是共享资源。
比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如 /etc 下的文件,这时其他容器的 /etc 是不会被修改的,修改只会被限制在单个容器内。这就是容器 Copy-on-Write 特性。
可写的容器层 当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。
容器层的细节说明 镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /a,上层的 /a 会覆盖下层的 /a,也就是说用户只能访问到上层中的文件 /a。在容器层中,用户看到的是一个叠加之后的文件系统。
文件操作的
只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Write。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。
这样就解释了我们前面提出的问题:容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。
参考: