1Docker 迁移存储目录
默认情况系统会将 Docker 容器存放在 /var/lib/docker 目录下
-
[问题起因] 今天通过监控系统,发现公司其中一台服务器的磁盘快慢,随即上去看了下,发现 /var/lib/docker 这个目录特别大。由上述原因,我们都知道,在 /var/lib/docker 中存储的都是相关于容器的存储,所以也不能随便的将其删除掉。
-
那就准备迁移 docker 的存储目录吧,或者对 /var 设备进行扩容来达到相同的目的。更多关于 dockerd 的详细参数,请点击查看 官方文档 地址。
-
但是需要注意的一点就是,尽量不要用软链, 因为一些 docker 容器编排系统不支持这样做,比如我们所熟知的 k8s 就在内。
ERROR:cannot create temporary directory!
$ du -h
$ sudo systemctl stop docker
$ sudo mv /var/lib/docker /data/
$ sudo ln -s /data/docker /var/lib/docker
$ sudo systemctl start docker
$ sudo vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --graph=/data/docker/
$ sudo vim /etc/docker/daemon.json
{
"live-restore": true,
"graph": [ "/data/docker/" ]
}
$ sudo mv /var/lib/docker /data/docker
$ sudo cp -arv /data/docker /data2/docker
Docker 迁移存储目录
2Docker 设备空间不足
Increase Docker container size from default 10GB on rhel7.
$ df -Th
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 40G 0G 100% /
tmpfs 7.8G 0 7.8G 0% /dev/shm
/dev/vdb1 493G 289G 179G 62% /mnt
$ docker info
Containers: 1
Images: 28
Storage Driver: devicemapper
Pool Name: docker-252:1-787932-pool
Pool Blocksize: 65.54 kB
Backing Filesystem: extfs
Data file: /dev/loop0
Metadata file: /dev/loop1
Data Space Used: 1.225 GB
Data Space Total: 107.4 GB
Data Space Available: 16.78 MB
Metadata Space Used: 2.073 MB
Metadata Space Total: 2.147 GB
$ du -d1 -h /var/lib/docker/containers | sort -h
$ cat /dev/null > /var/lib/docker/containers/container_id/container_log_name
2019-08-16 11:11:15,816 INFO spawned: 'app-demo' with pid 835
2019-08-16 11:11:16,268 INFO exited: app (exit status 1; not expected)
2019-08-16 11:11:17,270 INFO gave up: app entered FATAL state, too many start retries too quickly
cp: cannot create regular file '/etc/supervisor/conf.d/grpc-app-demo.conf': No space left on device
cp: cannot create regular file '/etc/supervisor/conf.d/grpc-app-demo.conf': No space left on device
cp: cannot create regular file '/etc/supervisor/conf.d/grpc-app-demo.conf': No space left on device
cp: cannot create regular file '/etc/supervisor/conf.d/grpc-app-demo.conf': No space left on device
{
"live-restore": true,
"storage-opt": [ "dm.basesize=20G" ]
}
$ sudo systemctl stop docker
$ sudo rm -rf /var/lib/docker
$ sudo vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd
and change it to:
ExecStart=/usr/bin/dockerd
$ sudo systemctl start docker
$ sudo systemctl daemon-reload
No space left on device
-
[解决方法] 因为 ext3 文件系统使用 inode table 存储 inode 信息,而 xfs 文件系统使用 B+ tree 来进行存储。考虑到性能问题,默认情况下这个 B+ tree 只会使用前 1TB 空间,当这 1TB 空间被写满后,就会导致无法写入 inode 信息,报磁盘空间不足的错误。我们可以在 mount 时,指定 inode64 即可将这个 B+ tree 使用的空间扩展到整个文件系统。
-
Docker+K8s+Jenkins 主流技术全解视频资料【干货免费分享】
# 查看系统的inode节点使用情况
$ sudo df -i
# 尝试重新挂载
$ sudo mount -o remount -o noatime,nodiratime,inode64,nobarrier /dev/vda1
-
[补充知识] 文件储存在硬盘上,硬盘的最小存储单位叫做 扇区 (Sector )。每个扇区储存 512 字节 (相当于 0.5KB )。操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个块 (block )。这种由多个扇区组成的块,是文件存取的最小单位。块的大小,最常见的是 4KB ,即连续八个 sector 组成一个 block 块。文件数据都储存在块中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做索引节点 (inode )。每一个文件都有对应的 inode ,里面包含了除了文件名以外的所有文件信息。
-
inode 也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是 inode 区 (inode table ),存放 inode 所包含的信息。每个 inode 节点的大小,一般是 128 字节或 256 字节。inode 节点的总数,在格式化时就给定,一般是每 1KB 或每 2KB 就设置一个 inode 节点。
$ stat check_port_live.sh
File: check_port_live.sh
Size: 225 Blocks: 8 IO Block: 4096 regular file
Device: 822h/2082d Inode: 99621663 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 1006/ escape) Gid: ( 1006/ escape)
Access: 2019-07-29 14:59:59.498076903 +0800
Modify: 2019-07-29 14:59:59.498076903 +0800
Change: 2019-07-29 23:20:27.834866649 +0800
Birth: -
$ df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
udev 16478355 801 16477554 1% /dev
tmpfs 16487639 2521 16485118 1% /run
/dev/sdc2 244162560 4788436 239374124 2% /
tmpfs 16487639 5 16487634 1% /dev/shm
3Docker 缺共享链接库
Docker 命令需要对 /tmp 目录下面有访问权限
# 提示错误信息
$ docker-compose --version
error while loading shared libraries: libz.so.1: failed to map segment from shared object: Operation not permitted
# 重新挂载
$ sudo mount /tmp -o remount,exec
4Docker 容器文件损坏
对 dockerd 的配置有可能会影响到系统稳定
b'devicemapper: Error running deviceCreate (CreateSnapDeviceRaw) dm_task_run failed'
$ sudo systemctl stop docker
$ sudo rm -rf /var/lib/docker/containers
$ sudo thin_check /var/lib/docker/devicemapper/devicemapper/metadata
$ sudo thin_check --clear-needs-check-flag /var/lib/docker/devicemapper/devicemapper/metadata
$ sudo systemctl start docker
5Docker 容器优雅重启
不停止服务器上面运行的容器,重启 dockerd 服务是多么好的一件事
$ sudo vim /etc/docker/daemon.yaml
{
"live-restore": true
}
$ sudo dockerd --live-restore
$ sudo systemctl reload docker
$ sudo systemctl restart docker
{
"registry-mirrors": ["https://vec0xydj.mirror.aliyuncs.com"],
"experimental": true,
"default-runtime": "nvidia",
"live-restore": true,
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
},
"default-address-pools": [
{
"scope": "local",
"base":"172.17.0.0/12",
"size":24
}
]
}
$ vim /etc/docker/daemon.json
{
"default-address-pools" : [
{
"base" : "172.240.0.0/16",
"size" : 24
}
]
}
6Docker 容器无法删除
找不到对应容器进程是最吓人的
# 删除容器
$ sudo docker rm -f f8e8c3..
Error response from daemon: Conflict, cannot remove the default name of the container
$ sudo rm -rf /var/lib/docker/containers/f8e8c3...65720
$ sudo systemctl restart docker.service
7Docker 容器中文异常
容器存在问题话,记得优先在官网查询
root@b18f56aa1e15:
C
C.UTF-8
POSIX
docker exec -it some-mysql env LANG=C.UTF-8 /bin/bash
docker run
-e MYSQL_ROOT_PASSWORD=my-secret-pw \
-d mysql:tag
8Docker 容器网络互通
了解 Docker 的四种网络模型
$ docker run -d -p 80:80 $PWD:/etc/nginx nginx
server {
...
location /api {
proxy_pass http:
}
...
}
$ ip addr show docker0
docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:d5:4c:f2:1e brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:d5ff:fe4c:f21e/64 scope link
valid_lft forever preferred_lft forever
server {
...
location /api {
proxy_pass http:
}
...
}
$ docker run -d -p 80:80 --network=host $PWD:/etc/nginx nginxx
9Docker 容器总线错误
总线错误看到的时候还是挺吓人了
# 总线报错
$ inv app.user_op --name=zhangsan
Bus error (core dumped)
root@18...35:/opt/app# df -TH
Filesystem Type Size Used Avail Use% Mounted on
overlay overlay 2.0T 221G 1.4T 3% /
tmpfs tmpfs 68M 0 68M 0% /dev
shm tmpfs 68M 41k 68M 1% /dev/shm
$ docker run -it --rm --shm-size=200m pytorch/pytorch:latest
$ shm_size: '2gb'
$ df -Th
Filesystem Type Size Used Avail Use% Mounted on
overlay overlay 1T 1T 0G 100% /
shm tmpfs 64M 24K 64M 1% /dev/shm
10Docker NFS 挂载报错
NFS 挂载之后容器程序使用异常为内核版本太低导致的
Traceback (most recent call last):
......
File "xxx/utils/storage.py", line 34, in xxx.utils.storage.LocalStorage.read_file
OSError: [Errno 9] Bad file descriptor
...
with open(self.mount(path), 'rb') as fileobj:
fcntl.flock(fileobj, fcntl.LOCK_EX)
data = fileobj.read()
return data
...
$ In Linux kernels up to 2.6.11, flock() does not lock files over NFS (i.e.,
the scope of locks was limited to the local system). [...] Since Linux 2.6.12,
NFS clients support flock() locks by emulating them as byte-range locks on the entire file.
11Docker 使用默认网段
启动的容器网络无法相互通信,很是奇怪!
Docker 默认使用网段
$ cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://vec0xydj.mirror.aliyuncs.com"],
"default-address-pools":[{"base":"172.17.0.0/12", "size":24}],
"experimental": true,
"default-runtime": "nvidia",
"live-restore": true,
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}
12Docker 服务启动串台
使用 docker-compose 命令各自启动两组服务,发现服务会串台!
A: /data1/app/docker-compose.yml
B: /data2/app/docker-compose.yml
Docker 服务启动串台
A: /data/app1/docker-compose.yml
B: /data/app2/docker-compose.yml
A: /data1/app-old/docker-compose.yml
B: /data2/app-new/docker-compose.yml
# 指定项目项目名称
$ docker-compose -f ./docker-compose.yml -p app1 up -d
13Docker 命令调用报错
在编写脚本的时候常常会执行 docker 相关的命令,但是需要注意使用细节!
Docker 命令调用报错
docker exec -it <container_name> psql -Upostgres ......
1 |
-i /-interactive |
即使没有附加也保持 STDIN 打开;如果你需要执行命令则需要开启这个选项 |
2 |
-t /–tty |
分配一个伪终端进行执行;一个连接用户的终端与容器 stdin 和 stdout 的桥梁 |
编号 |
参数 |
解释说明 |
Docker 命令调用报错
14Docker 定时任务异常
在 Crontab 定时任务中也存在 Docker 命令执行异常的情况!
0 */6 * * * \
docker exec -it <container_name> sh -c \
'exec mysqldump --all-databases -uroot -ppassword ......'
1 |
-i /-interactive |
即使没有附加也保持 STDIN 打开;如果你需要执行命令则需要开启这个选项 |
2 |
-t /–tty |
分配一个伪终端进行执行;一个连接用户的终端与容器 stdin 和 stdout 的桥梁 |
编号 |
参数 |
解释说明 |
15Docker 变量使用引号
compose 里边环境变量带不带引号的问题!
-
[问题起因] 使用过 compose 的朋友可能都遇到过,在编写启服务启动配置文件的时候,添加环境变量时到底是使用单引号、双引号还是不使用引号的问题?时间长了,我们可能会将三者混用,认为其效果是一样的。但是后来,发现的坑越来越多,才发现其越来越隐晦。
-
反正我是遇到过很多问题,都是因为添加引号导致的服务启动异常的,后来得出的结论就是一律不使引号。裸奔,体验前所未有的爽快!直到现在看到了 Github 中对应的 issus 之后,才终于破案了。
TEST_VAR="test"
TEST_VAR=test
docker run -it --rm -e TEST_VAR="test" test:latest
-
[解决方法] 得到的结论就是,因为 Compose 解析 yaml 配置文件,发现引号也进行了解释包装。这就导致原本的 TEST_VAR="test" 被解析成了 'TEST_VAR="test"' ,所以我们在引用的时候就无法获取到对应的值。现在解决方法就是,不管是我们直接在配置文件添加环境变量或者使用 env_file 配置文件,能不使用引号就不适用引号。
-
需要注意的是环境变量配置的是日志格式的话 (2022-01-01 ),如果使用的是 Python 的 yaml.load 模块的话,会被当做是 date 类型的,这是如果希望保持原样信息的话,可以使用 ' /" 引起来将其变成字符串格式的。
16Docker 删除镜像报错
无法删除镜像,归根到底还是有地方用到了!
$ docker rmi 3ccxxxx2e862
Error response from daemon: conflict: unable to delete 3ccxxxx2e862 (cannot be forced) - image has dependent child images
$ dcoker rmi -f 3ccxxxx2e862
Error response from daemon: conflict: unable to delete 3ccxxxx2e862 (cannot be forced) - image has dependent child images
$ docker image inspect --format='{{.RepoTags}} {{.Id}} {{.Parent}}' $(docker image ls -q --filter since=<image_id>)
$ docker rmi -f c565xxxxc87f
$ docker rmi $(docker images --filter "dangling=true" -q --no-trunc)
17Docker 普通用户切换
切换 Docker 启动用户的话,还是需要注意下权限问题的!
nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
2020/11/12 15:25:47 [emerg] 23
user www-data;
worker_processes 1;
error_log /data/logs/master_error.log warn;
pid /dev/shm/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
gzip on;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
client_body_temp_path /tmp/client_body;
fastcgi_temp_path /tmp/fastcgi_temp;
proxy_temp_path /tmp/proxy_temp;
scgi_temp_path /tmp/scgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
include /etc/nginx/conf.d/*.conf;
}
18Docker 绑定到 IPv6 上
Docker 服务在启动的时候,将地址绑定到 IPv6 地址上面了,提示报错信息!
docker run -p 80:80 nginx:alpine succeeds. Previously, this was failing with Error \
starting userland proxy: listen tcp6 [::]:80: socket: address family not supported by protocol.
$ cat /etc/sysctl.conf | grep ipv6
net.ipv6.conf.all.disable_ipv6=1
version: "3"
services:
app:
restart: on-failure
container_name: app_web
image: app:latest
ports:
- "0.0.0.0:80:80/tcp"
volumes:
- "./app_web:/data"
networks:
- app_network
networks:
app_network:
$ vim /etc/docker/daemon.json
{
"ipv6": false,
"fixed-cidr-v6": "2001:db8:1::/64"
}
$ systemctl reload docker
echo '1' > /proc/sys/net/ipv6/conf/lo/disable_ipv6
echo '1' > /proc/sys/net/ipv6/conf/lo/disable_ipv6
echo '1' > /proc/sys/net/ipv6/conf/all/disable_ipv6
echo '1' > /proc/sys/net/ipv6/conf/default/disable_ipv6
$ /etc/init.d/networking restart
ip addr show | grep net6
1919. Docker 容器启动超时
Docker 服务在启动的时候,提示超时,被直接终止了!
$ docker-compose up -d
ERROR: for xxx UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=70)
ERROR: An HTTP request took too long to complete. Retry with
If you encounter this issue regularly because of slow network conditions, consider setting COMPOSE_HTTP_TIMEOUT to a higher value (current value: 60).
$ sudo vim /etc/profile
export COMPOSE_HTTP_TIMEOUT=500
export DOCKER_CLIENT_TIMEOUT=500
$ sudo iotop
4269 be/4 escape 15.64 K/s 0.00 B/s 0.00 % 98.36 % rg --files --hidden
4270 be/4 escape 28.15 K/s 0.00 B/s 0.00 % 97.46 % rg --files --hidden
4272 be/4 escape 31.27 K/s 0.00 B/s 0.00 % 97.39 % rg --files --hidden
4276 be/4 escape 34.40 K/s 0.00 B/s 0.00 % 96.98 % rg --files --hidden
20Docker 端口网络限制
如果发现服务都一切正常,但是无法无法访问的话,则多为网络问题!
# 部署服务架构
nginx(80) -> web1(8080)
-> web2(8081)
# 报错信息如下所示
nginx connect() failed (113: No route to host) while connecting to upstream
$ sudo firewall-cmd --permanent --zone=public --list-ports
$ sudo firewall-cmd --permanent --zone=public --add-port=8080/tcp
$ sudo firewall-cmd --permanent --zone=public --add-port=8081/tcp
firewall-cmd --reload
# 关闭防火墙
$ sudo systemctl stop firewalld.service
# 禁用自启动
$ sudo systemctl disable firewalld.service
21Docker 无法获取镜像
新初始化的机器,无法获取私有仓库的镜像文件!
# 登录私有仓库
$ echo '123456' | docker login -u escape --password-stdin docker.escapelife.site
# 异常信息提示
$ sudo docker pull docker.escapelife.site/app:0.10
Error response from daemon: manifest for docker.escapelife.site/app:0.10 not found: manifest unknown: manifest unknown
$ cat .docker/config.json
{
"auths": {
"docker.escapelife.site": {
"auth": "d00u11Fu22B3355VG2xasE12w=="
}
}
}
22Docker 使容器不退出
如何使使用 docker-compose 启动的容器服务 hang 住而不退出
➜ docker ps -a
4e6xxx9a4 app:latest "/xxx/…" 26 seconds ago Restarting (1) 2 seconds ago
docker run -it --rm --entrypoint=/bin/bash xxx/app:latest
tty: true
command: tail -f /dev/null
tty: true
entrypoint: tail -f /dev/null
version: "3"
services:
app:
image: ubuntu:latest
tty: true
entrypoint: /usr/bin/tail
command: "-f /dev/null"
apiVersion: v1
kind: Pod
metadata:
name: ubuntu
spec:
containers:
- name: ubuntu
image: ubuntu:latest
command: ["/bin/bash", "-c", "--"]
args: ["while true; do sleep 30; done;"]
23Docker 不使用默认网段
有些情况,内部规划的网段和可能和 Dockerd 默认的网段有冲突,导致异常出现!
➜ nc -v 172.16.100.12 8000
nc: connect to 172.16.100.12 port 8000 (tcp) failed: Connection refused
$ python -m SimpleHTTPServer 8000
Serving HTTP on 0.0.0.0 port 8000 ...
➜ nc -v 172.16.100.12 8000
Connection to 172.16.100.12 8000 port [tcp/*] succeeded!
$ sudo cat /etc/docker/daemon.json
{
"default-address-pools":[{"base":"192.168.100.0/20","size":24}]
}
$ sudo systemctl restart docker
$ ip a
$ docker network inspect app | grep Subnet
Error response from daemon: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network
$ sudo cat /etc/docker/daemon.json
{
"default-address-pools":[{"base":"10.210.200.0/24","size":28}]
}
Docker 不使用默认网段
24Docker 添加私有仓库
有些情况,我们服务器上面需要使用内部私有的容器镜像地址!
$ docker pull 192.168.31.191:5000/nginx:latest
x509: certificate signed by unknown authority
$ sudo cat /etc/docker/daemon.json
{
"insecure-registries": ["192.168.31.191:5000"]
}
$ sudo systemctl restart docker
$ docker login 私库地址 -u 用户名 -p 密码
(责任编辑:IT) |