docker容器技术
1 简介
1.1 什么是docker
Docker属于Linux容器的一种封装,提供简单易用的容器使用接口。
Docker将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了Docker,就不用担心环境问题。
总体来说,Docker的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
1.2 docker概念
Docker是开发人员和系统管理员使用容器开发、部署和运行应用程序的平台。使用Linux容器来部署应用程序称为集装箱化。使用docker轻松部署应用程序。
集装箱化的优点:
- 灵活:即使是复杂的应用程序也可封装。
- 轻量级:容器利用并共享主机内核。
- 便携式:您可以在本地构建,部署到云上并在任何地方运行。
- 可扩展性:您可以增加和自动分发容器副本。
- 可堆叠:您可以垂直堆叠服务并及时并及时堆叠服务。
1.3 虚拟机
虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在Windows系统里面运行Linux系统。应用程序对此毫无感知,因为虚拟机看上去跟真丝系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其它部分毫无影响。
虚拟机的缺点:
- 资源占用多:虚拟机会独占一部分内存和硬盘空间。它运行的时候,其他程序就不能使用这些资源了。哪怕虚拟机里面的应用程序,真正使用的内存只有1M,虚拟机依然需要几百MB的内容才能运行。
- 冗余步骤多:虚拟机是完整的操作系统,一些系统级别的操作步骤,往往无法跳过,比如用户登录。
- 启动慢:启动操作系统需要多久,启动虚拟机就需要多久。可能要等几分钟,应用陈故乡才能真正运行。
1.4 Linux容器
由于虚拟机存在这个缺点,Linux发展出了另一种虚拟化技术:Linux容器(Linux Containers,缩写为LXC)。
Linux容器不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。
由于容器是进程级别的,相比虚拟机又很多优势。
- 启动快:容器里面的应用,直接就是底层系统的一个进程,而不是虚拟机内部的进程。所以,启动容器相当于启动本机的一个进程,而不是启动一个操作系统,速度就快很多。
- 资源占用少:容器只占用需要的资源,不占用那些没有用到的资源;虚拟机由于是完整的操作系统,不可避免要占用所以资源。另外,多个容器可以共享资源,虚拟机都是独享资源。
- 体积小:容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比虚拟机文件要小很多。总之,容器有点像轻量级的虚拟机,能够提供虚拟化的环境,但是成本开销小得多。
1.5 Docker的用途
Docker的主要用途,目前又三大类:
- 提供了一次性的环境:比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。
- 提供弹性的云服务:因为Docker容器可以随开随关,很适合动态扩容和所容。
- 组建微服务架构:通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。
1.6 Docker镜像
操作系统分为内核和用户空间,对于Linux而言,内核启动后,会挂载root文件系统为其提供用户空间支持。而Docker镜像(Image),就相当于是一个root文件系统。
Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
1.7 docker容器
镜像(image)和容器(container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户ID空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立宿主的系统下操作一样。这种特性使容器封装的应用比直接在宿主运行更加安全。
前面讲过镜像使用的是分层储存,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,可以称这个味容器运行时读写而准备的存储层为容器存储层。
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
按照Docker最佳实践的要求,容器不应该向其存储层写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(volume)、或者绑定宿主目录,在这些位置的读写会跳过存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。
1.8 仓库Docker Registry
镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。
一个Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(tag);每个标签对应一个镜像。
通常,一个仓库会包含一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件那个版本的镜像。如果不给出标签,将以laest作为默认标签。
以ubuntu镜像为例,ubuntu是仓库的名字,其包含有不同的版本标签,如,14.04,16.04。我们可以通过ubuntu:14.04或者ubuntu:16.04来具体指定所需要哪个版本的镜像。如果忽略了标签,比如ubuntu,那将视为ubuntu:latest。
仓库名经常以两段式路径形式出现,比如jwilder/nginx-proxy,前者意味着Docker Registry多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体Docker Registry的软件或服务。
2 安装与启动
2.1 安装docker
1 | yum install docker-ce # 安装社区版 |
2.2 设置USTC的镜像
编辑文件 /etc/docker/daemon.json 没有的话就创建一个
在该文件中输入:
1 | { |
2.3 升级到最新版本
查找主机上关于Docker的软件包
1
rpm -qa | grep docker – – 列出包含docker字段的软件的信息
使用
yum remove
卸载软件1
2
3yum remove docker-1.13.1-53.git774336d.el7.centos.x86_64
yum remove docker-client-1.13.1-53.git774336d.el7.centos.x86_64
yum remove docker-common-1.13.1-53.git774336d.el7.centos.x86_64使用
curl
升级到最新版1
curl -fsSL https://get.docker.com/ | sh
4 启动与重启
1 | systemctl restart docker # 重启docker |
查看版本信息
1 | docker version # 查看Docker版本信息 |
3 常用命令
1 镜像相关
1.1 列出镜像
1 | [root@izm5e7klp5h59pozbv3fghz ~]# docker images |
结构说明:
- REPOSITORY:仓库名称
- TAG:标签名称
- IMAGE ID:镜像ID
- CREATED:创建时间
- SIZE:所占用的空间
值得注意的是,一个镜像可以对象多个标签,判断是否为同一个镜像,我们可以查看它的镜像ID,镜像ID是镜像的唯一标识,如果镜像ID一样,则表示为同一镜像!!!
1.2 搜索镜像
格式: docker search [option] keyword
1 | [root@izm5e7klp5h59pozbv3fghz ~]# docker search mysql |
格式说明
- -f, –filter filter 过滤输出的内容
- –help Print usag
- –limit int 指定搜索内容展示个数 (default 25)
- –no-index Don’t truncate output
- –no-trunc Don’t truncate output
1 | [root@izm5e7klp5h59pozbv3fghz ~]# docker search --filter=stars=100 mysql |
1.3 获取镜像
格式: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
格式说明:
- OPTIONS选项。可以使用如下 OPTIONS
- -a, –all-tags:从镜像仓库中下载所有被标记的镜像
- –disable-content-trust:跳过验证
- NAME:仓库名
- TAG:标签
- DIGEST:数据摘要
1 | [root@izm5e7klp5h59pozbv3fghz ~]# docker pull tomcat |
1.4 删除镜像
格式: docker image rm [OPTIONS] IMAGE [IMAGE…]
按镜像id删除镜像
1 | docker rmi 镜像id |
删除所有镜像
1 | docker rmi `docker images -q` |
2 容器相关
1 查看容器
1 | docker ps # 查看正在运行的容器 |
2 创建与启动容器
创建容器参数说明
创建容器命令:docker run
**-i : **表示运行容器
**-t : **表示容器启动后会进入其命令行,加入这两个参数后,容器创建就能登录进去,即分配一个伪终端
**–name : **为创建的容器命名
-v : 表示目录映射,(前者是宿主目录,后者是映射到宿主机上的目录),可以使用多个-v做多个目录或文件映射,注意:最好做目录映射,在宿主机上做修改,然后共享到容器上
**-d : **在run后面加上-d参数,则会创建一个守护容器在后台运行(这样创建容器后不会自动登录容器,如果只加-i-t两个参数,创建后就会自动进去容器)。
**-p : **表示端口映射,前者是宿主机端口,后者是容器的映射端口,可以使用多个端口映射
交互式方式创建容器
1 | docker run -it --name=myubuntu ubuntu /bin/bash #--name=容器名称 镜像名称 |
这时,通过ps查看,发现可以看到容器已启动,
1 | exit; # 退出当前容器 |
守护式方式创建容器:
1 | docker run -di --name=myubuntu2 ubuntu # 守护式启动 (ubutu) |
1 | [root@izm5e7klp5h59pozbv3fghz ~]# docker run -di --name=myubuntu2 ubuntu |
3 停止与启动容器
1 | docker stop 容器id(或名称) # 停止容器 |
4 文件拷贝
将文件拷贝到容器内
1 | docker cp 需要拷贝的文件或目录 容器名称:容器目录 |
1 | [root@izm5e7klp5h59pozbv3fghz ~]# docker cp /usr/local/project/aa myubuntu2:/usr/local |
将文件从容器中拷贝出发
1 | docker cp 容器名称:容器目录 需要拷贝的文件或目录 |
5 目录挂载
我们在创建容器的时候,将宿主机的目录与容器内的目录进行映射,这样我们就可以通过修改宿主机某个目录的文件从而去影响容器
创建容器 添加 -v 参数后边为宿主机目录容器:容器目录,例如
1 | docker run -di --name=myubuntu3 -v /usr/local/myhtml:/usr/local/myhtml ubuntu |
6 查看容器IP
1 | docker inspect 容器名称(容器id) |
也可以直接执行下面的命令直接输出IP地址
1 | docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称(容器id) |
1 | [root@izm5e7klp5h59pozbv3fghz ~]# docker inspect --format='{{.NetworkSettings.IPAddress}}' myubuntu3 |
7 删除容器
1 | docker rm 容器名称(容器id) |
1 | [root@izm5e7klp5h59pozbv3fghz ~]# docker ps -a |
4 应用部署
1 MYSQL部署
拉取MySQL镜像
1 | docker pull centos/mysql-57-centos7 |
创建容器
1 | docker run -di --name=test2_mysql -p 33306:3306 -e MYSQL_ROOT_PASSWORD=123456 centos/mysql-57-centos7 |
-p : 代表端口映射,格式为 宿主机映射端口:容器映射端口
-e : 代表添加环境变量,MYSQL_ROOT_PASSWORD 是root用户的登录密码
进入MySQL容器
1 | docker exec -it test2_mysql /bin/bash |
登录mysql
1 | mysql -u root -p |
远程登录MySQL
连接宿主机的IP,指定端口为33306
2 Tomcat部署
拉取镜像
1 | docker pull tomcat:7-jre7 |
创建容器
1 | docker run -di --name=mytomcat -p 8090:8080 -v /usr/local/webapps:/usr/local/tomcat/webapps tomcat |
3 Nginx 部署
拉取镜像
1 | docker pull nginx |
创建容器
1 | docker run -di --name=mynginx -p 80:80 nginx |
4 Redis 部署
拉取镜像
1 | docker pull redis |
创建容器
1 | docker run -di --name=myredis -p 6379:6379 redis |
5 迁移与备份
容器保存为镜像
1 | docker commit mynginx mynginx_1 |
镜像备份
1 | docker save -o mynginx.tar mynginx_1 # 将镜像保存为tar文件 |
镜像恢复
1 | docker load -i mynginx.tar |
-i : 输入的文件
6 Dockerfile
Dockerfile 是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。
命令 | 作用 |
---|---|
FROM | 构造的新镜像是基于哪个镜像例如:FROM centos:v1 |
MAINTAINER | 维护者信息 例如:MAINTAINER yanglin |
ENV | 设置容器内环境变量 例如:ENV MYSQL_ROOT_PASSWORD 123456 |
RUN | 构建镜像时运行的shell命令例如:RUN [“yum”, “install”, “http”]RUN yum install httpd |
ADD | 拷贝文件或者目录到镜像,如果是URL或者压缩包会自动下载或者自动解压。例如:ADD hom* /mydir/ ADD test relativeDir/ |
COPY | 拷贝文件或者目录到镜像,用法同ADD。 例如:COPY ./startup.sh /startup.sh |
WORKDIR | 为RUN,CMD,ENTRYPOINT,COPY和ADD设置工作目录。 例如:WORKDIR /data |
使用脚本创建镜像
步骤:
1,创建目录
1 | mkdir -p /usr/local/dockerjdk8 |
2,下载jdk并上传到 /usr/local/dockerjdk8 目录
3,创建文件Dockerfile vi Dockerfile
1 | 依赖镜像名称和id(没有会自动下载) |
4,执行命令构建镜像
1 | docker build -t='jdk1.8' . # 注意后面的点 |
5,查看镜像是否创建完成
1 | docker images |
7 Docker 私有仓库
7.1 私有仓库搭建与配置
1,拉取私有仓库镜像
1 | docker pull registry |
2,启动私有仓库容器
1 | docker run -di --name=registry -p 5000:5000 registry |
3,打开浏览器输入地址:http://120.27.71.186:5000/v2/_catalog 看到 {"repositories":[]}
表示私有仓库搭建成功并且内容为空
4,修改daemon.json
1 | vi /etc/docker/daemon.json |
添加内容 : “insecure-registries”: [“120.27.71.186:5000”] 此步用于让docker信任私有仓库地址
1 | vi /etc/docker/daemon.json |
5,重启docker服务
1 | systemctl restart docker |
7.2 镜像上传到私有仓库
1,标记此镜像为私有仓库的镜像
1 | docker tag jdk1.8 120.27.71.186:5000/jdk1.8 |
2,上传标记的镜像
1 | docker push 120.27.71.186:5000/jdk1.8 |
8 DockerMaven插件
1 Maven插件自动部署
修改宿主机docker配置,让其可以远程访问
1 | vi /lib/systemd/system/docker.service |
其中ExecStart=后添加配置 -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
修改后如下:
1 | [Service] |
刷新配置,重启服务
1 | systemctl daemon-reload # 刷新配置 |
在工程pom.xml增加配置
1 | <build> |
以上配置会自动生成Dockerfile
1 | FROM jdk1.8 |
在项目目录下输入以下命令进行打包和上传镜像
1 | mvn clean package docker:build # 生成一个镜像 |
启动容器
1 | docker run -id --name=demo03 -p 9001:9001 120.27.71.186:5000/demo3 |
9 jenkins 持续集成
1 JDK安装
执行命令:
1 | https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html # JDK下载链接 |
RPM方式安装JDK,其根目录为:/usr/java/jdk1.8.0_221-amd64
2 Jenkins安装与启动
1 下载Jenkins
1 | https://pkg.jenkins.io/redhat-stable/ # jenkins下载链接 |
2 安装
1 | rpm -ivh jenkins-2.186-1.1.noarch.rpm |
3 配置
1 | vi /etc/sysconfig/jenkins |
4 修改用户和端口
1 | JENKINS_USER="root" |
5 启动服务
1 | systemctl start jenkins |
6 链接配置
访问:120.27.71.186:8888
此时出现填写密码的选型:根据提示进入指定目录取出密码填写
选择插件安装 这里安装推荐插件
这里进入了主页面
7 插件安装
主页面选择–系统管理—插件管理 进入插件安装页面
选择需要安装的插件 这里选了Maven Integration plugin
8 全局工具配置
主页面选择–系统管理—全局工具配置 进入全局工具配置页面
配置jdk 确保jdk路径配置正确
配置maven 确保maven路径配置正确
maven 仓库可自定义配置,然后可填充仓库jar包,避免打包时长时间下载jar包
10 docker 搭建gogs
1 下载镜像
1 | docker pull gogs/gogs |
2 创建容器
1 | docker run -id --name=gogs/gogs -p 10022:22 -p 3000:3000 -v /var/gogsdata:/data gogs/gogs |
3 配置gogs
打开浏览器输入:http://120.27.71.186:3000
配置信息如下:
1 | 数据库信息:SQLite3 |
11 Jenkins 任务配置与启动
输入任务名称,选择构建maven项目,确定
配置描述,源码管理,Build
1 | 源码管理配置 |
13 Jenkins+docker自动化部署
1 jenkins构建maven项目
2 填写jenkins配置
配置Git仓库
1 | 此处配置的Git仓库: |
配置pom及maven打包命令
1 | 此处配置的pom相对目录及打包命令: |
3 构建
执行构建,查看Jenkins工作空间下的打包文件
1 | 我的Jenkins工作目录: |
到此jenkins构建成功 我们可以拿到项目构建的最新jar包(//var/lib/jenkins/workspace/docker-test/docker-test/target/docke-test.jar),接下来就要考虑怎么把jar包自动化部署到docker容器中。
4 编写Dockerfile文件
在项目操作的路径(/work/project)下创建Dockerfile文件
编辑Dockerfile文件内容为
1 | 基于jdk1.8 |
5 编写jenkins中打包成功后执行的shell脚本
打开jenkins中的配置选择 Post Steps - Add post-build step - 执行shell
脚本值设置为:
1 | 操作/项目路径(Dockerfile存放的路劲) |
shell脚本流程解释:
a.备份(/work/project)下jar包
1 | cp /work/project/docker-test.jar /work/project/backup/docker-test-201805171416.jar |
b.项目构建的最新jar包(/var/lib/jenkins/workspace/docker-test/docker-test/target/docke-test.jar)移动到项目操作的路径(/work/project)
1 | cp /var/lib/jenkins/workspace/docker-test/docker-test/target/docker-test.jar /work/project |
c.判断docker镜像是否存在,不存在则进入Dockerfile存放的路径(/work/project)执行docker build操作构建名字为docker-test镜像
1 | cd /work/project |
d.判断docker容器是否存在,不存在则执行docker run命令创建容器,存在则docker restart重启容器
1 | docker run --name docker-test -v /work/project/:/work/project/ -d -p 8081:8080 docker-test |
6 效果检测
上步操作脚本写好保存后 点击立即构建查看日志如下图代表项目自动化打包构建成功
查看镜像:
查看容器
接口代码内容:
访问连接:
可以发现项目修改重新自动部署成功~