容器架构

目录

Iaas Paas Saas (了解)

  • Iaas:基础设施即服务 Infrastructure-as-a-Service
  • Paas:平台即服务 Platform-as-a-Service
  • Saas:软件即服务 Software-as-a-Service
  • Caas:容器即服务 介于IAAS和PAAS

IAAS,PAAS,SAAS这些服务,用于帮助人们更快实现目标(搭建环境,使用产品)

从左到右,人们需要管理与维护的地方越来越少,人们可以把重点关注在使用/应用上.

IAAS平台:基础设施,IDC机房的服务器出租,阿里云,云厂商.云服务器

PAAS平台:服务/运行环境搭好了,部署(托管)用户写的代码,公有云SLB(负载均衡),RDS(数据库)

SAAS平台:服务(软件)已经准备好,您直接用,具体产品,processon,wps,亿图.

容器概念

容器是 隔离 的环境中运行的一个 进程 ,如果进程结束,容器就会停止.

容器的隔离环境,拥有自己的ip地址,系统文件,主机名,进程管理,相当于一个mini的系统

容器 vs 虚拟机() ⭐⭐

vmware esxi:裸机安装的操作系统,适用于物理服务器

虚拟机:安装多个操作系统,每个系统都有完整的启动流程

容器:服务软件,依赖,需要用到的命令等等放在一起(常见的为alpine系统)

Docker部署与使用–官方下载地址

容器管理工具:docker、podman、containerd (k8s)

要求Linux内核: 3.10以上. 如果旧的内核需要升级内核才能使用.

uname -r

安装docker环境,docker-ce(开源) docker-ee(企业版)

从1.13版本开始改成年-月版本命名方式.

17.03 18 19.03 20.10 年-月方式命名.

从23.0之后改为 传统版本命名方式(新版加1)

23.0 和24.0 和 25.0

docker 麒麟sp3的yum安装版本为 18.09

机器清单:

  • sp3–10.0.0.81-docker01
  • sp3–10.0.0.82-docker02

1) 配置docker源:用于安装docker(适用非麒麟系统)

通用的安装脚本

curl -fsSL https://get.docker.com/ -o install-docker.sh

curl -fsSL https://get.docker.com -o get-docker.sh
#sudo sh get-docker.sh

sh get-docker.sh –mirror Aliyun

安装完成后执行
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker

下载到本地后直接bash执行脚本即可

配置docker yum源安装docker :安装最新版docker

#1.安装相关依赖.
sudo yum install -y yum-utils
#2.下载官方的docker yum源文件
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
#3.替换yum源地址
sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo
或者直接使用国内地址:yum-config-manager --add-repo http://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
#4.安装docker-ce
yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
#5.启动
systemctl enable --now docker 
#6.检查
docker version 检查

docker下载镜像加速的配置

我们使用docker的时候需要下载很多docker的镜像,为了加速下载,需要配置docker加速

docker下载镜像加速可以自己在阿里云,腾讯云申请加速用的地址.

阿里云为例,说明如何获取加速用的地址:搜索容器镜像服务

  1. 登录 容器镜像服务控制台
  2. 在左侧导航栏选择 镜像工具 > 镜像加速器
  3. 在 镜像加速器 页面获取您的加速器地址。

sudo mkdir -p /etc/docker
#/etc/docker/daemon.json docker服务端的配置文件. #配置docker下载镜像的加速地址. sudo tee /etc/docker/daemon.json <<'EOF' { "registry-mirrors":["https://bjjtv7cs.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.1panel.live",
"https://docker.m.ixdev.cn",
"https://hub.rat.dev",
"https://docker.xuanyuan.me",
"https://dockerproxy.net",
"https://docker-registry.nmqu.com",
"https://hub.amingg.com",
"https://docker.amingg.com",
"https://docker.hlmirror.com",
"https://hub1.nat.tf",
"https://hub2.nat.tf",
"https://hub3.nat.tf",
"https://docker.m.daocloud.io",
"https://docker.kejilion.pro",
"https://docker.367231.xyz",
"https://hub.1panel.dev",
"https://dockerproxy.cool",
"https://docker.apiba.cn",
"https://proxy.vvvv.ee"
]
}

运行第1docker

docker run -d -p 80:80 --name nginx_1st_1 nginx docker run xxxxx 选项/参数 镜像名字:版本 -d 守护进行,后台运行. -p 端口映射 宿主机端口:容器中的端口 --name nginx_1st 容器名字,不能冲突

docker架构

Docker C/S架构

docker典型的cs结构,基于go语言,

go语言写的软件特点:大部分二进制安装

cs client/server 客户端/服务端

Docker 服务端:docker daemon 叫dockerd

Docker 客户端:docker命令(下载镜像,运行容器 )

镜像 image: 存放各种的环境或服务
容器 container: 进程,运行起来的镜像.
仓库(存放镜像): 远程仓库,本地仓库

docker pull nginx 下载nginx镜像到本地仓库.

如果本地仓库有则提示镜像已经下载.

如果本地出仓库没有,则docker服务端访问远程仓库,下载镜像.

docker run -d -p 80:80 nginx:1.24-alpine 启动容器

-d容器后台运行

-p端口映射

nginx镜像名字

命令执行后的过程:

docker客户端找dockerd服务端,问是否有nginx镜像

如果有,则启动这个镜像,后台运行,访问容器端口是80端口.

如果没有,则从远程仓库下载镜像,启动这个镜像,后台运行,访问容器

端口是80端口.

1. 提示你本地没有nginx镜像 nginx:latest最新版

Unable to find image ‘nginx:latest’ locally

2. 找远程仓库下载

3. 运行镜像,成为docker容器.

4.查看镜像docker images

5.查看容器docker ps

6. 访问10.0.81:80👉容器的80端口(出现nginx界面)

注意事项: 此处使用到了docker -p端口映射公共,需要使用iptables的nat功能,需要在sysct.conf中加上一行开启系统的内核转发功能

# echo net.ipv4.ip_forward = 1 >>/etc/sysctl.conf net.ipv4.ip_forward = 1

# sysctl -p

net.ipv4.ip_forward = 1

Docker的镜像管理(相关命令)

镜像管理核心指令: 查看系统中的镜像

docker images   ==    docker image ls

docker search 搜索镜像, 优先选官方,stars数量多
docker pull 拉取镜像(下载镜像),注意版本
docker push 推送镜像(上传镜像)
docker load 导入镜像
#例子: docker load -i docker_nginx.tar.gz
docker save 导出镜像
#例子:docker save centos:7 -o
docker_centos7.tar.gz
docker images 查看镜像列表
docker rmi 删除镜像
#如果有容器用着镜像,那么镜像删不掉
docker tag 给镜像打标签
#tag标签相当于软链接,新增后不占空间

案例01: 下载nginx:alpine镜像并查看

#1. docker pull 下载镜像

docker pull nginx:1.22-alpine

#2.  docker image ls 简写为docker images查看镜像

docker images -a 查看所有镜像包含隐藏镜像.

查找镜像:

docker search  或者 访问hub.docker.com

镜像命名:

#指定版本: 只写服务名字一般下载服务的最新版本.

docker pull nginx   相当于 docker pull nginx:latest 下载最新版

下载ngx最新稳定的版本 nginx:stable

下载指定的版本         nginx:1.20.2

#指定系统: nginx镜像默认的系统是Debian系统

docker pull nginx:1.20-alpine 使用alpine系统更加节约空间(约比debian的小100M)

温馨提示:容器中常用的镜像

案例02: sl大法

保存docker镜像(save),其他节点上导入(load).

未来也可以搭建本地私有镜像仓库

docker image save   #(docker save)

docker image load   #(docker load)

保存docker 镜像 -o输出到指定的文件(这里的tar没有进行真正的压缩,大小体积没变)

docker save nginx:alpine  -o nginx_alpine.tar

#2. 导入load

docker load  -i nginx_alpine.tar

批量导入docker镜像

tar xf oldboyedu_useful_docker_images.tar.gz
unzip openjdk-docker-镜像.zip -d openjdk
cd oldboyedu_useful_docker_images
for name in `ls `
do
docker load -i $name
done
cd ../openjdk
for name in `ls `
do
docker load -i $name
done

#清理压缩包和解压后的目录

批量导出镜像
  • 一行命令实现导出,利用awk根据docker images的输出拼接成导出命令即docker save ****,但是只适用于镜像名里没有/,不支持目录结构的镜像

docker images | awk 'NR>1{print "docker save",$1":"$2 " -o "$1"_"$2".tar"}' > save.sh && bash save.sh

  • 脚本实现导出:
  • 思路还是使用awk取出docker save命令需要的第1,2列即镜像名:版本
  • 处理上面没有解决的输出tar文件名里面带/的问题
cat save_scripts.sh #批量导出docker镜像的脚本. #!/bin/bash #author: lidao996 #desc: 批量导出docker镜像 docker images |awk 'NR>1{print $1":"$2}' >/root/images.txt for name in `cat /root/images.txt` do name_new=`echo $name |sed -r 's#:|/#_#g' ` docker save ${name} -o ${name_new}.tar done

案例03:删除镜像

条件:镜像不能在使用中.(没有基于这个镜像的容器).

docker image rm == docker rmi

案例04:镜像清理用的命令

用于清理一些临时镜像,自定义镜像的时候

这些镜像一般来自于自定义镜像,生成临时镜像.没有名字和tag标签

docker image prune

docker images -a #可以查看系统中所有镜像,包含隐藏镜像

案例05:给镜像设置标签(类似ansible)

给镜像设置一个新的名字;tag标签相当于软链接,新增后不占空间

应用场景:

  • 自定义镜像.
  • 搭建与使用内部镜像仓库.registry
docker tag nginx:1.24 testngx:1.24
[root@sp3-docker01-10.0.0.81 ~]# docker images
nginx 1.24 b6c621311b44 2 years ago 142MB
testngx 1.24 b6c621311b44 2 years ago 142MB

案例06:查看镜像详细信息

docker 家目录在 /var/lib/docker/

docker inspect查看镜像容器,网络等各种信息

做镜像巡检的时候使用.

docker image inspect nginx:1.24  查看json数据配合jq使用

yum install -y jq

#jq用于专门过滤json形式的数据:

使用步骤:逐级进入,

结果中最外面是: [] 所以先用 jq .[]进入到 []中.
结果中{} 可以用jq .Id 形式取出,对于缩进的需要先访问上级然后继续访问.

docker inspect mysql:8.0-debian | jq .[]

docker inspect mysql:8.0-debian | jq .[].ContainerConfig

docker inspect mysql:8.0-debian | jq .[].ContainerConfig.ExposedPorts

多层[]时候使用多次.[]无效,需要加个管道再来一次.[]进入[]

案例07:自定义镜像

docker image build == docker build

docker image prune自定义镜像后进行清理无用的临时镜像

Docker的容器管理⭐

docker container xxx

docker ps 查看容器列表 -a 查看所有容器
docker run 创建并运行容器
#例子:docker run -d -it -p 80:80 nginx:latest
docker create --name创建容器 
docker start 启动容器
docker stop 停止容器
docker restart 重启容器
docker kill 强制停止容器
docker rm 删除容器
批量删除所有容器 docker rm -f `docker ps -a -q`
docker exec 进入正在运行的容器(分配一个新终端)
#例子: docker exec -it 容器id/容器名字 /bin/bash(/bin/sh)
docker attach 进入正在运行的容器(使用相同的终端),
偷偷离开的快捷键ctrl +p,ctrl +q
如果使用ctrlc会退出并关闭容器

docker inspect #查看详细信息
docker stats #查看容器运行状态,占用内存,cpu,io等信息
docker top #查看容器内当前进程

案例08:run 运行容器与查看容器信息

docker container run == docker run

  • docker container run过程⭐
    run包含了pull,create,start
    查找本地是否有这个镜像,如果没有则先下载镜像. docker image pull
    下载完成,创建容器 docker container create ,没有启动.
    启动容器docker container start
    容器启动,进行访问

docker container run -d -p 80:80 nginx

-d 后台运行; -p指定端口

docker端口映射过程

–name 创建容器并指定名称
查看容器运行状态
docker run -d -p 81:80 --name nginx-test nginx:1.24
docker ps -a #显示所有状态容器.
docker ps #只显示运行中的容器.不会显示其他状态容器

使用-p选项需要配置端口映射: vim /etc/sysctl.conf
# tail -1 /etc/sysctl.conf #写入到文件最后即可
net.ipv4.ip_forward = 1
# sysctl -p
net.ipv4.ip_forward = 1

查看各种镜像需要映射哪些端口
#查看redis镜像需要映射端口
docker inspect redis:5.0-alpine | jq .[].Config.ExposedPorts
{
"6379/tcp": {}
}
#查看tomcat镜像需要映射端口
docker inspect tomcat:9.0-jdk8 | jq .[].Config.ExposedPorts
{
"8080/tcp": {}
}
#查看nginx镜像需要映射端口
docker inspect nginx:1.24| jq .[].Config.ExposedPorts
{
"80/tcp": {}
}
#查看mysql镜像需要映射端口
docker inspect mysql:8.0-debian| jq .[].Config.ExposedPorts
{
"3306/tcp": {},
"33060/tcp": {}
}

案例09:删除容器

删除1个容器
docker container rm === docker rm
docker rm 容器名字或id
docker rm -f 容器名字或id #强制删除(运行中的容器无法强制删除,只能删除名字)
删除所有容器(极其危险⚠)

  • #显示所有容器(-a)并只显示容器id (-q)
  • docker ps -a -q
  • #删除容器
  • docker rm -f `docker ps -a -q`

案例10: 启动centos7容器运行系统镜像(用于临时测试)

docker run -it --name centos_7 centos:7 /bin/bash
docker run -it --name alpine_v2 alpine:latest /bin/sh
使用-it场景,用于测试或启动某个镜像并进入容器.
缺点:终端退出,容器退出
原因:运行中的容器需要在容器中持续运行某个命令或服务,(前台).
如服务软件有守护进程,所以容器可以一直运行
运行系统镜像时要在容器中有个命令/服务,把这个容器阻塞/卡住:运行sleep 9

docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker container run -d -p 80:80 nginx
docker container run -d --name "centos7.9_v1" centos:7 sleep 9

⚠⚠⚠⚠⚠温馨提示:
容器想要放在后台(-d)一直运行的话,那么容器的初始命令必须夯住(阻塞/前台运行),否则容器就会退出.

常见的前台运行方式:

nginx -g ‘daemon off;’ nginx前台运行.
/usr/sbin/php-fpm –nodaemonize php前台运行.
/usr/sbin/sshd -D ssh前台运行.
java -jar xxx.jar java前台运行.

#启动服务容器
docker run -d --name ngx_v1.24 -p 80:80 nginx:1.24
#启动系统容器(使用/bin/bash将系统阻塞住)
docker run -itd --name centos7_v4 centos:7 /bin/bash

案例11: 进入到已经运行的容器中.

如果容器已经运行了,无法使用docker run -it方式进入到容器中.

docker container exec === docker exec
#运行容器
docker run -itd --name "centos7_v1" centos:7 /bin/bash
#检查容器运行情况
docker ps
#连接到运行中的容器中
docker exec -it centos7_v1 /bin/bash
#对于其他系统可以用/bin/bash

案例12: execattach区别

docker attach 的特点
附加到运行中的进程:连接到容器的主进程(通常是前台进程),这时两个终端同时连接会显示出对方的输入和输出信息

docker attach centos7_v1
退出会停止容器:如果使用 Ctrl+C 或 Ctrl+P Ctrl+Q 退出可能会影响容器运行
如果 attach 后无法输入:可能是容器没有配置交互式终端,建议使用docker exec 

容器已经运行,如果重启docker服务端会怎么?

#发现问题
重启linux或docker服务后,容器处于关闭状态.类似于Linux的服务没有设置开机自启动一样.
#解决方法
1. docker start 启动
2. docker run的时候设置容器重启策略
docker run -d -p 80:80 --name ngx_1.24_alpine --restart=always nginx:1.24-alpine-new

docker重启策略说明:

案例14: 查看容器日志

docker logs 查看容器日志
-f 类似于tail -f显示实时更新
-n或–tail最近多少行日志
–since 从指定的时间开始到现在的日志
–until 指定结束的日志的时间(一般与since一起用,表示时间段)
docker logs --tail 10 nginx_v1.24
docker logs -f --since "2025-09-26T00:00:00Z" nginx_v1.24
注意:日期和时间都需要使用两位数

年月日十分秒中间需要加T
相对时间参数(推荐使用)相对时间更简单,不容易出错:
–since “1h” 最近1小时
–since “30m” 最近30分钟
–since “2d” 最近2天
–since “1h30m” 最近1小时30分钟

案例15: docker run 背后的指令

docker run -d -p 81:80 --name ngx_v1.24 --restart=always nginx:1.24
#1. 拉取镜像
docker pull nginx:1.24
#2. 创建容器
docker create -p 81:80 --name ngx_v1.24 --restart=always nginx:1.24
#3. 启动容器
docker start ngx_v1.24
#4. 检查结果
docker ps

docker pause,挂起相当于vm虚拟机的挂起,暂停运行

案例16: 宿主机文件传输到容器中

docker cp传输1个代码文件.

#1.问题:容器中默认没有远程连接服务,又要把宿主机文件传输到容器中.
#2.解决: cp
[root@docker01.linuxjk.cn ~]# cat index.html
docker cp docker.linuxjk.cn

docker cp index.html nginx_v1.24:/usr/share/nginx/html/

docker cp 传输配置文件

#1. 准备nginx配置文件:default.conf

[root@docker01.linuxjk.cn ~]# cat default.conf
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~* \.(html|css|js|jpg|jpeg|png)$ {
root /usr/share/nginx/html;
expires max;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

#2. 传输配置文件
docker cp default.conf nginx_v1.24:/etc/nginx/conf.d/
#3. 重启容器
docker restart nginx_v1.24
#4. 检查结果

案例17: 保存容器 👉 生成镜像

通过镜像启动的容器,往往无法完全符合我们使用要求.

每次都是修改配置.上传代码后使用

如何把修改保留下来:把被修改的容器保存成镜像.

启动基础镜像
docker run -d --name ngx_bunengsi_v1 -p 8848:80 --restart=always nginx:1.24
准备好bunengsi.tar代码,解压后传输到容器的/tmp/目录
tar xf bunengsi.tar
docker cp bunengsi ngx_bunengsi_v1:/tmp/
进入容器进行操作,把bunengsi/目录下面代码移动到站点目录
docker exec -it ngx_bunengsi_v1 /bin/bash
mv /tmp/bunengsi/* /usr/share/nginx/html/
访问当前容器并测试是否可以访问 http://10.0.0.82:8848
测试完成保存容器为镜像
docker commit ngx_bunengsi_v1 web:ngx_bunengsi_v1
通过新镜像创建容器并测试
docker run -d --name ngx_bunengsi_v2 -p 12306:80 --restart=always web:ngx_bunengsi_v1
测试通过,删除之前用于测试的临时容器
docker stop ngx_bunengsi_v1
docker rm ngx_bunengsi_v1

通过docker commit可以实现初步自定义镜像.

手动自定义镜像流程:
选择合适的基础镜像 .
启动容器, 连接容器,部署,配置,调试 .
commit生成镜像
通过镜像创建容器并调试

案例18:其他容器指令

docker kill 用于结束指定的容器. stop无法关闭,可以使用kill.

docker top 查看容器中进程信息.

docker stats 查看所有容器的cpu,内存,磁盘,网络,进程信息.

docker update 更新容器配置,增加cpu,内存限制,修改restart重启规则

不能添加规则,只能修改,比如没做数据卷挂载,端口映射只能重新创建容器

资源限制:   -m 限制内存  –cpus显示cpu核数

通过docker run的时候加上资源限制的选项

-e:创建或修改容器中的环境变量(全局变量)

案例19:exportimport导入导出

docker export(导出容器)

# 导出容器到.tar文件
docker export nginx_v1.24 > nginx_container.tar

# 或者使用 -o 参数指定输出文件nginx_container.tar,默认不会压缩
docker export -o nginx_container.tar nginx_v1.24

# 导出并压缩
docker export nginx_v1.24 | gzip > nginx_container.tar.gz

docker import(导入为镜像)

# 从tar文件导入为镜像
docker import nginx_container.tar mynginx:latest

# 从标准输入导入
cat nginx_container.tar | docker import - mynginx:latest

# 从压缩文件导入
docker import nginx_container.tar.gz mynginx:v1

# 指定更多信息(docker inspect 查看)
docker import --message "Imported from backup" nginx_container.tar mynginx:backup

docker commit 保存容器为镜像(手动自定义镜像)
与 docker save/load 的区别
特性export/importsave/load
操作对象容器 → 镜像镜像 → 镜像
保存内容仅文件系统文件系统+历史+元数据
层级结构扁平化(单层)保留所有层
使用场景创建基础镜像、备份容器迁移完整镜像

容器管理命令小结:

端口映射

docker run -d -p 选项.
使用docker的时候 外界访问docker容器中的服务或端口,需要使用端口映射.本质类似于iptables防火墙的端口映射.
应用场景: 未来容器需要被外界访问(80端口).需要暴漏在外界一个端口.
用户通过端口访问容器中的某个端口.
实现方法:docker run通过-p选项实现.
本质是通过iptables nat规则实现的.nat表中创建了docker自定义的链.
比如说

docker run -d --name "oldboy_nginx_1.20.2-apline" -p 8888:80 nginx:1.20.2-apline
1) 背后做了什么?
添加了对应防火墙规则
iptables -t nat -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8888 -j DNAT --to-destination 172.17.0.10:80
开启内核转发功能(需要我们自己开启)
# echo net.ipv4.ip_forward = 1 >>/etc/sysctl.conf net.ipv4.ip_forward = 1

 用户访问的时候经历了什么?

#输出所有运行中容器的ip地址.
for cid in `docker ps -q`
do
docker inspect $cid |jq .[].NetworkSettings.IPAddress
done

端口映射案

案例20: 11端口映射 ⭐⭐

映射80端口和443端口

docker run -d -p 80:80 -p 443:443 --name ngx_ports nginx:1.24-alpine-new

案例21: 映射多个端口

映射 容器中8080,8081,8082

一个一个写
docker run -d -p 8080:8080 -p 8081:8081 -p 8082:8082 -p 86:80 nginx:1.24-alpine

指定范围,宿主机8084-8086端口对应容器中的8080-8082

docker run -d -p 8084-8086:8080-8082 -p 88:80 nginx:1.24-alpine

docker port hopeful_northcutt(容器名字或id) 表示连续

案例22:把容器的端口随机映射到宿主机

docker run -d -P --name ngx_ports_v3 nginx:1.24-alpine
随机映射本质:根据镜像中的配置 EXPOSE配置映射端口.
docker inspect nginx:1.24-alpine |grep -i -A1 expose

可以看到nginx的镜像配置里面写的是80端口:

[root@sp3-docker02-10.0.0.82 ~]# docker inspect nginx:1.24-alpine |grep -i -A1 expose
"ExposedPorts": {
"80/tcp": {}
--
"ExposedPorts": {
"80/tcp": {}
案例23:ip绑定端口 ⭐
docker run -d -p 172.16.1.82:8080:80 --name secure_nginx nginx:1.24-alpine
3012118e5fb4878dc07344b5fd47dc0bbe5ef8e0846fc81260734de1e54607c2
[root@sp3-docker02-10.0.0.82 ~]# docker ps -a
CONTAINER ID IMAGE              PORTS                    NAMES
3012118e5fb4 nginx:1.24-alpine 172.16.1.82:8080->80/tcp secure_nginx

数据卷挂载

1) 概述

如果容器崩了,容器被误删除了,容器中的数据将会丢失,接下来解决数据不丢.
如何解决数据持久化问题? 数据卷(挂载),让数据永久保存在宿主机中

不做数据卷挂载,数据库被删除数据不会保留

2) 使用

不使用数据卷,数据会丢失;在上方的mysql容器运行指令中加上

-v /app/data/db80/:/var/lib/mysql/

注意目录后需要加/表示为目录

数据卷使用 -v选项:指定要挂载的目录/文件

格式:

-v 宿主机的路径:容器内部路径

案例24: 部署mysql容器并指定数据卷挂载

-e:创建或修改容器中的环境变量(全局变量)
docker run -p 3306:3306 --name db_8.0_v2 \
--restart always \
-v /app/mysql/log/:/var/log/mysql/ \
-v /app/mysql/data/:/var/lib/mysql/ \
-v /app/mysql/conf/:/etc/mysql/ \
-e MYSQL_ROOT_PASSWORD=1 \
-d mysql:8.0-debian

案例25: 挂载到数据卷空间(不指定存放位置,docker处理)

查看所有docker数据卷
docker volume ls
1.在宿主机上创建一个数据卷给容器mysql使用,实际位置在docker的目录/var/lib/docker
docker volume create mysql_data
运行mysql 容器中的/var/lib/mysql挂载到宿主机中.
-v mysql_data:/var/lib/mysql
2.使用(如果没执行下一步这里会自动创建数据卷)

docker run -p 3307:3306 -d --name mysql \
--restart always \
-v mysql_data:/var/lib/mysql/ \
-e MYSQL_ROOT_PASSWORD=1 \
mysql:8.0-debian

3.连接与创建用户,创建库
4.查看数据卷空间的信息(实际数据存放地址)
docker inspect mysql_data

数据卷部分官方文档:

查看一部分镜像的dockerfile:

docker history 镜像名/ID  (加上–no-trunc更全)

容器架构自动化部分

手动实现(commit指令),对于复杂的服务不建议用

1.创建容器

docker run -d -p 8080:80 --name ngx_bunengsi nginx:1.24-alpine
mkdir -p /app/dk/bunengsi
cp -a ~/bunengsi.tar /app/dk/bunengsi
vim bunengsi.conf
docker exec -it ngx_bunengsi /bin/sh
容器内部:mkdir -p /app/code/bunengsi

这里在容器内部创建目录时自动750,不给用户组权限会出现错误

解决方案:umask 查看输出,正常是0022,这个数字越大限制越多

修改方法:umask 0022

2.导入代码及配置文件

docker cp bunengsi.conf ngx_bunengsi:/etc/nginx/conf.d
docker cp bunengsi.tar ngx_bunengsi:/app/code/bunengsi
容器内部:tar xf bunengsi.tar
容器内部:nginx -t
docker restart ngx_bunengsi
docker logs -f ngx_bunengsi

3.测试,成功访问

4.将容器保存为镜像

docker commit ngx_bunengsi web:ngx_1.24_bunengsi_v1
检查
docker images | grep web

5.根据镜像生成容器

docker run -d -p 80:80 --name web_bunengsi_v1 web:ngx_1.24_bunengsi_v1
docker ps -a 查看刚生成的容器:web_bunengsi_v1
检查页面成功访问,手动将容器保存为镜像结束

自动实现Dockerfile实现

Dockerfile概述

应用场景: 通过1个文件Dockerfile,生成自定义镜像
为何使用Dockerfile:
我们目前都是手动拉取镜像,手动进行配置,手动安装依赖,手动编译安装,创建用户….
这个过程类似于命令行使用ansible模块(繁琐,不方便重复执行).
书写Dockerfile把之前手动创建自定义镜像的过程,通过Dockerfile里面的指令实现.类似于书写playbook.
Dockerfile用于根据要求自动创建镜像 .

Dockerfile格式

需要在容器中执行的指令可以写多行RUN,也可以写在一行RUN里面

书写dockerfile

ADD可以用于传配置文件(docker cp),或者传输代码后直接解压(保证压缩包里目录结构正确)

ADD和COPY都可以用于修改传输过去文件的所有者,

COPY –chown=root:root *****.tar.gz /app/code/test

COPY –chmod=755 *.sh   /*.sh

FROM nginx:1.24-alpine
LABEL author="linuxjk.cn"
ADD bunengsi.conf /etc/nginx/conf.d/
RUN umask 0022 && \
mkdir -p /app/code/bunengsi/
ADD bunengsi.tar.gz /app/code/bunengsi/
EXPOSE 80 443
CMD ["nginx","-g","daemon off;"]

nginx -g "daemon off" (容器环境nginx专用)
# Nginx 在前台运行,保持容器活跃
# 主进程不会退出,一直保持运行

进入dockerfile所在目录,根据dockerfile创建镜像

docker build -t web:ngx_bunengsi_v2_dockerfile .

docker images
web ngx_bunengsi_v2_dockerfile 553b048b46b4 4 seconds ago 41.2MB

根据镜像运行容器

docker run -d -p 80:80 --name bunengsi_dockerfile web:ngx_bunengsi_v2_dockerfile

容器启动后检查,访问宿主机80端口

docker ps
21f039e3e9ea web:ngx_bunengsi_v2_dockerfile "/docker-entrypoint.…" 2 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp, 443/tcp bunengsi_dockerfile

注意:每个项目的所需配置文件,代码等等和dockerfile都单独放在指定的目录中,否则会把目录中的所有文件交给docker服务端处理,像卡住

Dockerfile中的指令都是大写

FROM指定基础镜像

LABEL注释,镜像属性信息

RUN 在镜像中执行命令,尽可能把多个RUN合并,减少build的步骤

ADD传输文件,目录,压缩包等等,可以解压.tar.gz

COPY不能解压,只能传输(作用同上)

EXPOSE 服务需要的端口

CMD[“命令”,”参数”,”参数”]:容器的入口命令,运行容器后自动运行这个命令

最多三个””,最少两个,参数中可以写多个参数

ENV,WORKDIR,VOLUME

ENV

  • 定义全局环境变量,dockerfile中可用,dockerfile中涉及的脚本也可以用,用法和shell类似

定义:ENV CODE_NAME=bird.tar.gz

位置:FROM,LABEL下方,RUN上方

使用格式:ADD ${CODE_NAME} /app/code/code/

#将bird.tar.gz中的内容发到容器中的/app/code/bird目录

WORKDIR

  • 指定工作目录,进入容器所在的目录,一般web服务器指定代码的站点目录,不指定也可以

位置:都可以,放在ENV与EXPOSE之间

使用格式:WORKDIR /app/code/bird/

相当于执行了cd /app/code/bird/ ;下面的操作可以使用相对路径,比如ADD ${CODE_NAME} . 将代码直接发到站点目录

注意:和ENV一样可以在dockerfile中用多次

VOLUME

  • 指定容器中哪些目录或文件需要做数据卷挂载(-v),需要时加上

位置:一般写在下面,COMPOSE之前

使用格式:

  • VOLUME /app/code/bird/ 
  • VOLUME /etc/nginx/nginx.conf 

案例26 CMD, ENTRYPOINT区别

共同点:都与入口有关,运行容器的时候默认运行CMD或ENTRYPOINT后面的命令,使用格式相同

区别01:二选一时,在dockerfile中选择其一使用

CMD:使用较多(替换)

docker run的时候,如果镜像名字后面指定了命令,则cmd内容就会被替换

ENTRYPOINT:(追加)

run的时候,如果指定了命令内容,在entrypoint命令后面追加

区别02:一起使用

FROM nginx:1.24
LABEL author=linuxjk.cn desc="测试 cmd和entrypoint"
ENTRYPOINT ["nginx"]
CMD ["-g","daemon off;"]

CMD的内容会作为entrypoint的选项参数,运行容器时可以修改参数,但是命令不变

查看官方dockerfile格式:hub.docker.com👉github存放dockerfile

set -e: shell严格模式,前面命令执行报错自动退出脚本,不进行下一步操作,和手动加exit效果类似

所以用了-e选项后,在剧本中就可以将&&替换为; 效果相同

set  -x显示脚本详细输出

set -u 如果用到了没定义的变量,就报错

在脚本中可以写set -eux,严格模式+显示过程+引用未定义变量报错,实现的效果:引用未定义的变量直接退出脚本

案例27 极速搭建个人不限速的网盘,再也不用办理xx员了.

案例说明:

代码kodbox可道云.云盘和云桌面.

项目步骤:ngx+php镜像

基础镜像: debian:bullseye
启动debian容器映射端口80端口
docker run -itd --name ngx_php_kodbox_v1 -p 80:80 debian:bullseye /bin/bash

进入容器配置各种apt源:系统源,配置ngx源
cp /etc/apt/sources.list /tmp/

cat >/etc/apt/sources.list<<'EOF' deb https://mirrors.tencent.com/debian/ bullseye main non-free contrib deb-src https://mirrors.tencent.com/debian/ bullseye main non-free contrib deb https://mirrors.tencent.com/debian-security/ bullseye-security main deb-src https://mirrors.tencent.com/debian-security/ bullseye-security main deb https://mirrors.tencent.com/debian/ bullseye-updates main non-free contrib deb-src https://mirrors.tencent.com/debian/ bullseye-updates main non-free contrib deb https://mirrors.tencent.com/debian/ bullseye-backports main non-free contrib deb-src https://mirrors.tencent.com/debian/ bullseye-backports main non-free contrib EOF

临时禁用证书验证
# 临时解决方案(仅测试用)
apt update -o Acquire::https::Verify-Peer=false
#临时切换为http源安装ca-certificates
sed -i 's/https/http/g' /etc/apt/sources.list
apt install -y ca-certificates
sed -i 's/http/https/g' /etc/apt/sources.list
apt update
apt install -y curl gnupg2 ca-certificates lsb-release debian-archive-keyring unzip
时间同步
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
#配置ngx源-gpgcheck认证密钥
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
#配置ngx源
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \

http://nginx.org/packages/debian `lsb_release -cs` nginx" \
| tee /etc/apt/sources.list.d/nginx.list

apt update
#安装nginx
apt install -y nginx
#安装php

apt install -y php7.4-bcmath php7.4-bz2 php7.4-cgi \
php7.4-cli php7.4-common php7.4-curl php7.4-dba \
php7.4-dev php7.4-enchant php7.4-fpm php7.4-gd \
php7.4-gmp php7.4-imap php7.4-interbase php7.4-intl \
php7.4-json php7.4-ldap php7.4-mbstring php7.4-mysql \
php7.4-odbc php7.4-opcache php7.4-pgsql php7.4-phpdbg php7.4-pspell php7.4-readline php7.4-snmp \
php7.4-soap php7.4-sybase php7.4-tidy php7.4-xml \
php7.4-xmlrpc php7.4-xsl php7.4-zip php7.4-redis

#检查安装结果
dpkg -l |grep nginx
dpkg -l |grep php7.4 |wc -l
此处应输出33

安装后配置php
#默认为www-data 用户

#sed -i 's#^user =.*$#user =www-data#g' /etc/php/7.4/fpm/pool.d/www.conf
#sed -i 's#^group = www-data#group = nginx#g'/etc/php/7.4/fpm/pool.d/www.conf
cp /etc/php/7.4/fpm/pool.d/www.conf /tmp/
#开启php-fpm 9000端口
sed -i 's#/run/php/php7.4-fpm.sock#127.0.0.1:9000#g'/etc/php/7.4/fpm/pool.d/www.conf
#修改php7.4的pid文件的路径
sed -i 's#/run/php/php7.4-fpm.pid#/run/php7.4-fpm.pid#g' /etc/php/7.4/fpm/php-fpm.conf
#检查语法
php-fpm7.4 -t
#启动php
php-fpm7.4
#检查进程
ps -ef

安装后配置ngx
#修改ngx用户为www-data
sed -i '/^user/s#nginx#www-data#g' /etc/nginx/nginx.conf
#准备子配置文件

server {
listen 80;
server_name kodbox.linuxjk.cn;
root /app/code/kodbox;
access_log /var/log/nginx/kodbox.access.log main;
error_log /var/log/nginx/kodbox.error.log notice;
location / {
index index.php;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

#检查语法
nginx -t
#启动ngx
nginx -g "daemon off;"

日志软连接(dockerfile中创建软连接即可) 暂时略过
想使用docker logs查看日志而不是进入容器看日志,需要日志文件软连接到
/dev/stdout 普通访问日志
/dev/stderr 错误日志
lrwxrwxrwx 1 root root 15 Oct 4 03:44 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Oct 4 03:44 /dev/stdout -> /proc/self/fd/1
lrwxrwxrwx 1 root root 15 Oct 4 03:44 /dev/stdin -> /proc/self/fd/0

rm -f /var/log/nginx/*
rm -f /var/log/php7.4-fpm.log

ln -sf /dev/stdout /var/log/nginx/kodbox.access.log
ln -sf /dev/stderr /var/log/nginx/kodbox.error.log
ln -sf /dev/stderr /var/log/php7.4-fpm.log

部署代码
上传代码到/tmp/
unzip /tmp/kodbox.zip
mkdir -p /app/code/kodbox
mv /tmp/* /app/code/kodbox
#修改权限
chown -R www-data.www-data /app/code/kodbox/
chmod 755 /app/ /app/code/ /app/code/kodbox/
#报错没有读写权限可以执行chmod -R 777 /app/code/kodbox/

hosts解析并浏览器访问
常见故障
nginx命令启动ngx服务,重启nginx -s reload
重启php-fpm pkill php-fpm然后启动php-fpm7.4 即可.

项目步骤:启动mysql和redis镜像

启动mysql
docker volume create mysql57_kodbox docker volume ls docker run -d --name mysql57_kodbox --restart=always -v mysql57_kodbox:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=666 \ -e MYSQL_DATABASE=kodbox \ -e MYSQL_USER=kodbox \ -e MYSQL_PASSWORD=1 \ -p 3306:3306 \ -p 33060:33060 \ mysql:5.7-debian

链接数据库容器
docker exec -it mysql57_kodbox mysql -ukodbox -p666

-e指定容器所需变量
-e MYSQL_ROOT_PASSWORD=666    mysql的root密码
-e MYSQL_DATABASE=kodbox 创建1个数据库
-e MYSQL_USER=kodbox 指定用户(高权限用户)
-e MYSQL_PASSWORD=1 新建用户的密码

启动redis容器
docker volume create redis5.0_data
docker run -d --name "redis5.0" --restart=always -v redis5.0_data:/data/ -p 172.16.1.81:6379:6379 redis:5.0-alpine
限制本地ip
项目步骤:部署redis
用于缓存通用数据及会话session,加快系统访问

书写webdockerfile:      官方dockerfile

将宿主机的entry.sh发到容器中,放在根目录下
脚本中只写两条指令,一条后台运行php,一条前台运行nginx用于阻塞容器,只要跑多个服务就写脚本
CMD [“/entry.sh”]

#!/bin/bash
#desc:docker容器的入口脚本

php-fpm7.4
nginx -g “daemon off;”

根据dockerfile生成的镜像运行可道云容器并连接mysql,redis

进入Dockerfile所在目录生成镜像

chmod  +x entry.sh

docker build -t web:kodbox_v1 .

docker run -d --restart=always --name kodbox_v1 -p 8888:80 web:kodbox_v1 /entry.sh

启动mysql
docker volume create mysql57_kodbox
docker volume ls
docker run -d –name mysql57_kodbox –restart=always -v mysql57_kodbox:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=666 \
-e MYSQL_DATABASE=kodbox \
-e MYSQL_USER=kodbox \
-e MYSQL_PASSWORD=1 \
-p 3306:3306 \
-p 33060:33060 \
mysql:5.7-debian

链接数据库容器
docker exec -it mysql57_kodbox mysql -ukodbox -p1

启动redis容器
docker volume create redis5.0_data
docker run -d --name "redis5.0" --restart=always -v redis5.0_data:/data/ -p 172.18.244.60:6379:6379 redis:5.0-alpine

进入安装页面,mysql;redis的地址都写私网IP即可,成功配置后设置账号密码

admin 123456Ok.

dockerfile优化

清除镜像中缓存,避免镜像文件过大
可以删:
/var/cache 缓存文件
/usr/share/doc 软件的帮助
删前注意:
/usr/lib 软件安装位置,dockerfile中指定安装了很多php的依赖可以适当删除
/usr/bin 命令位置,系统内置到解释器中的命令删不掉(如cd)
/usr/share/locale 字符集语言,可以留几个常用的,zh,en开头留着

脚本优化方向

在容器运行后启动的脚本中加入语法检查的判断,如果检查失败则退出脚本输出报错

在根据dockerfile生成镜像的过程中,docker会把完成的每一步生成缓存,如果某一步报错了,修改dockerfile重新运行docker build会自动检查前面的步骤是否有变化,如果有变化则重新加载那一步,没变化不进行处理,从报错的步骤往下继续运行

kodbox两个模式

模拟桌面和类似网盘的文件管理系统

开源版本:用户10个以内,更多需要付费版支持

kodbox接入负载

多运行几个容器
docker run -d -p 8889:80 –name kodbox_final_8889 –restart=always web:kodbox_v1
docker run -d -p 8890:80 –name kodbox_final_8890 –restart=always web:kodbox_v1
docker run -d -p 8891:80 –name kodbox_final_8891 –restart=always web:kodbox_v1

负载机配置文件/etc/nginx/conf.d/kodbox.linuxjk.cn.conf

upstream kodbox_pools {
ip_hash;
#hash $remote_addr consistent;
server 10.0.0.81:80;
server 10.0.0.81:8889;
server 10.0.0.81:8890;
server 10.0.0.81:8891;
}

server {
listen 80;
server_name localkodbox.linuxjk.cn;
location / {
proxy_pass http://kodbox_pools;
include proxy.conf;
}
}

统一proxy配置/etc/nginx/proxy.conf

#Host头保留
proxy_set_header Host $http_host;
#XFF头
#XFF追加
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-Ip $remote_addr;
#proxy_cache oldboy_lidao;
#proxy_cache_valid 200 302 1h;
#proxy_cache_valid 301 1d;
#proxy_cache_valid any 1m;
#ngx buffer
proxy_buffering on;
proxy_buffer_size 128k;
proxy_busy_buffers_size 256k;
proxy_buffers 32 128k;

多阶段提交:编译安装tingene的dockerfile

一般在需要编译安装软件包或者代码时使用,一个Dockerfile中有多个FROM

解决镜像大小问题,第一次编译完361M,最终结果160M

ADD/COPY   –from调用中间镜像,最终把加工出的结果复制出来在最终镜像中使用

Dockerfile内容:

创建好临时镜像后使用COPY 或ADD  –from=temp ,将编译安装后的结果都复制到新镜像中

安装命令需要的依赖

创建用户组,用户

配置日志

构建与运行
docker build -t web:bunengsi_tengine_v1 .
docker run -d --name "bunengsi_tengine_v1" --restart=always -p 90:80 web:bunengsi_tengine_v1
浏览器访问

案例29 : war包容器tomcat

案例30: 制作jar包容器-ngx-webtui

案例:31前后端分离镜像

dockerfile小结

目标:自定义镜像

终极目标:根据企业需求创建各种各样的镜像(服务,配置,代码)

项目目标:

1.网站架构容器化.

2.一般web服务器即可

熟练掌握dockerfile格式及书写,dockerfile常用的指令,尽量多阅读官方或gitee/github上面的代码中的dockerfile.

.dockerignore 和dockerfile同一层级的隐藏文件

如果当前的dockerfile所在目录中正好有dockerfile所需的代码文件,用不到这个文件

如果dockerfile所在目录有很多和dockerfile不相关的文件,为了避免创建出来的文件过大,可以使用创建.dockerignore文件告诉docker服务端需要忽略的文件,不会被传输到镜像内(docker老版本有这个问题)

 docker镜像层次架构

未来应用的时候,镜像做好后存放在镜像仓库中

服务镜像:最好一个服务一个镜像

应用镜像:服务镜像+代码形成

这些镜像放在公司内部,做一个镜像仓库(私有云)

容器互联 —link 

–link是用于容器连接其他容器的选项,其他容器要运行中才行.

案例 分离式 nginx+php

问题:nginx和php如何互联

方案:1.使用ip链接,使用nginx的配置文件修改ip(繁琐)php的ip不固定

2. docker run 通过–link 连接两个容器(单向)类似于软链接

流程:

机器清单:nginx:1.24-alpine;php:7-fpm

准备好ngx,php配置文件, docker run -v 挂载配置文件,代码目录

修改配置,挂载配置,(nginx依赖php,先启动php,再启动nginx)

启动php容器 挂载www.conf到php容器中/usr/local/etc/php-fpm.d/www.conf

docker run -d –name test_php74 –restart=always \
-v `pwd`/conf/www.conf:/usr/local/etc/php-fpm.d/www.conf \
-v `pwd`/code/:/app/code/kodexp/ \
php:7-fpm
两个容器之间连接,所以php不需要设置端口映射

docker run -d –name kodexp_ngx –restart=always –link test_php74:php \
-p 12307:80 \
-v `pwd`/conf/nginx.conf:/etc/nginx/nginx.conf \
-v `pwd`/conf/kodexp.conf:/etc/nginx/conf.d/kodexp.conf \
-v `pwd`/code:/app/code/kodexp \
nginx:1.24
test_php74:php给test_php74容器起一个别名为php,nginx解析时会自动找到php容器的ip

在nginx配置文件中写–link右面的名字指代php容器的ip
location ~ \.php$ {
fastcgi_pass php:9000;

nginx与php,代码目录必须一致.因为php解析代码的时候也要找这个代码目录,如果不指定,php工作目录默认为/var/www/html/目录

小结

–link用于容器之间连接nginx ʖ php ,

–link本质是在对应的机器上添加了1个hosts解析 容器名字与容器的ip

给官方的php镜像安装php依赖:可以使用

docker-php-ext-install命令,我们自定义的镜像是不能使用的

通过自定义镜像或手动进入容器.
apt install -y zlib1g-dev libpng-dev
docker-php-ext-install gd
docker-php-ext-configure gd
php -m |grep gd
检查
<?php
phpinfo();
?>
里面有gd即可

docker -f过滤指令(docker自带过滤工具)

官方文档:

docker images -f 

也可以用于过滤特定状态的容器:

docker ps -f 

根据镜像名字进行过滤reference,过滤.

docker images -f  "reference=web"(默认按照时间排序)

docker images -f  "reference=web:exam*"

docker images -f  "reference=web:exam_back*"

对比镜像时间过滤出更加老的镜像

docker images  -f "before=web:exam_back_v2"

对比镜像时间过滤出更加新的镜像

docker images  -f "since=web:exam_back_v2"

过滤出指定镜像,同类中更老的镜像

docker images -f  "reference=web:exam_back*"  -f "before=web:exam_back_v2"

根据容器运行状态/是否health过滤:

docker ps -f "status=exited"(running)

docker ps -f    'health=unhealthy'

过滤后删除

docker images -f  “reference=web” | awk ‘NR>=2{print $3}’    (以后镜像名字可以写细致一点)
dd4eecedb141
087139b2256d
553b048b46b4
e4fc4a61b303

awk取出id后交给docker rmi或者加上-q就可以只显示镜像id,最后通过docker rmi删除

容器名字要有规范与标准化.

工具类镜像

好多镜像没有内置这些镜像,准备好一个有各种工具的镜像,需要运行的时候使用–link连接上需要调试的容器,

可以写dockerfile用于不同环境复用,也可以下载系统镜像进行安装

ping /telnet/nmap/nc/其他排查工具/ab/mysql客户端(测试mysql -h 指定ip   -P指定端口  -u 用户 -p 密码能不能连通)

docker run -itd   –link 调试容器 /bin/bash

Docker Compose—官网二进制版本(最新)

目前面临的问题:

  1. docker run指令越来越长.
  2. docker build后需要手动运行docker run.

解决:通过docker compose实现.

compose带来的新问题:docker compose单机编排工具,遇到网站群里的管理较为费劲.

容器集群管理解决方案:

  1. ansible+docker compose
  2. docker swarm docker官方提供集群管理工具.
  3. k8s(kubernetes) 容器集群编排与管理工具.
  4. mesos
  5. rancher web页面

通过Dockerfile一键创建镜像.

目前问题:⚠docker容器的管理(启动,关闭,重启),需要手动执行,如何管理多个容器.

部署与使用:

yum install -y docker-compose

环境准备

mkdir -p /server/compose/01-run-nginx

docker-compose格式

配置文件和ansible类似,但是比ansible简单

默认支持的compose文件名:docker-compose.yaml/docker-compose.yml

[root@docker01 /app/docker/compose/01-ngx]# cat index.html
docker-compose-ngx1.24
[root@docker01 /app/docker/compose/01-ngx]# cat docker-compose.yml
version: “3.3”
services:
ngx:
image: “nginx:1.24”
ports:
– 18888:80
restart: always
volumes:
– “./index.html:/usr/share/nginx/html/index.html”

1. 文件格式
cat docker-compose.yml
version: “3.3”
services:
web_ngx:
image: “nginx:1.20.2-alpine”
links:
– web_php
ports:
– “8000:80”
web_php:

image: “php:7-fpm”
2. 启动命令
docker-compose up -d
-d 后台运行

案例kodexp案例:nginx/php两个容器之间通信

注意这里使用的links连接方式,在Docker Compose中,links 参数应该使用服务名(service name)而不是容器名(container name)

  • 服务名(service name)kodexp_php_dc – 在Docker Compose网络内部使用的标识
  • 容器名(container name)kodexp_php_v2_dc – 在宿主机Docker环境中使用的标识

为什么使用服务名

Docker Compose网络机制

  • Compose会为项目创建一个专用网络
  • 在网络内部,服务之间通过服务名进行通信
  • links 参数实际上是在配置网络内的DNS解析

#在较新版本的docker-compose中 不需要显式声明links,Compose会自动创建网络

为什么可以省略links?

  1. 自动网络创建: Compose会自动创建网络并将所有服务加入
  2. DNS自动解析: 在网络内可以通过服务名直接访问其他服务
  3. 更简洁的配置: 减少冗余配置

depends_on指定依赖容器,需要先运行php

修改docker-compose与生效

如果docker-compose简单修改端口,数据卷.docker-compose up -d 会自动识别,重新创建容器.

如果容器的名字也改了,会造成新旧容器的端口冲突,会失败. 可以 up -d –remove-orphans 删除之前容器或失效容器

案例包含数据库kodbox案例:

部署kodbox,ngx,php,db

流程:

  •  docker run 数据库容器,数据卷挂载(数据卷空间)
  • ngx+php  1个镜像(dockerfile) docker build 然后run

改为docker-compose:

  • 读取dockerfile构建,并且指定镜像名字
  • cat docker-compose.yml
version: "3.3"
services:
kodbox_ngx_php:
image: "web:kodbox_dc_v1"
build:#根据Dockerfile构建上面名字的镜像
context: .
ports:
- 12306:80
links:#新版本的可以不加,会自动创建网络
- kodbox_db:db
depends_on:#此kodbox容器依赖db容器
- kodbox_db
restart: always
kodbox_db:
image: "mysql:5.7-debian"
volumes:#数据卷挂载
- kodbox_db_5.7:/var/lib/mysql
environment:#环境变量,同docker run 的-e
- MYSQL_ROOT_PASSWORD=666
- MYSQL_DATABASE=kodbox
- MYSQL_USER=kodbox
- MYSQL_PASSWORD=1
volumes:#与services同级,用于自动在宿主机上创建目录
kodbox_db_5.7:

compose文件的常用指令

volumes: 挂载数据卷

depends_on容器之间的依赖,先后顺序

其他选项:

docker-compose启动多个dockerfile的容器

前后端分离

nginx镜像包含前端代码+ngx配置文件

后端镜像jdk+jar包+配置文件

数据库独立.

后端内容[root@docker01 /app/docker/compose/04_all_in_one_exam]# tree -F
.
└── exam_back/
├── application-prod.yml
├── Dockerfile
├── entry.sh*
└── xzs-3.9.0.jar
1 directory, 4 files

前端内容
exam_front
├── admin.tar.gz
├── Dockerfile
├── exam.conf
└── student.tar.gz
2 directories, 8 files

书写docker-compose
version: "3.3"
services:
exam_db:
image: "web:exam_db_dc_v1"
container_name: exam_db_v1#指定容器名
build:#根据/db/路径下的Dockerfile进行构建镜像
context: ./db/
dockerfile: Dockerfile
volumes:
- exam_db_80_dc:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=1
- MYSQL_DATABASE=exam
- MYSQL_USER=1
- MYSQL_PASSWORD=1
exam_back:
image: "exam:backend_v1"
build:
context: ./exam_back/
dockerfile: Dockerfile
ports:
- 8000:8000
links:
#连接exam_db,简写db
#(在compose网络中exam_db就相当于exam_db_v1这个容器)
- exam_db:db
depends_on:
- exam_db
restart: always
exam_front:
image: "exam:front_v1"
build:
context: ./front/
dockerfile: Dockerfile
ports:
- 80:80
links:
- exam_back:back
depends_on:#前端依赖后端服务
- exam_back
restart: always
volumes:
exam_db_80_dc:

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部