docker初识

一、docker的三点好处

  • 统一环境和配置:想想平时怎么迁移服务。
  • 高效伸缩性:想想平时怎么扩容
  • 资源隔离(使用lxc):想想单机多部署。

二、docker在linux上安装方法

为了简单(非生产环境),使用yum进行安装。

所有安装的前提是内核版本要在大于等于3.10

1
2
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# uname -r
3.10.0-693.2.2.el7.x86_64

1.更新yum

1
yum update

2.添加yum仓库

1
2
3
4
5
6
7
8
$ tee /etc/yum.repos.d/docker.repo <<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF

3.安装docker

1
yum install -y docker-engine

但实际生产过程中,不一定要安装最新版本,可以通过如下方式获取现有的版本。

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
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# yum list docker-engine.x86_64 --showduplicates | sort -r
已加载插件:fastestmirror
已安装的软件包
可安装的软件包
Loading mirror speeds from cached hostfile
docker-engine.x86_64 1.9.1-1.el7.centos dockerrepo
docker-engine.x86_64 1.9.0-1.el7.centos dockerrepo
docker-engine.x86_64 1.8.3-1.el7.centos dockerrepo
docker-engine.x86_64 1.8.2-1.el7.centos dockerrepo
docker-engine.x86_64 1.8.1-1.el7.centos dockerrepo
docker-engine.x86_64 1.8.0-1.el7.centos dockerrepo
docker-engine.x86_64 1.7.1-1.el7.centos dockerrepo
docker-engine.x86_64 17.05.0.ce-1.el7.centos dockerrepo
docker-engine.x86_64 17.05.0.ce-1.el7.centos @dockerrepo
docker-engine.x86_64 17.04.0.ce-1.el7.centos dockerrepo
docker-engine.x86_64 17.03.1.ce-1.el7.centos dockerrepo
docker-engine.x86_64 17.03.0.ce-1.el7.centos dockerrepo
docker-engine.x86_64 1.7.0-1.el7.centos dockerrepo
docker-engine.x86_64 1.13.1-1.el7.centos dockerrepo
docker-engine.x86_64 1.13.0-1.el7.centos dockerrepo
docker-engine.x86_64 1.12.6-1.el7.centos dockerrepo
docker-engine.x86_64 1.12.5-1.el7.centos dockerrepo
docker-engine.x86_64 1.12.4-1.el7.centos dockerrepo
docker-engine.x86_64 1.12.3-1.el7.centos dockerrepo
docker-engine.x86_64 1.12.2-1.el7.centos dockerrepo
docker-engine.x86_64 1.12.1-1.el7.centos dockerrepo
docker-engine.x86_64 1.12.0-1.el7.centos dockerrepo
docker-engine.x86_64 1.11.2-1.el7.centos dockerrepo
docker-engine.x86_64 1.11.1-1.el7.centos dockerrepo
docker-engine.x86_64 1.11.0-1.el7.centos dockerrepo
docker-engine.x86_64 1.10.3-1.el7.centos dockerrepo
docker-engine.x86_64 1.10.2-1.el7.centos dockerrepo
docker-engine.x86_64 1.10.1-1.el7.centos dockerrepo
docker-engine.x86_64 1.10.0-1.el7.centos dockerrepo

然后在去安装,例如:

1
yum install -y docker-engine-1.8.3

4.启动docker

1
systemctl start docker.service

5.验证安装成功(客户端和服务端)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# docker version
Client:
Version: 17.05.0-ce
API version: 1.29
Go version: go1.7.5
Git commit: 89658be
Built: Thu May 4 22:06:25 2017
OS/Arch: linux/amd64
Server:
Version: 17.05.0-ce
API version: 1.29 (minimum version 1.12)
Go version: go1.7.5
Git commit: 89658be
Built: Thu May 4 22:06:25 2017
OS/Arch: linux/amd64
Experimental: false

6.卸载docker

  • 卸载docker软件包
1
yum -y remove docker-engine
  • 删除镜像、容器、卷以及自定义配置:
1
rm -rf /var/lidb/docker

三、docker的三个重要概念

  • Build: 构建,例如java项目,将tomcat + war包 + jdk(tomcat的docker会包含jdk)通过dockerfile构建在一起成为镜像
  • Ship: 集装箱,用于存储镜像,仓库有中央的(例如官方的nginx,redis,memcached, tomcat等等),私有仓库(例如公司的项目)
  • Container: 容器,可以认为是运行镜像的地方,容器实际是一个进程,进程之间彼此使用lxc进行隔离。

四、快速使用

1.从仓库下载镜像

仓库有国内外的,例如官网、阿里云、网易等

例如下载redis

1
docker pull redis

会下载最新版本的redis,如果需要下载指定版本的redis,可以用

1
docker pull redis:3.0.7

使用docker images可以查看当前机器拥有的镜像,例如当前:

1
2
3
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest c3eb149853f0 24 hours ago 107MB
  • REPOSITORY是镜像名
  • TAG是版本
  • IMAGE ID是镜像id

2.启动容器

例如启动redis,-d代表守护进程方式启动

1
2
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# docker run -d redis
7cce96da80a64c2575c28e0aeccc686f4b7b195790a76726e0343b882902b66e

docker ps可以看到所有的docker进程

1
2
3
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7cce96da80a6 redis "docker-entrypoint..." 31 seconds ago Up 31 seconds 6379/tcp elastic_brahmagupta

但是在进程外通过redis-cli是无法连接到redis的

1
2
3
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
Could not connect to Redis at 127.0.0.1:6379: Connection refused

而且netstat也看到6379端口

1
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# netstat -ant | grep 6379

这是因为宿主机和容器的端口是隔离的,容器的端口是虚拟的,宿主机需要做端口映射,要执行命令可以用两种方法

(1) 使用docker exec进入容器内部执行

1
2
3
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# docker exec -it 7cce96da80a6 redis-cli
127.0.0.1:6379> set hello world
OK
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# docker exec --help
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
Run a command in a running container
Options:
-d, --detach Detached mode: run command in the background
--detach-keys string Override the key sequence for detaching a container
-e, --env list Set environment variables
--help Print usage
-i, --interactive Keep STDIN open even if not attached
--privileged Give extended privileges to the command
-t, --tty Allocate a pseudo-TTY
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])

(2) 启动的时候做好端口映射

1
2
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# docker run -d -p 6380:6379 redis:3.0.7
606fd0bf0e2f72264025ebcf4909a1598a06060c2cf54939e3baec3a9a4d7726

-p 宿主机端口:容器端口

1
2
3
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# redis-cli -p 6380
127.0.0.1:6380> get hello
"world"

3.停止容器

1
docker stop ${containId}

或者

1
docker kill ${containId}

五、构建自己的镜像

构建一个spring boot的docker

1.准备jdk镜像

1
docker pull java:8u111-jdk

2.准备一个spring-boot带controller的jar包

1
mvn clean compile install

生成

3.编写dockerfile

1
2
3
FROM java
ADD spring-boot-docker-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

4.构建

将spring-boot-docker-0.0.1-SNAPSHOT.jar和Dockerfile放在一个目录

1
2
3
4
5
6
7
8
9
10
11
12
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# docker build -t spring-boot-docker-hello:1.0 .
Sending build context to Docker daemon 14.54MB
Step 1/3 : FROM java
---> d23bdf5b1b1b
Step 2/3 : ADD spring-boot-docker-0.0.1-SNAPSHOT.jar app.jar
---> Using cache
---> f9789f56d0fb
Step 3/3 : ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar /app.jar
---> Using cache
---> 8f553e152298
Successfully built 8f553e152298
Successfully tagged spring-boot-docker-hello:1.0

5.运行和测试

1
2
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# docker run -d -p 8888:8080 spring-boot-docker-hello:1.0
46b1cba713ed40015cadb7122a0fd55b3cc53507777e2f3f1d3eb66765366021

宿主机测试

1
2
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# curl "http://localhost:8888/hello"
hello docker and spring-boot

容器测试

1
2
[root@iZ2ze0ay4bt2m4mafbw5euZ ~]# docker exec -it 46b1cba713ed curl "http://localhost:8080/hello"
hello docker and spring-boot

五、docker工作流

1. 宿主机:

  • Docker deamon: 运行在宿主机的后台进程。
    • 用于接收客户端命令
    • 从仓库拉去镜像
  • Container: 运行镜像
  • images: 本地镜像

2. 客户端:

发送各种docker命令给Docker deamon。

3. 仓库:

存放镜像,概念和maven很类似,也可以划分本地仓库和中央仓库。

六、总结

本文只是简单了解了docker的部署和使用,实际生产过程中还有很多复杂的用法、配置等。但是docker确实解决第一节提到的三个问题,还是很值得学习的。