Docker:慕课网--第一个docker化的java应用

课程分享:

  1. 课程分享:Docker+Kubernetes(k8s)微服务容器化实践
  2. 课程分享:Kubernetes(k8s)生产级实践指南 从部署到核心应用

  3. 课程分享:(极客时间)深入剖析Kubernetes

Docker简介:

Docker是一个使用Go语言开发的开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的机器上。Docker的发展速度和火爆程度着实令人惊叹,一发不可收拾,形成了席卷整个IT界的新浪潮。学完本课程你将了解到什么是docker,docker的思想以及诸如镜像,仓库,容器等核心概念。你将学会怎样运行一个容器,如何搭建私有仓库,怎么写dockerfile以及怎样把自己的应用放到容器中运行。docker将会是你的IT路上一笔不小的财富。

什么是 Docker

Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动 开放容器联盟(OCI)。

Docker 自开源后受到广泛的关注和讨论,至今其 GitHub 项目 已经超过 5 万 2 千个星标和一万多个 fork。甚至由于 Docker 项目的火爆,在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用 Docker。

Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd

Docker:慕课网--第一个docker化的java应用_第1张图片 Docker 架构

 

runc 是一个 Linux 命令行工具,用于根据 OCI容器运行时规范 创建和运行容器。

containerd 是一个守护程序,它管理容器生命周期,提供了在一个节点上执行容器和管理镜像的最小功能集。

Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。

下面的图片比较了 Docker 和传统虚拟化方式的不同之处。

  • 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
  • 容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

 

Docker:慕课网--第一个docker化的java应用_第2张图片 传统虚拟化

 

 

Docker:慕课网--第一个docker化的java应用_第3张图片 Docker

 

第1章 课程介绍

对docker有个简单的印象,了解课程的安排。

Docker:慕课网--第一个docker化的java应用_第4张图片

  • Docker 是一个开源的应用容器引擎,主要利用 linux 内核 namespace 实现沙盒隔离,用cgroup 实现资源限制
  • Docker项目的目标是实现轻量级的操作系统虚拟化解决方案。
  • Docker的基础是Linux的容器技术(LXC)。
  • 而Docker,正是在容器的基础上进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作Docker的容器就像操作一个快速轻量级的虚拟机一样简单。

VM是在硬件层面实现虚拟化

Docker几乎没有使用虚拟化的东西,直接复用了host主机的os,是内核级的虚拟化

docker优势:

(1)Docker容器的启动可以在秒级实现,这相比传统的虚拟机方式要得多。

(2)其次,Docker对系统资源的利用率很高,一台主机上可以同时运行数千个Docker容器。而且容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。

 

第2章 了解docker

用形象的类比说明docker的集装箱、标准化、隔离的思想。在用几个工作学习中碰到的问题说明docker解决了哪些问题。

Docker:慕课网--第一个docker化的java应用_第5张图片

Docker解决的问题

Docker:慕课网--第一个docker化的java应用_第6张图片

  • 解决了运行环境不一致所带来的问题(它会将运行程序的相关配置,要求统一管理)
  • 解决耗内存问题,Docker会一开始就为每个程序指定内存分配
  • 让快速扩展,弹性伸缩变得简单

第3章 走进docker

  • 结合上面的类比引出docker的核心技术:镜像、仓库和容器的概念,并分别深入讲解技术、原理。

Docker:慕课网--第一个docker化的java应用_第7张图片

一句话概括核心技术就是:去仓库把镜像拉到本地,然后用一条命令把镜像运行起来,把镜像变成容器。

  • Build:构建镜像
  • Ship:运输镜像
  • Run:运行镜像

Docker包括三个基本概念

镜像(Image)  镜像就是一个只读的模板

容器(Container)  运行应用

仓库(Repository)  集中存放镜像文件的场所,分为公有仓库和私有仓库2种形式

1.Docker镜像(集装箱)

  • 构建镜像的目的:可以运行在其他环境中

镜像就是一系列的文件,它可以包括我们应用程序的文件,也可以包括应用环境的文件。

Docker会把这些文件保存到本地,存储方式采用Linux中的联合文件系统的分层概念方式

镜像可以用来创建Docker容器的。

  • 一个镜像可以包含一个完整的操作系统环境和用户需要的其它应用程序。
  • 在docker hub 里面有大量现成的镜像提供下载。
  • docker的镜像是只可读的,一个镜像可以创建多个容器,每个容器之间相互不干扰。

 示例存储方式见下图,由下往上分别是:

  • 操作系统的引导
  • 具体的Linux操作系统
  • 相关软件:tomcat、jdk等
  • 应用代码
  • 顶层为可写层(属于容器)

Docker:慕课网--第一个docker化的java应用_第8张图片

2.Docker容器(运行程序之地)

  • 容器的本质是一个进程,可以类同于虚拟机

Docker:慕课网--第一个docker化的java应用_第9张图片

Docker利用容器来开发、运行应用


容器是镜像创建的实例。它可以被启动、开始、停止、删除。每个容器都是 相互隔离的、保证安全的平台。

容器在运行过程中,如果要写一个镜像里面的文件:就需要将镜像里的文件拷贝到最上层,再进行修改;修改后,当我们应用读一个文件时,从上层开始读,上层没有才往下读;

3. Docker 仓库(超级码头)

Docker:慕课网--第一个docker化的java应用_第10张图片

仓库是集中存放镜像文件的场所。

每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。

  • 最大的公开仓库是DockerHub(https://hub.docker.com/),存放了数量庞大的镜像供用户下载。
  • 国内: Docker - 国内镜像的配置及使用;https://c.163yun.com/hub#/m/library/
  • 当然,用户也可以在本地网络内创建一个私有仓库

Docker:慕课网--第一个docker化的java应用_第11张图片

第4章 docker安装

分别在三种平台上讲解docker的安装。同学可以选择自己的平台观看。

在centos和redhat上安装docker

1.前置条件

  • 64-bit 系统
  • kernel 3.10+
    1.检查内核版本,返回的值大于3.10即可。
$ uname -r

2.使用 sudo 或 root 权限的用户登入终端。

3.卸载旧版本(如果安装过旧版本的话)

$ yum remove docker \
      docker-common \
      docker-selinux \
      docker-engine

4.安装需要的软件包

#yum-util提供yum-config-manager功能
#另外两个是devicemapper驱动依赖的
$ yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

5.设置yum源

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

6.安装docker

  • 6.1. 安装最新版本
$ yum install -y docker-ce
  • 6.2. 安装指定版本
#查询版本列表
$ yum list docker-ce --showduplicates | sort -r
已加载插件:fastestmirror, langpacks
已安装的软件包
可安装的软件包
 * updates: mirrors.163.com
Loading mirror speeds from cached hostfile
 * extras: mirrors.163.com
docker-ce.x86_64            17.09.1.ce-1.el7.centos            docker-ce-stable
docker-ce.x86_64            17.09.0.ce-1.el7.centos            docker-ce-stable
...
#指定版本安装(这里的例子是安装上面列表中的第二个)
$ yum install -y docker-ce-17.09.0.ce
  • 如果遇到,Docker安装指定版本异常:Error: Package: docker-ce-17.03.1.ce-1.el7.centos.x86_64 (docker-ce-stable)

请参考:https://blog.csdn.net/fly910905/article/details/97622433

  • 7.启动docker
$ systemctl start docker.service

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

$ docker version
Client:
 Version:      17.09.0-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   afdb6d4
 Built:        Tue Sep 26 22:41:23 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.09.0-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   afdb6d4
 Built:        Tue Sep 26 22:42:49 2017
 OS/Arch:      linux/amd64
 Experimental: false

 

第5章 docker初体验

 

第一个实例:用helloworld镜像带入,熟悉docker最基本的两个命令,拉取镜像和运行容器,并讲解背后运行逻辑。

第一个docker镜像


docker pull [OPTIONS] NAME[:TAG]

解释:拉取镜像,也就是从docker远程仓库拉去一个镜像到本地,

其中:TAG是可选的(指定版本),OPTIONS为拉取时的一些参数。

docker images [OPTIONS] [REPOSITOR[:TAG]]

解释:查看本机镜像,也可以验证上面的pull是否成功。

REPOSITOR表示镜像名称,:TAG表示版本。

第一个docker容器

docker run [OPTIONS] IMAGE[:TAG][COMMAND][ARG…]

解释:运行镜像,OPTIONS:TAG同上,

COMMAND表示这个IMAGE镜像运行起来后要执行的命令,ARG表示要执行的命令所依赖的参数。

 

Docker:慕课网--第一个docker化的java应用_第12张图片

上图共分为三部分,从左至右分别为 Client、Host、Registry。前两个属于本机,Registry在hello-world例子中相当于远程仓库,整个流程为:

docker pull 过程

 

  • 先向 docker daemon(在Host中)发送拉取镜像请求
  • daemon先在本机查找是否由符合版本要求的镜像,如果有,则不会做其他操作;
  • 没有的话,daemon就去 Registry中查找,Registry返回相应镜像到本地。

docker run 过程

 

  • 先向 docker daemon发送请求,镜像不存在则再执行一次 docker pull过程。
  • 然后通过一定方式把镜象变成容器

第6章 docker运行nginx静态网站

第二个实例:从运行nginx镜像引出docker网络概念和docker的端口映射,最后运行nginx容器。

  实践前奏

  • ngnix为持久运行的容器(不同于 hello-world)
  • 前台挂起&后台运行(前台运行的话,ctrl+c 即可结束进程,所以最好后台)
  • 进入容器内部,观察容器特征

1. 拉取nginx镜像

docker pull hub.c.163.com/library/nginx:latest

  • 终端执行docker images,可以看到nginx镜像拉取成功

 2 运行nginx镜像
      

前端运行nginx镜像+关闭镜像方法

执行 docker run hub.c.163.com/library/nginx:latest  语句,会发现没有任何响应。


另开一个窗口 执行 docker ps语句,该语句会显示正在运行的镜像

 

  • 因为nginx 此时是在前端运行,所以会出现docker run,没有任何响应。
  • 执行 docker kill 779ab2962a80关闭前端运行nginx镜像这个进程。(779ab2962a80*为上图中的容器ID,也可以用 容器名替代)

      

后台运行nginx镜像+进入容器内部


执行 docker run -d hub.c.163.com/library/nginx ,在后台运行该镜像,返回的值为容器的ID。

进入容器内部的命令为 docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

Docker:慕课网--第一个docker化的java应用_第13张图片

解释: 在一个正在运行的容器中执行一条命令。
OPTIONS为执行的参数(可以通过执行 docker exec --help查看)
CONTAINER 为容器名, COMMAND [ARG…]为命令名以及参数

执行 docker exec -it f4 bash

Docker:慕课网--第一个docker化的java应用_第14张图片
解释:-it为上图的 -i、-t的缩写,f4为容器ID的简写(因为现在在本机上的容器很少,通过23f就足以查找容器),bash为终端命令

  • 上图表明已经进入了 nginx 所在的linux终端,就可以执行相关的Linux命令了。
  • 执行完相关 Linux命令后,执行exit退出容器

3 Docker网络


网络类型

Docker:慕课网--第一个docker化的java应用_第15张图片


Bridge(默认)

bridge模式是Docker默认的网络设置,此模式会为每一个容器 分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。

  • Bridge模式:首先创建一个docker0网桥,这个网桥和主机的eth0网卡相连;在启动容器时,容器这边则会产生一个虚拟网卡,也和网桥相连。这种模式下,容器会有自己独立的IP和端口。

 

(1) 利用 veth pair 技术,在宿主机上创建两个虚拟网络接口设备,假设为veth0 和 veth1。而 veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将报文传输给另一方

(2) 将 veth0 附加到docker0 网桥上。保证宿主机的网络报文可以发往 veth0

(3) 将 veth1 添加到容器所属的 namespace 下,并被改名为 eth0。

如此一来,保证宿主机的网络报文若发往 veth0,则立即会被 eth0 接收,实现宿主机到容器网络的联通性;同时,也保证 容器单独使用 eth0,实现容器网络环境的隔离性。

缺点:和宿主机以外的网络通信比较困难

 

Host

不会创建独立的network namespace。Docker容器中的进程处于宿主机的网络环境中,相当于Docker容器和宿主机共同用一个network namespace,使用宿主机的网卡、IP和端口等信息。

但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

缺点:容器不再拥有隔离、独立的网络栈,会和宿主机发生资源抢夺

  • Host模式:容器直接连接主机的网卡eth0,两者使用同一网卡,看到的网络环境一样。

None

没有网络,Docker不会和外界进行通讯。Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。

 

Container

Container模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。

新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。

同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。

(1) 查找其他容器(即需要被共享网络环境的容器)的网络

(2) 将新创建的容器(也是需要共享其他网络的容器)的namespace,使用其他容器的namespace。

可以用来更好的服务于容器间的通信。可以通过 localhost 来访问 namespace 下的其他容器,传输效率较高。虽然多个容器共享网络环境,但是多个容器形成的整体依然与宿主机以及其他容器形成网络隔离。另外,这种模式还节约了一定数量的网络资源。

缺点:它并没有改善容器与宿主机以外世界通信的情况。


端口映射

使容器的端口在主机上访问到,采用端口映射,Docker可以将容器里面的端口与主机的端口进行映射,这样就可以通过访问主机端口去访问容器端口。

执行 docker run -d -p 8080:80 hub.c.163.com/library/nginx 运行Nginx镜像,如下图

解释:-d表示后台运行,-p为端口设置,8080为本机端口,80为Nginx容器开放的端口,hub.c.163.com/library/nginx为容器名。

注意:完成上面步骤后,浏览器访问 localhost:32768,会发现访问不到,我们需要 找到Window系统下的Linux环境的地址

docker-machine ip default,找到Window系统下的Linux环境的地址

另记:上面语句中的-p替代为-P,Docker 会随机映射一个  的端口到内部容器开放的网络端口。然后使用docker ps 可以查看映射的端口号。


第7章 第一个java web应用

最后一个实例:创建自己的镜像,引出dockerfile,讲解基本的dockerfile语法。然后讲解私有仓库的搭建。最后分别在两台机器上演示docker的跨平台运行我们的java web项目。

Docker运行MySql

执行 docker pull hub.c.163.com/library/mysql:latest,拉取mysql镜像,然后执行docker images查看本地镜像

终端执行docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=000000 -e MYSQL_DATABASE=jpress hub.c.163.com/library/mysql:latest,运行mysql镜像并创建数据库jpress

命令解释详见:library /mysql

完整步骤

1、下载mysql镜像

 

下载mysql镜像,找到镜像,之后执行

docker pull hub.c.163.com/library/mysql:latest

,之后我们重命名下这个镜像,不然名字太长了,执行

 docker tag hub.c.163.com/library/mysql:latest mysql:5.7

,之后执行

docker images

,应该可以看到变化了。

2、运行镜像

     执行

docker  run  -d --name  mysql5.7container  -p  3306:3306  -e  MYSQL_ROOT_PASSWORD=123  mysql:5.7

,注意:123是root用户的密码。之后执行

docker ps -a

,就会看到全部的容器了,可以看到一个名为mysql5.7container的容器。

3、远程连接

    之后用navicat进行远程连接,ip地址填宿主主机(即运行者docker的linux)的ip地址,用户名是root,密码是123.

拉取tomcat镜像

docker pull hub.c.163.com/library/tomcat:latest拉取tomcat镜像(tomcat镜像会包括jdk镜像),然后docker images查看本机镜像,tomcat镜像名为hub.c.163.com/library/tomcat 

Docker:慕课网--第一个docker化的java应用_第16张图片

编写Dockerfile文件

  1. 输入from hub.c.163.com/library/tomcat,这句话表明我要制作的镜像以tomcat的镜像为起点,其中hub.c.163.com/library/tomcat为tomcat的镜像名。
  2. MAINTAINER 为自己的一些信息(可以不写)。
  3. 输入COPY jpress-web-newest.war /usr/local/tomcat/webapps,将web应用拷贝到tomcat的webapps下,其中/usr/local/tomcat来tomcat的安装目录,jpress-web-newest.war是需要部署的javaWeb程序

Docker:慕课网--第一个docker化的java应用_第17张图片

执行Docker Build命令

docker build -t jpress:latest .

  • 注意最后面有“.”,表示当前目录
  • 解释: -t表示为创建镜像的参数 ,jpress为镜像名称,latest为镜像版本。

Docker:慕课网--第一个docker化的java应用_第18张图片

运行镜像

docker run -d -p 8888:8080 jpress,运行容器,其中,本机端口号为8888,jpress开放的端口号为8080

  • 注意:怎么查看tomcat中应用程序的名字?
  • 进入到 jpress镜像内部,docker exec -it 60 bash,其中,60为运行镜像时返回的ID,会发现直接跳转到了 Dockerfile文件中配置的 tomcat目录下
  • cd webapps下,然后输入ls展示所有文件,这里就可以看到应用程序的名字了

 

参考链接:https://www.imooc.com/learn/824

参考链接:https://www.imooc.com/article/16448

 

你可能感兴趣的:(Docker:一个应用容器引擎,Docker,kubernetes,容器化)