docker简介

docker

Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离

Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口

Docker 将应用程序与该程序的依赖,打包在一个文件(image)里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样.

容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例

容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版)

docker 用途

  1. 简化环境搭建
  2. 简化运维工作量
  3. 微服务利器

docker 安装

uname -r 内核版本大于 3.10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 先进行卸载
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine \
docker-ce \
docker-*

systemctl disable docker
rm -rf /etc/systemd/system/docker.service.d

rm -rf /var/lib/docker

rm -rf /var/run/docker



curl https://get.docker.com > /tmp/install.sh
chmod +x /tmp/install.sh
/tmp/install.sh

# curl -sSL https://get.daocloud.io/docker | sh # 国内可以这样安装
sudo usermod -aG docker $USER # 避免每次都输入 sudo,将用户加入 docker 用户组
newgrp docker
service docker restart
systemctl enable docker # 开机自启
docker info # 获取docker信息
docker --help # docker 帮助文档
service docker status

快速确认

docker version

换源

cd /etc/docker 目录下找到在daemon.json文件(没有就新建),将下面内容写入(阿里云)

1
2
3
4
5
6
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://1hdirfy9.mirror.aliyuncs.com"],
"exec-opts":["native.cgroupdriver=systemd"]
}
EOF

重启daemon

systemctl daemon-reload

重启docker服务

systemctl restart docker

第一个镜像

1
2
3
docker pull [Registry]/[Respository]/[images]:[tag]  # 获取镜像操作
docker pull debian # 获取官方仓库下的 debian:latest
docker run debian echo "hello world"
  1. docker run : 启动容器
  2. debian : 使用的镜像名称 (本地如果没有镜像,就在docker hub 进行搜素,并下载最新版)
  3. echo “hello world” : 执行的命令
1
2
docker run -i -t debian /bin/bash   
docker run -i -t debian # 也可以不加 /bin/bash
  1. -i -t : 附有一个 tty 的交互会话 -i 支持stdin , -t 终端或伪终端
  2. /bin/bash : 获得一个 bash shell
  3. 退出 shell, 容器就会停止, Ctrl+ P + Q 退出而不停止

容器生命周期

docker容器生命周期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
docker run --name weilai -h docker -it debian /bin/bash  # -h 指定hostname --name 指定docker name
docker inspect weilai # 获取 weilai 容器的更多信息
docker stats weilai # 查看容器 weilai 资源使用状态
docker run --name nginx -m 1024M --cpus=0.2 -d nginx # 启动限制资源容器
doker diff weilai # 查看 weilai 文件的更改
docker logs weilai # weilai 容器日志记录
docker ps # 正在运行的 docker 容器
docker ps -a # 列出所有容器
docker ps -n 2 # 显示最近创建的2个容器
docker ps -f status=exited # 查看停止的容器
docker start weilai # 启动已有容器 docker run 是启动一个新的实例
docker attach weilai # 切换到运行交互式容器,阻塞式 一般推荐使用 exec
docker exec -it weilai # 切换到运行交互式容器,阻塞式 一般推荐使用 exec
docker cp weilai:/tmp /home # 拷贝容器下的/tmp文件夹 到宿主机下的 /home 目录下
docker cp /home/test.sh weilai:/tmp/weuilai.sh # 宿主机下的 /home 目录的 tets.sh 到容器下的/tmp文件夹 并改名为weilai.sh
docker exec weilai ls -l # 进入容器 执行 ls -l 并回到宿主机,显示结果
docker start weilai # 查看容器进程
docker stop weilai # 停止容器
docker update --restart=always weilai # 已经启动的容器自动重启
docker kill weilai # 强制停止(不建议)
docker rm weilai # 删除容器
docker rmi -f debian # 删除 debian -f 强制删除

docker run :创建和启动一个新的容器实例,操作对象是镜像,选项较多,如果你要创建和启动一个容器,只能用run;
docker exec: 在已运行的容器中,执行命令,操作对象是容器,如果你要进入已运行的容器,并且执行命令,用exec;
docker attach: 同样操作的是已运行的容器,可以将本机标准输入(键盘输入)输到容器中,也可以将容器的输出显示在本机的屏幕上,如果你想查看容器运行过程中产生的标准输入输出,用attach;

docker 镜像

docker images : 列出本机所有镜像

1
2
3
docker images -qa # -a 显示所有镜像(含中间层) -q 只显示镜像id
docker images --digests # 显示镜像的摘要信息
docker images --no-trunc # 显示完整的镜像信息

docker search redis : 搜索 redis 镜像
docker pull redis:latest : 拉取 redis:latest 镜像 (TAG 默认为 latest

删除多个镜像:docker rmi -f 镜像名称1:[TAG] 镜像名称2:[TAG]
中间空格隔开

删除全部镜像:docker rmi -f $(docker images -qa)

同样的

强制删除 docker rm -f 容器ID或name

删除多个容器
docker rm -f 容器ID1 容器ID2

删除所有容器

docker rm -f $(docker ps -qa)

容器目录挂载

创建容器的时候,将宿主机的目录与容器内的目录进行映射,实现宿主机和容器目录的双向数据自动同步;

相比前面的 cp 更加简单方便

语法

docker run -it -v /宿主机目录:/容器目录 镜像名

多目录挂载
docker run -it -v /宿主机目录:/容器目录 -v /宿主机目录2:/容器目录2 镜像名

挂载目录制度
docker run -it -v /宿主机目录:/容器目录:ro 镜像名

例如安装redis

1
2
$ mkdir -p /opt/data/redis
$ docker run -p 6379:6379 --name myredis -v /opt/data/redis/redis.conf:/etc/redis/redis.conf -v /opt/data/redis:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes --requirepass "passwd"

安装 mysql

1
docker run -d -p 3306:3306 --name mysql -v /opt/mysql/data:/var/lib/mysql -v /etc/localtime:/etc/localtime -e MYSQL_ROOT_PASSWORD=password mysql:5.7.40

注意
同步多级目录,可能会出现权限不足的提示;
这是因为selinux把权限禁掉了,我们需要添加 –privileged=true 来解决挂载的目录没有权限的问题;

docker 网络模式

docker 默认使用的是 bridge桥接网络模式

1
2
3
4
5
# docker network ls
NETWORK ID NAME DRIVER SCOPE
d2a8ca970a9c bridge bridge local
e379fa1c8774 host host local
3dfff078ede1 none null local
  1. 自定义网络模式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # docker network create --subnet=172.20.0.0/16 extnetwork
    a2c75e5e49ea2bf16380befd73ac19be54e271f4ad1e39549c47290d1b9fa7f3
    # ifconfig
    br-a2c75e5e49ea: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
    inet 172.20.0.1 netmask 255.255.0.0 broadcast 172.20.255.255
    ether 02:42:43:82:72:6e txqueuelen 0 (Ethernet)
    RX packets 0 bytes 0 (0.0 B)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 0 bytes 0 (0.0 B)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

    docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
    inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
    inet6 fe80::42:d5ff:fe34:51d4 prefixlen 64 scopeid 0x20<link>
    ether 02:42:d5:34:51:d4 txqueuelen 0 (Ethernet)
    RX packets 10771 bytes 601704 (587.6 KiB)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 10230 bytes 51101359 (48.7 MiB)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
    ...
    ...
    ...
  2. 创建容器并指定ip --net extnetwork --ip 172.20.0.2

extnetwork 上文指定
172.20.0.1 是网关,所以从2 分配

1
2
3
4
5
6
7
8
9
10
# docker run -p 8066:8066 -it --net extnetwork --ip 172.20.0.2 debian
root@b4246dddf9f5:/#ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
17: eth0@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:14:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.20.0.2/16 brd 172.20.255.255 scope global eth0
valid_lft forever preferred_lft forever

也可以用 docker inspect 容器id 查看信息

1
2
3
4
5
6
7
8
9
10
# docker inspect b4246dddf9f5
....
"NetworkID": "a2c75e5e49ea2bf16380befd73ac19be54e271f4ad1e39549c47290d1b9fa7f3",
"EndpointID": "efa3cd2ed24010ba37bcf7183fba6cce7bc89f9327375f1148db1a6888005d6f",
"Gateway": "172.20.0.1",
"IPAddress": "172.20.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",

....
  1. 删除网络
    docker network rm extnetwork

  2. 限制cpu 内存等

容器的监控原理其实就是定时读取 Linux 主机上相关的文件并展示给用户。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
root@test:~# docker run --name nginx -m 200M --cpus=0.2 -d nginx
WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.
1c8999af3a3654cb9e053795198f0d1c377fc1080173213a6fdd2179123bcf00
root@test:~# ls -l /sys/fs/cgroup/memory/docker
total 0
drwxr-xr-x 2 root root 0 Oct 23 16:31 1c8999af3a3654cb9e053795198f0d1c377fc1080173213a6fdd2179123bcf00
-rw-r--r-- 1 root root 0 Oct 23 16:31 cgroup.clone_children
--w--w--w- 1 root root 0 Oct 23 16:31 cgroup.event_control
-rw-r--r-- 1 root root 0 Oct 23 16:31 cgroup.procs
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.failcnt
--w------- 1 root root 0 Oct 23 16:31 memory.force_empty
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.kmem.failcnt
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.kmem.max_usage_in_bytes
-r--r--r-- 1 root root 0 Oct 23 16:31 memory.kmem.slabinfo
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.kmem.tcp.failcnt
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.kmem.tcp.max_usage_in_bytes
-r--r--r-- 1 root root 0 Oct 23 16:31 memory.kmem.tcp.usage_in_bytes
-r--r--r-- 1 root root 0 Oct 23 16:31 memory.kmem.usage_in_bytes
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.move_charge_at_immigrate
-r--r--r-- 1 root root 0 Oct 23 16:31 memory.numa_stat
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.oom_control
---------- 1 root root 0 Oct 23 16:31 memory.pressure_level
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 Oct 23 16:31 memory.stat
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.swappiness
-r--r--r-- 1 root root 0 Oct 23 16:31 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.use_hierarchy
-rw-r--r-- 1 root root 0 Oct 23 16:31 notify_on_release
-rw-r--r-- 1 root root 0 Oct 23 16:31 tasks
root@test:~# ls -l /sys/fs/cgroup/memory/docker/1c8999af3a3654cb9e053795198f0d1c377fc1080173213a6fdd2179123bcf00
total 0
-rw-r--r-- 1 root root 0 Oct 23 16:32 cgroup.clone_children
--w--w--w- 1 root root 0 Oct 23 16:31 cgroup.event_control
-rw-r--r-- 1 root root 0 Oct 23 16:31 cgroup.procs
-rw-r--r-- 1 root root 0 Oct 23 16:32 memory.failcnt
--w------- 1 root root 0 Oct 23 16:32 memory.force_empty
-rw-r--r-- 1 root root 0 Oct 23 16:32 memory.kmem.failcnt
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root 0 Oct 23 16:32 memory.kmem.max_usage_in_bytes
-r--r--r-- 1 root root 0 Oct 23 16:32 memory.kmem.slabinfo
-rw-r--r-- 1 root root 0 Oct 23 16:32 memory.kmem.tcp.failcnt
-rw-r--r-- 1 root root 0 Oct 23 16:32 memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root 0 Oct 23 16:32 memory.kmem.tcp.max_usage_in_bytes
-r--r--r-- 1 root root 0 Oct 23 16:32 memory.kmem.tcp.usage_in_bytes
-r--r--r-- 1 root root 0 Oct 23 16:32 memory.kmem.usage_in_bytes
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 Oct 23 16:32 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 Oct 23 16:32 memory.move_charge_at_immigrate
-r--r--r-- 1 root root 0 Oct 23 16:32 memory.numa_stat
-rw-r--r-- 1 root root 0 Oct 23 16:31 memory.oom_control
---------- 1 root root 0 Oct 23 16:32 memory.pressure_level
-rw-r--r-- 1 root root 0 Oct 23 16:32 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 Oct 23 16:32 memory.stat
-rw-r--r-- 1 root root 0 Oct 23 16:32 memory.swappiness
-r--r--r-- 1 root root 0 Oct 23 16:32 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 Oct 23 16:32 memory.use_hierarchy
-rw-r--r-- 1 root root 0 Oct 23 16:32 notify_on_release
-rw-r--r-- 1 root root 0 Oct 23 16:32 tasks
root@test:~# cat /sys/fs/cgroup/memory/docker/1c8999af3a3654cb9e053795198f0d1c377fc1080173213a6fdd2179123bcf00/memory.limit_in_bytes
209715200 # 200M = 200 * 1024 * 1024 B = 209715200 B

memory.usage_in_bytes # 使用值

root@test:~# docker inspect nginx |grep Pid # 查看网络情况
"Pid": 7641,
"PidMode": "",
"PidsLimit": null,
root@test:~# cat /proc/7641/net/dev
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
eth0: 1186 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0

设置代理

dockerd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

mkdir -p /etc/systemd/system/docker.service.d

cat > /etc/systemd/system/docker.service.d/proxy.conf <<EOF
[Service]
Environment="http_proxy=http://user:[email protected]:9870"

Environment="https_proxy=http://user:[email protected]:9870"

Environment="no_proxy=127.0.0.0/8,10.0.0.0/8,100.64.0.0/10,172.16.0.0/12,192.168.0.0/16,ivolces.com,localhost"

EOF

systemctl daemon-reload
systemctl restart docker
systemctl show --property=Environment docker

containerd daemon.json 添加

1
2
3
4
5
6
7
8
9
10
11
{
"proxies":
{
"default":
{
"httpProxy": "http://proxy.example.com:8080",
"httpsProxy": "http://proxy.example.com:8080",
"noProxy": "localhost,127.0.0.1,.example.com"
}
}
}

build

1
2
3
4
5
docker build . \
--build-arg "HTTP_PROXY=http://proxy.example.com:8080/" \
--build-arg "HTTPS_PROXY=http://proxy.example.com:8080/" \
--build-arg "NO_PROXY=localhost,127.0.0.1,.example.com" \
-t your/image:tag