欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

Docker入门

程序员文章站 2022-06-20 23:39:37
[TOC] 一、Docker介绍 1.1 什么是Docker ​ Docker是一个开源的应用容器引擎,使用Go语言开发,基于Linux内核的cgroup,namespace,Union FS等技术,对应用进程进行封装隔离,并且独立于宿主机与其他进程,这种运行时封装的状态称为容器。 ​ Docker ......

目录

一、docker介绍

1.1 什么是docker

​ docker是一个开源的应用容器引擎,使用go语言开发,基于linux内核的cgroup,namespace,union fs等技术,对应用进程进行封装隔离,并且独立于宿主机与其他进程,这种运行时封装的状态称为容器。

​ docker早期版本实现是基于lxc,并进一步对其封装,包括文件系统、网络互联、镜像管理等方面,极大简化了容器管理。从0.7版本以后开始去除lxc,转为自省研发的libcontainer,从1.11版本开始,进一步为使用runc和containerd。

​ docker理念是将应用及依赖包打包到一个可移植的容器中,可发布到任意linux发行版docker引擎上。使用沙箱机制运行程序,程序之间相互隔离。

1.2 docker体系结构

Docker入门

containerd:是一个简单的守护进程,使用runc管理容器。向docker engine提供接口。

shim:只负责管理一个容器。

runc:是一个轻量级的工具,只用来运行容器。

Docker入门

  • docker client:客户端
  • docker daemon:守护进程
  • docker images:镜像
  • docker container:容器
  • docker registry:镜像仓库

1.3 docker内部组件

  • namespaces
命名空间,linux内核提供的一种对进程资源隔离的机制,例如进程、网络、挂载点等资源。
  • cgroup
控制组,linux内核提供的一种限制进程资源的机制;例如cpu、内存等资源。
  • unionfs
联合文件系统,支持将不同位置的目录挂载到同一虚拟文件系统,形成一种分层的模型。

1.4 什么是容器?

Docker入门

  • 对软件和其依赖的标准化打包
  • 应用之间相互隔离
  • 共享同一个os kernel
  • 可以运行在很多主流操作系统上

1.5 容器和虚拟机的区别

Docker入门

Docker入门

以kvm为例与docker对比

  • 启动时间
docker妙级启动,kvm分钟级启动。
  • 轻量级
容器镜像带下通常以m为单位,虚拟机以g为单位。
容器资源占用小,要比虚拟机部署更快捷。
  • 性能
容器共享宿主机内核,系统级虚拟化,占用资源少,没有hypervisor层开销,容器性能基本接近物理机;
虚拟机需要hypervisior层支持,虚拟化一些设备,具备完整的guestos,虚拟化开销大,因而降低性能,没有容器性能好。
  • 安全性
由于共享宿主机内核,只是进程级隔离,因此隔离性和稳定性不如虚拟机,容器具有一定权限访问宿主机内核,存在一定安全隐患。
  • 使用要求
kvm基于硬件的完全虚拟化、需要赢家cpu虚拟化技术支持;
容器共享所主机内核,可运行在主流的linux发行版,不用考虑cpu是否支持虚拟化技术。

1.6 虚拟化+容器

Docker入门

二、docker安装

2.1 docker官方网站

https://wwww.docker.com

2.2 docker版本

  • 社区版(community edition,ce)
  • 企业版(enterprise edition,ee)

2.3支持平台

  • linux(centos,debian,fedora,oracle linux,rhel,suse和ubuntu)
  • mac
  • windows

Docker入门

2.4 linux安装docker

2.4.1 docker文档

https://docs.docker.com
https://docs.docker.com/install/linux/docker-ce/centos/#set-up-the-repository

2.4.2 安装docker

2.4.2.1关闭防火墙

  systemctl stop firewalld
  systemctl disable firewalld

2.4.2.2关闭selinux

vi /etc/selinux/config
selinux=disabled    #设置为disabled
reboot  #重启服务器
# 查看selinux状态
[root@localhost ~]# getenforce
disabled

2.4.2.3安装所需的包

yum install -y yum-utils   device-mapper-persistent-data   lvm2

2.4.2.4配置yum源

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

2.4.2.5安装docker-ce

yum install docker-ce -y

2.4.2.6启动

systemctl start docker
# 加入开机启动
systemctl enable docker

2.4.2.7运行hello-world

docker run hello-world

2.4.2.8查看docker版本

[root@localhost ~]# docker info
containers: 1
 running: 0
 paused: 0
 stopped: 1
images: 1
server version: 18.09.0
storage driver: overlay2
 backing filesystem: xfs
 supports d_type: true
 native overlay diff: true
logging driver: json-file
cgroup driver: cgroupfs
plugins:
 volume: local
 network: bridge host macvlan null overlay
 log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
swarm: inactive
runtimes: runc
default runtime: runc
init binary: docker-init
containerd version: c4446665cb9c30056f4998ed953e6d4ff22c7c39
runc version: 4fc53a81fb7c994640722ac585fa9ca548971871
init version: fec3683
security options:
 seccomp
  profile: default
kernel version: 3.10.0-862.el7.x86_64
operating system: centos linux 7 (core)
ostype: linux
architecture: x86_64
cpus: 1
total memory: 1.779gib
name: localhost.localdomain
id: jdcf:rjad:hizf:zagm:ezns:46yy:i2am:okbh:prcs:aqbb:4dgt:x3rz
docker root dir: /var/lib/docker
debug mode (client): false
debug mode (server): false
registry: https://index.docker.io/v1/
labels:
experimental: false
insecure registries:
 127.0.0.0/8
live restore enabled: false
product license: community engine




[root@localhost ~]# docker version
client:
 version:           18.09.0
 api version:       1.39
 go version:        go1.10.4
 git commit:        4d60db4
 built:             wed nov  7 00:48:22 2018
 os/arch:           linux/amd64
 experimental:      false

server: docker engine - community
 engine:
  version:          18.09.0
  api version:      1.39 (minimum version 1.12)
  go version:       go1.10.4
  git commit:       4d60db4
  built:            wed nov  7 00:19:08 2018
  os/arch:          linux/amd64
  experimental:     false

2.4.2.9查看运行了哪些docker

[root@localhost ~]# docker run -it nginx    <<== -it前台运行、再打开一个终端用于查看
[root@localhost ~]# docker ps
container id        image               command                  created             status              ports               names
336509fd6799        nginx               "nginx -g 'daemon of…"   8 minutes ago       up 8 minutes        80/tcp              epic_ride

2.4.2.10查看容器信息

[root@localhost ~]# docker inspect 336509fd6799    <<==容器的id,用docker ps查看得到 
[
    {
        "id": "336509fd679988cf9e22d9fb1157e3bed5695aeb91d8d706b903b4943f33c30d",
        "created": "2018-11-08t12:30:38.462038658z",
        "path": "nginx",
        "args": [
            "-g",
            "daemon off;"
        ],
        "state": {
            "status": "running",
            "running": true,
            "paused": false,
            "restarting": false,
            "oomkilled": false,
            "dead": false,
            "pid": 1926,
            "exitcode": 0,
            "error": "",
            "startedat": "2018-11-08t12:30:38.800291064z",
            "finishedat": "0001-01-01t00:00:00z"
        },
        "image": "sha256:62f816a209e6b57dd5fe98c1994fe3ab19ba4e1fee2a5ec6d77f303be4ed90e9",
        "resolvconfpath": "/var/lib/docker/containers/336509fd679988cf9e22d9fb1157e3bed5695aeb91d8d706b903b4943f33c30d/resolv.conf",
        "hostnamepath": "/var/lib/docker/containers/336509fd679988cf9e22d9fb1157e3bed5695aeb91d8d706b903b4943f33c30d/hostname",
        "hostspath": "/var/lib/docker/containers/336509fd679988cf9e22d9fb1157e3bed5695aeb91d8d706b903b4943f33c30d/hosts",
        "logpath": "/var/lib/docker/containers/336509fd679988cf9e22d9fb1157e3bed5695aeb91d8d706b903b4943f33c30d/336509fd679988cf9e22d9fb1157e3bed5695aeb91d8d706b903b4943f33c30d-json.log",
        "name": "/epic_ride",
        "restartcount": 0,
        "driver": "overlay2",
        "platform": "linux",
        "mountlabel": "",
        "processlabel": "",
        "apparmorprofile": "",
        "execids": null,
        "hostconfig": {
            "binds": null,
            "containeridfile": "",
            "logconfig": {
                "type": "json-file",
                "config": {}
            },
            "networkmode": "default",
            "portbindings": {},
            "restartpolicy": {
                "name": "no",
                "maximumretrycount": 0
            },
            "autoremove": false,
            "volumedriver": "",
            "volumesfrom": null,
            "capadd": null,
            "capdrop": null,
            "dns": [],
            "dnsoptions": [],
            "dnssearch": [],
            "extrahosts": null,
            "groupadd": null,
            "ipcmode": "shareable",
            "cgroup": "",
            "links": null,
            "oomscoreadj": 0,
            "pidmode": "",
            "privileged": false,
            "publishallports": false,
            "readonlyrootfs": false,
            "securityopt": null,
            "utsmode": "",
            "usernsmode": "",
            "shmsize": 67108864,
            "runtime": "runc",
            "consolesize": [
                0,
                0
            ],
            "isolation": "",
            "cpushares": 0,
            "memory": 0,
            "nanocpus": 0,
            "cgroupparent": "",
            "blkioweight": 0,
            "blkioweightdevice": [],
            "blkiodevicereadbps": null,
            "blkiodevicewritebps": null,
            "blkiodevicereadiops": null,
            "blkiodevicewriteiops": null,
            "cpuperiod": 0,
            "cpuquota": 0,
            "cpurealtimeperiod": 0,
            "cpurealtimeruntime": 0,
            "cpusetcpus": "",
            "cpusetmems": "",
            "devices": [],
            "devicecgrouprules": null,
            "diskquota": 0,
            "kernelmemory": 0,
            "memoryreservation": 0,
            "memoryswap": 0,
            "memoryswappiness": null,
            "oomkilldisable": false,
            "pidslimit": 0,
            "ulimits": null,
            "cpucount": 0,
            "cpupercent": 0,
            "iomaximumiops": 0,
            "iomaximumbandwidth": 0,
            "maskedpaths": [
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "readonlypaths": [
                "/proc/asound",
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "graphdriver": {
            "data": {
                "lowerdir": "/var/lib/docker/overlay2/31cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d-init/diff:/var/lib/docker/overlay2/240731a3ae18beffce7a5053fb4b45c4a93c52c14b2b18e25751bd5ef5bce0b5/diff:/var/lib/docker/overlay2/613cf356b8ebdacffabca1e2f03c02102a19d13df25caef091c10858ec058731/diff:/var/lib/docker/overlay2/82d2821d41013463c69c23a8c1e58a96ab84ae9c6399a181d0b37f0459c8007b/diff",
                "mergeddir": "/var/lib/docker/overlay2/31cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d/merged",
                "upperdir": "/var/lib/docker/overlay2/31cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d/diff",
                "workdir": "/var/lib/docker/overlay2/31cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d/work"
            },
            "name": "overlay2"
        },
        "mounts": [],
        "config": {
            "hostname": "336509fd6799",
            "domainname": "",
            "user": "",
            "attachstdin": true,
            "attachstdout": true,
            "attachstderr": true,
            "exposedports": {
                "80/tcp": {}
            },
            "tty": true,
            "openstdin": true,
            "stdinonce": true,
            "env": [
                "path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "nginx_version=1.15.6-1~stretch",
                "njs_version=1.15.6.0.2.5-1~stretch"
            ],
            "cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "argsescaped": true,
            "image": "nginx",
            "volumes": null,
            "workingdir": "",
            "entrypoint": null,
            "onbuild": null,
            "labels": {
                "maintainer": "nginx docker maintainers <docker-maint@nginx.com>"
            },
            "stopsignal": "sigterm"
        },
        "networksettings": {
            "bridge": "",
            "sandboxid": "f98bbeec0b3b1822c8dd90123c99c7e8225470140148e1dc6075d0bf2685d74b",
            "hairpinmode": false,
            "linklocalipv6address": "",
            "linklocalipv6prefixlen": 0,
            "ports": {
                "80/tcp": null
            },
            "sandboxkey": "/var/run/docker/netns/f98bbeec0b3b",
            "secondaryipaddresses": null,
            "secondaryipv6addresses": null,
            "endpointid": "a6b4036fb031698c228b5b2567da7b07df949a960bffbe119645e88a9730cb27",
            "gateway": "172.17.0.1",
            "globalipv6address": "",
            "globalipv6prefixlen": 0,
            "ipaddress": "172.17.0.2",
            "ipprefixlen": 16,
            "ipv6gateway": "",
            "macaddress": "02:42:ac:11:00:02",
            "networks": {
                "bridge": {
                    "ipamconfig": null,
                    "links": null,
                    "aliases": null,
                    "networkid": "8a60ffdd13c42e28bfa9f6431d0264c790781ff8b5238dfc1f3af34c3d36d9ca",
                    "endpointid": "a6b4036fb031698c228b5b2567da7b07df949a960bffbe119645e88a9730cb27",
                    "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
                }
            }
        }
    }
]


[root@localhost ~]# curl -i 172.17.0.2
http/1.1 200 ok
server: nginx/1.15.6
date: thu, 08 nov 2018 12:43:20 gmt
content-type: text/html
content-length: 612
last-modified: tue, 06 nov 2018 13:32:09 gmt
connection: keep-alive
etag: "5be197d9-264"
accept-ranges: bytes

2.4.2.11进入容器中

[root@localhost ~]# docker exec -it 336509fd6799 bash
root@336509fd6799:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@336509fd6799:/# exit
exit

三、镜像管理

3.1 镜像是什么

  • 一个分层存储的文件
  • 一个软件的环境
  • 一个镜像可以创建n个容器
  • 一种标准化的交付
  • 一个不包含linux内核而又精简的linux操作系统

镜像不是一个单一的文件,而是有多层构成。我们可以通过docker history 查看镜像中各层内容及大小,每层对应着dockerfile中的一条指令。docker镜像默认存储在/var/lib/docker/<storage-driver>中。

[root@localhost ~]# docker history nginx        <<== 查看镜像有哪些分层
image               created             created by                                      size                comment
62f816a209e6        37 hours ago        /bin/sh -c #(nop)  cmd ["nginx" "-g" "daemon…   0b
<missing>           37 hours ago        /bin/sh -c #(nop)  stopsignal [sigterm]         0b
<missing>           37 hours ago        /bin/sh -c #(nop)  expose 80/tcp                0b
<missing>           37 hours ago        /bin/sh -c ln -sf /dev/stdout /var/log/nginx…   22b
<missing>           37 hours ago        /bin/sh -c set -x  && apt-get update  && apt…   53.8mb
<missing>           37 hours ago        /bin/sh -c #(nop)  env njs_version=1.15.6.0.…   0b
<missing>           37 hours ago        /bin/sh -c #(nop)  env nginx_version=1.15.6-…   0b
<missing>           3 weeks ago         /bin/sh -c #(nop)  label maintainer=nginx do…   0b
<missing>           3 weeks ago         /bin/sh -c #(nop)  cmd ["bash"]                 0b
<missing>           3 weeks ago         /bin/sh -c #(nop) add file:f8f26d117bc4a9289…   55.3mb


[root@localhost ~]# cd /var/lib/docker/
[root@localhost docker]# ls
builder  buildkit  containerd  containers  image  network  overlay2  plugins  runtimes  swarm  tmp  trust  volumes
[root@localhost docker]# cd overlay2/
[root@localhost overlay2]# ls
240731a3ae18beffce7a5053fb4b45c4a93c52c14b2b18e25751bd5ef5bce0b5
31cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d
31cc93e4ef8b9da5b5d98bc9a68cfdd8c1ba2a31bf65bcb21754defd68d85c5d-init
613cf356b8ebdacffabca1e2f03c02102a19d13df25caef091c10858ec058731
802c4abe1551fbbba1e4445b149852e2b0a8eb969adc2a45955d60ea88cdd370
82d2821d41013463c69c23a8c1e58a96ab84ae9c6399a181d0b37f0459c8007b
b5044ef06828dd2656c0d59f03cd854917033fe8ebd2e26bc3332b359cfcc148
b5044ef06828dd2656c0d59f03cd854917033fe8ebd2e26bc3332b359cfcc148-init
backingfsblockdev
l

3.1.1 镜像从那里来?

docker hub是由docker公司负责维护的公共注册中心,包含大量的容器镜像,docker工具默认从这个公共镜像库下载镜像。地址:https://hub.docker.com/explore

3.1.2 配置镜像加速器

https://www.daocloud.io/mirror
curl -ssl https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
systemctl restart docker

3.2 镜像与容器联系

Docker入门

如图,容器其实是在镜像的最上面加了一层读写层,在运行容器里文件改动时,会先从镜像里面要写的文件复制到容器自己的文件系统中(读写层)。

如果容器删除了,最上面的读写层也就被删除了,改动也就丢失了。所以无论多少个容器共享一个镜像,所做的写操作都是从镜像的文件系统中复制过来操作的,并不会修改镜像的源文件,这种方式提高磁盘利用率。

若想持久化这些改动,可以通过docker commit将容器保存成一新的镜像。

root@localhost ~]# docker run -itd nginx
5ba9e0be87ade5e68481bface386c8ef592bb80bbe7bf28cf1572e832c8ce355

[root@localhost ~]# docker ps
container id        image               command                  created             status              ports               names
5ba9e0be87ad        nginx               "nginx -g 'daemon of…"   51 seconds ago      up 50 seconds       80/tcp              sharp_mayer
[root@localhost ~]# docker exec -it 5ba9e0be87ad bash
root@5ba9e0be87ad:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@5ba9e0be87ad:/# touch nginx.txt
root@5ba9e0be87ad:/# exit
exit
[root@localhost ~]# docker inspect 5ba9e0be87ad
....
# 存储驱动
graphdriver": {
            "data": {
                "lowerdir": "/var/lib/docker/overlay2/44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a-init/diff:/var/lib/docker/overlay2/240731a3ae18beffce7a5053fb4b45c4a93c52c14b2b18e25751bd5ef5bce0b5/diff:/var/lib/docker/overlay2/613cf356b8ebdacffabca1e2f03c02102a19d13df25caef091c10858ec058731/diff:/var/lib/docker/overlay2/82d2821d41013463c69c23a8c1e58a96ab84ae9c6399a181d0b37f0459c8007b/diff",
                "mergeddir": "/var/lib/docker/overlay2/44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a/merged",
                "upperdir": "/var/lib/docker/overlay2/44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a/diff",
                "workdir": "/var/lib/docker/overlay2/44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a/work"
            },
            "name": "overlay2"
        },
       ...


[root@localhost ~]# cd /var/lib/docker/overlay2/44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a
[root@localhost 44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a]# ls
diff  link  lower  merged  work
[root@localhost 44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a]# ls diff/         # 与惊喜差异
nginx.txt  root  run  var
[root@localhost 44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a]# ls merged/   <<==nginx工作的数据驱动存储
bin  boot  dev  etc  home  lib  lib64  media  mnt  nginx.txt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@localhost 44cfba513bee96fa98dd85ef9cbf8a88f8286c90291b498a615be6f590bda66a]# ls work/
work

3.3 管理镜像常用命令

docker image --help

指令 描述
ls 列出镜像
build 构建镜像来自dockerfile
history 查看镜像历史
inspect 显示一个或多个镜像详细信息
pull 推送一个镜像到镜像仓库
rm 移除一个或多个镜像
prune 移除未使用的镜像。没有被标记或被任何容器引用的。
tag 创建一个引用源镜像标记目标镜像
export 导出容器文件系统到tar归档文件
import 导入容器文件系统tar归档创建镜像
save 保存一个或多个镜像到tar归档文件
load 加载镜像来自tar归档或标准输入

四、容器管理

4.1 创建容器常用选项

docker container run --help

选项 描述
-i,-interactive 交互式
-t,-tty 分配一个伪终端
-d,-detach 运行容器到后台
-e,-env 设置环境变量
-p,-publish list 发布容器端口到主机
-p,-publish-all 发布容器所有expose端口到宿主机随机端口
-name string 指定容器名称
-h,-hostname 设置容器主机名
-ip string 指定容器ip,只能用于自定义网络
-network 连接容器到一个网络
-mount mount 将文件系统附加到容器
-v,-volume list 绑定挂载一个卷
-restart string 容器退出时重启策略,默认no,可选值:[always|on-failure]

4.2 容器资源限制

选项 描述
-m,-memory 容器可以使用的最大内存量
-memory-swap 允许交换磁盘的内存量
-memory-swappiness=<0-100> 容器使用swap分区交换的百分比(0-100,默认为-1)
-oom-kill-disable 禁用oom killer
-cpus 可以使用的cpu数量
-cpuset-cpus 限制容器使用特定的cpu核心,(0-3,0,1)
-cpu-shares cpu共享(相对权重)

示例:

4.2.1 内存限额

允许容器最多使用500m内存和100m的swap,并禁用oom killer:
# 允许使用的swap=memory-swap - memory
# memory-swap='-1'时,无限制使用swap
# memory-swap 不设置时,默认swap的值时memory的2倍
# memory-swap的值等于memory值时,禁用swap
docker run -d --name nginx01 --memory="500m" --memory-swap="600m" --oom-kill-disable nginx

4.2.2 cpu限额

允许容器最多使用一个半的cpu:

docker run -d --name nginx04 --cpus="1.5" nginx

允许容器最多使用50%的cpu:

docker run -d --name nginx05 --cpus='.5' nginx

4.3 管理容器常用命令

docker container --help

选项 描述
ls 列出容器
inspect 查看一个或多个容器详细信息
commit 创建一个新镜像来自一个容器
cp 拷贝文件/文件夹到一个容器
logs 获取一个容器日志
port 列出或指定容器端口映射
top 显示一个容器运行的进程
stats 显示容器资源使用统计
stop/start 停止/启动一个或多个容器
rm 删除一个或多个容器

五、管理应用程序数据

5.1 将宿主机数据挂载到容器中的三种方式

Docker入门

docker提供三种方式数据从宿主机挂载到容器中:

  • volumes:docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。保存数据的最佳方式。
  • bind mounts:将宿主机上的任意位置的文件或者目录挂载到容器中。
  • tmpfs:挂载存储在主机系统的内存中,而不会写入主机的文件系统。如果不希望将数据持久化存储到任何位置,可以使用tmpfs,同时避免写入容器可写层提高性能。

5.2 volume

  • 管理卷
docker volume create nginx-vol
docker volume ls
docker volume inspect nginx-vol
  • 用卷创建一个容器
# 新语法
docker run -d --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx
# 旧语法
docker run -d --name=nginx-test -v nginx-vol:/usr/share/nginx/html nginx
  • 清理
docker stop nginx-test
docker rm nginx-test
docker volume rm nginx-vol

注意:

1. 如果没有指定卷,自动创建。
2. 建议使用—mount,更通用。

https://docs.docker.com/engine/admin/volumes/volumes/#start-a-container-with-a-volume

5.3 bind mounts

  • 用卷创建一个容器
# 新语法
docker run -d --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx
# 旧语法
docker run -d --name=nginx-test -v /app/wwwroot:/usr/share/nginx/html nginx
  • 验证绑定
docker inspect nginx-test
  • 清理
docker stop nginx-test
docker rm nginx-test

注意:

1.2 如果源文件/目录没有存在,不会自动创建,会抛出一个错误。

1.3 如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏。

https://docs.docker.com/engine/admin/volumes/bind-mounts/#start-a-container-with-a-bind-mount

volume特点

  • 多个运行容器之间共享数据。
  • 当容器停止或悲移除时,该卷依然存在。
  • 多个容器可以同时挂载相同的卷。
  • 当明确删除卷时,卷才会被删除。
  • 将容器的数据存储在远程主机或其他存储上
  • 将数据从一台docker主机迁移到另一台时,先停止容器,然后备份卷的目录(/var/lib/docker/volumes)

bind mounts特点

  • 从主机共享配置文件到容器。默认情况下,挂载主机/etc/resolv.conf到每个容器,提供dns解析。
  • 在docker主机上的开发环境和容器之间共享源代码。例如,可以将maven target目录挂载到容器中,每次在docker主机上构建maven项目时,容器都可以访问构建的项目包。
  • 当docker主机的文件或目录结构保证与容器所需的绑定挂载一致时。

六、容器网络

6.1 docker四种网络模式

  • bridge
-net=bridge
默认网络,docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。
  • host
-net=host
容器不会获得一个独立的network namespace,而是与宿主机共用一个,这就意味着容器不会有自己的网卡信息,而是使用宿主机的。容器除了网络,其他都是隔离的。
  • none
-net=none
获取独立的network namespave,但不为容器进行任何网络配置,需要我们手动配置。
  • container
-net=container:name/id
与指定的容器使用同一个network namespace,具有同样的网络配置信息,两个容器除了网络,其他都还黑隔离的。
  • 自定义网络
与默认的bridge原理一样,但自定义网络具备内部dns发现,可以通过容器名或者主机名容器之间网络通信。

6.2 容器网络访问原理

Docker入门

Docker入门

linux ip信息包过滤原理:

docker主要通过netfilter/iptables实现网络通信。
iptables由netfilter和iptables组成,netfilter组件是linux内核集成的信息包过滤系统,它维护一个信息包过滤表,这个表用于控制信息包过滤处理的规则集,而iptables只是一个在用户空间的工具,用于增删改查这个过滤表的规则。

Docker入门

filter(过滤) input、output、forward
nat(地址转换) prerouting、postrouting、output
mangle(拆包、修改、封装) input、output、prerouting、 postrouting、output
raw(数据包状态跟踪) prerouting、output

 容器访问外部

# iptables -t nat -nl
chain postrouting (policy accept) target prot opt source masquerade all -- 172.17.0.0/16
 destination
0.0.0.0/0

 外部访问容器

chain docker (2 references) target prot opt source dnat tcp -- 0.0.0.0/0
destination
0.0.0.0/0
tcp dpt:88 to:172.18.0.2:80

Docker入门

6.3 桥接宿主机网络与配置固定ip

  • 临时生效
# 网桥名称
br_name=br0
# 添加网桥
brctl addbr $br_name
# 给网桥设置ip
ip addr add 192.168.1.120/24 dev $br_name
# 删除已存在的eth0网卡配置
ip addr del 192.168.1.120/24 dev eth0
# 激活网卡
ip link set $br_name up
# 添加eth0到网桥
brctl addif $br_name eth0
# 添加路由
ip route add default via 192.168.1.1 dev br0

还需要在docker启动时桥街这个网桥:
# vi /usr/lib/systemd/system/docker.service
execstart=/usr/bin/dockerd -b=br0
# systemctl restart docker
  • 永久生效
# vi /etc/sysconfig/network-scripts/ifcfg-eth0
device=eth0
type=ethernet
onboot=yes
bridge=br0

# vi /etc/sysconfig/network-scripts/ifcfg-br0
device=br0
type=bridge
onboot=yes
bootproto=static
ipaddr=192.168.3.10
netmask=255.255.255.0
gateway=192.168.3.1
dns1=114.114.114.114
  • 配置固定ip
c_id=$(docker run -itd --net=none ubuntu)
c_pid=$(docker inspect -f '{{.state.pid}}' $c_id)
# 创建network namespace目录并将容器的network namespace软连接到此目录,以便ip netns命令读取 mkdir -p /var/run/netns
ln -s /proc/$c_pid/ns/net /var/run/netns/$c_pid
# 添加虚拟网卡veth+容器pid,类型是veth pair,名称是vp+容器pid
ip link add veth$c_pid type veth peer name vp$c_pid
# 添加虚拟网卡到br0网桥
brctl addif br0 veth$c_pid
# 激活虚拟网卡
ip link set veth$c_pid up
# 设置容器网络信息
ip='192.168.0.123/24'
gw='192.168.0.1'
# 给进程配置一个network namespace
ip link set vp$c_pid netns $c_pid
# 在容器进程里面设置网卡信息
ip netns exec $c_pid ip link set dev vp$c_pid name eth0
ip netns exec $c_pid ip link set eth0 up
ip netns exec $c_pid ip addr add $ip dev eth0
ip netns exec $c_pid ip route add default via 192.168.1.1
  • pipework工具配置容器固定ip
git clone https://github.com/jpetazzo/pipework.git cp pipework/pipework /usr/local/bin/
docker run -itd --net=none --name test01 ubuntu pipework br0 test01 192.168.0.123/24@192.168.0.1

七、dockerfile

7.1 dockerfile格式

from centos:latest
maintainer huwl
run yum install gcc -y
copy run.sh /usr/bin
expose 80
cmd ['run.sh]

7.2 dockerfile常用指令

指令 描述
from 构建新镜像是基于那个镜像
maintainer 镜像维护者姓名或邮箱地址
run 构建镜像时运行的shell命令
copy 拷贝文件或目录到镜像中
env 设置环境变量
user 为run、cmd和entrpotin执行命令指定运行用户
expose 声明容器运行的服务端口
healthcheck 容器中服务健康检查
workdir 为run、cmd、entrypotin、copy和add设置工作目录
entrypoin 运行容器时执行,如果有多个entrypoin指令,最后一个生效
cmd 运行容器时执行,如果有多个cmd指令,最后一个生效

7.3 build构建镜像

usage:docker build [options] path | url | - [flags]
options:
-t, --tag list      # 镜像名称
-f,--file string    #指定dockerfile文件位置


# docker build .
# docker bulid -t shykes/myapp .
# docker bulid -t shykes/myapp -f /path/dockerfile /path
# docker bulid -t shykes/myapp http://www.example.com/dockerfile

7.4 企业应用案例

7.4.1 构建nginx基础镜像

  • dockerfile
from centos:7
run yum install -y gcc gcc-c++ make openssl-devel pcre-devel dg-devel iproute net-tools telnet wget curl && yum clean all && rm -rf /var/cache/yum/*
run wget http://nginx.org/download/nginx-1.15.5.tar.gz && tar zxf nginx-1.15.5.tar.gz && cd nginx-1.15.5 && ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module && make && make install
env path $path:/usr/local/nginx/sbin
workdir /usr/local/nginx
expose 80
cmd ["./sbin/nginx","-g","daemon off;"]
  • 构建镜像
docker build -t nginx:v1 -f dockerfile .
# successfully built 373a0bdefe50
# successfully tagged nginx:v1

[root@localhost /]# docker image ls
repository          tag                 image id            created             size
nginx               v1                  373a0bdefe50        56 seconds ago      335mb
<none>              <none>              d582c01a839f        4 minutes ago       200mb
nginx               latest              62f816a209e6        2 days ago          109mb
centos              7                   75835a67d134        4 weeks ago         200mb
hello-world         latest              4ab4c602aa5e        2 months ago        1.84kb
  • 启动测试
[root@localhost /]# docker run -d --name nginx100 -p 80:80 nginx:v1
a29daf4614116f7dba18461e871d1a45ec9b55f722a98bead791c12294b9f1d3
[root@localhost /]# docker ps -l
container id        image               command                  created             status              ports                names
a29daf461411        nginx:v1            "./sbin/nginx -g 'da…"   6 seconds ago       up 5 seconds        0.0.0.0:80->80/tcp   nginx100


[root@localhost /]# curl -i http://192.168.56.146/
http/1.1 200 ok
server: nginx/1.15.5
date: fri, 09 nov 2018 12:34:03 gmt
content-type: text/html
content-length: 612
last-modified: fri, 09 nov 2018 12:29:20 gmt
connection: keep-alive
etag: "5be57da0-264"
accept-ranges: bytes

7.4.2 构建php基础镜像

  • dockerfile
from centos:7
run yum install -y gcc gcc-c++ make gd-devel libxml2-devel libcurl-devel libjpeg-devel libpng-devel openssl-devel
add php-5.6.31.tar.gz /tmp/

run cd /tmp/php-5.6.31 && \
    ./configure --prefix=/usr/local/php \
    --with-config-file-path=/usr/local/php/etc \
    --with-mysql --with-mysqli \
    --with-openssl --with-zlib --with-curl --with-gd \
    --with-jpeg-dir --with-png-dir --with-iconv \
    --enable-fpm --enable-zip --enable-mbstring && \
    make -j 4 && \
    make install && \
    cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf && \
    sed -i "s/127.0.0.1/0.0.0.0/" /usr/local/php/etc/php-fpm.conf && \
    sed -i "21a \daemonize = no" /usr/local/php/etc/php-fpm.conf
copy php.ini /usr/local/php/etc

run rm -rf /tmp/php-5.6.31* && yum clean all

workdir /usr/local/php
expose 9000
cmd ["./sbin/php-fpm", "-c", "/usr/local/php/etc/php-fpm.conf"]
  • 构建php镜像
docker build -t php:v1 -f dockerfile .
  • 启动测试
[root@localhost php]# docker run -d --name php01 php:v1
ed5276251a6bf5124efba4b314d29a2dbfd12ddc0e0c3371ea16184a07c12bbc
[root@localhost php]# docker ps -l
container id        image               command                  created             status              ports               names
ed5276251a6b        php:v1              "./sbin/php-fpm -c /…"   5 seconds ago       up 4 seconds        9000/tcp            php01
[root@localhost php]# docker exec -it php01 bash
[root@ed5276251a6b php]# ls
bin  etc  include  lib  php  sbin  var
[root@ed5276251a6b php]# sbin/php-fpm -v
php 5.6.31 (fpm-fcgi) (built: nov 10 2018 01:10:28)
copyright (c) 1997-2016 the php group
zend engine v2.6.0, copyright (c) 1998-2016 zend technologies

7.4.3 构建tomcat基础镜像并项目测试

  • dockerfile
from centos:7

add jdk-8u45-linux-x64.tar.gz /usr/local
env java_home /usr/local/jdk1.8.0_45

add apache-tomcat-8.0.46.tar.gz /usr/local
copy server.xml /usr/local/apache-tomcat-8.0.46/conf

run rm -f /usr/local/*.tar.gz

workdir /usr/local/apache-tomcat-8.0.46
expose 8080
entrypoint ["./bin/catalina.sh", "run"]
  • 构建tomcat镜像
docker build -t tomcat:v1 -f dockerfile .
  • 启动测试
[root@localhost tomcat]# docker run -d --name tomcat01 -p 8080:8080 tomcat:v1
b9ba85bc64748c90ebe8df19e41c36490881cbcf174dab00d127ae6bf1141814
[root@localhost tomcat]# curl -i http://192.168.56.146:8080
http/1.1 200 ok
server: apache-coyote/1.1
content-type: text/html;charset=utf-8
transfer-encoding: chunked
date: sat, 10 nov 2018 01:26:59 gmt

7.5.1 快速部署lnmp网站平台

Docker入门

  • 创建自定义网络
docker network create lnmp
  • 创建mysql容器
docker run -d --name lnmp_mysql --net lnmp --mount src=mysql-vol,dst=/var/lib/mysql -e mysql_root_password=123456 -e mysql_database=wordpress mysql:5.7 --character-set-server=utf8
  • 创建php容器
docker run -d --name lnmp_php --net lnmp --mount src=wwwroot,dst=/wwwwroot php:v1
  • 创建nginx容器
docker run -d --name lnmp_nginx --net lnmp -p 80:80 --mount type=bind,src=$(pwd)/nginx.conf,dst=/usr/local/nginx/conf/nginx.conf --mount src=wwwroot,dst=/wwwroot nginx:v1
  • 以wordpress博客为例
https://cn.wordpress.org/wordpress-4.9.4-zh_cn.tar.gz

八、企业级镜像仓库harbor

8.1 harbor介绍

​ habor是由vmware公司开源的容器镜像仓库。事实上,habor是在docker registry上进行了相应的企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:管理用户界面,基于角色的访问控制,ad/dalp集成以及审计日志等,足以满足基本企业需求。

官方地址:https://vmware.github.io/harbor/cn/

组件 功能
harbor-adminserver 配置管理中心
harbor-db mysql数据库
harbor-jobservice 负责镜像复制
harbor-log 记录操作日志
harbor-ui web管理页面和api
nginx 前端代理,负责前端页面和镜像上传或下载转发
reids 会话
registry 镜像存储

8.2 harbor部署

harbor安装有3种方式:

  • 在线安装:从docker hub下载harbor相关镜像,因此安装软件包非常小
  • 离线安装:安装包包含部署的相关镜像,因此安装包比较大
  • ova安装程序:当用户具有vcenter环境时,使用此安装程序,在部署ova后启动harbor

离线安装下载地址:https://github.com/goharbor/harbor/releases

  • 部署
curl -l "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

tar xf harbor-offline-installer-v1.6.1.tgz
cd harbor
vim harbor.cfg
harbor_admin_password = harbor12345

./prepare
./install.sh

[root@localhost harbor]# docker-compose ps
       name                     command                  state                                    ports
-------------------------------------------------------------------------------------------------------------------------------------
harbor-adminserver   /harbor/start.sh                 up (healthy)
harbor-db            /entrypoint.sh postgres          up (healthy)   5432/tcp
harbor-jobservice    /harbor/start.sh                 up
harbor-log           /bin/sh -c /usr/local/bin/ ...   up (healthy)   127.0.0.1:1514->10514/tcp
harbor-ui            /harbor/start.sh                 up (healthy)
nginx                nginx -g daemon off;             up (healthy)   0.0.0.0:443->443/tcp, 0.0.0.0:4443->4443/tcp, 0.0.0.0:80->80/tcp
redis                docker-entrypoint.sh redis ...   up             6379/tcp
registry             /entrypoint.sh /etc/regist ...   up (healthy)   5000/tcp
  • 访问

http://192.168.56.146/harbor/sign-in

Docker入门

8.3 harbor基础使用

  • 默认上传镜像连接使用https,添加http受信任
[root@localhost harbor]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["http://f1361db2.m.daocloud.io"],
"insecure-registries": ["192.168.56.146"]       #<<= 加入harbor的地址

}
  • 重启docker
systemctl restart docker

在harbor web管理——“系统管理”——“用户管理”——新建用户,在——“项目”——“library仓库” ——“成员”把之前添加的用户进来并赋予权限

  • 登录仓库上传镜像
docker tag nginx:v1 192.168.56.146/library/nginx:v1
docker login harbor地址
docker push 192.168.56.146/library/nginx:v1

九、图形化界面管理

9.1 portainer

官网:https://portainer.io

https://portainer.io/install.html

portainer是一个开源、轻量级docker管理用户界面,基于docker api,可管理docker主机或swarm集群,支持最新版docker和swarm模块。

  • 创建卷
docker volume create portainer_data
  • 创建portainer容器
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
  • 访问portainer

http://192.168.56.146:9000

Docker入门

十、构建容器监控系统

10.1 cadvisor+influxdb+grafna

  • 创建monitor
docker network create monitor
  • influxdb
docker run -d --name influxdb --net monitor -p 8083:8083 -p 8086:8086 tutum/influxdb
  • cadvisor
docker run -d --name=cadvisor --net monitor -p 8081:8080 --mount type=bind,src=/,dst=/rootfs,ro --mount type=bind,src=/var/run,dst=/var/run --mount type=bind,src=/sys,dst=/sys,ro --mount type=bind,src=/var/lib/docker/,dst=/var/lib/docker,ro google/cadvisor -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxdb:8086
  • grafana
docker run -d --name grafana --net monitor -p 3000:3000 grafana/grafana