【docker系列】docker高阶篇

欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。

  • 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老
  • 导航
    • 檀越剑指大厂系列:全面总结 java 核心技术点,如集合,jvm,并发编程 redis,kafka,Spring,微服务,Netty 等
    • 常用开发工具系列:罗列常用的开发工具,如 IDEA,Mac,Alfred,electerm,Git,typora,apifox 等
    • 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • 懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
    • 数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。 ✨✨ 欢迎订阅本专栏 ✨✨

博客目录

    • 一.基础概念
      • 1.什么是 docker?
      • 2.docker 有哪些优点
      • 3.docker 架构
      • 4.容器数据卷?
      • 5.docker 和虚拟机区别?
    • 二.Dockerfile
      • 1.什么是 Dockerfile
      • 2.文件格式
      • 3.构建镜像
      • 4.文件格式详解
      • 5.CMD 和 ENTRYPOINT
      • 6.时间不一致
    • 三.CentOS 安装 docker
      • 1.移除以前的安装
      • 2.配置 yum 源
      • 3.安装 docker
      • 4.启动
      • 5.配置加速
      • 6.验证安装
    • 四.docker 安装 nginx
      • 1.下载 nginx 镜像
      • 2.启动 nginx 容器
      • 3.nginx 配置
      • 4.nginx 目录
      • 5.nginx 命令
    • 五.部署文档
      • 1.镜像包
      • 2.执行脚本
      • 3.Dockerfile 配置

一.基础概念

1.什么是 docker?

Docker 是一个开源的应用容器引擎,基于 go 语言开发并遵循了 apache2.0 协议开源。
Docker 是在 Linux 容器里运行应用的开源工具,是一种轻量级的虚拟机。
Docker 的容器技术可以在一台主机上轻松为任何应用创建一个轻量级的,可移植的,自给自足的容器。
也可以这样形象的比喻:
Docker 的 Logo 设计为蓝色鲸鱼,拖着许多集装箱,鲸鱼可以看作为宿主机,集装箱可以理解为相互隔离的容器,每个集装箱中都包含自己的应用程序。

2.docker 有哪些优点

容器化越来越受欢迎,Docker 的容器有点总结如下:

  • 灵活:即使是最复杂的应用也可以集装箱化。
  • 轻量级:容器利用并共享主机内核。
  • 可互换:可以即时部署更新和升级。
  • 便携式:可以在本地构建,部署到云,并在任何地方运行。
  • 可扩展:可以增加并白动分发容器副本。
  • 可堆叠:可以垂直和即时堆叠服务。

3.docker 架构

Docker 的架构涉及多个组件,它们协同工作以实现容器化应用程序的构建、分发和运行。以下是 Docker 的基本架构组件:

  1. Client (Docker 客户端):Docker 客户端是用户与 Docker 交互的主要接口。用户可以使用命令行工具(如 docker 命令)或图形用户界面来与 Docker 进行交互。客户端将用户的命令和请求发送到 Docker Daemon 来执行。

  2. Docker Daemon (Docker 守护进程):Docker Daemon 是 Docker 引擎的后台服务,负责管理和运行容器。它监视来自 Docker 客户端的命令,处理容器的生命周期,管理镜像、网络、存储等各种操作。

  3. Docker Images (Docker 镜像):Docker 镜像是一个只读的文件系统快照,其中包含了应用程序运行所需的文件、库和依赖项。镜像是容器的基础,可以用来创建容器的实例。镜像可以通过 Docker Hub 或其他镜像仓库获取,也可以通过 Dockerfile 定义自定义镜像。

  4. Docker Containers (Docker 容器):容器是基于 Docker 镜像创建的运行实例。容器提供了一个隔离的环境,包括文件系统、进程空间和网络。每个容器都是独立的,可以在同一主机上并行运行多个容器。

  5. Docker Registry (Docker 仓库):Docker 仓库用于存储和分享 Docker 镜像。Docker Hub 是一个公共的 Docker 仓库,开发者可以在其中找到各种现成的镜像。除了公共仓库外,还可以搭建私有的 Docker 仓库以存储自定义镜像。

  6. Docker Compose:Docker Compose 是一个工具,允许用户使用一个 YAML 文件定义多个服务、网络和卷,从而可以通过单个命令启动、停止和管理多个容器。

  7. Docker Swarm:Docker Swarm 是 Docker 的集群和编排解决方案,允许用户在多台主机上创建和管理容器集群。它可以协调容器的部署、扩展和管理。

  8. Docker Machine:Docker Machine 是一个工具,用于在多种平台上创建、管理和维护 Docker 主机。它可以在虚拟机、云服务提供商等不同的环境中自动化地创建 Docker 主机。

这些组件一起构成了 Docker 的架构,使得开发者能够更轻松地构建、部署和管理容器化的应用程序。

【docker系列】docker高阶篇_第1张图片

4.容器数据卷?

数据卷是一个供容器使用的特殊目录,位于容器中。可将宿主机的目录挂载到数据卷上,对数据卷的修改操作立刻可见,并且更新数据不会影响镜像,从而实现数据在宿主机与容器之间的迁移。数据卷的使用类似于 Linux 下对目录进行的 mount 操作。

如果需要在容器之间共享一些数据,最简单的方法就是使用数据卷容器。数据卷容器是一个普通的容器,专门提供数据卷给其他容器挂载使用。

容器互联是通过容器的名称在容器间建立一条专门的网络通信隧道。简单点说,就是会在源容器和接收容器之间建立一条隧道,接收容器可以看到源容器指定的信息

5.docker 和虚拟机区别?

  • vm 虚拟机是 VM OS 系统+虚拟机监视器
  • docker 是 docker engine docker 引擎
  • docker 是运行在宿主机内核上的,没有自己的内核,小巧
  • vm 是操作系统的虚拟化,docker 是内核级别的虚拟化

二.Dockerfile

1.什么是 Dockerfile

Dockerfile 是一个创建镜像所有命令的文本文件, 包含了一条条指令和说明, 每条指令构建一层, 通过 docker build 命令,根据 Dockerfile 的内容构建镜像,因此每一条指令的内容, 就是描述该层如何构建.有了 Dockefile, 就可以制定自己的 docker 镜像规则,只需要在 Dockerfile 上添加或者修改指令, 就可生成 docker 镜像。

Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释。

2.文件格式

# 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

3.构建镜像

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

4.文件格式详解

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:用于设置镜像触发器

【docker系列】docker高阶篇_第2张图片

5.CMD 和 ENTRYPOINT

RUNCMDENTRYPOINT是在 Dockerfile 中用于定义容器镜像构建和运行时行为的指令。它们各自有不同的作用,下面是它们的区别和联系:

  1. RUN

    • RUN指令在镜像构建过程中执行命令,并在每个构建层中创建新的镜像。它用于在容器镜像中安装软件、设置环境变量、下载文件等。
    • 任何在RUN指令中执行的命令都会在构建时运行,以生成新的中间镜像层。这些命令对于构建容器的静态配置和设置非常有用。
    • 示例:RUN apt-get update && apt-get install -y nginx
  2. CMD

    • CMD指令定义默认情况下容器运行时要执行的命令。它可以在 Dockerfile 中只有一个,指定容器启动时默认执行的命令。
    • 如果在docker run命令中指定了要运行的命令,它将覆盖CMD中定义的默认命令。
    • CMD通常用于定义容器启动时的默认行为,例如应用程序的启动命令。
    • 示例:CMD ["nginx", "-g", "daemon off;"]
  3. 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结合使用可以创建更具灵活性的容器镜像。

通常情况下,CMDENTRYPOINT可以用来定义容器内的应用程序启动命令,而RUN用于构建容器镜像时的一次性操作。

6.时间不一致

在 Docker 容器中获取当前日期和时间的行为通常是与宿主操作系统的时区和时间设置有关的。如果 Docker 容器的时区设置不正确,可能会导致new Date()获取到的日期和时间不符合预期。

要解决这个问题,你可以采取以下步骤:

  1. 确保 Docker 容器的时区正确:在 Docker 容器中,时区通常默认设置为 UTC。你可以通过设置环境变量来更改容器的时区,以便其与你所期望的时区匹配。例如,在 Dockerfile 中,你可以添加以下行来设置时区:

    ENV TZ=Asia/Shanghai
    

    这将设置容器的时区为亚洲/上海。你需要根据你的实际时区进行设置。

  2. 使用java.time:建议使用java.time库来处理日期和时间,而不是使用java.util.Datejava.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 点之间获取日期时出现的问题。

三.CentOS 安装 docker

1.移除以前的安装

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

2.配置 yum 源

sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

3.安装 docker

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

4.启动

#开机启动
systemctl enable docker --now

5.配置加速

#创建目录
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

6.验证安装

是否成功(有 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 安装 nginx

1.下载 nginx 镜像

docker pull nginx

2.启动 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

3.nginx 配置

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;
        }
    }
}

4.nginx 目录

/etc/nginx
/usr/local/nginx/conf/nginx.conf
/usr/local/nginx/sbin/

5.nginx 命令

#指定配置文件启动
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

#查看是否启动
ps -ef|grep nginx

#停止
kill -9 nginx

#在目录sbin下,重启nginx
./nginx -s reload

五.部署文档

1.镜像包

#注意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

2.执行脚本

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
#最后改镜像名称

3.Dockerfile 配置

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 道阻且长,行则将至,让我们一起加油吧!

img

你可能感兴趣的:(s10,分布式,docker,容器,运维)