1 安装
$ sudo yum remove docker # 移除旧版本
docker-common
docker-selinux
docker-engine
$ curl -sSL https://get.daocloud.io/docker | sh # 超时
$ sudo yum -y install docker-io
$ sudo chkconfig docker on
$ sudo docker version
Client:
Version: 1.12.6
API version: 1.24
Package version: docker-1.12.6-61.git85d7426.el7.centos.x86_64
Go version: go1.8.3
Git commit: 85d7426/1.12.6
Built: Tue Oct 24 15:40:21 2017
OS/Arch: linux/amd64
Server:
Version: 1.12.6
API version: 1.24
Package version: docker-1.12.6-61.git85d7426.el7.centos.x86_64
Go version: go1.8.3
Git commit: 85d7426/1.12.6
Built: Tue Oct 24 15:40:21 2017
OS/Arch: linux/amd64
2 使用
2.1 docker加速器
https://cr.console.aliyun.com/#/accelerator
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxx"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
docker pull hello-world # 下载
docker images # 查看
docker rmi image-id #删除
docker run --name container-name -d image-name # 运行镜像为容器
docker ps # 容器列表
docker start/stop container-name/container-id
docker logs container-name/container-id # 查看容器日志
docker rm container-id
docker pull redis # 获取redis镜像
docker run -d -p 6378:6379 --name redis6378 redis # daemon方式运行,并且映射容器的6379端口到本机的6378端口
docker在容器内所有的改动都是暂时的。docker commit
可以保存对容器的更改,将其创建为新镜像:
docker commit -m '备注信息' [容器id或者name] [新镜像名称]
进入容器
docker exec -it [容器name] env TERM=xterm-256color bash
3 管理镜像
3.1 aliyun
push到国内的托管站会比较快。
登录后首先新建命名空间
1、从本地上传镜像
$ sudo docker login --username=aliyun容器镜像用户名 registry.cn-hangzhou.aliyuncs.com
# 默认为版本号为latest,不写也行
$ sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/[容器镜像命名空间]/my-oracle-xe-11g:[镜像版本号]
$ sudo docker push registry.cn-hangzhou.aliyuncs.com/[容器镜像命名空间]/my-oracle-xe-11g:[镜像版本号]
# 例子
$ sudo docker tag f794779ccdb9 registry.cn-hangzhou.aliyuncs.com/lawlietfans/my-oracle-xe-11g:v20171130
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wnameless/oracle-xe-11g latest f794779ccdb9 7 weeks ago 2.23GB
registry.cn-hangzhou.aliyuncs.com/lawlietfans/my-oracle-xe-11g v20171130 f794779ccdb9 7 weeks ago 2.23GB
$ sudo docker push registry.cn-hangzhou.aliyuncs.com/lawlietfans/my-oracle-xe-11g:v20171130
done
查看镜像列表:https://cr.console.aliyun.com/#/imageList
另一个例子:
2、从代码源构建镜像
代码源中一定要包含Dockerfile
3.2 docker官网
$ sudo docker tag [ImageId] [docker.com用户名]/[imagename]:[镜像版本号]
$ sudo docker push [docker.com用户名]/[imagename]:[镜像版本号]
查看自己的仓库列表:
https://cloud.docker.com/app/[docker.com用户名]/repository/list
4 Docker 原理以及和 Kubernetes 关系
4.1 什么是 Docker?
Docker的英文翻译是“搬运工”的意思,他搬运的东西就是我们常说的集装箱Container,Container 里面装的是任意类型的 App,我们的开发人员可以通过 Docker 将App 变成一种标准化的、可移植的、自管理的组件,我们可以在任何主流的操作系统中开发、调试和运行。
docker架构
Docker 使用 C/S (客户端/服务器)体系的架构,Docker 客户端与 Docker 守护进程通信,Docker 守护进程负责构建,运行和分发 Docker 容器。Docker 客户端和守护进程可以在同一个系统上运行,也可以将 Docker 客户端连接到远程 Docker 守护进程。Docker 客户端和守护进程使用 REST API 通过UNIX套接字或网络接口进行通信。
其中
Docker Damon:dockerd,用来监听 Docker API 的请求和管理 Docker 对象,比如镜像、容器、网络和 Volume。
Docker Client:docker,docker client 是我们和 Docker 进行交互的最主要的方式方法,比如我们可以通过 docker run 命令来运行一个容器,然后我们的这个 client 会把命令发送给上面的 Dockerd,让他来做真正事情。
Docker Registry:用来存储 Docker 镜像的仓库,Docker Hub 是 Docker 官方提供的一个公共仓库,而且 Docker 默认也是从 Docker Hub 上查找镜像的,当然你也可以很方便的运行一个私有仓库,当我们使用 docker pull 或者 docker run 命令时,就会从我们配置的 Docker 镜像仓库中去拉取镜像,使用 docker push 命令时,会将我们构建的镜像推送到对应的镜像仓库中。
Images:镜像,镜像是一个只读模板,带有创建 Docker 容器的说明,一般来说的,镜像会基于另外的一些基础镜像并加上一些额外的自定义功能。比如,你可以构建一个基于 Centos 的镜像,然后在这个基础镜像上面安装一个 Nginx 服务器,这样就可以构成一个属于我们自己的镜像了。
Containers:容器,容器是一个镜像的可运行的实例,可以使用 Docker REST API 或者 CLI 来操作容器,容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。
底层技术支持:Namespaces(做隔离)、CGroups(做资源限制)、UnionFS(镜像和容器的分层) the-underlying-technology Docker 底层架构分析
容器进程运行于属于自己的独立的命名空间,那么这一点是怎么做到的呢?
这就涉及Linux内核中Namespace 资源隔离的原理
命名空间 (namespaces) 是 Linux 为我们提供的用于分离进程树、网络接口、挂载点以及进程间通信等资源的方法。在日常使用 Linux 或者 macOS 时,我们并没有运行多个完全分离的服务器的需要,但是如果我们在服务器上启动了多个服务,这些服务其实会相互影响的,每一个服务都能看到其他服务的进程,也可以访问宿主机器上的任意文件,这是很多时候我们都不愿意看到的,我们更希望运行在同一台机器上的不同服务能做到完全隔离,就像运行在多台不同的机器上一样。
如果要自己实现一个资源隔离的容器,应该从哪些方面下手呢?
- 也许你第一反应可能就是 chroot 命令,这条命令给用户最直观的感觉就是使用后根目录 / 的挂载点切换了,即文件系统被隔离了。
- 然后,为了在分布式的环境下进行通信和定位,容器必然需要一个独立的 IP、端口、路由等等,自然就想到了网络的隔离。
- 同时,你的容器还需要一个独立的主机名以便在网络中标识自己。
- 想到网络,顺其自然就想到通信,也就想到了进程间通信的隔离。
- 可能你也想到了权限的问题,对用户和用户组的隔离就实现了用户权限的隔离。
- 最后,运行在容器中的应用需要有自己的 PID, 自然也需要与宿主机中的 PID 进行隔离。
由此,我们基本上完成了一个容器所需要做的六项隔离,Linux 内核中就提供了这六种 namespace 隔离的系统调用,如下表所示。
Linux 内核实现 namespace 的主要目的就是为了实现轻量级虚拟化(容器)服务。在同一个 namespace 下的进程可以感知彼此的变化,而对外界的进程一无所知。这样就可以让容器中的进程产生错觉,仿佛自己置身于一个独立的系统环境中,以此达到独立和隔离的目的。
Docker 的实现依赖四大核心技术
- 命名空间 Namespaces
- 控制组 Control groups
- Union file systems or UnionFS:回答 如何构建并且存储镜像的,镜像是如何被每一个容器所使用的
- Container format: docker引擎把namespaces, control groups, UnionFS 包装起来
Linux 的命名空间和控制组分别解决了不同资源隔离的问题,前者解决了进程、网络以及文件系统的隔离,后者实现了 CPU、内存等资源的隔离,
UnionFS 其实是一种为 Linux 操作系统设计的用于把多个文件系统『联合』到同一个挂载点的文件系统服务。而 AUFS 即 Advanced UnionFS 其实就是 UnionFS 的升级版,它能够提供更优秀的性能和效率。
see also docker核心技术与实现原理
4.2 Docker和kubernetes的关系
Docker 和 Kubernetes 从听过到略懂:给程序员的旋风教程 https://juejin.im/post/5b62d0356fb9a04fb87767f5
在现实的生产环境中 Docker 本身是一个相对底层的容器引擎,在有很多服务器的集群中,我们需要 Kubernetes 这样的系统来进行任务的编排和调度。