## 1 容器架构
### 1.1 iaas paas saas
IAAS:基础设施即服务,IDC机房服务器出租,云厂商,云服务器
PAAS:平台即服务,服务运行环境是ok
SAAS软件即服务,服务已经准备好,直接使用产品
\Typora\008-docker\image-20250107155347343.png)
### 1.2 什么是容器
容器是隔离环境中运行的一个进程,如果进程结束,容器就会停止
细致:容器的隔离环境,拥有自己的ip地址,系统文件,主机名,进程管理,相当于一个迷你的系统
### 1.3 容器和虚拟化
| | 虚拟机 | 容器 |
| —- | ———————————————————— | ———————————————————— |
| 优点 | 1、使用简单;2、有成熟的管理工具;3、可以随意定制;4、启动虚拟机要经历完整的linux启动流程 | 1、快速部署,扩容,弹性伸缩;2、大部分都有现成镜像;3、让我们不再关注系统基础设施,把关注点放在配置,升级,优化;4、不依赖硬件;5、启动容器秒级;6、相当于一个进程 |
| 缺点 | 1、需要硬件支持虚拟化技术;2、资源利用率不高;3、同一台虚拟机跑多个服务,可能会有冲突;4、占用资源较多;5、不满足升级,快速扩容,快速部署,回滚不方便 | 1、使用较为复杂;2、共享linux系统内核 |
\Typora\008-docker\image-20250107155409562.png)
### 1.4 docker极速上手指南
linux内核:3.10以上,如果旧的内核,需要升级内核才能使用
unamr -r
安装docker环境,docker-ce(开源),docker-ee(企业版)
安装升级
“`sh
yum install -y docker
wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.24.tgz
tar xf docker-20.10.24.tgz
chown -R root:root docker
mv docker/* bin
rm -rf /usr/local/bin/runc
systemctl enable –now docker
docker version
“`
\Typora\008-docker\image-20250107155415764.png)
### 1.5 配置docker源(用于安装docker 非麒麟系统)
“`sh
1、通用的安装脚本
curl -fsSL https://get.docker.com/ -o install-docker.sh
2、配置docker yum源安装docker
yum install -y yum-untils
yum-config-manager –add-repo https://download.docker.com/linux/centos/docker-ce.repo
sed -i
‘s+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+’ /etc/yum.repos.d/docker-ce.repo
yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable –now docker
docker version
“`
### 1.6 配置docker下载镜像的加速
“`sh
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
[root@docker01 ~]# systemctl daemon-reload
[root@docker01 ~]# systemctl restart
自动补全
yum install -y bash-completion bash-completion-extras
```
\Typora\008-docker\image-20250107155510526.png)
\Typora\008-docker\image-20250107155525060.png)
### 1.7 导入镜像到本地
```sh
tar xf yangsenlinedu_useful_docker_images.tar.gz
cd yangsenlinedu_useful_docker_images/
for n in `ls ` ;do docker load -i $n ;done
docker images
```
### 1.8 运行第一个容器
```sh
[root@docker02 ~/yangsenlinedu_useful_docker_images]# docker run -d -p 80:80 --name ngx_v1 nginx:1.24
-d后台运行
-p映射 宿主机:容器
--name 给容器指定名字,容器不通
```
\Typora\008-docker\image-20250107155555168.png)
\Typora\008-docker\image-20250107155604621.png)
### 1.9 docker C/S架构
cs client/server 客户端/服务器
| docker相关词汇 | 说明 |
| ---------------- | -------------------- |
| 镜像image | 存放各种环境或服务 |
| 容器container | 进程,运行起来的镜像 |
| 仓库(存放镜像) | 远程仓库,本地仓库 |
\Typora\008-docker\image-20250107155538077.png)
\Typora\008-docker\image-20250107155744481.png)
docker pull nginx下载nginx镜像到本地仓库
如果本地仓库有,则提示镜像已经下载
如果本地仓库没有,则docker服务端远程访问仓库,下载镜像
使用docker -p端口映射,需要开启iptables的nat内核转发功能net.ipv4.ip_forward = 1
镜像的一些命令
| 命令 | 说明 |
| ------------- | ---------------------------------------------- |
| docker search | 搜索镜像,优选官方,stars数量多的 |
| docker pull | 拉取镜像,注意版本 |
| docker push | 上传镜像 |
| docker load | 导入镜像 |
| docker save | docker save centos:7 -o docker_centos7.tar.gz |
| docker images | 查看镜像列表 |
| docker rmi | 删除镜像 |
| docker tag | 给镜像打标签 |
容器中常用的镜像
| docker镜像使用的系统 | 说明 |
| -------------------- | --------------------------------------------- |
| ubuntu | 都可以做镜像 18.04 20.04 22.04 |
| debian | 都可以做镜像bluster10,bullseye11,bookworm12 |
| centos | 都可以做镜像 |
| alpine | 镜像非常小 |
### 1.10 保存镜像和导入
简称sl
```sh
docker image save 简写docker save
docker image load 简写docker load
docker save nginx:alpine -o nginx_alpine.tar
docker save nginx:alpine | gzip ngx:alpine.tar.gz
导入
docker load -i nginx_alpine.tar
批量导入
使用for循环
批量导出
可以书写批量导出docker镜像脚本.
#!/bin/bash
#author: ysl996
#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 ‘s#:#_#g’`
docker save ${name} -o ${name_new}.tar
done
删除镜像
docker image rm ===docker rmi
docker image prune 清理未使用的镜像
docker iamges -a 查看所有镜像,包含隐藏镜像
“`
### 1.11给镜像设置标签
给镜像设置一个新的名字
应用场景
自定义镜像
搭建与使用内部仓库registry
“`sh
[root@docker01 ~]# docker tag nginx:1.24 nginx:1.24_v1
[root@docker01 ~]# docker images | grep nginx
nginx 1.24 b6c621311b44 17 months ago 142MB
nginx 1.24_v1 b6c621311b44 17 months ago 142MB
nginx 1.24-alpine 55ba84d7d539 17 months ago 41.1MB
“`
### 1.12 查看镜像详细信息
“`sh
[root@docker01 ~]# docker image inspect nginx:1.24-alpine
#jq专门过滤,json形式数据
docker inspect mysql:8.0-debian |jq .[].Id
docker inspect mysql:8.0-debian | jq .[].Config.Env | jq .
[0]
结果中最外面是: [] 所以先用 jq .[]进入到 []中.
结果中{} 可以用jq .Id 形式取出,对于缩进的需要先访问上级然后继续访问
jq需要安装yum install -y jq
“`
### 1.13 自定义镜像
Dockerfile详解
### 1.14 docker镜像指令小结
“`sh
docker pull
docker push
docker save
docker load
docker rmi
docker prune
docker tag
docker build
docker image inspect
“`
## 2 docker的容器管理
容器的一些命令
“`sh
docker container xxx
docker ps
docker run
dockercreate –name
docker start/stop/restart/kill
docker rm 批量删除所有容器docker rm -f `docker ps -aq`
docker exec -it 容器名 /bin/bash
docker inspect
docker stats
docker top
“`
### 2.1 run 运行容器与查看容器信息
“`sh
docker container run过程
1、查找本地是否有这个镜像,如果没有,则先下载镜像docker image pull
2、下载完成后创建容器
3、启动容器
一个docker run相当于pull/create/start
“`
### 2.2 docke容器指令的选项
| docker容器指令的选项 | 说明 |
| ——————– | ————————————— |
| -d | 后台运行 |
| -p | 端口映射 |
| -v | 数据卷挂载 |
| -i | interactive进入交互式,一般与-t一起使用 |
| -t | 分配一个终端 |
| –name | 给容器起名,不起的话会随机起名 |
| -e | 创建修改容器的环境变量 |
用到-p选项的时候需要在/etc/sysctl.conf添加一条net.ipv4.ip_forward = 1
\Typora\008-docker\image-20250107155836817.png)
### 2.3 删除容器
| 删除容器命令 | 说明 |
| ———————————————————— | ———————- |
| docker rm -f | 后面选项是容器名字或id |
| docker rm -f `docker ps -qa` 或docker ps -aq \| xargs docker rm -f | 删除所有容器 |
### 2.4 启动debian/ubt容器
“`sh
[root@docker01 ~]# docker run -it –name centos_7 centos:7 /bin/bash
这样起退出后容器也会退出
[root@docker01 ~]# docker run -itd –name centos_back centos:7 /bin/bash
这样就不会退出
选项-itd容器后台运行同时进入容器,可以用于没有服务的系统镜像后台运行
“`
### 2.5 容器可以一直运行的原理
运行中的容器需要在容器中持续运行某个命令或服务
要在容器中有个命令、服务把这个容器阻塞主
容器想要在后台一直运行,那么容器的初始命令必须阻塞,否则容器就会退出
前台运行
“`sh
nginx -g ‘dameon off’
/usr/sbin/php-fpm –nodaemize
/usr/sbin/sshd/ -D
java -jar xxx.jar
“`
### 2.6 进入容器
“`sh
[root@docker01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e8bc669b3d02 centos:7 “/bin/bash” 2 minutes ago Up 2 minutes centos_back
[root@docker01 ~]# docker exec -it centos_back /bin/bash
[root@e8bc669b3d02 /]#
“`
### 2.7 exec与attach区别
| docker | exec | attach |
| —— | ——————————- | ———————————————————— |
| 共同点 | 连接到已经运行的容器中 | 连接到已经运行的容器中 |
| 区别1 | 容器不需要有终端(不需要加-it) | 必须有终端(运行) |
| 区别2 | 每个连接互不影响 | 每个连接的所有操作与输出都是同步一致,退出容器后容器也退出了 |
\Typora\008-docker\image-20250107155912446.png)
### 2.8 docker重启策略
| docker重启策略 | 说明 |
| —————– | ———————— |
| always | 自动重启 |
| unless-stopped | 只在容器关闭,停止的时候 |
| on-failure | 只在失败的时候重启 |
| 默认不加–restart | 不会自动重启 |
“`sh
[root@docker01 ~]# docker run -d –name ngx_alpine –restart=always nginx:1.24-alpine
“`
重启策略在容器运行的时候也可以重新添加,所以运行的时候忘了也无所谓
“`sh
[root@docker01 ~]# docker update –restart always `docker ps -aq`
“`
### 2.9 容器日志
| docker logs | 说明 |
| ———– | —————————————— |
| -f | 查看实时更新,显示所有日志后再查看实时更新 |
| –tail 或-n | –tail 20,最近20行 |
| –since | 5m 最近5分钟日志 |
| –until | 指定到什么时间结束 |
“`sh
[root@docker01 ~]# docker logs -n20 -f nginx_test
docker logs -f –since “2023-11-16T00:00:00Z” nginx_v3
docker启动mysql的时候需要添加-e MYSQL_ROOT_PASSWORD=1
[root@docker01 ~]# docker run -d –name mysql_5.7 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=1 –restart=always mysql:5.7-debian
“`
### 2.10 docker run 背后的指令
“`sh
#1. 拉取镜像
docker pull nginx:1.24-alpine
#2. 创建容器
docker create -p 81:80 –name ngx_1.24_alpine_v2 —
restart=always nginx:1.24-alpine
#3. 启动容器
docker start ngx_1.24_alpine_v2
#4. 检查结果
docker ps
docker create
docker start
docker stop
docker restart
docker pause/unpause
“`
### 2.11 宿主机文件传输到容器中
“`sh
docker cp传输一个代码文件
[root@docker01 ~]# docker cp initial-setup-ks.cfg ngx_v2:/
“`
### 2.12 保存容器—生成镜像
“`sh
1、启动基础镜像
docker run -d –name ngx_bird_v1 -p 8848:80 –restart=always nginx:1.24
2.将代码传到容器
[root@docker01 ~]# docker cp bird/ ngx_bird_v1:/usr/share/nginx/html/
3.测试连接,没有问题后将容器保存为镜像
[root@docker01 ~]# docker commit ngx_bird_v1 web:ngx_bird_v1
4.使用新的镜像创建容器并测试
[root@docker01 ~]# docker run -d -p 8888:80 –restart=always –name ngx_bird_v2 web:ngx_bird_v1
5.测试通过后删除之前的临时容器
docker rm -f ngx_bird_v1
“`
\Typora\008-docker\image-20250107155928908.png)
“`sh
通过docker commit可以实现初步定义镜像
docker commit 容器名 镜像名:版本
1、选择合适的基础镜像;
2、启动容器,链接容器,部署,配置,调试
3、commit生成镜像
4、通过镜像创建容器并调试
“`
### 2.13 其他容器指令
“`sh
当docker stop关闭不了容器的时候使用docker kill
查看容器中进程信息
docker top 容器名
docker top 容器名 -ef/-efL/aux
docker stats
[root@docker01 ~]# docker top ngx_bird_v2
UID PID PPID C STIME TTY TIME CMD
root 5972 5953 0 11:38 ? 00:00:00 nginx: master process nginx -g daemon off;
101 6013 5972 0 11:38 ? 00:00:00 nginx: worker process
101 6014 5972 0 11:38 ? 00:00:00 nginx: worker process
资源限制
[root@docker01 ~]# docker run -d –name ngx_bird_v3 -m 50m –cpus 1 nginx:1.24
在启动容器的时候没有限制资源,也可以使用docker update添加限制
[root@docker01 ~]# docker update -m 80m –memory-swap 100m ngx_bird_v3
“`
\Typora\008-docker\image-20250107155940437.png)
### 2.14 export和import导入导出
类似于save和load
| save/load | export/import |
| ——— | ———————————– |
| 镜像 | export容器–镜像 import默认没有名字 |
“`sh
[root@docker01 ~]# docker export -o web_bird:v2 ngx_bird_v3
[root@docker01 ~]# ls
anaconda-ks.cfg initial-setup-ks.cfg
bird yangsenlinedu_useful_docker_images
docker yangsenlinedu_useful_docker_images.tar.gz
docker-20.10.24.tgz web_bird:v2
[root@docker01 ~]# docker import web_bird\:v2
sha256:5860fdd4c92ee4fa4e67de865ef72c1f7ab59f2b3778dc0396b65e984abb54e9
[root@docker01 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
“`
### 2.15 容器管理指令小结
| docker容器 | 说明 | 参数 |
| ——————————————– | ——————– | ——————————————- |
| docker run | 启动容器 | -d -it -itd –name –resart –cpus –memory |
| docker ps | 查看容器信息 | -q -a |
| docker exec/attach | 链接容器 | -it |
| docker update | 动态修改容器配置 | cpu限制,内存限制,修改重启规则 |
| docker cp | 传输文件或目录到容器 | 目录对目录,文件对文件 |
| docker commit | 把容器保存为镜像 | 简单定义,复杂一般使用dockerfile |
| docker stop/start/restart/pause/unpause/kill | | |
| docker top/stats | 查看容器状态 | |
| docker inspect | 查看容器信息 | |
| docker export和save区别 | 导出镜像 | |
### 2.16 docker inspect查看信息与过滤
“`sh
查看容器,镜像,网络,数据卷等资源的信息
输出形式是json
1.三剑客取行取列
2.jq命令加工json query查看
3.docker自带的工具
[root@docker01 ~]# docker inspect ngx_bird_v3 | jq .[].Config.ExposedPosts
镜像
镜像名字RepoTags
映射的端口号Config.ExposedPorts
镜像大小Size
容器
容器名字Name
容器状态State.Status
重启策略HostConfig.RestartPolicy
容器使用的镜像Config.Image
ip地址NetworkSettings.IPAddress
“`
### 2.17 端口映射
端口映射的本质类似于iptables防火墙的端口映射
用户通过端口访问容器中的某个端口
本质是通过iptables nat规则实现的,nat表中创建了docker自定义的链
“`sh
[root@docker01 ~]# docker run -d -p 8080:80 –name ngx_test nginx:1.24
相当于添加了一条
iptablws -t nat -A DOCKER ! -i docker0 -p tcp -m tcp –dport 8080 -j DNAT –to-destination 170.17.0.2:80
查看所有运行中容器的ip地址
for ip in `docker ps -q`
do
docker inspect $ip | jq .[].NetworkSettings.IPAddress
done
“`
### 2.18 端口映射案例
1对1端口映射
“`sh
[root@docker01 ~]# docker run -d -p 80:80 -p 443:443 –name ngx_ports nginx:1.24-alpine
-p后面也可以端口范围80-8080:80-8080
“`
映射多个端口
“`sh
一个一个写或者连续
“`
把容器的端口随机映射到宿主机
“`sh
[root@docker01 ~]# docker run -d -P –name ngx nginx:1.24-alpine
-P 大写P
docker ps查看映射到哪个端口了
“`
ip绑定端口
“`sh
用户只能通过宿主机的某个网卡连接这个端口
[root@docker01 ~]# docker run -d -p 172.16.1.81:8081:80 nginx:1.24-alpine
“`
用户访问的时候经历了什么\Typora\008-docker\image-20250107155958261.png)
### 2.19 数据卷挂载
#### 1 概述
如果容器崩了,容器被误删除了,容器中的数据将丢失,接下来解决数据不丢,
如何解决数据持久化问题?数据卷(挂载),让数据永久保存在宿主机中
\Typora\008-docker\image-20250107160046593.png)
\Typora\008-docker\image-20250107160112593.png)
#### 2 实战
docker run -v 宿主机路径:容器内部路径
3 创建数据库容器并完成持久化
| 内容 | 宿主机 | 容器 |
| ——– | ————— | ————– |
| 项目目录 | /app/data/db8.0 | /var/lib/mysql |
“`sh
1、创建主机目录
2、创建容器并指定持久化
[root@docker01 ~]# docker run -d –name mysql –restart always -v /app/data/db8.0:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=1 mysql:8.0-debian
3、进入数据库容器,并创建数据库
[root@docker01 ~]# docker exec -it mysql /bin/bash
mysql -uroot -p1
create database
4、删除容器
[root@docker01 ~]# docker rm -f mysql
5、再创建容器并指定持久化
[root@docker01 ~]# docker run -d –name mysql –restart always -v /app/data/db8.0:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=1 mysql:8.0-debian
6、查看库,库还在
[root@docker01 ~]# docker exec -it mysql mysql -uroot -p1
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.33 MySQL Community Server – GPL
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.
mysql> show databases;
+——————–+
| Database |
+——————–+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+——————–+
5 rows in set (0.00 sec)
“`
#### 3 数据卷挂载小结
把宿主机文件或目录挂载到容器中
数据持久化,容器没了,数据还在
#### 4 案例-挂载到数据卷空间
做数据持久化,不关注数据具体在哪里
/var/lib/docker目录下面
“`sh
1、创建数据卷空间
[root@docker01 ~]# docker volume create mysql_data
2、查看数据卷空间
[root@docker01 ~]# docker volume inspect mysql_data
3、创建容器
[root@docker01 ~]# docker run -d –name mysql –restart always -v mysql_data:/var/lib/mysql -v MYSQL_ROOT_PASSWORD=1 mysql:8.0-debian
4、查看
[root@docker01 ~]# docker inspect mysql
“`
\Typora\008-docker\image-20250107160136706.png)
#### 5 数据卷小结
熟悉掌握挂载指定的目录或文件到容器中即可
-v指定宿主机目录、文件和容器目录,文件
做持久化,不关注数据放在哪,数据卷空间即可,-v 数据卷空间:容器文件或目录
docker volume
### 3 容器架构自动化部分
docker镜像,容器,端口映射,数据卷挂载
目标:创建一个ngx+bird游戏镜像,自动化实现Dockerfile
#### 3.1 Dockerfile概述
应用场景,通过1个文件Dockerfile,生成自定义镜像
#### 3.2 Dockerfile格式
“`sh
1、指定基础镜像
FROM nginx:1.24-alpine
2、基本信息,相当于说明
LABEL nginx+bird
3、对镜像进行操作,执行命令
RUN sed -i ‘s/#gzip/gzip/g’ /etc/nginx/nginx.conf
4、把压缩包内容传输到目录
ADD bird.tar.gz /usr/share/nginx/html/
5、告诉镜像使用者容器映射的是80 443
EXPOSE 80 443
6、收尾、入口指令,运行容器后默认运行的命令
CMD [“nginx”,”-g”,”daemon off;”]
7、根据Dockerfile构建镜像,-t是给自定义镜像命名
docker build . -t ‘ngx:bird_v1’
8、运行
docker run -d –name bird -p 81:80 ngx:bird_v1
9、调试
“`
\Typora\008-docker\image-20250107160213347.png)
#### 3.3 Dockerfile中的指令
都是大写
| Dockerfile指令 | 含义 | 建议 |
| —————— | ———————————————————— | ———————————————————— |
| Dockerfile开头部分 | | |
| FROM | 指定基本镜像,类似于docker pull下载镜像 | 尽量指定具体的版本 |
| LABEL | 用于指定容器的属性信息 | 推荐使用LABEL,不推荐MAINTAINER |
| MAINTAINER | 不再使用,推荐使用LABEL 个人信息 | |
| ENV | 用于创建Dockerfile中使用的变量 | 软件版本可以创建使用变量 |
| Dockerfile中间部分 | | |
| RUN | 制作镜像过程中需要执行的命令,通常系统配置,服务配置,部署。但是不能出现阻塞 | 不建议连续使用多个RUN使用&&来执行多个命令 |
| ADD | 把指定文件或目录拷贝到容器中,会自动解压压缩包,但是解压不了zip | 拷贝压缩包使用 |
| COPY | 可以把指定的文件或目录拷贝到文件中,不支持地总解压 | 拷贝文件或目录 |
| WORKDIR | 指定容器的默认的工作目录 | 一般用于配合ADD,COPY需要书写容器中路径指令,Dockerfile使用相对路径操作容器 |
| VOLUME | 挂载数据卷 | 创建随机的数据卷挂载容器的目录,推介使用docker run的时候指定-v即可 |
| Dockerfile结尾部分 | | |
| EXPOSE | 指定镜像要对外暴露的端口 | 用于指定一个或多个容器的端口,未来这个端口可以被-P识别 |
| CMD | 容器的入口指令,可以在docker run的时候替换,==运行镜像启动容器的时候,容器默认运行的命令是什么 | 大部分都会使用CMD |
| ENTRYPOINT | 用于指定容器的入口命令,无法被docker run替换,docker run指定的时候仅仅作为entrypoint命令的参数而已 | 使用不多 |
#### 3.4 案例-Dockerfile使用WORKDIR,VOLUME,ENV
“`sh
ENV 全局变量
WORKDIR 工作目录,容器初始目录,进入容器后默认的所在目录,
VOLUME 容器中哪些目录或文件,需要做数据卷挂载-v
[root@docker01 /app/docker/dockerfile/bird]# cat Dockerfile
FROM nginx:1.24-alpine
LABEL bird and ngx
ENV NGX_CONF /etc/nginx/nginx.conf
ENV CODE_TAR bird.tar.gz
ENV VO_DIR /app/code/upload/
WORKDIR /usr/share/nginx/html/
RUN sed -i ‘s/#gzip/gzip/g’ ${NGX_CONF}
ADD ${CODE_TAR} .
VOLUME ${VO_DIR}
EXPOSE 80
CMD [“nginx”,”-g”,”daemon off;”]
[root@docker01 /app/docker/dockerfile/bird]#
“`
#### 3.5 小结
ENV创建全局环境变量
WORKDIR指定工作目录
VOLUME指定容器中哪些路径需要映射出去,类似EXPOSE
#### 3.6 Dockerfile相关故障
1.dockerfile书写问题
2.docker run然后看日志
3.docker run -it前台查看启动流程
4.docker run -it xxx /bin/bash进入容器,执行检查类命令,手动检查配置文件
#### 3.7 CMD,ENTRYPOINT区别
| CMD和ENTRYPOINT区别 | 共同点 | 区别 |
| ——————- | ————————————————- | ———————————————————— |
| CMD | 运行容器的时候默认运行CMD或者ENTRYPOINT后面的命令 | run的时候替换,如果镜像名字后面指定了命令,则CMD内容就会被替换 |
| ENTRYPOINT | 运行容器的时候默认运行CMD或者ENTRYPOINT后面的命令 | run的时候如果指定了命令内容,那只是entrypoint的参数而已,追加 |
“`sh
[root@docker02 /app/docker/dockerfile]# docker run -d -p 1111:80 –name nginx_entrypoint ngx_entrypoint:latest -g daemon off;
40832fd5b023943d8fc6ee686eda41a3386d9aae2f024defff9c700621a9a613
[root@docker02 /app/docker/dockerfile]# ls
03-test-cmd-entrypoint bird Dockerfile
[root@docker02 /app/docker/dockerfile]# cat Dockerfile
FROM nginx:1.24
LABEL author:ysl desc:test cmd and entrypoint
ENTRYPOINT [“nginx”]
“`
| CMD和ENTRYPOINT同时使用 | 说明 |
| ———————– | ————————————— |
| 同时使用 | CMD写的内容将作为ENTRYPOINT的内容的选项 |
| 使用 | ENTRYPOINT后面接脚本用于判断 |
“`sh
FROM nginx:1.24
LABEL author=ysl996 desc=”测试 cmd和entrypoint”
ENTRYPOINT [“nginx”]
CMD [“-g”,”daemon off;”]
“`
#### 3.8 多阶段提交
解决问题:
防止镜像过大,因为dockerfile创建镜像过程中每个步骤都会有子镜像产生,还有有些我们只需要结果,并不需要安装的依赖
使用dockerfile多阶段提交方法:类似于接力,选择一个或多个临时镜像进行编译,最终把临时镜像中的结果复制到指定的新的镜像中
“`sh
不使用多阶段提交,安装tengine
“`
#### 3.9 多阶段提交应用场景
目标:压缩镜像大小
应用场景:编译(nginx,java代码,golang代码,前端代码)
镜像分层次架构,适用于编程、构建场合,先通过中间镜像进行编译,变成结果放到新的镜像中
FROM ubuntu:22.04 AS temp 给中间镜像起个别名
最终镜像中通过COPY –from=temp /app/ /app/
/app/docker/dockerfile/04中Dockerfile有问题
#### 3.10 war包容器tomcat
“`sh
FROM tomcat:9.0-jdk8
LABEL author=ysl996
ENV WAR=ROOT.war
ENV WEBAPP=/usr/local/tomcat/webapps/
WORKDIR ${WEBAPP}
ADD ${WAR} .
EXPOSE 8080
CMD [“catalina.sh”,”run”]
#通过指定命令对容器中的服务进行检查
#用于检查容器运行中(服务运行)但是用户无法访问
HEALTHCHECK –interval=5s –timeout=20s –retries=2 CMD curl 127.0.0.1:8080
HEALTHCHECK指令监控服务,业务是否正常,CMD
curl web服务
mysql -ucheck -p1 -e “select user,host from mysql.user;”
redis-cli info
“`
#### 3.11 制作jar包容器-ngx-webtui
“`sh
FROM java:8u111-jdk
LABEL author=yangsenlinysl996
ENV CODE_DIR=/app/code/
ENV JAR_NAME=nginxWebUI-3.4.0.jar
#默认用的命令解释器/bin/sh
SHELL [“/bin/bash”,”-c”]
RUN set -euxo pipefail ;\
umask 0022 ;\
mkdir -p ${CODE_DIR} ;
WORKDIR ${CODE_DIR}
ADD ${JAR_NAME} .
ADD entry.sh /
EXPOSE 8080
CMD [“/entry.sh”]
HEALTHCHECK –interval=5s –timeout=20s –retries=2 \
CMD curl 127.0.0.1:8080
“`
#### 3.12 网站架构容器化(迁移到容器中)
服务,代码,自定义镜像(没有直接可用的镜像或官网的镜像无法满足)
自定义tengine镜像
自定义tomcat镜像
自定义jar包镜像
#### 3.13 前后端分离镜像
mysql8.0库,用户,导入sql
镜像后端jar+java
前端nginx+子配置文件+代码
“`sh
mysql容器变量
MYSQL_ROOT_PASSWORD root密码
MYSQL_DATABASE 创建指定的库
MYSQL_USER创建用户,MYSQL_PASSWORD用户对应的密码
添加exam库,并授予ysl用户管理exam库
docker run -d –name qh_mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=’XZnh@95599′ -e MYSQL_DATABASE=exam -e MYSQL_USER=exam -e MYSQL_PASSWORD=’XZnh@95599′ mysql_8.0-debian
“`
3.14 dockerfile小结
“`sh
FROM
LABEL
ENV
SHELL
WORKDIR
RUN
ADD/COPY
VOLUME
EXPOSE
ENTRYPOINT
CMD
HEALTHCHECK
“`
“`sh
目标:自定义镜像
中级目标:根据企业需求创建各种各样的镜像(服务,配置,代码)
项目目标:
1、网站架构容器化
2、一般web服务即可
熟练掌握dockerfile格式及书写
“`
尽量多阅读官方或gitee、github上面的代码中的dockerfile
“`sh
排障流程
第一类问题:运行docker build故障
根据错误提示的步骤大概定位是哪个步骤出了问题
如果是RUN,拆分,是为了定位哪个命令问题
其他指令看错误提示即可
第二类问题:运行docker run故障
查看docker ps -a –no-trunc查看详细入口命令与错误提示
辅助docker logs查看
docker run -it 容器名 /bin/bash前台运行,进入容器,手动启动服务,观察错误提示
“`
| 生产环境应用建议 | 说明 |
| ———————— | —————————————————- |
| 尽量保证每个镜像功能单一 | 尽量避免多个服务运行在同一个镜像中 |
| 选择合适的基础镜像 | 不一定都要从头做 |
| 注释与说明 | 添加一定的注释和镜像属性信息 |
| 指定版本号 | 使用镜像的时候指定版本 |
| 减少镜像层数/步骤 | 尽可能合并RUN,ADD,COPY |
| 记得收尾(减少镜像大小) | 清理垃圾,记得清理缓存,临时文件,压缩包 |
| 合理使用dockerignore | dockerfile同一个目录,隐藏文件,构建的时候忽略的文件 |
““sh
直接指定要排除的内容
cat .dockerignore
etc*.tar.gz
先排除所有,通过!准许指定文件传输到dockerd
*
!target/nginxWebUI-*.jar
!Dockerfile
!entrypoint.sh
““
#### 3.14 搭建个人网盘
可道云代码
kodexp仅需要ngx+php
kodbox需要ngx+php+mysql+存储+redis
“`sh
代码kodbox,云盘和云桌面
lnmp环境
nginx+php1个镜像
db mysql8.0
redis 5.0
“`
\Typora\008-docker\image-20250107160257687.png)
项目步骤:ngx+php镜像
启动debian容器映射80端口
“`sh
docker run -itd –name ngx_php_kodbox_v1 -p 80:80 ubuntu:22.04 /bin/bash
1、进入容器配置apt源
docker exec -it ngx_php_kodbox_v1 /bin/bash
cp /etc/apt/sources.list /etc/apt/sources.list.bak
sed -ri ‘s/archive.ubuntu.com\/|security.ubuntu.com\//mirrors.aliyun.com\//g’ /etc/apt/sources.list
2、配置nginx源、安装nginx
sed -i ‘s/deb.debian.org/mirrors.aliyun.com/g’ /etc/apt/sources.list
apt update
apt install -y curl gnupg2 ca-certificates lsb-release debian-archive-keyring
curl https://nginx.org/keys/nginx_signing.key | gpg –dearmor \
| tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
gpg –dry-run –quiet –no-keyring –import –import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
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
echo -e “Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n” \
| tee /etc/apt/preferences.d/99nginx
apt update
apt install -y nginx
3、安装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
4、检查nginx和php安装结果
dpkg -l |grep nginx
dpkg -l |grep php7.4 |wc -l
5、配置php
5.1 备份配置文件
cp /etc/php/7.4/fpm/pool.d/www.conf /etc/php/7.4/fpm/pool.d/www.conf`date +%F`
cp /etc/php/7.4/fpm/php-fpm.conf /etc/php/7.4/fpm/php-rpm.conf`date +%F`
5.2 修改php-fpm端口
sed -i ‘s/\/run\/php\/php7.4-fpm.sock/127.0.0.1:9000/g’ /etc/php/7.4/fpm/pool.d/www.conf
5.3 修改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-fpm7.4
ps -ef | grep php
6、配置ngx
sed -ri ‘/^user/s/nginx/www-data/g’ /etc/nginx/nginx.conf
增加子配置文件
server {
listen 80;
server_name kodbox.yangsenlinlinux.cn;
root /app/code/kodbox;
access_log /var/log/nginx/access_log.log main;
location / {
index index.php;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~* \.hph& {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
7、日志连接
root@9e6f1807a1a5:/etc/nginx/conf.d# rm -rf /var/log/nginx/*
root@9e6f1807a1a5:/etc/nginx/conf.d# ln -sf /dev/stdout /var/log/nginx/access_log.log
root@9e6f1807a1a5:/etc/nginx/conf.d# ln -sf /dev/stderr /var/log/nginx/error.log
部署代码
[root@docker01 ~]# docker cp kodbox/ ngx_php_kodbox_v1:/tmp/
[root@docker01 ~]# docker exec -it ngx_php_kodbox_v1 /bin/bash
root@9e6f1807a1a5:/# mkdir -p /app/code
root@9e6f1807a1a5:/# mv /tmp/kodbox/ /app/code/
root@9e6f1807a1a5:/# chown -R www-data:www-data /app/code/kodbox/
部署mysql和redis镜像
[root@docker01 ~]# docker volume create mysql57_kodbox
mysql57_kodbox
[root@docker01 ~]# docker volume ls
[root@docker01 ~]# docker inspect volume mysql57_kodbox
[root@docker01 ~]# docker run -d –name mysql_kodbox -v mysql57_kodbox:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=’XZnh@95599′ -e MYSQL_DATABASE=kodbox -e MYSQL_USER=kodbox -e MYSQL_USER_PASSWORD=’XZnh@95599′ -p 3306:3306 -p 33060:33060 mysql:5.7-debian
[root@docker01 ~]# docker run -d –name ‘redis5.0’ -v redis_data:/data -p 172.16.1.81:6379:6379 redis:5.0-alpine
“`
“`sh
项目步骤:书写web dockerfile
创建ngx+php镜像
流程
配置apt源,apt update
安装各种软件
进行配置ngx,php
站点目录,代码,修改权限
清理镜像缓存
cmd启动ngx和php
“`
#### 3.15容器互联 –link
–link是用于容器连接其他容器的选项,其他容器要运行中才行
本质是在容器中配置了hosts解析,单向解析
#### 3.16 docker -f 过滤指令
#### 3.17 docker compose
“`sh
目前面临的问题
docker run指令越来越长
docker build后需要手动运行docker run
通过docker compose实现
compose带来的新的问题:docker compose单机编排工具,遇到网站集群里的管理比较费劲
容器集群管理解决方案:
1、脚本
2、ansible+docker compose
3、docker swarm docker官方提供集群管理工具
4、k8s(kubernetes)容器集群编排与管理工具
5、mesos
6、rancher web页面
“`
\Typora\008-docker\image-20250107161203250.png)
单机容器编排工具
“`sh
docker compose类似于docker run指令
集群管理
ansible+shell或docker compose
docker compose需要单独安装,go语言写的,解压后放在/usr/sbin/目录下面
语法是yaml格式
“`
#### 1 compose极速上手指南
“`sh
环境准备
mkdir -p /server/compose/01-run-nginx
默认支持的compose名
docker-compose.yaml或docker-compose.yml
启动命令
docker-compose up -d
“`
| docker-compose组成 | 说明 |
| —————— | ———————————– |
| version | 3.3为了兼容旧的docker-compose加的, |
| services | 指定容器与容器相关信息,核心 |
| volumes | 创建数据卷空间 |
| networks | 自定义网络 |
| docker-compose命令格式 | 说明:这个命令包含了docker container和docker images命令 |
| ———————- | ———————————————————— |
| up -d | up==run创建并运行容器,启动的时候后台运行类似于docke rrun -d |
| down | 删除容器,删除所有内容(网络,数据卷) |
| stop/start/restart | 关闭、开启、重启 |
| ps | 查看容器运行情况,只有-q选项 |
| top | 查看容器进程信息 |
| logs | 容器日志 |
| rm | 删除容器(需要容器已经关闭) |
| 镜像 | |
| images | 查看镜像 |
#### 2 案例-包含数据库kodbox案例
“`sh
部署kodbox、nginx、php、db
流程
1、dockerfile自定义php,复用之前
2、docker run数据库容器,数据卷挂载,数据卷空间
3、docker-compose注意依赖
读取dockerfile
指定镜像名字
docker-compose运行指定的dockerfile,后期不用继续docker build,然后docker-compose up -d
看到day-54文档88页
“`
\Typora\008-docker\image-20250107160333118.png)
#### 3 小结
docker build 构建镜像docker run运行容器
书写docker compose的时候通过docker run自行测试
#### 3.18 docker,docker-compose升级案例
“`sh
1、背景
安全,旧的版本有漏洞,如果软件(命令,服务)有漏洞,升级软件到不受影响的版本
服务新版本,新功能,新环境,新业务使用,旧的保持不变
2、流程:
1.测试环境,部署新服务,部署代码测试
2.准备备用方案,回滚,备份
3.采取正式环境,逐步更新策略,修改负载权重,减小新节点访问量
4.测试ok,逐步更新其他机器
“`
3.具体流程
| 更新流程 | 说明 |
| ———————- | —————————————————- |
| 更新docker-compose | 下载二进制docker-compose的命令,备份已有的命令,替换 |
| 测试docker-compose | 最新版 |
| 更新docker | 下载二进制docker |
| 先备份已有的docker命令 | 关闭容器,服务,替换命令,检查,启动docker,启动容器 |
4.更新docker-compose
“`sh
which docker-compose
mkdir -p /backup/docker-compose
mv `which docker-compose` /backup/docker-compose/
mv docker-compose-linux-x86_64 /usr/bin/docker-compose
chmod 755 /usr/bin/docker-compose
docker-compose -v
“`
5.更新docker
“`sh
1.备份关闭
rpm -ql docker-engine |grep bin |xargs mv -t /backup/docker_bak/
docker stop `docker ps | awk ‘NR>1{print $1}’`
systemctl stop docker
2.升级
tar -xf docker-20.10.24.tgz
chown root.root docker/*
mv docker/* /bin/
systemctl start docker
docker start redis5.0
rm -f /usr/local/bin/runc
“`
### 4 docker镜像仓库
#### 4.1 registry仓库
仓库选型与概述
应用场景:
未来docker官方的镜像无法直接满足我们的需求
我们企业内部也要定制很多镜像
而且这些镜像不想公开,都是私有的
| docker镜像仓库方案 | 应用场景与特点 |
| —————— | ———————————————————— |
| 镜像保存为压缩包 | 使用的时候,sl(save/load),仅适用于节点极少的情况,很不方便 |
| registry镜像仓库 | 使用方便,适用于小型网站集群,(镜像不多,环境不复杂), |
| harbor镜像仓库 | 企业级镜像仓库(docker,k8s)都可以用,图形化界面 |
| 共有云镜像服务 | 阿里云ACR在公有云上申请,个人,企业 |
\Typora\008-docker\image-20250107161239116.png)
“`sh
cat >>/etc/hosts<
lrwxrwxrwx 1 root root 0 Jan 17 11:26 ipc -> ‘ipc:[4026531839]’
lrwxrwxrwx 1 root root 0 Jan 13 23:04 mnt -> ‘mnt:[4026531841]’
lrwxrwxrwx 1 root root 0 Jan 13 23:07 net -> ‘net:[4026531840]’
lrwxrwxrwx 1 root root 0 Jan 13 23:07 pid -> ‘pid:[4026531836]’
lrwxrwxrwx 1 root root 0 Jan 17 11:26 pid_for_children -> ‘pid:[4026531836]’
lrwxrwxrwx 1 root root 0 Jan 17 11:26 time -> ‘time:[4026531834]’
lrwxrwxrwx 1 root root 0 Jan 17 11:26 time_for_children -> ‘time:[4026531834]’
lrwxrwxrwx 1 root root 0 Jan 17 11:26 user -> ‘user:[4026531837]’
lrwxrwxrwx 1 root root 0 Jan 17 11:26 uts -> ‘uts:[4026531838]’
“`
| namespace分类 | 说明 |
| ————- | ———————— |
| net | 网络资源隔离 |
| user | 用户id,信息隔离 |
| mnt | 磁盘资源隔离 |
| ipc | 进程通讯,资源格式 |
| pid | 进程id隔离 |
| uts | 系统资源,比如主机名隔离 |
2 cgroups
“`sh
cd /sys/fs/cgroup/cpu
mkdir yangsenlin-cgroup
cd yangsenlin-cgroup
#压力测试
stress -c 4 -v -t 20m
#进行限制
echo 10000 >cpu.cfs_quota_us
#添加pid到tasks中 关联任务
“`