导航

Docker入门指南

Posted on 2022-09-13 08:40  Young哥哥  阅读(99)  评论(0编辑  收藏  举报

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软件包索引并允许使用储存库
$ 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命令图解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 

仓库 registry

# 搜索镜像
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]

镜像 image

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

容器 container

基础操作

# 启动容器
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

ip addr
bridge 模式

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 模式

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

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

Container 模式

Container 模式

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

None 模式

None 模式

None 模式

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

肆.常用安装


Portainer

# 可视化管理界面
# 其他类似的还有: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:

Portainer界面

Mysql

# 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

Nginx

$ 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

Registry

# 私有仓库安装示例

【本地版:

$ 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

# 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具有用于管理应用程序整个生命周期的命令:

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

Machine

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

Swarm集群

# Swarm 是使用 SwarmKit 构建的 Docker 引擎内置(原生)的集群管理和编排工具。
# Docker Swarm是 Docker 官方三剑客项目之一,提供 Docker 容器集群服务,是 Docker 官方对容器云生态进行支持的核心方案。
# 使用它,用户可以将多个 Docker 主机封装为单个大型的虚拟 Docker 主机,快速打造一套容器云平台。
# Swarm mode 内置 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多平台发布