欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
- 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老
- 导航
- 檀越剑指大厂系列:全面总结 java 核心技术点,如集合,jvm,并发编程 redis,kafka,Spring,微服务,Netty 等
- 常用开发工具系列:罗列常用的开发工具,如 IDEA,Mac,Alfred,electerm,Git,typora,apifox 等
- 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
- 懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
- 数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。 ✨✨ 欢迎订阅本专栏 ✨✨
Docker
是一个开源的应用容器引擎,基于 go 语言开发并遵循了 apache2.0 协议开源。
Docker
是在 Linux 容器里运行应用的开源工具,是一种轻量级的虚拟机。
Docker
的容器技术可以在一台主机上轻松为任何应用创建一个轻量级的,可移植的,自给自足的容器。
也可以这样形象的比喻:
Docker 的 Logo 设计为蓝色鲸鱼,拖着许多集装箱,鲸鱼可以看作为宿主机,集装箱可以理解为相互隔离的容器,每个集装箱中都包含自己的应用程序。
容器化越来越受欢迎,Docker 的容器有点总结如下:
Docker 的架构涉及多个组件,它们协同工作以实现容器化应用程序的构建、分发和运行。以下是 Docker 的基本架构组件:
Client (Docker 客户端):Docker 客户端是用户与 Docker 交互的主要接口。用户可以使用命令行工具(如 docker 命令)或图形用户界面来与 Docker 进行交互。客户端将用户的命令和请求发送到 Docker Daemon 来执行。
Docker Daemon (Docker 守护进程):Docker Daemon 是 Docker 引擎的后台服务,负责管理和运行容器。它监视来自 Docker 客户端的命令,处理容器的生命周期,管理镜像、网络、存储等各种操作。
Docker Images (Docker 镜像):Docker 镜像是一个只读的文件系统快照,其中包含了应用程序运行所需的文件、库和依赖项。镜像是容器的基础,可以用来创建容器的实例。镜像可以通过 Docker Hub 或其他镜像仓库获取,也可以通过 Dockerfile 定义自定义镜像。
Docker Containers (Docker 容器):容器是基于 Docker 镜像创建的运行实例。容器提供了一个隔离的环境,包括文件系统、进程空间和网络。每个容器都是独立的,可以在同一主机上并行运行多个容器。
Docker Registry (Docker 仓库):Docker 仓库用于存储和分享 Docker 镜像。Docker Hub 是一个公共的 Docker 仓库,开发者可以在其中找到各种现成的镜像。除了公共仓库外,还可以搭建私有的 Docker 仓库以存储自定义镜像。
Docker Compose:Docker Compose 是一个工具,允许用户使用一个 YAML 文件定义多个服务、网络和卷,从而可以通过单个命令启动、停止和管理多个容器。
Docker Swarm:Docker Swarm 是 Docker 的集群和编排解决方案,允许用户在多台主机上创建和管理容器集群。它可以协调容器的部署、扩展和管理。
Docker Machine:Docker Machine 是一个工具,用于在多种平台上创建、管理和维护 Docker 主机。它可以在虚拟机、云服务提供商等不同的环境中自动化地创建 Docker 主机。
这些组件一起构成了 Docker 的架构,使得开发者能够更轻松地构建、部署和管理容器化的应用程序。
数据卷
是一个供容器使用的特殊目录,位于容器中。可将宿主机的目录挂载到数据卷上,对数据卷的修改操作立刻可见,并且更新数据不会影响镜像,从而实现数据在宿主机与容器之间的迁移。数据卷的使用类似于 Linux 下对目录进行的 mount
操作。
如果需要在容器之间共享一些数据,最简单的方法就是使用数据卷容器。数据卷容器是一个普通的容器,专门提供数据卷给其他容器挂载使用。
容器互联是通过容器的名称在容器间建立一条专门的网络通信隧道。简单点说,就是会在源容器和接收容器之间建立一条隧道,接收容器可以看到源容器指定的信息
vm
虚拟机是 VM OS 系统+虚拟机监视器docker
是 docker engine docker 引擎docker
是运行在宿主机内核上的,没有自己的内核,小巧vm
是操作系统的虚拟化,docker 是内核级别的虚拟化Dockerfile 是一个创建镜像所有命令的文本文件, 包含了一条条指令和说明, 每条指令构建一层, 通过 docker build 命令,根据 Dockerfile 的内容构建镜像,因此每一条指令的内容, 就是描述该层如何构建.有了 Dockefile, 就可以制定自己的 docker 镜像规则,只需要在 Dockerfile 上添加或者修改指令, 就可生成 docker 镜像。
Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释。
# This dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..
# 1、第一行必须指定 基础镜像信息
FROM ubuntu
# 2、维护者信息
MAINTAINER docker_user [email protected]
# 3、镜像操作指令
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
# 4、容器启动执行指令
CMD /usr/sbin/nginx
docker build 命令用于从 Dockerfile 构建映像。可以在 docker build 命令中使用-f 标志指向文件系统中任何位置的 Dockerfile。-t 用于指定新构建的镜像的名称和标签。
docker build -t command-$PROFILE .
创建文件DockerFile
#构建镜像
docker build -f /home/muse/dockerfiles/dockerfile01 -t muse/centos:1.0 .
docker build -f /path/to/a/Dockerfile .
#启动镜像
docker run -it eb78333356a6 /bin/bash
#推送镜像到远程仓库
docker pull centos:1.0 qyj1992/centos:1.0
Docker 以从上到下的顺序运行 Dockerfile 的指令
FROM
:指定基础镜像,必须为第一个命令
MAINTAINER
: 维护者信息
RUN
:构建镜像时执行的命令
ADD
:将本地文件添加到容器中,tar 类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似 wget
COPY
:功能类似 ADD,但是是不会自动解压文件,也不能访问网络资源
CMD
:构建容器后调用,也就是在容器启动时才进行调用。
ENTRYPOINT
:配置容器,使其可执行化。配合 CMD 可省去"application",只使用参数。
LABEL
:用于为镜像添加元数据
ENV
:设置环境变量
EXPOSE
:指定于外界交互的端口
VOLUME
:用于指定持久化目录
WORKDIR
:工作目录,类似于 cd 命令
USER
:指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用 USER 指定用户时,可以使用用户名、UID 或 GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户
ARG
:用于指定传递给构建运行时的变量
ONBUILD
:用于设置镜像触发器
RUN
、CMD
和ENTRYPOINT
是在 Dockerfile 中用于定义容器镜像构建和运行时行为的指令。它们各自有不同的作用,下面是它们的区别和联系:
RUN:
RUN
指令在镜像构建过程中执行命令,并在每个构建层中创建新的镜像。它用于在容器镜像中安装软件、设置环境变量、下载文件等。RUN
指令中执行的命令都会在构建时运行,以生成新的中间镜像层。这些命令对于构建容器的静态配置和设置非常有用。RUN apt-get update && apt-get install -y nginx
CMD:
CMD
指令定义默认情况下容器运行时要执行的命令。它可以在 Dockerfile 中只有一个,指定容器启动时默认执行的命令。docker run
命令中指定了要运行的命令,它将覆盖CMD
中定义的默认命令。CMD
通常用于定义容器启动时的默认行为,例如应用程序的启动命令。CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT:
ENTRYPOINT
指令也用于定义容器启动时要执行的命令,但它具有更高的优先级,不会被docker run
命令中指定的命令覆盖。ENTRYPOINT
的参数会被视为容器的命令行参数,与 CMD 指令结合使用,可以创建可配置的容器镜像,其中ENTRYPOINT
定义了应用程序的主要执行逻辑,而CMD
则提供了默认参数。ENTRYPOINT ["java", "-jar", "myapp.jar"]
,然后可以在docker run
命令中提供额外的参数,例如docker run my-image arg1 arg2
联系与区别:
RUN
用于构建时,在镜像构建过程中运行命令来创建新的镜像层。CMD
用于指定默认的容器启动命令,可以在 Dockerfile 中只有一个,也可以在运行容器时被替换。ENTRYPOINT
也用于定义容器启动时的命令,但它的参数不会被覆盖
,与CMD
结合使用可以创建更具灵活性的容器镜像。通常情况下,CMD
和ENTRYPOINT
可以用来定义容器内的应用程序启动命令,而RUN
用于构建容器镜像时的一次性操作。
在 Docker 容器中获取当前日期和时间的行为通常是与宿主操作系统的时区和时间设置有关的。如果 Docker 容器的时区设置不正确,可能会导致new Date()
获取到的日期和时间不符合预期。
要解决这个问题,你可以采取以下步骤:
确保 Docker 容器的时区正确:在 Docker 容器中,时区通常默认设置为 UTC。你可以通过设置环境变量来更改容器的时区,以便其与你所期望的时区匹配。例如,在 Dockerfile 中,你可以添加以下行来设置时区:
ENV TZ=Asia/Shanghai
这将设置容器的时区为亚洲/上海。你需要根据你的实际时区进行设置。
使用java.time
库:建议使用java.time
库来处理日期和时间,而不是使用java.util.Date
。java.time
库更加现代化,支持更精确的日期和时间操作,并且更容易受到时区设置的影响。例如,你可以使用LocalDateTime
来获取当前日期和时间,然后根据时区进行处理,以确保得到正确的结果。
import java.time.LocalDateTime;
import java.time.ZoneId;
public class Main {
public static void main(String[] args) {
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
LocalDateTime now = LocalDateTime.now(zoneId);
System.out.println(now);
}
}
通过明确设置时区,你可以确保获取到的日期和时间是与你的预期一致的,而不会受到 Docker 容器的默认时区设置的干扰。
确保 Docker 容器的时区正确设置以及使用java.time
库来处理日期和时间应该能够解决在 0 点到 1 点之间获取日期时出现的问题。
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
#以下是在安装k8s的时候使用
yum install -y docker-ce-20.10.7 docker-ce-cli-20.10.7 containerd.io-1.4.6
#开机启动
systemctl enable docker --now
#创建目录
sudo mkdir -p /etc/docker
#配置加速文件
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
#重新加载文件
sudo systemctl daemon-reload
#重启docker
sudo systemctl restart docker
是否成功(有 client 和 service 两部分表示 docker 安装启动都成功了)
#查看版本
docker version
#启动容器,以镜像 soar/centos:7.1 创建名为 test 的容器,并以后台模式运行,并做端口映射到宿主机 2222 端口,P 参数重启容器宿主机端口会发生改变
docker run -d -p 2222:22 --name test soar/centos:7.1
docker pull nginx
docker run --name nginx -p 3000:3000 -p 3002:3002 -p 8080:8080 -v /root/java/docker/nginx.conf:/etc/nginx/nginx.conf -v /root/java/web:/home -d nginx:stable
user root;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#server {
# listen 8080;
# #server_name localhost;
# location / {
# proxy_pass http://10.201.1.98:3002;
# }
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# root html;
# }
#}
# abi
server {
listen 3000;
#server_name localhost;
location / {
root /home/abi/build;
index index.html index.htm;
}
location /abi/ {
proxy_pass http://10.201.1.84:8100/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# fast-bi-test
server {
listen 3002;
#server_name localhost;
location / {
root /home/fast-bi/test/build;
index index.html index.htm;
}
location /api/ {
proxy_pass http://127.0.0.1:8899/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# fast-bi-poc
server {
listen 8080;
#server_name localhost;
location / {
root /home/fast-bi/poc/build;
index index.html index.htm;
}
location /api/ {
proxy_pass http://127.0.0.1:8897/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
/etc/nginx
/usr/local/nginx/conf/nginx.conf
/usr/local/nginx/sbin/
#指定配置文件启动
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
#查看是否启动
ps -ef|grep nginx
#停止
kill -9 nginx
#在目录sbin下,重启nginx
./nginx -s reload
#注意rv-server和abi-web 服务名
docker pull deploy.xxx.com/kwan-dev/rv-server:20220506220402
docker tag deploy.xxx.com/kwan-dev/rv-server:20220506220402 rv-server:0407-01
docker stop 容器id
docker rm 容器id
docker rmi 镜像名称:tag
docker rmi 镜像id
#改tag名称:
docker pull 镜像地址
docker tag 镜像名称:tag 新的镜像名称:tag
docker run -d --net=host -v /home/logs:/home/logs --privileged=true \
-e server.port=8200 \
-e spring.datasource.dynamic.datasource.mysql.url="jdbc:mysql://xxxxxxxx:3306/rv?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai" \
-e spring.datasource.dynamic.datasource.mysql.username=root \
-e spring.datasource.dynamic.datasource.mysql.password=xxxx \
-e spring.datasource.dynamic.datasource.click.url="jdbc:clickhouse://xxxxx:8123/default?socket_timeout=300000" \
-e spring.datasource.dynamic.datasource.click.username=root \
-e spring.datasource.dynamic.datasource.click.password=xxxx \
-e nlp.http.post.url=http://xxxx:8300/ \
-e security.oauth2.signing-key=deepexi-@Jwt!&abi-demo^# \
-e security.oauth2.cache=true \
-e security.oauth2.token-expired-time=60 \
-e spring.redis.host=10.201.2.24 \
-e spring.redis.port=6379 \
-e spring.redis.password=xxxxx \
rv-server:1.1.3-hotfix
#最后改镜像名称
FROM devops-harbor.crv.com.cn/library/jdk8u202-skywalking7:v1
ARG BASE_DIR=/home
ENV BASE_DIR ${BASE_DIR}
WORKDIR ${BASE_DIR}
RUN mkdir -p ${BASE_DIR}
ADD startup.sh ${BASE_DIR}/startup.sh
RUN chmod +x ${BASE_DIR}/startup.sh
ADD target/*.jar ${BASE_DIR}/app.jar
ENTRYPOINT ["/home/startup.sh"]
觉得有用的话点个赞
呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!
Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!