docker
介绍
docker 是一个容器,基于进程封装隔离的虚拟化技术。容器是一个技术类型,docker则是当下最流行的一个容器方案。
docker和其他容器与传统容器最大的区别在于,一个是系统级,一个是进程级。
Docker 底层技术主要包括 Namespaces,Cgroups 和 rootfs。
Cgroups 控制组技术是用来限制、记录和隔离系统资源(包括CPU、内存、磁盘输入输出等)分配的关键技术。
Namespaces 用来隔离容器。
docker 可以快速构建、分享、运行应用。而且是跨平台、进程隔离的。
核心概念:
- network:网络
- volume:卷
- image:镜像
- container:容器
安装
首先安装docker环境,安装后的主机叫docker主机或者docker host
参照官网文档安装即可。
配置docker安装源,因为国内网络环境,直接下载会比较慢。
sh 代码解读复制代码# 配置docker yum源。
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 启动& 开机启动docker; enable + start 二合一
systemctl enable docker --now
配合镜像源地址,可以加速下载。
sh 代码解读复制代码# 配置加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://your_preferred_mirror",
"https://dockerhub.icu",
"https://docker.registry.cyou",
"https://docker-cf.registry.cyou",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://mirror.baidubce.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.iscas.ac.cn",
"https://docker.rainbond.cc"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
查看版本
shell代码解读复制代码docker --version
查看帮助
shell代码解读复制代码docker cmd --hlep
基本操作
镜像操作
下载镜像
shell代码解读复制代码docker pull image_name:tag
查看本地镜像
shell代码解读复制代码docker images
删除一个镜像
shell代码解读复制代码docker rmi image_id
i
表示 镜像(image)
查看具体镜像的历史记录
shell代码解读复制代码docker history image_id
可以查看镜像的构建历史,包括每一步的操作。
因为镜像的构建过程,就是一层层叠加起来的。
容器操作
创建容器
创建容器并不会启动,只有运行才会启动。
shell代码解读复制代码docker create [option] image
运行容器(在容器中执行一个命令)
运行容器时会创建并启动。
shell代码解读复制代码docker run [option] image [command] [arg...]
但这样的启动,占用当前会话窗口,一旦退出,容器也会停止。所以需要加一些参数
shell代码解读复制代码docker run -d --name myimage -p 80:80 image
上面的命令表示,创建一个名为myimage的后台运行容器,并且将容器的80端口映射到宿主机的80端口。
-d
表示后台运行--name
表示容器名-p
表示端口映射-v
表示挂载目录或卷 有2种模式:-v /宿主机目录:/容器目录
表示挂载目录-v 卷名:/容器目录
表示挂载卷
--network
表示指定网络
查看运行中的容器
shell代码解读复制代码docker ps
查看所有的容器
shell代码解读复制代码docker ps -a
启动一个容器
shell代码解读复制代码docker start container_id
停止一个容器
shell代码解读复制代码docker stop container_id
停止多个容器,可以使用docker stop $(docker ps -q)
重启一个容器
shell代码解读复制代码docker restart container_id
删除一个容器
shell代码解读复制代码docker rm container_id
-f
表示强制删除正在运行的容器
查看容器的日志
shell代码解读复制代码docker logs container_id
- -f 表示实时查看日志
- -t 表示显示时间戳
顺便提一下,查看docker引擎日志:
如果是CentOS,可以使用journalctl -u docker.service
查看。
查看容器的状态
shell代码解读复制代码docker stats container_id
进入容器(在容器中执行一个命令)
shell代码解读复制代码docker exec -it container_id /bin/bash
-it
表示进入交互模式,-i
表示标准输入,-t
表示分配一个伪终端。
/bin/bash
表示进入容器后使用bash,可简写为bash
docker attach
进入容器,但退出时,容器会停止。docker exec
则不会
分享社区
登录
-
登录docker hub,获取用户名和密码
-
命令行登录,会提示输入用户名和密码
sh代码解读复制代码docker login
命名
shell代码解读复制代码docker tag image username/image:tag
推送
shell代码解读复制代码docker push username/image:tag
建议推送一个最新版的,例如命名为 hlw/image:latest
存储
目录挂载
可以解决,容器内数据持久化问题,数据修改方便。容器停止后,数据还在宿主机上。
启动时添加参数
shell代码解读复制代码-v /宿主机目录:/容器内目录
卷映射
初始是以里面的目录为准,容器里面的东西,外面也会有。启动后可以随便改,2边一样。
启动时添加参数
shell代码解读复制代码-v 卷名:/容器内目录
启动后,统一放在 /var/lib/docker/volumes/卷名
目录下
对于mac用户,docker 虚拟机才是我创建容器的真正的宿主机,所以需要进入虚拟机内部操作。如下命令,可以进入虚拟机内部,查看卷映射的目录。
shell代码解读复制代码stty -echo -icanon && nc -U ~/Library/Containers/com.docker.docker/Data/debug-shell.sock && stty sane # ls -al /var/lib/docker/overlay2/
目录挂载与卷映射的区别:
- 写法上:目录挂载用的是宿主机路径,卷映射用的是卷名。
- 卷可以被docker管理,可以备份、迁移。
- 目录挂载性能更好,灵活性高;卷相反
绑定挂载和数据卷的传播覆盖原则
- 当绑定挂载和数据卷是空的时候,容器内目录的内容会传播到数据卷中
- 当绑定挂载和数据卷都不是空的时候,容器内目录的内容会被数据卷中的内容覆盖
使用 docker volume 命令可以管理卷
网络
docker的网络模式,用来解决容器与容器之间、容器与宿主机之间的通信问题。
默认他们是不互联互通的
docker每启动一个容器,都会自动分配一个虚拟的私有网络。使用容器的ip加端口可以互相访问。
docker0是默认的网络。不支持域名访问
自己创建网络,在容器内部可以使用容器名来互相访问
docker的网络模式:
- bridge:桥接模式,默认的网络。缺点:宿主机以外的世界无法访问
- host:主机模式,容器与宿主机共享网络。
- none:无网络模式,容器没有网络。
- container:容器模式,容器与另一个容器共享网络。
创建自定义网络
shell代码解读复制代码docker network create --driver bridge mynet
--driver
表示驱动,默认为bridge
启动容器时指定网络
shell代码解读复制代码docker run -d --name myimage --network mynet image
--network
表示指定网络
Docker Compose
批量管理容器的工具
- 创建一个compose.yml文件
- 参照官方文档编写
上线:docker compose up -d
下线: docker compose down
启动: docker compose start x1 x2
其他
- 更新yaml文件,再重上线只会启动修改的容器
默认
构建镜像
当从hub中下载的镜像,不能满足需求时,就需要构建自己的镜像了。
一般有2种方法:
- 使用docker commit命令,提交更改
- 使用docker build + Dockerfile构建
保存镜像-文件
提交镜像
将容器的存储层保存为镜像文件。相当于在原有镜像的基础上,新增了一层。
shell代码解读复制代码docker commit -m "change something" container_id newimage:tag
-m
表示提交的描述信息
备注:不推荐使用这种方式,因为这种在存储层修改的东西有很多文件改动和添加,会导致镜像及其臃肿;另外在存储层的操作都是黑箱操作,只有制作镜像的人知道,但时间一长也很快忘记,后期维护也很痛苦。
保存为文件
shell代码解读复制代码docker save image -o file.tar
-o
表示输出文件
从文件加载镜像
shell代码解读复制代码docker load -i file.tar
Dockerfile
构建自定义镜像
- 编写Dockerfile
如何编写Dockerfile,参照官方文档说明编写
官方文档 - 构建镜像
docker build -f Dockerfile -t image:tag .
镜像分层存储 基础组件可以公用,节省空间
最佳实践
- 启动一个容器,需要考虑(参照官方文档说明编写)
- 有没有端口需要映射出来,使用 -p 参数
- 有没有目录或者配置文件需要映射出来,使用 -v 参数
- 需不需要传入一个环境变量,使用 -e 参数
操作实践
搭建nginx服务
任务:
- 搭建一个nginx服务,端口映射到8080,
- 并且进行目录挂载,将nginx的默认页面改为自定义页面。
- 将配置文件映射到宿主机,方便修改。
操作步骤:
-
官网查找镜像
-
下载镜像
docker pull nginx
docker images
//查看镜像 -
运行容器
sh代码解读复制代码docker run -d --name mynginx -p 8080:80 \ -v /Users/hlw/docker-workspace/nginx-html:/usr/share/nginx/html \ -v nginx-conf:/etc/nginx nginx docker ps // 查看容器 docker exec -it mynginx bash // 进入容器 docker stop mynginx // 停止容器 docker start mynginx // 启动容器 docker logs mynginx // 查看日志 docker rm -f mynginx // 删除容器
搭建 redis 主从集群
任务:
- 搭建一个redis主从复制环境,端口映射到6379和6380。
- 数据持久化到宿主机上。
- 使用自定义网络。
操作步骤:
-
官网查找镜像
docker pull redis
docker images
//查看镜像 -
创建自定义网络
docker network create --driver bridge mynet
这一步主要是让他们在同一个网络中
-
创建挂载目录
-
主节点
-
创建数据目录
mkdir -p /Users/hlw/docker-workspace/app/rd2/data
创建配置文件mkdir -p /Users/hlw/docker-workspace/app/rd2/conf
-
编写配置文件
/Users/hlw/docker-workspace/app/rd2/conf/redis.conf
conf代码解读复制代码# 服务端口 默认6379 port 6379 # 关闭保护模式,允许远程连接 protected-mode no # 密码 requirepass 123456
-
-
从节点
-
创建数据目录
mkdir -p /Users/hlw/docker-workspace/app/rd1/data
创建配置文件mkdir -p /Users/hlw/docker-workspace/app/rd1/conf
-
编写配置文件
/Users/hlw/docker-workspace/app/rd1/conf/redis.conf
conf代码解读复制代码# 服务端口 默认6379 port 6379 # 关闭保护模式,允许远程连接 protected-mode no # 密码 requirepass 123456 # 主节点密码 masterauth 123456 # 配置主从复制 从节点默认只读 ## redis5.0后新版本配置 replicaof redis01 6379 ## redis5.0之前配置,新版本Redis也还可以用,我部署时确定6.0版本还是可用的 # slaveof 172.16.8.186 6379
replicaof redis01 6379
这里的 redis01 就是主节点的容器名,要和自定义网络中的容器名一致。
-
-
-
运行容器
-
创建主节点
shell代码解读复制代码docker run -d -p 6379:6379 \ -v /Users/hlw/docker-workspace/app/rd2/data:/data \ -v /Users/hlw/docker-workspace/app/rd2/conf/redis.conf:/etc/redis/redis.conf \ --network mynet --name redis01 \ redis \ redis-server /etc/redis/redis.conf
redis-server /etc/redis/redis.conf
指定配置文件以启动redis-server进程 -
创建从节点
shell代码解读复制代码docker run -d -p 6380:6379 \ -v /Users/hlw/docker-workspace/app/rd1/data:/data \ -v /Users/hlw/docker-workspace/app/rd1/conf/redis.conf:/etc/redis/redis.conf \ --network mynet --name redis02 \ redis \ redis-server /etc/redis/redis.conf
-
搭建redis集群
redis集群使用相当广泛,拥有数据分片,负载均衡,高可用,故障恢复等特性。
任务:搭建一个3主3从的redis集群
简要步骤:
- 创建网络
- 创建结点目录,目录包含配置文件和数据目录
- 编写配置文件
- 启动redis容器结点
- 使用redis-cli命令创建集群
- 验证
创建网络
shell代码解读复制代码docker network create redis-net
默认桥接模式,宿主机之外无法访问内部redis
创建结点目录
shell代码解读复制代码mkdir -p {7000,7001,7002,7003,7004,7005}/conf
编写配置文件
conf代码解读复制代码port 6379 bind 0.0.0.0 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip
# 根据节点修改(7000-7005) cluster-announce-port 7000 # 根据节点修改(17000-17005) cluster-announce-bus-port 17000 appendonly yes
将
替换为宿主机IP,文件保存到 7000/conf
目录下,其他节点同理。
启动redis容器结点
shell代码解读复制代码for port in 7000 7001 7002 7003 7004 7005; do docker run -d \ --name redis-${port} \ --net redis-net \ -p ${port}:6379 \ -p 1${port}:16379 \ -v $(pwd)/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \ -v $(pwd)/${port}/data:/data \ redis redis-server /usr/local/etc/redis/redis.conf done
使用redis-cli命令创建集群
shell代码解读复制代码redis-cli --cluster create \
:7000 \ :7001 \ :7002 \ :7003 \ :7004 \ :7005 \ --cluster-replicas 1
验证
shell 代码解读复制代码# 连接任意结点
redis-cli -c -h localhost -p 7000
cluster nodes
cluster info
评论记录:
回复评论: