Docker

Docker 核心概念及入门

Posted by leone on 2018-02-18

Docker

Docker 核心概念及入门

什么是docker

Docker是一个开放源代码软件项目,让应用程序布署在软件货柜下的工作可以自动化进行,借此在Linux操作系统上,提供一个额外的软件抽象层,以及操作系统层虚拟化的自动管理机制。Docker利用Linux核心中的资源分离机制,例如cgroups,以及Linux核心名字空间(namespaces),来创建独立的容器(containers)。这可以在单一Linux实体下运作,避免启动一个虚拟机造成的额外负担。Linux核心对名字空间的支持完全隔离了工作环境中应用程序的视野,包括进程树、网络、用户ID与挂载文件系统,而核心的cgroup提供资源隔离,包括CPU、存储器、block I/O与网络。从0.9版本起,Dockers在使用抽象虚拟是经由libvirt的LXC与systemd - nspawn提供界面的基础上,开始包括libcontainer库做为以自己的方式开始直接使用由Linux核心提供的虚拟化的设施,

Docker 版本简介

Docker有两个版本:
社区版(CE)
企业版(EE)
Docker Community Edition(CE)非常适合希望开始使用Docker并尝试使用基于容器的应用程序的个人开发人员和小型团队。

Docker企业版(EE)专为企业开发和IT团队而设计,他们可以在生产中大规模构建,发布和运行业务关键型应用程序

功能 社区版 企业版基础版 企业版标准 企业版高级版
容器引擎和内置编排,网络,安全性
经过认证的基础设施,插件和ISV容器
图像管理
容器应用管理
图像安全扫描

关于容器技术的介绍及概念

  • 容器技术

Linux容器技术很早就有了,比较有名的是被集成到主流Linux内核中的LXC项目。容器通过对操作系统的资源访问进行限制,构建成独立的资源池,让应用运行在一个相对隔离的空间里,同时容器间也可以进行通信。容器技术对比虚拟化技术,容器比虚拟化更轻量级,对资源的消耗小很多。容器操作也更快捷,启动和停止都要比虚拟机快。但Docker容器需要与主机共享操作系统内核,不能像虚拟机那样运行独立的内核。
Docker是一个基于LXC技术构建的容器引擎,基于GO语言开发,遵循Apache2.0协议开源。Docker的发展得益于为使用者提供了更好的容器操作接口。包括一系列的容器,镜像,网络等管理工具,可以让用户简单的创建和使用容器。
Docker支持将应用打包进一个可以移植的容器中,重新定义了应用开发,测试,部署上线的过程,核心理念就是 Build once, Run anywhere。Docker容器技术的典型应用场景是开发运维上提供持续集成和持续部署的服务。

  • 镜像

Docker的镜像概念类似于虚拟机里的镜像,是一个只读的模板,一个独立的文件系统,包括运行容器所需的数据,可以用来创建新的容器。镜像可以基于Dockerfile构建,Dockerfile是一个描述文件,里面包含若干条命令,每条命令都会对基础文件系统创建新的层次结构。用户可以通过编写Dockerfile创建新的镜像,也可以直接从类似github的Docker Hub上下载镜像使用。

  • 容器

Docker容器是由Docker镜像创建的运行实例。Docker容器类似虚拟机,可以支持的操作包括启动,停止,删除等。每个容器间是相互隔离的,但隔离的效果比不上虚拟机。容器中会运行特定的应用,包含特定应用的代码及所需的依赖文件。
在Docker容器中,每个容器之间的隔离使用Linux的 CGroups 和 Namespaces技术实现的。其中 CGroups 对CPU,内存,磁盘等资源的访问限制,Namespaces 提供了环境的隔离。

  • 仓库

如果你使用过 git 和 github 就很容易理解Docker的仓库概念。Docker仓库相当于一个 github 上的代码库。
Docker 仓库是用来包含镜像的位置,Docker提供一个注册服务器(Registry)来保存多个仓库,每个仓库又可以包含多个具备不同tag的镜像。Docker运行中使用的默认仓库是 Docker Hub 公共仓库。仓库支持的操作类似 git,创建了新的镜像后,我们可以 push 提交到仓库,也可以从指定仓库 pull 拉取镜像到本地。

Docker有下面这些组成

1.Docker 服务器守护程序(server daemon),用于管理所有的容器。

2.Docker 命令行客户端,用于控制服务器守护程序。

3.Docker 镜像:查找和浏览 docker 容器镜像。

Docker特性

文件系统隔离:每个进程容器运行在完全独立的根文件系统里。

资源隔离:可以使用cgroup为每个进程容器分配不同的系统资源,例如CPU和内存。

网络隔离:每个进程容器运行在自己的网络命名空间里,拥有自己的虚拟接口和IP地址。

写时复制:采用写时复制方式创建根文件系统,这让部署变得极其快捷,并且节省内存和硬盘空间。

日志记录:Docker将会收集和记录每个进程容器的标准流(stdout/stderr/stdin),用于实时检索或批量检索。

变更管理:容器文件系统的变更可以提交到新的映像中,并可重复使用以创建更多的容器。无需使用模板或手动配置。

交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上,例如运行一个一次性交互shell。

images 与 Container

Container和Image 在Docker的世界里,Image是指一个只读的层(Layer),这里的层是AUFS里的概念,最直观的方式就是看一下docker官方给出的图:

Docker使用了一种叫AUFS的文件系统,这种文件系统可以让你一层一层地叠加修改你的文件,最底下的文件系统是只读的,如果需要修改文件,AUFS 会增加一个可写的层(Layer),这样有很多好处,例如不同的Container可以共享底层的只读文件系统(同一个Kernel),使得你可以跑N多 个Container而不至于你的硬盘被挤爆了!这个只读的层就是Image!而如你所看到的,一个可写的层就是Container。

那Image和Container的区别是什么?很简单,他们的区别仅仅是一个是只读的层,一个是可写的层,你可以使用docker commit 命令,将你的Container变成一个Image,也就是提交你所运行的Container的修改内容,变成一个新的只读的Image,这非常类似于git commit命令。

安装Docker(基于CentOS_7.3_x64 安装 Docker CE)

Docker 要求 CentOS 系统的内核版本高于 3.10 ,安装前需要验证 CentOS 版本是否支持 Docker。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

# 命令查看你当前的内核版本
$ uname -r

# 更新yum
$ sudo yum makecache fast

# 安装yum-utils
$ sudo yum install yum-utils

# 使用以下命令设置稳定存储库
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 卸载旧版本(如果安装过旧版本的话)
$ sudo yum remove docker docker-common docker-selinux docker-engine

# 安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2

# 安装Docker
$ sudo yum install docker-ce

# 启动、停止、重启Docker服务
$ systemctl start | stop | restart docker.service

# 设置开机启动、关闭服务
$ systemctl enable | disable docker.service

# 验证安装是否成功(有client和service两部分表示docker安装启动都成功了)
$ docker version

[root@localhost ~]# docker version
Client:
Version: 18.03.0-ce
API version: 1.37
Go version: go1.9.4
Git commit: 0520e24
Built: Wed Mar 21 23:09:15 2018
OS/Arch: linux/amd64
Experimental: false
Orchestrator: swarm

Server:
Engine:
Version: 18.03.0-ce
API version: 1.37 (minimum version 1.12)
Go version: go1.9.4
Git commit: 0520e24
Built: Wed Mar 21 23:13:03 2018
OS/Arch: linux/amd64
Experimental: false
[root@localhost ~]#

# docker通过运行hello-world 映像验证是否已正确安装。
$ sudo docker run hello-world

Docker的常用操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 搜索镜像(我这里搜索的是tomcat的镜像)
$ docker search tomcat

# 下载镜像(在搜索出来的镜像列表中选择一个下载,我这里下载的是官方提供的centos镜像,速度会有点慢,耐心等待)
$ docker pull tomcat

# 列出本机的镜像
$ docker images

# 基于image创建一个容器,运行完毕后并退出
$ docker run [centos] /bin/echo 'Hello world'

# 运行一个交互式容器,-t表示指定一个容器内的伪tty。
# -i表示创建一个交互式连接,命令运行后,将会进入shell交互式界面,可执行任意的命令.
$ docker run -t -i centos /bin/bash

# 创建一个带名字的容器
$ docker run -d --name myweb centos /bin/bash

# 开始/停止/强制停止/重启一个的容器
$ docker start/stop/kill/restart [container]

# 删除一个容器
$ docker rm [container]

# 进入容器内容
$ docker exec -it [container] /bin/bash

# 列出正在运行的容器,[-a]列出所有状态下的容器,[-l]只列出最后一个启动的容器。
$ docker ps [-a] [-l]

Docker 创建容器

Docker 创建 MySQL 容器

1
2
3
4
5
6
7
8
9

$ docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=[password] \
-v /xxx/mysql:/var/lib/mysql \
-v /etc/my.cnf:/etc/my.cnf mysql:5.7.23

# -p 3306:3306:表示在这个容器中使用3306端口(第二个)映射到本机的端口号也为3306(第一个)

Docker 创建 Redis 容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ docker run -d \
--name redis \
-p 6379:6379 \
-v /xxx/redis:/data redis redis-server \
--appendonly yes \
--requirepass "[password]"


# 参数详解
docker run \
# 端口映射 宿主机:容器
-p 6379:6379 \
# 映射数据目录 rw 为读写
-v /xxx/data:/data:rw \
# 挂载配置文件 ro 为readonly
-v /xxx/conf/redis.conf:/etc/redis/redis.conf:ro \
# 给与一些权限
--privileged=true \
# 给容器起个名字
--name redis \
# 开启数据持久化
--appendonly yes \
# deamon 运行 服务使用指定的配置文件
-d redis redis-server /xxx/conf/redis.conf

Docker 创建 nexus 容器

1
2
3
4
5
$ docker run -d \
-p 8080:8080 \
--name nexus \
-v /xxx/nexus:/var/nexus-data \
--restart=always sonatype/nexus3

Docker 创建 Jenkins 容器

1
2
3
4
5
6
$ docker run -d \
-p 8080:8080 \
-p 50000:50000 \
--name jenkins \
--privileged=true \
-v /xxx/jenkins:/var/jenkins_home jenkins

Docker 创建 GitLab 容器

1
2
3
4
5
6
7
8
9
10
11
$ docker run --detach \
--hostname 120.76.77.230 \
--publish 444:443 \
--publish 8088:8088 \
--publish 25:22 \
--name gitlab \
--restart always \
--volume /xxx/gitlab/config:/etc/gitlab \
--volume /xxx/gitlab/logs:/var/log/gitlab \
--volume /xxx/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:latest

Docker 创建 rabbitmq 容器

1
2
3
4
5
6
$ docker run -d \
--hostname localhost \
--name rabbitmq \
-p 15672:15672 \
-p 5672:5672 \
rabbitmq:3-management

Docker 安装sqlserver

1
$ docker run --name sqlserver -d -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=<YourStrong!Passw0rd>' -p 1433:1433  microsoft/mssql-server-linux:2017-latest