Linux安装
centos7.x安装
- 卸载原始docker
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
- 安装docker依赖
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
- 设置docker的yum源
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
- 安装最新版的docker
$ sudo yum install docker-ce docker-ce-cli containerd.io
- 指定版本安装docker
- $ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
$ yum list docker-ce --showduplicates | sort -r
$ sudo yum install docker-ce-18.09.5-3.el7 docker-ce-cli-18.09.5-3.el7 containerd.io
- docker命令
# 开机启动&启动docker
systemctl enable docker
systemctl start docker
# 关闭docker
systemctl stop docker
所有平台安装
- 通过国内源安装docker应用
curl -fsSL get.docker.com -o get-docker.sh
sh get-docker.sh --mirror Aliyun
- 启动docker
systemctl enable docker
systemctl start docker
- 创建docker用户,并设置docker组
groupadd docker
groupadd -g docker docker
配置阿里云加速
登录阿里云官网,工作台-镜像容器服务-镜像工具-镜像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://9b2k04q7.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
核心架构
- 镜像:一个镜像代表一个应用环境,是一个只读文件,比如mysql镜像,redis镜像,tomcat镜像等等;
- 容器:镜像每次运行之后就会产生一个容器,就是正在运行的镜像,可读可写;
- 仓库:用来存放镜像的位置,类似与maven的远程仓库;
- dockerFile:docker生成镜像的配置文件,用来书写自定义镜像的一些配置;
- tar:对镜像打包的文件,可以恢复成为镜像
容器
数据卷
数据卷实现了容器与宿主机数据共享问题(只能在镜像第一次启动时指定数据卷)
docker run [-d][-p][--name][-v] 容器名/容器id
-d 后台守护进程运行
-p 指定宿主机与容器的端口映射
--name 指定容器名称
-v 指定数据卷
docker run -d -p 8080:8080 --name tomcat8 -v /opt/apps:/usr/local/tomcat/webapps tomcat:8.0
-v /opt/apps:/usr/local/tomcat/webapps
/opt/apps:宿主机地址
/usr/local/tomcat/webapps:容器路径(绑定数据卷后会以/opt/apps的文件夹内容为主,可能会将当前目录下文件清空)
# 保留容器数据卷内容,通过别名形式,默认数据卷地址为 /usr/lib/docker/volum/别名/_data
-v 别名:/usr/local/tomcat/webapps
# 容器内对数据卷只读,只能有宿主机操作 ro:Ready Only
-v 别名:/usr/local/tomcat/webapps:ro
高级数据卷
- 自定义提前创建好宿主机数据卷,在容器启动时进行别名绑定
- 在容器启动时使用未创建的别名绑定,那么会由Docker为我们创建一个为别名的宿主机数据卷,地址在:/usr/lib/docker/volum/别名/_data
docker volume list # 查看数据卷
docker volume create 数据卷名 # 创建数据卷
docker volume inspect 数据卷名 # 数据卷信息
docker volume rm 数据卷名 # 删除数据卷
数据卷详情
[root@iZbp18eahm3m5nczl60fo4Z ~]# docker volume inspect aaa
[
{
"CreatedAt": "2022-09-03T14:54:23+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/aaa/_data",
"Name": "aaa",
"Options": null,
"Scope": "local"
}
]
镜像
# 容器打包成为镜像
docker commit -m "描述" -a "作者" 容器id 打包后镜像名:TAG(版本)
# 打包镜像
docker save 镜像名 -o 名称.tar
# 恢复载入镜像
docker reload -i 名称.tar
软件安装
mysql 8.0.30
# 从DockerHub仓库中拉去mysql8.0.30版本镜像文件
docker pull mysql:8.0.30
# 启动命令
docker run -d -p 3306:3306 --name mysql --restart=always -e MYSQL_ROOT_PASSWORD=nieao0823.. -v /usr/local/docker/mysql/conf.d:/etc/mysql/conf.d -v /usr/local/docker/mysql/data:/var/lib/mysql mysql:8.0.30
-e MYSQL_ROOT_PASSWORD=nieao0823.. # 指定root密码
--restart=always # docker重启后自动加载该容器
-v /usr/local/docker/mysql/conf.d:/etc/mysql/conf.d # mysql配置文件与宿主机绑定
-v /usr/local/docker/mysql/data:/var/lib/mysql # mysql的数据与宿主机进行绑定
-d 后台运行 -p 端口映射 --name设置名称
# 导出全部库结构+数据
docker exec 容器名/容器id sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql
# 导出指定库结构+数据
docker exec mysql sh -c 'exec mysqldump --databases 库表 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql
# 导出指定库表结构(不包含数据)
docker exec mysql sh -c 'exec mysqldump --no-data --databases 库表 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql
# 执行sql
docker exec -i mysql sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"' < /root/xxx.sql
解决 Authentication plugin ‘caching_sha2_password‘ cannot be loaded 问题
# 原因是Nactive密码加密方式与mysql版本不一致导致,要么升级Nactive,要么将mysql的加密方式回退,此处采用重新指定mysql加密方式来进行
docker exec -it mysql bash # 进入mysql容器
mysql -u root -p # 进入mysql
# 修改账户密码加密规则
ALTER USER 'root'@'%' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER;
# 更新用户的密码
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
# 刷新权限
FLUSH PRIVILEGES;
# 重置密码
alter user 'root'@'%' identified by 'nieao0823..';
redis 6.2.7
docker run -d -p 6379:6379 --name redis --restart=always -v /usr/local/docker/redis/conf:/usr/local/etc/redis -v /usr/local/docker/redis/data:/data redis:6.2.7 redis-server /usr/local/etc/redis/redis.conf
--restart=always # docker 重启后自动加载该容器
-v /usr/local/docker/redis/conf:/usr/local/etc/redis # 数据卷、配置文件宿主机与容器同步
-v /usr/local/docker/redis/data:/data # 数据卷、Redis开启AOF日志持久化后,容器redis数据与宿主机同步
redis-server /usr/local/etc/redis/redis.conf # redis启动时加载指定路径的配置文件
高级
网络通讯
高级网络配置
当Docker启动时,会自动在宿主机上创建一个docker0的虚拟网桥,实际上是Linux的一个birdge,可以理解为一个软件交换机,他会在挂载到它的网口进行转发。当创建一个Docker容器时,同时会创建一对veth pair接口(当数据包发送到一个接口时,另外一个接口时也是可以收到相同的数据包,这就是为什么通过-p命令可以实现宿主机与容器之间的端口通信)。容器端即eth0,则另一个是本地挂载在docker0网桥,名称以veth0开头,通过这种方式,主机可以跟容器之间通信,容器之间也可以通信。
使用自定义网络桥段后,在容器内部依然可以互通,而且还可以通过容器名称来当做ip使用。
网络桥段命令
[root@iZbp18eahm3m5nczl60fo4Z ~] docker network list # 查看网络桥段信息,默认bridge桥接模式
NETWORK ID NAME DRIVER SCOPE
76c7e4783347 bridge bridge local
b6cd3b9ff50b host host local
a2180011fe38 none null local
docker network create -d bridge 网桥名称 # 创建网桥
docker network rm 网桥名称 # 删除网桥
docker network list # 查看全部网桥
docker network connect 网桥名称 容器id/名称 # 容器加入指定网桥
docker inspect 容器id/名称 # 可以查看容器网络信息
使用自定义网络桥段
容器启动时指定网络桥段
docker run -d -p 8080:8080 --name tomcat01 --network 网桥名称 tomcat:8.0
--network # 指定网络桥段名称
容器启动后加入某网络桥段
docker network connect 网络桥段名称 容器id/名称
Dockerfile
Dokcerfile是Docker镜像的描述文件、是由一系列命令和参数构成的脚本,主要用来构建docker镜像的构建文件。
| 关键字 | 作用 |
|---|---|
| FROM | 当前镜像是基于那个镜像的、第一个必须是FROM |
| RUN | 构建镜像时候需要运行的命令 |
| EXPOSE | 当前容器对暴露的端口号 |
| WORKDIR | 进入容器内落位置 |
| ENV | 用来构建镜像过程中的环境变量($ENV_NAME) |
| ADD | 将宿主机上的文件拷贝至镜像(ADD命令会自动处理url和解压tar包) |
| COPY | 类似与ADD、宿主机内构建文件所在的目录下的文件拷贝至镜像内目标路径 |
| VOLUME | 容器数据卷,用于数据保存和持久化工作 |
| CMD | 指定一个容器启动时要运行的命令、Dockerfile可以有多个cm指定,但是只会有最后一个生效、cmd会被docker run之后的参数替换 |
| ENTRYPOINT | 指定一个容器启动时运行的命令,ENTRYPOINT和CMD一样,都是在容器启动参数 |
构建SpringBoot项目镜像
编写Dockerfile文件
FROM openjdk:8
WORKDIR /ems
ADD ems.jar /ems
EXPOSE 80
ENTRYPOINT ["java","-jar"]
CMD ["ems.jar"]
# FROM 基于jdk8镜像开始构建
# WORKDIR 进入容器落脚点/ems
# ADD 将当前构建文件所在目录下的ems.jar拷贝到容器内的ems目录下
# EXPOSE 向外暴露端口 80
# ENTRYPOINT 【CMD】命令 java -jar ems.jar
# 此处项目名称使用CMD、是因为CMD是不固定、可以在Docker run 命令之后对其进行更改、java-jar是固定的命令,项目名称可能不是固定
docker build -t ems:version .
images_name 镜像名
version 指定版本,可以忽略不写,不指定版本则为最新版本 latest
Dockerfile文件与项目的jar包要处于统一目录
docker images 可以查看生成的容器信息
最后的.不要忘记
docker run -d -p 80:80 --name ems --restart=always ems:9,1 ems.jar
Docker Compose
Docker compose 实现对容器的编排
- 项目(project)是由一组容器(服务)构成的一个完整业务单元,在docker-compose.yml文件中定义
- 服务(service)一个应用容器,实际上可以运行多个相同镜像的实例
安装
Linux
curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# 国内源
curl -L https://download.fastgit.org/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
安装包
# 安装
mv docker-compose-Linux-x86_64 docker-compose # 重命名
mv docker-compose /usr/local/bin # 移动至bin
[root@iZbp18eahm3m5nczl60fo4Z bin]# docker-compose --version
docker-compose version 1.25.5, build 8a1c60f6
# 卸载
rm -rf /usr/local/bin/docker-compose
docker-compose 模板文件
默认模板文件名称为:docker-compose.yml,类型为yml
version:"3.8"第一行显示docker-compse版本、具体版本与docker版本相关(docker --version) 版本查看
services下面开始配置项目所需要的应用容器(第一个是容器的id,针对于这个项目的服务容器id)container_name容器名(docker ps 中显示的容器)image基于什么镜像ports端口映射volumes与宿主机的数据卷command容器启动后指定执行的命令restart: always应用重启后自启depends_on配置容器服务加载顺序build自定义构建镜像来(不能与image共存)context指定Dockerfile文件所在的上下文dockerfileDockefile文件名argDockerfile文件中参数
demo
version: "3.8"
# 项目服务
services:
nginx: # 服务名
container_name: "my_nginx"
image: nginx # 基于那个镜像
ports: # 开放端口
- "80:80"
volumes: # 数据卷
- "/usr/local/docker/nginx/index.html:/usr/share/nginx/html/index.html"
# command: echo "docker-compose services nginx install" # 容器启动后指定命令
restart: always # 应用重启后自启
depends_on: # 在以下容器启动后再启动当前容器
- tomcat
tomcat:
container_name: "my_tomcat"
image: "tomcat:${TOMCAT_VERSION}"
ports:
- "8080:8080"
volumes:
- "/usr/local/docker/tomcat/index.jsp:/usr/local/tomcat/webapps/ROOT/index.jsp"
# command: echo "docker-compose services tomcat install"
restart: always
ems:
container_name: "my_ems"
build:
context: ./docker-file # 指定Dockerfile所在文件夹的路径
dockerfile: ems-Dockerfile # 指定Dcokerfile文件名
args:
PROJECT_NAME: ems.jar
ports:
- "8099:8099"
restart: always
depends_on: # 在以下容器启动后再启动当前容器
- tomcat
- nginx
.env文件
docker-compose编排模板中有一些密码或者常量信息可以通过外部的.env文件来进行管理,因为当前文件是.开头隐藏文件,所以一般是看不到,使用
ll -a命令可以看到,格式key = value、在docker-compose.yml中可以通过${TOMCAT_VERSION}来引入。
[root@iZbp18eahm3m5nczl60fo4Z compose]# cat .env
TOMCAT_VERSION=9.0
基本命令
docker-compose up -d [service] 后台启动容器编排文件
docker-compose down 此命令后停止up命令所启动的容器,并移除网络
docker-compose exec [service] 入指定容器
docker-compose ps [service] 列出项目中所有的容器
docker-compose restart [service] 重启项目中容器
docker-compose rm -f [service] 删除项目中所有容器
docker-compose start [service] 启动项目中容器(或指定容器)
docker-compose stop [service] 暂停项目中容器(或指定容器)
mysql+redis+nginx+nacos+rabbitmq 编排文件
version: "3.8"
services:
mysql:
container_name: "app_mysql"
image: "mysql:8.0.30"
# 重启策略
restart: always
networks:
- app
# 端口映射
ports:
- "3306:3306"
volumes:
# 数据挂载
- "/usr/local/docker/app/mysql/data:/var/lib/mysql"
# 配置文件挂载
- "/usr/local/docker/app/mysql/config:/etc/mysql/conf.d"
environment:
# root用户密码
MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD}
# mysql时区
TZ: Asia/Shanghai
command:
# 将mysql8.0默认密码策略修改为原先策略 (mysql8.0对其默认策略做了更改 会导致密码无法匹配)
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
redis:
container_name: "app_redis"
image: "redis:6.2.7"
restart: always
networks:
- app
ports:
- "6379:6379"
volumes:
# 数据挂载、配置文件挂载、日志信息挂载
- "/usr/local/docker/app/redis/data:/data"
- "/usr/local/docker/app/redis/config/redis.conf:/usr/local/redis/config/redis.conf"
- "/usr/local/docker/app/redis/logs:/logs"
# 启动命令
command: ["redis-server","/usr/local/redis/config/redis.conf"]
nginx:
container_name: "app_nginx"
# 基于那个镜像
image: "nginx"
networks:
- app
# 开放端口
ports:
- "80:80"
volumes:
- "/usr/local/docker/app/nginx/config/nginx.conf:/etc/nginx/nginx.conf"
- "/usr/local/docker/app/nginx/logs:/var/log/nginx"
restart: always # 应用重启后自启
nacos:
container_name: "app_nacos"
image: "nacos/nacos-server:2.0.2"
networks:
- app
restart: always
ports:
- "8848:8848"
environment:
# 单机启动
MODE: standalone
rabbitmq:
container_name: "app_rabbitmq"
image: "rabbitmq:3.7.15"
networks:
- app
ports:
- "5672:5672"
- "15672:15672"
environment:
RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS}
RABBITMQ_DEFAULT_VHOST: ${RABBITMQ_DEFAULT_VHOST}
volumes:
- "/usr/local/docker/app/rabbitmq/data:/usr/lib/rabbitmq"
networks:
app: