Docker 入门指南
阅读原文时间:2023年07月10日阅读:1

Docker 入门指南

目录

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

壹.基础概念

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

解决难题:

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

虚拟机与容器的差别

主要用途:

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

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

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

结构

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

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

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

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

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

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

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

联合文件系统(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软件包索引并允许使用储存库
$ sudo apt-get update
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

# 添加Docker的官方GPG密钥
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

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

# 安装最新的Docker引擎
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

# 运行hello world
$ sudo docker run hello-world

# 显示输出:
> Hello from Docker!

Centos

# 安装所需的软件包。
$ sudo yum install -y yum-utils

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

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

# 开机自启并启动
$ sudo systemctl enable docker
$ sudo systemctl start docker

# 测试安装效果
$ docker version

Raspberry Pi OS (Raspbian)

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

$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh --mirror Aliyun
$ sudo usermod -aG docker $USER

# 开机自启,并启动
$ sudo systemctl enable docker
$ sudo systemctl start docker

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

Manjaro

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

# 安装docker
$ sudo pacman -S docker

# 完事,确认下
$ sudo docker version

# 设置开机自启并启动
$ sudo systemctl enable docker
$ sudo systemctl start docker

其他系统

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

设置国内镜像源

# 阿里加速服务:https://??????.mirror.aliyuncs.com (需自己申请个人加速服务地址,加速服务不只是提供镜像加速,还有 docker 在各种操作系统的安装文档和加速,注册地址:https://cr.console.aliyun.com/undefined/instances/mirrors)
# 或者一些其他的镜像(建议使用阿里的镜像):
# 官方 - https://registry.docker-cn.com
# 网易 - http://hub-mirror.c.163.com
# Azure 中国镜像 - https://dockerhub.azk8s.cn

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

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

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

# 然后重启服务
$ sudo systemctl daemon-reload && sudo systemctl restart docker
# 查看是否成功(看Registry Mirrors项):
$ docker info

设置用户组

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

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

# 把docker命令加入组中
$ sudo usermod -aG docker $USER

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

设置开机自启

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

# 重新启动
$ shutdown -r now
# 查看是否启动状态
$ systemctl status docker

docker-compose

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

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

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

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

# 如需卸载:
$ sudo rm /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的基本信息
$ docker version
# 系统信息,镜像和容器的数量
$ docker info 

# 查看docker事件
$ docker events [OPTIONS]

# 全部帮助
$ docker --help
# 个别命令帮助
$ docker [命令] --help
# 搜索镜像
docker search [OPTIONS] 镜像名

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

选项:
  -f,--filter filter 过滤输出
    --format string  格式化输出
    --limit int 最大搜索结果数(默认为25)
    --no-trunc 不截断输出

示例:
docker search mysql

docker login

# 登录到registry
docker login [OPTIONS] [SERVER]

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

示例:
docker login
>输入账号
>输入密码

# 登录到私有registry
docker login localhost:8080
docker login -u username -p userpasswd 192.168.1.33:5000

# 注销
docker logout [SERVER]

docker images

docker images [OPTIONS] [REPOSITORY[:TAG]]
docker images = docker image ls

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

示例:

# 只显示ID
docker images -aq

docker pull

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

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

docker rmi

# 删除镜像
docker rmi [OPTIONS] IMAGE [IMAGE...]

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

# 删除所有( linux 小技巧)
$ docker rmi -f $(docker images -aq)
# 或
$ docker images -qa | xargs docker rmi

docker import 与 export

# 导出镜像
docker export [OPTIONS] CONTAINER

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

例子:
docker export exampleimage > exampleimage.tar
# 或
docker export --output="exampleimage.tar" exampleimage
# 导入镜像
docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

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

示例:

# 远程
docker import http://example.com/exampleimage.tgz

# 本地
docker import /path/to/exampleimage.tgz
# 或
cat exampleimage.tgz | docker import - exampleimagelocal:new

# 本地目录
sudo tar -c . | docker import - exampleimagedir

基础操作

# 启动容器
docker start
# 重启容器
docker restart
# 停止容器
docker stop
# 杀掉容器
docker kill 

# 查看容器元数据(详细信息)
docker inspect
# 查看内容占用
docker stats
# 查看容器中的进程信息
docker top

docker ps

# 查看容器列表
docker ps [OPTIONS]
docker ps  = docker container ls

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

docker run

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

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

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

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

示例:
# 容器停止后自动删除
docker run --rm hello-world

# 后台运行并给它命名
docker run -itd --name uuu ubuntu

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

# 运行并映射卷到主机
docker run -p 3306:3306 --name mysql -v "$(pwd)"/docker_v/mysql/conf:/etc/mysql/conf.d mysql

docker rm

# 删除容器
docker rm [OPTIONS] CONTAINER [CONTAINER...]

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

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

docker logs

# 查看容器日志
docker logs [OPTIONS] CONTAINER

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

例子:
docker logs
docker logs -f -t --tail 10 容器名或id

docker exec

# 连接容器终端(进入容器)
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

# 也可以用 docker attach 进入容器终端

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

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

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

docker cp

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

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

docker update

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

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

示例:
# 更新某个容器的重启策略,使其重启自动启动
docker update --restart=always <CONTAINER ID>

docker volume create

# 创建卷
docker volume create [OPTIONS] [VOLUME]

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

示例:
# 创建一个卷
docker volume create hello

# 使用这个卷
docker run -d -v hello:/world busybox ls /world

挂载卷说明

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

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

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

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

# 查看所有挂载的卷:
docker volume ls

# 查看卷信息
docker volume inspect 卷名

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

示例:
# minio文件服务器,指定目录挂载
docker run -p 9000:9000 --name minio -d \
-e "MINIO_ACCESS_KEY=admin" \
-e "MINIO_SECRET_KEY=admin123456" \
-v /home/cc/minio/data:/data \
-v /home/cc/minio/config:/root/.minio minio/minio server /data

# 数据卷容器(多个容器共享一个卷)
docker run -it --name 容器02 --volumes from 容器01 镜像名/id

docker network create

# 创建一个网络
docker network create [OPTIONS] NETWORK

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

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

示例:
# 创建一个overlay 模式的网络
docker network create -d overlay my-network

# 容器连接至该网络
docker run -itd --network=my-network busybox

网络模式说明

# 查看IP
$ ip addr
# 查看docker0
$ ip addr show docker0

bridge 模式

bridge模式

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

# 新建一个网络
$ docker network create -d bridge my-net

# 运行一个容器并连接到新建的 my-net 网络
$ docker run -it --rm --name busybox1 --network my-net busybox sh

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

# 如果你有多个容器之间需要互相连接,推荐使用Docker Compose。

Host 模式

# 如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个 Network Namespace

示例:
$ docker run -tid --net=host --name docker_host1 ubuntu-base:v3

Container 模式

# 这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享
# 示例,独立的 docker_bri1 网络:
$ docker run -tid --net=container:docker_bri1 \
       --name docker_con1 ubuntu-base:v3

None 模式

None 模式

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

肆.常用安装


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

安装示例:

$ docker volume create portainer_data

$ docker run -d --name portainer --restart unless-stopped -p 9000:9000 \
-v ~/docker_v/portainer/data:/data \
-v /var/run/docker.sock:/var/run/docker.sock \
portainer/portainer-ce:latest

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

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

具体操作:

# 这里已经把配置文件my.cnf放到了~/docker_v/mysql/conf:
# 然后运行命令:
$ docker run -p 3306:3306 --name mysql \
-v ~/docker_v/mysql/conf:/etc/mysql/conf.d \
-v ~/docker_v/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-itd mysql:5.7.29


$ docker run -d -p 80:80 --name nginx \
-v /root/nginxFile/html:/usr/share/nginx/html \
-v /root/nginxFile/conf:/etc/nginx \
-v /root/nginxFile/log:/var/log/nginx \
nginx

# 如果想拷下原版的配置出来改的话:
# 新建个临时容器
$ docker run -d -p 127.0.0.1:8080:80 --rm --name mynginx -v "$PWD/html":/usr/share/nginx/html nginx

# 把容器中的nginx配置拷出来
$ docker cp mynginx:/etc/nginx .
$ docker stop mynginx

# 然后重新跑下上面 Nginx 的 docker run


# 私有仓库安装示例

【本地版:

$ docker run -d \
  -p 5000:5000 \
  --name registry
  --restart=always
  -v /opt/data/registry:/var/lib/registry \
  registry

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

【权限认证版:  

# 创建保存账号密码的文件
$ mkdir  /opt/data/auth
# 创建账号和密码
$ docker run --entrypoint htpasswd registry -Bbn username userpasswd > auth/htpasswd

$ docker run -d -p 5000:5000 --restart=always --name registry \
    -v /opt/data/registry:/var/lib/registry \
    -v /opt/data/auth:/auth \
    -e "REGISTRY_AUTH=htpasswd" \
    -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
    -e  REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
    registry

# 登录&退出
$ docker login -u username -p userpasswd 127.0.0.1:5000
$ docker logout 127.0.0.1:5000

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

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

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

# Ubuntu 16.04+, Debian 8+, centos 7
# 对于使用 systemd 的系统,在/etc/docker/daemon.json中增加如下内容
{
  "insecure-registries": [
    "192.168.199.100:5000"
  ]
}

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

# 重新启动服务:
$ sudo service docker restart

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

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

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

# 运行容器时加以下参数:
-v `pwd`/certs:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:80 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \

伍.其他构建类操作


docker commit

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

docker tag

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

示例:

docker tag id或名字 fedora/httpd:version1.0
docker tag httpd:test fedora/httpd:version1.0.test

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

docker push

docker push [OPTIONS] NAME[:TAG]

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

示例:

# 推送至私有注册表
docker image push registry-host:5000/用户名/rhel-httpd:latest
# 推送至中央注册表(需先docker login)
docker image push 用户名/rhel-httpd:latest
# 推送全部tag版本
docker image push --all-tags registry-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构建映像
docker build [OPTIONS] PATH | URL | -

常用选项:

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

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

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

dockerFile:
# 基于我编译好的一个镜像
FROM nibbbbbbbb/gdal-ubuntu-full:v1
MAINTAINER chenbihao
USER root
# 更换国内镜像源
RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
# 进入目录
WORKDIR /usr/local/
# 创建项目文件夹,并将外部文件夹内容添加进去
RUN mkdir demo ADD ./demo ./demo
# 设置编码 (gdal镜像默认编码是POSIX)
ENV LANG C.UTF-8
# 开放端口
EXPOSE 8080
# 启动命令
CMD ["java","-Dfile.encoding=utf-8","-jar","/usr/local/demo/demo.jar","--spring.profiles.active=dev"]

构建docker镜像:
$ docker build -t nibbbbbbbb/gdal-ubuntu-full:v1-app .

完成!

多阶段构建

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

比如,以下是同一个 dockerFile:

FROM golang AS build-env
ADD . /go/src/app
WORKDIR /go/src/app
RUN go get -u -v github.com/kardianos/govendor
RUN govendor sync
RUN GOOS=linux GOARCH=386 go build -v -o /go/src/app/app-server

FROM alpine
RUN apk add -U tzdata
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=build-env /go/src/app/app-server /usr/local/bin/app-server
EXPOSE 8080
CMD [ "app-server" ]

# 然后build
docker build -t cnych/docker-multi-stage-demo:latest .

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

陆.容器编排


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

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

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

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

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

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

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

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

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


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


# Swarm 是使用 SwarmKit 构建的 Docker 引擎内置(原生)的集群管理和编排工具。
# Docker Swarm是 Docker 官方三剑客项目之一,提供 Docker 容器集群服务,是 Docker 官方对容器云生态进行支持的核心方案。
# 使用它,用户可以将多个 Docker 主机封装为单个大型的虚拟 Docker 主机,快速打造一套容器云平台。
# Swarm mode 内置 kv 存储功能,提供了众多的新特性,比如:具有容错能力的去中心化设计、内置服务发现、负载均衡、路由网格、动态伸缩、滚动更新、安全传输等。使得 Docker 原生的 Swarm 集群具备与Mesos、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 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。