我在B站学云原生之Docker容器安装运行所遇异常问题解决集合
# 18.我在B站学云原生之Docker容器安装运行所遇异常问题解决集合
[https://www.bilibili.com/read/cv15670482](https://www.bilibili.com/read/cv15670482)
Docker容器技术入门实践系列历史已发布文章(点击即可进入):
[1.我在B站学云原生之Docker容器技术基础知识介绍](https://www.bilibili.com/read/cv15180540)
[2.我在B站学云原生之Docker容器环境安装实践](https://www.bilibili.com/read/cv15181036)
[3.我在B站学云原生之Docker容器三大核心概念介绍](https://www.bilibili.com/read/cv15181760)
[4.我在B站学云原生之Docker容器数据持久化介绍与实践](https://www.bilibili.com/read/cv15182308)
[5.我在B站学云原生之Docker容器网络介绍与实践](https://www.bilibili.com/read/cv15185166)
[6.我在B站学云原生之Docker容器Registry私有镜像仓库搭建实践](https://www.bilibili.com/read/cv15219863)
[7.我在B站学云原生之Docker容器Dockerfile镜像构建浅析与实践](https://www.bilibili.com/read/cv15220707)
[8.我在B站学云原生之Docker容器镜像构建最佳实践浅析](https://www.bilibili.com/read/cv15220861)
[9.我在B站学云原生之Docker容器优化镜像体积缩小技巧实践](https://www.bilibili.com/read/cv15226873)
[10.我在B站学云原生之Docker容器技术进阶知识介绍](https://www.bilibili.com/read/cv15227279)
[11.我在B站学云原生之Docker容器编排工具docker-compose安装使用实践](https://www.bilibili.com/read/cv15227639)
[12.我在B站学云原生之Docker容器底层原理浅析](https://www.bilibili.com/read/cv15228563)
[13.我在B站学云原生之Docker容器镜像构建存储原理浅析与实践](https://www.bilibili.com/read/cv15229214)
[14.我在B站学云原生之Docker容器Registry私有镜像仓库安全配置与GC回收实践](https://www.bilibili.com/read/cv15237911)
[15.我在B站学云原生之Docker镜像安全最佳实践](https://www.bilibili.com/read/cv15553799)
[16.我在B站学云原生之Docker容器安全最佳实践](https://www.bilibili.com/read/cv15554240)
[17.我在B站学云原生之Docker容器相关辅助工具使用介绍](https://www.bilibili.com/read/cv15669979)
[18.我在B站学云原生之Docker容器安装运行所遇异常问题解决集合](https://www.bilibili.com/read/cv15670482)
----------------------
本章目录
0x00 Docker 目录与路径
0x01 常规基础配置
1.如何进行 Docker 默认存储位置修改?
2.如果进行容器日志文件的分割?
3.如何配置Docker Deamon能被Docker Client远程链接?
4.修改正在运行的容器其映射端口?
5.本地的镜像文件都存放在哪里?
6.如何给容器指定一个固定 IP 地址,而不是每次重启容器 IP 地址都会变?_
7.修改已创建的镜像或者正在运行的容器中存储挂载的路径?
8.如何进入 Docker 容器的网络命名空间?
9.如何重置 Docker 本地数据?
0x02 入坑出坑
0x03 面试问题
面试问答1.仓库(Repository)、注册服务器(Registry)、注册索引(Index) 有何关系?
面试问答2.如何临时退出一个正在交互的容器的终端,而不终止它?
面试问答3.Dockerfile中 ADD 与 COPY 的区别?
面试问答4.Dockerfile中 CMD 与 ENTRYPOINT 的区别?
0x00 Docker 目录与路径
CentOS7:默认的Docker安装目录以及配置文件
# Systemctl 启动项参数
/etc/systemd/system/docker.service
/usr/lib/systemd/system/docker.service
# Docker 元数据目录
/var/lib/docker
# Docker Deamon启动项
/etc/sysconfig/docker
# Docker daemon.json 参数
/etc/docker/daemon.json
/root/.docker/config.json
Ubuntu:snap安装的Docker
# 全局配置
/var/snap/docker
/var/snap/docker/current/ # docker 启动配置
config/ etc/ run/
# 用户配置
/root/snap/docker
0x01 常规基础配置
.Docker日志设置定期清理
设置容器为3个日志文件容,分别是id+.json、id+1.json、id+2.json,但是此时只对新建的容器有效;
cat > /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": [
"https://kfwkfulq.mirror.aliyuncs.com",
"https://2lqq34jg.mirror.aliyuncs.com",
"https://pee6w651.mirror.aliyuncs.com",
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com"
],
"dns": ["114.114.114.114","8.8.4.4"],
"log-driver":"json-file",
"log-opts":{ "max-size" :"100m","max-file":"1"},
"ipv6": true,
"fixed-cidr-v6": "2001:db8:1::/64"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2.清理已存在的容器日志(全部容器)
#容器日志一般存放在/var/lib/docker下面
ls -lh $(find /var/lib/docker/containers/ -name *-json.log)
#方法1:
find /var/lib/docker/containers/ -name *-json.log -exec truncate -s 0 {} \;
#方法2:(已经停止的容器)
find /var/lib/docker/containers/ -name *-json.log -exec cat /dev/null > {} \;
如果docker容器正在运行,那么使用rm -rf 方式删除日志后,通过df -h会发现磁盘空间并没有释放;
原因:在Linux或者Unix系统中,通过rm或者文件管理器删除文件将会从文件系统的目录结构上解除链接(unlink).然而如果文件是被打开的(有一个进程正在使用),那么进程将仍然可以读取该文件,磁盘空间也一直被占用。
1.如何进行 Docker 默认存储位置修改?
描述:默认情况下Docker的存放位置为 /var/lib/docker , 具体的位置可以通过sudo docker info | grep "Docker Root Dir"查看。
方式1:通过软连接来实现,启动Docker时发现存储目录依旧是/var/lib/docker但是实际上是存储在数据盘的(容量变化)。
systemctl stop docker
#方式1.软连接
mv /var/lib/docker /disk/docker
ln -s /disk/docker /var/lib/docker #目标 软连接
#方式2.打包docker目录
sudo tar -czvf /usr/docker.tar.gz docker/
cd /disk/ && sudo tar -xzvf docker.tar.gz
方式2:改镜像和容器的存放路径即我们需要修改配置文件指定启动参数即可,指定镜像和容器存放路径的参数是--graph=/var/lib/docker,由于在docker.service中加载下面到环境变量中,最后一张图即可明了(可将下面几种方式看作一种)
#(1)注意:发行版本的异同,修改后重启即可
Ubuntu: /etc/default/docker
OPTIONS='--graph="/disk/docker" -H fd://' # 或者DOCKER_OPTS="-g /disk/docker"
CentOS6: /etc/sysconfig/docker
OPTIONS='--graph="/disk/docker" --selinux-enabled -H fd://'
#(2) 配置文件位置(不推荐此种方式)
#/usr/lib/docker-storage-setup/docker-storage-setup或者/etc/sysconfig/docker-storage-setup、/etc/sysconfig/docker-storage
DOCKER_STORAGE_OPTIONS=--graph="要保存的路径"
#限制性默认值,例如100GB最大存储空间。
DATA_SIZE=800GB #更改docker默认存储大小
#实际上都是依托于下述文件的加载我们可以直接在ExecStart启动中指定docker挂的存储位置所以看作一种修改方式);
CentOS7: /usr/lib/systemd/system/docker.service
EnviromentFile=-/etc/sysconfig/docker
Environment=GRAPH=/disk/docker
ExecStart=/usr/bin/dockerd --graph=/disk/docker $GRAPH $OPTIONS
systemctl daemon-reload # reload配置文件
systemctl restart docker.service # 重启docker
方式4:如果docker是1.12或以上的版本可以修改(或新建)/etc/docker/daemon.json文件
该方式的优点修改后会立即生效,不需重启docker服务。
vim /etc/docker/daemon.json
{"registry-mirrors": ["http://7e61f7f9.m.daocloud.io"],"graph": "/disk/docker"}
2.如果进行容器日志文件的分割?
描述:除了docker image 时间长了会占用大量磁盘空间外,容器在运行时大量写日志也是个很头疼的问题,而且在没有任何监控预警的情况下业务随时都会宕掉(至少我遇到过1次)。
默认情况下(JSON File logging drive ),Docker捕获所有容器的标准输出(和标准错误),并使用JSON格式将其写入文件中,对于应用的标准输出(stdout)日志,Docker Daemon 在运行这个容器时就会创建一个协程(goroutine),负责标准输出日志。
由于此 goroutine 绑定了整个容器内所有进程的标准输出文件描述符,因此容器内应用的所有标准输出日志都会被 goroutine 接收并写入与此容器—对应的日志文件中,即日志文件位于/var/lib/docker/containers/<container_id>/文件名为-json.log
Docker 则通过 docker logs 命令向用户提供日志接口,其实现原理的本质均基于与容器一一对应的-json.log,(kubectl logs类似)
针对日志文件过大的几种解决办法:
堵: 限定一个容器最多使用多少磁盘空间;
#docker的storage-driver是overlay2时,限制单个容器可占用的磁盘空间
- 1.xfs,linux 文件系统 CentOS 7开始,预设的文件系统由原来的EXT4变成了XFS文件系统
- 2.pquot(project quotas )SystemXFS支持按用户、组和项目设置磁盘配额。项目磁盘配额允许您限制单个目录层次结构上的磁盘空间数量。
# mount 时 指定文件系统类型,使用-o enbale project quotas
mount –o prjquota /dev/xvdb1 /xfs
# 限定 project=test 的 /data 目录 soft limit=5M hard limit=6M
xfs_quota –x –c 'limit –p bsoft=5m bhard=6m test' /data
疏: 以特定用户运行项目,该容器内用户只可以访问特定的文件夹,比如/logs,然后将容器/logs 映射到物理机上,定时清理;
监控: 时监控磁盘,异常时报警;执行docker system df -v可以列出每个容器占用的 磁盘空间,当期大小超过一定阈值时,可以根据container id(想办法将container id 与应用信息关联起来)将其删除
(1)Images space usage:
REPOSITORY TAG IMAGE ID CREATED SIZE SHARED SIZE UNIQUE SIZE CONTAINERS
onlyoffice/documentserver latest d06214a03e27 2 months ago 2.145GB 0B 2.145GB 1
(2)Containers space usage:
CONTAINER ID IMAGE COMMAND LOCAL VOLUMES SIZE CREATED STATUS NAMES
d415211e52da onlyoffice/documentserver "/bin/sh -c /app/ds/…" 6 986MB 4 weeks ago Up 3 days onlyoffice
(4)Local Volumes space usage:
VOLUME NAME LINKS SIZE
a4974599165f539b98fd57fc53ccc073a7e8cdf4cd36cbc5e349fb8d4f6a1325 0 2.51MB
(5)Build cache usage: 0B
CACHE ID CACHE TYPE SIZE CREATED LAST USED USAGE SHARED
日志由日志采集工具收集,不在磁盘上停留;
实操解决:
#示例1.清空停止的容器以及卷包括日志/容器/网络/镜像(以释放空间-尽量在缺订需要的容器)
docker system prune -af
# Deleted Containers:
# 9c8a4f60ad62cee63c7d5b48041e29363ee4f839aedb2cec9a76df3e6ccda2e8
# 2d5cca572c06e11a6a2005cd46d154b71bad151610ce074424a32850aedb2b39
# 8c78c868d29285afeb00eb617d0a8e3280b6da2f69bf8dd42e04a8e334d3ae22
# Deleted Networks:
# blog_default
# Deleted Images:
# untagged: snipe/snipe-it:latest
# untagged: snipe/snipe-it@sha256:7a61e8a407490b9e99c758a18ba814c10fe55f1465e036bfd1ee5445537c7661
# Total reclaimed space: 1.096GB
#示例2./etc/docker/daemon.json 经创建了的容器该选项的修改【重启daemon】是无法生效的,只对新建立的容器有效;
"log-driver":"json-file",
"log-opts": {"max-size":"500m", "max-file":"3"}
docker inspect -f '{{.HostConfig.LogConfig}}' test1
# {json-file map[max-file:10 max-size:2m]}
more /var/lib/docker/containers/25d2d645bfc9e6530039d6aac890f69dd9af33f8f966adc2d7287b74964678e3/25d2d645bfc9e6530039d6aac890f69dd9af33f8f966adc2d7287b74964678e3-json.log
# {"log":"Mem: 3164836K used, 696576K free, 45448K shrd, 2104K buff, 1633504K cached\n","stream":"stdout","time":"2020-06-18T03:34:33.738111441Z"}
# {"log":"CPU: 0% usr 0% sys 0% nic 100% idle 0% io 0% irq 0% sirq\n","stream":"stdout","time":"2020-06-18T03:34:33.73833528Z"}
# {"log":"Load average: 0.16 0.20 0.19 1/639 5\n","stream":"stdout","time":"2020-06-18T03:34:33.738342617Z"}
#示例3.将每个容器可以使用的磁盘空间设置为1G:
{
"data-root": "/data/docker",
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true",
"overlay2.size=1G"
],
}
# 示例4.清理日志文件
# 通过rm -rf或者文件管理器删除文件,将会从文件系统的目录结构上解除链接(unlink)前提是容器是停止的状态,否则如果该文件被进程占用,磁盘空间也一直被占用。
cat /dev/null >/var/lib/docker/containers/<container_id>/containerid-json.log
3.如何配置Docker Deamon能被Docker Client远程链接?
答: 我们需要在docker.service配置文件中进行更改dockerd的启动参数中添加-H tcp://0.0.0.0:2375
# 修改启动参数
nano /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375
# 重载守护进程与重启docker
systemctl daemon-reload
systemctl restart docker
# 查看监听情况
netstat -tlnp
# Active Internet connections (only servers)
# Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
# tcp6 0 0 :::2375 :::* LISTEN 11389/dockerd
# 简单验证远程访问
curl http://127.0.0.1:2375/containers/json | jq
[
{
"Id": "25d2d645bfc9e6530039d6aac890f69dd9af33f8f966adc2d7287b74964678e3",
"Names": [
"/test1"
],
"Image": "test1",
"ImageID": "sha256:5ec0e2b89f7aadb6178c17b3db73aba2e209f9556a436562de7f32b077b776bd",
"Command": "top -b -d 2",
"Created": 1592451272,
"Ports": [],
"Labels": {
"Author": "WeiyiGeek",
"Description": "Test Dockerfile"
},
"State": "running",
"Status": "Up 35 minutes",
"HostConfig": {
"NetworkMode": "default"
},
"NetworkSettings": {
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "257f6a8500710d76efba6a1c9be8c0f10b4308afb481baf1e9ba77cf98f596bd",
"EndpointID": "ac4518815359da7b8182167dfeeec728c0ea51accd1736719005f1596797e944",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
},
"Mounts": []
}
]
至此本节完毕,敬请期待下一小节内容。
Docker容器技术入门实践系列历史已发布文章(点击即可进入):
[1.我在B站学云原生之Docker容器技术基础知识介绍](https://www.bilibili.com/read/cv15180540)
[2.我在B站学云原生之Docker容器环境安装实践](https://www.bilibili.com/read/cv15181036)
[3.我在B站学云原生之Docker容器三大核心概念介绍](https://www.bilibili.com/read/cv15181760)
[4.我在B站学云原生之Docker容器数据持久化介绍与实践](https://www.bilibili.com/read/cv15182308)
[5.我在B站学云原生之Docker容器网络介绍与实践](https://www.bilibili.com/read/cv15185166)
[6.我在B站学云原生之Docker容器Registry私有镜像仓库搭建实践](https://www.bilibili.com/read/cv15219863)
[7.我在B站学云原生之Docker容器Dockerfile镜像构建浅析与实践](https://www.bilibili.com/read/cv15220707)
[8.我在B站学云原生之Docker容器镜像构建最佳实践浅析](https://www.bilibili.com/read/cv15220861)
[9.我在B站学云原生之Docker容器优化镜像体积缩小技巧实践](https://www.bilibili.com/read/cv15226873)
[10.我在B站学云原生之Docker容器技术进阶知识介绍](https://www.bilibili.com/read/cv15227279)
[11.我在B站学云原生之Docker容器编排工具docker-compose安装使用实践](https://www.bilibili.com/read/cv15227639)
[12.我在B站学云原生之Docker容器底层原理浅析](https://www.bilibili.com/read/cv15228563)
[13.我在B站学云原生之Docker容器镜像构建存储原理浅析与实践](https://www.bilibili.com/read/cv15229214)
[14.我在B站学云原生之Docker容器Registry私有镜像仓库安全配置与GC回收实践](https://www.bilibili.com/read/cv15237911)
[15.我在B站学云原生之Docker镜像安全最佳实践](https://www.bilibili.com/read/cv15553799)
[16.我在B站学云原生之Docker容器安全最佳实践](https://www.bilibili.com/read/cv15554240)
[17.我在B站学云原生之Docker容器相关辅助工具使用介绍](https://www.bilibili.com/read/cv15669979)
[18.我在B站学云原生之Docker容器安装运行所遇异常问题解决集合](https://www.bilibili.com/read/cv15670482)