DOCKER

## 1 容器架构

### 1.1 iaas paas saas

IAAS:基础设施即服务,IDC机房服务器出租,云厂商,云服务器

PAAS:平台即服务,服务运行环境是ok

SAAS软件即服务,服务已经准备好,直接使用产品

![image-20250107155347343](D:\Program Files (x86)\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系统内核 |

![image-20250107155409562](D:\Program Files (x86)\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

“`

![image-20250107155415764](D:\Program Files (x86)\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 ``` ![image-20250107155510526](D:\Program Files (x86)\Typora\008-docker\image-20250107155510526.png) ![image-20250107155525060](D:\Program Files (x86)\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 给容器指定名字,容器不通 ``` ![image-20250107155555168](D:\Program Files (x86)\Typora\008-docker\image-20250107155555168.png) ![image-20250107155604621](D:\Program Files (x86)\Typora\008-docker\image-20250107155604621.png) ### 1.9 docker C/S架构 cs client/server 客户端/服务器 | docker相关词汇 | 说明 | | ---------------- | -------------------- | | 镜像image | 存放各种环境或服务 | | 容器container | 进程,运行起来的镜像 | | 仓库(存放镜像) | 远程仓库,本地仓库 | ![image-20250107155538077](D:\Program Files (x86)\Typora\008-docker\image-20250107155538077.png) ![image-20250107155744481](D:\Program Files (x86)\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

![image-20250107155836817](D:\Program Files (x86)\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 | 每个连接互不影响 | 每个连接的所有操作与输出都是同步一致,退出容器后容器也退出了 |

![image-20250107155912446](D:\Program Files (x86)\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
“`

![image-20250107155928908](D:\Program Files (x86)\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
“`

![image-20250107155940437](D:\Program Files (x86)\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
5860fdd4c92e 4 seconds ago 140MB

“`

### 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

“`

用户访问的时候经历了什么![image-20250107155958261](D:\Program Files (x86)\Typora\008-docker\image-20250107155958261.png)

### 2.19 数据卷挂载

#### 1 概述

如果容器崩了,容器被误删除了,容器中的数据将丢失,接下来解决数据不丢,

如何解决数据持久化问题?数据卷(挂载),让数据永久保存在宿主机中

![image-20250107160046593](D:\Program Files (x86)\Typora\008-docker\image-20250107160046593.png)

![image-20250107160112593](D:\Program Files (x86)\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
“`

![image-20250107160136706](D:\Program Files (x86)\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、调试

“`

![image-20250107160213347](D:\Program Files (x86)\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

“`

![image-20250107160257687](D:\Program Files (x86)\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页面
“`

![image-20250107161203250](D:\Program Files (x86)\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页

“`

![image-20250107160333118](D:\Program Files (x86)\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在公有云上申请,个人,企业 |

![image-20250107161239116](D:\Program Files (x86)\Typora\008-docker\image-20250107161239116.png)

“`sh
cat >>/etc/hosts< ‘cgroup:[4026531835]’
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中 关联任务
“`

发表回复

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