Docker

Docker

安装Docker

1. 卸载旧版

首先如果系统中已经存在旧的Docker,则先卸载

1
2
3
4
5
6
7
8
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine

2. 配置Docker的yum库

首先需要安装一个yum工具

1
sudo yum install -y yum-utils

安装成功后执行命令,配置Docker的yum源

1
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

3. 安装Docker

最后,执行命令

1
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

4. 启动和校验

1
2
3
4
5
6
7
8
9
10
11
systemctl start docker

systemctl stop docker

systemctl restart docker

# 设置开机自启
systemctl enable docker

# 执行docker ps命令,如果不报错,说明安装启动成功
docker ps

5. 配置镜像加速

阿里云开通容器镜像服务

入门

部署MySQL

1
2
3
4
5
6
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
mysql

镜像和容器

  • 使用Docker安装应用时,Docker会自动搜索并下载应用镜像(image)。镜像不仅包含应用本身,还包含应用所需要的环境、配置、系统函数库。Docker会在运行镜像时创建一个隔离环境,称为容器(container)

  • 镜像仓库:存储和管理镜像的平台,Docker官方维护了一个公共仓库Docker Hub

命令解读

1
2
3
4
5
6
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
mysql

解读:

  • docker run -d :创建并运行一个容器,-d是让容器在后台运行
  • –name mysql : 给容器起个名字,必须唯一
  • -p 3306:3306 : 设置端口映射,宿主机端口映射到容器内端口
  • -e KEY=VALUE : 设置环境变量
  • mysql : 指定运行的镜像名称

镜像命名规范

  • 镜像名称一般分两部分组成:[repository]:[tag]
    • 其中repository就是镜像名
    • tag是镜像的版本
  • 在没有指定tag时,默认时latest,代表最新版本的镜像

基础

常见命令

Use the Docker command line | Docker Docs

其中,比较常见的命令有:

命令 说明 文档地址
docker pull 拉取镜像 docker pull
docker push 推送镜像到DockerRegistry docker push
docker images 查看本地镜像 docker images
docker rmi 删除本地镜像 docker rmi
docker run 创建并运行容器(不能重复创建) docker run
docker stop 停止指定容器 docker stop
docker start 启动指定容器 docker start
docker restart 重新启动容器 docker restart
docker rm 删除指定容器 docs.docker.com
docker ps 查看容器 docker ps
docker logs 查看容器运行日志 docker logs
docker exec 进入容器 docker exec
docker save 保存镜像到本地压缩文件 docker save
docker load 加载本地压缩文件到镜像 docker load
docker inspect 查看容器详细信息 docker inspect
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 第1步,去DockerHub查看nginx镜像仓库及相关信息

# 第2步,拉取Nginx镜像
docker pull nginx

# 第3步,查看镜像
docker images
# 结果如下:
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 16 months ago 141MB
mysql latest 3218b38490ce 17 months ago 516MB

# 第4步,创建并允许Nginx容器
docker run -d --name nginx -p 80:80 nginx

# 第5步,查看运行中容器
docker ps
# 也可以加格式化方式访问,格式会更加清爽
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"

# 第6步,访问网页,地址:http://虚拟机地址

# 第7步,停止容器
docker stop nginx

# 第8步,查看所有容器
docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"

# 第9步,再次启动nginx容器
docker start nginx

# 第10步,再次查看容器
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"

# 第11步,查看容器详细信息
docker inspect nginx

# 第12步,进入容器,查看容器内目录
docker exec -it nginx bash
# 或者,可以进入MySQL
docker exec -it mysql mysql -uroot -p

# 第13步,删除容器
docker rm nginx
# 发现无法删除,因为容器运行中,强制删除容器
docker rm -f nginx

命令别名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 修改/root/.bashrc文件
vi /root/.bashrc

内容如下:
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"'
alias dis='docker images'

# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi

执行命令使别名生效

1
source /root/.bashrc

数据卷

  • 数据卷(volume)是一个虚拟目录,是容器内目录宿主机目录之间映射的桥梁

数据卷命令

数据卷的相关命令有:

命令 说明 文档地址
docker volume create 创建数据卷 docker volume create
docker volume ls 查看所有数据卷 docs.docker.com
docker volume rm 删除指定数据卷 docs.docker.com
docker volume inspect 查看某个数据卷的详情 docs.docker.com
docker volume prune 清除数据卷 docker volume prune
  • 在执行docker run命令时,使用**-v 数据卷:容器内目录**可以完成数据卷挂载
  • 当创建容器时,如果挂载了数据卷且数据卷不存在,会自动创建数据卷
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
30
31
32
33
34
35
36
37
38
39
40
# 1.首先创建容器并指定数据卷,注意通过 -v 参数来指定数据卷
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx

# 2.然后查看数据卷
docker volume ls
# 结果
DRIVER VOLUME NAME
local d39e5d42d021dab48d2cbf817ed481940d832915098c5cbcb3aa6d164e73ae2e
local html

# 3.查看数据卷详情
docker volume inspect html
# 结果
[
{
"CreatedAt": "2023-10-04T16:56:53+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/html/_data",
"Name": "html",
"Options": null,
"Scope": "local"
}
]

# 4.查看/var/lib/docker/volumes/html/_data目录
ll /var/lib/docker/volumes/html/_data
# 可以看到与nginx的html目录内容一样,结果如下:
总用量 8
-rw-r--r--. 1 root root 497 8月 16 01:03 50x.html
-rw-r--r--. 1 root root 615 8月 16 01:03 index.html

# 5.进入该目录,并随意修改index.html内容
cd /var/lib/docker/volumes/html/_data
vi index.html

# 6.打开页面,查看效果

# 7.进入容器内部,查看/usr/share/nginx/html目录内的文件是否变化
docker exec -it nginx bash

本地目录挂载

  • 在执行docker run命令时,使用 **-v 本地目录 : 容器内目录 **可以完成本地目录挂载
  • 本地目录必须以 “/” 或 “./” 开头,如果直接以名称开头,会被识别为数据卷而非本地目录
    • -v mysql : /var/lib/mysql 会被识别为一个数据卷叫mysql
    • -v ./mysql : /var/lib/mysql 会被识别为当前目录下的mysql目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1.删除原来的MySQL容器
docker rm -f mysql

# 2.进入root目录
cd ~

# 3.创建并运行新mysql容器,挂载本地目录
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
-v ./mysql/data:/var/lib/mysql \
-v ./mysql/conf:/etc/mysql/conf.d \
-v ./mysql/init:/docker-entrypoint-initdb.d \
mysql

自定义镜像

  • 镜像就是包含了应用程序、程序运行的系统函数库、运行配置等文件的文件包。构建镜像的过程其实就是把上述文件打包的过程

镜像结构

Dockerfile

  • Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。将来Docker可以根据Dockerdfile来构建镜像
指令 说明 示例
FROM 指定基础镜像 FROM centos:6
ENV 设置环境变量,可在后面指令使用 ENV key value
COPY 拷贝本地文件到镜像的指定目录 COPY ./xx.jar /tmp/app.jar
RUN 执行Linux的shell命令,一般是安装过程的命令 RUN yum install gcc
EXPOSE 指定容器运行时监听的端口,是给镜像使用者看的 EXPOSE 8080
ENTRYPOINT 镜像中应用的启动命令,容器运行时调用 ENTRYPOINT java -jar xx.jar

官方文档

  • 可以基于Ubuntu基础镜像,利用Dockerfile描述镜像结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录、容器内时区
ENV JAVA_DIR=/usr/local
ENV TZ=Asia/Shanghai
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 设定时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安装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 8080
# 入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/app.jar"]
  • 也可以直接基于JDK为基础镜像,省略前面的步骤
1
2
3
4
5
6
7
8
9
# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]

编写好了Dockerfile,可以利用下面命令来构建镜像

1
2
3
4
# 进入镜像目录
cd /root/demo
# 开始构建
docker build -t docker-demo:1.0 .
  • -t:是给镜像起名,格式依然是repository:tag的格式,不指定tag时,默认为latest
  • .:是指定Dockerfile所在目录,如果就在当前目录,则指定为"."

总结

镜像的结构是怎样的?

  • 镜像中包含了应用程序所需要的运行环境、函数库、配置、以及应用本身等各种文件,这些文件分层打包而成

Dockerfile是做什么的?

  • Dockerfile利用固定的指令来描述镜像的结构和构建过程,这样Docker才可以依次来构建镜像

构建镜像的命令是什么?

  • docker build -t 镜像名 Dockerfile目录

网络

  • 默认情况下,所有容器都是以bridge方式连接到Docker的一个虚拟网桥上
  • 加入自定义网络的容器才可以通过容器名互相访问

网络操作命令

Docker的网络操作命令:

命令 说明 文档地址
docker network create 创建一个网络 docker network create
docker network ls 查看所有网络 docs.docker.com
docker network rm 删除指定网络 docs.docker.com
docker network prune 清除未使用的网络 docs.docker.com
docker network connect 使指定容器连接加入某网络 docs.docker.com
docker network disconnect 使指定容器连接离开某网络 docker network disconnect
docker network inspect 查看网络详细信息 docker network inspect
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
30
31
32
33
34
35
# 1.首先通过命令创建一个网络
docker network create hanyang

# 2.然后查看网络
docker network ls
# 结果:
NETWORK ID NAME DRIVER SCOPE
639bc44d0a87 bridge bridge local
403f16ec62a2 hanyang bridge local
0dc0f72a0fbb host host local
cd8d3e8df47b none null local
# 其中,除了hanyang以外,其它都是默认的网络

# 3.让dd和mysql都加入该网络,注意,在加入网络时可以通过--alias给容器起别名
# 这样该网络内的其它容器可以用别名互相访问!
# 3.1.mysql容器,指定别名为db,另外每一个容器都有一个别名是容器名
docker network connect hanyang mysql --alias db
# 3.2.db容器,也就是我们的java项目
docker network connect hanyang dd

# 4.进入dd容器,尝试利用别名访问db
# 4.1.进入容器
docker exec -it dd bash
# 4.2.用db别名访问
ping db
# 结果
PING db (172.18.0.2) 56(84) bytes of data.
64 bytes from mysql.hanyang (172.18.0.2): icmp_seq=1 ttl=64 time=0.773 ms
64 bytes from mysql.hanyang (172.18.0.2): icmp_seq=2 ttl=64 time=0.251 ms
# 4.3.用容器名访问
ping mysql
# 结果:
PING mysql (172.18.0.2) 56(84) bytes of data.
64 bytes from mysql.hanyang (172.18.0.2): icmp_seq=1 ttl=64 time=7.76 ms
64 bytes from mysql.hanyang (172.18.0.2): icmp_seq=2 ttl=64 time=0.271 ms
1
2
3
4
5
6
7
8
docker run -d \
--name nginx \
-p 18080:18080 \
-p 18081:18081 \
-v /root/nginx/html:/usr/share/nginx/html \
-v /root/nginx/nginx.conf:/etc/nginx/nginx.conf \
--network hanyang \
nginx

项目部署

DockerCompose

  • Docker Compose通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器,可以实现多个相互关联的Docker容器的快速部署

docker run 部署MySQL的命令:

1
2
3
4
5
6
7
8
9
10
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
-v ./mysql/data:/var/lib/mysql \
-v ./mysql/conf:/etc/mysql/conf.d \
-v ./mysql/init:/docker-entrypoint-initdb.d \
--network hanyang
mysql

docker-compose.yml 文件来定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
version: "3.8"

services:
mysql:
image: mysql
container_name: mysql
ports:
- "3306:3306"
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 123
volumes:
- "./mysql/conf:/etc/mysql/conf.d"
- "./mysql/data:/var/lib/mysql"
networks:
- new
networks:
new:
name: hanyang

黑马商城部署文件

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
version: "3.8"

services:
mysql:
image: mysql
container_name: mysql
ports:
- "3306:3306"
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 123
volumes:
- "./mysql/conf:/etc/mysql/conf.d"
- "./mysql/data:/var/lib/mysql"
- "./mysql/init:/docker-entrypoint-initdb.d"
networks:
- hm-net
hmall:
build:
context: .
dockerfile: Dockerfile
container_name: hmall
ports:
- "8080:8080"
networks:
- hm-net
depends_on:
- mysql
nginx:
image: nginx
container_name: nginx
ports:
- "18080:18080"
- "18081:18081"
volumes:
- "./nginx/nginx.conf:/etc/nginx/nginx.conf"
- "./nginx/html:/usr/share/nginx/html"
depends_on:
- hmall
networks:
- hm-net
networks:
hm-net:
name: hmall

对比如下:

docker run 参数 docker compose 指令 说明
–name container_name 容器名称
-p ports 端口映射
-e environment 环境变量
-v volumes 数据卷配置
–network networks 网络

命令格式

https://docs.docker.com/compose/reference/

docker compose 的命令格式:

1
docker compose [OPTIONS] [COMMAND]
类型 参数或指令 说明
Options -f 指定compose文件的路径和名称
-p 指定project名称。project就是当前compose文件中设置的多个service的集合,是逻辑概念
up 创建并启动所有service容器
down 停止并移除所有容器、网络
ps 列出所有启动的容器
logs 查看指定容器的日志
Commands stop 停止容器
start 启动容器
restart 重启容器
top 查看运行的进程
exec 在指定的运行中容器中执行命令

Docker
https://www.renkelin.vip/2023/10/07/Docker/
Author
Kolin
Posted on
October 7, 2023
Licensed under