Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上。
https://www.docker.com/
由于docker的官网很慢,阅读的朋友可利用特殊的技术处理一下
本文采用windows和ubuntu操作系统进行操作
windows:10
Ubuntu:22
注意windows上我显然不会让你去安装一个docke
Docker Desktop 是一个易于安装的应用程序,使您能够构建和共享容器化应用程序和微服务。 它与 Kubernetes、Docker Compose、BuildKit 和漏洞扫描等容器工具捆绑在一起。
开发人员可以使用 Docker Dashboard 直观地管理他们所有的容器资源——并且知道 Desktop 已经为资源消耗设置了健全和安全的默认值,因此高枕无忧。 不仅如此,Docker Desktop 现在还包括 Docker Extensions,允许开发人员通过集成由 Docker 合作伙伴、社区或他们的队友构建的其他开发人员工具来释放他们的生产力!
WSL2Linux内核现在使用单独的MSl updatepackage安装
随便找个文件夹打开搜索
打开控制面板中的开启windows功能
开启
更新wsl2
这个是windows说明文档
https://docs.microsoft.com/zh-cn/windows/wsl/install
这个是下载更新链接
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
下完之后直接安装
apt-get remove docker docker-engine docker.io containerd runc
apt update
apt-get install ca-certificates curl gnupg lsb-release
add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
apt-get install docker-ce docker-ce-cli containerd.io
虚拟机(virtual machine)是在操作系统中模拟硬件设备,然后运行另一个操作系统,比如在 Windows系统里面运行Ubuntu系统,这样就可以运行任意的Ubuntu应用了。使用的是Hypervisor技术
Docker则是打包了应用所需的依赖、函数库、操作系统函数库等,这样就可以直接无视操作系统的类型,实现跨系统运行
特性 | Docker | 虚拟机 |
---|---|---|
性能 | 接近原始系统 | 较差 |
硬盘占用 | MB | GB |
启动 | 快 | 较慢 |
Docker 包括三个基本概念:
容器就是对象,镜像就是类
概念 | 说明 |
---|---|
Docker 镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。 |
Docker 容器(Container) | 容器是独立运行的一个或一组应用,是镜像运行时的实体。 |
Docker 客户端(Client) | Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。 |
Docker 主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
Docker Registry | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。 Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。 一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。 通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。 |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
我这里选择了阿里云的
以下是Ubuntu的
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://iqav8sjk.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
数据卷是宿主机中的一个目录或文件
当容器目录和数据卷目录绑定后,对方的修改会立即同步
一个数据卷可以被多个容器同时挂载
一个容器也可以被挂载多个数据卷
通过数据卷容器可以做到多容器进行数据交换
docker search mysql
docker pull mysql:8.0.30
mkdir /root/docker/mysql
cd /root/docker/mysql
docker run -id \
-p 3333:3306 \
--name=dockerMysql1 \
-v $PWD/conf:/etc/mysql/conf.d \
-v $PWD/logs:/logs \
-v $PWD/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=xxxxxxx \
mysql:8.0.30
docker exec -it dockerMysql1 /bin/bash
mysql -u root -p
通过端口映射使得外部可以访问,这个我们前面已经设置好了
打开Navicat
进行连接
连接成功
通mysql
docker run -id --name=dockerNginx1 \
-p 80:80 \
-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf \
-v $PWD/logs:/var/log/nginx \
-v $PWD/html:/usr/share/nginx/html \
nginx
docker run -id --name=dockerRedis1 -p 6888:6379 redis
systemctl
docker images
由于我之前用docker部署过所以有这些东西,实际刚下载应该是没有的
docker search xxx
docker pull xxxx
比如我要下载最新版redis
docker pull xxx:版本号
如docker pull redis:7.0.
docker rmi id号
如docker rmi 0598c2b30119
docker rmi 名称:版本
docker rmi `docker images -q`
关闭后会自动关闭
docker run -it --name=容器名 操作系统:版本
关闭后后台运行
docker run -id --name=容器名 操作系统:版本
进入容器
docker exec -it 容器名 终端
如:docker exec -it test2 /bin/bash
docker ps
docker ps -a
docker stop 容器名
docker start 容器名
docker rm 容器ID或容器名
docker ps-aq
docker rm `docker ps-aq`
docker inspect 容器名
docker run -it --name=容器名 -v 宿主机目录:容器目录 操作系统:版本
如:docker run -it --name=test -v /root/test:/root/test_container centos7
docker run -it --name=容器名 -v /容器目录 操作系统:版本
以此方式,docker会在宿主机上自动分配一个目录作为数据卷目录
如:
docker run -it --name=c1 -v /volume centos:7
docker run -it --name=c2 --volumes-from c1 centos:7
docker run -it --name=c3 --volumes-from c1 centos:7
查看数据卷目录
docker inspect c1
目录位置在Mounts的Source下
Mounts:[
{
Source:
}
]
我们可以通过dockerHub网站查询到需要的dockerfile
如:mysql的dockerfile
Linux文件系统由bootfs和rootfs两部分组成
分为容器–>镜像–>压缩文件–>镜像
docker commit 容器id 镜像名称:版本号
docker save -o 压缩文件名称 镜像名称:版本号
docker load -i 压缩文件名称
关键字 | 作用 | 备注 |
---|---|---|
FROM | 指定父镜像 | 指定dockerfile基于那个image构建 |
MAINTAINER | 作者信息 | 用来标明这个dockerfile谁写的 |
LABEL | 标签 | 用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看 |
RUN | 执行命令 | 执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN [“command” , “param1”,“param2”] |
CMD | 容器启动命令 | 提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD [“command” , “param1”,“param2”] |
ENTRYPOINT | 入口 | 一般在制作一些执行就关闭的容器中会使用 |
COPY | 复制文件 | build的时候复制文件到image中 |
ADD | 添加文件 | build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务 |
ENV | 环境变量 | 指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value |
ARG | 构建参数 | 构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数 |
VOLUME | 定义外部可以挂载的数据卷 | 指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME [“目录”] |
EXPOSE | 暴露端口 | 定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp |
WORKDIR | 工作目录 | 指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径 |
USER | 指定执行用户 | 指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户 |
HEALTHCHECK | 健康检查 | 指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制 |
ONBUILD | 触发器 | 当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大 |
STOPSIGNAL | 发送信号量到宿主机 | 该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。 |
SHELL | 指定执行脚本的shell | 指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell |
touch spring_dockerfile
FROM java:8
MAINTAINER zhangsan
ADD spring.jar app.jar
CMD java -jar app.jar
docker build -f spring_dockerfile -t 容器名 .
-p:进行端口映射
docker run -id -p 8080:8080 app
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
docker-compose up
命令来启动并运行整个应用程序。curl -L https://get.daocloud.io/docker/compose/releases/download/v2.9.0/docker-compose-`uname -s`-`uname -m` > /usr/bin/docker-compose
验证
docker-compose -v
采用yaml文件进行编写
指定本 yml 依从的 compose 哪个版本制定的。
指定为构建镜像上下文路径:
例如 webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:
version: "3.7"
services:
webapp:
build: ./dir
或者,作为具有在上下文指定的路径的对象,以及可选的 Dockerfile 和 args:
上下文路径。
指定构建镜像的 Dockerfile 文件名。
添加构建参数,这是只能在构建过程中访问的环境变量。
设置构建镜像的标签。
多层构建,可以指定构建哪一层。
version: "3.7"
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
target: prod
添加或删除容器拥有的宿主机的内核功能。
cap_add:
- ALL # 开启全部权限
cap_drop:
- SYS_PTRACE # 关闭 ptrace权限
为容器指定父 cgroup 组,意味着将继承该组的资源限制。
cgroup_parent: m-executor-abcd
覆盖容器启动的默认命令
command: ["bundle", "exec", "thin", "-p", "3000"]
指定自定义容器名称,而不是生成的默认名称。
container_name: my-web-container
设置依赖关系
version: "3.7"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
指定与服务的部署和运行有关的配置。只在 swarm(集群) 模式下才会有用
version: "3.7"
services:
redis:
image: redis:alpine
deploy:
mode:replicated
replicas: 6
endpoint_mode: dnsrr
labels:
description: "This redis service label"
resources:
limits:
cpus: '0.50'
memory: 50M
reservations:
cpus: '0.25'
memory: 20M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
可以选参数:
访问集群服务的方式。
endpoint_mode: vip
# Docker 集群服务一个对外的虚拟 ip。所有的请求都会通过这个虚拟 ip 到达集群服务内部的机器。
endpoint_mode: dnsrr
# DNS 轮询(DNSRR)。所有的请求会自动轮询获取到集群 ip 列表中的一个 ip 地址。
在服务上设置标签。可以用容器上的 labels(跟 deploy 同级的配置) 覆盖 deploy 下的 labels。
指定服务提供的模式。
replicated:复制服务,复制指定服务到集群的机器上。
global:全局服务,服务将部署至集群的每个节点。
replicas:mode 为 replicated 时,需要使用此参数配置具体运行的节点数量。
resources:配置服务器资源使用的限制,例如上例子,配置 redis 集群运行需要的 cpu 的百分比 和 内存的占用。避免占用资源过高出现异常。
restart_policy:配置如何在退出容器时重新启动容器。
rollback_config:配置在更新失败的情况下应如何回滚服务。
update_config:配置应如何更新服务,对于配置滚动更新很有用。
指定设备映射列表。
- "/dev/ttyUSB0:/dev/ttyUSB0"
自定义 DNS 服务器,可以是单个值或列表的多个值。
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
自定义 DNS 搜索域。可以是单个值或列表。
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com
覆盖容器默认的 entrypoint。
entrypoint: /code/entrypoint.sh
也可以是以下格式:
entrypoint:
- php
- -d
- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
- -d
- memory_limit=-1
- vendor/bin/phpunit
从文件添加环境变量。可以是单个值或列表的多个值。
env_file: .env
也可以是列表格式:
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。
environment:
RACK_ENV: development
SHOW: 'true'
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数:
expose:
- "3000"
- "8000"
添加主机名映射。类似 docker client --add-host。
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
以上会在此服务的内部容器中 /etc/hosts 创建一个具有 ip 地址和主机名的映射关系:
162.242.195.82 somehost
50.31.209.229 otherhost
用于检测 docker 服务是否健康运行。
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序
interval: 1m30s # 设置检测间隔
timeout: 10s # 设置检测超时时间
retries: 3 # 设置重试次数
start_period: 40s # 启动后,多少秒开始启动检测程序
指定容器运行的镜像。以下格式都可以:
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd # 镜像id
服务的日志记录配置。
driver:指定服务容器的日志记录驱动程序,默认值为json-file。有以下三个选项
driver: "json-file"
driver: "syslog"
driver: "none"
仅在 json-file 驱动程序下,可以使用以下参数,限制日志得数量和大小。
logging:
driver: json-file
options:
max-size: "200k" # 单个文件大小为200k
max-file: "10" # 最多10个文件
当达到文件限制上限,会自动删除旧得文件。
syslog 驱动程序下,可以使用 syslog-address 指定日志接收地址。
logging:
driver: syslog
options:
syslog-address: "tcp://192.168.0.42:123"
设置网络模式。
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
配置容器连接的网络,引用顶级 networks 下的条目 。
services:
some-service:
networks:
some-network:
aliases:
- alias1
other-network:
aliases:
- alias2
networks:
some-network:
# Use a custom driver
driver: custom-driver-1
other-network:
# Use a custom driver which takes special options
driver: custom-driver-2
aliases :同一网络上的其他容器可以使用服务名称或此别名来连接到对应容器的服务。
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
注:swarm 集群模式,请改用 restart_policy。
存储敏感数据,例如密码:
version: "3.1"
services:
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secret
secrets:
- my_secret
secrets:
my_secret:
file: ./my_secret.txt
修改容器默认的 schema 标签。
security-opt:
- label:user:USER # 设置容器的用户标签
- label:role:ROLE # 设置容器的角色标签
- label:type:TYPE # 设置容器的安全策略标签
- label:level:LEVEL # 设置容器的安全等级标签
指定在容器无法处理 SIGTERM (或者任何 stop_signal 的信号),等待多久后发送 SIGKILL 信号关闭容器。
stop_grace_period: 1s # 等待 1 秒
stop_grace_period: 1m30s # 等待 1 分 30 秒
默认的等待时间是 10 秒。
设置停止容器的替代信号。默认情况下使用 SIGTERM 。
以下示例,使用 SIGUSR1 替代信号 SIGTERM 来停止容器。
stop_signal: SIGUSR1
设置容器中的内核参数,可以使用数组或字典格式。
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0
在容器内安装一个临时文件系统。可以是单个值或列表的多个值。
tmpfs: /run
tmpfs:
- /run
- /tmp
覆盖容器默认的 ulimit。
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
将主机的数据卷或着文件挂载到容器里。
version: "3.7"
services:
db:
image: postgres:latest
volumes:
- "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
- "/localhost/data:/var/lib/postgresql/data"
Docker官方的Docker hub (https://hub.docker.com)是一个用于管理公共镜像的仓库,我们可以从上面拉取镜像到本地,也可以把我们自己的镜像推送上去。但是,有时候我们的服务器无法访问互联网,或者你不希望将自己的镜像放到公网当中,那么我们就需要搭建自己的私有仓库来存储和管理自己的镜像。
docker pull registry
docker run -id --name=registry -p 5000:5000 registry
浏览器访问http://ip地址:5000/v2/_catalog
如下
打开daemon.json文件位置:/etc/docker
"insecure-registries": ["ip地址:5000","127.0.0.1:5000"]
systemctl restart docker
docker start registry
docker tag 你要上传的镜像名 ip:5000/目录地址
如:
docker tag redis 192.168.112.135:5000/redis
docker push ip:5000/目录地址
如
docker push 192.168.112.135:5000/redis
docker pull ip:5000/目录地址