Docker相关学习
8月8日更新
# Docker介绍
大型项目组件较多,运行环境也较为复杂,部署时会碰到一些问题:
- 依赖关系复杂,容易出现兼容性问题
- 开发、测试、生产环境有差异
Docker如何解决依赖的兼容问题的?
- 将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包
- 将每个应用放到一个隔离容器去运行,避免互相干扰
注意:仅限于同一个操作系统,这是因为docker是在操作系统的基础空间上运行的。
# Docker如何解决不同的操作系统
内核与硬件交互,提供操作硬件的指令
系统应用封装内核指令为函数,便于程序员调用
用户程序基于系统函数库实现功能
为什么应用需要在同一个操作系统中?
这是因为虽然都是基于Linux内核,但是系统应用不同,提供的函数库有差异。例如CentOS中没有Ubuntu中的某些函数库。
函数库是写死的,是执行时调用的方法函数。所以Docker会将依赖和需要的函数库一起打包。这样,就不会管系统应用是什么了,可以直接操作内核。
Docker如何解决不同系统环境的问题?
- Docker将用户程序与所需要调用的系统(比如Ubuntu)函数库一起打包
- Docker运行到不同操作系统时,直接基于打包的库函数,借助于操作系统的Linux内核来运行
Docker如何解决大型项目依赖关系复杂,不同组件依赖的兼容性问题?
- Docker允许开发中将应用、依赖、函数库、配置一起打包,形成可移植镜像
- Docker应用运行在容器中,使用沙箱机制,相互隔离
Docker如何解决开发、测试、生产环境有差异的问题
- Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意Linux操作系统上运行
# Docker与虚拟机
虚拟机(virtual machine)是在操作系统中模拟硬件设备,然后运行另一个操作系统,比如在 Windows 系统里面运行 Ubuntu 系统,这样就可以运行任意的Ubuntu应用了。
Docker与虚拟机的对比:
Docker和虚拟机的差异:
- docker是一个系统进程;虚拟机是在操作系统中的操作系统
- docker体积小、启动速度快、性能好;虚拟机体积大、启动速度慢、性能一般
# Docker镜像和容器
镜像(Image):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。
容器(Container):镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器做隔离,对外不可见。
通过Linux的隔离手段,一个容器会以为自己是当前计算机系统上的唯一进程,从而做到了隔离效果。
# 关于数据读取
容器是不可以把数据写入镜像文件中的,因为会对镜像进行污染。所以镜像只读不写。若要写数据,则拷贝一份文件到容器自己的独立文件系统里。
# Docker和DockerHub
- DockerHub:DockerHub是一个Docker镜像的托管平台。这样的平台称为Docker Registry。
- 国内也有类似于DockerHub 的公开服务,比如 网易云镜像服务、阿里云镜像库等。
# Docker架构
Docker是一个CS架构的程序,由两部分组成:
- 服务端(server):Docker守护进程,负责处理Docker指令,管理镜像、容器等
- 客户端(client):通过命令或RestAPI向Docker服务端发送指令。可以在本地或远程向服务端发送指令。
# Docker架构小结
镜像:
- 将应用程序及其依赖、环境、配置打包在一起
容器:
- 镜像运行起来就是容器,一个镜像可以运行多个容器
Docker结构:
- 服务端:接收命令或远程请求,操作镜像或容器
- 客户端:发送命令或者请求到Docker服务端
DockerHub:
- 一个镜像托管的服务器,类似的还有阿里云镜像服务,统称为DockerRegistry
# 安装Docker
# 操作系统版本
Docker CE 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10, CentOS 7 满足最低内核的要求,所以我们在CentOS 7安装Docker。
# 官网
https://www.docker.com (opens new window)
# 1.1.卸载(可选)
如果之前安装过旧版本的Docker,可以使用下面命令卸载:
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine \
docker-ce
2
3
4
5
6
7
8
9
10
11
# 1.2.安装docker
首先需要大家虚拟机联网,安装yum工具
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2 --skip-broken
2
3
然后更新本地镜像源:
# 设置docker镜像源
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
yum makecache fast
2
3
4
5
6
7
8
然后输入命令:
yum install -y docker-ce
docker-ce为社区免费版本。稍等片刻,docker即可安装成功。
# 1.3.启动docker
Docker应用需要用到各种端口,逐一去修改防火墙设置。非常麻烦,因此建议大家直接关闭防火墙!
启动docker前,关闭防火墙(一般不用关闭)
# 关闭
systemctl stop firewalld
# 禁止开机启动防火墙
systemctl disable firewalld
2
3
4
通过命令启动docker:
systemctl start docker # 启动docker服务
systemctl stop docker # 停止docker服务
systemctl restart docker # 重启docker服务
2
3
4
5
然后输入命令,可以查看docker版本:
docker -v
# 方式二安装
# 1.yum包更新到最新
yum update
# 2.安装需要的软件包,yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
yum install -y yum-utils device-mapper-persistent-data lvm2
# 3.设置yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 4.安装docker,出现输入的界面都按 y
yum install -y docker-ce
# 5.查看docker版本,验证是否成功
docker -v
2
3
4
5
6
7
8
9
10
# 配置镜像加速器
一这里使用的是阿里云的镜像加速器,地址:
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors (opens new window)
以下为阿里云提供的操作文档:
针对Docker客户端版本大于 1.10.0 的用户
您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
# 创建了一个文件
sudo mkdir -p /etc/docker
# 将阿里云的镜像文件配置写入文件内
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://4p32toi3.mirror.aliyuncs.com"]
}
EOF
# 重载
sudo systemctl daemon-reload
# 重启docker
sudo systemctl restart docker
2
3
4
5
6
7
8
9
10
11
12
# Docker基本操作
# 镜像相关命令
- 镜像名称一般分两部分组成:[repository]:[tag]。
- 在没有指定tag时,默认是latest,代表最新版本的镜像
# 镜像操作命令
# 从DockerHub拉取一个镜像
DockerHub官网:
https://hub.docker.com (opens new window)
搜索镜像名称,例如Nginx:
镜像详情页会有所有版本已经介绍,在右侧会有pull命令:
在控制面板输入命令,等待安装即可:
[root@VM-8-14-centos ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete
a9edb18cadd1: Pull complete
589b7251471a: Pull complete
186b1aaa4aa6: Pull complete
b4df32aa5a72: Pull complete
a0bcbecc962e: Pull complete
Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
2
3
4
5
6
7
8
9
10
11
12
通过输入docker images
命令可以查看目前已经pull下来的镜像:
[root@VM-8-14-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 7 months ago 141MB
hello-world latest feb5d9fea6a5 10 months ago 13.3kB
2
3
4
# 利用docker save导出镜像到磁盘,load加载回来
步骤一:利用docker xx --help命令查看docker save和docker load的语法
docker save
[root@VM-8-14-centos ~]# docker save --help
Usage: docker save [OPTIONS] IMAGE [IMAGE...]
# 保存一个或多个镜像到tar文件中
Save one or more images to a tar archive (streamed to STDOUT by default)
Options:
-o, --output string Write to a file, instead of STDOUT
2
3
4
5
6
7
8
docker load
-i:打印日志
-q:安静的,不会打印日志
[root@VM-8-14-centos ~]# docker load --help
Usage: docker load [OPTIONS]
Load an image from a tar archive or STDIN
Options:
-i, --input string Read from tar archive file, instead of STDIN
-q, --quiet Suppress the load output
2
3
4
5
6
7
8
9
步骤二:使用docker save导出镜像到磁盘
使用docker save -o [保存到哪一个文件] [镜像名称:tag]
导出
可以看到,导出了镜像文件到nginx.tar中:
[root@VM-8-14-centos ~]# docker save -o nginx.tar nginx:latest
[root@VM-8-14-centos ~]# ll
total 142532
-rw-r--r-- 1 root root 1781 Apr 8 2021 cosfs.sh
-rw-r--r-- 1 root root 1237 Jan 28 2021 dnspod.sh
-rw-r--r-- 1 root root 25166 Jan 14 2022 install_panel.sh
-rw-r--r-- 1 root root 2258 Mar 3 2021 install.sh
-rw------- 1 root root 145905152 Aug 4 15:50 nginx.tar
-rw-r--r-- 1 root root 1219 Feb 5 2021 txcdn.sh
2
3
4
5
6
7
8
9
步骤三:使用docker load加载镜像
首先我们将镜像删除:docker rmi [镜像名:tag(或者id)]
[root@VM-8-14-centos ~]# docker rmi nginx:latest
Untagged: nginx:latest
Untagged: nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Deleted: sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85
Deleted: sha256:b625d8e29573fa369e799ca7c5df8b7a902126d2b7cbeb390af59e4b9e1210c5
Deleted: sha256:7850d382fb05e393e211067c5ca0aada2111fcbe550a90fed04d1c634bd31a14
Deleted: sha256:02b80ac2055edd757a996c3d554e6a8906fd3521e14d1227440afd5163a5f1c4
Deleted: sha256:b92aa5824592ecb46e6d169f8e694a99150ccef01a2aabea7b9c02356cdabe7c
Deleted: sha256:780238f18c540007376dd5e904f583896a69fe620876cabc06977a3af4ba4fb5
Deleted: sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f
2
3
4
5
6
7
8
9
10
然后我们可以通过load命令来加载镜像了。
执行docker load -i [文件名]
[root@VM-8-14-centos ~]# docker load -i nginx.tar
2edcec3590a4: Loading layer [==================================================>] 83.86MB/83.86MB
e379e8aedd4d: Loading layer [==================================================>] 62MB/62MB
b8d6e692a25e: Loading layer [==================================================>] 3.072kB/3.072kB
f1db227348d0: Loading layer [==================================================>] 4.096kB/4.096kB
32ce5f6a5106: Loading layer [==================================================>] 3.584kB/3.584kB
d874fd2bc83b: Loading layer [==================================================>] 7.168kB/7.168kB
Loaded image: nginx:latest
2
3
4
5
6
7
8
9
# 容器相关命令
暂停:系统会将容器进程挂起,将容器关联的内存暂存起来,恢复之后,接着被运行。
停止:系统将进程杀死,将内存回收。start之后,会重新创建全新的进程。
# 创建一个容器
步骤一:去docker hub查看Nginx的容器运行命令命令
docker run --name containerName -p 80:80 -d nginx
解读:
- docker run :创建并运行一个容器
- --name : 给容器起一个名字,比如叫做mn
- -p :将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口
- -d:后台运行容器
- nginx:镜像名称,例如nginx
通过以下命令来创建一个容器:
docker run --name mn -p 80:80 -d nginx
[root@VM-8-14-centos ~]# docker run --name mn -p 80:80 -d nginx
9b0adfd41703d6ceec00396bcaf52c8dd9bc6a5371c1e1052d7169fb9069e0e5
docker: Error response from daemon: driver failed programming external connectivity on endpoint mn (e4a71cb76504ad0921984b224a6289bb07d497c490344440d40396182ade2bb7): Error starting userland proxy: listen tcp4 0.0.0.0:80: bind: address already in use.
2
3
以上是报错信息,因为端口号被占用,使用另外的端口就行了。
[root@VM-8-14-centos ~]# docker run --name mn -p 81:80 -d nginx
15c2c5c87c8d81150a244014beb60e977ae8e8be0b987b109fda82f3f11b8427
2
创建成功之后,通过ip加上代理的port端口号便可访问:
可以使用docker logs [容器名称]
查看日志
[root@VM-8-14-centos ~]# docker logs mn
/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
2022/08/04 08:53:04 [notice] 1#1: using the "epoll" event method
2022/08/04 08:53:04 [notice] 1#1: nginx/1.21.5
2022/08/04 08:53:04 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2022/08/04 08:53:04 [notice] 1#1: OS: Linux 3.10.0-1160.49.1.el7.x86_64
2022/08/04 08:53:04 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/08/04 08:53:04 [notice] 1#1: start worker processes
2022/08/04 08:53:04 [notice] 1#1: start worker process 32
2022/08/04 08:53:04 [notice] 1#1: start worker process 33
112.94.13.13 - - [04/Aug/2022:08:55:26 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" "-"
112.94.13.13 - - [04/Aug/2022:08:55:26 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://43.138.140.213:81/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" "-"
2022/08/04 08:55:26 [error] 33#33: *2 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 112.94.13.13, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "43.138.140.213:81", referrer: "http://43.138.140.213:81/"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
持续的日志输出
因为上述的日志是要自己手动获取的,不太方便于调试。
我们可以执行docker logs -f [容器名]
# 进入容器,修改内容
步骤一:进入容器。进入我们刚刚创建的nginx容器的命令为:
docker exec -it [容器名称] bash
命令解读:
- docker exec :进入容器内部,执行一个命令
- -it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
- mn :要进入的容器的名称
- bash:进入容器后执行的命令,bash是一个linux终端交互命令
进入后会发现,前置的编号就是容器的ID:
[root@VM-8-14-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
15c2c5c87c8d nginx "/docker-entrypoint.…" 8 minutes ago Up 8 minutes 0.0.0.0:81->80/tcp, :::81->80/tcp mn
[root@VM-8-14-centos ~]# docker exec -it mn bash
root@15c2c5c87c8d:/#
2
3
4
5
6
我们试试看执行ls
命令,会发现其目录的结构和Linux基本一样:
root@15c2c5c87c8d:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
2
3
但是,这些文件,只有与nginx有关的才是有意义的。
那么我们怎么知道nginx的文件放在哪一个文件下呢?我们不知道。不过我们可以借助dockerhub官网查看。
Alternatively, a simple
Dockerfile
can be used to generate a new image that includes the necessary content (which is a much cleaner solution than the bind mount above):FROM nginx COPY static-html-directory /usr/share/nginx/html
1
2
我们可以知道,nginx的静态资源存放在了/usr/share/nginx/html下。
我们进入路径下,查看路径文件,可以看到有两个html文件
root@15c2c5c87c8d:/# cd /usr/share/nginx/html
root@15c2c5c87c8d:/usr/share/nginx/html# ls
50x.html index.html
2
3
我们执行以下命令,可以直接修改文件中的内容:
sed -i 's#Welcome to nginx#早睡蛋学docker#g' index.html
sed -i 's#<head>#<head><meta charset="utf-8">#g' index.html
2
# 退出容器
# 命令
exit
2
# 停止容器
# 命令
docker stop [容器名]
2
# 删除容器
# 命令
docker rm [容器名]
2
注意,删除前要先停止容器,不然删除不了:
[root@VM-8-14-centos ~]# docker rm mn
Error response from daemon: You cannot remove a running container 15c2c5c87c8d81150a244014beb60e977ae8e8be0b987b109fda82f3f11b8427. Stop the container before attempting removal or force remove
2
我们可以使用强制删除命令来删除,这样就不用每次都先停再删了。
docker rm -f [容器名]
# Docker运行Redis容器
# 目的
创建并运行一个Redis容器,并且支持数据持久化
# 步骤
步骤一:到DockerHub搜索Redis镜像
步骤二:查看Redis镜像文档中的帮助信息
启动redis容器
$ docker run --name some-redis -d redis
1start with persistent storage(持久化开启)
$ docker run --name some-redis -d redis redis-server --save 60 1 --loglevel warning
1There are several different persistence strategies to choose from. This one will save a snapshot of the DB every 60 seconds if at least 1 write operation was performed (it will also lead to more logs, so the
loglevel
option may be desirable). If persistence is enabled, data is stored in theVOLUME /data
, which can be used with--volumes-from some-volume-container
or-v /docker/host/dir:/data
(see docs.docker volumes (opens new window)).For more about Redis Persistence, see http://redis.io/topics/persistence.
一般我们在run的时候需要指定一下端口,所以命令修改为:
docker run --name mr -p 6378:6379 -d redis redis-server --save 60 1 --loglevel warning
1步骤三:利用docker run 命令运行一个Redis容器
# 进入redis容器,并执行redis-cli客户端命令,存入num=666
- 进入容器
[root@VM-8-14-centos ~]# docker exec -it mr bash
root@6cba24a415a9:/data#
2
- 执行redis-cli客户端命令,查看所有键值对
root@6cba24a415a9:/data# redis-cli
127.0.0.1:6379> keys *
(empty array)
2
3
- 设置数据num=666
127.0.0.1:6379> set num 666
OK
127.0.0.1:6379> keys *
1) "num"
2
3
4
以上命令可以一步到位:
docker exec -it [容器名] redis-cli
# Docker数据卷
# 容器与数据耦合的问题
# 数据卷
数据卷(volume)是一个虚拟目录,指向宿主机文件系统中的某个目录。
# 操作数据卷
数据卷操作的基本语法如下:
docker volume [COMMAND]
docker volume命令是数据卷操作,根据命令后跟随的command来确定下一步的操作:
- create 创建一个volume
- inspect 显示一个或多个volume的信息
- ls 列出所有的volume
- prune 删除未使用的volume
- rm 删除一个或多个指定的volume
# 创建一个数据卷,并查看数据卷在宿主机的目录位置
创建数据卷
docker volume create html
查看所有数据卷
docker volume ls
查看数据卷的详细信息
docker volume inspect html
[root@VM-8-14-centos ~]# docker volume inspect html
[
{
"CreatedAt": "2022-08-05T14:40:01+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/html/_data",
"Name": "html",
"Options": {},
"Scope": "local"
}
]
2
3
4
5
6
7
8
9
10
11
12
其中,存储目录(挂载点)为:
"Mountpoint": "/var/lib/docker/volumes/html/_data",
# /_data为真实存储的
2
# 挂载数据卷
我们在创建容器时,可以通过 -v 参数来挂载一个数据卷到某个容器目录
docker run \
--name mn \
-v html:/root/html \
-p 8080:80
nginx \
2
3
4
5
- docker run :就是创建并运行容器
- -- name mn :给容器起个名字叫mn
- -v html:/root/htm :把html数据卷挂载到容器内的/root/html这个目录中
- -p 8080:80 :把宿主机的8080端口映射到容器内的80端口
- nginx :镜像名称
# 挂载案例
需求说明:上个案例中,我们进入nginx容器内部,已经知道nginx的html目录所在位置/usr/share/nginx/html ,我们需要把这个目录挂载到html这个数据卷上,方便操作其中的内容。
提示:运行容器时使用 -v 参数挂载数据卷
步骤:
- 创建容器并挂载数据卷到容器内的HTML目录
docker run --name mn -p 81:80 -v html:/usr/share/nginx/html -d nginx
- 进入html数据卷所在位置,并修改HTML内容
# 查看html数据卷的位置
docker volume inspect html
# 进入该目录
cd /var/lib/docker/volumes/html/_data
# 修改文件
vi index.html
2
3
4
5
6
我们进入数据卷的目录位置,可以看到,也有两个文件,此时并没有进入容器内部,所以说明我们挂载成功。
[root@VM-8-14-centos ~]# cd /var/lib/docker/volumes/html/_data
[root@VM-8-14-centos _data]# ls
50x.html index.html
2
3
我们进入index.html文件内进行内容修改,修改完成后,我们要证明确实在容器内也保存成功,我们可以直接打开浏览器查看,确实是修改成功了。
中文乱码的在head标签内加上meta charset="utf-8"即可
另外
如果我们把数据卷删掉,我们在运行新的容器时,将他挂载到一个不存在的卷时,docker会帮我们自动创建这个数据卷。
# 挂载案例2
创建并运行一个MySQL容器,将宿主机目录直接挂载到容器
提示:目录挂载与数据卷挂载的语法是类似的:
- -v [宿主机目录]:[容器内目录]
- -v [宿主机文件]:[容器内文件]
实现思路如下:
- 将mysql.tar文件上传到服务器,通过load命令加载为镜像
docker load -i mysql.tar
- 创建目录/tmp/mysql/data
mkdir -p mysql/data
- 创建目录/tmp/mysql/conf,将hmy.cnf文件上传到/tmp/mysql/conf
mkdir -p mysql/conf
去DockerHub查阅资料,创建并运行MySQL容器,要求:
1.挂载/tmp/mysql/data到mysql容器内数据存储目录
2.挂载/tmp/mysql/conf/hmy.cnf到mysql容器的配置文件
3.设置MySQL密码
https://hub.docker.com/_/mysql (opens new window)
-e:环境变量,可以让我们一个命令就设置密码
记得开放对应端口
docker run \
--name mysql \
-e MYSQL_ROOT_PASSWORD=123 \
-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
2
3
4
5
6
7
8
关于两个冒号后面的路径,我们查阅官网可知:
conf配置文件在路径:
The default configuration for MySQL can be found in
/etc/mysql/my.cnf
, which may!includedir
additional directories such as/etc/mysql/conf.d
or/etc/mysql/mysql.conf.d
. Please inspect the relevant files and directories within themysql
image itself for more details.
data文件在路径:
/var/lib/mysql
# 数据挂载的方式对比
docker run的命令中通过 -v 参数挂载文件或目录到容器中:
- -v volume名称:容器内目录
- -v 宿主机文件:容器内文件
- -v 宿主机目录:容器内目录
数据卷挂载与目录直接挂载
- 数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
- 目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看
# Docker镜像结构
镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。
# 自定义镜像(Dockerfile)
Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。
语法说明,请参考官网文档: https://docs.docker.com/engine/reference/builder (opens new window)
# 基于java:8-alpine镜像,将一个Java项目构建为镜像
实现思路如下:
新建一个空的目录,然后在目录中新建一个文件,命名为Dockerfile
拷贝课前资料提供的docker-demo.jar到这个目录中
编写Dockerfile文件:
基于java:8-alpine作为基础镜像
将app.jar拷贝到镜像中
暴露端口
编写入口ENTRYPOINT
使用docker build命令构建镜像
使用docker run创建容器并运行
Dockerfile文件:
# 指定基础镜像
FROM java:8-alpine
# 拷贝java项目的包
COPY ./docker-demo.jar /tmp/app.jar
# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar
2
3
4
5
6
7
8
9
10
使用build命令构建镜像:
[root@VM-8-14-centos docker-demo]# docker build -t javaweb:1.0 .
注意:记得要加 . 这个点代表的是dockerfile文件所在的目录。
构建好了之后,我们可以run一下镜像了。
docker run --name web -p 8090:8090 -d javaweb:1.0
# DockerCompose
# 什么是DockerCompose
- Docker Compose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器!
- Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。
version: "3.8"
services:
mysql:
image: mysql:5.7.25
environment:
MYSQL_ROOT_PASSWORD: 123
volumes:
- "/tmp/mysql/data:/var/lib/mysql"
- "/tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf"
web:
build: .
ports:
- "8090:8090"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DockerCompose的详细语法参考官网:https://docs.docker.com/compose/compose-file/ (opens new window)
# 安装DockerCompose
上传到/usr/local/bin/
目录。Linux下需要通过命令下载:
# 安装
curl -L https://github.com/docker/compose/releases/download/1.23.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
2
# 修改文件权限
修改文件权限:
# 修改权限
chmod +x /usr/local/bin/docker-compose
2
# Base自动补全命令
# 补全命令
curl -L https://raw.githubusercontent.com/docker/compose/1.29.1/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
2
如果这里出现错误,需要修改自己的hosts文件:
echo "199.232.68.133 raw.githubusercontent.com" >> /etc/hosts
# DockerCompose部署微服务
实现思路如下:
- 编写docker-compose文件
- 修改自己的cloud-demo项目,将数据库、nacos地址都命名为docker-compose中的服务名
- 使用maven打包工具,将项目中的每个微服务都打包为app.jar
- 将打包好的app.jar拷贝到cloud-demo中的每一个对应的子目录中
- 将cloud-demo上传至虚拟机,利用 docker-compose up -d 来部署