常见错误
Linux 中停止 Docker 服务报 warning 导致无法彻底停止问题如何解决?
systemctl stop docker
执行后报的时候报了一个 warning,如下
Warning: Stopping docker.service, but it can still be activated by:docker.socket
这时候使用 docker ps 命令时会发现 docker 依然在运行。这个警告之所以出现,是因为 systemd 管理的 Docker 服务不仅包括了 docker.service,还有与之相关的 docker.socket。为了更好地理解这个问题,需要简单了解下 systemd 的工作原理,以及 Docker 在 systemd 中的配置和激活机制。
systemd
systemd(system daemon)是一个系统和服务管理器,作为许多 Linux 发行版的默认初始化系统,负责启动和管理系统服务和进程。systemd 引入了一些新的概念和特性,比如并行化服务启动、依赖关系管理、日志记录以及 socket 激活等。systemd 也引入了单元(unit)的概念,其中最重要的几种单元类型包括:
- Service:代表了一个后台守护进程。
- Socket:用于监听网络连接或本地 Unix 域套接字并激活相关服务。
- Timer:基于时间的触发器,用于定时执行任务。
Docker Service 和 Socket
Docker 作为一个容器化平台,其服务由 systemd 通过 docker.service 单元管理。当 Docker 服务启动时,会在系统上创建一个 Unix 域套接字,通常是 /var/run/docker.sock,用于接收客户端的连接请求。这个套接字允许 Docker CLI 和其他工具与 Docker 守护进程进行通信。
为了让 Docker 服务能够在有连接请求时自动重启,systemd 还管理着 docker.socket单元。docker.socket 的作用是监听 /var/run/docker.sock,并在有客户端试图连接到这个套接字时激活 docker.service。这意味着即使 Docker 服务被停止,只要有一个客户端尝试连接到 docker.socket,systemd 就会自动重启 Docker 服务。
警告的原因 当看到“Warning: Stopping docker.service, but it can still be activated by: docker.socket”的警告时,并不意味着 Docker 服务没有被正确停止。实际上,Docker 服务确实被停止了,但是 systemd 仍旧保留着 docker.socket,以便在后续有客户端连接请求时能够立即重启 Docker 服务。这种机制确保了 Docker 服务的高可用性和快速响应能力,但同时也可能导致用户误以为 Docker 服务没有完全停止。
解决方法 如果想要彻底停止 Docker 服务并且不希望通过 socket 激活重新启动,可以分别执行以下命令:
//停止 docker.socket
systemctl stop docker.socket
//停止 docker.service
systemctl stop docker.service
//检查下是否停止成功
systemctl status docker.service
systemctl status docker.socket
docker
设置镜像源
在/etc/docker 下修改daemon.json
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.imgdb.de",
"https://docker-0.unsee.tech",
"https://docker.hlmirror.com",
"https://cjie.eu.org"
]
}
重启生效
sudo systemctl daemon-reload && sudo systemctl restart docker
查看是否生效 sudo docker info
命令
启动类
# 启动 docker
systemctl start docker
关闭 docker
systemctl stop docker
# 重新启动 docker
systemctl restart docker
# docker 设置自启动
systemctl enable docker
# 查看 docker 运行状态
systemctl status docker
# 查看 docker 版本号等信息
docker version
# 查看到有多少容器及其状态和镜像的信息
docker info
# docker 帮助
docker --help // 查看总体文档
docker run --help // 查看docker run 的帮助文档
镜像类
# 查看镜像
docker images
# 搜索镜像
docker search [OPTIONS] 镜像名字
docker search mysql
# 拉取镜像
docker pull
docker pull mysql #没有制定版本则默认最新版
# 运行镜像
docker run
docker run tomcat
# 运行镜像后可以按 ctrl+c 退出
# 删除镜像
docker rmi 镜像名/镜像ID #若镜像在运行则会报错
docker rmi -f 镜像名/镜像ID #强制删除一个
docker rmi -f mysql
docker rmi -f 镜像名/镜像ID 镜像名/镜像ID 镜像名/镜像ID #删除多个 其镜像ID或镜像用用空格隔开即可
docker rmi -f mysql redis
docker rmi -f $(docker images -aq)
#删除全部镜像 -a 意思为显示全部, -q 意思为只显示ID
# 加载镜像
docker load -i 镜像保存文件位置
docker load myimage.tar
# 保存镜像
docker save 镜像名/镜像ID -o 镜像保存位置和名字
docker save tomcat -o /myimage.tar
容器类
# 查看正在运行的容器
docker ps
docker ps -a # 查看所有容器
#加格式化方式访问,格式会更加清爽
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
# 创建容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
常用参数:
--name=NAME #为容器指定名字为NAME,不使用的话系统自动为容器命名
-d: 后台运行容器并返回容器ID,也即启动守护式容器(后台运行);
-i:以交互模式运行容器,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
也即启动交互式容器(前台有伪终端,等待交互,一般连用,即-it);
-P: 随机端口映射,大写P
-p: 指定端口映射,小写p
# 创建并允许 Nginx 容器
docker run -d --name nginx -p 80:80 nginx
# 启动守护式容器(后台运行)
docker run -d 容器名
# 停止容器
docker stop 容器名
# 启动容器
docker start 容器名
docker restart 容器名
# 进入正在运行的容器
docker exec -it 容器名 bashshell
docker exec -it nginx /bin/bash```
# 停止容器
docker stop 容器名
# 强制停止容器
docker kill 容器名
docker kill nginx
# 删除容器
# 删除一个
docker rm 容器ID
docker rm nginx
docker rm -f 容器ID #强制删除
docker rm -f nginx
# 删除多个
docker rm -f $(docker ps -a -q)
或
docker ps -a -q | xargs docker rm
# 查看容器日志
docker logs 容器名
docker logs nginx
# 查看容器内运行的进程
docker top 容器名
docker top nginx
# 查看容器内部细节
docker inspect 容器名
docker inspect nginx
# 创建容器数据卷挂载
# 创建容器并指定数据卷,注意通过 -v 参数来指定数据卷
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx
# 查看数据卷
docker volume ls
# 查看数据卷详情
docker volume inspect 数据卷名
docker volume inspect html
# 删除数据卷
docker volume rm 数据卷名
docker volume rm html
网络类
# 查看网络
docker network ls
# 创建网络
docker network create 网络名
docker network create hmall
# 查看网络数据源
docker network inspect 网络名
docker network inspect hmall
# 删除网络
docker network rm 网络名
docker nerwork rm hmall
docker拷贝容器文件到宿主机
方法 1:使用 docker cp 命令
# 1.exit退出容器:先从容器中退出到宿主机的命令行
# 2.使用 docker cp 命令将文件从容器复制到宿主机**
docker cp <容器ID>:<容器内路径> <宿主机路径>
- <容器ID>:容器的 ID 或名称。
- <容器内路径> :容器内文件或目录的路径。
- <宿主机路径>:宿主机上的目标路径。
Dockerfile
# 基于 Java 镜像构建
FROM openjdk:8u212-jre
# 配置参数
ENV TZ=Asia/Shanghai
ENV JAVA_OPTS="-Xms128m -Xmx256m -Dfile.encoding=UTF-8"
# 设置时区
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 设置工作目录
WORKDIR /app
# 复制 jar 包到镜像里
COPY target/my-app.jar /app/my-app.jar
# 暴露端口
EXPOSE 8080
# 配置启动命令
CMD java $JAVA_OPTS -jar /app/my-app.jar --server.port=8080
Dockerfile 示例的语法:
FROM: 指定基础镜像,这里是基于开源的 Java 8 JRE 镜像。ENV: 设置环境变量,这里配置了时区、JVM 参数等。RUN: 执行命令,这里用来设置时区。WORKDIR: 设置工作目录,相当于 cd 命令,之后的命令都在这个目录执行。COPY: 复制文件到镜像,这里复制了编译好的 Java jar 包。EXPOSE: 声明暴露的端口,这里是 8080。CMD: 启动命令,这里配置了启动 Java 程序的命令。
docker-compose
安装
#下载地址 https://github.com/docker/compose/tags
curl -SL https://github.com/docker/compose/releases/download/v2.27.3/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
#或者下载好的文件拷贝到 /usr/local/bin
mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose
#给可执行权限
chmod +x /usr/local/bin/docker-compose
#查看版本
docker-compose --version
# 查看帮助
docker-compose -h
# 启动所有服务
docker-compose up
docker-compose up -d # 后台运行
# 停止并删除容器、网络、卷、镜像。
docker-compose down
# 进入容器实例内部
docker-compose exec yml里面的服务id
# 展示容器
docker-compose ps
# 展示进程
docker-compose top
# 查看容器输出日志
docker-compose logs yml里面的服务id
# 检查配置
docker-compose config
docker-compose config -q # 检查配置,有问题才有输出
# 启动服务
docker-compose start
# 重启服务
docker-compose restart
# 停止服务
docker-compose stop
docker run 部署 mysql命令如下:
docker run -d \
--name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
-v ./mysql/data:/var/lib/mysql \
-v ./mysql/conf:/etc/mysql/conf.d \
-v ./mysql/init:/docker-entrypoint-initdb.d \
--network hmall
mysql
那么用docker-compose.yml 文件定义就是:
version: "3.8"
services:
mysql:
image: mysql
container_name: mysql
ports:
- "3306:3306"
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 123
volumes:
- "./mysql/conf:/etc/mysql/conf.d"
- "./mysql/data:/var/lib/mysql"
networks:
- new
networks:
new:
name: hmall
version: '3'
services:
waynboot-mobile-api:
image: ibm-semeru-runtimes:open-17-jdk
container_name: mobile
volumes:
- /etc/localtime:/etc/localtime
- /home/logs:/home/logs
- /opt/waynboot-mall/upload:/opt/waynboot-mall/upload
- ./jars/waynboot-mobile-api.jar:/home/app/waynboot-mobile-api.jar
restart: always
command: java -Xms512m -Xmx512m -Duser.timezone=GMT+8 -Dfile.encoding=utf-8 -jar /home/app/waynboot-mobile-api.jar
ports:
- "82:82"
environment:
- TZ=Asia/Shanghai
- LOG_PATH_PREFIX=/home/logs
- UPLOAD_DIR=/opt/waynboot-mall/upload
network_mode: "host"
# 依赖于redis和mysql,在启动本服务之前会先启动依赖的服务
depends_on:
- redis
- mysql
- rabbitmq
- elasticsearch
当编写 Docker Compose 文件时,以下是更详细的语法和配置选项解释:
-
版本(version) :Docker Compose 文件的版本,用于指定使用哪个版本的语法。常见的版本号有 '1'、'2'、'2.1'、'3' 等。不同的版本支持不同的功能和语法。
-
服务(services) :这是 Docker Compose 文件的核心部分,用于定义各个服务的配置。每个服务都是一个独立的容器。
-
image:指定要使用的镜像名称。可以是公共镜像(例如
nginx、mysql等),也可以是本地构建的私有镜像。如果指定了build,则会优先使用构建的镜像。 -
build:用于指定构建镜像所需的 Dockerfile 的路径。可以是相对于 Docker Compose 文件的相对路径,或者是包含 Git URL 的完整路径。
- context:构建上下文路径,表示构建时 Docker 将查找 Dockerfile 文件的位置。
- dockerfile:指定使用的 Dockerfile 文件名。默认为
Dockerfile。
-
ports:定义容器和主机之间的端口映射关系。可以是单个端口,也可以是一个范围。格式为
[主机端口]:[容器端口]。例如,ports: - "8080:80"表示将容器内的 80 端口映射到主机的 8080 端口。 -
volumes:定义容器和主机之间的文件卷绑定关系。格式为
[主机路径]:[容器路径],可以指定只读或可写。例如,volumes: - "./data:/app/data:ro"表示将主机上的./data目录挂载到容器内的/app/data路径,并以只读方式访问。 -
environment:设置容器中的环境变量。可以是一个键值对或一个列表。例如,
environment: - MYSQL_ROOT_PASSWORD=mysecretpassword设置了一个名为MYSQL_ROOT_PASSWORD值为mysecretpassword的环境变量。 -
depends_on:指定服务之间的依赖关系。例如,
depends_on: - db表示该服务依赖于名为db的服务,在启动时会先启动db服务。 -
command:定义容器启动时要执行的命令。例如,
command: bundle exec rails server表示在容器启动时执行bundle exec rails server命令。 -
restart:
- no:是默认的重启策略,在任何情况下都不会重启容器。
- always:容器总是重新启动。
- on-failure:在容器非正常退出时(退出状态非0),才会重启容器。
- unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
-
-
网络(networks) :用于定义网络配置。
- driver:指定网络使用的驱动程序。常见的驱动程序有
bridge、overlay、macvlan等。 - driver_opts:用于指定特定驱动程序的选项。例如,
driver_opts: myoption: value可以设置自定义选项。
- driver:指定网络使用的驱动程序。常见的驱动程序有
-
数据卷(volumes) :用于创建和管理数据卷。
- external:指定数据卷是否为外部数据卷,意味着数据卷由外部创建和管理。
-
命令(command) :定义容器启动时要执行的命令。
-
链接(links) :定义服务之间的链接关系,使一个服务可以通过名称引用另一个服务。
需要注意的是,在编写 Docker Compose 文件时,缩进和格式非常重要。使用正确的缩进,并确保语法正确才能成功构建和启动服务。
nginx
docker pull nginx
docker cp 容器id:/etc/nginx/nginx.conf /mydata/nginx/nginx.conf
docker run -d -p 81:80 \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/nginx.conf:/etc/nginx/nginx.conf \
--name my-nginx nginx:latest
# /usr/share/nginx/html 前端dist文件路径
# /etc/nginx/nginx.conf nginx.conf文件路径
nginx设置反向代理和负载均衡
mysql
mysql 5.7
命令方式
docker pull mysql:5.7
<!---->
docker run -itd --name my-mysql -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=a19960504 \
-v /mydata/docker/mysql/conf:/etc/mysql/conf.d \
-v /mydata/docker/mysql/data:/var/lib/mysql \
-v /mydata/docker/mysql/log:/var/log/mysql \
mysql
# -p 3306:3306 :映射容器服务的 3306 端口到宿主机的 3306 端口,外部主机可以直接通过 **宿主机ip:3306** 访问到 MySQL 的服务。
# MYSQL_ROOT_PASSWORD=123456:设置 MySQL 服务 root 用户的密码。
dockerfile方式
# 创建镜像
# docker build -t my-mysql .
# -t my-mysql:为镜像指定一个标签(名字为my-mysql)
# .:指示Docker在当前目录寻找Dockerfile
# 创建容器
# docker run -d --name my-mysql -p 3306:3306 my-mysql -v /Users/acton_zhang/docker/mysql/data:/var/lib/mysql
# -d:让容器后台运行
# 使用MySQL5.7镜像作为基础
FROM mysql:5.7
# FROM mysql:latest
# 复制自定义配置文件到容器内
# COPY ./my.cnf /etc/mysql/conf.d/my.cnf
#my.cnf是我们的自定义配置文件,用于优化MySQL性能和安全性
# 复制初始化脚本到容器内并执行
# COPY ./init.sh /docker-entrypoint-initdb.d/init.sh
# init.sh是一个初始化脚本,用于创建数据库和用户。
# 复制初始化SQL脚本到容器中
# 初始化SQL脚本init.sql复制到容器的/docker-entrypoint-initdb.d/目录中。这样,MySQL容器在启动时会自动执行该SQL脚本
# COPY *.sql /docker-entrypoint-initdb.d/
# 设置环境变量(root密码)
ENV MYSQL_ROOT_PASSWORD=a19960504
ENV MYSQL_DATABASE=my_database
ENV MYSQL_USER=zjx
ENV MYSQL_PASSWORD=a19960504
ENV LANG=C.UTF-8
# 告知Docker容器使用3306端口(Mysql默认端口)进行通信
EXPOSE 3306
docker-compse方式
version: '3'
services:
mysql:
image: registry.cn-hangzhou.aliyuncs.com/zhengqing/mysql:5.7 # 原镜像`mysql:5.7`
container_name: mysql_3306 # 容器名为'mysql_3306'
restart: unless-stopped # 指定容器退出后的重启策略为始终重启,但是不考虑在Docker守护进程启动时就已经停止了的容器
volumes: # 数据卷挂载路径设置,将本机目录映射到容器目录
- "./mysql/my.cnf:/etc/mysql/my.cnf"
- "./mysql/init-file.sql:/etc/mysql/init-file.sql"
- "./mysql/data:/var/lib/mysql"
# - "./mysql/conf.d:/etc/mysql/conf.d"
- "./mysql/log/mysql/error.log:/var/log/mysql/error.log"
- "./mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d" # 可执行初始化sql脚本的目录 -- tips:`/var/lib/mysql`目录下无数据的时候才会执行(即第一次启动的时候才会执行)
environment: # 设置环境变量,相当于docker run命令中的-e
TZ: Asia/Shanghai
LANG: en_US.UTF-8
MYSQL_ROOT_PASSWORD: root # 设置root用户密码
MYSQL_DATABASE: demo # 初始化的数据库名称
ports: # 映射端口
- "3306:3306"
mysql8.0
mongo
docker pull mongo
docker run -d --name my-mongo -p 27017:27017 mongo
redis
docker pull redis:6.2.6
docker run -d --name my-redis -p 6379:6379 redis:6.2.6
nacos
nacos默认用户名和密码都是nacos
单机
命令方式
docker run --name nacos -d -p 8848:8848 -p 9848:9848 -p 9849:9849 -e MODE=standalone nacos/nacos-server:v2.4.3
启动服务 http://192.168.57.130:8848/nacos
docker-compse方式
version: '3'
services:
nacos:
image: nacos/nacos-server:latest # 镜像`nacos/nacos-server:latest`
container_name: nacos # 容器名为'nacos'
restart: unless-stopped # 指定容器退出后的重启策略为始终重启,但是不考虑在Docker守护进程启动时就已经停止了的容器
volumes: # 数据卷挂载路径设置,将本机目录映射到容器目录
- ./nacos/logs:/home/nacos/logs
# - ./nacos/init.d/custom.properties:/home/nacos/init.d/custom.properties
environment: # 设置环境变量,相当于docker run命令中的-e
TZ: Asia/Shanghai
LANG: en_US.UTF-8
# PREFER_HOST_MODE: hostname
MODE: standalone # 单机模式启动
ports: # 映射端口
- "8848:8848"
sentinel
docker pull bladex/sentinel-dashboard
docker run --name sentinel -d -p 8858:8858 -d bladex/sentinel-dashboard
# 访问测试:http://IP:8858 用户名/密码:sentinel/sentinel
Seata
docker pull seataio/seata-server
docker run -d -p 8091:8091 -p 7091:7091 --name seata seataio/seata-server
elk
efk
version: '3'
# 网桥 -> 方便相互通讯
networks:
efk:
services:
elasticsearch:
image: registry.cn-hangzhou.aliyuncs.com/zhengqing/elasticsearch:7.14.1 # 原镜像`elasticsearch:7.14.1`
container_name: efk_elasticsearch # 容器名为'efk_elasticsearch'
restart: unless-stopped # 指定容器退出后的重启策略为始终重启,但是不考虑在Docker守护进程启动时就已经停止了的容器
volumes: # 数据卷挂载路径设置,将本机目录映射到容器目录
- "./app/elasticsearch/data:/usr/share/elasticsearch/data"
- "./app/elasticsearch/logs:/usr/share/elasticsearch/logs"
- "./app/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml"
# - "./app/elasticsearch/config/jvm.options:/usr/share/elasticsearch/config/jvm.options"
environment: # 设置环境变量,相当于docker run命令中的-e
TZ: Asia/Shanghai
LANG: en_US.UTF-8
TAKE_FILE_OWNERSHIP: "true" # 权限
discovery.type: single-node
ES_JAVA_OPTS: "-Xmx512m -Xms512m"
ELASTIC_PASSWORD: "123456" # elastic账号密码
ports:
- "9200:9200"
- "9300:9300"
networks:
- efk
kibana:
image: registry.cn-hangzhou.aliyuncs.com/zhengqing/kibana:7.14.1 # 原镜像`kibana:7.14.1`
container_name: efk_kibana
restart: unless-stopped
volumes:
- "./app/kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml"
ports:
- "5601:5601"
depends_on:
- elasticsearch
links:
- elasticsearch
networks:
- efk
filebeat:
image: registry.cn-hangzhou.aliyuncs.com/zhengqing/filebeat:7.14.1 # 原镜像`elastic/filebeat:7.14.1`
container_name: efk_filebeat
restart: unless-stopped # 指定容器退出后的重启策略为始终重启,但是不考虑在Docker守护进程启动时就已经停止了的容器
volumes: # 数据卷挂载路径设置,将本机目录映射到容器目录
- "./app/filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml"
- "./app/filebeat/logs:/usr/share/filebeat/logs"
- "./app/filebeat/my-log:/usr/share/filebeat/my-log"
environment: # 设置环境变量,相当于docker run命令中的-e
TZ: Asia/Shanghai
LANG: en_US.UTF-8
depends_on:
- elasticsearch
networks:
- efk
rabbitmq
docker pull rabbitmq:management
docker run -id --name=rabbitmq -v rabbitmq-home:/var/lib/rabbitmq -p 15672:15672 -p 5672:5672 rabbitmq:management
默认用户名guest 密码guest
rocketmq
kafka
minio
docker pull minio/minio
docker run -d -p 9000:9000 -p 9090:9090 --name my-minio \
-e "MINIO_ACCESS_KEY=minioadmin" \
-e "MINIO_SECRET_KEY=minioadmin" \
-v /mydata/minio/data:/data \
minio/minio server /data --console-address ":9090" -address ":9000"
-
-v:数据挂载。当 MinIO 将数据写入
/data时,该数据会镜像到本地路径/mydata/minio/data, 使其能够在容器重新启动时保持持久化。 -
--restart=always 设置重启策略,当容器因为某些原因停止后,Docker 会自动尝试重新启动容器。
-
-e 设置Api访问凭证的用户名、密码
-
minio/minio 是镜像名称;server是启动命令;/data 指定 Minio 服务存储数据的目录。
-
--console-address ":9090" -address ":9000" 控制台的访问地址ip+9090,api访问地址9000。
作者:ShiShuoMing
链接:juejin.cn/post/744364…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
jekins
docker pull jenkins/jenkins
docker run -d -u root -p 8080:8080 -p 50000:5000 --name jenkins jenkins/jenkins
Jenkins的配置
- Jenkins首次运行成功后输入管理员密码才可以使用,访问地址:http://192.168.3.101:8180/
- 可以使用以下命令从容器启动日志中获取管理密码;
docker logs -f jenkins
- 接下来就需要为Jenkins安装插件了,这里选择
安装推荐的插件;
- 安装完成后,创建一个Jenkins的管理员账号;
- 进行实例配置,配置Jenkins的URL;
- 点击
系统管理->插件管理,可以进行插件的安装;
- 这里需要安装插件;
Maven Integration plugin: Maven 集成管理插件。Docker plugin: Docker集成插件。GitLab Plugin: GitLab集成插件。Publish Over SSH:远程文件发布插件。SSH: 远程脚本执行插件。