Docker
# Docker
Docker 是一个开源的应用容器引擎
# 安装
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun # docker 官方脚本安装
yum install -y docker # yum 安装的可能版本没官方新
2
# 架构

# Docker 镜像加速器
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.1panel.live",
"https://dockerpull.org",
"https://registry.dockermirror.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2
3
4
5
6
7
8
9
10
11
# Docker 镜像使用代理
修改 /etc/systemd/system/multi-user.target.wants/docker.service
vim /etc/systemd/system/multi-user.target.wants/docker.service
在 Service 标签下添加代理地址
Environment=HTTP_PROXY=http://admin:[email protected]:1080
Environment=HTTPS_PROXY=http://admin:[email protected]:1080
Environment=NO_PROXY=localhost,127.0.0.1
2
3
重启 Docker 服务
systemctl daemon-reload
systemctl restart docker
2
# 修改 daemon 文件
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://o7uzc3zp.mirror.aliyuncs.com"],
"proxies": {
"http-proxy": "http://192.168.130.189:7890",
"https-proxy": "http://192.168.130.189:7890",
"no-proxy": "127.0.0.0/8"
}
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2
3
4
5
6
7
8
9
10
11
12
13
方式二直接以
sudo mkdir -p /etc/systemd/system/docker.service.d
cat <<EOF | sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://192.168.32.2:7890"
Environment="HTTPS_PROXY=http://192.168.32.2:7890"
Environment="NO_PROXY=.svc,.svc.cluster.local,.cluster.local,.todoit.tech,10.244.0.0/16,10.96.0.0/12,127.0.0.1,localhost,192.168.0.0/16,172.16.0.0/12,10.0.0.0/8"
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2
3
4
5
6
7
8
9
10
11
# 更改镜像存储路径
mkdir -p /mnt/sda1/docker # 在新存储路径下创建docker目录
systemctl stop docker.socket
systemctl stop docker
rsync -aqxP /var/lib/docker/ /mnt/sda1/docker/ # 迁移数据
2
3
4
修改 daemon.json 文件
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://o7uzc3zp.mirror.aliyuncs.com"],
"data-root": "/mnt/sda1/docker"
}
2
3
4
删除原 docker 存储,并软链接路径
rm -rf /var/lib/docker/* # 删除原路径 删除前请检查数据是否已经迁移完成
ln -s /mnt/sda/docker /var/lib/docker # 软链接
systemctl start docker
2
3
# Docker 命令
# 服务
systemctl start docker # 启动
systemctl stop docker # 停止
systemctl status docker #状态
systemctl restart docker #重启
systemctl enable docker #开机自启
2
3
4
5
# 镜像
查看本地镜像
docker images1搜索镜像
docker search 镜像名1拉取镜像
docker pull 镜像名:版本号 # 版本号默认为latest1删除镜像
docker rmi 镜像id # 也可以通过名称:版本号删除1删除所有镜像
docker rmi `docker images -q`1
# 容器
创建容器并 运行参数 run
- -i 保持运行
- -t 以终端模式运行并进入
- -d 后台常驻模式
- --name=xxx 此容器名称
- 镜像名 /id
- /bin/bash 初始化命令
docker run -it --name=redis redis /bin/bash #进入容器内部 docker run -d --name=redis2 redis # 后台运行容器1
2查询容器
docker ps #查询正在运行的容器 docker ps -a # 查看所有容器包括已停止的1
2进入已经运行的容器内部
docker exec -it 名称/id /bin/bash1运行 停止容器
docker stop 名称/id #停止容器 docker start 名称/id #启动容器1
2删除 00 容器
docker rm 名称/id # 删除容器 先docker ps -a 查询 docker rm `docker ps -aq` # 删除所有容器 慎用 正在运行的容器无法删除1
2查看容器 配置信息
docker inspect 名称/id1修改配置信息
systemctl stop docker
cd /var/lib/docker/containers/docekr inspect查出的id
vim config.v2.json
systemctl restart docker
2
3
4
用于清理磁盘,删除关闭的容器、无用的数据卷和网络,以及即无 tag 的镜像 谨慎使用
docker system prune1查看 docker 自身磁盘使用情况
docker system df1查看 volume 列表
docker volume ls1查看网络列表
docker network ls1
# 容器数据卷
数据卷是宿主机中的一个目录或文件 称为挂载目录 一个数据卷可以被多个容器同时挂载
创建启动容器时 使用 -v 参数 设置数据集
docker run -d -v 宿主机目录:容器内目录1目录必须为绝对路径 如果目录不存在则自动创建
# 数据卷容器
多容器进行数据交换 之前我们通过多容器绑定宿主机的同目录
创建一个数据卷容器 单创建容器目录 作为数据卷容器
docker run -it --name=c3 -v /volume redis /bin/bash1创建 c1 c2 容器 使用 --volume-from 参数 设置数据卷 from c3 数据卷容器中
docker run -it --name=c1 --volume-from c3 redis /bin/bash docker run -it --name=c2 --volume-from c3 redis /bin/bash1
2
# 重启策略
docker run -d \
--name clouddrive \
--restart=unless-stopped \
cloudnas/clouddrive
2
3
4
- --restart=no,默认策略,在容器退出时不重启容器
- --restart=on-failure,在容器非正常退出时(退出状态非 0),才会重启容器
- --restart=on-failure:3,在容器非正常退出时重启容器,最多重启 3 次
- --restart=always,在容器退出时总是重启容器
- --restart=unless-stopped,在容器退出时总是重启容器,但是不考虑在 Docker 守护进程启动时就已经停止了的容器
如果创建容器的时候没有指定 restart,可以使用 update 来更新策略
# 先用 docker ps -a 查出 已运行容器的id
docker update b941145096f0 --restart=always
# 或者直接使用容器名称
docker update clouddrive --restart=always
2
3
4
# 多容器通信
要想多容器之间互通,从 一个 容器访问 另一个 容器,我们只需要把他们放到同个网络中就可以了。
# 创建虚拟网络
# 创建一个名为 test-net 的网络:
docker network create test-net
# 运行 一个容器 在 test-net 网络中,别名 redis
- --network 创建容器时指定网络
- --network-alias 网络别名
docker run -d --name redis --network test-net --network-alias redis redis:latest
# 修改 另外一个容器 代码中访问 redis 的地址为网络别名

# 运行 另外一个容器,使用同个网络
docker run -p 8080:8080 --name test -v D:/test:/app --network test-net -d test:v1
- 创建一个虚拟网络
- 容器绑定网络
- 同一虚拟网络中多个容器之间可以相互通信
# 容器 hosts 配置
由于一些 dns 污染,我们需要在容器中更改 hosts 文件,但容器中的 hosts 文件是重启就还原,无法直接在容器中修改,需要在启动时配置
docker run -d \
--name=emby \
-p 8096:8096 \
--add-host=api.themoviedb.org:13.227.254.116 \
lscr.io/linuxserver/emby
2
3
4
5
其中 --add-host 是写入 hosts 中的配置, api.themoviedb.org 为域名 : 13.227.254.116 为 ip
通过 docker compose 构建
php72:
container_name: "php72"
hostname: "php72"
image: "xxxx"
extra_hosts:
- "www.baidu.com:127.0.0.1"
- "www.google.com:127.0.0.1"
volumes:
- xxx:xx
2
3
4
5
6
7
8
9
# 应用部署
# MySQL
创建容器
docker run -id \
-p 3307:3306 \
--name=my_mysql \
-v $PWD/conf:/etc/mysql \
-v $PWD/logs:/logs \
-v $PWD/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.6
2
3
4
5
6
7
8
进入容器中
docker exec -it my_mysql /bin/bash
mysql -uroot -p123456
2
# Tomcat
创建容器
docker run -d \
--name=my_tomcat \
-p 8080:8080 \
-v $PWD:/usr/local/tomcat/webapps \
tomcat
2
3
4
5
# Nginx
docker run -id \
--name=my_nginx \
-p 80:80 \
-v $PWD/html:/usr/share/nginx/html \
nginx
2
3
4
5
# Redis
docker run -id --name=my_redis -p 6379:6379 redis
# Docker 镜像

Docker 镜像是由特殊的文件系统叠加而成
最底端是 bootfs 并使用宿主机的 bootfs
第二层是 root 文件系统 rootfs 称为 base image

# 镜像制作
容器转为镜像 注意通过映射方式挂载的目录或文件 打包后并不会保存在镜像中
docker commit 容器id 镜像名称:版本号1镜像转为压缩文件
docker save -o 压缩名称.tar 镜像名称:版本号1从压缩文件中 加载镜像
docker load -i 压缩名称.tar1
# Dockerfile
Dockerfile 是一个文本文件 包含许多指令 每一条指令构建一层 基于基础镜像 最终构建出一个新的镜像
| 命令 | 说明 | 示例 | ||
|---|---|---|---|---|
| FROM | 基于这个 Image 开始 | FROM nginx:latest | ||
| ENV | 环境变量 | ENV localfile /usr/local/nginx | ||
| RUN | 新层中执行命令 | RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME' | ||
| LABEL | 设置 metadata | LABEL version="1.0" | ||
| MAINTAINER | 维护者 (deprecated) | MAINTAINER ducafecat | ||
| EXPOSE | 声明容器监听端口 | EXPOSE 80 443 | ||
| ADD | 复制文件 | ADD ./dist ${foo}/html | ||
| COPY | 复制文件 | COPY ./dist ${foo}/html | ||
| ENTRYPOINT | 容器启动时执行指令 | CMD ["ls"] | ||
| CMD | 容器启动时执行指令默认值 | CMD ["-la"] | ||
| VOLUME | 挂载点 | VOLUME ["/data"] | ||
| USER | 指定操作用户 | USER www | ||
| WORKDIR | 设置工作目录 | WORKDIR /path/to/workdir | ||
| ARG | 设置参数 | ARG user=www | ||
| ONBUILD | 镜像被 From 时触发 | ONBUILD RUN /bin/bash -c 'echo ONBUILD ...' | ||
| STOPSIGNAL | 停止信号退出 | STOPSIGNAL SIGTERM | ||
| HEALTHCHECK | 检查容器的健康状况 | HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ | exit 1 | |
| SHELL | 覆盖默认 shell | SHELL ["powershell", "-command"] |
# 通过官方 centos 自定义
- 创建 dockerfile 文件
FROM centos:7
MAINTAINER Iekr <[email protected]>
# 运行命令,安装依赖
# RUN 命令可以有多个,但是可以用 && 连接多个命令来减少层级。
# 例如 RUN npm install && cd /app && mkdir logs
RUN yum install -y vim
# 设置容器启动后的默认运行目录
WORKDIR /usr
# CMD 指令只能一个,是容器启动后执行的命令,算是程序的入口。
# 如果还需要运行其他命令可以用 && 连接,也可以写成一个shell脚本去执行。
# 例如 CMD cd /app && ./start.sh
CMD /bin/bash
2
3
4
5
6
7
8
9
10
11
12
13
14
15
通过 file 文件 build 镜像
# docker build -f dockerfile文件 -t 镜像名称:版本号 . # -f dockerfile名称 # -t 名称:标签的命名形式 # 注意最后有一个 点 docker build -f ./my_dockerfile -t my_centos:1 .1
2
3
4
5运行容器
#docker run --name <容器名称> -d -p 8080:8080 <上一步构建的镜像名称> docker run --name test -d -p 8080:8080 my_centos:11
2
# Spring Boot dockerfile
FROM java:8
MAINTAINER iekr [email protected]
VOLUME /home/iekr
ADD Schoolelectricity-1.0-SNAPSHOT.jar app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Duser.timezone=GMT+8","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
2
3
4
5
6
docker build -t mystory .
docker run -d -p 8080:8080 mystory
2
第二个方案
docker run -id -p 8080:8080 openjdk:8-jre-alpine
#添加时区
apk add tzdata
#下载好复制时区过去 就可以了
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2
3
4
5
6
nohup java -jar Schoolelectricity-1.0-SNAPSHOT.jar > /logs.log 2>&1 & #后台启动java
# Docker Compose 服务编排
微服务架构的应用系统一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,工作量会非常的大
Docker Compose 是一个编排多容器分布式部署的工具 提供命令集管理容器化应用的完整开发周期,包括服务构建 启动 停止
- 安装 Docker Compose
curl -L "https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker compose --version
2
3
4
创建 docker-compose.yml 同一个 compose 配置的容器网络互通
# yaml 配置实例 version: '3' services: web: #自定义名称 build: . # build dockerfile ports: #映射端口 - "5000:5000" volumes: #映射目录 - .:/code - logvolume01:/var/log links: #当前容器可以访问下面的容器 - redis # 指定时区 environment: - TZ=Asia/Shanghai redis: # 第二个容器 image: redis #容器名称 volumes: logvolume01: {}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19在当前目录 构建编写配置
docker compose up #启动配置 docker compose up -d # 后台启动1
2
其他命令如容器状态 运行停止与 docker 一致
查看运行状态: docker compose ps
停止运行: docker compose stop
重启: docker compose restart
重启单个服务: docker compose restart service-name
进入容器命令行: docker compose exec service-name sh
查看容器运行 log: docker compose logs [service-name]
# 私有仓库
服务端
docker pull registry
docker run -id --name=registry -p 5000:5000 registry
#访问 http://192.168.130.124:5000/v2/_catalog 如果出现{"repositories":[]}则安装成功
2
3
客户端
vim /etc/docker/daemon.json
#添加为私有仓库服务端地址
{"insecure-registries":["192.168.130.124:5000"]}
#重启docker服务
systemctl restart docker
2
3
4
5
上传前先给镜像打上标记
#docker tag 镜像名:版本号 私有仓库地址/镜像名:版本号
docker tag centos:7 192.168.130.124:5000/centos:7
2
上传
docker push 192.168.130.124:5000/centos:7
从仓库拉取镜像
docker pull 192.168.130.124:5000/centos:7
# Docker Hub
登陆 输入账号和密码
docker login
镜像改名 以自己 用户名 / 镜像名 改
docker tag centos:7 iekr/centos:7
docker push iekr/centos:7
2
# docker 容器与虚拟机比较


# 本地镜像导出和导入
使用 export 和 import 将容器镜像导出和导入操作
# 导出
docker export 镜像 id > 压缩文件名.tar
docker export f299f501774c > hangger_server.tar
# 导入
docker import - 自定义容器名称 < 镜像压缩文件.tar
docker import - new_hangger_server < hangger_server.tar
- export 命令是从容器(container)中导出 tar 文件,而 save 命令则是从镜像(images)中导出
- save 保存镜像所有的信息 - 包含历史
- export 只导出当前的信息 只包含当前版本信息 无法回滚其他版本