Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker 学习笔记 #14

Open
bouquetrender opened this issue Nov 1, 2023 · 0 comments
Open

Docker 学习笔记 #14

bouquetrender opened this issue Nov 1, 2023 · 0 comments
Labels
Docker New feature or request

Comments

@bouquetrender
Copy link
Owner

bouquetrender commented Nov 1, 2023

概念

docker 使用容器化技术,可以将应用程序及其依赖项打包到一个独立的容器中,然后在环境中运行这个容器,保持环境一致性。

容器 Containers:一个轻量级、独立、可执行的软件包,包含应用程序和其所有依赖项,例如代码、运行时、库、环境变量等。每个容器都运行在宿主操作系统的 kernel 内核上,是一个隔离的环境,会与其他容器和宿主系统隔离开。

镜像 Images:snapshot of file system,用于创建容器。包含了运行应用程序所需的信息。

仓库 Repository:用于存储 docker 镜像

dockerfile:文本文件,其中包含了一系列的命令和参数,用于自动化地构建 docker 镜像。通过 dockerfile 可以定义镜像中的操作系统、应用程序、依赖项等内容。

命令行运行 docker run hello-world 启动新容器,docker client 接收命令,传输到 docker server,检查是否有 local copy,image cache 是空所以通过 docker hub(free public image)查找镜像,找到后下载存储到本地硬盘,并运行。

安装 docker 实际上是 linux 虚拟机,通过 linux kernel 托管容器内的 running process。

基础命令

docker version 查看版本信息

docker run busybox ls 命令,ls 在 running process 中执行并输出 fs 目录,可以成功运行 ls 是因为 ls 程序存在于 busybox 镜像(包含 file system)

docker ps 列出所有正在运行的容器,可以查看 id/command/created/status/ports/random names

docker ps --all 查看所有曾经创建过的容器

docker run命令实际上有两步docker createdocker start,执行 docker create 命令会生成一个 id,可以通过docker start -a <id>启动容器(-a 观察容器并打印输出到控制台)。

可以通过 docker ps 获得的容器 id,再次执行 start 启动该容器

使用了长时间 docker 或者清理强迫症可以使用 docker system prune用于删除不再使用的 docker 资源:

  • 停止的容器(Stopped containers)
  • 未被任何容器引用的卷(Volumes not used by at least one container)
  • 未被任何容器引用的网络(Networks not used by at least one container)
  • 无标签的镜像(Dangling images,即没有标签的镜像)
  • 所有未使用的镜像(Images that are not referenced by any container)

docker log <id> 显示指定容器的输出日志

docker stop <id> 用于停止运行中的容器。当使用 docker stop 命令停止容器时,Docker 首先会向容器发送一个 SIGTERM 信号(用于请求程序安全退出),这个信号可以被监听并可以让开发者做些清理保存之类的操作,像是执行终止前的生命周期方法,等待一定的时间(默认为 10 秒,可以通过--time 选项指定)以便容器可以自行处理收尾工作,并在等待超时后发送一个 SIGKILL 信号强制终止容器

docker kill <id> 用于立即停止运行中的容器。它会发送一个 SIGKILL 信号给容器,强制终止容器的运行,不管容器内的应用程序是否正在执行某些操作

docker exec -it <id> <command> 在指定容器内启动第二个程序,执行附加命令,-it可以使 input 命令输入到容器中。

linux 进程三个通信通道

  • STDIN 进程从用户获取输入的通道。当在终端输入命令时这些输入会被发送到标准输入
  • STDOUT 进程将结果输出到用户的通道。当进程执行命令并产生输出时,这些输出通常会被发送到标准输出(终端显示)
  • STDERR 进程将错误消息输出到用户的通道

-it分为两个选项:

  • -i 代表交互式(interactive)。使得终端保持对容器的标准输入(STDIN)开放,这样可以向容器发送输入。
  • -t 代表终端(terminal)。让 docker 分配一个伪终端(pseudo-TTY),通常与一个 shell 进程关联,使得可以在容器内部获得一个交互式的命令行界面。

docker exec -it <id> sh 在指定的 docker 容器内部启动一个交互式的 shell 终端(通过 command/ctrl+d 退出)

dockerfile

# 使用已有的 docker image(作为初始操作系统)
# 或者 FROM ubuntu:latest
FROM alpine

# 下载安装依赖(apk包管理器,类似于homebrew)
RUN apk add --update redis

# 告诉 image 在作为 container 启动时应该做什么
CMD ["redis-server"]

docker build . 构建成功得到
docker run <id> 运行 image

FROM 用于指定基础镜像
RUN 用于在镜像中运行命令
CMD 用于定义 container 启动时默认运行的命令

dockerfile 除了第一个步骤 FROM 外的每个步骤指令开始时会输出一个 container ,指令结束时会提示 removing intermediate container ,然后生成一个 fs 快照 id,接着从这个 fs 快照开始执行下个指令,重新执行相同的构建会取缓存。

docker build -t <docker id>/<project name>:<version> . 给 image 一个 tag(version)
docker run <docker id>/<project name> 运行 image

nodejs web app

https://hub.docker.com/_/node

  1. 创建用于测试基础的 package.json 和 index.js,通过 express 启动 web 服务监听 8081

  2. 创建 dockerfile

直接运行 npm install 会导致找不到 package.json 文件,因为 container 是完全隔离的,所以需要运行 COPY 命令,第一个参数是用于创建 context 需要复制的文件夹的相对路径,第二个参数是复制到 container 的位置,如果设置了 workdir 则根目录就是 指定的 workdir 目录。

FROM node:alpine

# 设置容器内部的工作目录,如果目录不存在自动创建
WORKDIR /usr/app

# 分离不常改动的文件利用cache
RUN COPY ./package.json ./
RUN npm install

RUN COPY ./ ./

CMD ["npm", "start"]
  1. 执行 docker build -t learndocker/mywebserver .

  2. 端口映射,本机 5000 端口映射到 container 8081 端口,执行 docker run -p 5000:8081 learndocker/mywebserver

docker compose

用于定义和管理多个 Docker 容器的工具。允许使用一个简单的 YAML 文件来配置应用程序的服务、网络和卷,并且可以通过一个命令来启动或停止整个应用程序。

compose会自动创建一个网络将不同的 container 连接在一起可以互相通信。

version: '3'
services:
  redis-server:
    image: 'redis'
  node-app:
    restart: always
    build: .
    ports:
      - "4001:8081"

自动重启容器 restart

  • no 默认值,不自动重启
  • on-failure 非0状态码退出时重启
  • always 任何原因导致的容器停止都会重启
  • unless-stopped 非手动关闭时重启

docker-compose up 启动 Docker Compose 文件中定义的服务,如果需要构建加上参数--build

docker-compose down 关闭所有的容器

docker-compose ps 查看 compose 状态

需要当前目录有 docker-compose.yml 文件才能执行 docker-compose 命令

Volumes

将主机的文件或目录挂载到容器内部,使得容器可以访问这些文件或目录

docker run -p 3000:3000 -v /app/node_modules -v $(pwd):/app <id>

-v /app/node_modules 含义为类似于加一个书签或者标记给这个目录, 表示容器内这个文件夹不需要映射,而是使用容器本身的文件

pwd(print work directory)当前工作目录
$(pwd):/app:当前工作目录下的app文件夹
-v $(pwd):/app 含义为 设置一个卷目录为 $(pwd):/app 当前工作目录下的app文件夹

可以将 -v 命令写入 docker-compose.yml

version: '3'
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    volumes:
      - /usr/app/node_modules
      - .:/usr/app
@bouquetrender bouquetrender changed the title Docker Docker 学习笔记 Nov 1, 2023
@bouquetrender bouquetrender added the Docker New feature or request label Nov 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Docker New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant