本篇介绍在 centos7 操作系统下 docker 的安装与基本操作。

安装 docker

yum remove -y docker docker-common container-selinux docker-selinux docker-engine docker-engine-selinux && \

yum install -y yum-utils device-mapper-persistent-data lvm2 && \

yum-config-manager --enable extras && \

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo && \

yum makecache fast && \

yum install -y docker-ce

基本上是先删除之前安装过的 docker 模块,再安装一些必要的工具,添加 docker 的 yum 源,最后使用yum 安装 docker。

启动 docker 服务

systemctl start docker

停止 docker 服务

systemctl stop docker

查看 docker 基本信息

docker info
[root@localhost ~]# docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 17.06.1-ce
Storage Driver: overlay
 Backing Filesystem: xfs
 Supports d_type: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 6e23458c129b551d5c9871e5174f6b1b7f6d1170
runc version: 810190ceaa507aa2727d7ae6f4790c76ec150bd2
init version: 949e6fa
Security Options:
 seccomp
  Profile: default
Kernel Version: 3.10.0-514.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 992.7MiB
Name: localhost.localdomain
ID: PSVE:UJSY:QW2G:FE23:KFCI:FYXR:XJBX:XP6U:2TYN:P54I:QMWZ:MIZB
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

docker 基本操作

查看镜像

docker images
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              328edcd84f1b        10 days ago         193MB
[root@localhost ~]# 

当前有一个 centos 的镜像

删除所有镜像

docker rmi $(docker images -q)
[root@localhost ~]# docker rmi $(docker images -q)
Untagged: centos:latest
Untagged: centos@sha256:26f74cefad82967f97f3eeeef88c1b6262f9b42bc96f2ad61d6f3fdf544759b8
Deleted: sha256:328edcd84f1bbf868bc88e4ae37afe421ef19be71890f59b4b2d8ba48414b84d
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
[root@localhost ~]# 

centos 镜像已被删除

运行容器

docker run xxx(镜像名)
[root@localhost ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b04784fba78d: Pull complete
Digest: sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

docker run 发现本地没有名为 hello-world 的镜像, 自动从 docker hub 上拉取到本地

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              1815c82652c0        2 months ago        1.84kB

查看正在运行的容器

docker ps
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
565ebd954fd6        registry            "/entrypoint.sh /e..."   12 minutes ago      Up 12 minutes       0.0.0.0:5000->5000/tcp   peaceful_fermat
7c2b28c1c8b2        sample_img          "java -jar /data/s..."   23 minutes ago      Up 23 minutes       0.0.0.0:9000->8080/tcp   c_sample

这有2个容器在运行,ID 分别为 565ebd954fd6 和  7c2b28c1c8b2

查看所有容器

docker ps -a
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                          PORTS               NAMES
7a7386a0c148        hello-world         "/hello"            About a minute ago   Exited (0) About a minute ago                       objective_clarke

删除所有容器

docker rm $(docker ps -a -q)

从 docker hub 上面拉取一个 centos 镜像

docker pull xxx (镜像名)
docker pull centos:latest

根据Dockfile(稍后会介绍)构建镜像

docker build -t xxx(镜像名) .

根据Dockfile(稍后会介绍)构建好的镜像启动一个容器

docker run --name xxx(容器名) -d -p xxx(docker端口):xxx(程序端口) xxx(镜像名)

查看容器日志

docker logs -f xxx(容器ID)

进入正在运行的容器内部

docker exec -it xxx (容器ID) /bin/bash

提交容器

docker commit -m "注释内容" xxx(容器ID) xxx(新的镜像名)

镜像重命名

docker tag centos(原镜像名) cnetos_jdk:latest(新镜像名)

搭建私有仓库

docker pull registry
docker run -d -p 5000:5000 registry

默认情况下,会将仓库存放于容器内的/tmp/registry目录下,这样如果容器被删除,则存放于容器中的镜像也会丢失,所以我们一般情况下会指定本地一个目录挂载到容器内的/tmp/registry下

docker run -d -p 5000:5000 -v /data/registry:/tmp/registry registry

重命名镜像

[root@localhost ~]# docker tag sample_img 127.0.0.1:5000/sample_img:latest
[root@localhost ~]# docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
127.0.0.1:5000/sample_img   latest              33c863b35655        17 minutes ago      584MB
sample_img                  latest              33c863b35655        17 minutes ago      584MB
...
[root@localhost ~]# 

上传镜像到私有仓库

[root@localhost ~]# docker push 127.0.0.1:5000/sample_img
The push refers to a repository [127.0.0.1:5000/sample_img]
3935bdccc733: Pushed
0dd42e651e88: Pushed
b36ecdce0393: Pushed
b362758f4793: Pushed
latest: digest: sha256:605d2cade53a657e32e1fc33e483c81591e1e8afb85e4ce0deefac54e94206c8 size: 1161

检查仓库镜像

curl 127.0.0.1:5000/v2/_catalog
[root@localhost ~]# curl 127.0.0.1:5000/v2/_catalog
{"repositories":["sample_img"]}

下次用到的话可以直接从本地镜像下载,不必再去 docker hub 上面下载。

如遇到 类似的问题

http: server gave HTTP response to HTTPS client

在 /etc/docker/ 目录下,创建 daemon.json 文件。在文件中写入:

{ "insecure-registries":["127.0.0.1:5000"] }

保存退出后,重启docker

注意:因为某种原因 docker 私有仓库没有删除镜像的功能。当前时间是 2017-08-22, docker 版本是 17.06.1-ce,不知道以后会不会添加这个功能。

导出容器

docker export xxx(容器ID) > xxx.tar

导入容器

docker import - xxx.tar

导出镜像

docker save xxx(镜像ID) > xxx.tar

导入镜像

docker load < xxx.tar

下面演示使用 docker 启动一个 spring boot 应用

使用 Dockerfile 创建一个镜像。在任意目录创建一个 Dockerfile

vi dockerfile

输入以下内容

FROM centos:latest

LABEL author="mike" version="1.0"

ENV JAVA_HOME /data/jdk1.8.0_131
ENV PATH $JAVA_HOME/bin:$PATH
ENV TZ Asia/Shanghai

ADD sample.jar /data/
ADD jdk-8u144-linux-x64.tar.gz /data/

RUN cp /usr/share/zoneinfo/$TZ /etc/localtime

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "/data/sample.jar"]

FROM centos:latest 先检索本地有没有名字为 centos 标签为 latest 的镜像,如果没有检测到会去 docker hub 上面拉取镜像到本地。命令等同于 docker pull centos:latest, 镜像名后面不加标签默认拉取最新的版本(latest),否则拉取指定版本的镜像。例如我还可以拉取 centos:6 centos:6.9 ubuntu:16.04 之类的版本的镜像。

LABEL author="mike" version="1.0" 添加 author, version 变量。

ENV JAVA_HOME /data/jdk1.8.0_131 设置 JAVA_HOME 环境变量

ENV PATH $JAVA_HOME/bin:$PATH 设置 PATH 环境变量

ENV TZ Asia/Shanghai 设置时区环境变量

ADD sample.jar /data/ 添加 spring boot 应用到 docker 容器内部 /data/ 文件夹

ADD jdk-8u144-linux-x64.tar.gz /data/ 添加 jdk1.8 到 docker 容器内部 /data/ 文件夹

RUN cp /usr/share/zoneinfo/$TZ /etc/localtime 复制宿主机的时区到 docker 容器内(解决 docker 内部时间和宿主机不一致的问题)

EXPOSE 8080 docker 内部暴露 8080 端口, 实际为 spring boot 启动的端口号

ENTRYPOINT ["java", "-jar", "/data/sample.jar"] 程序入口,启动 docker 容器的时候实际执行的是这里的命令

具体关于 Dockerfile 如何使用,官网上面提供了详细的教程。有兴趣可以仔细看下。(https://docs.docker.com/engine/reference/builder/)

构建镜像, jdk 和 sample.jar 必须和 Dockerfile 放在同一个目录下

docker build -t sample_img .
[root@localhost ~]# docker build -t sample_img .
Sending build context to Docker daemon  200.8MB
Step 1/10 : FROM centos:latest
 ---> 328edcd84f1b
Step 2/10 : LABEL author "mike" version "1.0"
 ---> Using cache
 ---> 296971e5a18b
Step 3/10 : ENV JAVA_HOME /data/jdk1.8.0_131
 ---> Using cache
 ---> adbafff9ec20
Step 4/10 : ENV PATH $JAVA_HOME/bin:$PATH
 ---> Using cache
 ---> a82606788be7
Step 5/10 : ENV TZ Asia/Shanghai
 ---> Using cache
 ---> ecdbca9ad394
Step 6/10 : ADD sample.jar /data/
 ---> 2eb7bf1d4518
Removing intermediate container bd8c795f540c
Step 7/10 : ADD jdk-8u144-linux-x64.tar.gz /data/
 ---> a28d4094a526
Removing intermediate container f2915c259563
Step 8/10 : RUN cp /usr/share/zoneinfo/$TZ /etc/localtime
 ---> Running in 989ba6843fb9
 ---> 18caa6df7026
Removing intermediate container 989ba6843fb9
Step 9/10 : EXPOSE 8080
 ---> Running in 184105d158a2
 ---> 6ba63148d968
Removing intermediate container 184105d158a2
Step 10/10 : ENTRYPOINT java -jar /data/sample.jar
 ---> Running in a91fae2179ff
 ---> 6debaae62f6d
Removing intermediate container a91fae2179ff
Successfully built 6debaae62f6d
Successfully tagged sample_img:latest

查看镜像可以看到 sample_img 已经生成

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
sample_img          latest              6debaae62f6d        22 seconds ago      584MB
centos              latest              328edcd84f1b        10 days ago         193MB
hello-world         latest              1815c82652c0        2 months ago        1.84kB

启动容器

[root@localhost ~]# docker run --name c_sample -d -p 9000:8080 sample_img
7c2b28c1c8b24a5423e65851b6fc851d96ecdd9fdc4edc2d493023eab4ce4526

docker run 运行容器命令

--name 指定容器名是 c_sample

-d 后台运行

-p 指定容器的 8080 端口对外映射到 9000 端口 

sample_img 镜像名

查看容器

[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
7c2b28c1c8b2        sample_img          "java -jar /data/s..."   31 seconds ago      Up 30 seconds       0.0.0.0:9000->8080/tcp   c_sample

容器在 31 秒前创建

查看容器日志

docker logs -f 7c2b
docker logs -f 7c2b28c1c8b2
docker logs -f c_sample

以上3个命令等价,可以通过容器ID或者容器的名字或者容器ID前4位查看。

[root@localhost ~]# docker logs -f c_sample

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.4.RELEASE)

2017-08-14 15:32:40.334  INFO 1 --- [           main] com.ccm.Application                      : Starting Application on 7c2b28c1c8b2 with PID 1 (/data/sample.jar started by root in /)
2017-08-14 15:32:40.343  INFO 1 --- [           main] com.ccm.Application                      : No active profile set, falling back to default profiles: default
2017-08-14 15:32:40.559  INFO 1 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@4b9af9a9: startup date [Mon Aug 14 15:32:40 CST 2017]; root of context hierarchy
2017-08-14 15:32:44.999  INFO 1 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2017-08-14 15:32:45.037  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2017-08-14 15:32:45.048  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.15
2017-08-14 15:32:45.354  INFO 1 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2017-08-14 15:32:45.355  INFO 1 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 4806 ms
....

docker logs -f 效果等同于 linux 中 tail -f

进入容器内部

[root@localhost ~]# docker exec -it c_sample /bin/bash
[root@7c2b28c1c8b2 /]#

可以看到 /data/下面是我们刚才添加的文件

[root@7c2b28c1c8b2 /]# ll /data/
total 14932
drwxr-xr-x. 8   10  143      255 Aug 14 15:31 jdk1.8.0_144
-rw-r--r--. 3 root root 15287879 Aug 14 15:18 sample.jar
[root@7c2b28c1c8b2 /]#

测试容器是否启动成功

bingaos-MacBook-Pro:Desktop bingao$ curl -i http://192.168.0.106:9000/hello
HTTP/1.1 200
Content-Type: text/plain;charset=ISO-8859-1
Content-Length: 12
Date: Mon, 14 Aug 2017 07:50:46 GMT

Hello World!bingaos-MacBook-Pro:Desktop bingao$

对 9000 端口(我们刚才设置的)发送了 /hello 请求,成功返回 Hello World!

03-15 20:37