Docker

Docker

Docker作用

大型项目组件较多,运行环境也较为复杂,部署时所需要的函数库、依赖项各不相同,甚至会有冲突。给部署带来了极大的困难

Docker为了解决依赖的兼容问题的,采用了两个手段:

  • 将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包

  • 将每个应用放到一个隔离容器去运行,避免互相干扰

Docker架构

概念:

  • 镜像(Image):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。

  • 容器(Container):镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器进程做隔离,对外不可见。

  • DockerHub:DockerHub是一个官方的Docker镜像的托管平台。这样的平台称为Docker Registry。

Docker是一个CS架构的程序,由两部分组成:

  • 服务端(server):Docker守护进程,负责处理Docker指令,管理镜像、容器等
  • 客户端(client):通过命令或RestAPI向Docker服务端发送指令。可以在本地或远程向服务端发送指令。

安装Docker

CentOS8

CentOS8 安装 Docker-阿里云开发者社区 (aliyun.com)

  1. 卸载老版本Docket

    1
    2
    3
    4
    5
    6
    7
    8
    yum remove docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine
  2. 安装docket基础包

    1
    2
    3
    yum install -y yum-utils \
    device-mapper-persistent-data \
    lvm2
  3. 设置国内仓库

    1
    2
    3
    yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  4. 安装Docket社区版

    1
    yum install --allowerasing docker-ce
  5. 启动docket

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Docker应用需要用到各种端口,逐一去修改防火墙设置。非常麻烦
    启动docker前,建议关闭防火墙
    # 关闭
    systemctl stop firewalld
    # 禁止开机启动防火墙
    systemctl disable firewalld

    sudo systemctl start docker # 启动docker
    docker run hello-world #测试
  6. 配置国内镜像源

    容器镜像服务 (aliyun.com)

Docker Desktop

Docker Desktop 是 Docker 在 Windows 10 和 macOS 操作系统上的官方安装方式,这个方法依然属于先在虚拟机中安装 Linux 然后再安装 Docker 的方法

安装参考:https://blog.csdn.net/GoodburghCottage/article/details/131413312

  1. 官网下载https://www.docker.com/,双击,直接next即可,安装完需要重启

  2. 打开Docker Desktop

    • 如果提示WSL needs updating,从https://github.com/microsoft/WSL/releases下载离线包双击安装。通过`wsl –update`速度会很慢
    • 如果提示Virtualization support not detected,检查以下两点
      • 需要开启Hyper-V 服务。点击控制面板 -> 程序 -> 启用或关闭Windows功能,勾选Hyper-V容器Windows 虚拟机监控程序平台适用于Linux的Windows子系统
      • Windows Hypervisor未正确启动。cmd命令bcdedit /enum,检查hypervisorlaunchtype是否为AUTO,如果是OFF,则bcdedit /set hypervisorlaunchtype AUTO
      • 设置完记得重启
  3. 配置镜像源:点击设置 -> Docker Engine,添加以下内容,之后点击Apply

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    {
    "builder": {
    "gc": {
    "defaultKeepStorage": "20GB",
    "enabled": true
    }
    },
    "experimental": false,
    "registry-mirrors" : [
    "https://do.nark.eu.org",
    "https://do.js.work",
    "https://docker.m.daocloud.io",
    "https://dockerproxy.com",
    "https://dockermirrors.ustc.edu.cn",
    "https://docke.nju.edu.cn"
    ]
    }
  4. 修改镜像保存路径

    1. 点击Setting -> GeneralUse the WSL 2 based engine取消勾选
    2. 点击Resources,修改Disk image location
    3. 再将Use the WSL 2 based engine勾选,点击Apply
  5. 测试:在控制台输入docker images测试

Docker命令

镜像相关

  • 拉取镜像

    1
    2
    docker pull 镜像名:版本
    # 没加版本默认latest(最近的)
  • 查看镜像

    1
    docker images
  • 通过–help来查看提示

    1
    docker save --help
  • 删除镜像

    1
    docker rmi 镜像名:版本
  • 保存/导入镜像

    1
    2
    3
    4
    # 保存镜像到tar
    docker save -o nginx.tar nginx:latest
    # 导入镜像
    docker load -i nginx.tar

容器相关

  • 创建并运行容器

    -d为后台运行

    1
    docker run --name 给容器起名 -p 80:80 -d nginx
  • 运行/停止容器

    1
    docker start/stop 容器名
  • 查看正在运行的容器

    1
    2
    3
    docker ps

    docker ps -a #查看所有容器
  • 查看容器日志

    1
    docker logs 容器名
  • 进入/退出容器

    1
    2
    3
    docker exec -it 容器名 bash

    exit # 退出容器
    • docker exec :进入容器内部,执行一个命令
    • -it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
    • bash:进入容器后执行的命令,bash是一个linux终端交互命令
  • 删除容器

    1
    docker rm 容器名

Dockerfile自定义镜像

镜像组成结构

Dockerfile指令是一个文本文件,其中包含一个个的**指令(Instruction)**,用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer

官网文档 https://docs.docker.com/engine/reference/builder

Dockerfile示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local

# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar

# 安装JDK
RUN cd $JAVA_DIR \
&& tar -xf ./jdk8.tar.gz \
&& mv ./jdk1.8.0_144 ./java8

# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin

# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar

构建镜像命令

1
docker build -t 镜像名称:版本 .

数据卷

数据卷(volume)是一个虚拟目录,指向宿主机文件系统中的某个目录

创建的数据卷会保存在/var/lib/docker/volumes/目录下

通过容器和数据卷的挂载(绑定),就能在外部操作容器内的目录了

数据卷基本命令

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@root ~]# docker volume --help

Usage: docker volume COMMAND

Manage volumes

Commands:
create 创建数据卷
inspect 查看一个数据卷详细信息
ls 查看所有数据卷
prune 删除所有未使用的数据卷
rm - 删除指定数据卷

挂载数据卷

例子:

  1. 创建创建容器并挂载数据卷到容器内的HTML目录

    1
    docker run --name mynginx -v html:/usr/share/nginx/html -p 80:80 -d nginx

    -v html:/usr/share/nginx/html: 创建html数据卷并把容器中的/usr/share/nginx/html挂载上

  2. 查看html数据卷位置

    1
    2
    3
    4
    5
    docker volume inspect html
    # 进入该目录
    cd /var/lib/docker/volumes/html/_data
    # 修改文件
    vi index.html

挂载自定义的本地目录

容器不仅仅可以挂载数据卷,也可以直接挂载到宿主机目录上

  • 带数据卷模式:宿主机目录 –> 数据卷 —> 容器内目录
  • 直接挂载模式:宿主机目录 —> 容器内目录

例子: 给mysql挂载到本地目录

1
2
3
4
5
6
7
docker run \
--name mysql \
-e MYSQL_ROOT_PASSWORD=123456 \ #数据库密码
-p 3307:3306 \ #宿主机端口:容器端口
-v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf \ #宿主机文件:容器内文件
-v /tmp/mysql/data:/var/lib/mysql \ #宿主机目录:容器内目录
-d mysql:5.7.25

数据卷挂载与目录直接挂载的

  • 数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
  • 目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看

DockerCompose容器编排

Docker Compose可以基于Compose文件帮我们一键部署和启动多个容器,而无需手动一个个创建和运行容器

安装

1
2
3
4
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

#修改文件权限
sudo chmod +x /usr/local/bin/docker-compose

Base自动补全命令

1
2
# 补全命令
curl -L https://raw.githubusercontent.com/docker/compose/1.29.1/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose

使用

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
# 以部署wordpress为例

# 创建一个文件夹用于存放compose文件
mkdir /home/wordpress
cd wordpress

# 将dockerhub中wordpress的compose文件复制进来
vim docker-compose.yml

# 创建启动(后台)
docker compose up -d

# 查看启动的容器
docker compose ps

# 停止容器
docker compose stop

# 启动
docker compose start

# 删除容器(数据卷不会一起被删)
docker compose down

# 查看日志
docker compose logs -f

Docker网络命令

1
2
3
4
5
6
7
# bridge网络
# 不指定网络时,新创建的容器默认将连接到bridge网络上
# 容器之间只能通过ip通讯,ip会随启动顺序而变化,因此不推荐

# 查看容器ip
docker inspect \
--format='{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 容器名字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 用户自定义网络
# 容器之间可以通过容器名进行访问
# docker会通过嵌入式DNS服务器将容器名解析成IP

# 创建自定义网络
docker network create 网络名

# 将已有容器连接到此网络
docker network connect 网络名 容器名

# 断开容器和网络的连接
docker network disconnect 网络名 容器名

# 创建容器时指定网络(mysql为例)
docker run -it --rm --network 网络名 容器名 mysql:5.7 mysql -h容器名 -u用户名 -p密码

Dockerfile

相当于启动应用的一系列操作的集合,打包成一个镜像

1
2
3
4
5
6
FROM openjdk:8u342-jre
WORKDIR /app
COPY ./ruoyi-admin.jar .
RUN make .
CMD ["java", "-jar", "ruoyi-admin.jar"]
EXPOSE 8080
  • FROM:基础镜像
  • WORKDIR:相当于cd,进入工作目录
  • COPY:将宿主机的文件复制到容器中
  • RUN:打包时执行的命令
  • CMD:运行镜像时执行的命令
  • EXPOSE:监听的端口
1
2
3
4
5
# 构建镜像
docker build dockerfile所在路径

# 指定镜像名称、版本号
docker tag 镜像id 名称:版本

Docker
http://xwww12.github.io/2022/09/09/微服务/Docker/
作者
xw
发布于
2022年9月9日
许可协议