参考
一、什么是docker
docker
是开源的应用容器引擎,相比 virtual machine 更加轻量、更加便捷。docker提出build once, run anywhere, configure once, run anywhere
,日常开发使用docker
的过程中我也是深有体会 —— 不会出现不同环境部署同一部署包表现不一致的情况、不用担心出现因软件安装依赖的缺失或者版本不对导致安装失败等等的问题。
docker和vm架构的比较:
可见,使用VM
还需要安装Guest OS
(即用户操作系统),而Docker Engine
则运行在宿主机上,单单启动速度 docker 就甩了 vm 几条街了。docker 还共享了底层二进制库文件更加轻量。
二、docker安装
1. 获取安装权限(非root用户安装,root用户跳过此步骤)
如果服务器禁止使用root
登录,我们可以将以下两种方法安装:
1.1 使用sudo获取root权限 (sudo提权)
# 让管理员通过root用户账号增加一个test用户
sudo adduser test
# 设置test账户密码
passwd test
# 将test用户加入到sudoers
echo 'test ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
1.2 将当前用户添加到docker用户组
这里可以让root用户操作,或者root用户使用使用sudo获取root权限
临时释放sudo权限,用户安装好后收回sudo权限。
# 查看是否存在docker用户组
cat /etc/group | grep docker
# 不存在则创建docker用户组
sudo groupadd docker
# 方式一:将登录用户加到docker用户组
sudo gpasswd -a $USER docker
# 方式一:更新用户组 (或者重启docker)
newgrp docker
# 或者方式二(test是创建的用户名,aG表示 append groups):
sudo usermod -aG docker test
# 测试docker命令是否可以正常使用
docker ps
2. 安装docker - CentOS7
2.1 卸载旧docker (可选,第一次安装跳过)
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine docker-ce -y
2.2 删除镜像、容器、配置文件等内容 (可选,第一次安装跳过)
rm -rf /var/lib/docker
2.3 安装所需要的软件包
yum-utils 提供了 yum-config-manager ,并且 device mapper 存储驱动程序需要 device-mapper-persistent-data 和 lvm2。
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
2.4 设置仓库源地址
sudo yum-config-manager --add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 缓存yum信息,提高检索效率
yum makecache fast
2.5 安装docker
sudo yum install docker-ce docker-ce-cli containerd.io
2.6 设置开机自启
systemctl start docker.service
systemctl enable docker.service
2.7 启动docker
sudo systemctl start docker
# 验证是否安装成功
docker version
2.8 运行 hello-world 映像来验证是否正确安装
sudo docker run hello-world
3. 安装docker - Ubantu
3.1 卸载旧版本
Docker 的旧版本被称为 docker,docker.io 或 docker-engine 。如果已安装,请卸载它们:
# 删除软件包而保留软件的配置文件
sudo apt-get remove docker docker-engine docker.io containerd runc
# 会同时清除软件包和软件的配置文件
sudo apt-get purge docker-ce
# 删除镜像、容器、配置文件等内容
sudo rm -rf /var/lib/docker
3.2 设置仓库
# 更新apt索引包
sudo apt-get update
# 安装apt依赖包(通过http的方式获取仓库)
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# 添加 Docker 的官方 GPG 密钥 (验证软件来源, 类似MD5)
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# 设置稳定版仓库
sudo add-apt-repository \
"deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/ \
$(lsb_release -cs) \
stable"
3.3 有了仓库(数据源),开始安装docker
sudo apt-get update && apt-get install -y docker-ce docker-ce-cli containerd.io
# 验证是否安装成功
docker version
4. 修改docker registry镜像源(改为阿里云)
4.1 登录阿里云获取镜像加速地址
步骤:阿里云>容器镜像服务>镜像加速器: https://xxxxx.mirror.aliyuncs.com
或者
使用其他国内公共的镜像源(菜鸟教程里面有列举部分,可以去找找)
4.2 配置镜像地址
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://cll2207n.mirror.aliyuncs.com"]
}
EOF
# 重启服务
sudo systemctl daemon-reload
sudo systemctl restart docker
4.3 验证镜像源是否配置成功
docker info
三、docker感悟
docker是cs架构,我们的服务器上安装好docker的客户端(cli)和服务器(deamon),然后命令行发送docker pull
到服务器(server),然后服务器拉取远端的Docker Registry的镜像,最终获取镜像到本地。
容器可以看作镜像的实例,类比java:Image container = new Image();
。
container
是我们通过docker run
构建出来的容器,可以构建多份。这还不能类比于普通的软件安装包
,一般一个系统同一个程序安装包只能安装一个,但
docker 因为容器的隔离性
所以只要硬件资源够,就可以构建很多份同一个镜像的容器。比如一个linux环境的服务器,我可以构建5个、10个mysql,不用去考虑环境变量冲突等等问题。
四、docker常用命令
1. 基本命令
# 查看docker信息
docker info
# 查看docker版本
docker version
# 看docker images的大小, 启动/停止的容器数量等等
docker system df
# 删除所有无用的镜像、容器、网络、卷
docker system prune
2. 镜像命令
2.1 docker images:列出本地镜像
语法:
docker images [OPTIONS] [REPOSITORY[:TAG]]
OPTIONS说明:
- -a :列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层);(--all,含中间映像层)
- --digests :显示镜像的摘要信息;(manifest清单的sha256sum,用不上)
- -f :显示满足条件的镜像;(--filter过滤d)
- --format :指定返回值的模板文件;(go的模板格式,用不上)
- --no-trunc :显示完整的镜像信息;(don't trancate output,不要截断输出,可以看完整的image id。完整的image id是Manifest内容(一个json)的config部分的有关镜像配置文件sha256sum的值)
- -q :只显示镜像ID。(--quiet,安静——只显示id)
同一个仓库源可以有多个TAG,表示这个仓库源的不同版本。我们可以使用REPOSITORY:TAG来定义不同的镜像。如果不指定一个镜像的版本标签,例如只使用tomcat,docker将默认使用tomcat:latest镜像。
2.2 镜像搜索
# 搜索仓库MySQL镜像
docker search mysql
# --filter=stars=600:只显示 starts>=600 的镜像
docker search --filter=stars=600 mysql
docker search -f stars=600 mysql
# --no-trunc 显示镜像完整 DESCRIPTION 描述
docker search --no-trunc mysql
# --automated :只列出 AUTOMATED=OK 的镜像
docker search --filter=is-automated=true mysql
参数说明:
NAME: 镜像仓库源的名称
DESCRIPTION: 镜像的描述
OFFICIAL: 是否 docker 官方发布
STARS: 类似 Github 里面的 star,表示点赞、喜欢的意思。
AUTOMATED: 自动构建。
2.3 镜像下载
语法:
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
# 下载Redis官方最新镜像,相当于:docker pull redis:latest
docker pull redis
# 下载仓库所有Redis镜像
docker pull -a redis
# 下载私人仓库镜像
docker pull bitnami/redis
# 指定tag(版本)的mysql镜像
docker pull mysql:5.7
2.4 镜像删除
# 单个镜像删除,相当于:docker rmi redis:latest
docker rmi redis
# 强制删除 (针对基于镜像有运行的容器进程)
docker rmi -f redis
# 多个镜像删除,不同镜像间以空格间隔
docker rmi -f redis tomcat nginx
# 删除本地全部镜像
docker rmi -f $(docker images -q)
2.5 镜像构建
# 编写dockerfile
cd /docker/dockerfile
vim mycentos
# 构建docker镜像(-f:指定dockerfile路径,-t:指定tag)
docker build -f /docker/dockerfile/mycentos -t mycentos:1.1
3. 容器命令
3.1 新建并启动容器
# -i :terminal 表示分配一个伪终端,-t :以交互模式运行容器 --name :为容器指定一个名称
docker run -i -t --name myTomcat
# -d :detach 分离,表示后台运行容器 -p :宿主机端口:容器端(publish)
docker run -d -p 80:8080 myTomcat
# -v :volumn表示挂载卷(必备,不然容器内外交换不了数据)。-e 时间环境变量(必备,不然保存时间错误) -v /etc/localtime:/etc/localtime:ro 也是解决时间错误问题。
docker run --name tomcat -p 8080:8080 -v /volume/tomcat/data/:/usr/local/tomcat/webapps -v /volume/tomcat/upload/:/usr/local/tomcat/upload -v /etc/localtime:/etc/localtime:ro -e TZ="Asia/Shanghai" -d tomcat
# 启动一个或多个停止的容器
docker start tomcat
# 重启
docker restart tomcat
3.2 查看容器
# 查看正在运行的容器(ps:process status,有进程状态表示正在运行)
docker ps
# 查看正在运行的容器的ID
docker ps -q
# 查看正在运行+历史运行过的容器(所有容器)
docker ps -a
# 显示运行容器总文件大小
docker ps -s
# 显示最近创建容器
docker ps -l
# 显示最近创建的3个容器
docker ps -n 3
# 不截断输出
docker ps --no-trunc
3.3 容器日志
# 查看tomcat容器日志 (日志文件大的情况下不推荐)
docker logs tomcat
# 查看容器tomcat从2022年01月01日后的最新10条日志。
docker logs --since="2022-01-01" --tail=10 tomcat
# 查看最近30分钟的日志
docker logs --since 30m tomcat
# 查看某时间段的日志
docker logs --since="2022-01-01T09:00:37" --until "2022-01-05T16:23:37" tomcat
# 查看tomcat容器日志,参数:-f follow,跟踪日志输出;-t 显示时间戳;--tail 仅列出最新N条容器日志;(强烈推荐)
docker logs -f -t --tail=20 tomcat
3.4 进入、退出容器
# 在 centos 容器中打开新的交互模式终端,可以启动新进程,参数:-i 即使没有附加也保持STDIN 打开;-t 分配一个伪终端
docker exec -it tomcat /bin/bash
# 退出
exit
3.5 容器的停止和删除
# 停止一个运行中的容器
docker stop tomcat
# 杀掉一个运行中的容器
docker kill tomcat
# 删除一个已停止的容器
docker rm tomcat
# 删除一个运行中的容器
docker rm -f tomcat
# 删除多个容器
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
## -v 删除容器,并删除容器挂载的数据卷
docker rm -v tomcat
3.6 容器的其他命令
# top 语法格式:docker top [OPTIONS] CONTAINER [ps OPTIONS]
# 列出 tomcat 容器中运行进程
docker top tomcat
# 查看所有运行容器的进程信息
for i in `docker ps |grep Up|awk '{print $1}'`;do echo \ &&docker top $i; done
# 获取容器 tomcat 的元信息
docker inspect tomcat
# 获取容器 mysql 的ip(有用,容器内ip连接要这个)
# 一般是这种地址:172.17.0.2
docker inspect --format='{{.NetworkSettings.IPAddress}}' mysql
# 除了volumn之外,可以通过 docker cp 实现容器内外数据互通
docker cp /home/1.sql mysqlMaster:/home/tmp/1.sql
# 根据 容器 生成镜像,不推荐,没有dockerfile的详细步骤,这个镜像就像一个黑盒
docker commit -a="author" -m="memo" [tomcat容器ID] mytomcat:v1.1
五、使用docker需要注意的点
1. docker run可配置的其他参数
- --restart=always: 当 Docker 重启时,容器会自动启动。
- --privileged=true:容器内的 root 拥有真正 root 权限,否则容器内 root 只是外部普通用户权限。
外部普通用户权限
就是你进入到容器会发现一些root命令执行不了。
2. 容器内部的时间错误
时间不一致的4中解决办法:
1、【镜像未生成前】 在 Dockerfile 中设置时区: (一般我们不会创建镜像,用不到)
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/TZ /etc/localtime && echo TZ > /etc/timezone
2、【镜像生成后 && 容器未创建】 创建并启动容器时:(推荐)
docker run --name -v /etc/localtime:/etc/localtime:ro -e TZ="Asia/Shanghai" ...
3、【镜像生成后 && 容器启动】 容器外,宿主机中修改:(补救用)
3.1 docker cp /etc/localtime [容器ID或者NAME]:/etc/localtime
3.2.1 不存在则新建:echo "Asia/shanghai" > /etc/timezone
3.2.2 docker cp /etc/timezone tomcat:/etc/timezone
4、【镜像生成后 && 容器启动】 容器中 (用不上)
apk add tzdata
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone
通过date
和date -R
验证,一个是服务器内日期,一个是时区,两个都正确才是 ok 的。
3. 容器日志大小限制
公司运行了 gitlab 的容器,一年后日志膨胀到2.4G,导致docker写失败,最终宕机起不来。
3.1 删除日志文件(临时解决)
- docker 日志存放在
/var/lib/docker/containers
目录中,进入目录,执行du -sh * | sort -h
找到大文件。 - 发现
/var/lib/docker/containers/5c0c836b5aaf2088e04d4df1ed9cc3aa770f300ca097b9a8c70416983ed31bd8
这个容器目录下日志文件占了2.4G。 - 进入
容器id
命名的目录,find /var/lib/docker/containers -name *.log
找到日志文件。 sudo sh -c "cat /dev/null > ${log_file}"
,${log_file}
替换成要删除的文件名。
3.2 docker run 指定大小(单个容器解决)
# max-size 单个文件大小 max-file 最大文件个数
docker run -it --log-opt max-size=10m --log-opt max-file=3 tomcat
3.3 全局配置(最优方案)
创建或修改文件/etc/docker/daemon.json
,并增加以下配置:
vi /etc/docker/daemon.json
{"registry-mirrors": ["https://registry.docker-cn.com"],
"log-driver":"json-file",
"log-opts": {"max-size":"100m", "max-file":"3"}
}
log-driver:日志驱动。默认就是json-file
。
max-size=50m,意味着一个容器日志大小上限是50M。
max-file=3,意味着一个容器最多有三个日志,分别是id-json.log、(id+1)-json.log、(id+2)-json.log。如果超过最大值,则会删除最旧的文件。仅在 max-size 设置时有效,默认为5。不过已存在的容器不会生效,需要重建才可以。
# 重启服务生效
sudo systemctl daemon-reload
sudo systemctl restart docker