0%

Docker常用命令

Docker常用命令

参考:http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html

在过去,软件的交付件是代码和它编译的二进制文件,而Docker的出现使软件的交付件完全可以是容器。

容器的优点如下:

image-20210430152833830

Docker的基本组成

image-20200606212250845
  1. ==镜像(image)==:docker镜像好比一个模板,可以通过这个模板来创建容器(container),一个镜像可以创建多个容器,类似Java中的Class

  2. ==容器(container)==:类似Java中通过Class创建的实例,Object;容器可以理解为一个简易的系统

  3. ==仓库(repository)==:存放镜像的地方,分为共有仓库和私有仓库

    • Docker Hub:国外的
    • 阿里云

Docker 需要用户具有 sudo 权限,为了避免每次命令都输入 sudo,可以把用户加入 Docker 用户组(如果是root用户就不用考虑这个了)。

国内连接 Docker 的官方仓库很慢,还会断线,需要将默认仓库改成国内的镜像网站。

centos配置阿里云镜像:

1
2
3
$ sudo yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 阿里云镜像

运行HelloWorld:

1
docker run hello-world

image-20200616151641013

帮助命令

1
2
3
4
5
docker version # 显示docker的基本信息

docker info # 系统信息,镜像和容器的数量

docker --help # 全部信息

镜像命令

查看所有本地主机上的镜像

1
docker images 

举例:

1
2
3
4
5
6
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 87eca374c0ed 2 weeks ago 447MB
nginx latest 62d49f9bab67 3 weeks ago 133MB
hello-world latest d1165f221234 2 months ago 13.3kB
centos latest 300e315adb2f 4 months ago 209MB

解释:

1
2
3
4
5
REPOSITORY  # 镜像仓库源
TAG # 镜像的版本
IMAGE ID # 镜像的ID
CREATED # 镜像的创建时间
SIZE # 镜像的大小

搜索仓库中的镜像

1
2
3
docker search

docker search mysql # 搜索mysql

下载镜像

1
2
3
4
5
docker pull 

docker pull mysql # 下载mysql镜像,默认最新版latest

docker pull mysql:5.7 # 指定版本下载

删除镜像

注意:拥有容器的镜像不可以删除,即使容器处于停止状态,必须先删除所有容器!!!

1
2
3
4
5
6
7
8
9
10
docker rmi

# 删除一个 可以通过名称 也可以指定id -f表示删除所有
docker rmi -f 9cfcce23593a

# 删除多个 用空格分隔id
docker rmi -f id id id

# 删除所有 images -aq就是查所有镜像id,从而递归删除
docker rmi -f $(docker images -aq)

还要注意一种情况:多个镜像id相同,此时删除也会不成功。

image-20210506174020708

此时还可以根据”REPOSITORY”和”TAR”进行删除:

1
2
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# docker rmi tomcat:latest
Untagged: tomcat:latest

容器命令

有了镜像才能创建容器。

新建容器并启动

1
2
3
4
5
6
7
8
9
10
11
12
docker run [可选参数] image

# 参数说明
--name=“Name” # 容器名字,用于区分容器
-d 后台方式运行
-it 使用交互方式运行,可以进入容器查看内容
-p 指定容器的端口 如-p:8080:8080
-p ip:主机端口:容器端口
-p :主机端口:容器端口(常用方式)
-p 容器端口

--rm:容器停止运行后,自动删除容器文件
  • 如果在docker run后面追加-d=true或者-d,那么容器将会运行在后台模式。此时所有I/O数据只能通过网络资源或者共享卷组来进行交互。因为容器不再监听你执行docker run的这个终端命令行窗口。但你可以通过执行docker attach来重新附着到该容器的会话中。
  • 在前台模式下(不指定-d参数即可),Docker会在容器中启动进程,同时将当前的命令行窗口附着到容器的标准输入、标准输出和标准错误中。也就是说容器中所有的输出都可以在当前窗口中看到。甚至它都可以虚拟出一个TTY窗口,来执行信号中断。

比如进入centos容器查看文件并退出:

image-20200617104004004

查看运行的容器

1
2
3
4
# 查看正在运行的容器
docker ps
# 查看曾经运行的容器
docker ps -a

退出容器

1
2
3
4
# 容器停止退出
exit
# 容器不停止退出 注意必须在英文输入法下,中文输入法不行
Ctrl + P + Q

比如退出再进入容器(我发现使用了Ctrl + P + Q退出之后,exit退出也不能停止容器了):

1
2
3
4
5
[root@192 ~]# docker run -it centos /bin/bash
### 按下Ctrl + P + Q
[root@bfcea13c40cd /]# [root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f73e417ed8e4 centos "/bin/bash" 2 minutes ago Up 2 minutes frosty_wilson

删除容器

注意:正在运行的容器不能删除!!!

1
2
3
4
5
6
# 删除指定容器 不能删除正在运行的容器,如果强制删除 rm -f
docker rm 容器id
# 删除所有容器
docker rm -f $(docker ps -aq)
# 删除所有容器
docker ps -a -q|xargs docker rm

启动和停止容器

1
2
3
4
5
docker start 容器id/容器name  # 已创建但是停止的容器可以通过这个命令启动

docker restart 容器id/容器name

docker stop 容器id/容器name # 对于已启动的容器通过这个命令停止

在容器中执行命令

1
docker exec

比如进入centos:

1
2
3
4
5
6
[root@192 ~]# docker run -it centos /bin/bash
### 按下Ctrl + P + Q
[root@bfcea13c40cd /]# [root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f73e417ed8e4 centos "/bin/bash" 2 minutes ago Up 2 minutes frosty_wilson
[root@192 ~]# docker exec -it f73e417ed8e4 /bin/bash ### 再次进入

部署nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# 下载镜像
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
f7ec5a41d630: Already exists
aa1efa14b3bf: Pull complete
b78b95af9b17: Pull complete
c7d6bca2b8dc: Pull complete
cf16cd8e71e0: Pull complete
0241c68333ef: Pull complete
Digest: sha256:75a55d33ecc73c2a242450a9f1cc858499d468f077ea942867e662c247b5e412
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
# 查看镜像
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 87eca374c0ed 2 weeks ago 447MB
nginx latest 62d49f9bab67 3 weeks ago 133MB
hello-world latest d1165f221234 2 months ago 13.3kB
centos latest 300e315adb2f 4 months ago 209MB
# 创建并启动容器 -d 后台运行(前台运行会显示输出),--name 命名,-p 暴露端口,3344服务器、宿主机的端口,容器内部端口
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# docker run -d --name nginx01 -p:3344:80 nginx
7b8e0497226d6138fdef504b5dad6105ec96d2d2a11695f3451418fa72919c74
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7b8e0497226d nginx "/docker-entrypoint.…" 8 seconds ago Up 7 seconds 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
# 使用3344可以访问成功
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# curl localhost:3344
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

如果需要修改配置文件或者网页文件:

1
2
3
4
5
6
7
8
9
10
# 进入容器
[root@cdfgroup ~]# docker exec -it nginx01 /bin/bash
# 查一下nginx在哪
root@7b8e0497226d:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
# 到这个目录
root@7b8e0497226d:/# cd /etc/nginx
root@7b8e0497226d:/etc/nginx# ls
conf.d fastcgi_params koi-utf koi-win mime.types modules nginx.conf scgi_params uwsgi_params win-utf
# 之后修改nginx.conf文件

每次改动都需要进入容器内部,十分麻烦。而且docker是要将应用和环境打包成一个镜像,这样,数据就不应该在容器中,否则容器删除,数据就会丢失。

使用数据卷技术可以实现容器之间数据共享,数据双向同步。

直接用命令来挂载:

1
2
docker run -v
# -v volume卷技术

参考:https://www.ruanyifeng.com/blog/2018/02/nginx-docker.html

新建文件夹进入(/root/nginx-docker-demo):

1
2
mkdir nginx-docker-demo
cd nginx-docker-demo

从docker容器里面拷贝文件到主机:

1
docker cp 容器名:容器文件路径 主机文件路径

从主机拷贝文件到docker容器:

1
docker cp 主机文件路径 容器名:容器文件路径

拷贝网页文件到当前文件夹:

1
docker cp nginx01:/usr/share/nginx/html .

拷贝配置文件到当前文件夹:

1
docker cp nginx01:/etc/nginx .

改名:

1
mv nginx conf

挂载的方式启动(注意:这时候启动必须在创建的文件夹下,否则找不到配置文件就不会启动):

1
2
3
4
5
6
7
8
docker run \
--rm \
--name mynginx \
--volume "$PWD/html":/usr/share/nginx/html \
--volume "$PWD/conf":/etc/nginx \
-p 3366:80 \
-d \
nginx

终止容器:(把这个容器终止,由于 --rm参数的作用,容器文件会自动删除)

1
docker stop mynginx

部署tomcat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# docker pull tomcat:9.0
9.0: Pulling from library/tomcat
bd8f6a7501cc: Pull complete
44718e6d535d: Pull complete
efe9738af0cb: Pull complete
f37aabde37b8: Pull complete
b87fc504233c: Pull complete
8bf93eef8c9e: Pull complete
8d33b4df10ef: Pull complete
2d77aa1a5442: Pull complete
baa04cc4071d: Pull complete
a3a752513415: Pull complete
Digest: sha256:0509684774ac53d8b152f4a50dd92889218a8633c0feddb4b35d092e55cd215d
Status: Downloaded newer image for tomcat:9.0
docker.io/library/tomcat:9.0
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat 9.0 c0e850d7b9bb 13 days ago 667MB
mysql 5.7 87eca374c0ed 2 weeks ago 447MB
nginx latest 62d49f9bab67 3 weeks ago 133MB
hello-world latest d1165f221234 2 months ago 13.3kB
centos latest 300e315adb2f 4 months ago 209MB
# 务必加上版本号,否则会自动下载最新版运行
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# docker run -d -p 3355:8080 --name tomcat01 tomcat:9.0
fb26f874d72d67ad7210ab9c186d11b5f3f4d3cf4728459f3f5864f70988b0d9
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fb26f874d72d tomcat:9.0 "catalina.sh run" 8 seconds ago Up 7 seconds 0.0.0.0:3355->8080/tcp, :::3355->8080/tcp tomcat01
# 测试
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# curl localhost:3355
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/9.0.45</h3></body></html>
# 发现并没有访问到tomcat的页面,报错404
# 进入容器
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# docker exec -it tomcat01 /bin/bash
root@fb26f874d72d:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work
root@fb26f874d72d:/usr/local/tomcat# cd webapps
root@fb26f874d72d:/usr/local/tomcat/webapps# ls
# 可以发现webapps下什么都没有
# 这是阿里云镜像的原因:默认使用最小镜像,所有不必要的都剔除了,保证最小可运行环境
# 实际上东西都在 webapps.dist里面
root@fb26f874d72d:/usr/local/tomcat/webapps# cd ..
root@fb26f874d72d:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@fb26f874d72d:/usr/local/tomcat# cd webapps
root@fb26f874d72d:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
# Ctrl + P + Q 退出当前容器
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# curl localhost:3355
# 这个时候就可以访问到了

webapps文件的挂载和nginx是一样的。这里我把war包拷贝到docker容器中运行。

1
2
3
4
5
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# docker cp /www/report_pdf/kaoping.war tomcat01:/usr/local/tomcat/webapps
[root@iZ8vbb58nh9e5zf1j0dbg2Z ~]# docker exec -it tomcat01 /bin/bash
root@fb26f874d72d:/usr/local/tomcat# cd webapps
root@fb26f874d72d:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager kaoping kaoping.war manager

部署mysql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker search mysql

# 拉取
docker pull mysql:5.7

# 挂载
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql5.7

-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置 安装启动mysql需要配置密码
--name 容器名字

可视化管理

portainer可视化工具。

下载:

1
docker pull portainer/portainer

启动容器:

1
docker run -d -p 3350:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

第一次运行会要求创建账户密码。

创建完成后如下:

image-20210508172439382

点击 connect就能连上本地仓库。

DockerFile

dockerfile是用来构建docker镜像的文件,命令参数脚本。

很多官方镜像都是基础包,很多功能没有(比如centos没有vim、ipconfig),我们通常会配置环境和软件自己搭建镜像。

image-20210909110000357

常用命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
FROM   # 基础镜像,一切从这里开始构建 centos
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 放入一些文件如一个tomcat压缩包,会自动解压
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOST # 默认端口配置
CMD # 指定容器启动的时候要运行的命令,只有最后一个会生效,可被替代
# CMD 一行只执行一个命令,写多个CMD都会执行
ENTRYPOINTY # 指定容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承DockerFile这个时候就会运行ONBUILD的指令
COPY # 类似ADD命令,将文件拷贝到镜像中
ENV # 构建的时候设置环境变量

构建自己的centos:

1
2
3
4
5
6
7
8
9
10
11
12
13
FROM centos
MAINTAINER xiaoshi<1209001368@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

# RUN yum -y install net-tools

EXPOSE 80
# echo 输出信息
CMD echo $MYPATH
CMD echo "----END----"
CMD /bin/bash

构建命令:

1
2
3
docker build -f dockerfile文件路径 -t 镜像名:[版本号] .

docker build -f mydockerfile -t mycentos:0.1 .
  • **-f :**指定要使用的Dockerfile路径;
  • –tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;
  • 最后的 . 号,指定镜像构建过程中的上下文环境的目录

Docker 在运行时分为 Docker引擎(服务端守护进程) 以及 客户端工具,我们日常使用各种 docker 命令,其实就是在使用客户端工具与 Docker 引擎 进行交互。

那么当我们使用 docker build 命令来构建镜像时,这个构建过程其实是在 Docker引擎 中完成的,而不是在本机环境。

那么如果在 Dockerfile 中使用了一些 COPY 等指令来操作文件,如何让 Docker引擎 获取到这些文件呢?

这里就有了一个镜像构建上下文的概念,当构建的时候,由用户指定构建镜像的上下文路径,而 docker build 会将这个路径下所有的文件都打包上传给 Docker 引擎,引擎内将这些内容展开后,就能获取到所有指定上下文中的文件了。

比如说 dockerfile 中的 COPY ./package.json /project,其实拷贝的并不是本机目录下的 package.json 文件,而是 docker引擎中展开的构建上下文中的文件。

.dockerignore 文件就是忽略某些文件。

查看构建历史:

1
docker history docker镜像名/id

SpringBoot微服务打包镜像

  1. 项目打包jar
  2. 编写dockerfile
  3. 构建镜像
  4. 发布运行

最后交付的就是一个镜像。

1
2
3
4
5
6
7
8
9
FROM java:8

COPY *.jar /app.jar

CMD ["--SERVER.PORT=8080"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]
1
sudo docker run -d -p:8080:8080 --name demo_sqlserver server_demo_sqlserver

如果最后有很多镜像,比如上百个,集群如何管理?

这就要用:

Docker Compase

Docker Swarm

Docker Compose

Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。使用前面介绍的Dockerfile我们很容易定义一个单独的应用容器。然而在日常开发工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器;再比如在分布式应用一般包含若干个服务,每个服务一般都会部署多个实例。如果每个服务都要手动启停,那么效率之低、维护量之大可想而知。这时候就需要一个工具能够管理一组相关联的的应用容器,这就是Docker Compose。

参考:https://baijiahao.baidu.com/s?id=1659023590103934059&wfr=spider&for=pc

安装docker-compose

1
2
apt install docker-compose  //安装命令
docker-compose -v //验证安装

Windows的坑

Windows有一个Docker Desktop桌面版软件,电脑如果安装了VM虚拟机,再安装Docker就会导致VM虚拟机不能用。

参考:https://www.freesion.com/article/6760723270/

image-20220527153440880

我首先是卸载了Docker

之后由于win10家庭教育版没有“Hyper-V”

直接命令行输入:

1
bcdedit /set hypervisorlaunchtype off

解决方案是在windows上安装wsl,在wsl里面通过命令安装docker