一.理解docker
docker提供了一个开发,打包,运行APP的平台,它可以把APP和底层infrastructure隔离开来
Application | |
Docker Engine | |
infrastructure(physical / virtual) |
Docker Engine: 是一个 Client-Server 架构, 主要由三部分构成.
- 后台进程 (dockerd) : Docker daemon
- REST API Server : 一套与 Docker daemon 交互的 REST API
- CLI接口 (docker) : 一个命令行客户端
注:通过 ps -ef | grep docker 可以看到dockerd进程
Docker的总体架构:
Docker底层技术支持:
- Namespaces: 做隔离pid, net, ipc, mnt, uts
- Control groups: 做资源限制
- Union file ststems: Container和image的分层
二.Docker Image
docker image 介绍:
- 文件(rootfs) 和 meta data的集合
- 分层的,并且每一层都可以添加改变删除文件,成为一个新的image
- 不同的image可以共享相同的layer (image #2, image #4 共享Centos Image)
- Image本身是只读的
- (注: linux系统分为内核空间(bootfs,即Linux Kernel) 和 用户空间(rootfs), 在bootfs上做的一些linux发行版(ubuntu, centos, debian等) 就是rootfs,这些 linux发行版属于Base Image. Base Image 只包含rootfs,不包含bootfs,不同的base image 可以共享主机里的Linux Kernal,这就是docker比较小巧的原因. 在base image 上可以添加修改删除文件(即安装一些软件),就会产生新的一层,从而产生一个新的image)
docker image 的获取:
- 编写dockerfile,build成image
- 从registry (如 docker hub)上pull image
通过添加docker用户组,可以去掉执行docker命令时的"sudo"权限:
sudo groupadd docker //新建一个名为docker的用户组
sudo gpasswd -a vagrant docker //将用户vagrant加到docker组里
//执行完上述命令后,可能还需要重启docker服务,重新进入vagrant虚机
1>. groupadd命令:
为了方便管理,可以对一群有相近需求的用户新增一个组,groupadd命令可以实现这个功能,groupadd命令用于增加一个新组。
Usage: groupadd [options] GROUP
Options: -f, --force 强制建立已经存在的组(如果存在则返回成功)
-g, --gid GID 设置新建立组的识别码,0--499保留给系统服务,可以指定500以上的唯一数值(除非用--non-unique参数)。
-o, --non-unique 允许重复使用组识别码。
-p, --password PASSWORD 设置新组的密码
-r, --system 创建一个系统账号
例:新建立一个名为test的组
linux@cdyemail:~$ sudo groupadd test
linux@cdyemail:~$ cat /etc/group | grep test
test:x:1002:
注:/etc/group的格式
group name : password : GID : user lists
2>. gpasswd命令
gpasswd命令是Linux下工作组文件/etc/group和/etc/gshadow管理工具。
语法:gpasswd -a user_name group_name 用于将某个用户添加到某个用户组
选项:-a:添加用户到组;
-d:从组删除用户;
-A:指定管理员;
-M:指定组成员和-A的用途差不多;
-r:删除密码;
-R:限制用户登入组,只有组中的成员才可以用newgrp加入该组。
编写"Hello World!" Base Image:
1>. 创建一个目录,编写一个"Hello World"C程序,并打包成可执行的二进制文件
mkdir hello-world
cd hello-world
s
//安装vim
sudo yum install vim
vim hello.c
//hello.c 源文件
#include<stdio.h>
int main()
{
printf("Hello Docker!\n");
}
//安装编译工具gcc
sudo yum install gcc
sudu yum install glibc-static
gcc -static hello.c -o hello //-o 用于编译时指定输出名称,否则统一为a.out
2>. 将可执行c程序打包到一个dockerfile中
vim Dockerfile
//编写Dockerfile
FROM scratch //Base Image的From为scratch
ADD hello / //将可执行文件hello添加到image的根目录
CMD ["/hello"]
docker build -t crownt/hello-world . //"."表示上下文为当前目录
docker run crownt/hello-world
docker build [OPTIONS] 上下文路径|URL 用于Dockerfile 构建镜像
[OPTIONS] : -t : 指定镜像的名字及tag,
-f : 显示指定构建镜像的 Dockerfile 文件(Dockerfile 可不在当前路径下), 如果不使用 -f,则默认将上下文路径下的 名为 Dockerfile 的文件认为是构建镜像的 "Dockerfile" 。
上下文路径|URL: 指定构建镜像的上下文的路径,构建镜像的过程中,可以且只可以引用上下文中的任何文件
docker history imageID 用于查看指定镜像的创建历史
三.Docker Container
docker container概念:
- container通过image创建
- 在image layer之上建立了一个container layer (container layer是可读可写的)
- 类比面向对象:类和实例
- Image负责App的存储和分发,Container负责App的运行
docker常用命令:
docker container ls //查看container
docker container ls -a //查看所有container,包括已退出的.其中显示出的COMMAND字段,就是Dockerfile中CMD的参数
//交互式运行container的方法: 通过 -it 参数
docker run centos //运行完container就退出了
docker run -it centos //container不会立即退出,而是进入了一个可以交互的centos,可以在其中进行读写
docker image ls (docker images) //列出本地image
docker image rm imageID (docker rmi imageID) //删除image
docker container ls (docker ps) //列出本地container
docker container ls -a (docker ps -a) //列出包括退出的container
docker container rm containerID (docker rm containerID) //删除运行过的container,containerID不需要写全
docker run -d xxx //在后台运行xxx的docker服务
docker run ImageName //拉取iamge, Run a command in a new container
docker container commit //Create a new Image from a container's changes
//一些高级用法:
docker container ls -aq //列出所有container的ID
docker rm $(docker container ls -aq) //一次性删除所有container
docker container ls -f "status=exited" //列出已经退出的container
docker container ls -f "status=exited" -q //列出已经退出的container的ID
docker rm $(docker container ls -f "status=exited" -q) //删除已退出的container