1.什么是docker

要想使用linux容器,至少要在linux内核支持两种技术:namespacecgourps

我们可以在用户空间组织一些工具,利用内核提供的这些技术从而实现容器运行的目的

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
  • odoo docker 启动odoo_docker

  • 如上图,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已有程序包

odoo docker 启动odoo_docker_02

通过yum install docker-ce(1.使用默认的Extra则yum install docker;2.区分ce概念)

odoo docker 启动odoo_odoo docker 启动odoo_03


如上,安装完毕!

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的镜像,如下

odoo docker 启动odoo_套接字_04

  • 顶级仓库
    我们能看到标注出来的nginx没有任何任何分隔符,直接就是应用程序名,叫做顶级仓库,docker hub官方的仓库
  • 用户/项目仓库
    从名称上来看是存在分隔符的,由于docker hub是允许个人创建账号并上传自己制作的镜像,因此这种叫做用户仓库或者项目仓库
  • alpine版镜像说明
    我们从hub.docker.com中查看某些应用的镜像,会发现每个应用都有不同的tag,比如stable、lastest、alpine等,其中alpine是简洁版,专门构建小的镜像文件的微型发行版,能给程序运行提供基础环境,但体积非常小;但是缺少将来可能用到的调试工具(测试可使用,生产环境不建议)
  • 私有仓库
    自己用服务器做一个registry,可以存放常用镜像和自己制作的镜像,规避了由于网络导致的上传下载的问题

5.7 拉取镜像

  1. 拉取镜像文件
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 ~]#
  1. 列出镜像文件相关信息
[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 ~]#

odoo docker 启动odoo_odoo docker 启动odoo_05

  1. 镜像文件字段介绍
  • RePOSITORY:仓库名称
  • TAG:镜像标签
  • IMAGE ID:镜像唯一标识ID
  • GREATED:镜像创建时间
  • SIZE:镜像文件大小

6.容器的相关操作

一般新建并运行一个容器,可以用docker container rundocker 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查看当前容器

odoo docker 启动odoo_套接字_06

说明

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查看当前容器

odoo docker 启动odoo_nginx_07


docker container ps -a查看当前容器

odoo docker 启动odoo_odoo docker 启动odoo_08

  • 启动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查看当前容器

odoo docker 启动odoo_odoo docker 启动odoo_09

6.2 以nginx为例操作容器

  • 以nginx镜像启动容器
    因为nginx不需要交互式,因此直接后台运行该容器即可
[root@vincent ~]# docker container run --name web1 -d nginx:1.14-alpine
8832469ea98425d6367f41f239c7ca53df1d868adb0acf722eef6f2bf819d68d
[root@vincent ~]#

docker container ps查看当前容器

odoo docker 启动odoo_套接字_10

说明

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查看当前容器

odoo docker 启动odoo_nginx_11

  • 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 ~]#

7.容器状态转换图

odoo docker 启动odoo_docker_12