目录
Docker是基于Go开发的应用容器引擎,属于 Linux 容器的一种封装,提供简单易用的容器使用接口。
解决难题:
虚拟机与容器的差别
主要用途:
提供一次性的环境。比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。
提供弹性的云服务。因为 Docker 容器可以随开随关,很适合动态扩容和缩容,组建微服务架构。
当人们说 "Docker" 时,他们通常是指 Docker Engine,它是一个客户端-服务器应用程序, 由 Docker 守护进程、REST API、命令行接口(CLI)组成。
结构
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:需要卸载旧版本
# 更新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!
# 安装所需的软件包。
$ 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
# 不能直接使用存储库安装,需要使用脚本二进制安装:
# 注:其实无论什么发行版都可以通过二进制安装,也可以通过脚本自动安装,不过要注意,使用脚本前需要确认脚本是否安全,并且因为脚本是全自动,也可能会安装很多其他的东西 /滑稽
$ 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 一样有包管理器的话那就简单多了,这里举 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
# 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
# 登录到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 [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 [OPTIONS] NAME[:TAG|@DIGEST]
# 默认仓库为docker.io/library/
# 默认版本为:latest
# 所以docker pull mysql 等价于 docker pull docker.io/library/mysql:latest
# 删除镜像
docker rmi [OPTIONS] IMAGE [IMAGE...]
常用选项:
-f 强制删除图像
# 删除所有( linux 小技巧)
$ docker rmi -f $(docker images -aq)
# 或
$ docker images -qa | xargs docker rmi
# 导出镜像
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 [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 [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 [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 [OPTIONS] CONTAINER
常用选项::
--details 显示详细信息
-f,--follow 跟随日志输出
--since string 显示自时间戳
--tail string 显示行数
-t,--timestamps显示时间戳
例子:
docker logs
docker logs -f -t --tail 10 容器名或id
# 连接容器终端(进入容器)
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 容器名/id:容器内路径 主机文件路径
示例:
#拷贝容器数据到主机
docker cp 容器名:/home/file /home
#更新基础设置
docker update [OPTIONS] CONTAINER [CONTAINER...]
常用选项:
-c cpu权重
-m 内存限额
--restart 重启策略
示例:
# 更新某个容器的重启策略,使其重启自动启动
docker update --restart=always <CONTAINER ID>
# 创建卷
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 [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模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个 Network Namespace
示例:
$ docker run -tid --net=host --name docker_host1 ubuntu-base:v3
# 这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享
# 示例,独立的 docker_bri1 网络:
$ docker run -tid --net=container:docker_bri1 \
--name docker_con1 ubuntu-base:v3
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 -m="描述信息" -a="作者" 容器id 目标镜像名:[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 [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命令:
FROM 基础镜像:Centos/Ubuntu
MAINTAINER 镜像作者+邮箱
RUN 镜像构建的时候需要运行的命令
ADD 为镜像添加内容(压缩包)
WORKDIR 镜像工作目录(进入容器时的目录)
VOLUME 挂载的目录
EXPOSE 暴露端口配置
CMD/ENTRYPOINT 指定这个容器启动时要运行的命令(CMD替代先前命令,ENTRYPOINT在先前命令后追加)
COPY 类似于ADD,将文件拷贝到镜像中
ENV 构建时设置环境变量
# 每个保留关键字(指令)都必须是大写字母
# 从上到下顺序执行
# "#" 表示注释
# 每一个指令都会创建提交一个新的镜像层并提交
# 从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 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章