docker的意义

  • 把事情简单化
    • Docker友好的基于CLI的工作流使各种技能水平的开发人员都可以访问构建,共享和运行容器化应用程序。
  • 快速移动
    • 从单个软件包安装即可在几分钟内启动并运行。在确保开发与生产之间一致性的同时,在本地进行编码和测试。
  • 合作

什么是虚拟化容器

容器是打包代码及其所有依赖项的软件的标准单元,因此应用程序可以从一个计算环境快速可靠地运行到另一个计算环境。Docker容器映像是一个轻量级的,独立的,可执行的软件软件包,其中包含运行应用程序所需的一切:代码,运行时,系统工具,系统库和设置。

容器映像在运行时会成为容器,对于Docker容器,映像会在Docker Engine上运行时成为容器。不论基础架构如何,容器化软件都可用于基于Linux和Windows的应用程序,始终运行相同。容器将软件与其环境隔离开来,并确保尽管开发和登台之间存在差异,但软件仍可以均匀运行。

在Docker Engine上运行的Docker容器:

  • 标准: Docker创建了容器的行业标准,因此它们可以在任何地方移植
  • 轻巧:容器共享计算机的OS系统内核,因此不需要每个应用程序都具有OS,从而提高了服务器效率,并降低了服务器和许可成本
  • 安全:应用程序在容器中更安全,并且Docker提供了业界最强大的默认隔离功能
容器图

容器与虚拟机

容器图 虚拟机图

容器和虚拟机具有相似的资源隔离和分配优势,但是功能不同,因为容器虚拟化了操作系统,而不是硬件。容器更加便携和高效。

容器

容器是应用程序层的抽象,将代码和依赖项打包在一起。多个容器可以在同一台计算机上运行,​​并与其他容器共享OS内核,每个容器在用户空间中作为隔离的进程运行。容器占用的空间少于VM(容器映像的大小通常为几十MB),可以处理更多的应用程序,并且需要的VM和操作系统更少。

虚拟机

虚拟机(VM)是将一台服务器转变为多台服务器的物理硬件的抽象。虚拟机管理程序允许多个VM在单台计算机上运行。每个VM包含操作系统,应用程序,必要的二进制文件和库的完整副本-占用数十GB。VM也可能启动缓慢。

简单来说就是容器可以共享物理机的运行内存、网络带宽等,而虚拟机是独占运行内存、网络带宽,需要主动分配给虚拟机一定的内存大小、带宽等。

仓库(Repository)

Docker用Registry来保存用户构建的镜像。Registry分为公共和私有两种。Docker公司运营公共的 Registry叫做Docker Hub。 远程仓库地址:https://hub.docker.com/

国内镜像仓库

  • docker官方中国区: https://registry.docker-cn.com
  • 网易: http://hub-mirror.c.163.com
  • ustc: http://docker.mirrors.ustc.edu.cn
  • 阿里云:http://<专属个人ID>.mirror.aliyuncs.com

镜像(Image)

镜像不是单一的文件:而是有多层构成,我们可以通过 docker history 镜像名|id 查看镜像中各层内 容及大小,每层都对应着Dockerfile中的一条指令。Docker镜像默认存在在/var/lib/docker/中。
镜像从何而来:Docker Hub是由docker公司负责和维护的公共注册中心,包含大量的镜像文件, Docker客户端工具默认从这个公共镜像仓库下载镜像, 远程仓库地址:https://hub.docker.com/

镜像就像你下载了一个gz或zip压缩包。只不过这个镜像文件中意见包括了几个部分:

  • 微型计算机(文件系统,网络)
  • 当前镜像的文件

比如你下载的tomcat,tomcat的镜像文件就包括了:
微型计算机 + Tomcat环境+Jdk环境 = Tomcat镜像

容器(Container)

就是镜像创建出来的一个运行的系统,与其说是系统还不如说,容器就是一个进程。

使用docker

安装docker

官方安装脚本自动安装(公网环境)

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

手动安装

Ubuntu 14.04 16.04 (使用apt-get进行安装)
# step 1: 安装必要的一些系统工具
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# step 2: 安装GPG证书
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# Step 3: 写入软件源信息
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# Step 4: 更新并安装 Docker-CE
sudo apt-get -y update
sudo apt-get -y install docker-ce

注意:其他注意事项在下面的注释中
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# apt-cache madison docker-ce
#   docker-ce | 17.03.1~ce-0~ubuntu-xenial | http://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
#   docker-ce | 17.03.0~ce-0~ubuntu-xenial | http://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
# Step 2: 安装指定版本的Docker-CE: (VERSION 例如上面的 17.03.1~ce-0~ubuntu-xenial)
# sudo apt-get -y install docker-ce=[VERSION]

# 通过经典网络、VPC网络内网安装时,用以下命令替换Step 2、Step 3中的命令
# 经典网络:
# curl -fsSL http://mirrors.aliyuncs.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyuncs.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# VPC网络:
# curl -fsSL http://mirrors.cloud.aliyuncs.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# sudo add-apt-repository "deb [arch=amd64] http://mirrors.cloud.aliyuncs.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
CentOS 7 (使用yum进行安装)
# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加软件源信息
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3: 更新并安装 Docker-CE
sudo yum makecache fast
sudo yum -y install docker-ce
# Step 4: 开启Docker服务
systemctl start docker

注意:其他注意事项在下面的注释中
# 官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,你可以通过以下方式开启。同理可以开启各种测试版本等。
# vim /etc/yum.repos.d/docker-ce.repo
#   将 [docker-ce-test] 下方的 enabled=0 修改为 enabled=1
#
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# yum list docker-ce.x86_64 --showduplicates | sort -r
#   Loading mirror speeds from cached hostfile
#   Loaded plugins: branch, fastestmirror, langpacks
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            docker-ce-stable
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            @docker-ce-stable
#   docker-ce.x86_64            17.03.0.ce-1.el7.centos            docker-ce-stable
#   Available Packages
# Step2 : 安装指定版本的Docker-CE: (VERSION 例如上面的 17.03.0.ce.1-1.el7.centos)
# sudo yum -y install docker-ce-[VERSION]
# 注意:在某些版本之后,docker-ce安装出现了其他依赖包,如果安装失败的话请关注错误信息。例如 docker-ce 17.03 之后,需要先安装 docker-ce-selinux。
# yum list docker-ce-selinux- --showduplicates | sort -r
# sudo yum -y install docker-ce-selinux-[VERSION]

# 通过经典网络、VPC网络内网安装时,用以下命令替换Step 2中的命令
# 经典网络:
# sudo yum-config-manager --add-repo http://mirrors.aliyuncs.com/docker-ce/linux/centos/docker-ce.repo
# VPC网络:
# sudo yum-config-manager --add-repo http://mirrors.cloud.aliyuncs.com/docker-ce/linux/centos/docker-ce.repo

安装校验

root@iZbp12adskpuoxodbkqzjfZ:$ docker version
Client:
 Version:      17.03.0-ce
 API version:  1.26
 Go version:   go1.7.5
 Git commit:   3a232c8
 Built:        Tue Feb 28 07:52:04 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.03.0-ce
 API version:  1.26 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   3a232c8
 Built:        Tue Feb 28 07:52:04 2017
 OS/Arch:      linux/amd64
 Experimental: false

docker卸载

1、查询docker安装过的包: yum list installed | grep docker
2、删除安装包: yum remove docker-ce.x86_64 ddocker-ce-cli.x86_64 -y
3、删除镜像/容器: rm -rf /var/lib/docker

设置docker仓库使用国内镜像

通常是编辑/etc/docker/daemon.json(没有的话需要创建)

{
  "registry-mirrors" : [
    "https://ajxzc7hl.mirror.aliyuncs.com",
    "https://registry.docker-cn.com",
    "http://docker.mirrors.ustc.edu.cn",
    "http://hub-mirror.c.163.com"
  ],
  "insecure-registries" : [
    "192.168.20.8:34830"
  ],
  "debug" : true,
  "experimental" : true
}

然后还需要重启docker服务

sudo systemctl daemon-reload
sudo systemctl restart docker

阿里源需要用自己的账号登录阿里云后台获得只有自己有的源地址,如下:

阿里容器镜像加速

阿里源地址为:https://cr.console.aliyun.com/cn-qingdao/mirrors
insecure-registries里的镜像指的是没有权限认证的仓库,如果搭建私人仓库可以将私人仓库的地址(host+port)放在这里。

docker的命令

镜像相关

拉取/下载镜像
#NAME is images name, tag is images's version
docker pull [NAME][:TAG]
查看已有的镜像
> docker images

Usage:	docker images [OPTIONS] [REPOSITORY[:TAG]]

List images

Options:
  -a, --all             Show all images (default hides intermediate images)
      --digests         Show digests
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print images using a Go template
      --no-trunc        Don't truncate output
  -q, --quiet           Only show numeric IDs


-a,--all=true|false:列出所有的镜像文件(包括临时文件),默认为
否;
--format="TEMPLATE":控制输出格式,如.ID代表ID信息,.Repository 代表仓库信息等;
--no-trunc=true|false:对输出结果中太长的部分是否进行截断,如镜像 的ID信息,默认为是;
--digests=true|false:列出镜像的数字摘要值,默认为否; 
-f,--filter=[]:过滤列出的镜像,如 dangling=true只显示没有被使用的镜像;也可指定带有特定标注的镜像等;
-q,--quiet=true|false:仅输出 ID信息,默认为否。 

其中,对输出结果进行控制的选项如-f,--filter=[]、--no-trunc=true|false、-q,--quiet=true|false等,大部分子命令都支持。

为镜像添加标签
docker tag ubuntu:latest myubuntu:latest
查看镜像详细信息
docker inspect ubuntu:14.04
查看镜像的历史记录
docker history redis:latest
搜索镜像
docker search nginx

--automated=true|false:仅显示自动创建的镜像,默认为否;
--no-trunc=true|false:输出信息不截断显示,默认为否;
-s,--stars=X:指定仅显示评价为指定星级以上的镜像,默认为0,即 输出所有镜像。
删除镜像
docker stop redis
# 删除容器
docker rm redis
# 删除镜像
docker rmi redis

一般容器运行时直接删除镜像会提示容器运行中,不允许删除,此时可加-f强制删除(不推荐)。或者先将容器停掉然后删除。

容器相关

  • docker ps,查看运行的容器,-a查看所有容器
  • docker start|stop|restart [NAME][:TAG],启动|停止|重启容器
  • docker run -it [NAME] /bin/bash,启动一个bash终端,允许用户进行交互
  • docker create -it [NAME][:TAG],新建一个容器(不启动)
  • docker run [NAME][:TAG],新建并启动容器
  • docker logs -f [NAME]:[TAG],查看服务的日志
  • docker exec -it [NAME][:TAG] /bin/bash,进入到运行的容器中,进行操作
    • -i,--interactive=true|false:打开标准输入接受用户输入命令,默认为
      false;
    • --privileged=true|false:是否给执行命令以高权限,默认为false;
    • -t,--tty=true|false:分配伪终端,默认为false;
    • -u,--user="":执行命令的用户名或ID。
  • docker attach [NAME][:TAG],进入到运行的容器中,进行操作
    • --detach-keys[=[]]:指定退出attach模式的快捷键序列,默认是CTRL-p CTRL-q;
    • --no-stdin=true|false:是否关闭标准输入,默认是保持打开;
    • --sig-proxy=true|false:是否代理收到的系统信号给应用进程,默认为 true。

通过指定- it参数来保持标准输入打开,并且分配一个伪终端。通过exec 命令对容器执行操作是最为推荐的方式。

容器互联

容器互联可以让一个容器有访问另一个容器的权限,另一个容器并不需要将端口映射到宿主机上,可以避免暴露端口到外部网络中。

docker run -d -P --name my-service --link redis:redis

--link参数的格式为-- link name:alias,其中name是要连接的容器名
称,alias是这个连接的别名。

注:两个容器互联需要两个容器都在启动时加入--link参数,或者可使用network参数。例:创建网络:docker network create test-net;加入网络:docker network connect test-net [CONTAINER]
还可以在容器启动时使用--network=[NETWORK]来指定一个网络

env参数可以查看容器的环境变量,比如docker exec redis env

Dockerfile文件构建镜像

一个简单的例子:

mkdir nginx
cd nginx
vim Dockerfile
# 添加下面的指令并保存
FROM nginx
RUN echo '<h1>Hello, Docker Nginx!</h1>' > /usr/share/nginx/html/index.html

docker build -t nginx:v1 .
docker run -d --name mynginx -p 80:80 nginx:v1

# 访问http://127.0.0.1

Dockerfile中的指令

FROM
FROM images-name指令等同于docker pull images-name

MAINTAINER
MAINTAINER docker_user (user@docker.com)

RUN

  • RUN <shell命令>指令等同于在命令行中执行输入的命令
  • RUN ["可执行文件", "参数1", "参数2"]等同于执行了一个shell脚本,并给予了几个参数。比如:RUN "./test.sh", "dev", "offilne"

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

FROM centos
RUN yum install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
# 以上执行会创建 3 层镜像。可简化为以下格式:
FROM centos
RUN yum install wget \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && tar -xvf redis.tar.gz

如上,以&& 符号连接命令,这样执行后,只会创建 1 层镜像。

COPY
复制指令,从上下文目录(就是示例中.,即当前目录)中复制文件或者目录到容器里指定路径。

COPY [--chown=<user>:<group>] <源路径1>...  <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",...  "<目标路径>"]
  • [--chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。
  • 源路径可以使用通配符表达式(使用的是GO的路径匹配规则),比如COPY hom* /dirCOPY hom? /dir
  • 目标路径容器内的路径,不存在会自动创建

ADD
功能与COPY类似(格式相同),不同的是ADD会将路径中的tar,gzip,bzip2,xz压缩文件复制到目标路径后解压。如果是一个URL则会尝试下载这个链接的文件放到目标目录中。在需求相同时,官方推荐使用COPYADD会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。

CMD
类似于RUN(格式相同),不同的是两者的运行时间不同。

  • CMD运行于docker run命令发起时
  • RUN运行于docker build命令发起时

作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。

ENTRYPOINT
类似于 CMD 指令(格式相同),但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。

但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。

优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。

注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

FROM nginx

ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参 

假设根据上面的Dockerfile构建了一个nginx:test的镜像。

  • 不传参运行docker run nginx:test,则默认执行的是nginx -c /etc/nginx/nginx.conf
  • 传参运行docker run nginx:test -c /etc/nginx/conf/nginx.conf,则执行的是nginx -c /etc/nginx/conf/nginx.conf

ENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。

ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

ARG
构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
格式:ARG <参数名>[=<默认值>]
构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。

VOLUME
定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

作用:

  • 避免重要的数据,因容器重启而丢失,这是非常致命的。
  • 避免容器不断变大。

格式:

  • VOLUME ["<路径1>", "<路径2>"...]
  • VOLUME <路径>
    在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。

EXPOSE
声明端口,在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。

格式:EXPOSE <端口1> [<端口2>...]

WORKDIR
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。

docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。

格式:WORKDIR <工作目录路径>

通过WORKDIR设置工作目录后,Dockerfile 中其后的命令 RUN、CMD、ENTRYPOINT、ADD、COPY 等命令都会在该目录下执行。 如,使用WORKDIR设置工作目录:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

在以上示例中,pwd 最终将会在 /a/b/c 目录中执行。在使用docker run 运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。

USER
用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。

格式:USER <用户名>[:<用户组>]

HEALTHCHECK
用于指定某个程序或者指令来监控 docker 容器服务的运行状态。

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

HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。

ONBUILD
用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。

格式:ONBUILD <其它指令>

LABEL
LABEL用于为镜像添加元数据,元数以键值对的形式指定:LABEL <key>=<value> <key>=<value> <key>=<value> ...

使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。 如,通过LABEL指定一些元数据:LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"

指定后可以通过docker inspect查看:

docker inspect itbilu/test
"Labels": {
    "version": "1.0",
    "description": "这是一个Web服务器",
    "by": "IT笔录"
}

STOPSIGNAL
STOPSIGNAL用于设置停止容器所要发送的系统调用信号:STOPSIGNAL signal
所使用的信号必须是内核系统调用表中的合法的值,如:SIGKILL。

SHELL
SHELL用于设置执行命令(shell式)所使用的的默认 shell 类型:SHELL ["executable", "parameters"]

SHELL在Windows环境下比较有用,Windows 下通常会有 cmd 和 powershell 两种 shell,可能还会有 sh。这时就可以通过 SHELL 来指定所使用的 shell 类型:

FROM microsoft/windowsservercore

# Executed as cmd /S /C echo default
RUN echo default

# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default

# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello

# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello

示例Dockerfile

#设置继承自用户创建的sshd镜像
FROM sshd:Dockerfile
#下面是一些创建者的基本信息
MAINTAINER docker_user (user@docker.com) 
# 设置环境变量,所有操作都是非交互式的
ENV DEBIAN_FRONTEND noninteractive 
#注意这里要更改系统的时区设置
RUN echo "Asia/Shanghai" > /etc/timezone && \
dpkg-reconfigure -f noninteractive tzdata 
#安装跟tomcat用户认证相关的软件
RUN apt-get install -yq --no-install-recommends wget pwgen ca-certificates && \ apt-get clean && \
rm -rf /var/lib/apt/lists/*
#设置tomcat的环境变量,若读者有其他的环境变量需要设置,也可以在这里添加。 
ENV CATALINA_HOME /tomcat
ENV JAVA_HOME /jdk
#复制tomcat和jdk文件到镜像中
ADD apache-tomcat-7.0.56 /tomcat
ADD jdk /jdk
ADD create_tomcat_admin_user.sh /create_tomcat_admin_user.sh
ADD run.sh /run.sh
RUN chmod +x /*.sh
RUN chmod +x /tomcat/bin/*.sh
EXPOSE 8080
CMD ["/run.sh"]

建议

  • 容器轻量化。从镜像中产生的容器应该尽量轻量化,能在足够短的时间内停止、销毁、重新生成并替换原来的容器。
  • 使用 .gitignore。在大部分情况下,Dockerfile 会和构建所需的文件放在同一个目录中,为了提高构建的性能,应该使用 .gitignore 来过滤掉不需要的文件和目录。
  • 为了减少镜像的大小,减少依赖,仅安装需要的软件包。
  • 一个容器只做一件事。解耦复杂的应用,分成多个容器,而不是所有东西都放在一个容器内运行。如一个 Python Web 应用,可能需要 Server、DB、Cache、MQ、Log 等几个容器。一个更加极端的说法:One process per container。
  • 减少镜像的图层。不要多个 Label、ENV 等标签。
  • 对续行的参数按照字母表排序,特别是使用apt-get install -y安装包的时候。
  • 使用构建缓存。如果不想使用缓存,可以在构建的时候使用参数--no-cache=true来强制重新生成中间镜像。

Docker构建SpringBoot

  1. 添加docker的maven插件
<properties>
	<docker.image.prefix>springboot</docker.image.prefix>
</properties>

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
		<!-- Docker maven plugin -->
		<plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.2.0</version>
                <executions>
                    <execution>
                        <id>build-image</id>
                        <phase>package</phase>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <dockerHost>http://192.168.10.54:2376</dockerHost>
                    <imageName>${docker.images.prefix}/${project.artifactId}</imageName>
                    <imageTags>
                        <imageTag>${project.version}</imageTag>
                    </imageTags>
                    <forceTags>true</forceTags>
                    <dockerDirectory>${project.basedir}</dockerDirectory>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>		<!-- Docker maven plugin -->
	</plugins>
</build>
  1. 添加Dockerfile文件
FROM java:8
MAINTAINER Bennett (w2500513053@outlook.com)
VOLUME /tmp
ADD target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
  1. 开启docker的远程访问
    修改/usr/lib/systemd/system/docker.service文件,加入下面内容
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock

重新docker

systemctl daemon-reload
systemctl restart docker
  1. 使用maven打包
  2. 使用docker service中创建好的镜像,添加参数然后运行

Kubernetes(k8s)

Docker-Desktop-k8s

启动Docker桌面版带的k8s前需要使用国内镜像源下载下面的镜像

k8s.gcr.io/pause:3.2=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2
k8s.gcr.io/kube-controller-manager:v1.18.8=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.18.8
k8s.gcr.io/kube-scheduler:v1.18.8=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.18.8
k8s.gcr.io/kube-proxy:v1.18.8=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.18.8
k8s.gcr.io/kube-apiserver:v1.18.8=registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.18.8
k8s.gcr.io/etcd:3.4.3-0=registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.3-0
k8s.gcr.io/coredns:1.6.7=registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.6.7
quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1=registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.26.1
docker/desktop-storage-provisioner                               v1.1
docker/desktop-vpnkit-controller                                 v1.0

查看部署的集群

kubectl config use-context 

使用docker-desktop集群

kubectl config use-context docker-desktop 

安装管理面板(使用国内的kuboard)

kubectl apply -f https://kuboard.cn/install-script/kuboard.yaml
kubectl apply -f https://addons.kuboard.cn/metrics-server/0.3.7/metrics-server.yaml

查看pod状态

kubectl get pods -l k8s.kuboard.cn/name=kuboard -n kube-system 

获取登录dashboard的token

echo $(kubectl -n kube-system get secret $(kubectl -n kube-system get secret | grep kuboard-user | awk '{print $1}') -o go-template='{{.data.token}}' | base64 -d)

访问http://localhost:32567/,输入token登录到dashboard

kuboard官方文档

Linux安装k8s

准备环境

# 关闭防火墙:
systemctl stop firewalld
systemctl disable firewalld
# 关闭selinux:
sed -i 's/enforcing/disabled/' /etc/selinux/config $ setenforce 0
# 关闭swap:
swapoff -a $ 临时
vim /etc/fstab $ 永久
# 添加主机名与IP对应关系(记得设置主机名): $ cat /etc/hosts
192.168.23.35 k8s-master 192.168.23.36 k8s-node1 192.168.23.37 k8s-node2
# 将桥接的IPv4流量传递到iptables的链:
cat > /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF
sysctl --system

添加k8s的yum源,安装kubectlkubeletkubeadm

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
setenforce 0

yum install -y kubelet kubeadm kubectl
systemctl enable kubelet && systemctl start kubelet

部署master(在master节点执行)

由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址。

kubeadm init \
--apiserver-advertise-address=192.168.31.61 \ --image-repository registry.aliyuncs.com/google_containers \ --kubernetes-version v1.15.0 \
--service-cidr=10.1.0.0/16 \ --pod-network-cidr=10.244.0.0/16

使用kubectl工具

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes

安装网络插件(CNI)

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c11463 8878db11b/Documentation/kube-flannel.yml

如果下载失败,可以改成这个镜像地址:lizhenliang/flannel:v0.11.0-amd64

加入Kubernetes Node 在192.168.31.62/63(Node)执行。

向集群添加新节点,执行在kubeadm init输出的kubeadm join命令:

kubeadm join 192.168.23.35:6443 --token esce21.q6hetwm8si29qxwn \ --discovery-token-ca-cert-hash
sha256:00603a05805807501d7181c3d60b478788408cfe6cedefedb1f97569708be9c5

测试集群

在Kubernetes集群中创建一个pod,验证是否正常运行:

kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort 
kubectl get pod,svc

访问地址:http://[NodeIP]:[Port]

部署Dashboard

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recomm ended/kubernetes-dashboard.yaml

默认镜像国内无法访问,修改镜像地址为: lizhenliang/kubernetes-dashboard-amd64:v1.10.1

默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部:

kind: Service
apiVersion: v1
metadata:
labels:
	k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kube-system
spec:
type: NodePort
ports:
  - port: 443 
   targetPort: 8443
   nodePort: 30001
selector:
	k8s-app: kubernetes-dashboard




kubectl apply -f kubernetes-dashboard.yaml

访问地址:http://NodeIP:30001
创建service account并绑定默认cluster-admin管理员集群角色:

kubectl create serviceaccount dashboard-admin -n kube-system  
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin  
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}') 

使用输出的token登录Dashboard。

Docker + K8s + Gitlab + Jekins自动化部署

这里给个写的比较好的作者,我就不写了。
Gitlab+Jenkins Pipeline+Docker+k8s+Helm自动化部署实践