docker 基础入门知识和一些常用命令解析
一 镜像命令
镜像相当于 java 中的类,一个 Java 类能生成多个实例,同样的一样镜像也能生成多个容器。
1.1 查询镜像
docker images #列出本地主机上的
yishui@yishui:~$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest fce289e99eb9 8 weeks ago 1.84kB
- REPOSITORY : 镜像的仓库源
- TAG : 镜像的标签
- IMAGE ID : 镜像的 id
- CREATED : 镜像的创建时间
- SIZE : 镜像的大小
同一个仓库源可以由多个 TAG,代表这个仓库源的不同版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。
如果不能指定一个镜像的版本标签,可以只使用 如 ubuntu ,docker 将默认使用 ubuntu:latest 镜像。
参数说明
-a 列出本地所有的镜像(含中间映像层)
-q 只显示镜像地
—digests 显示镜像的摘要信息
—no-trunc 显示完整的镜像信息
1.2 搜索镜像
dokcer search 某个镜像的名字
我们可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/
我们也可以使用 docker search 命令来搜索镜像。比如我们需要一个 httpd 的镜像来作为我们的 web 服务。我们可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。
yishui@yishui:~$ docker search tomcat NAME DESCRIPTION STARS OFFICIAL AUTOMATED tomcat Apache Tomcat is an open source implementati… 2300 [OK] tomee Apache TomEE is an all-Apache Java EE certif… 62 [OK] dordoka/tomcat Ubuntu 14.04, Oracle JDK 8 and Tomcat 8 base… 52 [OK] davidcaste/alpine-tomcat Apache Tomcat 7/8 using Oracle Java 7/8 with… 34 [OK] bitnami/tomcat Bitnami Tomcat Docker Image 27 [OK] cloudesire/tomcat Tomcat server, 6/7/8 14 [OK] tutum/tomcat Base docker image to run a Tomcat applicatio… 11 aallam/tomcat-mysql Debian, Oracle JDK, Tomcat & MySQL 11 [OK] meirwa/spring-boot-tomcat-mysql-app a sample spring-boot app using tomcat and My… 11 [OK] jeanblanchard/tomcat Minimal Docker image with Apache Tomcat 8 arm32v7/tomcat Apache Tomcat is an open source implementati… 6 rightctrl/tomcat CentOS , Oracle Java, tomcat application ssl… 3 [OK] maluuba/tomcat7-java8 Tomcat7 with java8. 3 amd64/tomcat Apache Tomcat is an open source implementati… 2 fabric8/tomcat-8 Fabric8 Tomcat 8 Image 2 [OK] arm64v8/tomcat Apache Tomcat is an open source implementati… 2 99taxis/tomcat7 Tomcat7 1 [OK] camptocamp/tomcat-logback Docker image for tomcat with logback integra… 1 [OK] 1and1internet/debian-9-java-8-tomcat-8.5 Our tomcat 8.5 image 0 [OK] s390x/tomcat Apache Tomcat is an open source implementati… 0 picoded/tomcat7 tomcat7 with jre8 and MANAGER_USER / MANAGER… 0 [OK] oobsri/tomcat8 Testing CI Jobs with different names. 0 cfje/tomcat-resource Tomcat Concourse Resource 0 jelastic/tomcat An image of the Tomcat Java application serv… 0 swisstopo/service-print-tomcat backend tomcat for service-print "the true, … 0
- NAME:镜像仓库源的名称
DESCRIPTION:镜像的描述
OFFICIAL:是否 docker 官方发布
参数说明
-s 点赞数大于 如:docker search -s 30 tomcat
—no-trunc 说明不要被省略
—automated 只罗列出 automated build 类型的镜像
1.3 拉取镜像
docker pull 某个镜像的名字
我们决定使用上图中的 httpd 官方版本的镜像,使用命令 docker pull 来下载镜像。
yishui@yishui:~$ docker pull tomcat Using default tag: latest latest: Pulling from library/tomcat 741437d97401: Pull complete 34d8874714d7: Pull complete 0a108aa26679: Pull complete eea0f08c7492: Pull complete ca74b3d90c15: Pull complete f11a643c4a85: Pull complete 05eafed73b65: Pull complete f24105f282aa: Pull complete e27e73cbbd3f: Pull complete 801f808615c2: Pull complete 294f3735a5f6: Pull complete Digest: sha256:2af4741120ac4b2e1993412e34b73565d1b859d8a44b1b5f0e1963d97cc921a1 Status: Downloaded newer image for tomcat:latest
下载完成后,我们就可以使用这个镜像了。
1.4 删除镜像
docker rmi 某个镜像的 id
删除某个镜像
1 | yishui@yishui:~$ docker rmi hello-world |
注意
正在运行的容器不能删除,需要强制删除,命令如下:
yishui@yishui:~$ docker rmi -f hello-world Untagged: hello-world:latest Untagged: hello-world@sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535 Deleted: sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e
删除多个镜像 docker rmi -f 镜像名 1:TAG 镜像名 2:TAG
删除全部镜像 docker rmi -f \${docker images -qa}
1.5 删除悬空镜像
我们在build镜像的过程中,可能会产生一些临时的不具有名称也没有作用的镜像他们的名称一般都是
1 | docker rmi $(docker images -f "dangling=true" -q) |
二 容器命令
docker 利用容器独立运行一个或一组应用。容器是镜像创建的运行实例。
他可以被启动、开始、停止、删除。每个容器都是相互隔离,保证安全的平台。
容器的定义和镜像几乎是一模一样,唯一的区别在于容器的最上一层是可读可写的
2.1 启动容器
命令格式如下:
1 | docker start 容器 id 或者容器名字 |
示例1:
1 | docker run -d --name=tomcat_demo --net=host --restart=always tomcat |
docker run -d —name=tomcat_demo —net=host —restart=always tomcat
示例2:
1 | docker run -d --name=tomcat_demo -p 本地端口:容器端口 --restart=always tomcat |
docker run -d —name=tomcat_demo -p 本地端口:容器端口 —restart=always tomcat
2.1.1 重启策略
Docker容器的重启策略如下:
- no,默认策略,在容器退出时不重启容器
- on-failure,在容器非正常退出时(退出状态非0),才会重启容器
- on-failure:3,在容器非正常退出时重启容器,最多重启3次
- always,在容器退出时总是重启容器
- unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
带重启的命令样例如下:
1 | docker run -d --restart always tomcat |
修改重启策略命令如下:
1 | docker container update --restart=always 容器名字 |
2.1.2 网络模式
docker run创建Docker容器时,可以用 --net
选项指定容器的网络模式
- host模式:使用
--net=host
指定。 - none模式:使用
--net=none
指定。 - bridge模式:使用
--net=bridge
指定,默认设置。 - container模式:使用
--net=container:NAME_or_ID
指定
带网络模式的启动命令如下:
1 | docker run -d --net=host 容器名字 |
2.1.3 启动权限
默认情况下container内的root只是外部的一个普通用户权限,使用privileged
参数可以使用container内的root拥有真正的root权限。privileged启动的容器,可以看到很多host上的设备,并且可以执行mount。甚至允许你在docker容器中启动docker容器。
示例
1 | docker run -d --name="centos7" --privileged=true centos:7 |
2.2 新建并启动容器
docker run [options] images [command][args]
参数说明
- —name=”容器的新名字” #为容器指定一个名字
—net=host # docker 跳过配置容器的独立网络栈
-d #后台运行容器,并返回容器 ID,即启动守护式容器
-i #以交互模式运行容器 ,通常与-t 同时使用
-t #为容器重新分配一个伪输入终端,通常与-一起使用
-P #随机端口映射(当使用 -P 标记时,Docker 会随机映射一个
49000~49900
的端口到内部容器开放的网络端口)- -p 指定要映射的端口
-p(小写的)则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有 ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort
。
2.2.1 映射所有接口地址
使用 hostPort:containerPort
格式本地的 5000 端口映射到容器的 5000 端口,可以执行
1 | $ sudo docker run -d -p 5000:5000 training/webapp python app.py |
此时默认会绑定本地所有接口上的所有地址。
2.2.2 映射到指定地址的指定端口
可以使用 ip:hostPort:containerPort
格式指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1
1 | $ sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py |
2.2.3 映射到指定地址的任意端口
使用 ip::containerPort
绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口。
1 | $ sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py |
还可以使用 udp 标记来指定 udp 端口
1 | $ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py |
2.2.4 查看映射端口配置
使用 docker port
来查看当前映射的端口配置,也可以查看到绑定的地址
1 | $ docker port nostalgic_morse 5000 |
注意:
- 容器有自己的内部网络和 ip 地址(使用
docker inspect
可以获取所有的变量,Docker 还可以有一个可变的网络配置。) - -p 标记可以多次使用来绑定多个端口
例如
1 | $ sudo docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py |
启动一个容器
yishui@yishui:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat latest 168588387c68 2 weeks ago 463MB
centos latest 1e1148e4cc2c 2 months ago 202MB
yishui@yishui:~$ docker run -it 1e1148e4cc2c
[root@e26764ed06b4 /]# docker ps
bash: docker: command not found
[root@e26764ed06b4 /]# docker -ps
bash: docker: command not found
[root@e26764ed06b4 /]#
[root@e26764ed06b4 /]#
[root@e26764ed06b4 /]# ls
anaconda-post.log dev home lib64 mnt proc run srv tmp var
bin etc lib media opt root sbin sys usr
[root@e26764ed06b4 /]#
[root@e26764ed06b4 /]#
如上所示 root@e26764ed06b4 表明当前已经运行了 docker 容器,并进入了 docker 容器之中,直接进入了 docker 的终端。
注意:
守护式容器不能通过 docker ps 命令查询到
2.3 查看正在运行镜像
yishui@yishui:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e26764ed06b4 1e1148e4cc2c "/bin/bash" 9 minutes ago Up 9 minutes happy_edison 286f29cabb2c centos "/bin/bash" 10 minutes ago Up 10 minutes festive_mcnulty
参数说明
-a #列出当前所有正在运行的容器和历史上运行过的容器
-l #显示最近创建的容器
-n #显示最近 n 创建的容器
-q #静默模式,只显示容器的编号
—no-trunc #显示完整的信息
2.4 退出容器
exit: 容器停止并退出
ctrl+P+Q: 容器不停止并退出
2.5 重启容器
1 | docker restart 容器id或者容器名字 |
2.6 关闭容器
1 | docker stop 容器id或者容器名字 |
2.7 强制停止容器
1 | docker kill 容器id或者容器名字 |
2.8 删除已停止的容器
1 | docker rm 容器 id |
一次删除多个容器 :
1 | docker rm -f \$(docker ps -a -q) |
或者
1 | docker ps -a -q | xargs docker rm |
2.9 守护式容器
使用镜像 centos:latest 以后台模式启动一个容器
1 | docker run -d centos |
然后以 docker ps -a 命令查看,会发现容器已经退出
这是因为 Dcoker 容器后台运行,就必须有一个前台进程
容器运行的命令如果不是那些一直挂起的命令,(比如运行 top ,tail)就会自动退出
这是 docker 的机制问题,比如你的 web 容器,如 nginx,在正常情况下,我们配置启动服务只需要启动相应的 service 即可,如
service start nginx
但是这样做会导致 nginx 以后台进程模式运行,从而导致 docker 前台没有运行的应用,因此容器后台启动后,会觉得自己没事可做了而自杀,所以最佳的解决方案是,将要运行的程序以前台进程的形式启动。
如
1 | docker run -d centos /bin/sh -c "while true;do echo hello world;sleep 2;done" |
上述命令为在后台持续打印输出,此时该 docker 容器不会退出。
2.10 查看容器日志
1 | docker logs -f -t --tail 容器 Id |
参数说明
-t : 加入时间
-f : 跟随最新的日志打印
—tail :数字显示多少条
2.11 查看容器内运行的进程
1 | docker top 容器 Id |
查看容器内部细节
1 | docker inspect 容器 Id |
2.12 进入正在运行的容器并以命令行交互
直接进入容器启动命令的终端,不会启动新的进程
1 | docker exec -it 容器 Id bashShell |
在容器中打开新的终端,并且可以启动新的进程
1 | 重新进入 docker attach 容器 Id |
以 root 用户进入容器
1 | docker exec -it --user root 容器 Id /bin/bash |
直接返回命令的结果
yishui@yishui:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 72ff727faba0 centos "/bin/sh -c 'while t…" 3 hours ago Up 3 hours festive_hypatia yishui@yishui:~$ docker exec -t 72ff727faba0 ls -l /tmp total 4 -rwx------ 1 root root 836 Dec 5 01:37 ks-script-h2MyUP -rw------- 1 root root 0 Dec 5 01:36 yum.log yishui@yishui:~$
上述命令可以直接返回命令的结果
进入终端
yishui@yishui:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 72ff727faba0 centos "/bin/sh -c 'while t…" 3 hours ago Up 3 hours festive_hypatia yishui@yishui:~$ docker exec -t 72ff727faba0 /bin/bash [root@72ff727faba0 /]#
上述命令可以直接进入 docker 容器的终端。
2.13 从容器内拷贝文件到主机上
1 | docker cp 容器 Id:容器内的路径 目的路径 |
三 docker 的基本概念
docker 镜像都是只读的
当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称为容器层,容器曾之下的斗角镜像层。
3.1 生 docker 成镜像
docker commit 提交容器的副本使之成为一个新的镜像
1 | docker commit -m="提交的描述信息" -a="作者" 容器 Id 要创建的目标镜像名:[标签名] |
启动一个 tomcat 容器
yishui@yishui:~$ docker images tomcat REPOSITORY TAG IMAGE ID CREATED SIZE tomcat latest 168588387c68 3 weeks ago 463MB yishui@yishui:~$ yishui@yishui:~$ docker run -it -p 8888:8080 tomcat Using CATALINA_BASE: /usr/local/tomcat Using CATALINA_HOME: /usr/local/tomcat Using CATALINA_TMPDIR: /usr/local/tomcat/temp Using JRE_HOME: /docker-java-home/jre
上述命令标识启动一个 tomcat 容器实例,该实例以宿主机上 8888 端口映射 docker 里面的 8080 端口。
启动成功后,可以通过http://localhost:8888/看到熟悉的tomcat管理界面了。
接下来,进入 docker 容器里面删除 tomcat 里面的 doc 文件
退出容器,执行以下命令
yishui@yishui:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 03e78242bfea tomcat "catalina.sh run" 29 minutes ago Up 29 minutes 0.0.0.0:8888->8080/tcp elastic_varahamihira yishui@yishui:~$ docker commit -a="yishuifengxiao" -m="生成第一个docker demo镜像" 03e78242bfea yishui/tomcat-demo:1.0 sha256:1323b27a2652b2eb28963dc7e31632d4574ee49225b74f9cb5bd5dad925c788d yishui@yishui:~$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE yishui/tomcat-demo 1.0 1323b27a2652 15 seconds ago 463MB <none> <none> 7cfe70fc34b0 About a minute ago 463MB tomcat latest 168588387c68 3 weeks ago 463MB centos latest 1e1148e4cc2c 2 months ago 202MB yishui@yishui:~$
在上述命中,参数意义如下
- -a : 指明作者
- -m : 描述
- yishui/tomcat-demo:1.0 : yishui 为命名空间,1.0 表示版本号
执行完上述命令后,我们可以看到已经生成了一个名为 yishui/tomcat-demo 的镜像
yishui@yishui:~$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE yishui/tomcat-demo 1.0 1323b27a2652 20 minutes ago 463MB <none> <none> 7cfe70fc34b0 21 minutes ago 463MB tomcat latest 168588387c68 3 weeks ago 463MB centos latest 1e1148e4cc2c 2 months ago 202MB yishui@yishui:~$ yishui@yishui:~$ yishui@yishui:~$ yishui@yishui:~$ yishui@yishui:~$ docker run -it -p 8888:8080 yishui/tomcat-demo:1.0 Using CATALINA_BASE: /usr/local/tomcat
启动自定义镜像,可以看到生成的自定义镜像能正常启动。
注意:由于这里版本号不是 latest,一次启动时必须带上 TAG
提示 这里用-d 命令启动守护容器,docker 容器也不会自动退出。
3.2 docker网络
当你安装完Docker时,它会自动创建三个网络。你可以使用以下docker network ls
命令列出这些网络:
1 | docker network ls |
结果应如下
1 | NETWORK ID NAME DRIVER SCOPE |
Docker内置这三个网络,运行容器时,你可以使用该来指定容器应连接到哪些网络。
我们在使用docker run创建Docker容器时,可以用--network
标志 选项指定容器的网络模式,Docker有以下4种网络模式:
- host模式:使用 —net=host 指定。
- none模式:使用 —net=none 指定。
- bridge模式:使用 —net=bridge 指定,默认设置。
- container模式:使用 —net=container:NAMEorID 指定。
3.2.1 host模式
Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。
host模式类似于Vmware的桥接模式,与宿主机在同一个网络中,但没有独立IP地址。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
3.2.2 container模式
Docker网络container模式是指,创建新容器的时候,通过--net container
参数,指定其和已经存在的某个容器共享一个 Network Namespace。如下图所示,右方黄色新创建的container,其网卡共享左边容器。因此就不会拥有自己独立的 IP,而是共享左边容器的 IP 172.17.0.2,端口范围等网络资源,两个容器的进程通过 lo 网卡设备通信。
但这两个容器在其他的资源上,如文件系统、进程列表等还是隔离的。
3.2.3 bridge桥接模式
Docker安装时会创建一个名为docker0的虚拟网桥。除非我们进行另外的配置,新创建的容器都会自动连接到这个虚拟网桥提供的风格,bridge网络用于同一主机上的docker容器相互通信,连接到同一个网桥的docker容器可以相互通信。
bridge 对宿主机来讲相当于一个单独的网卡设备 对于运行在宿主机上的每个容器来说相当于一个交换机,所有容器的虚拟网线的一端都连接到docker0上。
容器通过本地主机进行上网,容器会创建名为veth的虚拟网卡,网卡一端连接到docker0网桥,另一端连接容器,容器就可以通过网桥通过分配的IP地址进行上网。
我们也可以自定义自己的bridge网络,docker文档建议使用自定义bridge网络,
四 docker安装
4.1 卸载旧版本
较旧的 Docker 版本称为 docker 或 docker-engine 。如果已安装这些程序,请卸载它们以及相关的依赖项。
1 | sudo yum remove docker \ |
4.2 设置仓库
安装所需的软件包。yum-utils 提供了 yum-config-manager ,并且 device mapper 存储驱动程序需要 device-mapper-persistent-data 和 lvm2。
1 | sudo yum install -y yum-utils \ |
使用以下命令来设置稳定的仓库。
1 | sudo yum-config-manager \ |
4.3 安装 Docker Engine-Community
安装最新版本的 Docker Engine-Community 和 containerd,或者转到下一步安装特定版本:
1 | sudo yum install docker-ce docker-ce-cli containerd.io |
或者
Ubuntu Docker 安装
使用官方安装脚本自动安装
安装命令如下:
1 | curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun |
也可以使用国内 daocloud 一键安装命令:
1 | curl -sSL https://get.daocloud.io/docker | sh |
CentOS Docker 安装
安装命令如下:
1 | curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun |
也可以使用国内 daocloud 一键安装命令:
1 | curl -sSL https://get.daocloud.io/docker | sh |
4.4 常见问题
1) 如果运行docker 命令出现
1 | Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? |
时,表明docker进程未运行。
解决办法
1 | systemctl daemon-reload |
2) 若出现以下问题
package docker-ce-3:19.03.11-3.el7.x86_64 requires containerd.io >= 1.2.2-3, but none of the providers can be installed
解决方法:
进入阿里云镜像地址:https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/edge/Packages/ 找到你想要的或者最新的containerd.io包,拼接在阿里云地址后面,
如下:
yum install -y https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.13-3.1.el7.x86_64.rpm
然后再执行
1 | yum install docker-ce docker-ce-cli containerd.io |
即可。
4.5 配置镜像加速器
针对Docker客户端版本大于 1.10.0 的用户
您可以通过修改daemon
配置文件/etc/docker/daemon.json
来使用加速器
1 | sudo mkdir -p /etc/docker |