1.什么是docker
要想使用linux容器,至少要在linux内核支持两种技术:namespace
和cgourps
我们可以在用户空间组织一些工具,利用内核提供的这些技术从而实现容器运行的目的
docker在容器运行、使用简化的道路上更近一步,使用镜像及分层构建的镜像的方式,使得容器技术的使用进一步被简化
因此,docker就是linux容器技术的一种实现形式,一种前端工具
2.docker相关机构及标准
后来,又出现了OCI
以及OCF
:
- OCI(Open Container Initiative)
- 由Linux基金会主导于2015年6月创立
- 旨在围绕
容器格式
和运行时
指定一个开放的工业化标准
- OCF(Open Container Format)
- runC是此种格式的主要实现形式之一
3.docker架构
3.1 组成部分
- 主要有三部分组成:
- client端/docker client
- server端/docker host/docker daemon(因此docker是c/s架构的应用程序)
- Containers/容器
- Images/镜像
- docker Registries(镜像仓库)(docker hub是其中最出名的一个)
无论是client端还是server端,都是由docker一个程序提供;该程序有很多子程序,其中有个子程序有一个子命令daemon
,即运行为守护进程;
因此若运行docker deamon
,意味着该主机成为一个守护进程服务器;它可以监听在某个作为的套接字之上,为了安全起见,仅提供本机的socket文件(unix socket文件)
unix本地套接字:通常套网络套接字socket API是通过IP+Port的方式实现多台主机通信的,当单台主机内进程间通信也可以通过127.0.0.1地址进行通信。而Unix本地套接字,其实就是一种专门用于本地(也就是单个主机上的)网络通信的一种方法
常见的docker镜像仓库:docker hub,阿里云仓库,
-
为什么叫docker registry 而不叫docker repository?
因为docker registry拥有两层功能:1.提供镜像存储的仓库 2.用户来获取竟像时的认证功能 3.提供了镜像文件的索引功能
在docker上,通常一个仓库/repo只放一个应用程序的镜像,但是该仓库里存放着该应用程序的不同版本的镜像(如一个nginx仓库存放多个版本nginx的镜像),因此提供了一个tag标签来标识不同版本的镜像文件(如,nginx:1.10),因此需要用
仓库名+标签
来唯一标识一个镜像;而一个镜像可以有多个标签(如,一个stable标签会指向最新稳定版本,一旦最新稳定版本更新,该标签也会随之指向该版本的镜像)
因此在registry(如,docker hub)上会有很多的repo/仓库;一个repository是一个应用程序的集合,而registry则是repository的集合 -
Repository和Registry区别
-
Repository:
本身是一个仓库,这个仓库里面可以放具体的镜像,是指
具体的某个镜像
的仓库,比如Tomcat下main有很多个版本的镜像,它们共同组成了Tomcat的Repository -
Registry:
镜像的仓库,比如docker官方镜像仓库是Docker Hub,它是开源的,也可以私人部署一个,
Registry上有很多Repository
,Redis、Tomcat、MySQL等等Repository组成了Registry
如上图,docker的log,其中Repository就是一个一个的集装箱,而Registry则是鲸鱼
-
3.2 架构图
- 整体架构图
- 说明:
1. Docker Host与Registry之间默认是通过HTTPS协议通信的,也可以通过HTTP协议,前提是确认允许忽略安全问题
2. Docker Host中,可以直接通过socket/套接字进行监听的(通常是监听在Unix本地套接字上)
3. Client与Dcoker Host之间,由于Dcoker Host仅监听本地套接字文件,因此默认配置下,仅允许客户端在本地,也就是Docker daemon只能响应来自本地的Host的客户端请求
4.docker资源/对象
- images(只读/read-only,除非要重构镜像)
- containers
- networks
- volumes
- plugins
- others
说明1:
所有的资源对象都是可以单独地进行增删改查的
说明2:
镜像,是静态的,它不会运行
容器,是动态的,它有生命周期
容器和镜像的关系就类似进程和程序的关系;进程可以启动、终止,但是程序文件还在,同理,容器可以启动、终止,但是镜像文件还在
5.docker的安装与使用
5.1 依赖环境基础
- 64 bits CPU
- Linux Kernel 3.10+(Centos7.2的内核版本是3.10,也就是说尽量使用Centos7安装docker)
- lkLinux Kernel cgroups and namespace
5.2 安装docker的两种方式
-
CentOS7默认
“Extras” repository ,该仓库中有docker,如下
https://mirrors.tuna.tsinghua.edu.cn/centos/7/extras/x86_64/Packages/
通常不用Centos自带的docker
-
单独/第三方的仓库下载docker
如,以清华镜像站为例,
https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
将该repo文件下载到/etc/yum.repos.d/下
[root@vincent yum.repos.d]# wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
更改该repo文件中默认的baseurl的地址,如在清华镜像站中docker-ce里centos7 x86_64的具体url为
https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/Packages/
用
https://mirrors.tuna.tsinghua.edu.cn/docker-ce/
替换原repo文件中basurl的前缀部分https://download.docker.com/
vim中批量替换掉方法如下
:%s@https://download.docker.com/@https://mirrors.tuna.tsinghua.edu.cn/docker-ce/@
通过
yum repolist
查看当前仓库信息,可以看到docker-ce已有程序包
通过
yum install docker-ce
(1.使用默认的Extra则yum install docker;2.区分ce概念)
如上,安装完毕!
5.3 docker配置文件
-
docker-ce的配置文件
/etc/docker/daemon.json
,初次安装默认该目录及文件不存在,如果需要启动前定义某些配置,需要手动创建该目录及配置文件(比如配置镜像加速器) -
docker镜像加速
- doker.cn
- 阿里云加速器
- 中国科技大学加速器
比如,若使用docker.cn加速器,则需要在daemon.json中增加如下json格式的数组配置
{ "registry-mirrors":["https://registry.docker-cn.com"] }
5.4 docker启用
[root@vincent docker]# systemctl start docker.service
[root@vincent docker]#
可以直接通过docker
命令来打印docker的说明信息来确定docker启动成功
5.5 docker常用命令
-
命令说明
老版本中,docker的命令是直接
docker+command
的形式,比如docker create
代表新建容器,后来新版本中,docker将各个命令进行了分组管理,比如原来的docker create
分到了container
组中,新命令为docker container create
为了兼容,新版docker也是兼容老版本命令格式的,但是建议后续要用新的分组管理的命令形式
-
常见命令
docker --help # 展示docker命令帮助手册
docker <命令分组> --help # 展示docker某分组下的命令帮助手册 docker <命令组> <命令> --help # 具体命令的具体参数使用方法
命令(old) 命令(new) 说明 docker search docker search search the Docker Hub for images docker pull docker image pull pull an image docker images dockre image ls list images docker create docker container create create a new container docker start docker container start start one ore more containers docker run docker container run run a command in a new container docker attach docker container attach attach to a running container docker ps docker container ls list containers docker logs docker container logs fetch the logs of a container docker restart docker container restart restart a container docker stop docker container stop stop one or more running containers docker kill docker container kill kill one or more running containers docker rm docker container rm remove one or more containers docker version - show the version of docker client/server docker info - show the detailed information of docker
5.6 docker镜像说明
我们通过docker search nginx
查看nginx的镜像,如下
-
顶级仓库
我们能看到标注出来的
nginx
没有任何任何分隔符,直接就是应用程序名,叫做顶级仓库
,docker hub官方的仓库 -
用户/项目仓库
从名称上来看是存在分隔符的,由于docker hub是允许个人创建账号并上传自己制作的镜像,因此这种叫做
用户仓库
或者项目仓库
-
alpine版镜像说明
我们从
hub.docker.com
中查看某些应用的镜像,会发现每个应用都有不同的tag,比如stable、lastest、alpine等,其中alpine是简洁版,专门构建小的镜像文件的微型发行版,能给程序运行提供基础环境,但体积非常小;但是缺少将来可能用到的调试工具(测试可使用,生产环境不建议) -
私有仓库
自己用服务器做一个registry,可以存放常用镜像和自己制作的镜像,规避了由于网络导致的上传下载的问题
5.7 拉取镜像
- 拉取镜像文件
docker pull <registry>[:<port>]/[<namespace>/]<name>:<tag>
[root@vincent ~]# docker image pull nginx:1.14-alpine
1.14-alpine: Pulling from library/nginx
bdf0201b3a05: Pull complete
3d0a573c81ed: Pull complete
8129faeb2eb6: Pull complete
3dc99f571daf: Pull complete
Digest: sha256:485b610fefec7ff6c463ced9623314a04ed67e3945b9c08d7e53a47f6d108dc7
Status: Downloaded newer image for nginx:1.14-alpine
docker.io/library/nginx:1.14-alpine
You have mail in /var/spool/mail/root
[root@vincent ~]#
[root@vincent ~]# docker image pull busybox
Using default tag: latest
latest: Pulling from library/busybox
76df9210b28c: Pull complete
Digest: sha256:95cf004f559831017cdf4628aaf1bb30133677be8702a8c5f2994629f637a209
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest
[root@vincent ~]#
- 列出镜像文件相关信息
[root@vincent ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 1c35c4412082 3 weeks ago 1.22MB
nginx 1.14-alpine 8a2fb25a19f5 14 months ago 16MB
[root@vincent ~]#
- 镜像文件字段介绍
- RePOSITORY:仓库名称
- TAG:镜像标签
- IMAGE ID:镜像唯一标识ID
- GREATED:镜像创建时间
- SIZE:镜像文件大小
6.容器的相关操作
一般新建并运行一个容器,可以用docker container run
或 docker container create
+docker container start
-
docker container run 常见参数说明
语法格式:
docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]
参数 说明1 说明2 - t Allocate a pseudo-TTY 运行为交互式接口 - i Keep STDIN open even if not attached 交互式访问 – name str Assign a name to the container 给容器命名 – network str Connect a container to a network 指定容器网络,有默认网络 – rm Automatically remove the container when it exits 容器停止后,自动删除 - d Run container in background and print container ID 容器启动后直接运行在后台 - exec Run a command in a running container 跨越容器边界,在运行的容器中执行命令 -
docker网络
关于容器的网络,,可以通过
docker network ls
看下当前有多少网络,默认是bridge网络,默认是172.17.
网段,且是nat桥
/地址转换桥[root@vincent ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 78a835505101 bridge bridge local 38517f976413 host host local 09a904f816d0 none null local [root@vincent ~]#
docker启用之后就会默认有一个
docker0
的网络,默认地址是172.17.
段[root@vincent ~]# ip a 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 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether fa:16:3e:6e:05:b6 brd ff:ff:ff:ff:ff:ff inet 10.0.0.16/24 brd 10.0.0.255 scope global eth0 valid_lft forever preferred_lft forever 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:37:52:3a:46 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever [root@vincent ~]#
6.1 以busybox为例操作容器
-
以busybox镜像启动容器
用
busybox:latest
镜像,以交互式、带终端的方式创建并启动一个名为b1
的容器[root@vincent ~]# docker container run --name b1 -it busybox:latest
[root@vincent ~]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest 1c35c4412082 3 weeks ago 1.22MB nginx 1.14-alpine 8a2fb25a19f5 14 months ago 16MB [root@vincent ~]# [root@vincent ~]# docker container run --name b1 -it busybox:latest / # / #
用
docker container ps
查看当前容器
说明:
run命令后面跟的镜像名由
REPOSITORY
+TAG
组成;若该镜像文件在本地不存在,则会默认到网上的registory去拉取 ps命令默认仅显示运行中的容器,如果容器存在但是处于未运行/停止状态则同样不会打印出来
-
测试httpd服务
新建一个测试用的index.html文件,并写入测试的文字,然后启动httpd并服务指向该文件
/ # mkdir /home/html / # vi /home/html/index.html / # httpd -f -h /home/html/
index.html文件内容:this is a httpd by busybox in docker container test
通过
docker inspect b1
命令httpd服务的ip地址"IPAddress": "172.17.0.2"
在全局环境中,通过curl命令测试httpd服务
[root@vincent /]# curl 172.17.0.2 this is a httpd by busybox in docker container test [root@vincent /]#
-
停止b1容器
docker container stop [OPTIONS] CONTAINER [CONTAINER...]
- -t, --time int:Seconds to wait for stop before killing it (default 10)/不加则默认10s停止
[root@vincent /]# docker container stop b1 b1 [root@vincent /]#
由于busybox是一个shell进程,因此直接通过exit退出后,容器也会自动停止
/ # exit [root@vincent ~]#
用
docker container ps
查看当前容器
用docker container ps -a
查看当前容器
-
启动b1容器
docker container start [OPTIONS] CONTAINER [CONTAINER...]
- -a, --attach:Attach STDOUT/STDERR and forward signals/连接容器并打印输出或错误
- -i, --interactive:Attach container’s STDIN/启动容器并进入交互模式
[root@vincent ~]# docker container start -i -a b1 / #
说明:
若要启动的容器并非shell,而是一个nginx守护进程,不用加
-ai
直接启动即可 -
删除b1容器
删除容器,要先保证容器处于
停止状态
docker container rm [OPTIONS] CONTAINER [CONTAINER...]
[root@vincent /]# docker container rm b1 b1 [root@vincent /]#
用
docker container ps -a
查看当前容器
6.2 以nginx为例操作容器
-
以nginx镜像启动容器
因为nginx不需要交互式,因此直接后台运行该容器即可
[root@vincent ~]# docker container run --name web1 -d nginx:1.14-alpine 8832469ea98425d6367f41f239c7ca53df1d868adb0acf722eef6f2bf819d68d [root@vincent ~]#
用
docker container ps
查看当前容器
说明:
nginx -g 'daemon of...'
指定该程序不要运行在后台
。对于docker容器来说,一个容器仅能运行一个程序,如果该程序还去后台运行,则容器会认为自身内部没有程序在运行,那么容器就会自动结束因此,要注意,容器里的程序不能跑在后台,程序本身就是这个容器的骨架
-
测试nginx服务是否启动
通过
docker inspect b1
命令httpd服务的ip地址"IPAddress": "172.17.0.2"
在全局环境中,通过curl命令测试nginx服务
[root@vincent ~]# curl 172.17.0.2 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> [root@vincent ~]#
-
exec命令绕过容器边界
docker container exec [OPTIONS] CONTAINER COMMAND [ARG...]
- -i, --interactive:Keep STDIN open even if not attached
- -t, --tty:Allocate a pseudo-TTY
[root@vincent ~]# docker container exec -it web1 /bin/sh / # ps PID USER TIME COMMAND 1 root 0:00 nginx: master process nginx -g daemon off; 6 nginx 0:00 nginx: worker process 12 root 0:00 /bin/sh 17 root 0:00 ps / # / # netstat -tnl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN / #
-
查看docker容器中进程的日志
docker容器的日志默认打到工作台,而不是存到日志,可以直接通过命令查看
[root@vincent ~]# docker container logs web1 172.17.0.1 - - [27/Jun/2020:05:42:52 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-" [root@vincent ~]#
6.3 以redis为例(本地无镜像)操作容器
-
创建并启动容器
本地并没有
redis:4-alpine
镜像文件,因此默认会去网上下载[root@vincent ~]# docker run --name kvstor1 -d redis:4-alpine Unable to find image 'redis:4-alpine' locally 4-alpine: Pulling from library/redis cbdbe7a5bc2a: Pull complete dc0373118a0d: Pull complete cfd369fe6256: Pull complete 152ffd6a3b24: Pull complete 7c01860f13a3: Pull complete aa6ecacd3bee: Pull complete Digest: sha256:aaf7c123077a5e45ab2328b5ef7e201b5720616efac498d55e65a7afbb96ae20 Status: Downloaded newer image for redis:4-alpine 67c805d9bef3a0ea16033a71acb7a048dd6789409838b029d3e49de674596471 [root@vincent ~]#
用
docker container ps
查看当前容器
-
exec命令绕过容器边界
[root@vincent ~]# docker container exec -it kvstor1 /bin/sh /data # ps PID USER TIME COMMAND 1 redis 0:00 redis-server 12 root 0:00 /bin/sh 19 root 0:00 ps /data # netstat -tnl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN tcp 0 0 :::6379 :::* LISTEN /data # redis-cli -p 6379 127.0.0.1:6379> 127.0.0.1:6379> KEYS * (empty list or set) 127.0.0.1:6379> exit /data # /data # exit [root@vincent ~]#