Docker

Docker

一、基本概念

镜像(image)好比模板,可以根据镜像创建容器服务

容器(container)

仓库(repository)是存放镜像的地方

二、环境准备

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
 # 卸载旧版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 需要的安装包
sudo yum install -y yum-utils

# 设置镜像仓库
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 更新软件索引
yum makecache fast

# 安装docker
sudo yum install docker-ce docker-ce-cli containerd.io

# 启动docker
systemctl start docker

# 使用docker version查看是否安装成功
# 测试: docker run hello-world

三、基本命令

3.1 镜像

搜索镜像:

1
2
docker search mysql
docker search mysql --filter=stars=3333

下载镜像:

1
2
docker pull mysql
docker pull mysql:5.7

查看本地镜像:

1
docker images

查看容器/镜像/数据卷所占空间:

1
docker system df

删除镜像:

1
2
docker rmi -f 镜像id
docker rmi -f $(docker images -aq) # 删除全部

导出镜像:

1
docker save -o jwt.tar jwt:1.0 # 注意:这里的名字和标签要一一对应, 不能乱写, 否则后面load时名字和标签会变成none

加载镜像:

1
docker load < jwt.tar

虚悬镜像的查看与删除:

1
2
docker images -f dangling=true
docker image prune

3.2 容器

运行容器:

1
docker run -it -d -p 80:80 centos /bin/bash

删除容器:

1
2
docker rm id # 删除容器
docker rm -f id # 强制删除容器

启动、重启、关闭、杀掉容器:

1
2
3
4
docker start id 
docker restart id # 重启容器
docker stop id
docker kill id # 强制停止容器

退出容器:

1
2
ctrl + p + q # 不停止容器退出
exit # 停止容器并退出

查看容器:

1
2
docker ps # 查看运行中容器
docker ps -a # 查看运行中容器+历史容器/

3.3 常见的其他命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
docker info # 查看docker概要信息
docker logs -ft --tail 10 id # 显示日志 -t加时间,-f保留打印窗口,--tail 显示最后的几行
docker top id #查看docker内进程,得到的结果中 uid为用户id,pid为进程id,ppid为父进程id
docker inspect id # 查看容器内部细节
docker exec -it id /bin/bash # 进入容器,开启新的终端
docker attach id # 进入容器,进入正在执行的终端
# attach进入容器启动命令的终端,exit不会停止容器
# exec进入容器会打开新的终端,用exit退出不会导致容器的停止
docker cp id:目录/文件 主机目录 # 将容器内文件复制到物理机
docker export # 将容器转化为tar归档文件
docker export 2bd > 123.tar
docker import # 将tar文件导入为镜像
cat 123.tar | docker import - d4wn/ubuntu:3.7
docker run -d tomcat -p 3356:8080 --name tomcat01 # 部署tomcat
docker stats # 查看内存状态
docker commit -m="描述信息" -a="作者" id 目标镜像名[:tags]

3.4 推送镜像到Docker hub

1
2
3
docker login -u d4wnnn
docker tag centos:7 d4wnnn/centos:7
docker push 昵称/镜像名

四、卷技术

1
2
3
4
docker run -itd -v /home/ceshi:/webapps --priviledged=true tomcat[:ro] /bin/bash # 指定路径挂载
docker run -itd -v name:/webapps tomcat[:ro] /bin/bash # 具名挂载
docker run -itd -v /webapps tomcat[:ro] /bin/bash # 匿名挂载
# 拓展 [:ro] 即read only,只能在宿主机改数据,默认为rw

五、DockerFile

保留字必须为大写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FROM 			# 基于什么镜像
MAINTAINER # 维护者
ENV # 构建的时候设置环境变量,可以在后续的RUN指令中使用
RUN # 镜像构建的时候需要运行的命令,就是在终端操作的命令(安装完系统后)
# exec格式:RUN ["./test.php","dev","offline"]
# ["可执行文件","param1",:param2]
# shell格式:RUN yum install -y vim
ADD # 将宿主机目录下的文件拷贝进镜像,并且会自动处理url和解压tar压缩包
COPY # 类似ADD,将文件拷贝到镜像, COPY 源路径 目的路径
WORKDIR # 登录进来的目录
USER # 指定镜像以什么样的用户去执行,默认为root
VOLUME # 挂载的目录
EXPOSE # 暴露端口配置,只是便于在元数据中展示,实际没用
ONBUILD # 当构建一个被继承DockerFile时就会自动触发
CMD # 注意,可以指定多个CMD,但是只有最后一个生效,docker run后的命令比如bin/bash会替换
# 掉他。CMD是在docker run的时候运行,RUN是在docker build的时候运行
ENTRYPOINT # 类似CMD,但是ENTRYPOINT不会被docker run后的命令覆盖,而且这些命令行参数会被当作ENTRYPOINT指令的参数
# 若同时指定ENTRYPOINT,则CMD的含义发生了变化,不再是直接运行其命令,而是将CMD的内容作为参数传递给ENTRYPOINT指令

EG.1-多阶段构建

在build阶段安装了编译工具和依赖项,复制了应用程序的源代码,安装了Python依赖项,并且编译了应用程序。

在release阶段从第一阶段复制了构建好的应用程序。这个阶段生成的镜像只包含运行时所需的组件,不包含编译工具和依赖项。

通过这种方式,最终的镜像将比第一阶段的镜像更小,因为它只包含了运行应用程序所需的内容。这提高了镜像的安全性,同时也减小了镜像的大小。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 第一阶段:构建应用程序
FROM python:3.9-slim-buster as build
WORKDIR /app
# 安装编译工具和依赖项
RUN apt-get update && apt-get install -y build-essential libffi-dev libssl-dev
# 复制应用程序的源代码到容器中
COPY . .
# 安装Python依赖项
RUN pip install --no-cache-dir -r requirements.txt
# 编译应用程序(假设你的应用程序需要编译)
RUN python build.py

# 第二阶段:最终镜像
FROM python:3.9-slim-buster as release
WORKDIR /app
# 从第一阶段复制构建好的应用程序到最终镜像
COPY --from=build /app /app
# 设置环境变量等
# 最终镜像只包含运行时所需的组件
CMD ["python", "app.py"]

六、网络

1
2
3
4
5
docker network ls # 列出网络
docker network create name network # 创建网络
docker network rm name # 移除网络
docker network inspect xxx # 查看网络
# docker 自定义网络支持通过主机名访问其他主机

若同时创建多个容器,比如指定容器名为web1,web2。他们默认都会连接到桥接网络,但是并不会提供DNS解析服务,也就是无法根据对应的容器名找到对应的IP地址。只有自己指定一个网络,才会为其设置DNS服务,使得容器名可以对应IP地址。

七、Docker-compose

定义: 是Docker官方的开源项目,负责实现Docker容器集群的快速编排。

应用场景:比如在启动Web服务前,需要先启动MySQL服务,涉及到了容器的启动顺序问题。

1
2
3
4
5
6
7
8
9
version: '3'
services:
redis_container:
build: .
ports:
- "6379:6379"
- "8888:22"
volumes:
- /path/to/your/physical/file:/path/inside/container

buildimage字段:

参考:https://www.jianshu.com/p/2217cfed29d7

若仅仅使用image字段,则会首先查找有无该image,若无则去pull该image

若仅仅使用build字段,则会build该镜像

build后可以仅仅加上Dockerfile的目录,

也可以通过下面这种方式设置

1
2
3
build:
context: ../
dockerfile: xxx

若同时指定了image和build,则build的镜像会重命名为image字段设置的值

restart: always

该选项可以让docker-compose重启指定容器始终保持运行。如果容器因为某些原因停止运行,docker-compose将会自动重启它。

depends_on

它指定了一个或多个服务依赖于其他服务,以确保在启动依赖服务之前,必须先启动它们

八、其它问题

千古问题:Is the docker daemon running?

彻底解决:

查看当前有哪些关于docker的包:

1
dpkg -l | grep -i docker

然后删除

1
2
sudo apt-get purge -y xxx
sudo apt-get autoremove -y --purge xxx

然后重新安装

参考:https://askubuntu.com/questions/935569/how-to-completely-uninstall-docker


Docker
https://d4wnnn.github.io/2022/03/09/DevOps/Docker/
作者
D4wn
发布于
2022年3月9日
许可协议