Docker基础教程

245 阅读12分钟

Docker基础教程

1、Docker是什么?

​ Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

1.1、Docker的应用场景

  • Web 应用的自动化打包和发布
  • 自动化测试和持续集成、发布
  • 在服务型环境中部署和调整数据库或其他的后台应用
  • 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境

1.2、Docker 的优点

​ Docker 是一个用于开发,交付和运行应用程序的开放平台。Docker 使您能够将应用程序与基础架构分开,从而可以快速交付软件。借助 Docker,您可以与管理应用程序相同的方式来管理基础架构。通过利用 Docker 的方法来快速交付,测试和部署代码,您可以大大减少编写代码和在生产环境中运行代码之间的延迟。

1.2.1、快速交付

Docker 允许开发人员使用您提供的应用程序或服务的本地容器在标准化环境中工作,从而简化了开发的生命周期。容器非常适合持续集成和持续交付(CI / CD)工作流程,请考虑以下示例方案:

  • 您的开发人员在本地编写代码,并使用 Docker 容器与同事共享他们的工作。
  • 他们使用 Docker 将其应用程序推送到测试环境中,并执行自动或手动测试。
  • 当开发人员发现错误时,他们可以在开发环境中对其进行修复,然后将其重新部署到测试环境中,以进行测试和验证。
  • 测试完成后,将修补程序推送给生产环境,就像将更新的镜像推送到生产环境一样简单。

1.2.2、响应式部署和扩展

Docker 是基于容器的平台,允许高度可移植的工作负载。Docker 容器可以在开发人员的本机上,数据中心的物理或虚拟机上,云服务上或混合环境中运行。

Docker 的可移植性和轻量级的特性,还可以使您轻松地完成动态管理的工作负担,并根据业务需求指示,实时扩展或拆除应用程序和服务。’

1.2.3、高资源使用率

Docker 轻巧快速。它为基于虚拟机管理程序的虚拟机提供了可行、经济、高效的替代方案,因此您可以利用更多的计算能力来实现业务目标。Docker 非常适合于高密度环境以及中小型部署,而您可以用更少的资源做更多的事情。

2、Docker 架构

Docker 包括三个基本概念:

  • 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
  • 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
  • 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。

Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。

Docker 容器通过 Docker 镜像来创建。

容器与镜像的关系类似于面向对象编程中的对象与类。

Docker面向对象
容器对象
镜像

img

概念说明
Docker 镜像(Images)Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。
Docker 容器(Container)容器是独立运行的一个或一组应用,是镜像运行时的实体。
Docker 客户端(Client)Docker 客户端通过命令行或者其他工具使用 Docker SDK (docs.docker.com/develop/sdk…) 与 Docker 的守护进程通信。
Docker 主机(Host)一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。
Docker RegistryDocker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(hub.docker.com) 提供了庞大的镜像集合供使用。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
Docker MachineDocker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。

3、Docker安装

3.1 、Centos 7下安装

##安装命令
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
##安装完成后启动服务
service docker start

3.2、Windows 10下安装

现在 Docker 有专门的 Win10 专业版系统的安装包,需要开启 Hyper-V。请参考如下链接

docs.microsoft.com/zh-cn/virtu…

首先注册一个dockerhub账号:hub.docker.com/

Docker 下载地址:download.docker.com/win/stable/…

download.docker.com/win/stable/…

安装完成Docker-Desktop后,启动容器。然后即可。然后听过powershell控制台操作。

3.3、Mac下安装

##命令安装
brew cask install docker

也可以离线安装:download.docker.com/mac/stable/…

4、镜像仓库

4.1、国内仓库

网易: c.163yun.com/hub#/m/home… (需登录) 阿里云:cr.console.aliyun.com/cn-beijing/… (需登录) DaoCloud 道客网络: hub.daocloud.io/

4.2、国外仓库

Docker Hub: hub.docker.com/ Quay: quay.io/search

4.3、配置镜像加速

  • 桌面版的可以通过设置进行设置镜像加速器(如下MAC中配置的我自己的阿里云镜像加速器)

image-20200718161359293

  • 控制台可以通过修改 /ect/docker/daemon.json进行修改(Linux非桌面版本)
{
  "registry-mirrors": [
    "https://registry.docker-cn.com",
    "http://hub-mirror.c.163.com",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}

5、Docker常用命令

具体命令的说明,点开链接进行查看使用说明

5.1、容器生命周期管理

5.2、容器操作

5.3、容器rootfs命令

5.4、镜像仓库

5.5、本地镜像管理

5.6、info|version

6、创建镜像

​ 首先我们要知道怎么来创建镜像,创建镜像需要写一些命令脚本来加载依赖项或者执行一些必要的操作。而这些命令的集合存放的文件就叫做Dockerfile。

6.1、Dockerfile文件

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。相关指令说明如下:

说明命令备注
基础镜像信息FROM加载依赖项
维护者信息MAINTAINER作者信息
镜像操作指令RUN、COPY、ADD、EXPOSE、WORKDIR、ONBUILD、USER、VOLUME、ENV等
容器启动时执行指令CMD、ENTRYPOINT

6.1.1、FROM:指定基础镜像

第一条指令。scratch是虚拟的镜像,表示一个空白的镜像。例如镜像依赖tomcat 。 FROM tomcat

6.1.2、RUN:执行命令

shell 格式: RUN <命令> ,RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
exec 格式: RUN ["可执行文件", "参数1", "参数2"] 。run可以写多个,每一个指令都会建立一层,所以正确写法应该是↓
RUN buildDeps='gcc libc6-dev make' \
         && apt-get update \
         && apt-get install -y $buildDeps \
         && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \
         && mkdir -p /usr/src/redis \
         && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
         && make -C /usr/src/redis \
         && make -C /usr/src/redis install \
         && rm -rf /var/lib/apt/lists/* \
         && rm redis.tar.gz \
         && rm -r /usr/src/redis \
         && apt-get purge -y --auto-remove $buildDeps

6.1.3、COPY:复制文本

COPY <源路径>... <目标路径>
COPY ["<源路径1>",... "<目标路径>"]
<源路径> 可以是多个、以及使用通配符,通配符规则满足Go的filepath.Match 规则,如:COPY hom* /mydir/    COPY hom?.txt /mydir/
<目标路径>使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等。

6.1.4、ADD:高级复制文件

ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
<源路径> 可以是一个 URL ,下载后的文件权限自动设置为 600 。

6.1.5、CMD:容器启动命令

shell 格式: CMD <命令>
exec 格式: CMD ["可执行文件", "参数1", "参数2"...]

CMD ["nginx", "-g", "daemon off;"]

6.1.6、ENTRYPOINT:入口点

同CMD,指定容器启动程序及参数。 通过--entrypoint 参数在运行时替换。

用例一:使用CMD要在运行时重新写命令才能追加运行参数,ENTRYPOINT则可以运行时接受新参数。
示例:
FROM ubuntu:16.04
RUN apt-get update \
&& apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]

追加-i参数
$ docker run myip -i

6.1.7、ENV:设置环境变量

在其他指令中可以直接引用ENV设置的环境变量

ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
示例:
ENV VERSION=1.0 DEBUG=on NAME="Happy Feet"

6.1.8、ARG:构建参数

与ENV不同的是,容器运行时不会存在这些环境变量。 可以用 docker build --build-arg <参数名>=<值> 来覆盖。

6.1.9、VOLUME:定义匿名卷

VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

6.1.10、EXPOSE:暴露端口

EXPOSE <端口1> [<端口2>...] 
EXPOSE :EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。

6.1.11、WORKDIR:指定工作目录

WORKDIR <工作目录路径>
RUN cd /app
RUN echo "hello" > world.txt
两次run不在一个环境内,可以使用WORKDIR。

6.1.12、USER:指定当前用户

这个用户必须是事先建立好的,否则无法切换。
USER <用户名>

6.1.13、HEALTHCHECK:健康检查

HEALTHCHECK [选项] CMD <命令> :设置检查容器健康状况的命令
HEALTHCHECK NONE :如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

HEALTHCHECK 支持下列选项:
    --interval=<间隔> :两次健康检查的间隔,默认为 30 秒;
    --timeout=<时长> :健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
    --retries=<次数> :当连续失败指定次数后,则将容器状态视为 unhealthy ,默认 3次。

示例
FROM nginx
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s \
CMD curl -fs http://localhost/ || exit 1

6.2、创建镜像

​ 以springboot项目(docker-demo)为例项目地址:github.com/JianJang201…

Dockerfile文件内容如下:

FROM java:8
MAINTAINER JianJang
LABEL name="docker-demo" version="1.0.0" author="JianJang"
VOLUME /tmp
ADD target/docker-demo.jar /docker-demo.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/docker-demo.jar"]
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
EXPOSE 8080

6.2.1、创建步骤

  1. 拉取代码

  2. maven项目打包

  3. 进入项目根目录可以看到对应的Dockerfile文件

  4. 执行构建命令进行构建

    docker build -t springboot/docker-demo .
    
  5. 查看镜像信息

    docker images;
    

    image-20200718231136759

  6. 启动容器

    docker run -d -p 8080:8080 --name docker-demo springboot/docker-demo
    
  7. 访问验证

    curl  localhost:8080/docker/index.do
    

6.3、镜像上传仓库

6.3.1、创建镜像仓库

首先我们要在阿里云上创建自己的仓库。例如我的仓库如下图所示,然后我们需要创建本地标签。

image-20200719120231866

6.3.2、账号登录

使用docker login 命令登录cr.console.aliyun.com/repository/…

image-20200719115402510

6.3.3、本地标签并上传

在上传之前,先给本地镜像打个tag标签,相当于重新复制镜像并重命名为docker账户名/仓库名称。

语法:docker tag 本地镜像:tag docker账号/docker仓库:tag

docker tag springboot/docker-demo:latest registry.cn-shanghai.aliyuncs.com/jianjang/springboot-docker:v1

查看镜像

docker images

image-20200719112845156

上传镜像

docker push registry.cn-shanghai.aliyuncs.com/jianjang/springboot-docker:v1

上传成功后可以在阿里云的容器镜像服务的控制台中看到对应的镜像信息,如下图:

image-20200719164624405

拉取镜像

##拉取镜像
docker pull registry.cn-shanghai.aliyuncs.com/jianjang/springboot-docker:v1
##启动容器
docker run -d -p 8080:8080 --name docker-demo registry.cn-shanghai.aliyuncs.com/jianjang/springboot-docker:v1
##查看容器
docker ps 
##验证
curl localhost:8080/docker/index.do

6.4、通过maven插件创建镜像

插件名称为dockerfile-maven-plugin,配合Dockfile文件使用,Dockerfile存放目录和项目根目录下,即和pom.xml在相同目录下。直接在项目的pom.xml中进行配置即可,配置示例如下:

<build>
		<finalName>docker-demo</finalName>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<plugin>
        <!--插件-->
				<groupId>com.spotify</groupId>
				<artifactId>dockerfile-maven-plugin</artifactId>
				<version>1.4.13</version>
				<executions>
					<execution>
						<id>default</id>
						<goals>
							<goal>build</goal>
							<goal>push</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
          <!-- 对应阿里云中的仓库路径-->
					<repository>registry.cn-shanghai.aliyuncs.com/zhangjian_sh/docker-demo</repository>
					<tag>${project.version}</tag>
          <!--阿里云镜像仓库账号及密码-->
					<username>username</username>
					<password>123456</password>
					<buildArgs>
						<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
					</buildArgs>
				</configuration>
			</plugin>
		</plugins>
	</build>

Dockerfile内容

FROM java:8
MAINTAINER JianJang
LABEL name="docker-demo" version="1.0.0" author="JianJang"
VOLUME /tmp
ADD ${JAR_FILE} /docker-demo.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/docker-demo.jar"]
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
EXPOSE 8080

配置完成后就可以在maven视图通通过插件进行build->tag->push等操作了。如下图:

image-20200719164848658

7、Docker应用示例

7.1、在Docker中启动Redis服务

  • 拉取镜像

    docker pull redis
    
  • 启动服务

    docker run  -d -p 6379:6379 --name myredis redis
    

7.2、在Docker中启动Mysql服务

  • 拉取镜像

    docker pull mysql
    
  • 启动服务

    docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=JianJang123 mysql
    
  • 进入服务后台

    语法: docker exec -it 容器名称 bash。容器后台就是容器启动所依赖的平台内部。

    docker exec -it mysql-test bash
    
  • 登录mysql

    mysql -uroot -pjianjang123
    

image-20200719170456153

8、镜像仓库

​ 镜像仓库顾名思义就是镜像的仓库,用于存放镜像对应的发布版本信息,就像maven仓库一样。我们可以在仓库里找到三方或者官方提供的公开的镜像信息。

Docker Hub作为Docker默认官方公共镜像,如果想要自己搭建私有镜像残酷,官方也提供Registry镜像,使得我们搭建私有仓库变得非常简单。

  所谓私有仓库,也就是在本地(局域网)搭建的一个类似公共仓库的东西,搭建好之后,我们可以将镜像提交到私有仓库中。这样我们既能使用 Docker 来运行我们的项目镜像,也避免了商业项目暴露出去的风险。下面我们来说看看如何搭建私有仓库。

8.1、搭建私有仓库

8.1.1、通过Registry镜像搭建

  • 拉取镜像

    docker pull registry
    
  • 启动服务

    docker run -d -v /edc/images/registry:/var/lib/registry -p 5000:5000 --restart=always --name my-registry registry
    
  • 配置仓库

    为啥配置,因为有配置https所以要授信。

    修改配置文件 vim /etc/docker/daemon.json 或者修改docker-desktop的设置如下:

    { 
        "insecure-registries" : [ "your-server-ip:5000" ] 
    }
    
  • 上传镜像

    ##打tag
    docker tag your-image-name:tagname your-server-ip:5000/your-image-name:tagname
    ##上传
    docker push your-registry-server-ip:5000/your-image-name:tagname
    
  • 拉取镜像

    docker pull your-server-ip:5000/your-image-name:tagname
    
  • 查看镜像

    curl http://your-server-ip:5000/v2/_catalog
    

8.1.2、Docker Hub公共镜像仓库

​ 到docker hub的官网去注册一个账号即可,网址:hub.docker.com/。国内的也可以到阿里云…

8.1.3、企业级镜像仓库Harbor

​ Harbor是VMware公司开源的一个企业级Docker Registry项目,项目地址:github.com/goharbor/ha…

 img

  Harbor作为一个企业级私有Registry服务器,提供了更好的性能和安全,提升了用户使用Registry构建和运行环境传输镜像的效率。虽然Harbor和Registry都是私有镜像仓库的选择,但是Harbor的企业级特性更强,因此也是更多企业级用户的选择。

  Harbor实现了基于角色的访问控制机制,并通过项目来对镜像进行组织和访问权限的控制,也常常和K8S中的namespace结合使用。此外,Harbor还提供了图形化的管理界面,我们可以通过浏览器来浏览,检索当前Docker镜像仓库,管理项目和命名空间。

8.1.3.1、Harbor安装

前提条件是先安装docker和docker-compose,例如我在腾讯云的centos 7.5上安装,相关命令如下:

  • 安装docker
yum install docker   # 安装docker
...
systemctl start docker   # 运行docker服务
  • 安装docker-compose
yum install docker-compose
  • 下载harbor安装包

    在服务器上通过如下命令下载,这里我安装的是harbor-offline-installer-v1.10.4.tgz版本,由于网络原因,可能下载速度比较慢,也可以到我的百度网盘中下载(链接: pan.baidu.com/s/1IDXHtwyP… 提取码: b7a3)

wget https://github.com/goharbor/harbor/releases/download/v1.10.4/harbor-offline-installer-v1.10.4.tgz
  • 安装harbor

    解压后,修改配置文件中的hostname:A.B.C.D(ip或者域名)和port 默认为80(此处的是对外服务端口),同时注释掉https相关的属性。如下图:

###解压,默认到harbor目录
tar -xvzf harbor-offline-installer-v1.10.4.tgz
###修改配置harbor/harbor.yml
vi harbor/harbor.yml
##开始安装
sh harbor/install.sh
###看到如下内容说明安装成功
✔ ----Harbor has been installed and started successfully.----

image-20200725123553210

  • 访问harbor的portal页面

    http://ip:port/即可进入ui页面如下:默认账号:admin/Harbor12345

    image-20200725124635725

  • 创建项目

    登录harbor创建项目jiangjang,同时创建用户zhangjian_sh。并将其设置为项目管理员。相关操作略。可参考如下文章内容

    www.yht7.com/news/34086

  • 上传镜像到仓库

    • 本地docker 配置

    配置harbor镜像仓库地址注册(docker-desktop配置如下图)。否则不会被授信。如果不是desktop版本修改 /etc/docker/daemon.json文件加入如下配置,配置完成后重启docker 。

    {
      "insecure-registries":[
        "123.207.206.153:1180"
      ]
    }
    

    image-20200725130827028

    • 打TAG

    此处以将本地仓库的java 8上传到harbor仓库为例

    docker tag java:8 123.207.206.153:1180/jianjang/java:8
    

    image-20200725131612940

    • 推送到仓库

      推送之前需要先登录到远程仓库

      docker login  123.207.206.153:1180
      

      推送镜像到仓库

      docker push 123.207.206.153:1180/jianjang/java:8
      

      image-20200725132810271

    • 查看镜像

      image-20200725133408204

9、参考资源列表

10、总结

​ 至此,本教程就是终结了,主要针对基础的使用做了部分讲解。对于应用方面说明的比较少。后续如果有时间,会增加企业级实战相关的教程。