Java运维-Docker
容器
容器的概念
- 容器的概念在软件行业应用很广,比如 Tomcat 容器,Java 开发所使用的 Spring 容器。而今天介绍的容器,是基于操作系统特性所实现的容器化技术。它与 Tomcat 类似,也是用于存放应用的容器。区别在于 Tomcat 仅仅用于存放 Servlet 应用,而基于操作系统所实现的容器化技术所构建的容器,可以存放几乎所有应用。
- 容器是利用操作系统(Linux)的容器化技术(操作系统自带的命令或者API)所构建的一套应用运行时期的独立的标准化环境,在这套环境中集成了要运行的软件所依赖的所有其他应用、工具等,容器内的一切工具、应用是以为容器中的主应用运行而生的。
容器化的两大特性
- 标准化: 一个应用运行时期所需要的所有本地环境信息(工具、依赖等)都将集成在一个容器中,因此任意一台服务器只要支持容器化技术,都能够轻易的将一个应用直接部署起来。
- 隔离性: 容器中的环境信息与其他容器,甚至是宿主机之间都是隔离的。这个隔离包括了网络、文件系统、内存、硬盘和CPU等等关键硬件资源。我们可以在一台机器上部署多个容器,而多个容器中分别运行着不同版本 JDK 的 Java 应用,它们之间不会存在任何冲突问题。
容器的作用
- 拥有了标准化与隔离性,可以轻松的为需要部署的应用构建一套独立的运行环境,且可以在任意支持容器运行的环境中快速部署我们的应用,提高应用的交付能力
容器 VS 虚拟机
- 容器是应用程序的抽象,将应用程序代码与环境打包在一起构建一套独立的运行环境,多个容器可以在一台计算机上运行并且与其他容器共享OS内核。且每个容器之间利用用户空间来进行资源隔离,相对于操作系统来说是非常轻量的。
- 虚拟机则完全是对于一台计算机的抽象,一个操作系统上可以运行多个虚拟机,但每个虚拟机都是一个独立运行的操作系统,且有着完整的一套基于硬件设备的虚拟设备进行资源的隔离,这样的抽象方式导致虚拟机无论是在运行时的资源损耗还是启动的效率都是非常重量级的操作。
具体对比如下表格:
类别 | 容器 | 虚拟机 |
---|---|---|
操作系统 | 与主机共享 OS | 在宿主机OS之上运行虚拟机OS |
部署难度 | 非常简单 | 组件多,部署复杂 |
启动速度 | 秒级 | 分钟级 |
执行性能 | 和物理系统几乎一致 | VM会占用一部分资源 |
镜像体积 | 容器镜像是 MB 级别的 | 虚拟机镜像是GB级别的 |
管理效率 | 管理简单 | 组件相互依赖,管理复杂 |
隔离性 | 比较弱 | 彻底隔离 |
Docker
Docker的概念
- Docker 官网
- Docker 的思想来源于集装箱,集装箱最大的作用在于能够将货品标准化,并且集装箱与集装箱之间互相隔离,货物之间不会有任何影响。那么就不再需要专门的船去运输专门的货品,只要货品在集装箱内好好封存着,那就可以使用一艘大船将他们都运走。
- 对于我们来说,Docker 也担任了类似的角色,应用或者所依赖的第三方服务可以理解为货品,而 Docker 则是将我们的货品规范化管理起来,从而可以轻易的完成产品交付,环境转移等等诸多问题,并且 Docker 对于主机资源的消耗非常小,可以实现对服务器资源的最大利用
- Docker(Moby)诞生于2013年,是一款基于 Linux LXC 容器化技术的开源的容器引擎。需要注意的是,2013版原始的开源版本 “Docker” 现在不叫 “Docker” 了,而是 “Moby”。这一改变发生在 2017 年的 Docker Con 大会上,因此现在常说的 “Docker” 实际上代表的是 Docker 公司,现在市面上所能看到的 Docker 版本通常为 Docker EE(企业版)和 Docker CE(社区版),也就是收费版和免费版本的区别,而现在的 Docker CE 实际上就可以理解为 “Moby”。企业版有一些丰富的功能,收费,所以现在使用k8s。
- Docker是一个将操作系统的容器化技术封装后的容器引擎,核心功能是构建、打包和运行单个容器,不是容器。
- 作用:将应用及其依赖(代码、库、环境配置等)打包成标准化、轻量级的容器镜像。
Docker 三大概念:镜像、容器、仓库
- 镜像(Image):可以理解为一个只读的压缩包文件(可以类比于操作系统的ISO镜像),其中包含了容器运行时的所有依赖包。镜像可以用来构建容器,一个镜像可以创建多个容器
- 容器(Container): 容器是由镜像构建出的实例(可以理解为一个运行时的空间)。它可以被启动、停止、运行、删除。每个容器之间是互相隔离的、保证安全的独立空间
- 仓库(Repository):仓库是用于存放镜像的地方,类似于 Maven 仓库、Git 仓库等用途。仓库之上还有 仓库注册服务器(Registry) 的概念,上面可以存放着多个仓库,每个仓库中又有多个镜像,而每个镜像又可以有多个标签(tag)。目前Docker 官方的公开仓库是 Docker Hub,我们可以使用类似 Git 命令的方式去 pull/push 镜像。
- 如果需要构建容器,先从仓库拉取镜像,然后构建容器。
Docker的安装(CenterOS环境)
- 简介:Docker CE 是免费的 Docker 产品的新名称,Docker CE 包含了完整的 Docker 平台,非常适合开发人员和运维团队构建容器 APP。
- Docker CE 镜像:[来源] 阿里云镜像站
-
配置方法(CentOS 7(使用 yum 进行安装))
# step 1: 安装必要的一些系统工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 # Step 2: 添加软件源信息,更换镜像仓库地址为阿里 sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # PS:如果出现如下错误信息 Loaded plugins: fastestmirror adding repo from: https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo grabbing file https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo Could not fetch/save url https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to file /etc/yum.repos.d/docker-ce.repo: [Errno 14] curl#60 - "Peer's Certificate issuer is not recognized." # 编辑 /etc/yum.conf 文件, 在 [main] 下面添加 sslverify=0 参数 vi /etc/yum.conf # 配置如下---------------------- [main] sslverify=0 # ----------------------------- # Step 3: 更新并安装Docker-CE sudo yum makecache fast sudo yum -y install docker-ce # Step 4: 开启Docker服务 sudo service docker start # Step 5: 安装校验 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 # 注意: # 官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,您可以通过以下方式开启。同理可以开启各种测试版本等。 # vim /etc/yum.repos.d/docker-ee.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 加速
- 由于 Docker 默认下载镜像的仓库是在国外的(Docker Hub), 因此国内用户访问相对来说会较慢一些, 目前国内一些大公司与学校搭建了一些国内的镜像仓库, 可以让我们在下载镜像时更方便些
- 阿里云镜像仓库配置
- 注册阿里云账号,并登陆到阿里云后台,进入控制台面板
- 进入控制台以后,找到左上方的三横的功能列表按钮,在弹出来的功能列表处选择
弹性计算
下的容器镜像服务
- 进入
容器镜像服务
页面后,点击左侧菜单栏中镜像中心
下的镜像加速器
菜单获取镜像加速器地址,在操作文档处选择 Docker 所在服务器的操作系统,并按照文档提示完成配置即可
- CentOS环境下如何修改仓库地址
- 针对Docker客户端版本大于 1.10.0 的用户,您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["此处修改成你自己的加速 url"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
- 下载地址:https://mirrors.aliyun.com/docker-ce/
- 官方主页:https://www.docker.com/community-edition
常用命令
- 图中一共有6个对象:Images、Container、Host(主机)、Tarfiles、Dockerfile、Registry、Engine
- 主要是体现了Images(镜像)与其他对象之间的操作,比如将1个镜像运行为一个容器,使用run命令
镜像相关
# 从远程仓库查找镜像,若没有配置国内服务,默认从Docker Hub查询
docker search xxx
# 拉取镜像,通过 镜像名称:Tag 的方式定位镜像,其中 Tag 你可以理解为版本号 `docker pull <imageName:tag>
docker pull centos:7
# 查看本地镜像,命令来查看本地已有的镜像
docker images xxx
# 删除镜像
docker rmi centos:7
容器相关
docker run 创建且运行一个容器
- 直接通过
docker run
命令创建并运行一个容器,如果该容器的镜像在本地存在那么则直接使用本地的镜像,如果不存在那么就会从远程仓库中下载镜像,并在下载完成后将该容器创建并运行起来 - 举例:
docker run hello-world
- 直接通过
docker run 镜像名:tag
可以快速运行一个容器,不过并不是所有容器都会长时间的保持着持续运行,例如上面的hello-world
容器就仅仅只是简单的输出一段内容后既自动退出。 docker run
命令提供了许多的可选参数,你可以通过这些参数来实现对容器进行更深层的控制,以下是关于docker run
命令的详细使用方式以及相关参数说明
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] Run a command in a new container Options: --add-host list 添加一个自定义的 主机名-ip 的映射 (host:ip) -a, --attach list Attach to STDIN, STDOUT or STDERR --blkio-weight uint16 Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0) --blkio-weight-device list Block IO weight (relative device weight) (default []) --cap-add list Add Linux capabilities --cap-drop list Drop Linux capabilities --cgroup-parent string Optional parent cgroup for the container --cidfile string 将容器id写到一个指定的文件 --cpu-period int 限制 CPU 在指定周期内配合下面的配置:单位微秒:100000μs=100ms --cpu-quota int 限制 CPU 可以使用的时间:单位微秒:100000μs=100ms --cpu-rt-period int Limit CPU real-time period in microseconds --cpu-rt-runtime int Limit CPU real-time runtime in microseconds -c, --cpu-shares int CPU shares (relative weight) --cpus decimal 限制容器可以使用的 CPU 数量 --cpuset-cpus string CPUs in which to allow execution (0-3, 0,1) --cpuset-mems string MEMs in which to allow execution (0-3, 0,1) -d, --detach 容器在后台运行且容器启动后打印容器id --detach-keys string Override the key sequence for detaching a container --device list Add a host device to the container --device-cgroup-rule list Add a rule to the cgroup allowed devices list --device-read-bps list Limit read rate (bytes per second) from a device (default []) --device-read-iops list Limit read rate (IO per second) from a device (default []) --device-write-bps list Limit write rate (bytes per second) to a device (default []) --device-write-iops list Limit write rate (IO per second) to a device (default []) --disable-content-trust Skip image verification (default true) --dns list 自定义 dns 列表 --dns-option list Set DNS options --dns-search list Set custom DNS search domains --domainname string Container NIS domain name --entrypoint string Overwrite the default ENTRYPOINT of the image -e, --env list 为容器设置环境变量 name=value,可以设置多个 --env-file list 读取一个环境变量文件 --expose list Expose a port or a range of ports --gpus gpu-request GPU devices to add to the container ('all' to pass all GPUs) --group-add list 为容器添加一个组 --health-cmd string Command to run to check health --health-interval duration Time between running the check (ms|s|m|h) (default 0s) --health-retries int Consecutive failures needed to report unhealthy --health-start-period duration Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s) --health-timeout duration Maximum time to allow one check to run (ms|s|m|h) (default 0s) --help Print usage -h, --hostname string 设置容器的主机名 --init Run an init inside the container that forwards signals and reaps processes -i, --interactive 以交互模式运行容器,通常与 -t 同时使用 --ip string 设置容器的 IPv4 地址 (e.g., 172.30.100.104) --ip6 string 设置容器的 IPv6 地址 (e.g., 2001:db8::33) --ipc string IPC mode to use --isolation string Container isolation technology --kernel-memory bytes 容器中内核的可使用内存数,单位可以为 b,k,m,g。最小为 4M -l, --label list Set meta data on a container --label-file list Read in a line delimited file of labels --link list 打通当前容器和另一个容器的网络 --link-local-ip list Container IPv4/IPv6 link-local addresses --log-driver string Logging driver for the container --log-opt list Log driver options --mac-address string 设置容器 MAC 地址 (e.g., 92:d0:c6:0a:29:33) -m, --memory bytes 内存限制,格式是数字加单位,单位可以为 b,k,m,g。最小为 4M --memory-reservation bytes 内存的软性限制。格式同上 --memory-swap bytes 内存+交换分区大小总限制。格式同上。必须必-m设置的大 --memory-swappiness int Tune container memory swappiness (0 to 100) (default -1) --mount mount 加载一个磁盘到容器中 --name string 为容器设置一个名字 --network network Connect a container to a network --network-alias list Add network-scoped alias for the container --no-healthcheck Disable any container-specified HEALTHCHECK --oom-kill-disable 是否阻止 OOM killer 杀死容器,默认没设置 --oom-score-adj int 容器被 OOM killer 杀死的优先级,范围是[-1000, 1000],默认为 0 --pid string pid 命名空间,默认没有设置。当前容器只能看到容器内所运行的进程 pid。另外还有两种模式可以设置:'container:<name|id>' 查看某一个容器中的所有进程,'host'表示查看主机的所有进程 --pids-limit int Tune container pids limit (set -1 for unlimited) --privileged Give extended privileges to this container -p, --publish list 将容器中的某一个端口映射到主机,配置格式为 hostPort:containerPort -P, --publish-all 将容器中所有暴露的端口映射到主机的随机端口上 --read-only Mount the container's root filesystem as read only --restart string 容器退出时的重启策略,默认为 no,可选配置有:no,on-failure,always 其中 on-failure 可以配置重启次数如 on-failure:3 表示当容器因为失败而退出时重启,如果重启超过3次还失败则放弃重启 --rm 当容器退出时自动删除 --runtime string Runtime to use for this container --security-opt list Security Options --shm-size bytes Size of /dev/shm --sig-proxy Proxy received signals to the process (default true) --stop-signal string Signal to stop a container (default "SIGTERM") --stop-timeout int Timeout (in seconds) to stop a container --storage-opt list Storage driver options for the container --sysctl map Sysctl options (default map[]) --tmpfs list Mount a tmpfs directory -t, --tty 为容器重新分配一个伪输入终端,通常与 -i 同时使用 --ulimit ulimit Ulimit options (default []) -u, --user string 用户名或用户 id (format: <name|uid>[:<group|gid>]) --userns string User namespace to use --uts string UTS namespace to use -v, --volume list 绑定加载一个数据卷 --volume-driver string Optional volume driver for the container --volumes-from list 加载一个数据卷容器 -w, --workdir string Working directory inside the container
查看容器
-
通过
docker ps
命令可以查看目前已经被创建的容器。默认情况下你只能看到正在运行中的容器列表,如果想要看到所有的容器,那么你可以使用docker ps -a
来进行查看$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8909b024ddd9 hello-world "/hello" 1 second ago Exited (0) 1 second ago condescending_darwin
删除容器
-
当容器不再需要时,为了清除容器运行时所占用的磁盘空间,可以使用
docker rm
命令将容器中的内容全部删除$ docker rm 8909b024ddd9
停止容器
-
如果需要将一个正在运行时的容器停止,可以使用
docker stop
命令$ docker stop e40655248e77
启动容器
-
当一个容器因为一些原因停止后,如果想要再次运行起来,则可以使用
docker start
命令$ docker start e40655248e77
进入容器内部
-
有的时候,你可能需要进入容器内部去查看一些文件或执行一些相关操作,那么你可以通过
docker exec
命令来进入容器内部# it:进入当前容器,而且当前容器会占用控制台窗口 $ docker exec -it e40655248e77 /bin/bash #已经进入容器内部 [root@e40655248e77 /]# cat /etc/hostname e40655248e77 [root@e40655248e77 /]# echo "现在就是在容器内了" 现在就是在容器内了 #退出容器 [root@e40655248e77 /]# exit
并不是所有容器都支持进入容器内的,当不支持时执行 docker exec 命令可能会卡住,此时只需要按 ctrl + c 退出即可 如果需要从容器中退出只需要在容器中输入 exit 命令即可
查看容器日志
-
当我们部署一些自己的应用或第三方服务需要查看日志时,可以通过
docker logs
命令来查看容器中的日志$ docker logs e40655248e77 64 bytes from 127.0.0.1: icmp_seq=670 ttl=64 time=0.035 ms 64 bytes from 127.0.0.1: icmp_seq=671 ttl=64 time=0.032 ms 64 bytes from 127.0.0.1: icmp_seq=672 ttl=64 time=0.048 ms
如果不带任何参数,默认会将容器中所有的日志输出,如果需要跟踪日志输出或只显示最新的指定数量的日志信息,即可使用 Usage 中的相关参数来指定即可
Usage: docker logs [OPTIONS] CONTAINER Fetch the logs of a container Options: --details Show extra details provided to logs -f, --follow 跟踪日志输出,类似于 tail -f 参数的作用 --since string 按照时间切分日志,切分格式: (e.g. 2013-01-02T13:23:37) 或 (e.g. 42m for 42 minutes) --tail string 显示最新的指定数量的 -t, --timestamps 显示时间戳 --until string 显示某个时间之后的日志 (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
数据卷
- 当在容器中运行一些关键的应用如MySQL、Redis等服务,其中都会存储着一些关键数据,这些数据是希望即使删除容器也不应该被删除的,此时便需要用到数据卷了。可以将数据卷理解为文件目录的映射,可以通过 Docker 提供的相关命令,来将主机中的某一个文件目录映射到容器中,此时在容器中操作该目录下的文件时,实际上操作的就是主机中的文件。
- 数据卷相当于是容器的虚拟文件系统和主机的真实文件系统之间的一个桥梁,建立数据卷就相当于是打通了容器于主机之间的文件交互通道,可以让容器运行时所产生的数据变更被保存到主机中,能够更方便的对数据进行备份以及保护
绑定方式
匿名绑定
-
在启动容器时直接使用
-v /container_dir
即可完成匿名绑定,匿名绑定的方式将在 Docker 的 volumes 目录下生成一个 sha256 的字符串作为目录名,且指定的/container_dir
中的文件或目录会被保存在该处,匿名绑定的 volume 在容器被删除的时候,数据卷也会被删除# 运行nginx这个服务,如果没有安装包则自动下载,并在容器的volumes目录下自动生成 ”sha256字符串/www/test“目录,然后自动映射到主机的某个目录下 $ docker run --rm -d -p 80:80 -v /www/test nginx f46e0e5aeacfabcf59d70e73acc13ce9db66c08158f58baaf60d2d5babffa7c3
- 匿名绑定方式由于不知道主机的路径名称,因此如果需要查看数据卷在主机的哪个位置,需要使用
docker inspect -f '' container_id
来查看 - 即:启动容器并指定容器的某个路径,则生成该路径编码到容器volumes目录下,并自动映射到主机某个目录下。
具名绑定
-
同样是启动容器时绑定一个数据卷,不同的是可以为该数据卷起个名字
-v volume-name:container_dir
,通过名字你可以快速的定位并管理这些 volume# 运行nginx这个服务,如果没有安装包则自动下载,并在容器的volumes目录下自动生成 ”sha256字符串/www/test“目录,然后映射到主机的某个路径下的nginx-www文件目录下 $ docker run --rm -d -p 80:80 -v nginx-www:/www/test nginx 13f9d01f9e70970235a7b8fdc692f7afdcdecaaff985425d99c8a8b4d1cd7224
Bind Mount
- 绑定并加载主机的某个文件目录到容器中,这种方式是平常最常用的。在容器启动时使用
-v host_dir:container_dir
的格式来完成映射 - 场景举例分析:(容器中部署一个nginx服务)
- nginx有2个东西需要经常修改,一个是nginx.conf,一个是html文件目录下的内容,html文件目是在nginx.conf配置文件中指定的
- 由于容器可以删除,下次重新启动容器还要重新配置nginx.conf、html文件目录下的内容,那么最好是将nginx.conf与html文件目录映射到主机物理地址,这样容器后序就可以随便删除了
-
执行命令
# 运行了一个nginx容器,然后将本机目录下的html文件路径`/www/wolfcode` 与容器html文件路径’/www/wolfcode‘,进行映射。 同理将本机目录下的conf文件路径`/etc/nginx/nginx.conf` 与容器conf文件路径’/etc/nginx/nginx.conf‘,进行映射 $ docker run --rm -d -p 80:80 -v /www/wolfcode:/www/wolfcode -v /etc/nginx/nginx.conf:/etc/nginx/nginx.conf nginx
-p 80:80
:将容器的80端口映射到主机的80端口
- 将主机目录映射到容器中以后,在容器中读取到的就是主机上的文件,同时你可以在参数后配置
:ro
或:rw
方式来控制容器内是否可以针对该数据卷进行读写操作,如-v /www/wolfcode:/usr/share/nginx/html:ro
则表示容器中对/usr/share/nginx/html
目录中的文件只有只读权限
数据卷管理
-
Docker 为我们提供了一些专门用于管理数据卷的命令
docker volume
,通过下面的 Usage 来查看相关命令的使用Usage: docker volume COMMAND Manage volumes Commands: create 创建一个数据卷 inspect 显示一个或多个数据卷的详细信息 ls 查看目前已有的数据卷列表 prune 删除所有本地没有被使用的数据卷 rm 删除一个或多个数据卷
构建镜像
- Docker 提供了两种方式让我们来创建镜像,一种是将一个被修改后的容器重新打包为一个镜像,还有一种更常用的方式就是 Dockerfile,你可以利用 Dockerfile 构建一个属于你应用的专属镜像,只需要按照规定的格式完成相关的配置即可
容器构建镜像
-
有的时候你可能需要对一个已经运行的容器内的环境做出一些修改,而你也希望之后即使删除这个容器也能够保存这些变动,便于下次再启动一个新的容器,此时便可以利用
docker commit
命令将一个容器重新打包为一个镜像,这样下次便可以直接基于这个新的镜像来构建容器了# -m "描述内容“ 镜像id 仓库名称/镜像名称:版本号 $ docker commit -m "build my centos" 88468edb2a4b wolf/centos:7 sha256:ff800663234ab0eb0d821b196839fa24133df8f3c17dd70854d6c45a25aa0c09 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE wolf/centos 7 ff800663234a About a minute ago 203MB
Dockerfile构建镜像。
- Docker 为我们提供了一套约定的配置文件,该文件的作用就是描述构建镜像时所需要进行的相关操作,你只需要按照约束配置好需要构建的镜像的相关指令信息,并且将该文件的名字命名为 Dockerfile,那么你就可以直接使用
docker build
命令让 Docker 帮我们完成镜像的构建操作 -
Dockerfile 提供了许多构建镜像相关的指令,下面的是一些常用指令,其他的可以从 Docker 官方文档 查看
FROM 指定基础镜像,依赖于哪个镜像 MAINTAINER 指定维护者信息 RUN 在构建镜像的过程中,需要执行哪些命令;即在要执行的命令前加上RUN即可 ADD 即往容器中copy文件,copy后会自动解压该文件 WORKDIR 设置当前的工作目录,类似cd VOLUME 设置卷,挂载主机目录,就是前面的数据卷 EXPOSE 暴露一些端口等,容器运行后需要暴露一些端口 CMD/ENTRYPOINT 指定容器启动后默认要执行的命令 ********举例******** # 基于哪个镜像 From openjdk:8 # 维护者 MAINTAINER Leon <liugang@wolfcode.cn> # 复制文件到容器,将代码目录下(target/*-server*)的jar包,复制到容器中,然后重命名为app.jar ADD target/*-server*.jar /app.jar # 环境变量:JVM 调优参数 # 配置容器启动后执行的命令 CMD ["java","-jar","/app.jar"]
-
通过以上文件即可构建一个具有 JDK8 的且包含了一个 java 应用的容器,在项目根目录创建一个 Dockerfile 文件,打开控制台并输入以下命令进行构建镜像
# -t:构建镜像之后的名字 最后一个点"." 指的是Dockerfile这个文件的目录。由于Dockerfile在根目录,所以这里直接就是. 或者./ $ docker build -t demo-server:1.0.0 .
docker build 命令的使用格式如下
Usage: docker build [OPTIONS] DOCKERFILE_PATH | URL | - Build an image from a Dockerfile Options: --add-host list Add a custom host-to-IP mapping (host:ip) --build-arg list Set build-time variables --cache-from strings Images to consider as cache sources --cgroup-parent string Optional parent cgroup for the container --compress Compress the build context using gzip --cpu-period int Limit the CPU CFS (Completely Fair Scheduler) period --cpu-quota int Limit the CPU CFS (Completely Fair Scheduler) quota -c, --cpu-shares int CPU shares (relative weight) --cpuset-cpus string CPUs in which to allow execution (0-3, 0,1) --cpuset-mems string MEMs in which to allow execution (0-3, 0,1) --disable-content-trust Skip image verification (default true) -f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile') --force-rm Always remove intermediate containers --iidfile string Write the image ID to the file --isolation string Container isolation technology --label list Set metadata for an image -m, --memory bytes Memory limit --memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap --network string Set the networking mode for the RUN instructions during build (default "default") --no-cache Do not use cache when building the image --pull Always attempt to pull a newer version of the image -q, --quiet Suppress the build output and print image ID on success --rm Remove intermediate containers after a successful build (default true) --security-opt strings Security options --shm-size bytes Size of /dev/shm -t, --tag list Name and optionally a tag in the 'name:tag' format --target string Set the target build stage to build. --ulimit ulimit Ulimit options (default [])
容器镜像私有仓库
- 在公司中通常会搭建一个私有仓库,用于管理公司内部的镜像。为了便于服务的部署,我们会在开发完成后将服务打包成镜像,并且将其推送到公司的私有镜像仓库,当我们需要在公司内任意环境部署服务时,只需要从私有仓库中下载镜像并运行容器即可
- 部署流程:项目开发 > 打包 > 发布到仓库 > 拉取到对应环境部署
配置
- 为了容器安全考虑,Docker 默认是拒绝将镜像推送到除 Docker 官方仓库以外的其他仓库的,因此我们需要将公司的私有仓库添加到授信的仓库列表,这样才能对仓库进行后续操作
-
修改
/etc/docker/daemon.json
文件,在其中加入insecure-registries
配置$ vi /etc/docker/daemon.json # 加入如下配置即可,私有仓库的地址:端口号 { "insecure-registries": ["192.168.113.103:20000"] } $ systemctl daemon-reload $ systemctl restart docker
认证
-
通常来说,私有仓库是需要对用户进行认证的,因此在进行操作之前,我们需要先使用
docker login
命令来进行登录认证,认证通过以后才能正常操作仓库# gz-java 私有仓库的账号 $ docker login -u gz-java 192.168.113.103:20000 # gz.java 私有仓库的密码 password: gz.java Login Succeeded
推送到仓库
要将一个镜像推送到仓库,需要分成两个步骤
-
打标签: 首先需要为镜像重新打一个 tag
# 仓库地址/仓库名称/镜像名称:版本号 $ docker tag demo-server:1.0.0 192.168.113.103:20000/java/demo-server:1.0.0
-
推送: 将新打 tag 的镜像推送到仓库
$ docker push 192.168.113.103:20000/java/demo-server:1.0.0 The push refers to repository [192.168.113.103:20000/java/demo-server] 18718166a51a: Pushed edf3aa290fb3: Pushed 1.0.0: digest: sha256:1fb403755a7c5bdb50b279a849604d0ab1131943a34c0ecbd9fa799ee3b49da9 size: 236
从仓库拉取
-
当项目发布到仓库以后,由于已经配置了可信的私有仓库,因此在拉取镜像时会自动的从私有仓库先进行拉取
docker pull 192.168.113.103:20000/java/demo-server:1.0.0
容器编排
- 有的时候我们会需要涉及到在一台机器部署多个容器,那么此时再手动的每次输入相关的一堆配置命令再来启动容器,还是产生了很多无意义的重复性劳动。针对单机的多容器部署的情况,Docker 为我们提供了一个单机版本的服务编排工具
docker-compose
-
Docker-Compose 可以高效便捷的管理单机上运行的所有容器,它通过 yaml 配置文件的方式完成之前执行
docker run
命令所设置的所有参数,你可以先针对单机上的所有容器进行相关配置,配置完成后即可使用 docker-compose 对单机多容器进行高效的管理version: "2" services: nginx: conatiner_name: "nginx-demo" image: "nginx" volumes: - /www/wolfcode:/usr/share/nginx/html:ro - /etc/nginx/nginx.conf:/etc/nginx/nginx.conf networks: - demo-net ports: - "80:80" environment: NGINX_HOME=/usr/local/nginx restart: on-failure:3 networks: demo-net: driver: bridge
- 详细配置查看 Docker Compose 官方文档
-
通过以上的配置文件,即可完成对容器的统一管理,并且配合 docker-compose 所提供的命令即可完成容器的创建、启动、停止和删除等等相关操作
Define and run multi-container applications with Docker. Usage: docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...] docker-compose -h|--help Options: -f, --file FILE Specify an alternate compose file (default: docker-compose.yml) -p, --project-name NAME Specify an alternate project name (default: directory name) --verbose Show more output -v, --version Print version and exit -H, --host HOST Daemon socket to connect to --tls Use TLS; implied by --tlsverify --tlscacert CA_PATH Trust certs signed only by this CA --tlscert CLIENT_CERT_PATH Path to TLS certificate file --tlskey TLS_KEY_PATH Path to TLS key file --tlsverify Use TLS and verify the remote --skip-hostname-check Don't check the daemon's hostname against the name specified in the client certificate (for example if your docker host is an IP address) Commands: build 构建或重新构建一个服务 bundle Generate a Docker bundle from the Compose file config 验证并查看 compose 文件 create 创建一个服务 down 停止并删除容器、网络、镜像和数据卷 events Receive real time events from containers exec 在一个运行中的容器执行命令 help 获取帮助信息 kill 关闭一个容器 logs 显示服务的日志信息 pause 暂停一个服务 port 打印一个端口绑定的公开端口 ps 查看容器列表 pull 拉取镜像 push 推送镜像 restart 重启容器 rm 删除已经停止的容器 run 运行一个一次性执行的命令 scale 设置服务的容器数量 start 启动服务 stop 停止服务 unpause 恢复一个暂停的服务 up 创建并启动一个容器 version 显示 compose 的版本信息
Docker Compose
Compose 简介
- Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
Compose 安装
-
安装命令
sudo curl -L "http://mirrors.aliyun.com/docker-toolbox/linux/compose/1.9.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- 要安装其他版本的 Compose,请替换 1.24.1。
-
将可执行权限应用于二进制文件:
sudo chmod +x /usr/local/bin/docker-compose
-
创建软链:
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
-
测试是否安装成功:
docker-compose --version
- 注意: 对于 alpine,需要以下依赖包: py-pip,python-dev,libffi-dev,openssl-dev,gcc,libc-dev,和 make。
Docker Swarm
- Docker Compose:帮助在 同一个节点 上部署多个容器。
- Docker Swarm:多台机器上部署容器。开箱即用,快速部署容器。偏重容器部署
- K8s:社区活跃度高,组件丰富。微服务化,偏重应用的部署
- compose支持在 同一节点 上部署,swarm支持在多个节点上部署容器。这两者都是docker原生支持的docker集群部署方式,开箱即用,比较方便,偏重于容器的部署。
- Docker Swarm 和 Docker Compose 一样,都是 Docker 官方容器编排项目,但不同的是,Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,而 Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,对于微服务的部署,显然 Docker Swarm 会更加适合。
- 从 Docker 1.12.0 版本开始,Docker Swarm 已经包含在 Docker 引擎中(docker swarm),并且已经内置了服务发现工具,我们就不需要像之前一样,再配置 Etcd 或者 Consul 来进行服务发现配置了。
- swarm偏重的是容器的部署,而k8s偏重于应用的部署。k8s对容器的所有操作都渗透着为应用而服务的理念,比如pod是为了让联系紧密但又不适合部署在一起的应用分别部署在不同docker里面,但docker之间共享volume和network namespace方式,以便实现紧密地“交流”,在比如service是为了隐藏pod(容器的集合,下文会介绍到)的网络细节,让pod提供固定的访问入口,从而方便地让其他应用访问等。
- 在swarm中,被创建、调度和管理的最小单元就是docker。在k8s中,最小单元则是pod。