Docker的基本组成
- 镜像(image)
相当于一个模板,容器的启动依赖于这个模板 - 容器(container)
相当于一个迷你版的linux系统, - 仓库(repository)
存放镜像的地方,分私有仓库和公有仓库
Docker的安装
官方文档
查看Linux的相关信息
- 查看系统架构
[root@fishpie-one ~]# uname -a
Linux fishpie-one 4.18.0-348.7.1.el8_5.x86_64 #1 SMP Wed Dec 22 13:25:12 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
- 查看服务器基础信息
[root@fishpie-one ~]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="8"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Linux 8"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-8"
CENTOS_MANTISBT_PROJECT_VERSION="8"
卸载旧版本的Docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
安装Docker
- 下载docker依赖文件
sudo yum install -y yum-utils
- 设置镜像仓库
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
- 更新软件包索引
#CentOS8
yum makecache
#CentOS7
yum makecache fast
- 下载最新版的Docker引擎
yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- 启动docker
systemctl start docker
#设置docker为开机自启动
systemctl enable docker
- 检查Docker是否安装成功
[root@fishpie-one ~]# docker version
Client: Docker Engine - Community
Version: 26.0.2
API version: 1.45
Go version: go1.21.9
Git commit: 3c863ff
Built: Thu Apr 18 16:28:46 2024
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 26.0.2
API version: 1.45 (minimum version 1.24)
Go version: go1.21.9
Git commit: 7cef0d9
Built: Thu Apr 18 16:27:41 2024
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.31
GitCommit: e377cd56a71523140ca6ae87e30244719194a521
runc:
Version: 1.1.12
GitCommit: v1.1.12-0-g51d5e94
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Docker的常用命令
帮助命令
docker version #查看docker版本和一些基础信息
docker info #查看docker的系统信息
docker 命令 --help #万能命令
镜像命令
- 列出本机现有镜像
docker images #查看docker镜像仓库
- 搜索镜像
#使用docker搜索mysql镜像,和再docker hub上搜索mysql是一样的效果
docker search <镜像名称>
#搜索STARTS数在3000以上的mysql镜像,推荐直接去dockerhub上寻找
docker search <镜像名称> --filter=STARTS=3000
- 下载镜像
#docker下载镜像,默认标签latest
docker pull <镜像名称>:<标签>
docker下载镜像公用的部分不会重复下载
- 删除镜像
docekr rmi <镜像id>
docker rmi -f <镜像id> #强制删除指定镜像,多个容器之间使用空格分隔
docker rmi -f $(docker images -aq) #删除所有镜像
容器命令
- 启动容器
docker run [可选参数] <镜像ID>
#参数说明
--name="Name" #指定容器名字
-it #使用交互方式运行,进入容器查看内容
-p 主机端口:容器端口 #指定容器的端口 -p 8080:8080
-P #随机指定未使用的端口号
-d #后台方式运行
-v 主机目录:容器内目录 #具名挂载
特别说明:docker容器使用后台运行,就必须要有一个前台进程,docker发现没有容器运行就会自动停止(当没有容器运行时,此时使用后台运行的命令就不会启动容器)
- 退出容器
#容器退出,若此时没有其他容器在运行则会停止该容器
exit
#容器不停止的退出(按键行为),ctrl后先按p后按q
[按键] ctrl + p + q
- 查看运行容器
#查看现在正在运行的容器
docker ps
#查看运行过的容器
docker ps -a
-a 列出当前正在运行的容器 + 历史运行过的容器
-n=? 显示最近创建的 ?个 容器
-q 只显示容器的编号
- 删除容器
#删除容器,删除镜像是rmi
docker rm 容器id //删除指定容器,不能删除正在运行的容器
docker rm -f $(docker ps -aq) //删除全部容器
- 进入正在运行的容器
docker exec -it <容器id> bash #进入容器后打开一个新的终端,可以在里面操作(常用)
docker attach <容器id> #进入容器正在执行的终端,不会启动新的线程
- 拷贝容器内文件到主机
docker cp 容器ID:容器内路径 目的主机路径
#示例:
#拷贝镜像60b4ead93451内的demo.java文件到本机的/home目录下
[root@fishpie-one ~]# docker cp 60b4ead93451:/home/demo.java /home
Successfully copied 2.05kB to /home
日志命令
查看日志
docker logs -tf #t是时间戳,f是跟随最新的日志打印
docker logs -tail number 数字 #要显示日志条数
查看容器中的进程信息
docker top 容器ID
docker inspect 容器ID #容器的详细信息
容器数据卷
数据卷(Volume)是一种持久化数据的机制,使容器内的数据存储在宿主机上,
挂载就是将docker容器内的目录与实体机中的目录做绑定,挂载可分为匿名挂载与具名挂载
- 获取容器元数据
docker inspect <容器ID>
使用数据卷
docker run -it --name 自定义名称 -v 主机目录:容器内目录 镜像名
使得容器内外的这个目录的物理存储地址为同一个(说明不论容器是否在运行,文件修改都会存在),一种同步
具名挂载和匿名挂载
匿名挂载
#匿名挂载
#Docker自动在宿主机上创建一个随机命名的目录,然后将容器内的 /data 目录挂载到这个随机命名的目录
docker run -d -v /data nginx
具名挂载(推荐)
此处示例目录为 /home/fishpie/nginx
#具名挂载 推荐
#启动nginx镜像,并将这个运行的容器命名为nginx02,
docker run -d -P --name nginx02 -v /home/fishpie/nginx:/etc/nginx nginx
查看挂载方式
docker inspect <容器的名称或ID>
#然后查找Mounts字段中的内容
示例
"Mounts": [
{
"Type": "bind",
"Source": "/home/fishpie/apps/mysql/conf.d",
"Destination": "/etc/mysql/conf.d",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/home/fishpie/apps/mysql/data",
"Destination": "/var/lib/mysql",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
此处有两处挂载
- 本机/home/fishpie/apps/mysql/conf.d 目录挂载到 容器内/etc/mysql/conf.d 目录
- 本机 /home/fishpie/apps/mysql/data 目录挂载到容器内 /var/lib/mysql 目录
拓展:
#通过 -v 容器内路径,ro rw 改变读写权限
ro 全称 readonly #只读
#ro说明这个路径只能通过宿主机来操作,容器内是无法操作的
rw 全称 readwrite #可读可写
docker run -d -P --name nginx20 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx20 -v juming-nginx:/etc/nginx:rw nginx
创建数据卷
docker自带的存储数据卷的目录,如果机器使用多个挂载目录的话会特别特别方便!
这个目录一般为 /var/lib/docker/volumes
- 创建数据卷
docker volume create my-data
只需要创建数据卷名称,不需要再手动指定位置
- 列出所有创建的数据卷
[root@node1 volumes]# docker volume ls
DRIVER VOLUME NAME
local my-data
- 使用创建的数据卷
docker run -d --name <容器自定义名称> -v my-data:/<容器内挂载目录> <容器名>
#示例:
docker run -d --name my-container -v my-data:/data my-image
- 查看卷的详细信息
使用数据卷的好处就是查看挂载情况会方便很多
docker volume inspect my-data
[
{
"CreatedAt": "2023-06-09T10:30:00Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-data/_data",#此处就根据名字my-data自动挂载到此目录
"Name": "my-data",
"Options": {},
"Scope": "local"
}
]
- 删除未使用的数据卷
数据卷也是一种持久化手段,删除数据卷可以释放磁盘空间
docker volume prune
DockerFile
Dockerfile 就是用来构建docker镜像的构建文件(命令脚本)
#创建一个dockerfile文件,名字可以随意,但是建议使用 Dockerfile
#文件中的内容 指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "---end---"
CMD /bin/bash
#这里的每一个命令,就是镜像的一层
构建docker镜像
docker build -f /home/docker-test-volume/dockerfile1 -t fishpie/centos1.0 .
-f 指的是文件地址
-t 指的是生成路径
命令末尾一定要加 .
启动自定义的docker镜像
docker run -it --name docker01 bcb7b9d02259
-it 后台运行
--name 给运行的镜像起个名字
最后面的是镜像ID
此处的volume01和volume02就是自己设置的自动挂载的数据卷目录
这个卷和外部一定有一个同步的目录
再用同一个镜像运行一个容器,使其数据卷挂载到docker01
docker run -it --name docker02 --volumes-from docker01 bcb7b9d02259
此时删除docker01,docker02的数据卷还在,不是删除docker01后docker02的数据卷就不在了
这里是将两个容器的地址映射到同一个
DockerFile的构建过程
构建步骤:
- 编写一个 dockerfile 文件
- docker build 构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像(DockerHub、阿里云镜像仓库)
dockerfile命令可通过网络检索图片找到
- dockerfile的命令必须都是大写字母
- 语句执行顺序自上而下
- #表示注释
- 每一个指令创建提交一个新的镜像层
面向开发,发布项目可以通过编写 dockerfile 文件来实现对于项目容器的完成
DockerFile的指令
FROM #指定基础镜像,构建的开始,第一句必须是这个
#FROM <image>[:<tag>] [AS <name>]
#<image>:指定基础镜像的名称。
#[:<tag>]:可选项,指定基础镜像的标签。如果不提供标签,默认使用 latest。
#[AS <name>]:可选项,给基础镜像命名一个别名,可以在多阶段构建中使用。
#例如 FROM ubuntu:20.04 AS builder
LABEL #镜像的作者,格式为:姓名 + 邮箱
#例如
#LABEL maintainer="John Doe <john.doe@example.com>"
#LABEL version="1.0"
#LABEL description="This is a Docker image for my application."
RUN #镜像构建的时候需要运行的命令
#RUN <command>
#<command>:要在容器中执行的命令,可以是任何有效的 Linux 命令。
#例如
#RUN apt-get update && apt-get install -y \
# software-package
#此处使用 \ 可以减少镜像的层数
ADD #添加内容,比如Tomcat压缩包
#用于将文件、目录、URL 等添加到容器中,支持从 URL 下载并解压文件,以及自动解压缩压缩文件。
#慎用,部分场景能用 COPY 就不用 ADD
#ADD <src>... <dest>
#<src>:指定要复制的源文件、目录或 URL。
#<dest>:指定目标路径,即文件或目录将被复制到容器中的位置。
#例如:
# 从 URL 下载文件并复制到容器中,自动解压
#ADD https://example.com/file.tar.gz /tmp/
WORKDIR #镜像的工作目录
#工作目录是在容器中执行命令时的默认目录,可以简化命令的书写,同时也可以帮助组织容器内的文件结构。
#WORKDIR /app 将工作目录设置为 /app,接下来的 COPY、RUN、ENV 等指令都将以 /app 为相对路径进行操作。这使得 Dockerfile 更加清晰和易读,同时也有助于组织容器中的文件结构。
#WORKDIR 不会创建目录,它只是设置容器中执行命令时的默认目录。如果指定的目录不存在,Docker 将自动创建
#例如:
## 设置工作目录为/app
#WORKDIR /app
# 复制本地文件到工作目录
#COPY . .
VOLUME #挂载的目录
EXPORT #指定暴露的端口,相当于容器运行时的 -p
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD
#用于定义在将当前镜像作为基础镜像(被继承)时执行的构建触发器。
#ONBUILD <INSTRUCTION>
#<INSTRUCTION> 是任何有效的 Dockerfile 指令
COPY #用于复制文件或目录到容器中
#复制本地文件到容器中
#COPY source.txt /app/
#复制本地目录到容器中
#COPY myapp/ /app/
ENV #设置环境变量
需注意,应该在完成相同操作功能的情况在尽可能少地使用 DockerFile 指令,每一个指令都是一层一层镜像,命令添加用多了镜像最后构建出来的体积也会变大
docker build -f mydockerfile-centos -t fishepiecentos:0.1 .
-f 指定镜像路径,这里是直接在当前文件夹(在WORKDIR后)
-t 指定镜像名
一定要以 . 结尾
发布自己的镜像
发布镜像到DockerHub
先登录自己的dockerhub
[root@fishpie-one ~]# docker login --help
Usage: docker login [OPTIONS] [SERVER]
Log in to a registry.
If no server is specified, the default is defined by the daemon.
Options:
-p, --password string Password
--password-stdin Take the password from stdin
-u, --username string Username
#要先打成tag
docker tag <制作的镜像ID> <自定义镜像名称>:<自定义tag>
#发布镜像
docker push 镜像名字:TAG
提交的时候也是按照层级来提交
docker部署MySQL8
直接部署MySQL
- 拉取mysql 8的镜像
docker pull mysql:8
- 在本机创建MySQL配置文件目录,此处示例目录:/home/fishpie/apps
mkdir -p /home/fishpie/apps/mysql/conf.d
- 编辑 mysql.cnf 文件并保存,等会儿挂载用
vim mysql.cnf
文件内容(设置了MySQL的默认身份验证插件为 mysql_native_password
)
[mysqld]
default-authentication-plugin=mysql_native_password
- 创建MySQL数据目录,等会儿挂载用
mkdir -p /home/fishpie/apps/mysql/data
- 运行MySQL容器
docker run -d --name mysql8 \
-p 3306:3306 \
-v /home/fishpie/apps/mysql/conf.d:/etc/mysql/conf.d \
-v /home/fishpie/apps/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8
运行情况
[root@node1 conf.d]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1d9d2a63b5dd mysql:8 "docker-entrypoint.s…" 14 minutes ago Up 19 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql8
- 进入MySQL容器
docker exec -it mysql8 bash
- 连接MySQL
mysql -u root -p
#密码为运行容器时设置,此处为123456
- 设置root用户的host,目的是为了远程连接
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
FLUSH PRIVILEGES;
- 退出MySQL服务与容器
exit #退出MySQL服务
exit #退出容器
此时就可以使用远程连接数据库的工具,如DataGrip、navicat等,使用账号密码连接数据库了
如果忘了容器的挂载目录
- 查看容器详细信息
docker inspect mysql8
其中字段 Mounts 会显示挂载情况
"Mounts": [
{
"Type": "bind",
"Source": "/home/fishpie/apps/mysql/conf.d", #挂载目录1
"Destination": "/etc/mysql/conf.d",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/home/fishpie/apps/mysql/data", #挂载目录2
"Destination": "/var/lib/mysql",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
推荐在每个容器启动时记住它的启动命令
使用DockerFile部署MySQL
- 创建DockerFile文件
mkdir mysql-dockerfile
cd mysql-dockerfile
vim DockerFile
文件内容如下
FROM mysql:8
# 设置环境变量
ENV MYSQL_ROOT_PASSWORD=123456
ENV MYSQL_DATABASE=mydb
ENV MYSQL_USER=root
ENV MYSQL_PASSWORD=123456
# 复制配置文件和初始化脚本到镜像中
COPY mysql.cnf /etc/mysql/conf.d/
COPY init.sql /docker-entrypoint-initdb.d/
# 创建数据目录并设置权限
RUN mkdir -p /var/lib/mysql \
&& chown -R mysql:mysql /var/lib/mysql
# 暴露端口
EXPOSE 3306
# 启动MySQL服务
CMD ["mysqld"]
在当前目录下(此处为DockerFile文件所在目录)创建mysql.cnf与init.sql文件
[mysqld]
default-authentication-plugin=mysql_native_password
CREATE DATABASE IF NOT EXISTS `mydb`;
USE `mydb`;
CREATE USER 'root'@'%' IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON `mydb`.* TO 'root'@'%';
FLUSH PRIVILEGES;
- 使用此DockerFile文件构建Docker镜像
docker build -t mysql-custom .
末尾的 .
不要省略
- 运行构建的 mysql-custom 镜像
docker run -d --name mysql-custom -p 3306:3306 mysql-custom