跳至主要內容

容器改变世界

大约 18 分钟约 5321 字

[TOC]

容器改变世界

1 虚拟化与容器

容器和虚拟机是两种不同的虚拟化技术,它们各有优缺点,具体如下:

容器(Container):

优点:

  • 快速启动:容器是基于宿主机操作系统内核的虚拟化技术,因此启动速度非常快,可以在几秒钟内启动。
  • 轻量级:容器可以共享宿主机的操作系统内核,因此容器的资源占用相对较少。
  • 易于管理:容器可以通过容器编排工具进行集中管理,可快速部署、扩展和升级。
  • 更高的性能:由于容器直接运行在宿主机上,因此不需要额外的虚拟化层,可以获得更高的性能。

缺点:

  • 不同宿主机的差异性:容器的应用程序运行在宿主机的操作系统内核上,因此如果在不同的宿主机上运行,则可能会受到宿主机的差异性影响。
  • 安全性问题:如果容器中的一个应用程序被攻击,则可能会影响容器中运行的其他应用程序。
  • 网络配置较为复杂:在多个容器之间建立网络连接和配置网络规则比较复杂。

虚拟机(Virtual Machine):

优点:

  • 可以在不同的操作系统上运行:虚拟机可以模拟出一个完整的操作系统环境,可以在不同的操作系统上运行。
  • 隔离性:不同的虚拟机之间是完全隔离的,即使一个虚拟机被攻击,也不会影响其他虚拟机的运行。
  • 更安全:由于虚拟机之间是隔离的,因此安全性相对较高。
  • 网络配置相对容易:虚拟机之间建立网络连接和配置网络规则相对容易。

缺点:

  • 启动速度慢:虚拟机需要启动完整的操作系统,因此启动速度相对较慢。
  • 资源占用较高:每个虚拟机都需要完整的操作系统和应用程序支持,因此资源占用相对较高。
  • 管理和部署较为繁琐:虚拟机需要进行操作系统和应用程序的管理和维护,因此相对繁琐。

image-20230331152521012

1.1 虚拟化

虚拟化操作系统

1.2 容器

IaaS、 PaaS、 SaaS 和 CaaS 是不同类型的云计算服务

IaaS (基础设施即服务) : 在 IaaS 中,云提供商通过互联网向客户提供虚拟化的计算资源,如服务器、存储和网络。客户可以使用这些资源来构建和管理自己的 IT 基础设施,包括操作系统和应用程序。IaaS 提供商的例子包括 Amazon Web Services (AWS)、 Microsoft Azure 和 Google Cloud Platform

PaaS (平台即服务) : 在 PaaS 中,云提供商为客户提供一个开发、运行和管理应用程序的平台。该平台包括必要的基础设施,如服务器、存储和网络,以及用于构建、测试和部署应用程序的工具。客户可以专注于编写自己的应用程序,而不必担心管理底层基础设施。PaaS 提供商的例子包括 Heroku、 Google App Engine 和 Microsoft Azure。

SaaS (Software as a Service) : 在 SaaS 中,云提供商通过互联网提供软件应用程序,通常是以订阅为基础。客户可以通过网络浏览器或其他客户端软件访问软件,而无需自己安装和维护软件。SaaS 提供商的例子包括 Salesforce、 Zoom 和 Dropbox。

CaaS (Container as a Service) : 在 CaaS 中,云提供商为客户提供了一个管理和编排容器的平台。容器是打包应用程序及其依赖项的轻量级方法,使其更容易部署和管理。CaaS 平台为客户部署和管理容器提供了必要的基础设施和工具,而不必管理底层服务器和网络。CaaS 提供者的例子包括 Amazon Elastic Container Service (ECS)、 Google Kubernetes Engine (GKE)和 Microsoft Azure Container Instances (ACI)。

2 docker容器

2.1 docker容器介绍

1)镜像,容器,应用关系

容器安全服务open in new window

image-20230331153623388

2.2 docker登录

1)docker官方文档

docker官方文档open in new window

2)docker hub登录

第一次登录,需要注册账号,注册完账号点击sign in登录,登录进去,在搜索框里面选择自己需要的镜像即可

image-20230331153906032

image-20230331153851173

image-20230331153729330

image-20230331154009753

2.3 容器架构

1)容器C/S架构⭐⭐⭐

docker架构open in new window

  • 客户端
  • 服务端
  • 远程镜像仓库

image-20230331154055885

2.4 安装docker

1)配置docker清华源

  • 清华源

清华源open in new window

# 安装依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

# 下载centos/redhat版本repo文件
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 软件仓库地址替换为清华源
sudo sed -i 's+download.docker.com+mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo
  • 华为云

    华为云服务器,centos7.9系统安装docker-ce配置repo源,云服务器不需要配置镜像加速

image-20230331154351527

image-20230331154547278

2)安装docker-ce

sudo yum makecache fast
sudo yum install docker-ce

3)设置镜像加速

  • 阿里云配置镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://krtjlnjl.mirror.aliyuncs.com"]
}
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl enable docker --now

image-20230331154620097

image-20230331154643802

4)检查docker

yum list |grep dockerrpm -qa | grep docker

image-20230331154656321

image-20230331154704709

2.5 docker命令使用

1)查看docker信息

# 查看docker信息
docker info

# 查看docker版本
docker version

2)拉取镜像

docker pull 

3) 查看本地镜像

docker images

4)运行容器

案例1-下载hello-world镜像并运行

docker run hello-world

image-20230331154720002

案例2-下载nginx:alpine镜像并运行

# 容器命名不符合命名规范,包含空格
docker run -d -p 80:80 --name "nginx container by rhythm" nginx:alpine

# 正确的容器名 下划线_连接
docker run -d -p 80:80 --name "nginx_container_by_rhythm" nginx:alpine

# 开启linux内核端口转发
[root@docker01 ~]# tail -1 /etc/sysctl.conf 
net.ipv4.ip_forward = 1
[root@docker01 ~]# cat /etc/sysctl.conf
net.ipv4.ip_forward = 1

# 从/etc/sysctl.conf读取值,并立即生效
[root@docker01 ~]# sysctl -p
net.ipv4.ip_forward = 1

image-20230331154733814

# 查看docker run帮助
docker run --help

# 查看docker run帮助
man docker run

2.6 docker镜像命令⭐⭐⭐

docker参考文档open in new window

1)拉取镜像

案例3-拉取镜像nginx:1.22-alpine

# 默认下载latest版本镜像
docker pull nginx:latest

docker pull hello-world

# 指定下载nginx:1.22版本 alpine系统
docker pull nginx:1.22-alpine

2)查看镜像

docker image lsdocker images

3)查找镜像

# 命令行搜索
docker search nginx

# docker hub官网搜索
hub.docker.com

4)推送镜像

docker push sweetpage/nginx

5)save保存镜像

sl大法

# 保存hello-world镜像
docker image save hello-world:latest -o hello-world.tar

# 批量导出所有镜像
[root@docker01 ~]# docker images  | awk 'NR>1{print "docker save "$1":"$2" -o " $1"_"$2".tar"}' |bash

# 逗号,在awk拼接语句中,输出时使用空格替代
docker images  | awk 'NR>1{print "docker save "$1":"$2",-o,"$1"_"$2".tar"}' |bash

image-20230331154752796

6)load加载镜像

# 加载hello-world镜像
docker image load -i hello-world.tar

7)镜像打tag标签

# 可以看到新生成的tag和原tag对应的image id是一样的,类似硬链接
docker image tag hello-world:latest hello-world:rhythm

image-20230331154830611

8)查看镜像内部详细信息

# docker inspect和docker images中镜像id对应关系 <ID:feb5d9fea6a5 前12位对应镜像id>
docker inspect  hello-world:latest

image-20230331154841187

image-20230331154851177

9)删除镜像

docker rmi 三种删除镜像标签方法:

  • 基于镜像名 :docker rmi centos
  • 基于tag标签名 :docker rmi centos:7
  • 基于镜像ID :docker rmi 08f7eebd39d6
# 根据镜像标签删除镜像
docker rmi <REPOSITORY>:<TAG>

# 删除镜像centos-php-mariadb-docfile-yum:latest
[root@docker01 ~]# docker rmi centos-php-mariadb-docfile-yum:latest 
Untagged: centos-php-mariadb-docfile-yum:latest

image-20230331154904225

  • 强制删除镜像

    💁‍♂️提示:如果您要删除正在使用的 Docker 镜像或标签,则需要先停止使用该镜像或标签的容器。否则,Docker 将拒绝删除正在使用的镜像或标签,但是可以使用-f来强制删除镜像

    -f 强制删除镜像

# 删除镜像
docker image rm hello-world:latest或 docker rmi nginx:alpine

# 提示无法移除镜像参考的镜像仓库,容器再使用参考的镜像时
# -f强制删除镜像
docker image rm -f nginx:alpine

image-20230331154916266

2.7 docker容器命令⭐⭐⭐

容器:运行的镜像就是容器,1个容器相当于1个进程

容器相关命令,支持tab键补全

docker命令行参考文档open in new window

1)运行容器(run)

当使用docker run命令启动容器时,Docker底层会执行以下几个主要步骤:

  1. 创建容器:Docker会创建一个新的容器实例,该实例包含容器的文件系统、网络和其他配置。
  2. 创建命名空间:Docker会使用Linux的命名空间技术,创建一个独立的进程命名空间,使容器内的进程与宿主机器上的进程相隔离。
  3. 分配文件系统:Docker会为容器分配一个独立的文件系统,包括容器内部的文件和目录。这个文件系统可以是基于镜像的,也可以是可写的,具体取决于你如何启动容器。
  4. 分配网络:Docker会分配一个独立的网络命名空间,为容器提供一个独立的网络栈。Docker还会为容器分配一个IP地址,并将其映射到宿主机器上的端口,使得容器可以被访问。
  5. 启动容器进程:Docker会在容器内部启动一个进程,这个进程通常是应用程序或服务。在启动进程之前,Docker会应用容器的配置,并将它们传递给容器内部的进程。

总的来说,docker run命令会执行一系列的步骤,将容器和宿主机器之间的资源和隔离度进行配置,使得容器能够运行并且与宿主机器进行交互。

docker run == docker pull + create + start

  • docker pull 拉取镜像
  • docker create 创建容器
  • docker start 启动容器
  • docker stop 停止容器
  • docker kill 杀死容器
  • docker restart 重启容器
# 使用nginx:alpine镜像运行容器,容器名rhythm_nginx_alpine1
docker run -d -p 80:80  --name "rhythm_nginx_alpine1" nginx:alpine

# -d选项 后台运行daemon模式,不加-d,可能运行容器的时候,在前台,会有容器内部信息输出
# -p选项 端口映射,实际是通过iptables防火墙做的nat转换,访问host主机的80端口就相当于访问容器的80端口
# -p选项 端口范围:端口范围 例如: -p 80-84:80-84 宿主机的80到84端口,对应docker容器的80-84
# --name 设置容器名,注意命名规范不能使用空格,可以使用_连接字符串

image-20230331154924885

image-20230331154932313

# 创建容器
docker create --name "nginx_alpine_create_container" nginx:alpine

# 启动容器
docker container start nginx_alpine_create_container

image-20230331154943126

2)查看运行的容器(ps 或ps -a)

docker ps官网使用open in new window

# 查看运行中的容器
docker ps
等价于
docker container ps

# 查看所有状态的容器
docker ps -a

# 只查看容器的ID
docker ps -q

image-20230331154950124

image-20230331154957467

# 浏览器访问nginx:alpine镜像运行的容器
http://www.rhythmcloud.cn:8088/

image-20230331155301949

3)停止运行的容器(stop)

# 停止运行中的容器
docker container stop rhythm_nginx_alpine1

4)删除容器(rm)

# 删除容器
# docker rm 容器ID或容器名
docker rm rhythm_nginx_alpine1
或者
docker container rm 容器ID或容器名

# 选项 -f 强制删除容器(包括运行的容器,危险操作,容易导致容器内服务运行的数据丢失)
docker rm -f 容器ID 

# 强制删除所有容器
docker rm -f `docker ps -q`

5)创建centos容器,并进入(-it)

# 新建1个centos容器,并进入容器
docker run -it --name "rhythm_centos" centos:latest

# 查看容器内进程信息
ps -ef

docker run -it --name "rhythm_centos7.9_2009" centos:centos7.9.2009

image-20230331155331112

6)查看容器信息(stats|inspect|top)

docker stats 容器名 # 查看容器id,name,cpu,mem/limit mem% net i/o block i/o pid进程数
docker inspect 容器名 # 查看容器详细信息
docker top 容器名 # 查看容器中的进程

image-20230331155340484

image-20230331155348080

image-20230331155357505

7)持续运行容器(-itd)

docker run -itd --name "rhythm_centos7.9_2009" centos:centos7.9.2009 /bin/bash

8)连接进入已经启动的容器(exec)

  • docker exec
# 多个tty终端执行exec连接到同1个容器,执行操作,在所有终端上是相互独立的
docker exec -it 运行的容器名 /bin/bash或/bin/sh

# nginx:alpine镜像起的容器,没有/bin/bash命令,可以使用/bin/sh登录
docker exec -ti rhythm_nginx_alpine1 /bin/bash

# 使用/bin/sh正常登录容器
docker exec -ti rhythm_nginx_alpine1 /bin/sh

image-20230331155415272

image-20230331155423991

image-20230331155433174

  • docker attach
# 多个tty终端执行attach连接到同1个容器,执行操作,在所有终端上是同步的,不是相互独立的
docker container attach rhythm_centos7.9_2

8)宿主机拷贝文件到容器(容器到宿主机cp)

  • 宿主机拷贝文件到容器
# 下载百度首页,并保存为index.html
curl -o index.html www.baidu.com

# 拷贝index.html到容器
docker container cp index.html rhythm_nginx_alpine1:/usr/share/nginx/html/index.html

# 宿主机curl访问本地80端口
curl localhost

# 浏览器访问容器主页
http://docker.rhythmcloud.cn/

# 更多帮助
docker container cp --help
  • 拷贝容器文件到宿主机
docker container cp rhythm_nginx_alpine1:/usr/share/nginx/html/index.html /tmp/index.html

image-20230331155456033

9)生成镜像(commit)⭐⭐⭐

docker commit: 在学习docker file之前自定义镜像方法

# 上传静态网站代码restart-new.zip
# lrzsz上传静态网站代码到docker01
# 拷贝网站代码到容器内,并解压
docker container cp restart-new.zip rhythm_nginx_alpine1:/app/code/restart

# 修改nginx配置文件
vi /etc/nginx/conf.d/default.conf

# nginx容器配置文件
/app/code/restart # cat /etc/nginx/conf.d/default.conf
server {
  listen 80;
  server_name restart.rhythmcloud.cn;
  root /app/code/restart;
  location / {
    index index.html;
  }
  location ~* \.css$ {
    root /app/code/restart/css;
  }
}

# 检查语法,并重启nginx
nginx -t
nginx -s reload

# 浏览器访问docker01的80端口
http://docker.rhythmcloud.cn/

image-20230331155538329

  • docker commit
# 将指定的容器使用docker commit生成指定的镜像
# 语法格式:docker container commit 或 commit 容器名 镜像名(命名空间+系统+版本信息)
docker commit rhythm_nginx_alpine1 nginx:alpine-restart-v1

# 通过commit新生成的镜像运行容器81端口
docker run -d -p 81:80 --name "rhythm-nginx-commit-create" nginx:alpine-restart-v1

image-20230331155812266

image-20230331155820049

# 浏览器访问81端口
http://docker.rhythmcloud.cn:81/

2.8 端口映射

端口映射的作用:实现外部人员访问宿主机内的容器

-p参数

#端口映射的本质就是通过iptables防火墙,给nat表添加了一条DOCKER链规则,具体如下:
#将docker宿主机上非docker0网卡(宿主机其他物理网卡来的流量)的tcp协议,tcp数据包,目的地是8888端口的流量转发到容器内的ip地址172.17.0.10和端口80上
#docker宿主机需要启用ip转发功能,确保流量在宿主机和容器正确转发
#iptables规则说明:
iptables -t nat  -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8888 -j DNAT --to-destination 172.17.0.10:80

image-20230331155857926

1)1对1端口映射

# -p 80:80 宿主机80端口:容器80端口
# -p :80 宿主机随机端口:容器80端口
# -p 80-84:8080-8084 宿主机80-84端口:容器8080-8084端口(端口范围)
docker run -d -p 80:80 --name "nginx_alpine_rhythm_v1" nginx:alpine-restart-v1
docker run -d -p :80 --name "nginx_alpine_rhythm_v2" nginx:alpine-restart-v1
docker run -d -p 80-84:8080-8084 --name "nginx_alpine_rhythm_v3" nginx:alpine-restart-v1

2)映射多个端口

多个-p映射多个端口,端口不连续时

docker run -d -p 80:80 -p 443:443 --name "容器名" 镜像名

3)ip绑定端口

只允许指定ip端口访问,出于安全要求

# 宿主机的内网网卡+81端口172.16.1.81:81:容器的80端口 容器名 镜像名
docker run -d -p 172.16.1.81:81:80 --name "nginx_alpine_rhythm_81_80" nginx:alpine

[root@docker01 ~]# ss -lntup |grep 81
tcp    LISTEN     0      128    172.16.1.81:81                    *:*                   users:(("docker-proxy",pid=43063,fd=4))

# 使用curl访问
curl 172.16.1.81:81
curl localhost:81
curl 10.0.0.81:81

image-20230331155910011

image-20230331155919326

2.9 数据卷挂载

数据卷挂载的作用:

  • 容器删除后,容器中的数据就被丢失了,如何持久化存储,就引入了数据卷挂载,实现将宿主机的文件或目录挂载到容器中,修改宿主机的文件就修改了容器运行时使用的文件

  • 将宿主机文件和目录挂载到容器中,就不需要单独进入容器,修改容器内的文件和目录,只需要修改宿主机中的即可

  • 多个容器,

数据卷挂载命令:docker run -v参数

docker官网volumesopen in new window

1)挂载宿主机主页文件到容器

# 宿主机创建主页文件
mkdir -p /app/docker/code
echo "volume test in container" >> index.html


# 挂载宿主机主页文件到容器(一行)
docker run -d -p 80:80 --name "nginx_alpine_volume" -v /app/docker/code/index.html:/usr/share/nginx/html/index.html nginx:alpine

# 将上面一行写成多行(使用\续行符,后面不能跟空格,直接回车换行)
docker run -d -p 80:80 --name "nginx_alpine_volume" \
-v /app/docker/code/index.html:/usr/share/nginx/html/index.html \
nginx:alpine

# 浏览器访问
http://docker.rhythmcloud.cn/

image-20230331155937069

# 使用echo追加内容(echo修改文件内容之后,不会修改文件的inode号)
echo "rhythm volume test in container" >> index.html

# 浏览器访问
http://docker.rhythmcloud.cn/

image-20230331163959365

2)inspect查看volume挂载信息

docker inspect nginx_alpine_volume | jq .[].HostConfig.Binds

image-20230331160103356

案例1:挂载代码目录,配置文件和目录⭐⭐⭐

挂载,映射多个文件+目录使用多个-v选项

# 运行容器,使用-v挂载, --restart=always表示重启后,容器会自启动
docker run -d -p 81:80 --name "restart_volume" \
-v /app/docker/restart/code/:/app/code/restart \
-v /app/docker/restart/conf/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /app/docker/restart/conf/nginx/conf.d/:/etc/nginx/conf.d/ \
--restart=always \
nginx:alpine

# 浏览器访问容器81端口
http://docker.rhythmcloud.cn:81/

image-20230331160116055

# 在宿主机修改容器的restart.conf配置文件,给css文件添加expires时间
# F12打开开发工具-开启响应头cache-control,查看超时时间
[root@docker01 /app/docker/restart/conf/nginx/conf.d]# cat restart.conf 
server {
  listen 80;
  server_name restart.rhythmcloud.cn;
  root /app/code/restart;
  location / {
    index index.html;
  }
  location ~* \.css$ {
    root /app/code/restart/css;
    expires 10d;
  }
}

# 浏览器刷新,F12开发工具查看

案例2:创建数据卷空间

两种方法查看容器中日志:

  • 访问日志格式是软链接格式的,可以在容器外使用docker logs查看

  • 访问日志是文件的使用head tail cat等查看,也可以通过创建软链接,实现docker logs查看

# 创建数据卷rhythmlogdata
docker volume create rhythmlogdata

# 查看数据卷
docker volume ls

# 查看数据卷路径:/var/lib/docker/volumes/数据卷名/
ls /var/lib/docker/volumes/rhythmlogdata/

# 运行容器,挂载rhythmlogdata到nginx:alpine容器的日志目录/var/log/nginx
docker run -d --name "datavolume_nginx_alpine" -v rhythmlogdata:/var/log/nginx/ -p :80 nginx:alpine 

# 查看数据卷挂载信息
ls -al /var/lib/docker/volumes/rhythmlogdata/_data
lrwxrwxrwx 1 root root 11 Dec 30  2021 access.log -> /dev/stdout
lrwxrwxrwx 1 root root 11 Dec 30  2021 error.log -> /dev/stderr

# 查看数据库容器日志,查看nginx日志
# 格式:docker logs 容器名
# --since 加时间,表示至从某1个时间到现在,例如 --since 120m,表示最近的120分钟的日志
docker logs mariadb --since 120m
docker logs nginx_alpine --since 120m

# 查看nginx_alpine容器内日志的时间不正确(需要修改时区)
# 具体查看chatgpt解决方案
[root@docker01 ~]# docker logs nginx_alpine --since 120m
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/03/27 08:30:41 [notice] 1#1: using the "epoll" event method
2023/03/27 08:30:41 [notice] 1#1: nginx/1.21.5
2023/03/27 08:30:41 [notice] 1#1: built by gcc 10.3.1 20211027 (Alpine 10.3.1_git20211027) 
2023/03/27 08:30:41 [notice] 1#1: OS: Linux 3.10.0-1160.el7.x86_64
2023/03/27 08:30:41 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2023/03/27 08:30:41 [notice] 1#1: start worker processes
2023/03/27 08:30:41 [notice] 1#1: start worker process 32
2023/03/27 08:31:05 [notice] 1#1: signal 3 (SIGQUIT) received, shutting down
2023/03/27 08:31:05 [notice] 32#32: gracefully shutting down
2023/03/27 08:31:05 [notice] 32#32: exiting
2023/03/27 08:31:05 [notice] 32#32: exit
2023/03/27 08:31:05 [notice] 1#1: signal 17 (SIGCHLD) received from 32
2023/03/27 08:31:05 [notice] 1#1: worker process 32 exited with code 0
2023/03/27 08:31:05 [notice] 1#1: exit

image-20230331160137415

  • 容器时区问题
# nginx:alpine容器时间修改为中国时间
docker exec -it <container_name_or_id> sh
apk add --no-cache tzdata
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo "Asia/Shanghai" > /etc/timezone

# 退出容器再进,执行时间命令查看
date

image-20230331160219631

案例3:启动1个mariadb容器

具体启动mariadb容器实例,可以查看hub.docker.com中mariadb官方镜像使用说明

image-20230331160233608

image-20230331160244425

# 运行mariadb容器
# 运行时需要加-e或--env环境变量,否则容器会自动停止
docker run --detach --name some-mariadb  --env MARIADB_ROOT_PASSWORD=1  mariadb:latest

# 进入容器启动mysql
docker exec -it some-mariadb /bin/bash
mysql -uroot -p1

// 2 运行容器时,直接加mysql -uroot -p1
docker run -d --name maraidb -e MARIADB_ROOT_PASSWORD=1 mariadb:latest

# 直接接mysql命令进入数据库,不需要先进入/bin/bash后执行mysql命令
docker exec -it maraidb mysql -uroot -p1

image-20230331160253588

image-20230331160300861

image-20230331160308523