Docker 基础介绍与微服务应用
Docker简介
Docker是一个开源的容器引擎,它有助于更快地交付应用。 Docker可将应用程序和基础设施层隔离,并且能将基础设施当作程序一样进行管理。使用 Docker可更快地打包、测试以及部署应用程序,并可以缩短从编写到部署运行代码的周期。
Docker的优点如下:
- 简化程序
Docker 让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,便可以实现虚拟化。Docker改变了虚拟化的方式,使开发者可以直接将自己的成果放Docker中进行管理。方便快捷已经是Docker的最大优势,过去需要用数天乃至数周的 任务,在Docker容器的处理下,只需要数秒就能完成。
- 简化部署
Docker 镜像中包含了运行环境和配置,所以 Docker 可以简化部署多种应用实例工作。比如 Web 应用、后台应用、数据库应用、大数据应用比如 Hadoop 集群、消息队列等等都可以打包成一个镜像部署。
- 降低成本
一方面,云计算时代到来,使开发者不必为了追求效果而配置高额的硬件Docker 改变了高性能必然高价格的思维定势。Docker 与云的结合,让云空间得到更充分的利用。不仅解决了硬件管理的问题,也改变了虚拟化的方式。
Docker相关概念:
- Docker daemon( Docker守护进程)
Docker daemon是一个运行在宿主机( DOCKER-HOST)的后台进程。可通过
Docker客户端与之通信。
- Client( Docker客户端)
Docker客户端是 Docker的用户界面,它可以接受用户命令和配置标识,并Docker daemon通信。docker build等都是 Docker的相关命令。
- Images( Docker镜像)
Docker镜像是一个只读模板,它包含创建 Docker容器的说明。它和系统安装光盘有点像,使用系统安装光盘可以安装系统,同理,使用Docker镜像可以运行 Docker镜像中的程序。
- Container(容器)
容器是镜像的可运行实例。镜像和容器的关系有点类似于面向对象中,类和对象的关系。可通过 Docker API或者 CLI命令来启停、移动、删除容器。
- Registry
Docker Registry是一个集中存储与分发镜像的服务。构建完 Docker镜像后,就可在当前宿主机上运行。但如果想要在其他机器上运行这个镜像,就需要手动复制。此时可借助 Docker Registry来避免镜像的手动复制。一个 Docker Registry可包含多个 Docker仓库,每个仓库可包含多个镜像标签,每个标签对应一个 Docker镜像。这跟 Maven的仓库有点类似,如果把 Docker Registry比作 Maven仓库的话,那么Docker仓库就可理解为某jar包的路径,而镜像标签则可理解为jar包的版本号。
Docker 的安装
Docker 是一个开源的商业产品,有两个版本:社区版(Community Edition,缩写为
CE)和企业版(Enterprise Edition,缩写为 EE)。企业版包含了一些收费服务,个人开发者一般用不到。下面的介绍都针对社区版。
Docker CE 的安装请参考官方文档。
下面以CentOS为例安装Docker。
1、Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker 。
通过 uname -r 命令查看你当前的内核版本
[root@node-100 software]# uname -r
3.10.0-327.el7.x86_64
2、使用 root 权限登录 Centos。确保 yum 包更新到最新。
[root@node-100 software]# yum -y update
3、卸载旧版本(如果安装过旧版本的话)
[root@node-100 software]# yum remove docker docker-common docker-selinux docker-engine
4、安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是
devicemapper驱动依赖的
[root@node-100 software]# yum install -y yum-utils device-mapper-persistent-data lvm2
5、设置yum源
[root@node-100 software]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
6、可以查看所有仓库中所有docker版本,并选择特定版本安装
[root@node-100 software]# yum list docker-ce --showduplicates | sort -r
7、安装docker,#由于repo中默认只开启stable仓库,故这里安装的是最
新稳定版18.03.1
[root@node-100 software]# sudo yum install docker-ce-18.03.1.ce
安装完毕:
已安装:
docker-ce.x86_64 0:18.03.1.ce-1.el7.centos
作为依赖被安装:
audit-libs-python.x86_64 0:2.8.4-4.el7 checkpolicy.x86_64 0:2.5-8.el7 container-selinux.noarch 2:2.74-1.el7 libcgroup.x86_64 0:0.41-20.el7
libsemanage-python.x86_64 0:2.5-14.el7 libtool-ltdl.x86_64 0:2.4.2-22.el7_3 pigz.x86_64 0:2.3.3-1.el7.centos policycoreutils-python.x86_64 0:2.5-29.el7_6.1
python-IPy.noarch 0:0.75-6.el7 setools-libs.x86_64 0:3.3.8-4.el7
完毕!
8、启动并加入开机启动
[root@node-100 software]# systemctl start docker
[root@node-100 software]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
[root@node-100 software]#
9、验证安装是否成功(有client和service两部分表示docker安装启动都成功了)
[root@node-100 software]# docker version
Client:
Version: 18.03.1-ce
API version: 1.37
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:20:16 2018
OS/Arch: linux/amd64
Experimental: false
Orchestrator: swarm
Server:
Engine:
Version: 18.03.1-ce
API version: 1.37 (minimum version 1.12)
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:23:58 2018
OS/Arch: linux/amd64
Experimental: false
[root@node-100 software]#
10、卸载docker(如有需要)
yum -y remove docker-engine
注意:需要配置镜像加速器
我们可以借助阿里云的镜像加速器,登录阿里云
https://cr.console.aliyun.com/cn-hangzhou/mirrors
登录后可以在容器镜像服务中找到镜像加速器
然后再操作文档中找到如下内容
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://1glxkz12.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
然后根据上面显示的,一步步执行
sudo mkdir -p /etc/docker
cd /etc/docker
vim daemon.json
新增
{
"registry-mirrors": ["https://1glxkz12.mirror.aliyuncs.com"]
}
wq保存 然后重启
sudo systemctl daemon-reload
sudo systemctl restart docker
Docker常用命令
镜像相关命令
1、搜索镜像
可使用 docker search命令搜索存放在 Docker Hub中的镜像。
docker search java
执行该命令后, Docker就会在Docker Hub中搜索含有 java这个关键词的镜像仓库。
[root@node-100 docker]# docker search java
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
node Node.js is a JavaScript-based platform for s… 7028 [OK]
tomcat Apache Tomcat is an open source implementati… 2283 [OK]
java Java is a concurrent, class-based, and objec… 1946 [OK]
openjdk OpenJDK is an open-source implementation of … 1509 [OK]
ghost Ghost is a free and open source blogging pla… 926 [OK]
anapsix/alpine-java Oracle Java 8 (and 7) with GLIBC 2.28 over A… 389 [OK]
jetty Jetty provides a Web server and javax.servle… 288 [OK]
couchdb CouchDB is a database that uses JSON for doc… 261 [OK]
ibmjava Official IBM® SDK, Java Technology Edition … 64 [OK]
groovy Apache Groovy is a multi-faceted language fo… 62 [OK]
lwieske/java-8 Oracle Java 8 Container - Full + Slim - Base… 43 [OK]
cloudbees/jnlp-slave-with-java-build-tools Extends cloudbees/java-build-tools docker im… 25 [OK]
zabbix/zabbix-java-gateway Zabbix Java Gateway 16 [OK]
frekele/java docker run --rm --name java frekele/java 13 [OK]
davidcaste/alpine-java-unlimited-jce Oracle Java 8 (and 7) with GLIBC 2.21 over A… 11 [OK]
blacklabelops/java Java Base Images. 8 [OK]
fabric8/s2i-java S2I Builder Image for plain Java applications 7
rightctrl/java Oracle Java 3 [OK]
appuio/s2i-maven-java S2I Builder with Maven and Java 2 [OK]
cfje/java-test-applications Java Test Applications CI Image 1
cfje/java-resource Java Concourse Resource 1
cfje/java-buildpack Java Buildpack CI Image 1
appuio/s2i-gradle-java S2I Builder with Gradle and Java 1 [OK]
thingswise/java-docker Java + dcd 0 [OK]
cfje/cf-java-client Cloud Foundry Java Client CI Image 0
以上列表包含五列,含义如下:
- NAME:镜像仓库名称。
- DESCRIPTION:镜像仓库描述。
- STARS:镜像仓库收藏数,表示该镜像仓库的受欢迎程度,类似于 GitHub的stars0
- OFFICAL:表示是否为官方仓库,该列标记为[0K]的镜像均由各软件的官方项目组创建和维护。
- AUTOMATED:表示是否是自动构建的镜像仓库。
2、下载镜像
使用命令docker pull命令即可从 Docker Registry上下载镜像
docker pull java:8
执行该命令后,Docker会从 Docker Hub中的 java仓库下载最新版本的 Java镜像。如果要下载指定版本则在java后面加冒号指定版本,例如:docker pull java:8
3、列出镜像
[root@node-100 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
以上列表含义如下
- REPOSITORY:镜像所属仓库名称。
- TAG:镜像标签。默认是 latest,表示最新。
- IMAGE ID:镜像 ID,表示镜像唯一识。
- CREATED:镜像创建时间。
- SIZE: 镜像大小。
4、删除本地
使用 docker rmi命令即可删除指定镜像
docker rmi java
容器相关命令
1、新建并启动容器
使用以下docker run命令即可新建并启动一个容器,该命令是最常用的命令,它有很多选项,下面将列举一些常用的选项。
-d选项:表示后台运行
-P选项:随机端口映射
-p选项:指定端口映射,有以下四种格式。
-- ip:hostPort:containerPort
-- ip::containerPort
-- hostPort:containerPort
-- containerPort
--net选项:指定网络模式,该选项有以下可选参数:
--net=bridge:默认选项,表示连接到默认的网桥。
--net=host:容器使用宿主机的网络。
--net=container:NAME-or-ID:告诉 Docker让新建的容器使用已有容器的网络配置。
--net=none:不配置该容器的网络,用户可自定义网络配
例如:
docker run -d -p 91:80 nginx
这样就能启动一个 Nginx容器。
docker run添加了两个参数,含义如下:
-d 后台运行
-p 宿主机端口:容器端口 #开放容器端口到宿主机端口
访问 http://192.168.5.100:91/,将会看到nginx的主界面如下:
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.
Thank you for using nginx.
需要注意的是,使用 docker run命令创建容器时,会先检查本地是否存在指定镜像。如果本地不存在该名称的镜像Docker就会自动从 Docker Hub下载镜像并启动一个 Docker容器。
[root@node-100 docker]# docker run -d -p 91:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
6ae821421a7d: Pull complete
da4474e5966c: Pull complete
eb2aec2b9c9f: Pull complete
Digest: sha256:dd2d0ac3fff2f007d99e033b64854be0941e19a2ad51f174d9240dda20d9f534
Status: Downloaded newer image for nginx:latest
6b3eead5d213dd274b92256965063557b1d7e5b55e273de08711ce1cb42debc7
[root@node-100 docker]#
2、列出容器
用 docker ps命令即可列出运行中的容器
[root@node-100 docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6b3eead5d213 nginx "nginx -g 'daemon of…" 2 minutes ago Up About a minute 0.0.0.0:91->80/tcp admiring_nobel
[root@node-100 docker]#
如需列出所有容器(包括已停止的容器),可使用-a参数。该列表包含了7列,含义如下
- CONTAINER_ID:表示容器 ID。
- IMAGE:表示镜像名称。
- COMMAND:表示启动容器时运行的命令。
- CREATED:表示容器的创建时间。
- STATUS:表示容器运行的状态。UP表示运行中, Exited表示已停止。
- PORTS:表示容器对外的端口号。
- NAMES:表示容器名称。该名称默认由 Docker自动生成,也可使用 docker run命令的--name选项自行指定。
3、停止容器
使用 docker stop命令,即可停止容器
[root@node-100 docker]# docker stop 6b3eead5d213
6b3eead5d213
[root@node-100 docker]#
其中6b3eead5d213是容器 ID,当然也可使用 docker stop容器名称来停止指定容器
4、强制停止容器
可使用 docker kill命令发送 SIGKILL信号来强制停止容器
[root@node-100 docker]# docker kill 6b3eead5d213
5、启动已停止的容器
使用docker run命令,即可新建并启动一个容器。对于已停止的容器,可使用 docker
start命令来启动
[root@node-100 docker]# docker start 6b3eead5d213
6b3eead5d213
[root@node-100 docker]#
6、查看容器所有信息
[root@node-100 docker]# docker inspect 6b3eead5d213
7、查看容器日志
[root@node-100 docker]# docker container logs 6b3eead5d213
192.168.5.1 - - [16/Feb/2019:10:14:57 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)" "-"
2019/02/16 10:14:58 [error] 5#5: *3 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.5.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.5.100:91"
192.168.5.1 - - [16/Feb/2019:10:14:58 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)" "-"
[root@node-100 docker]#
8、查看容器里的进程
[root@node-100 docker]# docker top 6b3eead5d213
UID PID PPID C STIME TTY TIME CMD
root 39956 39944 0 18:21 ? 00:00:00 nginx: master process nginx -g daemon off;
101 39984 39956 0 18:21 ? 00:00:00 nginx: worker process
[root@node-100 docker]#
9、进入容器
使用docker container exec命令用于进入一个正在运行的docker容器。如果docker run命令运行容器的时候,没有使用-it参数,就要用这个命令进入容器。一旦进入了容器,就可以在容器的 Shell 执行命令了
[root@node-100 docker]# docker container exec -it 6b3eead5d213 /bin/bash
root@6b3eead5d213:/# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
root@6b3eead5d213:/#
exit退出
10、删除容器
使用 docker rm命令即可删除指定容器
[root@node-100 docker]# docker rm 6b3eead5d213
该命令只能删除已停止的容器,如需删除正在运行的容器,可使用-f参数
将微服务运行在docker上
使用Dockerfile构建Docker镜像
Dockerfile是一个文本文件,其中包含了若干条指令,指令描述了构建镜像的细节先来编写一个最简单的Dockerfile,以上文下载的Nginx镜像为例,来编写一Dockerfile修改该nginx镜像的首页
新建一个目录
mkdir -p /usr/local/docker/app
cd /usr/local/docker/app
新建文件
vim Dockerfile
添加以下两行内容
from nginx
run echo '<h1>this is my nginx!</h1>' > /usr/share/nginx/html/index.html
该Dockerfile非常简单,其中的 FORM、 RUN都是 Dockerfile的指令。 FROM指令用于指定基础镜像, RUN指令用于执行命令。
在Dockerfile所在路径执行以下命令构建镜像:
[root@node-100 app]# docker build -t nginx:demo .
Sending build context to Docker daemon 2.048kB
Step 1/2 : from nginx
---> f09fe80eb0e7
Step 2/2 : run echo '<h1>this is my nginx!</h1>' > /usr/share/nginx/html/index.html
---> Running in 20dda34eb953
Removing intermediate container 20dda34eb953
---> a838995d130c
Successfully built a838995d130c
Successfully tagged nginx:demo
[root@node-100 app]#
其中,-t指定镜像名字,命令最后的点(.)表示Dockerfile文件所在路径
执行以下命令,即可使用该镜像启动一个 Docker容器
[root@node-100 app]# docker run -d -p 92:80 nginx:demo
0134ab93afa5dee00097e67bf02a7f13c8a8081418d030ef93eabda0bcc7f5cc
访问http://192.168.5.100:92/ 进行查看,显示如下
this is my nginx!
Dockerfile常用指令
命令 | 描述 | |
---|---|---|
FROM | 基础镜像文件 | |
RUN | 构建镜像阶段执行命令ADD <src> <dest> | 添加文件,从src目录复制文件到容器的dest,其中 src可以是Dockerfile所在目录的相对路径,也可以是一个 URL,还可以是一个压缩包 |
COPY | 拷贝文件,和ADD命令类似,但不支持URL和压缩包 | |
CMD | 容器启动后执行命令 | |
EXPOSE | 声明容器在运行时对外提供的服务端口 | |
WORKDIR | 指定容器工作路径 | |
ENV | 指定环境变量 | |
ENTRYPINT | 容器入口, ENTRYPOINT和 CMD指令的目的一样,都是指定Docker容器启动时执行的命令,可多次设置,但只有最后一个有效。 | |
USER | 该指令用于设置启动镜像时的用户或者 UID,写在该指令后的 RUN、CMD以及ENTRYPOINT指令都将使用该用户执行 | |
VOLUME | 指定挂载点,该指令使容器中的一个目录具有持久化存储的功能,该目录可被容器本身使用,也可共享给其他容器。当容器中的应用有持久化数据的需求时可以在 Dockerfile中使用该指令。格式为:VOLUME["/data"]。 |
注意:
RUN命令在 image 文件的构建阶段执行,执行结果都会打包进入 image 文件;
CMD命令则是在容器启动后执行。另外,一个 Dockerfile 可以包含多个RUN命令,但是只能有一个CMD命令。注意,指定了CMD命令以后,docker container run命令就不能附加命令了(比如前面
的/bin/bash),否则它会覆盖CMD命令
使用Dockerfile构建微服务镜像
为了方便,去 https://start.spring.io/
创建一个简单的SpringBoot项目,maven编译成jar
下面开始将可运行jar包构建成docker镜像
创建一个测试目录
[root@node-100 docker]# mkdir springboot
[root@node-100 docker]# cd springboot/
[root@node-100 springboot]# pwd
/usr/local/docker/springboot
[root@node-100 springboot]#
上传jar包到该目录,在jar包所在目录创建名为Dockerfile的文件
[root@node-100 springboot]# vim Dockerfile
新增如下内容
# 基于哪个镜像
From java:8
# 将本地文件夹挂载到当前容器
VOLUME /tmp
# 复制文件到容器
ADD springboot-demo-0.0.1-SNAPSHOT.jar /springboot.jar
# 声明需要暴露的端口
EXPOSE 10086
# 配置容器启动后执行的命令
ENTRYPOINT ["java","-jar","/springboot.jar"]
保存后使用docker build命令构建
[root@node-100 springboot]# docker build -t springboot:0.0.1 .
Sending build context to Docker daemon 16.73MB
Step 1/5 : FROM java:8
8: Pulling from library/java
5040bd298390: Pull complete
fce5728aad85: Pull complete
76610ec20bf5: Pull complete
60170fec2151: Pull complete
e98f73de8f0d: Pull complete
11f7af24ed9c: Pull complete
49e2d6393f32: Pull complete
bb9cdec9c7f3: Pull complete
Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d
Status: Downloaded newer image for java:8
---> d23bdf5b1b1b
Step 2/5 : VOLUME /tmp
---> Running in 030476e68207
Removing intermediate container 030476e68207
---> e1928fb571dc
Step 3/5 : ADD springboot-demo-0.0.1-SNAPSHOT.jar /springboot.jar
---> 942309050024
Step 4/5 : EXPOSE 8761
---> Running in ddf0e47c7be0
Removing intermediate container ddf0e47c7be0
---> 3b4bb5b9da39
Step 5/5 : ENTRYPOINT ["java","-jar","/springboot.jar"]
---> Running in 842ec587196a
Removing intermediate container 842ec587196a
---> 966885bc8baa
Successfully built 966885bc8baa
Successfully tagged springboot:0.0.1
[root@node-100 springboot]#
启动镜像,加-d可在后台启动
[root@node-100 springboot]# docker run -p 8761:8761 springboot:0.0.1
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.0.BUILD-SNAPSHOT)
2019-02-16 16:24:26.512 INFO 1 --- [ main] c.d.s.s.SpringbootDemoApplication : Starting SpringbootDemoApplication v0.0.1-SNAPSHOT on e6429e81d454 with PID 1 (/springboot.jar started by root in /)
2019-02-16 16:24:26.530 INFO 1 --- [ main] c.d.s.s.SpringbootDemoApplication : No active profile set, falling back to default profiles: default
2019-02-16 16:24:32.404 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-02-16 16:24:34.451 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-02-16 16:24:34.452 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.16]
2019-02-16 16:24:34.485 INFO 1 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib]
2019-02-16 16:24:34.665 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-02-16 16:24:34.665 INFO 1 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 7291 ms
2019-02-16 16:24:36.307 INFO 1 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-02-16 16:24:37.168 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-02-16 16:24:37.176 INFO 1 --- [ main] c.d.s.s.SpringbootDemoApplication : Started SpringbootDemoApplication in 13.283 seconds (JVM running for 16.657)
启动成功。
如果问题,欢迎留言进行交流:)。
网友评论