Docker架构
docker中的容器:lxc -> libcontainer -> runC
Docker目前有两个版本:
- docker EE:企业版
- docker CE:社区版
Docker是C/S架构,通过https协议通信。daemon可以监听在套接字之上,默认只提供unix sock文件套接字,为了安全起见。它支持ipv4,ipv6,unix sock套接字三种用户接入方式。
- Docker host运行Docker Daemon,它包含两个重要组件:
- container:容器
- image:镜像
镜像来自于registry镜像仓库,默认为docker hub镜像仓库。可下载到本地后共享给上层使用。启动容器是基于镜像而启动,为镜像创建专用的可写层。
Image存储在host本地或者公共存储中,通过http/https加载到本地才能被使用,默认使用的方式为https。
由于docker hub在fw之外,国内为了实现加速访问,维护了docker.cn或者可从阿里云、中国科技大的镜像加速。用户也可以创建自己的私有仓库。
- Docker Client
与Docker daemon交互的工具,docker命令使用docker API - Docker registies
仓库:registry
它是一个可提供镜像存储的仓库,可提供用户获取镜像的认证,并为当前可用镜像作搜索索引。
一个仓库有自己专属的名称,一般一个仓库仅存放一个应用的镜像,也就是存放同一类应用的不同版本。仓库名就是应用程序名,比如nginx。不同镜像通过添加标签的方式,来相互区分。因此,仓库名+标签才能唯一标识一个镜像。如果只给镜像名而没有标签,则默认访问最新版本的镜像,比如 nginx:stable nginx:latest
镜像(静态的)和容器(动态的,存在生命周期)的关系,如同程序和进程的关系。
Docker安装和使用
本次示例安装Docker CE,配置方法参考阿里云Docker-CE镜像。
依赖的基础环境:
- ubuntu18.04 server
- 64 bits CPU
- Linux Kernel 3.10 +
- Linux Kernel cgroups and namespaces
- Docker Daemon systemctl start docker.service
# step 1: 安装必要的一些系统工具
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# step 2: 安装GPG证书
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# Step 3: 写入软件源信息
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# Step 4: 更新并安装Docker-CE
sudo apt-get -y update
sudo apt-get -y install docker-ce
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# apt-cache madison docker-ce
# docker-ce | 17.03.1~ce-0~ubuntu-xenial | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
# docker-ce | 17.03.0~ce-0~ubuntu-xenial | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
# Step 2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.1~ce-0~ubuntu-xenial)
# sudo apt-get -y install docker-ce=[VERSION]
安装完毕后,添加docker-ce的配置文件daemon.json,指定镜像源,并添加cgroup驱动:
# vim /etc/docker/daemon.json
{
"exec-opts": ["native.cgrounpdriver=systemd"],
"registry-mirrors": ["https://jw6lqah3.mirror.aliyuncs.com","https://registry.docker-cn.com"]
}
# systemctl start docker
# docker info
...
Insecure Registries:
127.0.0.0/8
Registry Mirrors:
https://registry.docker-cn.com/
Live Restore Enabled: false
常用操作
- docker search
- docker pull
- docker images
- docker create
- docker start
- docker run
- docker attach
- docker ps
- docker logs
- docker restart
- docker stop
- docker kill
- docker rm
搜索,下载并启动一个镜像:
- 搜索镜像
root@eto:~# docker search nginx
nginx # 顶级仓库,为docker hub官方
jwilder/nginx-proxy # jwilder账号建立的仓库
- 下载镜像
root@eto:~# docker image pull nginx:stable-alpine # 下载镜像
##
Alpine镜像:体积非常小,提供基础的应用环境,可安装在不同的发行版中。测试的时候可以安装此版本,不过缺少调试工具。
最好自己编制镜像,上传到docker hub或者建立私有registry
- 启动容器
root@eto:~# docker run --name ngx1 -it nginx:stable-alpine
root@eto:~# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a4bc2485df9d nginx:stable-alpine "nginx -g 'daemon of…" 26 seconds ago Up 24 seconds 80/tcp ngx1
- 显示网络
root@eto:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
ae6de969cb96 bridge bridge local
509f1fdd50fb host host local
83fea3e78ba1 none null local
安装docker后,会默认创建docker0 桥172.17.0.1。容器会自动nat到桥上以对外通信。默认会接入到bridge中。
- 删除容器
# 优雅的停止并删除方式,可以让容器在限定期内处理数据回收
root@eto:~# docker stop ngx1
ngx1
root@eto:~# docker rm ngx1
ngx1
# 暴力删除,可能存在数据丢失
root@eto:~# docker kill ngx1
ngx1
root@eto:~# docker rm ngx1
ngx1
- 删除镜像
root@eto:~# docker image rm nginx:stable-alpine
Untagged: nginx:stable-alpine
Untagged: nginx@sha256:0a052037ddcb53c9df3845edea8787202f05e53b55ae5f7ffbe25643d7dd6442
Deleted: sha256:5fad07aba15a1047c94b9818de93093310ed1bf2db98c185f5f8486a6e53f434
Deleted: sha256:904c568586c16fae1dbeeb9ef03bae0e5fc81294e9196c2df7d9f442fbde42bc
Deleted: sha256:531743b7098cb2aaf615641007a129173f63ed86ca32fe7b5a246a1c47286028
启用一个busybox容器,并查看内部的进程。
root@eto:~# docker run --name b1 -it busybox
/ # ls
bin dev etc home proc root sys tmp usr var
/ # ps aux
PID USER TIME COMMAND
1 root 0:00 sh
7 root 0:00 ps aux
Pid为1是用户空间的总进程,如果退出sh,则容器消失。
查看容器具体信息:
# docker inspect b1
...
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
...
此时可以直接在宿主机上,和容器通信。
root@eto:~# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.049 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.051 ms
退出容器,并重新激活它:
root@eto:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6eada2ba2c29 busybox "sh" 4 minutes ago Exited (0) 6 seconds ago b1
root@eto:~# docker start -ai b1
/ #
运行一个nginx容器,并访问它,并查看它的日志。
root@eto:~# docker run --name web1 -d nginx:stable-alpine
7b77d4370b42621501eae396b1b0de927f9e21c3b065f42147fb0222dfbb6a39
root@eto:~# curl 172.17.0.2
root@eto:~# docker logs -f web1
172.17.0.1 - - [24/Apr/2020:07:31:59 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.58.0" "-"
172.17.0.1 - - [24/Apr/2020:07:33:12 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.58.0" "-"
可以用下图来总结docker的声明周期:
docker的状态机