Docker 新手向导

news2024/12/23 10:53:30

博文目录

文章目录

  • 新手向导 (Get Started)
    • 应用程序容器化
      • 下载应用代码
      • 容器化该应用
        • 配置镜像加速器
      • 启动这个应用容器
    • 更新应用程序
    • 共享应用程序
      • 推送镜像
      • Play with Docker
      • 使用镜像
    • 持久化数据库
      • 容器的文件系统
      • 容器卷 (Container volumes)
      • 保留所有数据
      • 深入卷
    • 使用绑定装载
      • 快速卷类型比较
      • 尝试绑定装载
      • 开发容器
        • 在开发容器中运行应用程序
        • 使用开发容器开发应用程序
    • 多容器应用程序
      • 容器网络
        • 启动 MySQL
        • 连接到 MySQL
        • 使用 MySQL 运行应用程序
    • 使用 Docker Compose
      • 安装 Docker Compose
  • 常用命令
    • 帮助命令
    • 镜像命令
      • docker images
      • docker search
      • docker pull
      • docker rmi
    • 容器命令
      • docker run 创建容器
      • docker ps 列出容器
      • docker rm 删除容器
      • 启动和停止容器
      • 其他常用命令
        • 后台启动
        • docker logs 查看日志
        • docker top 查看容器中的进程信息
        • docker inspect 查看容器的元数据
        • 进入当前运行的容器


docker入门,这一篇就够了。

新手向导 (Get Started)

官方文档 Get Started

本向导中的试验部分需要一台Linux主机, 可以是云服务器, 也可以是虚拟机, 需安装 Docker 环境

应用程序容器化

本节里, 我们会容器化一个简单的 Web Node.js 应用 Todo, 它的主要功能就是管理一些要做的事项, 可以添加/删除事项, 可以标记事项已完成. 这个示例并不需要我们熟悉 Node.js 和 JavaScript, 仅仅是展示下构建镜像运行镜像的流程

下载应用代码

如果Linux服务器上安装了Git, 那可以直接运行 git clone https://github.com/docker/getting-started.git 克隆项目代码, 也可以在Windows上克隆代码, 再通过FTP工具传到服务器

容器化该应用

要构建镜像, 需要使用 Dockerfile, 这是一个文本文件, 没有扩展名

通过 cd getting-started/app 进入 app 目录, 目录中有 package.json 和 spec 与 src 两个目录, 通过 touch Dockerfile 新建一个 Dockerfile, 使用 vim 或 文本编辑器 把下面的内容写入到 Dockerfile 中

# syntax=docker/dockerfile:1
   
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
EXPOSE 3000

然后通过 docker build -t getting-started . 命令构建镜像

docker build 命令使用Dockerfile来构建一个新的镜像。你可能已经注意到Docker下载了很多“层”。这是因为您指示生成器要从 node:18-alpine 节点开始。但是,由于你的机器上没有,Docker会自动下载这些镜像。

Docker下载镜像后,Dockerfile中的指令会复制到您的应用程序中,并使用yarn安装应用程序的依赖项。CMD指令指定从此映像启动容器时要运行的默认命令。

最后,-t 选项用于标记您的镜像。可以简单地认为是指定最终镜像的名称。由于您在开始时命名了该镜像,因此在运行容器时可以引用该镜像。

这个 `.` 在docker构建命令的末尾,告诉docker它应该在当前目录中查找Dockerfile。

构建成功后, 执行 docker images 即可看到该镜像

REPOSITORY        TAG       IMAGE ID       CREATED       SIZE
getting-started   latest    ed1ef9e8de78   About a minute ago   265MB

配置镜像加速器

运行构建命令很有可能会失败, 大概率是网络问题, 可以配置一下国内的镜像加速器, 建议多配几家, 我一开始只配了个阿里的, 结果构建直报错, 后来又加了腾讯的和其他的, 这才最终成功, 但中途也失败了几次, 所以, 构建失败可以多执行几次, 有概率成功

阿里云 Docker 镜像加速器

当你下载安装的 Docker 版本不低于1.10时,建议直接通过daemon config进行配置。使用配置文件 /etc/docker/daemon.json(没有时新建该文件),然后通过 systemctl restart docker 重启 Docker 即可

{
  "registry-mirrors": ["https://whvuvvy4.mirror.aliyuncs.com"]
}

启动这个应用容器

镜像已经构建好了, 通过 docker run -dp 3000:3000 --name getting-started getting-started:1.0.0 命令来创建并启动该镜像的一个容器, -d 是指定容器在后台运行, -p 用来绑定服务器端口和容器内端口的映射关系, 如果没有绑定这个端口印射, 我们没有办法访问容器内的应用程序

执行 docker ps 就可以看到正在运行的容器了

在浏览器打开 http://localhost:3000 就可以看到我们的 “Todo” 应用了

在这里插入图片描述
在这里插入图片描述

更新应用程序

本节我们修改一些应用的代码, 然后将其重新构建为镜像, 并重新运行容器

修改 src/static/js/app.js 中第56行的 No items yet! Add one above!You have no todo items yet! Add one above!

使用 docker build -t getting-started 命令来重新构建该镜像的新版本

REPOSITORY        TAG       IMAGE ID       CREATED       SIZE
getting-started   latest    b5a67802db59   About a minute ago   265MB
<none>            <none>    ed1ef9e8de78   15 minutes ago       265MB

使用 docker run -dp 3000:3000 --name getting-started getting-started:1.1.0 来启动新容器, 结果会报错, 新容器无法启动, 因为旧容器运行时占用了主机的3000端口, 只有停止旧容器才可以运行新容器

可以使用 docker ps 查看容器 ID, 使用 docker stop <the-container-id> 停止容器, 使用 docker rm <the-container-id> 删除容器, 也可以使用 docker rm -f <the-container-id> 直接停止并删除容器

再次使用 docker run -dp 3000:3000 --name getting-started getting-started:1.1.0 来启动新容器, 刷新浏览器可以看到文本内容已经变化

在这里插入图片描述

共享应用程序

要想共享镜像, 需要使用到镜像仓库, 默认的全球仓库是 Docker Hub

注册并登录 Docker Hub, 创建一个仓库, 名称使用 getting-started, 可见性选 Public, 我的该仓库推送镜像的命令是 docker push mrathena/getting-started:tagname, 其中 mrathena 是 Namespace, 也就是我的账号 ID, getting-started 是仓库名称, 一个仓库只能存同名镜像的不同版本

推送镜像

执行 docker push mrathena/getting-started 报本地不存在 Tag 为 mrathena/getting-started 的镜像, 我们得 tag 本地已有的镜像并为其命名

执行 docker login -u mrathena 在命令行里登录 Docker Hub

通过执行 docker tag getting-started mrathena/getting-started, 给 getting-started 镜像一个新的名字 mrathena/getting-started, 如果新名称后面不追加 :tagname 部分, 则默认是 latest

REPOSITORY                 TAG       IMAGE ID       CREATED          SIZE
getting-started            latest    b5a67802db59   15 minutes ago   265MB
mrathena/getting-started   latest    b5a67802db59   15 minutes ago   265MB
<none>                     <none>    ed1ef9e8de78   29 minutes ago   265MB

再次推送, 发现推送成功了

Play with Docker

我们在自己的主机上推送镜像, 速度慢的简直无法忍受, Docker 提供了一个免费的工具 Play with Docker , 我们可以使用该工具来做我们主机能做的所有事情, 该工具连接着真正的互联网, 网速非常快, 体验相当不错

使用镜像

在另一台装有 Docker 环境的主机上, 即可下载并启动刚刚推送的镜像, 使用 Play with Docker 来完成这个测试

浏览器打开 Play with Docker, 关联到我们的 Docker Hub 账户, 点击 Start, 再点击 ADD NEW INSTANCE, 开始使用真正的 Docker 环境

执行 docker run -dp 0.0.0.0:3000:3000 mrathena/getting-started 即可自动下载并运行一个新的容器

在这里插入图片描述
在这里插入图片描述

持久化数据库

前面的例子里, 当我们重启容器后, 先前添加的项目就全丢失了, 本节我们将深入了解容器是如何工作的

容器的文件系统

当容器运行时,它使用镜像中的各个层作为其文件系统。每个容器也有自己的“暂存空间”来创建/更新/删除文件。即使使用的是相同的镜像,在另一个容器中也看不到当前容器中的任何更改。

容器卷 (Container volumes)

卷提供了将容器的特定文件系统路径连接回主机的能力。就是把主机的某个路径印射了到容器中的某个路径, 在容器或主机中操作文件等同于在另一方操作文件。如果在容器重新启动时装载相同的目录,则会看到相同的文件。

保留所有数据

默认情况下,Todo 应用程序将其数据存储在容器文件系统中 /etc/todos/todo.db 的 SQLite 数据库中。我们只要创建一个卷将 /etc/todos 目录印射到主机的某个目录, 其内的 todo.db 就可以保存在主机的文件系统中, 这样重启容器数据也不会丢失

我们应该将卷装载视为不透明的数据桶。由Docker完全管理卷,包括磁盘上的存储位置。我们只需要记住卷的名称。

执行 docker volume create todo-db 创建了一个卷, 执行 docker rm -f <id> 删除正在运行的容器, 执行 docker run -dp 3000:3000 --mount type=volume,src=todo-db,target=/etc/todos getting-started 启动 Todo 应用程序容器,添加 --mount 选项以指定卷装载。为卷指定一个名称,并将其装载到容器中的 ‘/etc/todos’,该容器将捕获在该路径上创建的所有文件。

执行 docker rm -f <id> 删除当前容器, 执行 docker run -dp 3000:3000 --mount type=volume,src=todo-db,target=/etc/todos getting-started 创建并启动一个新的容器, 刷新浏览器, 之前添加的数据项应该没有丢失

深入卷

执行 docker volume inspect todo-db 即可查看卷的详细信息

[
    {
        "CreatedAt": "2023-06-19T14:19:01+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
        "Name": "todo-db",
        "Options": null,
        "Scope": "local"
    }
]

也可以通过 docker inspect <id> 来查看容器信息, 其中 Mounts 不分就是装载的卷的信息

"Mounts": [
    {
        "Type": "volume",
        "Name": "todo-db",
        "Source": "/var/lib/docker/volumes/todo-db/_data",
        "Destination": "/etc/todos",
        "Driver": "local",
        "Mode": "z",
        "RW": true,
        "Propagation": ""
    }
],

使用绑定装载

在上节中, 我们使用了卷装载来将数据持久化到数据库中。当您需要一个持久的地方来存储应用程序数据时,卷装载是一个不错的选择。

绑定装载是另一种类型的装载,它允许您将主机文件系统中的目录共享到容器中。在处理应用程序时,可以使用绑定装载将源代码装载到容器中。保存文件后,容器会立即看到您对代码所做的更改。这意味着您可以在容器中运行进程来监视文件系统更改并对其作出响应。(感觉类似CI/CD的提交代码自动部署功能)

在本节中, 我们将使用绑定装载和名为nodemon的工具来监视文件更改,然后自动重新启动应用程序

快速卷类型比较

下表概述了卷装载和绑定装载之间的主要区别。除了卷装载和绑定装载外,Docker还支持其他装载类型和存储驱动程序,以处理更复杂、更专业的用例。要了解有关高级存储概念的更多信息,请参阅Docker中的 Manage data in Docker。

Named volumesBind mounts
印射到主机的位置Docker 选择你决定
Mount 示例 (使用 --mount)type=volume,src=my-volume,target=/usr/local/datatype=bind,src=/path/to/data,target=/usr/local/data
Populates new volume with container contentsYesNo
支持卷驱动YesNo

尝试绑定装载

执行 cd getting-started/app

执行 docker run -it --mount type=bind,src="$(pwd)",target=/src ubuntu bash, Docker在容器文件系统的根目录中启动一个交互式bash会话。

在带有绑定挂载的ubuntu容器中启动bash, --mount 选项告诉Docker创建一个绑定挂载,其中src是主机上的当前工作目录getting-started/app,target是该目录应该出现在容器中的位置(/src)。

此时我们已经进入了容器, 执行 ls 可以查看容器的目录, 执行 cd src, 执行 ls, 发现 src 目录下内容与主机 getting-started/app 目录完全一致, 在容器内创建文件, 在主机也能看到, 两个路径已经印射起来了, 使用 Ctrl+D 快捷键可以退出容器的交互式会话

开发容器

在本地开发设置中,使用绑定挂载是很常见的。其优点是开发机器不需要安装所有的构建工具和环境。通过一个docker run命令,docker可以提取依赖项和工具。

这里用 getting-started 来演示实际开发过程中, 实时查看修改的内容

在开发容器中运行应用程序

以下步骤描述了如何使用执行以下操作的绑定装载来运行开发容器:

  • 将源代码装入容器
  • 安装所有依赖项
  • 启动 nodemon 以监视文件系统更改

通过以下步骤运行带有绑定装载的容器。

  • 确保没有 getting-started 容器在运行
  • 在 getting-started/app 目录运行以下命令
    docker run -dp 3000:3000 \
    -w /app --mount type=bind,src="$(pwd)",target=/app \
    node:18-alpine \
    sh -c "yarn install && yarn run dev"
    

以下是部分解释

  • -w /app, 设置“工作目录”或命令将从当前目录运行
  • –mount type=bind,src=“$(pwd)”,target=/app, 将当前目录从主机装入容器中的/app目录
  • node:18-alpine, 要使用的镜像。请注意,这是Dockerfile中应用程序的基本镜像
  • sh -c “yarn install && yarn run dev”, 使用sh(alpine没有bash)启动一个shell,运行yarn install来安装包,然后运行yarn run dev来启动开发服务器。如果您查看package.json内容,您将看到dev脚本启动nodemon。

执行 docker logs <container-id> 查看容器日志, 类似如下时, 说明好了

yarn install v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
Done in 20.24s.
yarn run v1.22.19
$ nodemon src/index.js
[nodemon] 2.0.20
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node src/index.js`
Using sqlite database at /etc/todos/todo.db
Listening on port 3000

使用开发容器开发应用程序

在主机上更新应用程序,并查看容器中反映的变化。

  • 在 src/static/js/app.js 文件的第109行,将“Add Item”按钮更改为简单的“Add”:
  • 刷新浏览器, 几乎实时变化, 而 Node Server 可能需要几秒钟的时间才能重新启动
  • 可以随意进行其他更改。每次进行更改并保存文件时,nodemon 进程都会自动重新启动容器中的应用程序。全部完成后,停止容器并执行 docker build -t getting-started . 可构建新镜像

多容器应用程序

通常,每个容器都应该只做一件事并做好它。即应用运行在一个容器中, 数据库运行在另一个容器中

在这里插入图片描述

容器网络

默认情况下,容器是孤立运行的,对同一台机器上的其他进程或容器一无所知。那么,如何允许一个容器与另一个容器进行通信呢?答案是建立网络。如果你把两个容器放在同一个网络上,它们可以相互通信。

启动 MySQL

在网络上放置容器有两种方法:

  • 启动容器时分配网络。
  • 将已运行的容器连接到网络。

在以下步骤中,我们将首先创建网络,然后在启动时附加MySQL容器。

执行 docker network create todo-app 创建一个网络

执行如下命令, 启动一个 MySQL 容器并将其连接到网络。我们还将定义一些环境变量,数据库将使用这些变量来初始化数据库。要了解有关MySQL环境变量的更多信息,参考 MySQL Docker Hub listing 列表中的“Environment Variables”部分。

docker run -d \
     --network todo-app --network-alias mysql \
     -v todo-mysql-data:/var/lib/mysql \
     -e MYSQL_ROOT_PASSWORD=secret \
     -e MYSQL_DATABASE=todos \
     mysql:8.0

在上面的命令中,有一个名为 todo-mysql-data 的卷,它安装在 /var/lib/mysql 中,这是MySQL存储数据的地方。但是,我们从未运行过 docker volume create 命令。Docker识别出您]我们想要使用一个命名卷,并自动创建了一个。

通过 --network 指定使用 todo-app 网络, 通过 --network-alias 给容器的网络起了个别名为 mysql

若要确认数据库已启动并运行,需要连接到数据库来确认

docker exec -it <mysql-container-id> mysql -u root -p

出现密码提示时,键入 secret, 执行 SHOW DATABASES;, 执行 exit 退出容器, 至此, MySQL 容器就好了

连接到 MySQL

每个容器都有自己的IP地址。

为了更好地理解容器网络,我们先用一用 nicolaka/netshoot 容器,该容器附带了许多工具,这些工具对解决或调试网络问题非常有用。

执行 docker run -it --network todo-app nicolaka/netshoot 下载并启用该容器, 确保该容器和 MySQL 容器在同一个网络上

在该容器中,我们将使用 dig 命令,这是一个有用的DNS工具。您将查找主机名mysql的IP地址。

执行 dig mysql 得到如下的响应

; <<>> DiG 9.16.22 <<>> mysql
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6853
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;mysql.				IN	A

;; ANSWER SECTION:
mysql.			600	IN	A	172.18.0.2

;; Query time: 1 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Mon Jun 19 07:45:21 UTC 2023
;; MSG SIZE  rcvd: 44

在“ANSWER SECTION (应答部分)”中,我们看到mysql的一条A记录,解析为172.18.0.2(您的IP地址很可能有不同的值)。虽然mysql通常不是一个有效的主机名,但Docker能够将其解析为具有该网络别名的容器的IP地址。我们之前使用了 --network-alias。

这意味着你的应用程序只需要连接到一个名为 mysql 的主机,它就会与数据库对话。

使用 MySQL 运行应用程序

Todo 应用程序支持设置一些环境变量来指定MySQL连接设置。它们是:

  • MYSQL_HOST: 运行 MySQL Server 的主机的 hostname
  • MYSQL_USER: 用户名
  • MYSQL_PASSWORD: 密码
  • MYSQL_DB: 数据库名

在 getting-started/app 路径下执行如下命令

docker run -dp 3000:3000 \
   -w /app -v "$(pwd):/app" \
   --network todo-app \
   -e MYSQL_HOST=mysql \
   -e MYSQL_USER=root \
   -e MYSQL_PASSWORD=secret \
   -e MYSQL_DB=todos \
   node:18-alpine \
   sh -c "yarn install && yarn run dev"

执行 docker logs <container-id> 查看容器的日志,会看到类似于下面的消息,这表明它正在使用mysql数据库。

yarn install v1.22.19
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.41s.
yarn run v1.22.19
$ nodemon src/index.js
[nodemon] 2.0.20
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node src/index.js`
Waiting for mysql:3306.
Connected!
Connected to mysql db at host mysql
Listening on port 3000

刷新浏览器, 并添加一些新的项目

执行 docker exec -it <mysql-container-id> mysql -p todos 连接到 MySQL 查看数据

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| todos              |
+--------------------+
5 rows in set (0.00 sec)

mysql> 
mysql> use todos;
Database changed
mysql> 
mysql> select * from todo_items;
+--------------------------------------+------+-----------+
| id                                   | name | completed |
+--------------------------------------+------+-----------+
| 7d57e3e3-c01e-43e1-b34a-28efa4022e0d | 111  |         0 |
| bc071de0-77d5-486f-8fb6-c9b9172ded6a | 222  |         1 |
| 29037f15-20ed-4120-8f59-bbe260d57c0e | 333  |         0 |
+--------------------------------------+------+-----------+
3 rows in set (0.00 sec)

使用 Docker Compose

Docker Compose 是一个旨在帮助定义和共享多容器应用程序的工具。使用Compose,使用Compose,我们可以创建一个YAML文件来定义服务,并使用一个命令将所有服务启动或关闭。

使用Compose的一个重要优势是,您可以在一个文件中定义应用程序堆栈,将其保留在项目存储库的根目录下(现在已进行版本控制),并轻松地让他人贡献到您的项目中。其他人只需要克隆您的存储库并启动Compose应用程序即可。实际上,在GitHub / GitLab上可能会看到现在有很多项目都在使用这种方法。

安装 Docker Compose

常用命令

Docker 官网文档 命令

systemctl start docker
systemctl stop docker
systemctl restart docker

docker search nginx # 检索 Nginx
docker pull nginx # 下载最新标签的 Nginx
docker images # 列出本地镜像
docker run -d --name nginx -p 80:80 nginx # 以后台模式运行 Nginx 镜像, 指定名称为 nginx, 指定端口印射 物理端口:容器端口=81:80, 容器内 nginx 默认运行在 80 端口, 指定通过物理机 81 端口访问容器的 80 端口
docker ps # 列出运行容器
docker ps -a # 列出全部容器
docker exec -it 容器id/name /bin/bash # 进入运行中的容器, -it:交互方式进入容器; 容器id只需要前几位能和其他容器区分开即可, 其他地方同样适用
exit # 退出容器
docker stop 容器id/name # 停止容器
docker rm 容器id # 删除容器
docker rm -f nginx # 删除镜像

docker commit -a mrathena -m test-commit nginx mrathena/nginx:20230616 # 将当前的容器(name:nginx)做成镜像, REPOSITORY:mrathena/nginx, TAG:20230616

帮助命令

docker version # 版本信息
docker info # 系统信息, 包括镜像和容器的数量等
docker 命令 --help

镜像命令

docker images

docker images [OPTIONS] [REPOSITORY[:TAG]]

[root@mrathena yum.repos.d]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    feb5d9fea6a5   5 months ago   13.3kB

# REPOSITORY: 镜像的仓库源
# TAG:        镜像的标签(版本)
# IMAGE ID:   镜像的id
# CREATED:    镜像的创建时间
# SIZE:       镜像的大小

# 可选项
-a, --all 		# 列出所有镜像
-q, --quiet		# 只显示镜像id

docker search

docker search [OPTIONS] TERM

[root@mrathena yum.repos.d]# docker search mysql
NAME                             DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                            MySQL is a widely used, open-source relation…   12216     [OK]       
mariadb                          MariaDB Server is a high performing open sou…   4689      [OK]       
mysql/mysql-server               Optimized MySQL Server Docker images. Create…   907                  [OK]
percona                          Percona Server is a fork of the MySQL relati…   570       [OK]       
phpmyadmin                       phpMyAdmin - A web interface for MySQL and M…   465       [OK]       
mysql/mysql-cluster              Experimental MySQL Cluster Docker images. Cr…   93                   
centos/mysql-57-centos7          MySQL 5.7 SQL database server                   92                   
bitnami/mysql                    Bitnami MySQL Docker Image                      64                   [OK]
circleci/mysql                   MySQL is a widely used, open-source relation…   25                   
ubuntu/mysql                     MySQL open source fast, stable, multi-thread…   24                   
mysql/mysql-router               MySQL Router provides transparent routing be…   23                   
arey/mysql-client                Run a MySQL client from a docker container      20                   [OK]
google/mysql                     MySQL server for Google Compute Engine          19                   [OK]
mysqlboy/docker-mydumper         docker-mydumper containerizes MySQL logical …   3                    
mysqlboy/mydumper                mydumper for mysql logcial backups              3                    
bitnami/mysqld-exporter                                                          2                    
ibmcom/mysql-s390x               Docker image for mysql-s390x                    1                    
mysqlboy/percona-server          Percona-Server a MySQL Fork with enhancement…   1                    [OK]
mirantis/mysql                                                                   0                    
mysqlboy/elasticsearch                                                           0                    
mysqleatmydata/mysql-eatmydata                                                   0                    
mysql/mysql-operator             MySQL Operator for Kubernetes                   0                    
mysql/ndb-operator               MySQL NDB Operator for Kubernetes               0                    
cimg/mysql                                                                       0                    
ibmcom/tidb-ppc64le              TiDB is a distributed NewSQL database compat…   0 

[root@mrathena yum.repos.d]# docker search mysql --filter=STARS=9999
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   12216     [OK]  

docker pull

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

[root@mrathena yum.repos.d]# docker pull mysql
Using default tag: latest # 不写TAG默认就是 latest 最新的
latest: Pulling from library/mysql
72a69066d2fe: Pull complete # 分层下载, docker image 核心, 联合文件系统
93619dbc5b36: Pull complete 
99da31dd6142: Pull complete 
626033c43d70: Pull complete 
37d5d7efb64e: Pull complete 
ac563158d721: Pull complete 
d2ba16033dad: Pull complete 
688ba7d5c01a: Pull complete 
00e060b6d11d: Pull complete 
1c04857f594f: Pull complete 
4d7cfa90e6ea: Pull complete 
e0431212d27d: Pull complete 
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709 # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址

[root@mrathena yum.repos.d]# docker pull mysql:5.7
5.7: Pulling from library/mysql
72a69066d2fe: Already exists # 可以直接利用已经存在的部分文件
93619dbc5b36: Already exists 
99da31dd6142: Already exists 
626033c43d70: Already exists 
37d5d7efb64e: Already exists 
ac563158d721: Already exists 
d2ba16033dad: Already exists 
0ceb82207cd7: Pull complete 
37f2405cae96: Pull complete 
e2482e017e53: Pull complete 
70deed891d42: Pull complete 
Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

docker rmi

docker rmi [OPTIONS] IMAGE [IMAGE…]

# 删除指定容器
docker rmi -f 容器id
# 删除多个容器
docker rmi -f 容器id 容器id 容器id
# 删除全部容器, 参数替换, 拿 $() 执行结果作为参数来删除
docker rmi -f $(docker images -aq)

容器命令

有镜像才可以创建容器, 下载一个linux镜像来学习测试

docker pull centos

docker run 创建容器

docker run [OPTIONS] IMAGE [COMMAND] [ARG…]

# 参数说明
--name="name" 			# 容器名字 用来区分容器
-d						# 后台方式运行
-it						# 使用交互方式运行, 方便我们进入容器查看内容
-p						# 指定容器端口, -p:80:8080
	-p ip:主机端口:容器端口
	-p 主机端口:容器端口 (最常用)
	-p 容器端口
	容器端口
-P						# 随机端口

# 测试, 启动并进入容器, 主机名发生变化
[root@mrathena yum.repos.d]# docker run -it centos /bin/bash
[root@434d27e6adde /]# 

# 查看容器内容
[root@434d27e6adde /]# ls  
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

# 退出
exit 			# 停止容器并退出
Ctrl + P + Q 	# 不停止容器推出

docker ps 列出容器

docker ps [OPTIONS]

[root@mrathena yum.repos.d]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

[root@mrathena yum.repos.d]# docker ps -a
CONTAINER ID   IMAGE         COMMAND       CREATED             STATUS                            PORTS     NAMES
434d27e6adde   centos        "/bin/bash"   3 minutes ago       Exited (127) About a minute ago             intelligent_cohen
2966bf3f4cbd   hello-world   "/hello"      About an hour ago   Exited (0) About an hour ago                determined_blackwell

# 参数说明
		# 列出当前正在运行的容器
-a		# 列出当前正在运行的容器 + 历史运行的容器
-n=?	# 列出最近创建的几个容器
-q		# 只显示容器的编号

docker rm 删除容器

docker rm 容器id					# 删除指定容器, 不能删除正在运行的容器, 强制删除 rm -rf
docker rm -f $(docker ps -aq)
docker ps -a -q | xargs docker rm

启动和停止容器

docker start 容器id
docker restart 容器id
docker stop 容器id		# 停止运行的容器
docker kill 容器id		# 强制停止运行的容器

其他常用命令

后台启动

# 后台启动
docker run -d centos
# 通过 docker ps 发现 centos 停止了, 常见的坑, docker 容器使用后台运行时要求必须有一个前台进程, 如果docker发现容器中没有应用在运行就会自动停止

docker logs 查看日志

docker logs --help
docker logs -ft --tail 10 afd77ec4f3a8
# 自己写个shell脚本
"while true; do echo hello; sleep 1; done"

[root@mrathena yum.repos.d]# docker run -d centos /bin/sh -c "while true; do echo hello; sleep 1; done"
a0dc75d7d93a5269604695f20655057e387412ab663722bd3486d5802ec7b818

[root@mrathena yum.repos.d]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
a0dc75d7d93a   centos    "/bin/sh -c 'while t…"   3 seconds ago   Up 3 seconds             serene_cannon
[root@mrathena yum.repos.d]# docker logs -ft --tail 10 a0dc75d7d93a
2022-03-06T17:36:55.221020791Z hello
2022-03-06T17:36:56.222716774Z hello
2022-03-06T17:36:57.226031883Z hello

docker top 查看容器中的进程信息

[root@mrathena yum.repos.d]# docker top a0dc75d7d93a
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                4705                4686                0                   01:36               ?                   00:00:00            /bin/sh -c while true; do echo hello; sleep 1; done
root                4958                4705                0                   01:40               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1

docker inspect 查看容器的元数据

[root@mrathena yum.repos.d]# docker inspect a0dc75d7d93a
[
    {
        "Id": "a0dc75d7d93a5269604695f20655057e387412ab663722bd3486d5802ec7b818",
        "Created": "2022-03-06T17:36:47.00014358Z",
        "Path": "/bin/sh",
        "Args": [
            "-c",
            "while true; do echo hello; sleep 1; done"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 4705,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-03-06T17:36:47.202311706Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
        "ResolvConfPath": "/var/lib/docker/containers/a0dc75d7d93a5269604695f20655057e387412ab663722bd3486d5802ec7b818/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/a0dc75d7d93a5269604695f20655057e387412ab663722bd3486d5802ec7b818/hostname",
        "HostsPath": "/var/lib/docker/containers/a0dc75d7d93a5269604695f20655057e387412ab663722bd3486d5802ec7b818/hosts",
        "LogPath": "/var/lib/docker/containers/a0dc75d7d93a5269604695f20655057e387412ab663722bd3486d5802ec7b818/a0dc75d7d93a5269604695f20655057e387412ab663722bd3486d5802ec7b818-json.log",
        "Name": "/serene_cannon",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/4a44aee72d0f2c025fdbebf35b47c87a31f48ecc342db821d20642320772e783-init/diff:/var/lib/docker/overlay2/f06b910a8a08366072e81f2eadf81bb94b9500bfd791b204dbfe80ce01ebd210/diff",
                "MergedDir": "/var/lib/docker/overlay2/4a44aee72d0f2c025fdbebf35b47c87a31f48ecc342db821d20642320772e783/merged",
                "UpperDir": "/var/lib/docker/overlay2/4a44aee72d0f2c025fdbebf35b47c87a31f48ecc342db821d20642320772e783/diff",
                "WorkDir": "/var/lib/docker/overlay2/4a44aee72d0f2c025fdbebf35b47c87a31f48ecc342db821d20642320772e783/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "a0dc75d7d93a",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "while true; do echo hello; sleep 1; done"
            ],
            "Image": "centos",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20210915",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "9aa9a53c095fc39d31cd7f2974bf08ff3b3546e2cde7603209d21107467def99",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/9aa9a53c095f",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "416ebf084c86aea3e061976abce95dfdc09cda0e9622dcc08c721bd6dbe10306",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "947ffb23cceba0e0444083b9a63d40159a5ed24d06e88ce71ca9a014847a93eb",
                    "EndpointID": "416ebf084c86aea3e061976abce95dfdc09cda0e9622dcc08c721bd6dbe10306",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

进入当前运行的容器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/692880.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android Jetpack Compose之TabRow的使用

Android Jetpack Compose是一个现代化的UI工具包&#xff0c;它让开发者可以以声明式的方式来构建出美观且功能强大的Android应用。在本文中&#xff0c;我们将详细介绍其中的一个重要组件——TabRow。 一. TabRow简介 TabRow是Jetpack Compose中的一个组件&#xff0c;主要用…

在家用电脑怎么赚钱,在家就能获得收益的三种方式

如何在家赚钱可能是许多人都困扰的问题之一。实际上&#xff0c;有很多在家赚钱的方法可供选择。然而&#xff0c;我在网上发现许多人缺乏学习的动力&#xff0c;不愿意承担风险&#xff0c;因此大约80%的人选择从事辛苦劳动或成为被剥削的人&#xff0c;导致他们连续几年在互联…

SpringBoot中的bean管理

一、获取bean 默认情况下&#xff0c;Spring项目启动时&#xff0c;会把bean都创建好放在IOC容器中&#xff0c;如果想要主动获取这些bean&#xff0c;可以通过如下方式: 根据name获取bean: object getBean (String name)根据类型获取bean: <T> T getBean (Class<…

8.1 PowerBI系列之DAX函数专题-进阶-解决列排序对计算的影响

需求 下列矩阵中&#xff0c;在月份列不按照原始数据的month_no排列时&#xff0c;能正确计算销售额占比&#xff0c;但是当月份按照month_no排序时就会出错&#xff0c;需要解决这个问题。 实现 month % divide([amount],calculate([amount],all(date[month desc]))) //排…

计算机网络—局域网

文章目录 ARP协议以太网以太网帧结构交换机交换机的端口划分 PPP协议 MAC地址 封装在链路帧中的地址&#xff0c;作为每一个接口的地址。&#xff08;一般是48bit大小&#xff09; MAC地址是刻画到我们物理接口上的&#xff0c;我们的网卡一旦出厂之后就会携带一个唯一的物理地…

升级HarmonyOS 3,通话一步切换更便捷

小伙伴们&#xff0c;今天和大家来聊聊HarmonyOS 3音频播控中心有哪些真香体验。不少朋友可能会脱口而出&#xff1a;一键切换音频App&#xff0c;一键实现音频跨设备流转&#xff0c;还有音频共享。这一次&#xff0c;音频播控中心又带来了新技能——一键切换通话音频。 相信大…

Java集合相关问题

java集合框架体系 数据结构 算法复杂度分析 时间复杂度分析&#xff1a;对代码运行时间所消耗时间多少进行分析空间复杂度分析&#xff1a;对代码运行所占用的内存的大小进行分析 时间复杂度 时间复杂度分析&#xff1a;来评估代码的执行耗时 假如执行每行代码的执行耗时一…

electron实现子窗口中创建右键菜单

后续可能会用electron开发一些工具&#xff0c;包括不限于快速生成个人小程序、开发辅助学习的交互式软件、帮助运维同学一键部署的简易版CICD工具等等。 开发进度&#xff0c;取决于我懒惰的程度。 不过不嫌弃的同学还是可以先关注一波小程序&#xff0c;真的发布工具了&…

Shopee(虾皮)运营没流量?没销量?只因你没掌握店铺引流方法大全

一、站内引流 - 类目 选品&#xff1a;侧重高性价比的潮流商品&#xff0c;及时上架销售热卖商品&#xff1b; 根据目标客户群选品&#xff1a;比如&#xff0c;如果60%-70%的用户为年轻女性&#xff0c;则关注性价比高的潮流商品&#xff1b; 根据重点品类选品&#xff1a;流…

C语言笔记-小智课堂-常用语法

嵌入式常用C语言语法 - 小智课程 类型&字节转换 define语法 define只是单纯替换&#xff0c;如果是运算记得加括号 防止多个文件调用重定义问题 define与typedef&#xff08;替换与别名&#xff09; enum语法 enum用于变量的枚举。 定义枚举类型的变量&#xff0c;变量…

MSP430G2553 Proteus仿真0~5V电压表数码管显示报警系统-0046

MSP430G2553 Proteus仿真0~5V电压表数码管显示报警系统-0046 Proteus仿真小实验&#xff1a; MSP430G2553 Proteus仿真0~5V电压表数码管显示报警系统-0046 功能&#xff1a; 硬件组成&#xff1a;51单片机 8位数码管MAX7219数码管驱动模块多个按键LED灯蜂鸣器 1.准确测量信…

43 # buffer 的应用

buffer Buffer 代表的都是二进制数据&#xff0c;代表是内存&#xff0c;它不能扩容&#xff08;java 数组不能扩容&#xff0c;想扩容可以使用动态数组&#xff0c;或者生成一个新的内存拷贝过去&#xff09; 服务端可以操作二进制&#xff0c;Buffer 可以和字符串进行相互转…

学习adaboost(二,第一次迭代,c#实现)

我觉得这两个公式推导的特别好。我们来搞第一次迭代&#xff1a; 我们取x<2.5,标签1&#xff0c;else&#xff0c;标签-1这个分类器&#xff0c;发现分错的是5&#xff0c;7&#xff0c;8三组数据 &#xff0c;正确的都由0.1变为0.0714了&#xff0c;降低了&#xff0c;错误…

课程20:API项目重构

🚀前言 本文是《.Net Core从零学习搭建权限管理系统》教程专栏的课程(点击链接,跳转到专栏主页,欢迎订阅,持续更新…) 专栏介绍:以实战为线索,基于.Net 7 + REST + Vue、前后端分离,不依赖任何第三方框架,从零一步一步讲解权限管理系统搭建。 专栏适用于人群:We…

Debezium系列之:记录一次Debezium集群服务器端口打满的原因和对应的解决方法

Debezium系列之:记录一次Debezium集群服务器端口打满的原因和对应的解决方法 一、背景二、查看被占端口使用情况三、查看日志四、定位原因五、快速解决六、再次查看服务器端口使用情况七、总结一、背景 运维Debezium集群,停止Debezium集群后,再次启动Debezium集群提示端口被…

一个注解让你的项目减少30%SQL代码量

今天给大家介绍一个很好用的开源项目&#xff1a;easy_trans&#xff0c;它能让你的项目减少30%的SQL代码量&#xff0c;接下来让我们进一步了解它。 什么是Easy_Trans Easy Trans是一款用于做数据翻译的代码辅助插件&#xff0c;利用MyBatis Plus/JPA/BeetlSQL 等ORM框架的能…

算法----使二进制字符串字符交替的最少反转次数

题目 给你一个二进制字符串 s 。你可以按任意顺序执行以下两种操作任意次&#xff1a; 类型 1 &#xff1a;删除 字符串 s 的第一个字符并将它 添加 到字符串结尾。 类型 2 &#xff1a;选择 字符串 s 中任意一个字符并将该字符 反转 &#xff0c;也就是如果值为 ‘0’ &…

django框架-2

创建项目 创建项目文件夹创建项目 django-admin startproject BaseDjangoProject 创建应用 python manage.py startapp goods settings.py 在最后面添加上应用goods INSTALLED_APPS [django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contr…

Java字符串中字符的Unicode码点、编码

以前对于Java字符串中字符的Unicode码点、UTF编码没有仔细研究。今天研究了下。 Unicode是一个字符集&#xff0c;其实是一个映射&#xff0c;给每个字符映射了一个数值&#xff0c;称为码点&#xff08;Code Point&#xff09;。 而UTF-8、UTF-16、UTF-32则是对Unicode码点的转…

shiro反序列化漏洞

Shiro简述 Shiro 是 Java 的一个安全框架&#xff0c;执行身份验证、授权、密码、会话管理shiro默认使用了CookieRememberMeManager&#xff0c;其处理cookie的流程是&#xff1a;得到rememberMe的cookie值–>Base64解码–>AES解密–>反序列化 然而AES的密钥是硬编码…