安装完Docker后,下面看一下容器的使用。
Docker的安装可以看我之前写的Docker安装:https://blog.csdn.net/flq18210105507/article/details/125671118
如果我们本地没有 nginx 镜像,我们可以使用 docker pull 命令来下载 nginx 镜像:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker pull nginx
以下命令使用 nginx 镜像启动一个容器,参数为以命令行模式进入该容器:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker run -it nginx /bin/bash
参数说明:
-i: 交互式操作。
-t: 终端。
nginx: nginx镜像。
/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
root@87cecc2d65e7:/# exit
查看所有的容器命令如下:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker ps -a
使用 docker start 启动一个已停止的容器:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker start e8b623502b19
在大部分的场景下,我们希望 docker 的服务是在后台运行的,通过 -d 指定容器的运行模式。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker run -itd --name nginx-test nginx /bin/bash
注:加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec(下面会介绍到)。
停止容器的命令如下:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker stop e8b623502b19
停止的容器可以通过 docker restart 重启:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker restart e8b623502b19
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:
docker attach
docker exec:推荐大家使用 docker exec 命令,因为此命令会退出容器终端,但不会导致容器的停止。
attach 命令
下面演示了使用 docker attach 命令。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker attach e8b623502b19
注意: 如果从这个容器退出,会导致容器的停止。
exec 命令
下面演示了使用 docker exec 命令。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker exec -it e8b623502b19 /bin/bash
注意: 如果从这个容器退出,容器不会停止,这就是为什么推荐大家使用 docker exec 的原因。
更多参数说明请使用 docker exec --help 命令查看。
导出容器
如果要导出本地某个容器,可以使用 docker export 命令。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker export e8b623502b19 > nginx.tar
导出容器 e8b623502b19 快照到本地文件 nginx.tar。
这样将导出容器快照到本地文件。
导入容器快照
可以使用 docker import 从容器快照文件中再导入为镜像,以下实例将快照文件 nginx.tar 导入到镜像 test/nginx:v1:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# cat nginx.tar | docker import - test/nginx:v1
删除容器使用 docker rm 命令:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker rm -f e8b623502b19
下面的命令可以清理掉所有处于终止状态的容器。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker container prune
前面我们运行的容器并没有一些什么特别的用处。
接下来让我们尝试使用 docker 构建一个 web 应用程序。
我们将在docker容器中运行一个 Python Flask 应用来运行一个web应用。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker pull training/webapp
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker run -d -P training/webapp python app.py
参数说明:
-d:让容器在后台运行。
-P:将容器内部使用的网络端口随机映射到我们使用的主机上。
使用 docker ps 来查看我们正在运行的容器:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
45c5beeccd16 training/webapp "python app.py" 17 seconds ago Up 16 seconds 0.0.0.0:32768->5000/tcp funny_jones
这里多了端口信息。
PORTS
0.0.0.0:32769->5000/tcp
Docker 将5000端口映射到主机端口 32768 上。
这时我们可以通过浏览器访问WEB应用
我们也可以通过 -p 参数来设置不一样的端口:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker run -d -p 5000:5000 training/webapp python app.py
docker ps查看正在运行的容器
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
787c5678dfc8 training/webapp "python app.py" 20 seconds ago Up 19 seconds 0.0.0.0:5000->5000/tcp mystifying_merkle
容器内部的 5000 端口映射到我们本地主机的 5000 端口上。
通过 docker ps 命令可以查看到容器的端口映射,docker 还提供了另一个快捷方式 docker port,使用 docker port 可以查看指定 (ID 或者名字)容器的某个确定端口映射到宿主机的端口号。
上面我们创建的 web 应用容器 ID 为 787c5678dfc8 名字为 mystifying_merkle。
我可以使用 docker port 787c5678dfc8 或 docker port mystifying_merkle 来查看容器端口的映射情况。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker port 787c5678dfc8
5000/tcp -> 0.0.0.0:5000
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker port mystifying_merkle
5000/tcp -> 0.0.0.0:5000
docker logs [ID或者名字] 可以查看容器内部的标准输出。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker logs -f 787c5678dfc8
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
220.194.188.241 - - [21/Jul/2022 08:22:11] "GET / HTTP/1.1" 200 -
220.194.188.241 - - [21/Jul/2022 08:22:11] "GET /favicon.ico HTTP/1.1" 404 -
220.194.188.241 - - [21/Jul/2022 08:22:13] "GET / HTTP/1.1" 200 -
-f: 让 docker logs 像使用 tail -f 一样来输出容器内部的标准输出。
从上面,我们可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志。
查看WEB应用程序容器的进程
我们还可以使用 docker top 来查看容器内部运行的进程
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker top 787c5678dfc8
UID PID PPID C STIME TTY TIME CMD
root 25096 25080 0 16:17 ? 00:00:00 python app.py
使用 docker inspect 来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker inspect mystifying_merkle
[
{
"Id": "787c5678dfc8a3ed6c86b5495cfdd509be402c8c0aa0af22d8acd707bc670ad1",
"Created": "2022-07-21T08:17:07.055256597Z",
"Path": "python",
"Args": [
"app.py"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 25096,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-07-21T08:17:07.461224215Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
......
停止 WEB 应用容器
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker stop mystifying_merkle
mystifying_merkle
重启WEB应用容器
已经停止的容器,我们可以使用命令 docker start 来启动。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker start mystifying_merkle
mystifying_merkle
docker ps -l 查询最后一次创建的容器:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
787c5678dfc8 training/webapp "python app.py" 9 minutes ago Up 39 seconds 0.0.0.0:5000->5000/tcp mystifying_merkle
正在运行的容器,我们可以使用 docker restart 命令来重启。
我们可以使用 docker rm 命令来删除不需要的容器
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker rm mystifying_merkle
mystifying_merkle
删除容器时,容器必须是停止状态,否则会报如下错误
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker rm mystifying_merkle
Error response from daemon: You cannot remove a running container 787c5678dfc8a3ed6c86b5495cfdd509be402c8c0aa0af22d8acd707bc670ad1. Stop the container before attempting removal or force remove
当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。
我们可以使用 docker images 来列出本地主机上的镜像。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test/nginx v1 bdfca17c58db 44 minutes ago 140MB
nginx latest 605c77e624dd 6 months ago 141MB
各个选项说明:
REPOSITORY:表示镜像的仓库源
TAG:镜像的标签
IMAGE ID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小
同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如 nginx 仓库源里,有 1.15、1.14 等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。
所以,我们如果要使用版本为1.15的nginx系统镜像来运行容器时,命令如下:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker run -t -i nginx:1.15 /bin/bash
Unable to find image 'nginx:1.15' locally
1.15: Pulling from library/nginx
743f2d6c1f65: Pull complete
6bfc4ec4420a: Pull complete
688a776db95f: Pull complete
Digest: sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68
Status: Downloaded newer image for nginx:1.15
root@d00e428195f2:/#
参数说明:
-i: 交互式操作。
-t: 终端。
nginx:1.15: 这是指用 nginx 1.15 版本镜像为基础来启动容器。
/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
如果要使用版本为 1.14 的 nginx 系统镜像来运行容器时,命令如下:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker run -t -i nginx:1.14 /bin/bash
Unable to find image 'nginx:1.14' locally
1.14: Pulling from library/nginx
27833a3ba0a5: Pull complete
0f23e58bd0b7: Pull complete
8ca774778e85: Pull complete
Digest: sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
Status: Downloaded newer image for nginx:1.14
root@a6b9309acc3b:/#
如果你不指定一个镜像的版本标签,例如你只使用 nginx,docker 将默认使用 nginx:latest 镜像。
当我们在本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。如果我们想预先下载这个镜像,我们可以使用 docker pull 命令来下载它。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker pull nginx:1.13
1.13: Pulling from library/nginx
f2aa67a397c4: Pull complete
3c091c23e29d: Pull complete
4a99993b8636: Pull complete
Digest: sha256:b1d09e9718890e6ebbbd2bc319ef1611559e30ce1b6f56b2e3b479d9da51dc35
Status: Downloaded newer image for nginx:1.13
docker.io/library/nginx:1.13
下载完成后,我们可以直接使用这个镜像来运行容器。
我们可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/
我们也可以使用 docker search 命令来搜索镜像。比如我们需要一个 httpd 的镜像来作为我们的 web 服务。我们可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker search httpd
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
httpd The Apache HTTP Server Project 4090 [OK]
centos/httpd-24-centos7 Platform for running Apache httpd 2.4 or bui… 44
centos/httpd 35 [OK]
solsson/httpd-openidc mod_auth_openidc on official httpd image, ve… 2 [OK]
clearlinux/httpd httpd HyperText Transfer Protocol (HTTP) ser… 2
hypoport/httpd-cgi httpd-cgi 2 [OK]
nnasaki/httpd-ssi SSI enabled Apache 2.4 on Alpine Linux 1
dockerpinata/httpd 1
jonathanheilmann/httpd-alpine-rewrite httpd:alpine with enabled mod_rewrite 1 [OK]
inanimate/httpd-ssl A play container with httpd, ssl enabled, an… 1 [OK]
centos/httpd-24-centos8 1
dariko/httpd-rproxy-ldap Apache httpd reverse proxy with LDAP authent… 1 [OK]
manageiq/httpd Container with httpd, built on CentOS for Ma… 1 [OK]
publici/httpd httpd:latest 1 [OK]
httpdocker/kubia 0
patrickha/httpd-err 0
e2eteam/httpd 0
amd64/httpd The Apache HTTP Server Project 0
manageiq/httpd_configmap_generator Httpd Configmap Generator 0 [OK]
manasip/httpd 0
ppc64le/httpd The Apache HTTP Server Project 0
httpdss/archerysec ArcherySec repository 0 [OK]
paketobuildpacks/httpd 0
19022021/httpd-connection_test This httpd image will test the connectivity … 0
sandeep1988/httpd-new httpd-new
NAME: 镜像仓库源的名称
DESCRIPTION: 镜像的描述
STARS: 类似 Github 里面的 star,表示点赞、喜欢的意思。
OFFICIAL: 是否 docker 官方发布
AUTOMATED: 自动构建。
我们决定使用上图中的 httpd 官方版本的镜像,使用命令 docker pull 来下载镜像。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker pull httpd
Using default tag: latest
latest: Pulling from library/httpd
a2abf6c4d29d: Already exists
dcc4698797c8: Pull complete
41c22baa66ec: Pull complete
67283bbdd4a0: Pull complete
d982c879c57e: Pull complete
Digest: sha256:0954cc1af252d824860b2c5dc0a10720af2b7a3d3435581ca788dff8480c7b32
Status: Downloaded newer image for httpd:latest
docker.io/library/httpd:latest
下载完成后,我们就可以使用这个镜像了。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker run httpd
镜像删除使用 docker rmi 命令,比如我们删除 hello-world 镜像:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker rmi httpd
当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。
1、从已经创建的容器中更新镜像,并且提交这个镜像
2、使用 Dockerfile 指令来创建一个新的镜像
更新镜像之前,我们需要使用镜像来创建一个容器。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker run -t -i nginx:1.15 /bin/bash
root@82f15384b3b0:/#
在运行的容器内使用 apt-get update 命令进行更新。
在完成操作之后,输入 exit 命令来退出这个容器。
此时 ID 为 82f15384b3b0 的容器,是按我们的需求更改的容器。我们可以通过命令 docker commit 来提交容器副本。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker commit -m="update nginx" -a="test" 82f15384b3b0 nginx/nginx:v2
sha256:a89a4ca6aa0ea392da40f71a09c1728c629aed12998665b9b23a1a612d05c623
各个参数说明:
-m: 提交的描述信息
-a: 指定镜像作者
82f15384b3b0 :容器 ID
nginx/nginx:v2: 指定要创建的目标镜像名
我们可以使用 docker images 命令来查看我们的新镜像 nginx/nginx:v2:
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx/nginx v2 a89a4ca6aa0e 55 seconds ago 109MB
test/nginx v1 bdfca17c58db About an hour ago 140MB
nginx latest 605c77e624dd 6 months ago 141MB
httpd latest dabbfbe0c57b 7 months ago 144MB
使用我们的新镜像 nginx/nginx 来启动一个容器
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker run -t -i nginx/nginx:v2
root@473ff9f833ef:/#
我们使用命令 docker build , 从零开始来创建一个新的镜像。为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# cat Dockerfile
FROM centos
MAINTAINER "[email protected]"
RUN /bin/echo 'root:123' |chpasswd
RUN useradd Lqjun
RUN /bin/echo 'Lqjun:123' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
第一条FROM,指定使用哪个镜像源
RUN 指令告诉docker 在镜像内执行命令,安装了什么。。。
然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker build -t centos/centos .
Sending build context to Docker daemon 2.092GB
Step 1/9 : FROM centos
---> 5d0da3dc9764
Step 2/9 : MAINTAINER "[email protected]"
---> Using cache
---> 031f13b7b2c7
Step 3/9 : RUN /bin/echo 'root:123' |chpasswd
---> Using cache
---> ea978571432c
Step 4/9 : RUN useradd Lqjun
---> Running in a04671812bb6
Removing intermediate container a04671812bb6
---> f8840e297883
Step 5/9 : RUN /bin/echo 'Lqjun:123' |chpasswd
---> Running in 0ddbbaf12963
Removing intermediate container 0ddbbaf12963
---> 3bbaa81be1c0
Step 6/9 : RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
---> Running in 3a171c253604
Removing intermediate container 3a171c253604
---> a0aa1d2a332b
Step 7/9 : EXPOSE 22
---> Running in 3cdb33d05335
Removing intermediate container 3cdb33d05335
---> bb20c29a928b
Step 8/9 : EXPOSE 80
---> Running in 76bcd1aa2ed3
Removing intermediate container 76bcd1aa2ed3
---> 337391af0dec
Step 9/9 : CMD /usr/sbin/sshd -D
---> Running in a4b36285702e
Removing intermediate container a4b36285702e
---> f5157bd50271
Successfully built f5157bd50271
Successfully tagged centos/centos:latest
参数说明:
-t :指定要创建的目标镜像名
. :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
使用docker images 查看创建的镜像已经在列表中存在,镜像ID为f5157bd50271
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos/centos latest f5157bd50271 2 minutes ago 232MB
我们可以使用新的镜像来创建容器
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker run -t -i centos/centos /bin/bash
[root@26cb9acec436 /]# id Lqjun
uid=1000(Lqjun) gid=1000(Lqjun) groups=1000(Lqjun)
从上面看到新镜像已经包含我们创建的用户 Lqjun。
我们可以使用 docker tag 命令,为镜像添加一个新的标签。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker tag f5157bd50271 centos/centos:test
docker tag 镜像ID,这里是 f5157bd50271 ,用户名称、镜像源名(repository name)和新的标签名(tag)。
使用 docker images 命令可以看到,ID为 f5157bd50271 的镜像多一个标签。
[root@iz2ze2a63q9mc2ltw33zu4z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos/centos latest f5157bd50271 6 minutes ago 232MB
centos/centos test f5157bd50271 6 minutes ago 232MB