Docker基础操作
整合一遍Docker相关的操作。
一、介绍
Docker 是一款开源的应用容器平台。主要概念是镜像、容器、仓库。
生命周期
1
| 创建(create)→ 启动(start)→ 运行(running)→ 停止(stop)→ 重启(restart)→ 删除(rm)
|
二、安装
需要内核高于3.10版本。
2.1 在线脚本安装
官网安装脚本
清华源在线安装脚本
国内通用镜像源
1 2 3 4 5
| export DOWNLOAD_URL="https://mirrors.tuna.tsinghua.edu.cn/docker-ce"
curl -fsSL https://raw.githubusercontent.com/docker/docker-install/master/install.sh | sh
wget -O- https://raw.githubusercontent.com/docker/docker-install/master/install.sh | sh
|
注意:本质就是设置 DOWNLOAD_URL,镜像源有 docker-ce 的都可以。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| export DOWNLOAD_URL="https://mirrors.aliyun.com/docker-ce"
export DOWNLOAD_URL="https://mirrors.163.com/docker-ce"
export DOWNLOAD_URL="https://mirrors.ustc.edu.cn/docker-ce"
export DOWNLOAD_URL="https://mirror.nyist.edu.cn/docker-ce"
export DOWNLOAD_URL="https://mirrors.sohu.com/docker-ce"
|
2.2 yum安装
- 卸载旧版本
1 2 3 4 5 6 7 8
| yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
|
- 安装依赖
1
| yum install -y yum-utils device-mapper-persistent-data lvm2
|
- 配置docker源,(使用阿里云)
1
| yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
|
- 安装最新版本Docker CE(社区版)
1
| yum install -y docker-ce docker-ce-cli containerd.io
|
安装指定版本Docker CE(社区版)
1
| yum install -y docker-ce-20.10.24 docker-ce-cli-20.10.24 containerd.io-1.6.33
|
- 验证
1 2
| docker --version docker info
|
- 开启自启
1 2
| systemctl start docker systemctl enable docker
|
2.3 Docker官方维护的yum 源
1 2
| curl -o /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo sed -i 's+download.docker.com+mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo
|
或
1 2 3
| yum install -y yum-utils yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo
|
- 卸载
1 2 3 4 5 6 7 8
| yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
|
- 安装最新版
1
| yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
- 查看支持的版本
1
| yum list docker-ce --showduplicates
|
- 安装指定的版本
1 2 3
| yum -y install docker-ce-20.10.24 docker-ce-cli-20.10.24 yum -y install bash-completion source /usr/share/bash-completion/bash_completion
|
- 打包离线版本
1
| cd ~ && mkdir docker-rpm-20_10_24 && find /var/cache/yum -name "*.rpm" |xargs mv -t docker-rpm-20_10_24/
|
- 本地安装
2.4 docker-compose安装
20.10.24版本没有自带compose
1
| curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
1
| curl -L "https://gh.bravexist.cn/https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
1
| chmod +x /usr/local/bin/docker-compose
|
1
| ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
|
1
| docker-compose --version
|
三、配置镜像源
配置镜像源主要为了能拉取镜像。有时也可以直接使用代理。
1 2
| mkdir -p /etc/docker vim /etc/docker/daemon.json
|
1 2 3
| { "registry-mirrors": ["https://hub.bravexist.cn"] }
|
1 2
| sudo systemctl daemon-reload sudo systemctl restart docker
|
验证
1
| docker info | grep -A 1 "Registry Mirrors"
|
直接使用代理。
1 2
| mkdir /usr/lib/systemd/system/docker.service.d vi /usr/lib/systemd/system/docker.service.d/http-proxy.conf
|
1 2 3 4
| [Service] Environment="HTTP_PROXY=http://127.0.0.1:7897" Environment="HTTPS_PROXY=http://127.0.0.1:7897" Environment="NO_PROXY=localhost,127.0.0.1,.example.com"
|
1 2
| sudo systemctl daemon-reload sudo systemctl restart docker
|
1
| systemctl show docker --property Environment
|
四、镜像
- 拉取镜像
- 查看镜像
- 删除镜像
1
| docker image rm 镜像名称或镜像ID
|
- 保存镜像
1
| docker save 镜像名称 -o 镜像的tar包
|
- 导入镜像
- 打标签
1
| docker tag 源镜像:标签 目标镜像:标签
|
- 生成导出所有的镜像命令
1
| docker images|awk 'NR>1{print "docker save",$1":"$2,"-o",$1"_"$2".tar"}'
|
1
| docker images|awk 'NR>1{print "docker save",$1":"$2,"-o",$1"_"$2".tar"}' |bash
|
注意
新版本显示格式稍有区别。
1
| docker images |awk 'NR>1{print "docker save",$1,"-o",$1".tar"}'
|
1
| docker images |awk 'NR>1{print "docker save",$1,"-o",$1".tar"}'|bash
|
通用导出命令
1 2 3
| docker images --format '{{.Repository}} {{.Tag}}' | \ awk '{f=$1"_"$2".tar";gsub("/","_",f);print $1":"$2, f}' | \ xargs -n2 sh -c 'docker save "$0" -o "$1"'
|
导入
1
| for image in *.tar; do docker load -i "$image"; done
|
- 查看镜像的详细信息
1
| docker image inspect 镜像名称
|
- 清理无效的镜像(名称、标签都为none)
- 构建镜像
- 搜索镜像
五、容器
- 启动容器,以
nginx 为例。
1
| docker run -itd -p 宿主机端口:容器内部端口 --name 实例名称 镜像名称:版本号 终端名称
|
1
| docker run -d -p 90:80 --name "qk_nginx" nginx:alpine
|
- 查看运行中的容器
- 查看所有的容器
- 进入容器内部
1
| docker exec -it 容器名称或容器ID 执行的命令
|
- 查看容器日志
- 实时查看容器日志
1
| docker logs -f 容器名称或容器ID
|
- 停止容器
- 删除停止的容器(高风险操作)
- 重启容器
1
| docker restart 容器名称或容器ID
|
- 删除运行中的容器(高风险操作)
- 拷贝文件
1
| docker cp 宿主机文件 容器名称:容器内部文件
|
1
| docker cp 容器名称:容器内部文件 宿主机文件
|
六、构建镜像
构建镜像会使用 Dockerfile 文件。
6.1 核心指令
| 指令 |
作用 |
实例 |
| FROM |
指定基础镜像(必须是第一条指令) |
FROM centos:7 |
| MAINTAINER |
(弃用)维护者信息 |
MAINTAINER devops <admin@example.com> |
| LABEL |
全能的键值对 |
LABEL maintainer="ZhangSan <zhangsan@example.com>" |
| RUN |
构建时执行的命令(如安装软件) |
RUN rm -rf /etc/yum.repos.d/* |
| COPY |
复制主机文件、目录到容器 |
COPY index.html /usr/share/nginx/html |
| ADD |
类似 COPY ,支持解压压缩包、下载远程文件 |
ADD app.tar.gz /opt |
| WORKDIR |
设置容器工作目录(后续指令的执行目录) |
WORKDIR /usr/share/nginx |
| EXPOSE |
生命容器暴露的端口(仅文档说明,不会自动映射) |
EXPOSE 80 |
| CMD |
容器启动时执行的命令(可被 docker run 覆盖) |
CMD ["nginx", "-g", "daemon off;"] |
| ENTRYPOINT |
容器启动时的入口命令(不可被覆盖,需结合 --entrypoint 参数) |
ENTRYPOINT ["nginx"],默认是/bin/sh -c |
| ENV |
设置环境变量 |
ENV NGINX_VERSION=1.24 |
6.2 构建镜像
1
| docker build -t 新镜像的名称:版本号 .
|
6.3 Dockerfile 案例
NodeJS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
ARG NODE_VERSION=18 FROM node:${NODE_VERSION}-alpine AS builder
RUN apk add --no-cache libc6-compat python3 make g++
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:${NODE_VERSION}-alpine AS runner
LABEL org.opencontainers.image.authors="你的名字 <email@example.com>" LABEL org.opencontainers.image.source="https://github.com/你的仓库"
WORKDIR /app
ENV NODE_ENV=production ENV PORT=3000
RUN addgroup -g 1001 -S nodejs && \ adduser -S nodejs -u 1001
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist COPY --from=builder --chown=nodejs:nodejs /app/package.json ./package.json
USER nodejs
EXPOSE 3000
CMD ["node", "dist/main.js"]
|
静态网站
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./ RUN npm install --registry=https://registry.npmmirror.com
COPY . . RUN npm run build
FROM nginx:alpine AS runner
LABEL maintainer="Docker爱好者"
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/public /usr/share/nginx/html
RUN apk add --no-cache tzdata && \ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ echo "Asia/Shanghai" > /etc/timezone
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
|
6.4 优化 Dockerfile
- 合并
RUN 指令,减少镜像层数
- 清理yum缓存
- 使用轻量级基础镜像(如
alpine )
七、网络及数据持久化
7.1 网络模式
| 模式 |
特点 |
使用场景 |
| bridge(桥接) |
默认模式,容器连接到 docker0 网桥,与主机互通,荣期间通过网桥通信 |
大多数单机应用 |
| host(主机) |
容器共享主机网络命名空间,无端口映射,性能最高 |
网络性能要求高的应用 |
| container |
共享另一个容器的网络命名空间 |
多容器协同(如应用 + 数据库) |
| none |
容器无网络接口,仅本地回环 |
无需网络的离线应用 |
使用 -net ,--network 指定。如:
-net=host
-net=container(容器名或ID)
-net=bridge
7.2 网络相关命令
- 查看网络
- 创建自定义桥接网络
1
| docker network create 网络名称
|
- 查看网络详情
1
| docker network inspect 网络名称
|
- 启动时加入网络
1
| docker run -d --network 网络名称 镜像名称
|
7.3 数据持久化
- 创建数据卷
1
| docker volume create 数据卷名称
|
- 查看数据卷
- 查看数据卷详情(默认路径在
/var/lib/docker/volume )
1
| docker volume inspect 数据卷名称
|
- 数据卷挂载
1
| docker run -d -v 数据卷:容器内目录 镜像名称
|
- 绑定挂载
1
| docker run -d -v 本地目录:容器内目录 镜像名称
|
- 删除数据卷
八、Docker Compose
容器编排技术,使用 yaml 文件来定多容器应用的服务。
yaml 文件常命名为 docker-compose.yaml 或 compose.yaml,.ymal 和 .yml 也可以混用。
8.1 安装(旧版本)
旧版本需要单独安装 docker-compose 命令,新版本 docker 自带子命令 compose
1
| curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
1
| chmod +x /usr/local/bin/docker-compose
|
1
| ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
|
1
| docker-compose --version
|
8.2 相关操作
核心结构
1 2 3 4 5 6 7 8 9 10
| version: "3.8" services: service1: image: ports: volumes: environment: networks: networks: volumes:
|
启动
停止
重启
1
| docker compose restart 服务名
|
进入某个服务
1
| docker compose exec 服务名 /bin/bash
|
构建自定义镜像
8.3 案例
案例一,wordpress
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| version: "3.8" services: db: image: mysql:5.7 volumes: - mysql-data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: 123456 MYSQL_DATABASE: wordpress MYSQL_USER: wp_user MYSQL_PASSWORD: wp_pass networks: - wp-network wordpress: depends_on: - db image: wordpress:latest volumes: - wp-data:/var/www/html ports: - "8080:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wp_user WORDPRESS_DB_PASSWORD: wp_pass WORDPRESS_DB_NAME: wordpress networks: - wp-network
volumes: mysql-data: wp-data:
networks: wp-network:
|
案例二,前后端分离应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| version: "3.8" services: redis: image: redis:6.2 ports: - "6379:6379" volumes: - redis-data:/data networks: - app-network backend: image: springboot-app:v1 ports: - "8080:8080" environment: SPRING_REDIS_HOST: redis SPRING_REDIS_PORT: 6379 depends_on: - redis networks: - app-network frontend: image: nginx:1.24 ports: - "80:80" volumes: - ./frontend:/usr/share/nginx/html - ./nginx.conf:/etc/nginx/conf.d/default.conf depends_on: - backend networks: - app-network volumes: redis-data: networks:
|
九、私有仓库 registry
registry 是 Docker官方的私有仓库。
- 运行私有仓库。
1
| docker run --name "pri_registry" --restart=always -d -p 5000:5000 registry
|
- 验证是否运行成功
- 放行防火墙
1 2
| firewall-cmd --permanent --add-port=5000/tcp firewall-cmd --reload
|
- 上传下载,测试功能是否正常
1 2 3
|
docker tag busybox 192.168.10.18:5000/busybox
|
1 2
| docker push 192.168.10.18:5000/busybox docker pull 192.168.10.18:5000/busybox
|
默认使用 https ,不会成功。
1
| vim /etc/docker/daemon.json
|
1 2 3 4
| { "registry-mirrors": ["https://hub.bravexist.cn"], "insecure-registries": ["192.168.10.18:5000"] }
|
1 2
| sudo systemctl daemon-reload sudo systemctl restart docker
|
十、Web-UI
10.1
很旧的一个Web-UI,cli 也能看的一些内容。
1
| docker pull uifd/ui-for-docker
|
1
| docker run -it -d --name docker-web -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock uifd/ui-for-docker
|
1 2
| firewall-cmd --permanent --add-port=9000/tcp firewall-cmd --reload
|
10.2 portainer-ce
1
| docker pull portainer/portainer-ce
|
1
| docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
|
1 2
| firewall-cmd --permanent --add-port=8000/tcp --add-port=9443/tcp firewall-cmd --reload
|
1
| https://192.168.10.18:9443
|
中文版(非官方版本)
1
| docker pull 6053537/portainer-ce
|
1 2
| firewall-cmd --permanent --add-port=9000/tcp firewall-cmd --reload
|
1
| http://192.168.10.18:9000
|
10.3 dockge
uptime-kuma 作者的产品,使用 docker-compose 部署。可以手动修改版本。
方便的编写 compose 可视化。
1 2 3 4 5 6 7 8 9 10 11 12
| mkdir -p /opt/stacks /opt/dockge cd /opt/dockge
curl https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml --output compose.yaml
docker compose up -d
|
1 2
| firewall-cmd --permanent --add-port=5001/tcp firewall-cmd --reload
|
1
| http://192.168.10.18:5001
|
10.4 yacht
1 2
| docker volume create yacht docker run -d -p 8000:8000 -v /var/run/docker.sock:/var/run/docker.sock -v yacht:/config --name yacht --restart unless-stopped selfhostedpro/yacht
|
10.5 1panel
….
十一、Harbor镜像仓库
官网仓库
- 下载
1
| wget https://github.com/goharbor/harbor/releases/download/v2.14.1/harbor-offline-installer-v2.14.1.tgz
|
- 解压
1
| tar xf harbor-offline-installer-v2.14.1.tgz -C /usr/local/
|
- 编辑配置文件,注释掉
https 相关的内容。
1 2 3
| cd /usr/local/harbor cp harbor.yml.tmpl harbor.yml vim harbor.yml
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| hostname = 192.168.1.200 //修改IP地址
https: port: 443 certificate: /your/certificate/path private_key: /your/private/key/path
harbor_admin_password: Harbor@123
data_volume: /data
|
默认不带杀毒,可选项
1
| ./install.sh --with-trivy
|
- 访问
- 登录
1
| vim /etc/docker/daemon.json
|
1 2 3 4
| { "registry-mirrors": ["https://hub.bravexist.cn"], "insecure-registries": ["192.168.10.18:5000"] }
|
1 2
| sudo systemctl daemon-reload sudo systemctl restart docker
|
1
| docker login 192.168.10.18:80
|
push、pull
1
| docker tag hello-world 192.168.10.18:80/system/hello-world
|
1
| docker push 192.168.10.18:80/system/hello-world:latest
|
1
| docker pull 192.168.10.18:80/system/hello-world:latest
|
十二、问题
- docker内无法解析域名,导致无法安装软件包
1
| sudo vim /etc/docker/daemon.json
|
1 2 3 4 5 6 7
| { "dns": [ "223.5.5.5", "114.114.114.114", "8.8.8.8" ] }
|
1 2
| sudo systemctl daemon-reload sudo systemctl restart docker
|
- Harbor 不支持扫描,安装时携带扫描器
1
| ./install.sh --with-trivy
|