学习docker
简介
docker是为了简化外网服务器软件环境部署的工作。现在初浅的理解是,可以在linux机器上通过docker单独安装mysql,nginx,应用程序的也可以跑在一个docker之上。
Docker 包括三个基本概念:
镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
- 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
- 仓库(Repository):仓库可看着一个代码控制中心,用来保存镜像。
安装
使用脚本一口气安装好。
1 | curl -fsSL https://test.docker.com -o test-docker.sh |
参考了腾讯在线实验 菜鸟入门 可以很快速的将docker部署到你的服务器上。
- 可能需要卸载掉老的docker
1 | $ sudo yum remove docker \ |
- 设置仓库
1 | $ sudo yum install -y yum-utils \ |
- 安装
1 | sudo yum install docker-ce docker-ce-cli containerd.io |
安装完成之后,可以通过docker -v来查看当前docker的版本信息。
- 使用国内加速
创建或修改 /etc/docker/daemon.json 文件
1 | { |
基本操作
- 运行一个容器
1 | sudo systemctl start docker |
密码生成脚本
1 | import random |
更多指令可以后续补充
安装mysql
1 | ## 拉取mysql5.7版本 |
设置docker的子目录
1 | docker run -d -p 3306:3306 --name my_mariadb -v /data/mariadb/data/:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mariadb:lastest |
将本地端口 3306 映射到 docker 端口 3306
安装nginx
1 | ## 拉取版本 |
扩展
后续如果有时间,可以再去研究一下 docker compose & swarm;dockerfile之类的东西。再做记录。
修改docker ulimit
1 | [How to increase number of open files limit]](<https://mtyurt.net/post/docker-how-to-increase-number-of-open-files-limit.html>) |
服务器的网络ip地址修改了之后,需要重启docker
直接通过docker搭建centos7的环境,会安装一些必要的工具
1 | docker pull centos:7 |
报错
安装时错误
1 | System.InvalidOperationException: |
使用管理员执行一次netsh winsock reset
。
1 | PS C:\Windows\system32> netsh winsock reset |
启动报错
Reached end of stream before finding a line seperator
这个是由于现在没有足够的资源启动服务器。
利用nginx反向代理解决跨域的问题
先使用指令将一个docker Nginx部署出来
1 | ## 创建存放位置 |
意图就是如果访问根的时候,就去读取资源信息,如果访问了/api/的东西,将会去掉/api/前缀,保持参数不动专发给内部的服务器,这样就不会有跨域的问题。
1 |
|
ubuntu安装
https://www.runoob.com/docker/ubuntu-docker-install.html
1 |
|
docker随系统启动
docker-run命令详解这个页面下面搜索Restart policies (--restart)
。
实例:docker run --restart=always redis
.
The following example starts a Redis container and configures it to always restart unless it is explicitly stopped or Docker is restarted.
docker run -d —restart unless-stopped redis
This command changes the restart policy for an already running container named redis.
docker update —restart unless-stopped redis
可选值:
no:不自动重启容器。
on-failure[:max-retries]:在容器失败时自动重启,可选指定最大重试次数。
unless-stopped:除非明确停止容器,否则在容器退出时自动重启。
always:无论容器以何种方式退出,均自动重启。
docker 需要创建用户组
1 | groupadd docker |
https://blog.csdn.net/carefree2005/article/details/121427448
docker Dockerfile 创建 image 最后跑起来
1 | # 通过 Dockerfile 定义的规则,构建一个image,可以取名字 |
docker 已经在运行的镜像如何修改暴露的端口
1 | # 查看当前启动的 docker 实例 |
清理掉已经删除掉的docker 对应的 volume
1 | # 先通过命令找出当前跑的全部 container . 第一列就是 container id。我们可以使用这个container id 继续查询出对应的 volume |
修改docker映射端口
不仅仅是dockerfile里面需要暴露端口,而且在run的时候,需要将端口指定出来。
使用修改配置文件的方式来搞定这个事情。
我们对比一下设置正常的redis配置。
1 | { |
具体操作:
1 | # 关闭机器上全部的docker |
安装PostgreSQL14
1 | docker run --name my-postgreSQL -e POSTGRES_PASSWORD=12345678 -e POSTGRESQL_USER=postgres -e POSTGRESql_DB=mydatabase -p 5432:5432 -d postgres:14 |
查看docker里面的日志
初次使用docker的时候,发现无法使用 grep 。
docker logs nginx 2>&1
stackoverflow-finding-a-string-in-docker-logs
I wonder if the docker logs command itself prints to stderr instead of stdout. –
Code-Apprentice
this can happen if the container is logging to stderr, piping works only for stdout, so try:
docker logs nginx 2>&1 | grep “127.”
“2>&1” will tells the shell to redirect stderr to stdout and give the output to grep using pipe.
docker logs -f -n 10 container_name | grep ‘height=’
使用dockerfile编译成image
1 | docker build -f Dockerfile -t bsc-image . |
使用 docker-compose 部署一套 nginx
https://cloudinfrastructureservices.co.uk/install-nginx-with-docker-compose/
PostgreSQL
https://www.commandprompt.com/education/how-to-install-and-set-up-docker-postgresql-environment/
1 | docker run --name postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres |
限制机器的cpu、带宽、内存(好像需要升级docker-compose才能用)*
暂时没有用起来。
1 | docker run --cpus=2 my_image |
设置 valoume
docker run —volume 主机地址:宿机地址 -p 主机端口:宿机端口 —name container名称 -d image名称
通过 network 命令打通两个 docker container
1 | # 创建一个network,其中有很多中模式,默认就是bridge |
将 docker 编译出来,并且运行起来;
1 | docker build -t spider_image:v1 . |
从docker中拷贝进出文件
1 | docker cp docker_prometheus:/etc/prometheus/prometheus.yml $PWD |
使用 docker-compose
https://github.com/docker/compose/releases/tag/v2.23.1
下载然后复制到:
sudo mv ./docker-compose-linux-x86_64 /usr/local/bin/docker-compose
ubuntu 如何安装 docker
https://www.runoob.com/docker/ubuntu-docker-install.html
docker image 常用
要共享 Docker 镜像给其他机器,通常有几个步骤,主要涉及到保存镜像、传输镜像文件以及在目标机器上加载镜像。以下是一些方法:
方法一:使用 Docker Hub
保存镜像: 如果你的镜像已经构建并且你有 Docker Hub 账号,可以使用以下命令将镜像保存为 tar 文件:
1
docker save -o my-golang-app.tar my-golang-app
上传到 Docker Hub: 使用
docker push
命令将保存的 tar 文件上传到 Docker Hub。1
2
3docker login # 登录到 Docker Hub
docker tag my-golang-app <你的用户名>/my-golang-app:版本号
docker push <你的用户名>/my-golang-app:版本号在其他机器上拉取镜像: 在其他机器上,登录到 Docker Hub 并拉取你的镜像。
1
2docker login
docker pull <你的用户名>/my-golang-app:版本号
方法二:使用本地文件
保存镜像: 使用
docker save
命令将镜像保存为 tar 文件。1
docker save -o my-golang-app.tar my-golang-app
传输文件: 将保存的 tar 文件传输到目标机器,可以使用 scp、rsync 等工具。
1
scp my-golang-app.tar user@remote-machine:/path/to/destination
加载镜像: 在目标机器上,使用
docker load
命令加载保存的 tar 文件。1
docker load -i /path/to/destination/my-golang-app.tar
方法三:使用 Docker 镜像仓库
使用私有 Docker 镜像仓库: 如果你有一个私有 Docker 镜像仓库(比如 Harbor、Nexus 等),可以将镜像推送到私有仓库,然后在其他机器上拉取。
在其他机器上拉取镜像: 在其他机器上,使用
docker pull
命令从私有仓库拉取镜像。
无论你选择哪种方法,都需要在目标机器上确保已经安装 Docker,并且具有适当的权限。通过上述步骤,你就能在不同机器上轻松共享和使用相同的 Docker 镜像。
如何使用命令行将某个容器的network切换
1 | docker stop node_exporter |
/var/log/journal
目录通常是由 systemd 日志守护进程(systemd-journald)使用的,用于存储二进制日志文件。这些日志文件可能会占用大量的磁盘空间,因此有时候需要清理。
要清理 /var/log/journal
目录,可以按照以下步骤操作:
1. 检查当前日志的使用情况
首先,检查当前日志的磁盘使用情况:1
sudo journalctl --disk-usage
这会显示当前日志文件占用的空间大小。
2. 清理旧的日志文件
你可以使用 journalctl
命令来清理旧的日志文件。例如,保留最近7天的日志,删除其他的:1
sudo journalctl --vacuum-time=7d
你还可以通过指定最大占用空间来清理日志文件。例如,保留不超过100M的日志文件:1
sudo journalctl --vacuum-size=100M
3. 手动删除
如果需要手动删除日志文件,你可以直接删除 /var/log/journal
目录中的文件:1
sudo rm -rf /var/log/journal/*
请注意,手动删除可能会导致日志服务中断,因此一般建议使用 journalctl
提供的清理命令。
4. 配置自动清理
你还可以配置 systemd-journald 自动清理日志文件。在 /etc/systemd/journald.conf
文件中进行配置,例如:1
2
3
4[Journal]
SystemMaxUse=100M
SystemMaxFileSize=10M
MaxRetentionSec=1month
然后重启 systemd-journald
服务以使配置生效:1
sudo systemctl restart systemd-journald
通过这些步骤,你可以有效地管理和清理 /var/log/journal
目录中的日志文件。/var/lib/docker/overlay2
目录是 Docker 用于存储容器镜像和容器层文件系统的一个关键目录。具体来说,overlay2
是一种存储驱动程序,它使用 Linux 内核的 OverlayFS 文件系统来高效地管理和存储 Docker 镜像和容器。
主要功能
镜像层存储:
- Docker 镜像由多个只读层组成,每个层代表镜像的一个历史状态。
overlay2
存储驱动程序将这些层存储在/var/lib/docker/overlay2
目录中,并通过 OverlayFS 文件系统将它们组合在一起。
容器层存储:
- 当你启动一个容器时,Docker 会为该容器创建一个可写层,并将其放置在
/var/lib/docker/overlay2
目录中。 - 这个可写层允许容器在运行时进行文件系统操作,而不会修改底层只读镜像层。
- 当你启动一个容器时,Docker 会为该容器创建一个可写层,并将其放置在
写时复制(Copy-on-Write):
overlay2
存储驱动程序通过写时复制机制来实现文件系统的高效管理。当容器需要修改一个文件时,只有该文件被复制到可写层中进行修改,而其他未修改的文件仍然从只读层读取。
目录结构
在 /var/lib/docker/overlay2
目录中,你会看到许多子目录和文件,这些子目录通常是以长字符串(如哈希值)命名的。每个子目录代表一个 Docker 镜像层或容器层。具体结构如下:
- diff 目录:包含层的实际文件系统内容。
- link 目录:用于快速查找层。
- merged 目录:用于挂载点,显示合并后的文件系统视图。
- work 目录:用于 OverlayFS 的临时工作目录。
- lower 文件:包含底层只读层的信息。
清理与管理
由于 Docker 镜像和容器的数据存储在这个目录中,随着时间的推移,这个目录可能会占用大量的磁盘空间。可以使用以下命令来清理未使用的镜像和容器:
清理未使用的容器:
1
docker container prune
清理未使用的镜像:
1
docker image prune
清理所有未使用的对象(包括镜像、容器、网络等):
1
docker system prune
通过定期清理未使用的 Docker 对象,你可以有效地管理 /var/lib/docker/overlay2
目录的磁盘使用情况。
即使清理了未使用的 Docker 对象,有时 /var/lib/docker/overlay2
目录仍然会占用大量空间。这可能是因为某些未被清理的层或镜像仍然占据磁盘空间。以下是一些进一步的步骤,帮助你释放更多空间:
1. 检查占用空间的 Docker 对象
首先,可以检查每个 Docker 对象占用的空间:1
docker system df
这会显示镜像、容器、卷和构建缓存的磁盘使用情况。
2. 删除未使用的卷
有时 Docker 卷可能会占用大量空间,可以删除未使用的卷:1
docker volume prune
3. 删除悬挂的镜像(Dangling Images)
这些是构建过程中产生但未被标记的镜像:1
docker image prune -a
此命令会删除所有未被容器使用的镜像,包括悬挂的镜像。
4. 删除特定的镜像或容器
检查特定镜像和容器的大小,并手动删除不再需要的镜像和容器。例如,要删除一个特定的镜像:1
docker rmi IMAGE_ID
要删除一个特定的容器:1
docker rm CONTAINER_ID
5. 检查构建缓存
Docker 在构建镜像时会使用构建缓存,可以通过以下命令清理:1
docker builder prune
6. 检查和删除未使用的网络
未使用的 Docker 网络也会占用一些空间:1
docker network prune
7. 手动清理 /var/lib/docker/overlay2
如果上述方法仍然不能释放足够的空间,可以手动检查和清理 /var/lib/docker/overlay2
目录中的文件和目录。需要非常小心,以免删除重要的数据。
步骤:
停止 Docker 服务:
1
sudo systemctl stop docker
检查并删除无效的目录:
可以手动检查和删除一些未使用或无效的目录。这些目录通常是以长字符串命名的,可以通过查找一些异常大的目录来确定是否需要删除。1
sudo du -sh /var/lib/docker/overlay2/* | sort -h
根据输出结果,手动删除占用空间异常大的无效目录。
重启 Docker 服务:
1
sudo systemctl start docker
8. 考虑使用更大或额外的存储设备
如果上述方法都无法满足需求,可以考虑增加存储空间或将 Docker 数据目录移动到更大的存储设备。
更改 Docker 数据目录:
停止 Docker 服务:
1
sudo systemctl stop docker
复制数据到新目录:
1
sudo cp -r /var/lib/docker /path/to/new/docker
更新 Docker 配置文件:
编辑/etc/docker/daemon.json
文件,添加或修改以下内容:1
2
3{
"data-root": "/path/to/new/docker"
}重启 Docker 服务:
1
sudo systemctl start docker
通过以上步骤,你应该能够更好地管理和释放 /var/lib/docker/overlay2
目录的磁盘空间。如果还有其他问题,欢迎随时咨询。
可能还需要重启服务器一次。
- 使用 docker-compose 配置解决权限问题
现在是由于docker在运行的时候无法写入。需要如何做比较合适。
如果使用 docker-compose,可以通过 volumes 和 user 选项来配置。例如:
1 | version: '3.8' |
通过 trivy 工具扫描镜像是否有高风险内容
- 安装 trivy 软件
1 | curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin |
- 通过命令行能分析出哪些库比较高风险;
Trivy 可以直接分析 Go 程序的依赖(包括使用 go.mod 或已编译的二进制文件)以检测其依赖中存在的漏洞。以下是具体操作方法:
- 安装 Trivy
参考之前的安装方式:
sudo apt-get install wget -y
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo gpg —dearmor -o /usr/share/keyrings/trivy.gpg
echo “deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main” | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy -y
- 使用 Trivy 检查 Go 依赖
如果你的 Go 项目使用 go.mod 文件,可以直接扫描项目目录。
命令:
trivy fs .
解释:
• fs 表示文件系统扫描。
• . 表示当前目录,Trivy 会自动检测 go.mod 和 go.sum 文件来扫描依赖库的漏洞。
示例输出:
2024-12-23T10:30:00.000+0000 INFO Vulnerability scanning is enabled
2024-12-23T10:30:00.000+0000 INFO Go module found, scanning dependencies…
…
go.mod
Package: github.com/sirupsen/logrus
Version: v1.8.0
Vulnerabilities:
- CVE-2021-12345: Details about the vulnerability…
Package: github.com/gin-gonic/gin
Version: v1.6.3
Vulnerabilities:
- CVE-2022-54321: Another vulnerability details…
- 扫描已编译的 Go 二进制程序
如果你只有一个已编译的二进制文件,也可以直接扫描它。
命令:
trivy fs ./myprogram
注意:
• Trivy 会尝试解析二进制文件的依赖(例如,已静态链接的第三方库)。
• 如果程序打包了已知的漏洞库,Trivy 会列出相关信息。
- 使用 Trivy 结合 Docker 镜像
如果你的 Go 应用已经打包成 Docker 镜像,也可以直接扫描整个镜像。
命令:
trivy image myapp:latest
示例输出:
2024-12-23T10:45:00.000+0000 INFO Vulnerability scanning is enabled
2024-12-23T10:45:00.000+0000 INFO Starting image scan…
Image: myapp:latest
OS: debian
Version: bullseye
Vulnerabilities:
- CVE-2023-12345 in libssl1.1 (critical)
- CVE-2023-67890 in libc6 (high)
Go dependencies: - github.com/sirupsen/logrus v1.8.0 (medium)
- github.com/gin-gonic/gin v1.6.3 (high)
- 高效处理结果
通过 Severity 过滤:
如果你只想查看高危漏洞,可以添加 —severity 参数:
trivy fs —severity HIGH,CRITICAL .
输出为 JSON:
如果需要将结果存储或自动化处理,可以使用 JSON 输出:
trivy fs —format json —output result.json .
忽略特定漏洞:
可以通过配置 .trivyignore 文件忽略一些已知但可以接受的漏洞:
CVE-2021-12345
CVE-2022-54321
运行扫描时会自动忽略:
trivy fs .
- 在 CI/CD 中使用 Trivy
为了确保代码上线前无已知漏洞,可以将 Trivy 集成到 CI/CD 管道中,例如 GitHub Actions、GitLab CI 或 Jenkins。
GitHub Actions 示例:
在你的 GitHub 仓库中添加以下 workflow:
name: Trivy Scan
on:
push:
branches:
- main
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install Trivy
run: |
sudo apt-get install wget -y
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo gpg --dearmor -o /usr/share/keyrings/trivy.gpg
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy -y
- name: Run Trivy
run: trivy fs .
总结
• 源码扫描:trivy fs . 自动分析 go.mod 和 go.sum。
• 二进制扫描:trivy fs ./myprogram 检查静态依赖。
• 容器镜像扫描:trivy image myapp:latest 确保运行环境无漏洞。
• 通过过滤和 CI/CD 集成,可以轻松自动化安全检测。
引用
- [1] 官方网站
- [2] 菜鸟入门
- [3] 腾讯在线实验
- [4] Docker中安装nginx与自定义配置
- [5] docker compose swarm
- [6] 1小时docker上手
- [7] Docker 1小时快速上手教程,无废话纯干货
- [8] 安装docker的脚本-github里面的-安全