Docker 入门指南

目录

  1. 基础概念
  2. 安装教程
  3. 基本操作
  4. 常用安装
  5. 构建操作
  6. 容器编排

壹.基础概念

什么是Docker?

Docker是基于Go开发的应用容器引擎,属于 Linux 容器的一种封装,提供简单易用的容器使用接口。

解决难题:

  • 环境配置不一致
  • 虚拟机累赘(资源占用大、启动慢等)
虚拟机与容器的差别

虚拟机与容器的差别

主要用途:

提供一次性的环境。比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。

提供弹性的云服务。因为 Docker 容器可以随开随关,很适合动态扩容和缩容,组建微服务架构。

当人们说 “Docker” 时,他们通常是指 Docker Engine,它是一个客户端-服务器应用程序, 由 Docker 守护进程、REST API、命令行接口(CLI)组成。

docker

结构

结构

  1. 客户端调用 Docker
  2. Docker 从 Registry 拉取镜像(image)
  3. 通过镜像生成容器(container)实例

镜像 image

Docker 把应用程序及其依赖,打包在 image 文件里面。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例

image 文件是通用的。一般来说,为了节省时间,我们应该尽量使用别人制作好的 image 文件。即使要定制,也应该基于别人的 image 文件进行加工,而不是从零开始制作。

容器 container

容器是一个镜像的可运行的实例,可以使用 Docker REST API 或者 CLI 来操作容器,容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。

容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。

注册表(仓库)registry

存放镜像的地方(公有/私有)

为了方便共享,image 文件制作完成后,可以上传到网上的仓库。Docker 的官方仓库 Docker Hub 是最重要、最常用的 image 仓库。

UnionFS 联合文件系统

联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。

联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来只能看到一个文件系统。联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

镜像加载原理

Docker的镜像是由多层文件系统组成:

分层

bootfs(boot file system)主要包含 bootloader 和 kernel。bootloader 主要是引导加载kernel,完成后整个内核就都在内存中了。此时内存的使用权已由bootfs转交给内核,系统卸载 bootfs。可以被不同的 Linux 发行版共用。

rootfs(root file system),包含典型Linux系统标准目录和文件。相当于各种不同操作系统发行版(Ubuntu,Centos等)。因为底层直接用Host的kernel,rootfs只包含最基本的命令,工具和程序就可以了。 当进行修改或者更新时,会在当前镜像层上新建新的层级。

分层结构

容器启动时会在最上层创建一个可读写的容器层(其它层只读)

不同镜像的相同文件层无需再次下载

贰.安装


不同版本安装

Tips:需要卸载旧版本

Ubuntu

#更新apt软件包索引并允许使用储存库
$sudoapt-getupdate
$sudoapt-getinstall\
apt-transport-https\
ca-certificates\
curl\
gnupg\
lsb-release

#添加Docker的官方GPG密钥
$sudoapt-getinstalldocker-cedocker-ce-clicontainerd.io

#设置稳定的存储库
$echo\
"deb[arch=amd64signed-by=/usr/share/keyrings/docker-archive-keyring.gpg]https://download.docker.com/linux/ubuntu\
$(lsb_release-cs)stable"
|sudotee/etc/apt/sources.list.d/docker.list>/dev/null

#安装最新的Docker引擎
$sudoapt-getupdate
$sudoapt-getinstalldocker-cedocker-ce-clicontainerd.io

#运行helloworld
$sudodockerrunhello-world

#显示输出:
>HellofromDocker!

Centos

#安装所需的软件包。
$sudoyuminstall-yyum-utils

#使用以下命令来设置稳定的存储库。
$sudoyum-config-manager--add-repohttps://download.docker.com/linux/centos/docker-ce.repo

#安装DOCKER引擎
#(centos8此步containerd.io版本过低,解决方案:https://www.backendcloud.cn/2020/03/16/centos8installdocker/)
$sudoyuminstalldocker-cedocker-ce-clicontainerd.io

#开机自启并启动
$sudosystemctlenabledocker
$sudosystemctlstartdocker

#测试安装效果
$dockerversion

Raspberry Pi OS (Raspbian)

#不能直接使用存储库安装,需要使用脚本二进制安装:
#注:其实无论什么发行版都可以通过二进制安装,也可以通过脚本自动安装,不过要注意,使用脚本前需要确认脚本是否安全,并且因为脚本是全自动,也可能会安装很多其他的东西/滑稽

$
curl-fsSLhttps://get.docker.com-oget-docker.sh
$sudoshget-docker.sh--mirrorAliyun
$sudousermod-aGdocker$USER

#
开机自启,并启动
$sudosystemctlenabledocker
$sudosystemctlstartdocker

#
一般arm架构无法直接使用X86的image,需要使用Dockerfile重新构建arm版或使用别人编译好的arm架构版image
#可以在dockerHub搜arm或rpi
#还有常见的arm架构仓库:arm32v7、arm64v8、hypriot

Manjaro

#如果你的系统也和Manjaro一样有包管理器的话那就简单多了,这里举pacman或yay的例子:
#更新包管理器
$sudopacman-Syu

#
安装docker
$sudopacman-Sdocker

#
完事,确认下
$sudodockerversion

#
设置开机自启并启动
$sudosystemctlenabledocker
$sudosystemctlstartdocker

其他系统

#win和mac官方都有桌面版可以直接下载安装,并且还可以附带UI操作界面应用
#win版需要开启WSL2或者Hyper_v后才能安装,但是以上2者跟虚拟机不兼容
#Debian和Fedora在Docker官网文档也有安装方法

安装后的通用操作

设置国内镜像源

#阿里加速服务:https://" />#或者一些其他的镜像(建议使用阿里的镜像):
#官方-https://registry.docker-cn.com
#网易-http://hub-mirror.c.163.com
#Azure中国镜像-https://dockerhub.azk8s.cn

#
这里仅展示ubuntu和centos的操作,对于DockerforWindows、DockerforMac在设置中编辑daemon.json,增加和下面一样的字符串即可

#
使用vim编辑
$sudovim/etc/docker/daemon.json
#复制进去:
{
"registry-mirrors":["https://??????.mirror.aliyuncs.com","https://registry.docker-cn.com"]
}

#
或者命令写入:
$sudomkdir-p/etc/docker
$sudotee/etc/docker/daemon.json<<-'EOF'
{
"registry-mirrors":["https://??????.mirror.aliyuncs.com"]
}
EOF

#
然后重启服务
$sudosystemctldaemon-reload&&sudosystemctlrestartdocker
#查看是否成功(看RegistryMirrors项):
$dockerinfo

设置用户组

设置用户组,打 docker 命令不用加 sudo

#添加组,一般安装完会自动创建好了
$sudogroupadddocker

#
把docker命令加入组中
$sudousermod-aGdocker$USER

重新登录或:
$su${USER}

设置开机自启

#用systemctl管理服务的linux版本可以直接这样:
#开机自启并启动
$sudosystemctlenabledocker

#
重新启动
$shutdown-rnow
#查看是否启动状态
$systemctlstatusdocker

其他安装

docker-compose

#Win和Mac安装完docker后自带docker-compose

#
linux上安装docker-compose:
#下载
$sudocurl-L"https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname-s)-$(uname-m)"-o/usr/local/bin/docker-compose

#
设置可执行权限
$sudochmod+x/usr/local/bin/docker-compose

#
安装完成,查看版本
$docker-compose--version

#
如需卸载:
$sudorm/usr/local/bin/docker-compose

叁.基本操作

docker命令图解

小Tisp1:linux中的命令行参数

-后面跟缩写,如 -a,-q,-aq(相当于-a -q) –后面跟完整参数名,如–all,–quiet

小Tisp2:命令行中换行:

win换行: ^ linux换行: \

小Tisp3:win的路径输入:

还像在win中【d:\】吗?不对哟,是:

/d/tool/DockerDesktop/minio/data

基本信息

信息查看

#显示docker的基本信息
$dockerversion
#系统信息,镜像和容器的数量
$dockerinfo

#
查看docker事件
$dockerevents[OPTIONS]

#
全部帮助
$docker--help
#个别命令帮助
$docker[命令]--help

仓库 registry

docker search

#搜索镜像
dockersearch[OPTIONS]镜像名

#
相当于在hub.docker.com页面搜索

选项:
-f,--filterfilter过滤输出
--formatstring格式化输出
--limitint最大搜索结果数(默认为25)
--no-trunc不截断输出

示例:
dockersearchmysql

docker login

#登录到registry
dockerlogin[OPTIONS][SERVER]

常用选项:
-p,--password密码
-u,--username用户名

示例:
dockerlogin
>输入账号
>输入密码

#
登录到私有registry
dockerloginlocalhost:8080
dockerlogin-uusername-puserpasswd192.168.1.33:5000

#
注销
dockerlogout[SERVER]

镜像 image

docker images

dockerimages[OPTIONS][REPOSITORY[:TAG]]
dockerimages=dockerimagels

常用选项:
-a,--all#显示所有(默认隐藏中间图像)
--digests#显示摘要
-f,--filterfilter#过滤输出
--formatstring#格式化输出
--no-trunc#不截断输出(ID缩写是12位,不截断输出就是64位)
-q,--quiet#只显示id

示例:

#
只显示ID
dockerimages-aq

docker pull

#拉取镜像
dockerpull[OPTIONS]NAME[:TAG|@DIGEST]

#
默认仓库为docker.io/library/
#默认版本为:latest
#所以dockerpullmysql等价于dockerpulldocker.io/library/mysql:latest

docker rmi

#删除镜像
dockerrmi[OPTIONS]IMAGE[IMAGE...]

常用选项:
-f强制删除图像

#
删除所有(linux小技巧)
$dockerrmi-f$(dockerimages-aq)
#
$dockerimages-qa|xargsdockerrmi

docker import 与 export

#导出镜像
dockerexport[OPTIONS]CONTAINER

常用选项:
-o,--output写入文件,而不是STDOUT

例子:
dockerexportexampleimage>exampleimage.tar
#
dockerexport--output="exampleimage.tar"exampleimage
#导入镜像
dockerimport[OPTIONS]file|URL|-[REPOSITORY[:TAG]]

常用选项:
-c,--change将Dockerfile指令应用于创建的映像(支持的Dockerfile指令:CMD|ENTRYPOINT|ENV|EXPOSE|ONBUILD|USER|VOLUME|WORKDIR)
-m,--message设置导入图像的提交消息
--platformAPI1.32+;如果服务器支持多平台,则设置平台

示例:

#
远程
dockerimporthttp://example.com/exampleimage.tgz

#
本地
dockerimport/path/to/exampleimage.tgz
#
catexampleimage.tgz|dockerimport-exampleimagelocal:new

#
本地目录
sudotar-c.|dockerimport-exampleimagedir

容器 container

基础操作

#启动容器
dockerstart
#重启容器
dockerrestart
#停止容器
dockerstop
#杀掉容器
dockerkill

#
查看容器元数据(详细信息)
dockerinspect
#查看内容占用
dockerstats
#查看容器中的进程信息
dockertop

docker ps

#查看容器列表
dockerps[OPTIONS]
dockerps=dockercontainerls

常用选项:
-a,--all显示所有容器(默认显示正在运行)
-f,--filter过滤输出
--format使用Go模板格式化输出
-n,--last显示n个最后创建的容器
-l,--latest显示最新创建的容器
--no-trunc不要截断输出
-q,--quiet仅显示容器ID
-s,--size显示文件总大小

docker run

#运行容器
dockerrun[OPTIONS]IMAGE[COMMAND][ARG...]

#
run的时候如果本地没有镜像的话,会自动执行拉取操作

常用选项:
-d,--detach在后台运行容器并打印容器ID
-e,-envlist设置环境变量
-h,--hostnamestring容器主机名
--mountmount绑定卷
--namestring分配名称
--network连接到网络
--rm退出时自动删除容器
-v,-volumelist映射卷
-p指定容器的端口如-p8080:8080
例子:
-pip:主机端口:容器端口
-p主机端口:容器端口
-p容器端口

-i交互式操作。
-t--tty分配一个伪TTY连接终端
-m--memorybytes内存限制
--privileged赋予最高权限(危,无限制,有主机权限)
--restartstring重启策略,参数示例:
--restart=always自启
--restart=on-failure:3非正常退出重试3次
--restart=unless-stopped不尝试启动


示例:
#容器停止后自动删除
dockerrun--rmhello-world

#
后台运行并给它命名
dockerrun-itd--nameuuuubuntu

#
run并且以终端模式进入该容器
dockerrun-itubuntu/bin/bash
#输入exit回车停止并退出容器
#或快捷键Ctrl+P+Q不停止容器的退出

#
运行并映射卷到主机
dockerrun-p3306:3306--namemysql-v"$(pwd)"/docker_v/mysql/conf:/etc/mysql/conf.dmysql

docker rm

#删除容器
dockerrm[OPTIONS]CONTAINER[CONTAINER...]

常用选项:
-f,--force强制删除正在运行的容器(使用SIGKILL)
-l,--link删除指定的链接
-v,--volumes删除与容器关联的匿名卷

示例:
#删除指定容器不能删除正在运行的容器,如果强制删除rm-f
dockerrm容器id
#删除所有容器
dockerrm-f$(dockerps-aq)
#删除所有容器
dockerps-a-q|xargsdockerrm

docker logs

#查看容器日志
dockerlogs[OPTIONS]CONTAINER

常用选项::
--details显示详细信息
-f,--follow跟随日志输出
--sincestring显示自时间戳
--tailstring显示行数
-t,--timestamps显示时间戳

例子:
dockerlogs
dockerlogs-f-t--tail10容器名或id

docker exec

#连接容器终端(进入容器)
dockerexec[OPTIONS]CONTAINERCOMMAND[ARG...]

#
也可以用dockerattach进入容器终端

常用选项:
-d,--detach在后台运行命令
-e,-env环境变量
-i,--interactive即使未连接STDIN仍保持打开状态(交互式操作)
-t,--tty分配伪TTY(终端)

#
同上面的run中操作一样,这一步可以在运行后进入到容器中,如:
dockerexec-ituuu/bin/bash

#
区别
#dockerexec进入容器后开启一个新的终端,可以在里面操作(常用)
#dockerattach进入容器正在执行的终端,不会启动新的进程

docker cp

#拷贝容器中的文件
dockercp容器名/id:容器内路径主机文件路径

示例:
#拷贝容器数据到主机
dockercp容器名:/home/file/home

docker update

#更新基础设置
dockerupdate[OPTIONS]CONTAINER[CONTAINER...]

常用选项:
-ccpu权重
-m内存限额
--restart重启策略

示例:
#更新某个容器的重启策略,使其重启自动启动
dockerupdate--restart=always

其他操作

docker volume create

#创建卷
dockervolumecreate[OPTIONS][VOLUME]

选项:
-d,--driver默认local指定卷驱动程序名称
--label设置卷的元数据
--name指定卷名
-o,--opt设置驱动程序特定选项

示例:
#创建一个卷
dockervolumecreatehello

#
使用这个卷
dockerrun-d-vhello:/worldbusyboxls/world

挂载卷说明

容器数据卷
#将容器内的目录,挂载到宿主机上或其他容器内,实现同步和共享,并且删除日期后挂载到本地的文件也不会消失

#
指定目录挂载:
dokcerrun-it-v主机内目录:容器内目录镜像名/id

#
匿名挂载:
dockerrun-d-v容器内目录镜像名/id

#
具名挂载
dockerrun-d-v卷名:容器内目录镜像名/id

#
查看所有挂载的卷:
dockervolumels

#
查看卷信息
dockervolumeinspect卷名

#
所有docker容器内的卷,在未指定主机内目录时,都会创建在:/var/lib/docker/volumes/卷名/_data下

示例:
#minio文件服务器,指定目录挂载
dockerrun-p9000:9000--nameminio-d\
-e"MINIO_ACCESS_KEY=admin"\
-e"MINIO_SECRET_KEY=admin123456"\
-v/home/cc/minio/data:/data\
-v/home/cc/minio/config:/root/.miniominio/minioserver/data

#
数据卷容器(多个容器共享一个卷)
dockerrun-it--name容器02--volumesfrom容器01镜像名/id

docker network create

#创建一个网络
dockernetworkcreate[OPTIONS]NETWORK

常用选项:
-d,--driver驱动程序,默认bridge,可选overlay或第三方或自定义
--config-from从中复制配置的网络
--ipv6启用IPv6网络
--label在网络上设置元数据

network创建参数挺多的,这里不赘述,感兴趣可以看下官网文档

示例:
#创建一个overlay模式的网络
dockernetworkcreate-doverlaymy-network

#
容器连接至该网络
dockerrun-itd--network=my-networkbusybox

网络模式说明

#查看IP
$ipaddr
#查看docker0
$ipaddrshowdocker0

bridge 模式

bridge模式

#当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥
#这个docker0也作为容器的默认网关,主机也可以ping通容器,但是容器之间是隔离的
#不写–net参数,默认就是bridge模式。使用dockerrun-p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables-tnat-vnL查看。

#
新建一个网络
$dockernetworkcreate-dbridgemy-net

#
运行一个容器并连接到新建的my-net网络
$dockerrun-it--rm--namebusybox1--networkmy-netbusyboxsh

#
加入系统网络的应用,可以互相ping通,如我可以在其他加入了my-net的容器里:
$pingbusybox
>PINGbusybox(172.19.0.2):56databytes
>64bytesfrom172.19.0.2:seq=0ttl=64time=0.064ms
>64bytesfrom172.19.0.2:seq=1ttl=64time=0.143ms

#
如果你有多个容器之间需要互相连接,推荐使用DockerCompose。
Host 模式
Host 模式
#如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的NetworkNamespace,而是和宿主机共用一个NetworkNamespace

示例:
$dockerrun-tid--net=host--namedocker_host1ubuntu-base:v3
Container 模式
Container 模式
#这个模式指定新创建的容器和已经存在的一个容器共享一个NetworkNamespace,而不是和宿主机共享
#示例,独立的docker_bri1网络:
$dockerrun-tid--net=container:docker_bri1\
--namedocker_con1ubuntu-base:v3
None 模式
None 模式

None 模式

#Docker容器拥有自己的NetworkNamespace,但是,并不为Docker容器进行任何网络配置(如有需要,自己手动配置)

肆.常用安装


Portainer

#可视化管理界面
#其他类似的还有:Rancher、cAdvisor

安装示例:

$
dockervolumecreateportainer_data

$
dockerrun-d--nameportainer--restartunless-stopped-p9000:9000\
-v~/docker_v/portainer/data:/data\
-v/var/run/docker.sock:/var/run/docker.sock\
portainer/portainer-ce:latest

安装后能很方便的管理 docker:

Portainer界面

Mysql

#MySQL(5.7.19)的默认配置文件是/etc/mysql/my.cnf文件。
#如果想要自定义配置,建议向/etc/mysql/conf.d目录中创建.cnf文件。

具体操作:

#
这里已经把配置文件my.cnf放到了~/docker_v/mysql/conf:
#然后运行命令:
$dockerrun-p3306:3306--namemysql\
-v~/docker_v/mysql/conf:/etc/mysql/conf.d\
-v~/docker_v/mysql/data:/var/lib/mysql\
-eMYSQL_ROOT_PASSWORD=123456\
-itdmysql:5.7.29

Nginx

$dockerrun-d-p80:80--namenginx\
-v/root/nginxFile/html:/usr/share/nginx/html\
-v/root/nginxFile/conf:/etc/nginx\
-v/root/nginxFile/log:/var/log/nginx\
nginx

#
如果想拷下原版的配置出来改的话:
#新建个临时容器
$dockerrun-d-p127.0.0.1:8080:80--rm--namemynginx-v"$PWD/html":/usr/share/nginx/htmlnginx

#
把容器中的nginx配置拷出来
$dockercpmynginx:/etc/nginx.
$dockerstopmynginx

#
然后重新跑下上面Nginx的dockerrun

Registry

#私有仓库安装示例

【本地版:

$
dockerrun-d\
-p5000:5000\
--nameregistry
--restart=always
-v/opt/data/registry:/var/lib/registry\
registry

#
用curl查看仓库中的镜像
$curl-XGET127.0.0.1:5000/v2/_catalog
#查看镜像列表
$curl-XGET127.0.0.1:5000/v2/image_name/tags/list

【权限认证版:

#
创建保存账号密码的文件
$mkdir/opt/data/auth
#创建账号和密码
$dockerrun--entrypointhtpasswdregistry-Bbnusernameuserpasswd>auth/htpasswd

$
dockerrun-d-p5000:5000--restart=always--nameregistry\
-v/opt/data/registry:/var/lib/registry\
-v/opt/data/auth:/auth\
-e"REGISTRY_AUTH=htpasswd"\
-e"REGISTRY_AUTH_HTPASSWD_REALM=RegistryRealm"\
-eREGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd\
registry

#
登录&退出
$dockerlogin-uusername-puserpasswd127.0.0.1:5000
$dockerlogout127.0.0.1:5000


【外网访问-白名单版(前面2版之一的基础上):

#
如果不想用127.0.0.1:5000作为仓库地址,而是用局域网或者外网IP访问,会有错误。
#这是因为Docker默认不允许非HTTPS方式推送镜像。我们可以通过Docker的配置选项来取消这个限制

#
Ubuntu14.04,Debian7Wheezy:
#对于使用upstart的系统而言,编辑/etc/default/docker文件,在其中的DOCKER_OPTS中增加如下内容:
DOCKER_OPTS="--insecure-registries=192.168.199.100:5000"

#
Ubuntu16.04+,Debian8+,centos7
#对于使用systemd的系统,在/etc/docker/daemon.json中增加如下内容
{
"insecure-registries":[
"192.168.199.100:5000"
]
}

#
对于DockerforWindows、DockerforMac在设置中编辑daemon.json增加和上边一样的字符串即可。

#
重新启动服务:
$sudoservicedockerrestart


【外网访问-https版(前面2版之一的基础上):

#
创建证书目录
$mkdir-pcerts
#生成证书的操作这里不赘述,将你生成的或者已有的.crt和.key文件直接拷贝到certs路径

#
如果使用的是intermediate证书:
#若是.crt和.pem文件:
$catdomain.crtintermediate-certificates.pem>certs/domain.crt
#若是.crt和IntermediateCA.crt文件
$catssl_certificate.crtIntermediateCA.crt>certs/domain.crt

#
运行容器时加以下参数:
-v`pwd`/certs:/certs\
-eREGISTRY_HTTP_ADDR=0.0.0.0:80\
-eREGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt\
-eREGISTRY_HTTP_TLS_KEY=/certs/domain.key\

伍.其他构建类操作


推送镜像

docker commit

#提交容器成为一个新镜像
dockercommit-m="描述信息"-a="作者"容器id目标镜像名:[tag]

docker tag

#给某个镜像创建一个标签(标记版本号)
dockertagSOURCE_IMAGE[:TAG]TARGET_IMAGE[:TAG]

示例:

dockertagid或名字fedora/httpd:version1.0
dockertaghttpd:testfedora/httpd:version1.0.test

#
要推送至私有注册表时需要加上私有地址和端口:
dockertag0e5574283393myregistryhost:5000/fedora/httpd:version1.0

docker push

dockerpush[OPTIONS]NAME[:TAG]

常用选项:
-a,--all-tags将所有标记的图像推送到存储库中

示例:

#
推送至私有注册表
dockerimagepushregistry-host:5000/用户名/rhel-httpd:latest
#推送至中央注册表(需先dockerlogin)
dockerimagepush用户名/rhel-httpd:latest
#推送全部tag版本
dockerimagepush--all-tagsregistry-host:5000/用户名/rhel-httpd

构建镜像

dockerFile

#新建一个dockerFile,从头构建一个属于自己的镜像。

dockerFile命令:

FROM基础镜像:Centos/Ubuntu
MAINTAINER镜像作者+邮箱
RUN镜像构建的时候需要运行的命令
ADD为镜像添加内容(压缩包)
WORKDIR镜像工作目录(进入容器时的目录)
VOLUME挂载的目录
EXPOSE暴露端口配置
CMD/ENTRYPOINT指定这个容器启动时要运行的命令(CMD替代先前命令,ENTRYPOINT在先前命令后追加)
COPY类似于ADD,将文件拷贝到镜像中
ENV构建时设置环境变量

#
每个保留关键字(指令)都必须是大写字母
#从上到下顺序执行
#"#"表示注释
#每一个指令都会创建提交一个新的镜像层并提交

docker build

#从Dockerfile构建映像
dockerbuild[OPTIONS]PATH|URL|-

常用选项:

--add-host添加自定义主机到IP的映射(host:ip)
--build-arg设置构建时变量
--compress使用gzip压缩构建上下文
--file,-fDockerfile的名称(默认为“PATH/Dockerfile”)
--label设置图像的元数据
-m,--memory内存限制
--rmtrue成功构建后删除中间容器
-t,--tag格式的标签
--target设置要构建的目标构建阶段。
--ulimitUlimit选项

整体流程:
#构建镜像(文件名为Dockerfile时-f可省略,并且最后的.不要忽略)
dockerbuild-f文件路径-t标签.
#运行镜像
dockerrun
#发布镜像
dockerpush

实战例子(基于GDAL环境部署):

dockerFile:
#基于我编译好的一个镜像
FROMnibbbbbbbb/gdal-ubuntu-full:v1
MAINTAINERchenbihao
USERroot
#更换国内镜像源
RUNsed-is@/archive.ubuntu.com/@/mirrors.aliyun.com/@g/etc/apt/sources.list
#进入目录
WORKDIR/usr/local/
#创建项目文件夹,并将外部文件夹内容添加进去
RUNmkdirdemoADD./demo./demo
#设置编码(gdal镜像默认编码是POSIX)
ENVLANGC.UTF-8
#开放端口
EXPOSE8080
#启动命令
CMD["java","-Dfile.encoding=utf-8","-jar","/usr/local/demo/demo.jar","--spring.profiles.active=dev"]

构建docker镜像:
$dockerbuild-tnibbbbbbbb/gdal-ubuntu-full:v1-app.

完成!

多阶段构建

#多阶段构建可以在一个Dockerfile中使用多个FROM语句。
#每个FROM指令都可以使用不同的基础镜像,并表示开始一个新的构建阶段。
#你可以很方便的将一个阶段的文件复制到另外一个阶段,在最终的镜像中保留下你需要的内容即可。

比如,以下是同一个dockerFile:

FROMgolangASbuild-env
ADD./go/src/app
WORKDIR/go/src/app
RUNgoget-u-vgithub.com/kardianos/govendor
RUNgovendorsync
RUNGOOS=linuxGOARCH=386gobuild-v-o/go/src/app/app-server

FROMalpine
RUNapkadd-Utzdata
RUNln-sf/usr/share/zoneinfo/Asia/Shanghai/etc/localtime
COPY--from=build-env/go/src/app/app-server/usr/local/bin/app-server
EXPOSE8080
CMD["app-server"]

#
然后build
dockerbuild-tcnych/docker-multi-stage-demo:latest.

#
这样实现了先在go环境中编译,编译完后复制到新的alpine镜像中(因为alpine只有5MB)

陆.容器编排


限于篇幅原因这里不细讲了,仅大致介绍。

Compose、Machine 和 Swarm 集群是 Docker 官方容器编排三剑客。

Kubernetes(k8s)是 google 开源的一个拥有强大生态的容器编排平台。

Compose

#Compose是用于定义和运行多容器Docker应用程序的工具。
#通过Compose,你可以使用YAML文件来配置应用程序的服务。然后,使用一个命令,就可以从配置中创建并启动所有服务。
#Compose可在所有环境中工作:生产,开发,测试以及CI工作流。
#使用Compose基本上是一个三步过程:

#
使用定义您的应用环境,Dockerfile以便可以在任何地方复制它。
#定义组成应用程序的服务,docker-compose.yml以便它们可以在隔离的环境中一起运行。
#运行dockercomposeup,然后Dockercompose命令启动并运行您的整个应用程序。

一个docker-compose.yml看起来像这样:

version:"3.9"#optionalsincev1.27.0
services:
web:
build:.
ports:
-"5000:5000"
volumes:
-.:/code
-logvolume01:/var/log
links:
-redis
redis:
image:redis
volumes:
logvolume01:{}

#
Compose具有用于管理应用程序整个生命周期的命令:

#
启动,停止和重建服务
#查看正在运行的服务的状态
#流运行服务的日志输出
#在服务上运行一次性命令

Machine

#DockerMachine是Docker官方提供的一个工具,它可以帮助我们在远程的机器上安装Docker,或者在虚拟机host上直接安装虚拟机并在虚拟机中安装Docker。
#我们还可以通过docker-machine命令来管理这些虚拟机和Docker。
#DockerMachine支持多种后端驱动,包括虚拟机、本地主机和云平台等。

Swarm集群

#Swarm是使用SwarmKit构建的Docker引擎内置(原生)的集群管理和编排工具。
#DockerSwarm是Docker官方三剑客项目之一,提供Docker容器集群服务,是Docker官方对容器云生态进行支持的核心方案。
#使用它,用户可以将多个Docker主机封装为单个大型的虚拟Docker主机,快速打造一套容器云平台。
#Swarmmode内置kv存储功能,提供了众多的新特性,比如:具有容错能力的去中心化设计、内置服务发现、负载均衡、路由网格、动态伸缩、滚动更新、安全传输等。使得Docker原生的Swarm集群具备与Mesos、Kubernetes竞争的实力。

Kubernetes

#Kubernetes缩写是k8s(k+8个字母+s)
#Google在2014年开源了Kubernetes项目。
#Kubernetes是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。Kubernetes拥有一个庞大且快速增长的生态系统。Kubernetes的服务、支持和工具广泛可用。

#
容器是打包和运行应用程序的好方式。在生产环境中,你需要管理运行应用程序的容器,并确保不会停机。例如,如果一个容器发生故障,则需要启动另一个容器。如果系统处理此行为,会不会更容易?
#这就是Kubernetes来解决这些问题的方法!Kubernetes为你提供了一个可弹性运行分布式系统的框架。Kubernetes会满足你的扩展要求、故障转移、部署模式等。例如,Kubernetes可以轻松管理系统的Canary部署。

#
Kubernetes提供:

-服务发现和负载均衡
Kubernetes可以使用DNS名称或自己的IP地址公开容器,如果进入容器的流量很大,Kubernetes可以负载均衡并分配网络流量,从而使部署稳定。
-存储编排
Kubernetes允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。
-自动部署和回滚
你可以使用Kubernetes描述已部署容器的所需状态,它可以以受控的速率将实际状态更改为期望状态。例如,你可以自动化Kubernetes来为你的部署创建新容器,删除现有容器并将它们的所有资源用于新容器。
-自动完成装箱计算
Kubernetes允许你指定每个容器所需CPU和内存(RAM)。当容器指定了资源请求时,Kubernetes可以做出更好的决策来管理容器的资源。
-自我修复
Kubernetes重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。
-密钥与配置管理
Kubernetes允许你存储和管理敏感信息,例如密码、OAuth令牌和ssh密钥。你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。
导图

本文由 mdnice 多平台发布