一、docker的组成
1、容器技术是linuz内核核心提供的,docker只是容器的管理引擎。在内核当中关键支持容器技术的核心有两个
1)namespaces 名称空间(Mount 文件系统树、进程、IPC 进程间通信、network、UTS 主机名称和域名、user 用户)六个名称空间,正是由于内核的这6个名称空间,可以切割成多个独立的容器,每个容器都有其自己的名称空间
2)control group 实现资源配额
2、docker的基础架构
1)docker client docker客户端,(我们使用的命令行客户端,其还有提供的api客户端)
2)docker Host(daemon) 容器引擎
3)docker registries 镜像仓库(默认的仓库是dockerhub),1个registry可以包含多个repository,而1个repository中会储存多个同种的application。每个application使用 name:tag来表示其版本。
3、当docker容器生成之后,其网络地址默认会使用172.17.0.0/16段内的网络地址,并会将地址桥接到nat模式的docker0网桥上与主机进行通信。
4、每个容器都只能启动单一进程,如果需要运行多个进程则需要使用监管服务作为其第一个进程,如init、systemd、supervisord。
5、如果要配置容器内的应用程序,docker提供了环境变量的方式来向容器内传值;但是如何将环境变量替换到容器内的配置文件中去呢,而且传递过去之后如何生效也是一个问题。
二、docker镜像仓库
1、docker镜像的结构
Docker镜像含有启动容器所需要的文件系统及其内容,因此,其用于创建并启动docker容器。镜像文件使用Union FS分层构建;最底层为 bootfs ,其之为rootfs;位于下层的镜像称为父镜像 (parent image),最底层的称为基础镜像(base image), 最上层为“ 可读写” 层,其下的均为“ 只读” 层。
bootfs :用于系统引导的文件系统,包括 bootloader 和 kernel,容器启动完成后会被卸载以节约内存资源;
rootfs :位于 bootfs 之上,表现为 docker容器的根文件系统
docker 中, rootfs 由内核挂载为“只读”模式,而后通过“联合挂载 ”技术额外挂载一个“可写”层;
2、Docker所使用的Union FS
1)Aufs:aufs 是之前的 UnionFS 的重新实现, 在 Ubuntu 系统下, docker 默认 Ubuntu 的 aufs
2)overlayfs:从 3.18 版本开始被合并到 Linux内核
3)docker 的分层镜像,除了 aufs , docker 还支持 btrfs, devicemapper 和 vfs等;在 CentOS7 上,用的是devicemapper ;
4)Device Mapper 是 Linux2.6 内核中支持逻辑卷管理的通用设备映射机制,它为实现用于存储资源管理的块设备驱动提供了一个高度模块化的内核架构。在内核中它通过一个一个模块化的 target driver 插件实现对 IO请求的过滤或者重新定向等工作,当前已经实现的 target driver插件包括软 raid、软加密、逻辑卷条带、多路径、镜像、快照等。
3、Docker Registry 分类
Registry 用于保存 docker 镜像,包括镜像的层次结构和元数据;用户可自建 Registry ,也可使用官方的Docker Hub
4、Repository
一个Registry可以储存多个Repository;Repository 可分为“顶层仓库”和“用户仓库”;用户仓库名称格式为“用户名 / 仓库名”;每个仓库可以包含多个 Tag( 标签) ,每个标签对应一个镜像
5、Index
维护用户帐户、镜像的校验以及公共命名空间的信息;相当于为 Registry 提供了一个完成用户认证等功能的检索接口。
6、docker镜像的获取
格式:docker pull <registry>[:port]/[<namespace>/]<name>:<tag>
注意:registry是通过https来进行数据传输的,所以证书需要配置
可以使用 docker search 来搜索我们所需要的镜像(默认会从docker hub上获取),例:
[root@ansible_master ~]# docker search alpine
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
alpine A minimal Docker image based on Alpine Linux… 3421 [OK]
mhart/alpine-node Minimal Node.js built on Alpine Linux 346
anapsix/alpine-java Oracle Java 8 (and 7) with GLIBC 2.23 over A… 299 [OK]
gliderlabs/alpine Image based on Alpine Linux will help you wi… 177
frolvlad/alpine-glibc Alpine Docker image with glibc (~12MB) 137 [OK]
kiasaki/alpine-postgres PostgreSQL docker image based on Alpine Linux 41 [OK]
zzrot/alpine-caddy Caddy Server Docker Container running on Alp… 32 [OK]
easypi/alpine-arm AlpineLinux for RaspberryPi 26
davidcaste/alpine-tomcat Apache Tomcat 7/8 using Oracle Java 7/8 with… 24 [OK]
alpine/git A simple git container running in alpine li… 22 [OK]
etopian/alpine-php-wordpress Alpine WordPress Nginx PHP-FPM WP-CLI 12 [OK]
byrnedo/alpine-curl Alpine linux with curl installed and set as … 10 [OK]
davidcaste/alpine-java-unlimited-jce Oracle Java 8 (and 7) with GLIBC 2.21 over A… 9 [OK]
graze/php-alpine Smallish php7 alpine image with some common … 8 [OK]
yobasystems/alpine-xen-orchestra Xen Orchestra running on Alpine Linux [docke… 7 [OK]
hermsi/alpine-sshd Dockerize your OpenSSH-server upon a lightwe… 7 [OK]
zzrot/alpine-node Alpine Node Base Image Running On Alpine Lin… 5 [OK]
tenstartups/alpine Alpine linux base docker image with useful p… 5 [OK]
spotify/alpine Alpine image with `bash` and `curl`. 4 [OK]
hermsi/alpine-fpm-php Dockerize your FPM PHP 7.2 upon a lightweigh… 3 [OK]
govuk/gemstash-alpine Gemstash server running on Alpine 2 [OK]
functions/alpine Alpine Linux / BusyBox with the OpenFaaS wat… 2
colstrom/alpine Alpine Linux is a security-oriented, lightwe… 2 [OK]
casept/alpine-amd64 A basic alpine linux image. 0
smartentry/alpine alpine with smartentry 0 [OK]
以上是alpine的docker镜像文件,其中OFFICIAL标志为[OK]的表示官方镜像,我们可以在dockerhub上注册一个账户来上传我们所制作的镜像。
我们可以使用docker images 来查看已经pull下来的docker镜像文件
[root@ansible_master ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 8ac48589692a 9 days ago 1.15MB
nginx 1.12-alpine 24ed1c575f81 3 months ago 15.5MB
alpine latest 3fd9065eaf02 3 months ago 4.15MB
7、镜像的生成途径
1)Dockerfile
2)基于容器的的制作(commit)
3)Docker Hub automated builds
三、Centos OS环境配置
1、配置docker源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
如果没有“yum-config-manager”工具,请安装“yum-utils”
yum install -y yum-utils
2、安装合适的docker版本
yum list docker-ce-17.* --showduplicates #17是版本号
yum install -y docker-ce-17.12.1.ce #选择合适的版本安装
3、启动docker并确认docker版本信息
systemctl start docker
docker info
-----------------------------------------------------------------
Containers: 0 #容器的数量
Running: 0 #容器运行的个数
Paused: 0 #容器暂停的个数
Stopped: 0 #容器停止的个数
Images: 0 #镜像数量
Server Version: 17.12.1-ce #当前docker版本
Storage Driver: overlay2 #存储驱动,如果是devicemapper,请更新docker版本,难用的一B
Backing Filesystem: xfs #底层文件系统
Supports d_type: true #创建xfs文件系需要加上-n ftype=1,否则跪了不怨我,请注意您需要将文件系统重现格式化为支持ftype
Native Overlay Diff: true
Logging Driver: json-file #日志驱动
Cgroup Driver: cgroupfs #资源限制驱动 cgroup
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive #docker内嵌的容器编排工具
Runtimes: runc #运行时
Default Runtime: runc
Init Binary: docker-init
containerd version: 9b55aab90508bd389d7654c4baf173a981477d55
runc version: 9f9c96235cc97674e935002fc3d78361b696a69e
init version: 949e6fa
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-693.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 472.3MiB
Name: ansible_master
ID: CGJB:S2UL:QEYA:NAVX:Q5DW:KWKJ:67XO:ZCAF:PRW3:W2A4:MZVK:B76O
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
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
4、拉取镜像
注意:不建议拉去重量级的镜像,如centos、ubuntu等;建议使用busybox,cirros,alpine等比较微量的镜像。
例:
#拉镜像的时候不加tags,默认拉去最新的镜像
doker pull busybox
docker pull busybox
docker pull alpine
docker pull nginx:1.12-alpine
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 8ac48589692a 9 days ago 1.15MB
nginx 1.12-alpine 24ed1c575f81 3 months ago 15.5MB
alpine latest 3fd9065eaf02 3 months ago 4.15MB
5、查看镜像内容
[root@ansible_master ~]# docker inspect nginx:1.12-alpine
[
{
"Id": "sha256:24ed1c575f8176d90af60ed57f89a9bae0e16c56b48519311f48b106e0e0c407",
"RepoTags": [
"nginx:1.12-alpine"
],
"RepoDigests": [
"nginx@sha256:db5acc22920799fe387a903437eb89387607e5b3f63cf0f4472ac182d7bad644"
],
"Parent": "",
"Comment": "",
"Created": "2018-01-10T04:14:23.895465626Z",
"Container": "3ddffbf118572c37d9964268683d020e3b9c42133e39f706855be181b2f0e45d",
"ContainerConfig": {
"Hostname": "3ddffbf11857",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.12.2"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"nginx\" \"-g\" \"daemon off;\"]"
],
"ArgsEscaped": true,
"Image": "sha256:817dd39d3988823f385cab63355897d76b4b976333c0b78761df4855bf856eb3",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": [],
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGTERM"
},
"DockerVersion": "17.06.2-ce",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.12.2"
],
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"ArgsEscaped": true,
"Image": "sha256:817dd39d3988823f385cab63355897d76b4b976333c0b78761df4855bf856eb3",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": [],
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGTERM"
},
"Architecture": "amd64",
"Os": "linux",
"Size": 15502679,
"VirtualSize": 15502679,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/545b1bcf85e3f7464cd7676422a0f5546eadb2d70e6b2c18ae57f5ae2ce28f56/diff:/var/lib/docker/overlay2/948f78fb3e8d67f6a55508882e4d26b005841de8956f2ead392bbdbb93fb7bfc/diff:/var/lib/docker/overlay2/e4d4d565074f5224031bd34e4acbcd6cf7b79d110d133b7e9cc5e148cdd88931/diff",
"MergedDir": "/var/lib/docker/overlay2/79201561e69c053d1888f99347aa7dad198bfe2bb2e99f841c90b9e88050f73e/merged",
"UpperDir": "/var/lib/docker/overlay2/79201561e69c053d1888f99347aa7dad198bfe2bb2e99f841c90b9e88050f73e/diff",
"WorkDir": "/var/lib/docker/overlay2/79201561e69c053d1888f99347aa7dad198bfe2bb2e99f841c90b9e88050f73e/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:d39d92664027be502c35cf1bf464c726d15b8ead0e3084be6e252a161730bc82",
"sha256:8460a579ab63027b243e6e9b666ff0d735c5258f43abcd582e9a9ca31f28b117",
"sha256:c1dc81a64903af713ca2b8c1f40463856a77a3a694c43d89174e6cac06b90322",
"sha256:68695a6cfd7dc5338b88d09f2f1a7bcff336caa0eb9ccc51ada7de023017ed9d"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
注意:容器内的进程必须在前台执行,如上述结果的“ “Cmd”: [ “nginx”, “-g”, “daemon off;”]”
6、容器的基础操作(创建、运行、停止、终止、重启、暂停、删除、查看)
docker create --name alpine -it alpine:latest #创建容器
7eb56776ccd5c734bb5f04f5f1f8bfbfc88740720d654058af5382034cb2e684 #容器编号
docker start 7eb5 #运行上面创建的容器“7eb5”是容器编号的前4位
docker run --name b1 -itd nginx:1.12-alpine #创建并启动容器,-d讲当前容器丢后台
docker rm 7eb5 #删除镜像
docker pause
docker unpause
docker top
7、基于已运行的容器制作新的镜像
基于一个运行的nginx的容器,制作镜像
1)修改容器内配置
[root@ansible_master ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9f528e597ffc nginx:1.12-alpine "nginx -g 'daemon of…" 4 hours ago Up 4 hours 80/tcp nginx_alpine
77bdb349a8fa alpine:latest "/bin/sh" 4 hours ago Up 4 hours alpine
[root@ansible_master ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9f528e597ffc nginx:1.12-alpine "nginx -g 'daemon of…" 4 hours ago Up 4 hours 80/tcp nginx_alpine
77bdb349a8fa alpine:latest "/bin/sh" 4 hours ago Up 4 hours alpine
[root@ansible_master ~]# docker exec -it 9f52 /bin/sh
/ # vi /etc/nginx/nginx.conf
修改
worker_processes 2;
/ # nginx -t #检查配置文件
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
/ # nginx -s reload #重载nginx配置
2018/04/14 14:59:53 [notice] 22#22: signal process started
2)提交制作镜像
[root@ansible_master ~]# docker help commit
Options:
-a, --author string Author (e.g., "John Hannibal Smith <hannibal@a-team.com>") #指明作者
-c, --change list Apply Dockerfile instruction to the created image #指明修改的列表
-m, --message string Commit message #提交信息
-p, --pause Pause container during commit (default true) #提交时暂停容器
[root@ansible_master ~]# docker commit -a "<joker@777.com>" -m "modify /etc/nginx/nginx.conf:worker_processes 2;" 9f52 #生成新的镜像
sha256:26fce246aebb96d5bc3a768494fe107dfad9a536ca093a5063804bf90d98b1c0
3)查看我们生成的镜像
[root@ansible_master ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 26fce246aebb 25 seconds ago 15.5MB #我们生成的
busybox latest 8ac48589692a 9 days ago 1.15MB
nginx 1.12-alpine 24ed1c575f81 3 months ago 15.5MB
alpine latest 3fd9065eaf02 3 months ago 4.15MB
#没有Repository 和tag
4)为我们的镜像生成仓库和tag
[root@ansible_master ~]# docker tag 26fce nginx:1.23-alpine.041418
[root@ansible_master ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx 1.23-alpine.041418 26fce246aebb 13 minutes ago 15.5MB #OK
busybox latest 8ac48589692a 9 days ago 1.15MB
nginx 1.12-alpine 24ed1c575f81 3 months ago 15.5MB
alpine latest 3fd9065eaf02 3 months ago 4.15MB
5)将镜像上传到镜像仓库
docker login --user=... registryURI
docker push registry/namespace/repository:tags
docker image push registry/namespace/repository:tags
6)使用save、load来打包镜像
[root@ansible_master ~]# docker save nginx:1.23-alpine.041418 nginx:1.12-alpine -o nginx.tar
[root@ansible_master ~]# docker load -i nginx.tar
Loaded image: nginx:1.23-alpine.041418
Loaded image: nginx:1.12-alpine
四、数据卷管理
1、原理
docker容器内所生成的数据都是临时数据,当容器关闭时则临时数据丢失,但其所生成真实数据我们是需要储存的,我们不能让docker生成的真实数据随容器的关闭而丢失,这时就必须用到数据卷,即将操作系统的文件系统映射到容器内,使容器运行所产生的重要数据保存在卷当中,当容器关闭,数据不会丢失。操作系统所提供的文件系统可以是分布式文件系统、本地磁盘、网络文件系统。
docker支持的卷类型有两种:
1)绑定挂载卷,可以自定义指定挂载的路径,但路径必须是实现生成好的。
2)docker管理卷,按需在容器内创建指定目录,但所映射的操作系统路径只能在特定目录下生成(/var/lib/docker/vfs/dir/volume_ID)
2、创建卷
1)创建docker管理卷
[root@ansible_master ~]# docker run -itd -v data nginx:1.12-alpine
2f490a3a2fffd8b5a197437ac13b1fa8811cbdafa31af0383c73034459efafe0
[root@ansible_master ~]# docker exec -it 2f49 /bin/sh
/ # ls
bin dev home media proc run srv tmp var
data etc lib mnt root sbin sys usr
#data即卷创建的目录
显示所创建的卷
[root@ansible_master ~]# docker volume ls
DRIVER VOLUME NAME
local 47f74350a325c26ef042b43962af7d2b148e98fdff8e87d465f64cda4826fb4c
[root@ansible_master ~]# docker volume inspect 47f74350a325c26ef042b43962af7d2b148e98fdff8e87d465f64cda4826fb4c
[
{
"CreatedAt": "2018-04-15T02:47:53+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/47f74350a325c26ef042b43962af7d2b148e98fdff8e87d465f64cda4826fb4c/_data",
"Name": "47f74350a325c26ef042b43962af7d2b148e98fdff8e87d465f64cda4826fb4c",
"Options": {},
"Scope": "local"
}
]
使用inspect 显示指定容器的指定属性
#两个大括号是固定格式,Config.Volumes表示Config下的Volumes属性,可参见完整的inspect信息来查找指定的参数。
[root@ansible_master ~]# docker inspect -f {{.Config.Volumes}} 2f49
map[data:{}]
#获取容器的IP地址
[root@ansible_master ~]# docker inspect -f {{.NetworkSettings.Networks.bridge.IPAddress}} 2f49
2)绑定挂载卷的使用方法
#宿主机创建绑定挂载卷目录
[root@ansible_master ~]# mkdir /data/containers/a{1..3} -pv
mkdir: 已创建目录 "/data/containers"
mkdir: 已创建目录 "/data/containers/a1"
mkdir: 已创建目录 "/data/containers/a2"
mkdir: 已创建目录 "/data/containers/a3"
#创建属主机到容器目录的目录映射
[root@ansible_master ~]# docker run -itd --name test1 -v /data/containers/b2:/data/web/html nginx:1.12-alpine
d3342e5b617f6faac1abbe818be96640115e108943631e48188aa15e9ab1743f
#进入容器,在共享卷中创建数据
[root@ansible_master ~]# docker exec -it d334 /bin/sh
/ # cd /data/web/html/
/data/web/html # echo 1 >ok.html
/data/web/html # exit
#退出容器,查看宿主机生成的数据
[root@ansible_master ~]# cat /data/containers/b2/ok.html
1
3)从其他容器复制共享卷
#创建共享卷容器,也叫基础架构容器
[root@ansible_master b2]# docker run -itd -v /data/redis:/data --name b1 busybox
#从共享卷容器复制共享卷
[root@ansible_master b2]# docker run -itd --name redis --volumes-from b1 busybox /bin/sh
897d6fa9524ac93e2a8aad603ac148c4c6f451fa6c39eee0e3a1691c1d560311