当前位置: 首页 > news >正文

Linux云计算 |【第五阶段】CLOUD-DAY5

主要内容:

容器的镜像编排,commit简单镜像创建,Dockerfile制作服务镜像(语法、创建镜像)、创建复杂镜像(Docker微服务架构、示例:NGINX+PHP)、私有仓库

一、简单镜像创建

1、自定义镜像原理

① 镜像采用分层设计

Docker镜像采用分层设计,每一层都是一个只读的文件系统层。这些层可以被多个镜像共享,从而节省存储空间并提高镜像的构建效率。每一层都代表了对文件系统的增量修改。

② 创建读写层

当您启动一个容器时,Docker会在镜像的最上层添加一个读写层。这个读写层允许您在容器中进行修改,而不会影响底层的只读层。

③ 修改配置

在容器中,您可以进行各种自定义修改,例如安装软件包、修改配置文件、添加或删除文件等。这些修改都会记录在读写层中。

④ 重新打包(commit)

当您完成自定义修改后,可以使用 docker commit 命令将当前容器的读写层和底层的只读层打包成一个新的镜像。这个新镜像包含了您所做的所有修改。

2、使用Commit创建镜像

原理:使用 docker commit 命令可以将一个正在运行的容器的状态保存为一个新的镜像。这个过程包括将容器的读写层和底层的只读层打包成一个新的镜像层。

格式:docker commit 容器id 新镜像名称:标签

容器ID:您要提交的容器的ID。

新镜像名称:您要创建的新镜像的名称。

标签:新镜像的标签,通常用于版本控制。

例如:假设有一个正在运行的容器,其ID为 abcd1234,您希望将其保存为一个新的镜像,名称为 my-custom-image,标签为 v1.0。您可以使用以下命令:

docker commit abcd1234 my-custom-image:v1.0

示例:通过Commit创建(打包)自定义镜像

① 使用centos镜像启动容器

[root@docker-0001 ~]# docker run -it centos:latest

② 自定义修改:配置Yum源(华为云YUM源),安装软件

[root@6f239a4d0fc3 /]# rm -f /etc/yum.repos.d/*.repo
[root@6f239a4d0fc3 /]# curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.myhuaweicloud.com/repo/CentOS-Base-7.repo
[root@6f239a4d0fc3 /]# yum install -y net-tools vim-enhanced tree bash-completion iproute psmisc && yum clean all
[root@6f239a4d0fc3 /]# exit
exit

③ 创建自定义镜像(对容器进行打包制作新镜像)

[root@docker-0001 ~]# docker commit 6f239a4d0fc3 myos:latest
sha256:8ee6a9acdcd19ed70e78d74ead608fde5a4bdb12faa147f6fd3acd257179fb76

④ 验证镜像

[root@docker-0001 ~]# docker images

[root@docker-0001 ~]# docker run -it myos:latest    //基于新镜像运行容器
[root@183f4b606ff2 /]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
[root@docker-0001 ~]# docker history myos:latest    //查看容器制作历史

补充:打包完成新镜像后,可将制作镜像的容器删除,以及基于的centos镜像删除,都不会影响现有的新镜像;

[root@docker-0001 ~]# docker rm 6f239a4d0fc3
6f239a4d0fc3
[root@docker-0001 ~]# docker rmi centos:latest
Untagged: centos:latest

二、Dockerfile概述

Dockerfile 是一个文本文件,包含了一系列指令,用于定义如何构建 Docker 镜像。每个指令都会在镜像中创建一个新的层,从而实现分层构建。

1、docker commit 的局限性

虽然 docker commit 命令可以快速创建自定义镜像,但它有一些明显的局限性:

  • 难以管理复杂配置:对于复杂的镜像,例如需要设置默认的启动命令、环境变量、开放特定端口等,docker commit 很难满足需求。
  • 缺乏版本控制:使用 docker commit 创建的镜像缺乏版本控制,难以追踪和管理不同版本的镜像。
  • 不可重复性:每次使用 docker commit 创建的镜像都是基于当前容器的快照,难以保证每次构建的结果一致。

2、Dockerfile 的优势

Dockerfile 是一种更强大、更灵活的镜像制作方式,它允许您通过编写类似脚本的文件来定义镜像的构建过程。以下是 Dockerfile 的主要优势:

  • 可重复性:Dockerfile 允许您定义镜像的构建步骤,确保每次构建的结果一致。
  • 版本控制:Dockerfile 可以与版本控制系统(如 Git)结合使用,方便追踪和管理不同版本的镜像。
  • 复杂配置管理:Dockerfile 支持设置默认的启动命令、环境变量、开放端口等复杂配置,使得镜像的构建更加灵活和可控。
  • 依赖管理:Dockerfile 可以明确指定镜像的依赖关系,确保构建过程中所需的软件包和库都能正确安装。
  • 自动化构建:Dockerfile 可以与 CI/CD 工具集成,实现自动化构建和部署。

3、Dockerfile 的基本结构

1)FROM

指定构建镜像的基础镜像:所有 Dockerfile 都必须以 FROM 指令开始。

FROM ubuntu:20.04

2)LABEL

指定镜像的维护者信息:添加元数据,如维护者信息、版本号等。

LABEL maintainer="your-email@example.com"

3)ENV

设置环境变量:

ENV MY_VAR="my-value"

4)WORKDIR

指定工作目录:后续的 RUN、CMD、ENTRYPOINT、COPY 和 ADD 指令都会在该目录下执行。

WORKDIR /app

5)COPY

将本地文件拷贝到镜像中:

COPY . /app

6)RUN

安装所需的软件包:在镜像中执行命令。每个 RUN 指令都会创建一个新的层。

RUN apt-get update && apt-get install -y \package1 \package2

7)EXPOSE

指定镜像需要暴露的端口:

EXPOSE 8080

8)CMD

设置默认的启动命令:一个 Dockerfile 中只能有一个 CMD 指令。

CMD ["python", "app.py"]

9)ADD

类似于 COPY,但支持从 URL 下载文件并解压缩 tar 文件。

ADD https://example.com/file.tar.gz /app/

10)ENTRYPOINT

设置容器启动时执行的命令,通常用于设置可执行文件。CMD 可以作为参数传递给 ENTRYPOINT

ENTRYPOINT ["python"]
CMD ["app.py"]

11)VOLUME

创建一个挂载点,用于持久化数据。

VOLUME /data

12)USER

设置运行后续指令的用户。

USER myuser

13)ARG

定义构建时传递的参数。

ARG MY_ARG="default-value"

14)ONBUILD

设置当该镜像被用作基础镜像时,自动执行的指令。

ONBUILD COPY . /app

4、使用 Dockerfile 构建镜像

工作流程:

① 创建目录(例如:mkdir mybuild);

② 在目录中编写Dockfile文件;

③ 生成镜像;

在编写好 Dockerfile 后,可以使用 docker build 命令来构建镜像:

  • 格式:docker build -t 镜像名称:标签 Dockerfile所在目录
docker build -t my-custom-image:v1.0 .
  • -t 参数用于指定新镜像的名称和标签。
  • . 表示 Dockerfile 所在的当前目录。

- CMD指令 可以查看 service 文件的启动命令 ExecStart(/lib/systemd/system/httpd.service)

- ENV 环境变量查询服务文件中的环境变量配置文件 EnvironmentFile 指定的文件内容


示例:通过Dockerfile制作apache+php服务镜像

# 提前拷贝webhome.tar.gz到192.168.1.31(参考:/web_install/files/webhome.tar.gz)

[root@ecs-proxy ~]# scp /root/other/web_install/files/webhome.tar.gz 192.168.1.31:/root

① 创建并切换apache目录

[root@docker-0001 ~]# mkdir apache
[root@docker-0001 ~]# cp webhome.tar.gz /root/apache/  //需放到同Dockerfile相同目录
[root@docker-0001 ~]# cd apache

② 编写Dockerfile文件

[root@docker-0001 apache]# vim Dockerfile
FROM myos:latest                    //指定基础镜像myos:latest
RUN yum install -y httpd php        //执行命令:安装Apache、php服务
ENV LANG=C                          //设置环境变量
ADD webhome.tar.gz /var/www/html/   //ADD复制压缩包到镜像并自动解压
WORKDIR /var/www/html/              //指定工作目录
EXPOSE 80                           //声明开放的端口
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]    //容器启动命令(参考service文件)

③ 使用docker build对Dockerfile内容生成镜像

[root@docker-0001 apache]# docker build -t myos:httpd .   //【.】为Dockerfile所在目录
…
Successfully built 5adb6e780c95
Successfully tagged myos:httpd

④ 查看镜像,并基于myos: httpd镜像,启动容器并验证服务

[root@docker-0001 apache]# docker images

[root@docker-0001 ~]# docker run -itd myos:httpd    //启动容器并放入后台运行
73985edea99f5b80bf557dda8e8b663ef7650b24e28d56dfd957089515653117
[root@docker-0001 ~]# docker ps

[root@docker-0001 ~]# docker inspect 73985edea99f    //查看容器详细信息
…"IPAddress": "172.17.0.3",    //查找到容器的IP
…

注意:使用docker inspect可以查看镜像或者容器的详细信息,只有容器中才会有IP信息;

[root@docker-0001 ~]# curl http://172.17.0.3/info.php   //验证服务
<pre>
Array
([REMOTE_ADDR] => 172.17.0.1[REQUEST_METHOD] => GET[HTTP_USER_AGENT] => curl/7.29.0[REQUEST_URI] => /info.php
)
php_host:       73985edea99f
1229

三、复杂镜像创建

1、微服务架构介绍

微服务架构(Microservices Architecture)是一种软件架构风格,它将一个大型应用程序拆分为一组小型、独立的服务。每个服务都运行在自己的进程中,并通过轻量级机制(如 HTTP/REST 或消息队列)进行通信。每个服务都专注于完成一个特定的业务功能,并且可以独立开发、部署和扩展。

1)微服务架构与单体架构的区别

  • 单体架构:传统的单体应用将所有功能打包在一个单一的代码库中,部署在一个单一的进程中。虽然开发和部署相对简单,但随着应用规模的扩大,单体应用会变得越来越复杂,难以维护和扩展。
  • 微服务架构:微服务架构将应用拆分为多个核心功能,每个功能作为一个独立的服务运行。每个服务都可以独立开发、部署和扩展,从而解决了单体应用的复杂性问题。

2)微服务架构的优势:

高可扩展性:每个服务都可独立扩展,根据需求增加或减少资源
出色的弹性:微服务架构允许服务之间相互隔离,一个服务的故障不会影响整个应用
易于部署:每个服务都可独立部署,减少了部署的风险和复杂性
易于访问:每个服务都可通过标准化的接口(如 RESTful API)进行访问,便于集成和调用
更加开发:微服务架构鼓励团队独立开发和维护各自的服务,提高了开发效率
松耦合高内聚:服务之间通过明确定义的接口进行通信,降低了耦合性,同时每个服务内部保持高内聚

3)微服务架构的核心思想:

微服务的核心思想是将应用服务“拆分”成多个核心功能。每个服务都应该是独立的、自治的,并且可以独立开发、测试、部署和扩展。

4)构建微服务的关键点:

  • 服务拆分:理清各个服务之间的关系,确保每个服务都专注于一个特定的业务功能
  • 服务通信:选择合适的通信机制(如 HTTP/REST、消息队列等),确保服务之间的松耦合和高内聚
  • 持续演进:保持服务的持续演进,使服务能够快速、低成本地被拆分和合并,以快速响应业务的变化,持续迭代
  • 自动化工具:利用自动化工具(如 CI/CD 工具)实现服务的自动化构建、测试和部署

5)Docker 与微服务架构:

Docker 是一种应用的管理模式,它通过容器化技术将每个服务封装在一个独立的容器中。每个容器承载一个服务,一台计算机可以同时运行多个容器,从而轻松模拟出复杂的微服务架构。Docker 的优势在于:

隔离性:每个容器都是独立的,互不干扰,确保服务的隔离性和安全性。
一致性:Docker 确保在开发、测试和生产环境中的一致性,减少了环境差异带来的问题。
快速部署:Docker 容器可以快速启动和停止,便于服务的快速部署和扩展。
资源利用率:Docker 容器共享主机操作系统的内核,提高了资源利用率。


示例:通过Dockerfile制作一个NGINX微服务 + PHP-FPM微服务

步骤1:制作php-fpm镜像

① 创建并切换php目录

[root@docker-0001 ~]# mkdir php ; cd php

② 编写Dockerfile文件

[root@docker-0001 php]# vim Dockerfile
FROM myos:latest                 //指定myos基础镜像
RUN yum install -y php-fpm       //运行命令:安装php软件包
EXPOSE 9000                      //声明开放的端口
CMD ["/usr/sbin/php-fpm","--nodaemonize"]   //容器启动命令(参考service文件)

③ 使用docker build对Dockerfile内容生成镜像

[root@docker-0001 php]# docker build -t myos:php-fpm .
…
Successfully built 6fad12240171
Successfully tagged myos:php-fpm

④ 基于myos:php-fpm镜像,启动容器并验证服务

[root@docker-0001 php]# docker run -itd myos:php-fpm     //启动容器并放入后台运行
b2bd2f88c33330c192ca34ec5b373e77dcea70bddbded5010899d35bccaf8182
[root@docker-0001 php]# docker ps     //查看运行的容器

[root@docker-0001 php]# docker exec -it b2bd2f88c333 /bin/bash    //进入容器
[root@b2bd2f88c333 /]# ss -nlptu | grep :9000     //查看监听端口
tcp    LISTEN     0      128    127.0.0.1:9000                  *:*                   users:(("php-fpm",pid=1,fd=6))

提示:容器启动命令CMD ["/usr/sbin/php-fpm","--nodaemonize"],可根据service文件查看,需要自行安装php-fpm软件包,查找到service启动文件;

步骤2:制作nginx镜像

提示:Nginx一般采用编译安装,在容器内编译不容易排错也不便于管理;根据Dockfile文件中的语法ADD可以将一个压缩包复制到容器内并自动解压释放特性,可以在外部编译Nginx并把编译好的程序目录打包,使用打包文件构建Nginx镜像服务;

注意:Nginx进程默认在后台运行,可以使用参数daemon off,强制进程在前台运行;

# 提前将所需软件包拷贝到192.168.1.31中(参考:other/nginx-1.12.2.tar.gz)

[root@ecs-proxy ~]# scp /root/other/nginx-1.12.2.tar.gz 192.168.1.31:/root

① 编译安装Nginx服务

[root@docker-0001 ~]# yum -y install gcc make pcre-devel openssl-devel  //安装依赖包
[root@docker-0001 ~]# useradd nginx   //创建Nginx用户
[root@docker-0001 ~]# tar -xf nginx-1.12.2.tar.gz
[root@docker-0001 ~]# cd nginx-1.12.2/
[root@docker-0001 nginx-1.12.2]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module
[root@docker-0001 nginx-1.12.2]# make && make install
[root@docker-0001 nginx-1.12.2]# ls /usr/local/nginx/
conf  html  logs  sbin

② 拷贝docker-images/目录下的测试文件info.html和info.php到nginx/html目录

[root@ecs-proxy ~]# scp /root/kubernetes/docker-images/info.* 192.168.1.31:/usr/local/nginx/html/

③ 将编译好的Nginx程序目录打包

[root@docker-0001 ~]# cd /usr/local/
[root@docker-0001 local]# tar -czf nginx.tar.gz nginx/

④ 制作nginx镜像

[root@docker-0001 ~]# mkdir nginx ; cd nginx
[root@docker-0001 nginx]# cp /usr/local/nginx.tar.gz .   //拷贝压缩文件到当前目录
[root@docker-0001 nginx]# ls
nginx.tar.gz
[root@docker-0001 nginx]# vim Dockerfile
FROM myos:latest                  //基于基础镜像myos:latest
RUN yum install -y pcre openssl && useradd nginx   //执行命令:安装依赖包和创建用户
ADD nginx.tar.gz /usr/local/      //ADD复制压缩包到镜像并自动解压
EXPOSE 80                         //声明开放端口
WORKDIR /usr/local/nginx/html    //指定工作目录
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]   //容器启动命令

补充:因为启动Nginx使用/usr/local/nginx/sbin/nginx不需要环境变量

⑤ 使用docker build对Dockerfile内容生成镜像

[root@docker-0001 nginx]# docker build -t myos:nginx .
…
Successfully built 9879ea2fc8f3
Successfully tagged myos:nginx

⑥ 基于myos:nginx镜像,启动容器并验证服务

[root@docker-0001 ~]# docker images

[root@docker-0001 ~]# docker run -itd myos:nginx    //运行容器,并放入后台
abfe8fcb0685ebccf3b3106813c8a019e9cc5609670a9457b3c59626762f868c
[root@docker-0001 ~]# docker ps -a

[root@docker-0001 ~]# docker inspect abfe8fcb0685
…"IPAddress": "172.17.0.5",    //查看容器的IP
…
[root@docker-0001 ~]# curl http://172.17.0.5/info.html

[root@docker-0001 ~]# curl http://172.17.0.5/info.php


补充:Docker运行Nginx为什么要使用“nginx -g 'daemon off;”

  • 首先,Docker容器启动时,默认会把容器内部的第一个进程(上帝进程),也就是pid=1的程序作为docker容器是否正在运行的依据,如果docker 容器pid=1进程挂了,那么docker容器便会直接退出。
  • 其次,Nginx程序启动并在后台运行,这时Nginx并不是pid为1的程序,而是执行的bash,这个bash执行了Nginx指令后就挂了(Nginx运行会再开一个后台子进程,并将父进程杀掉)
  • 然后,当Docker run的时候把command作为容器内部启动命令,如果使用Nginx,那么Nginx程序将在后台运行,Docker未执行自定义的CMD之前,Nginx的pid是1,执行到CMD之后,Nginx就在后台运行,bash或sh脚本的pid变成了1。所以一旦执行完自定义CMD,Nginx容器也就退出了。
  • 所以,使用Docker编写Nginx镜像CMD容器启动命令时,需要使用“nginx -g 'daemon off;” 让Nginx在当前进程pid=1(前台)下执行主程序;

 

四、发布容器服务

访问容器服务遇到问题:

- 默认容器可以访问外网,但外部网络的主机不可以访问容器内的资源,容器每次创建IP地址都会改变;

- 解决这个问题的最佳方法是端口绑定,容器可以与宿主机的端口进行绑定,从而把宿主机变成对应的服务,不用关系容器的IP地址;

1、发布容器服务

在 Docker 中,使用 -p 参数可以将容器的端口与宿主机的端口进行绑定,从而使容器内的服务可以通过宿主机的网络进行访问。以下是详细的使用方法和注意事项。

  • 格式:docker run -itd -p 宿主机端口:容器端口 镜像名称:标签

-itd:-i 表示交互式运行,-t 表示分配一个伪终端,-d 表示在后台运行容器。
-p:用于端口映射,将宿主机的端口与容器的端口绑定。
宿主机端口:容器端口:宿主机的端口在前,容器的端口在后。
镜像名称:标签:指定要运行的 Docker 镜像及其标签。

例如:当访问宿主机的 http://localhost:80 时,实际访问的是容器内运行在 8080 端口的服务

docker run -itd -p 80:8080 my-web-service:v1.0

1)绑定多个端口:使用多个 -p 参数来绑定多个端口

例如:容器的 8080 端口被映射到宿主机的 80 端口,容器的 8443 端口被映射到宿主机的 443 端口。

docker run -itd -p 80:8080 -p 443:8443 my-web-service:v1.0

2)绑定特定 IP 地址:指定宿主机的特定 IP 地址进行端口绑定

例如:只有通过 192.168.1.100:80 才能访问容器内的服务。

docker run -itd -p 192.168.1.100:80:8080 my-web-service:v1.0

注意事项:

  • 端口冲突:同一宿主机的同一端口只能绑定一个容器服务。如果尝试绑定已经使用的端口,Docker 会报错。
  • 安全性:确保只暴露必要的端口,避免不必要的安全风险。
  • 网络配置:在生产环境中,建议使用 Docker 的网络配置(如 bridge、host、overlay 等)来管理容器的网络访问。

示例:使用容器的宿主机对外发布容器服务

步骤1:给docker-0001云主机绑定一个公网IP:124.71.115.1

步骤2:对外发布服务Apache服务、Nginx服务

① 把docker-0001主机绑定Apache容器的端口,并提供Apahce服务

[root@docker-0001 ~]# docker run -itd -p 80:80 myos:httpd
eb809138c6c52bc03e519c3807a2f9e1341e516fd88b7d2e8ac81f2a6086875e
[root@docker-0001 ~]# ss -nlptu | grep :80
tcp    LISTEN     0      1024   [::]:80                 [::]:*                   users:(("docker-proxy",pid=32100,fd=4))

# 浏览器测试访问服务http://127.71.115.1

# 浏览器测试访问服务http://127.71.115.1/info.php

② 把docker-0001主机绑定Nginx容器的端口,并提供Nginx服务

[root@docker-0001 ~]# docker stop $(docker ps -q)   //启动Nginx服务前,停止Apache
[root@docker-0001 ~]# docker run -itd -p 80:80 myos:nginx
b142115293b22545071404038df5876995fe7b7cbeb2ebce1900528ae6a13468
[root@docker-0001 ~]# ss -nlptu | grep :80
tcp    LISTEN     0      1024   [::]:80                 [::]:*                   users:(("docker-proxy",pid=32353,fd=4))

# 浏览器测试访问服务http://127.71.115.1

# 浏览器测试访问服务http://127.71.115.1/info.html


注意:浏览器测试访问服务http://127.71.115.1/info.php不能解析,其中包含三个问题:

① 因先前压缩的Nginx程序目录时,并未修改nginx配置文件的PHP动态解析配置,导致WEB页面无法解析PHP文件,且直接进入容器修改Nginx配置文件,需要重启Nginx服务及其麻烦;(容器共享卷)

② PHP文件要解析,需交给php-fpm后端服务解析,而php容器则作为后端解析程序,但php容器需要怎么获取Nginx的php文件?(容器共享卷)

③ Nginx容器与PHP容器之间的通信及发布端口需要得到解决;(容器网络通信)

2、主机卷映射(Host Volume Mapping)

Docker 容器的设计初衷是轻量级、可移植的,因此不适合在容器内保存重要数据。主要原因包括:

- 数据易丢失:容器可以随时被删除或替换,导致数据丢失。
- 数据管理困难:在多个容器中修改数据非常困难,尤其是在容器之间需要共享数据时。

为了解决上述问题,Docker 提供了主机卷映射功能。通过将宿主机的文件或目录映射到容器中,可以实现以下目标:

  • 数据持久化:数据保存在宿主机上,即使容器被删除,数据仍然存在。
  • 数据共享:多个容器可以共享同一个宿主机目录,实现数据同步和共享。

映射原则:

目标对象不存在:如果容器内的目标对象(文件或目录)不存在,Docker 会自动创建。
目标对象存在:如果容器内的目标对象已经存在,Docker 会直接覆盖掉。
多容器共享:多个容器可以映射同一个宿主机对象,实现数据共享。
类型匹配:文件只能映射文件,目录只能映射目录。

在启动容器时,可以使用 -v 参数将宿主机的文件或目录映射到容器中

  • - 格式:docker run -itd -v 宿主机对象:容器内对象 镜像名称:标签

-v:用于指定卷映射,将宿主机的文件或目录映射到容器中。
宿主机对象:容器内对象:宿主机的文件或目录在前,容器的文件或目录在后。

例如:将宿主机的 /data 目录映射到容器内的 /app/data 目录,容器内的 /app/data 目录将与宿主机的 /data 目录同步,任何在 /app/data 目录中的更改都会反映在宿主机的 /data 目录中,反之亦然

docker run -itd -v /data:/app/data my-app:v1.0

1)多个卷映射

将宿主机的 /data 目录映射到容器内的 /app/data 目录,宿主机的 /config 目录映射到容器内的 /app/config 目录。

docker run -itd -v /data:/app/data -v /config:/app/config my-app:v1.0

注意事项:

  • 权限问题:确保宿主机上的文件或目录对 Docker 容器有适当的读写权限。
  • 数据一致性:在多容器共享同一个宿主机目录时,注意数据一致性和并发访问问题。
  • 备份与恢复:定期备份宿主机上的数据,以防止数据丢失。

示例:在宿主机上修改Nginx配置文件,通过卷映射到容器内

① 创建目录,修改配置文件

[root@docker-0001 ~]# mkdir /var/webconf
[root@docker-0001 ~]# cp /usr/local/nginx/conf/nginx.conf /var/webconf/
[root@docker-0001 ~]# vim /var/webconf/nginx.conflocation ~ \.php$ {root           html;fastcgi_pass   127.0.0.1:9000;fastcgi_index  index.php;#   fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;include        fastcgi.conf;}

② 启用容器并映射宿主机的nginx.conf文件到容器内的nginx.conf文件

  • - 格式:docker run -itd -p 宿主机端口:容器端口 镜像名称:标签
[root@docker-0001 ~]# docker run -itd -p 80:80 --name nginx \
> -v /var/webconf/nginx.conf:/usr/local/nginx/conf/nginx.conf myos:nginx
a685e6096357597a4bfdc1bd7dca3dd7f60d21e760559966a8ce1e5ef534a636

③ 查看配置文件中,php动态解析相关配置是否被映射到容器内

[root@a685e6096357 ~]# cat /usr/local/nginx/conf/nginx.conf

3、容器网络通信

在 Docker 中,Nginx 容器调用 PHP-FPM 容器通常需要利用容器的网络特性,特别是通过共享网络命名空间来实现通信。以下是实现这一目标的步骤和方法。

① 共享网络命名空间

为了让 PHP-FPM 容器监听 Nginx 容器的网络端口,可以使用 Docker 的 container 网络模式,共享 Nginx 容器的网络命名空间。

docker run -itd --name nginx-container nginx:latest
docker run -itd --network container:nginx-container --name php-fpm-container php:fpm

在这个例子中,php-fpm-container 容器将与 nginx-container 容器共享网络命名空间,因此可以直接通过 localhost 或 127.0.0.1 进行通信。


② 共享卷映射

当客户端访问 Nginx 的 PHP 文件时,Nginx 会向后端 PHP-FPM 传递文件路径。由于 PHP-FPM 容器本身没有 Nginx 的文件,因此可以使用宿主机的共享卷,在 Nginx 和 PHP-FPM 容器之间共享目录。

docker run -itd -v /host/path/to/web:/usr/share/nginx/html --name nginx-container nginx:latest
docker run -itd -v /host/path/to/web:/usr/share/nginx/html --network container:nginx-container --name php-fpm-container php:fpm

在这个例子中,宿主机的 /host/path/to/web 目录被映射到 Nginx 和 PHP-FPM 容器的 /usr/share/nginx/html 目录。这样,PHP-FPM 容器可以找到并解析 PHP 文件,然后将解析结果反馈给 Nginx,最终返回给客户端。

1)Docker 网络通信模式

Docker 提供了多种网络通信模式,每种模式都有其特定的用途和适用场景。

  • - 格式:docker run -itd –network container:共享容器 镜像名称:标签

① host 模式:容器与宿主机共享网络栈,容器的网络配置与宿主机完全相同

docker run -itd --network host 镜像名称:标签

② container 模式:新创建的容器与指定的容器共享网络命名空间

docker run -itd --network container:共享容器 镜像名称:标签

③ none 模式:容器没有网络配置,不与任何网络连接

docker run -itd --network none 镜像名称:标签

④ bridge 模式: Docker 的默认网络模式,容器通过 Docker 的虚拟网桥进行通信

docker run -itd 镜像名称:标签

⑤ 自定义网络:允许用户创建自定义的桥接网络或 overlay 网络,以满足特定的网络需求

docker network create my-custom-network
docker run -itd --network my-custom-network 镜像名称:标签

示例:结合容器共享卷+容器网络通信,将Nginx服务上线

# 提前将所需网页文件拷贝到192.168.1.31中(参考:kubernetes/docker-images)

[root@ecs-proxy docker-images]# scp info.php info.html 192.168.1.31:/root

步骤1:创建目录,并将所需网页文件、配置文件拷贝到对应目录

[root@docker-0001 ~]# mkdir -p /var/{webroot,webconf}
[root@docker-0001 ~]# cp info.php info.html /var/webroot/    //共享网页目录
[root@docker-0001 ~]# cp /usr/local/nginx/conf/nginx.conf /var/webconf/
[root@docker-0001 ~]# vim /var/webconf/nginx.conf    //修改配置文件location ~ \.php$ {root           html;fastcgi_pass   127.0.0.1:9000;fastcgi_index  index.php;#   fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;include        fastcgi.conf;}

步骤2:停止并删除所有的容器

[root@docker-0001 ~]# docker stop $(docker ps -qa)
[root@docker-0001 ~]# docker rm $(docker ps -qa)

步骤3:启动前端nginx服务,并映射共享目录和配置文件

[root@docker-0001 ~]# docker images

[root@docker-0001 ~]# docker run -itd --name nginx -p 80:80 \
> -v /var/webconf/nginx.conf:/usr/local/nginx/conf/nginx.conf \
> -v /var/webroot/:/usr/local/nginx/html/ myos:nginx
f3f2f92d2df2b4381e19d5703a7b78d485e1429180356e27dd8cc717a9a2b047

步骤4:启动后端 php 服务,并映射共享目录

[root@docker-0001 ~]# docker run -itd --network=container:nginx \
> -v /var/webroot/:/usr/local/nginx/html/ myos:php-fpm
155d8c8625a8bc1b611da7298b6d2a158359f54de9b0410b396e81af63cb500b

解释:network=container:nginx,共享nginx容器的网络命名空间,两个容器共用网卡,是nginx容器的eth0地址,所以不需要再用【-p】发布端口;启动php容器后能监听到80和9000端口,但监听的80端口无法控制也无法查到对应服务,该80端口由nginx容器进行控制;

步骤5:验证服务

[root@docker-0001 ~]# curl http://docker-0001/info.html
<html><marquee  behavior="alternate"><font size="12px" color=#00ff00>Hello World</font></marquee>
</html>[root@docker-0001 ~]# curl http://docker-0001/info.php
<pre>
Array
([REMOTE_ADDR] => 172.17.0.1[REQUEST_METHOD] => GET[HTTP_USER_AGENT] => curl/7.29.0[REQUEST_URI] => /info.php
)
php_host:       f3f2f92d2df2
1229

五、Docker私有镜像仓库

1、私有仓库的用途

私有仓库是组建容器集群的必要组件,主要用途包括:

  • 镜像管理:集中管理内部使用的 Docker 镜像,确保镜像的安全性和一致性。
  • 版本控制:方便进行镜像的版本控制和回滚。
  • 加速部署:减少从公共仓库拉取镜像的时间,加速容器部署。

 

2、搭建私有仓库(服务端)

① 安装私有仓库软件

使用 yum 安装 docker-distribution 软件包:

yum install docker-distribution

② 启动私有仓库,并设置开机自启动

systemctl enable --now docker-distribution
  • 仓库配置文件/etc/docker-distribution/registry/config.yml
  • 数据存储路径/var/lib/registry/
  • 默认端口号:5000

查看私有镜像仓库中的镜像名称或标签

  • 查看镜像名称
curl http://192.168.1.100:5000/v2/_catalog
  • 查看镜像标签
curl http://192.168.1.100:5000/v2/镜像名称/tags/list

注意:私有仓库里的镜像与 Docker 本地镜像不是同一个对象。私有仓库的镜像必须使用curl 命令查询,而本地镜像可以通过 docker images 查看。

3、管理私有仓库(客户端)

为了让本地 Docker 客户端知道私有仓库的地址,需要编辑 /etc/docker/daemon.json 文件,添加以下内容:

{"exec-opts": ["native.cgroupdriver=systemd"],"registry-mirrors": ["https://hub-mirror.c.163.com"],"insecure-registries": ["192.168.1.100:5000", "registry:5000"]
}

cgroup 驱动:Docker 默认驱动是 cgroupfs,可以改为 systemd 以提高性能。
默认下载仓库:使用国内镜像源加速访问。
私有仓库地址:指定私有镜像仓库的 IP 地址和端口号。

编辑完成后,重启 Docker 服务:

systemctl restart docker

4、为镜像创建标签,上传镜像:

1)创建标签

为本地镜像创建标签,指向私有仓库:docker tag 本地镜像:标签 私有镜像仓库IP:5000/镜像:标签

例如:

docker tag my-image:latest 192.168.1.100:5000/my-image:latest

2)上传镜像

将镜像推送到私有仓库:docker push 私有镜像仓库IP:5000/镜像:标签

例如:

docker push 192.168.1.100:5000/my-image:latest

注意:镜像名称必须包含私有仓库的 IP 地址和路径,否则无法确定上传位置

5、通过私有仓库镜像启动容器

使用私有仓库中的镜像启动容器:docker run -it 私有镜像仓库IP:5000/镜像:标签
例如:

docker run -it 192.168.1.100:5000/my-image:latest

总结:通过搭建和管理私有镜像仓库,可以有效管理内部使用的 Docker 镜像,确保镜像的安全性和一致性。合理配置私有仓库和客户端,可以加速容器部署和版本控制。


示例:部署Docker私有仓库

主机名

IP地址

最低配置

registry

192.168.1.100

1CPU,1G内存

步骤1:购买1台云主机

[root@ecs-proxy ~]# ping 192.168.1.100
PING 192.168.1.100 (192.168.1.100) 56(84) bytes of data.
64 bytes from 192.168.1.100: icmp_seq=15 ttl=64 time=0.748 ms
64 bytes from 192.168.1.100: icmp_seq=16 ttl=64 time=0.219 ms

步骤2:搭建私有仓库(registry操作)

[root@ecs-proxy ~]# ssh 192.168.1.100
[root@registry ~]# yum -y install docker-distribution    //安装软件包
[root@registry ~]# systemctl enable --now docker-distribution  //开启服务并设开机自启
[root@registry ~]# curl http://192.168.1.100:5000/v2/_catalog  //查看私有仓库中的镜像名称
{"repositories":[]}

步骤3:Docker客户端配置(docker-0001操作)

[root@docker-0001 ~]# vim /etc/docker/daemon.json
{"exec-opts": ["native.cgroupdriver=systemd"],   //cgroup驱动"registry-mirrors": ["https://hub-mirror.c.163.com"],   // 默认下载仓库"insecure-registries":["192.168.1.100:5000", "registry:5000"]   //私有仓库地址
}
[root@docker-0001 ~]# systemctl restart docker.service   //重启服务
[root@docker-0001 ~]# docker info | grep Cgroup   //查看容器信息
Cgroup Driver: systemd

步骤4:上传镜像(myos:latest, myos:httpd, myos:nginx, myos:php-fpm)

  • 格式:docker tag 本地镜像:标签 私有镜像仓库IP:5000/镜像:标签    //创建标签
  • 格式:docker push 私有镜像仓库IP:5000/镜像:标签    //上传镜像
[root@docker-0001 ~]# docker tag myos:latest 192.168.1.100:5000/myos:latest
[root@docker-0001 ~]# docker images

[root@docker-0001 ~]# docker push 192.168.1.100:5000/myos:latest
The push refers to repository [192.168.1.100:5000/myos]
f22c5cb6be20: Pushed
bcc97fbfc9e1: Pushed
latest: digest: sha256:4a8d25a7efe3c962c8ec7eb2b21d6d3817319d3e738a4b8fd8d45f4dc9f8cb9a size: 741

 # 使用For循环批量上传镜像

[root@docker-0001 ~]# for i in httpd php-fpm nginx
> do
> docker tag myos:${i} 192.168.1.100:5000/myos:${i}
> docker push 192.168.1.100:5000/myos:${i}
> done

步骤5:验证测试,查看私有镜像仓库中的镜像名称和标签(docker-0002操作)

  • 命令:curl http://仓库IP:5000/v2/_catalog    //查看私有仓库中的镜像名称
  • 命令:curl http://仓库IP:5000/v2/镜像名称/tags/list  //查看私有仓库中的镜像名称的标签
[root@docker-0001 ~]# ssh 192.168.1.32
[root@docker-0002 ~]# curl http://192.168.1.100:5000/v2/_catalog
{"repositories":["myos"]}
[root@docker-0002 ~]# curl http://192.168.1.100:5000/v2/myos/tags/list
{"name":"myos","tags":["php-fpm","httpd","latest","nginx"]}

步骤6:验证测试,使用远程镜像启动容器(docker-0002操作)

  • 格式:docker run -it 私有镜像仓库IP:5000/镜像:标签

① Docker端编写配置文件,连接私有仓库

[root@docker-0002 ~]# vim /etc/docker/daemon.json
{"exec-opts": ["native.cgroupdriver=systemd"],"registry-mirrors": ["https://hub-mirror.c.163.com"],"insecure-registries":["192.168.1.100:5000", "registry:5000"]
}
[root@docker-0002 ~]# systemctl restart docker   //重启服务

② 使用远程镜像启动容器

[root@docker-0002 ~]# docker run -it 192.168.1.100:5000/myos:latest
Unable to find image '192.168.1.100:5000/myos:latest' locally
latest: Pulling from myos
7dc0dca2b151: Pull complete
62f184ddaa87: Pull complete
Digest: sha256:4a8d25a7efe3c962c8ec7eb2b21d6d3817319d3e738a4b8fd8d45f4dc9f8cb9a
[root@238c1ad313d4 /]# exit
Exit
[root@docker-0002 ~]# docker ps -a

[root@docker-0002 ~]# docker images

步骤6:下载镜像

[root@docker-0002 ~]# docker pull 192.168.1.100:5000/myos:httpd
httpd: Pulling from myos
7dc0dca2b151: Already exists
62f184ddaa87: Already exists
7def584b8ca0: Pull complete
2be9ee4dc167: Pull complete
Digest: sha256:23c1514167627cad7ab9bf90bab5852a2908a0a1e902bf251da125c68c71cb91
Status: Downloaded newer image for 192.168.1.100:5000/myos:httpd
[root@docker-0002 ~]# docker run -itd 192.168.1.100:5000/myos:httpd
b2209bfc1188312a2e8a055ce1059f3927101c2fb8230eb49e3138d7bbac6928

常见报错:Docker本地端未编写配置文件指定私有仓库地址,则会有以下报错

扩展知识:使用Dockerfile制作Tomcat的镜像

步骤1:自定义基础镜像

① 拷贝镜像压缩包到192.168.1.32

[root@ecs-proxy ~]# scp /root/kubernetes/docker-images/centos.tar.gz 192.168.1.32:/root/

② 导入镜像压缩包

[root@node-0002 ~]# docker load -i centos.tar.gz

③ 修改镜像内容

[root@node-0002 ~]# docker run -it centos:latest /bin/bash
[root@76e6c1740ccc /]# rm -rf /etc/yum.repos.d/*.repo
[root@76e6c1740ccc /]# curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.myhuaweicloud.com/repo/CentOS-Base-7.repo
[root@76e6c1740ccc /]# yum install -y net-tools vim-enhanced tree bash-completion iproute psmisc && yum clean all
[root@76e6c1740ccc /]# exit

④ 创建自定义镜像

[root@node-0002 ~]# docker ps -a
CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS                         PORTS               NAMES
76e6c1740ccc        centos:latest                   "/bin/bash"              2 minutes ago       Exited (0) 30 seconds ago                          hopeful_noether
[root@node-0002 ~]# docker commit 76e6c1740ccc baseos:latest
sha256:1ca4ec4086ba5b50d2b6e95e298f96a37e3163b086f639d2ff3d2f4ede75f572
[root@node-0002 ~]# docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
baseos                          latest              1ca4ec4086ba        12 seconds ago      281MB

步骤2:通过Dockerfil制作Tomcat镜像

① 创建存放目录

[root@node-0002 ~]# mkdir tomcat ; cd tomcat
[root@node-0002 tomcat]# exit
logout
[root@ecs-proxy ~]# scp apache-tomcat-9.0.6.tar.gz 192.168.1.32:/root/tomcat
[root@node-0002 tomcat]# ls
apache-tomcat-9.0.6.tar.gz

② 编写Dockerfile文件

[root@node-0002 tomcat]# vim Dockerfile
FROM baseos:latest
RUN yum -y install java-1.8.0-openjdk java-1.8.0-openjdk-devel && useradd tomcat
ADD apache-tomcat-9.0.6.tar.gz /usr/local/
EXPOSE 8080
CMD ["/usr/local/apache-tomcat-9.0.6/bin/catalina.sh","run"]

③ 使用docker build对Dockerfile内容生成镜像

[root@node-0002 tomcat]# docker build -t myos:tomcat .
...
Successfully built f73ed852de80
Successfully tagged myos:tomcat
[root@node-0002 tomcat]# docker run -itd myos:tomcat
a4c84ef277549a39bb19f811e219e950d587edc33c125e41eb9c570f20d93090
[root@node-0002 tomcat]# docker exec -it a4c84ef277 /bin/bash
[root@a4c84ef27754 /]# ss -nlptu | grep :8080
tcp    LISTEN     0      100       *:8080                  *:*                   users:(("java",pid=1,fd=51))

思维导图:

 

小结:

本篇章节为【第五阶段】CLOUD-DAY5 的学习笔记,这篇笔记可以初步了解到 容器的镜像编排,commit简单镜像创建,Dockerfile制作服务镜像(语法、创建镜像)、创建复杂镜像(Docker微服务架构、示例:NGINX+PHP)、私有仓库。


Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解。

相关文章:

Linux云计算 |【第五阶段】CLOUD-DAY5

主要内容&#xff1a; 容器的镜像编排&#xff0c;commit简单镜像创建&#xff0c;Dockerfile制作服务镜像&#xff08;语法、创建镜像&#xff09;、创建复杂镜像&#xff08;Docker微服务架构、示例&#xff1a;NGINXPHP&#xff09;、私有仓库 一、简单镜像创建 1、自定义…...

被上传文件于后端的命名策略

上一篇博客我们了解了前端上传的文件资源应该存放在后端项目中的什么位置&#xff0c;那么随之而来的另一个问题——我们应该如何为上传的文件命名呢&#xff1f;往往直接采用原文件名并不稳妥&#xff0c;会导致命名冲突、文件冲突、数据库管理冲突等多种问题&#xff0c;下面…...

哈希表 算法专题

哈希表简介 是什么 存储数据的容器有啥用? "快速"查找某个元素什么时候用哈希表 频繁地查找某个数(有序用二分)怎么用哈希表 容器用数组模拟 字符串中的字符 范围比较小的数 一. 两数之和 两数之和 class Solution {public int[] twoSum(int[] nums, int targe…...

unity3d————[HideInInspector]

在Unity3D中&#xff0c;[HideInInspector]是一个属性修饰符&#xff0c;它的主要作用是在Unity的Inspector窗口中隐藏变量或属性。以下是关于[HideInInspector]的详细解释和作用&#xff1a; 作用 隐藏变量或属性&#xff1a;当你在脚本中使用[HideInInspector]修饰符时&…...

Soanrquber集成Gitlab 之 导入Gitlab项目

集成Gitlab 之 导入Gitlab项目 说明&#xff1a; Sonarquber里面的项目&#xff0c;顺便设置&#xff0c;只要在集成CI的时候&#xff0c;使用这个项目的项目标识即可。 当然项目名称一一对应是最好的了&#xff0c;所以这里讲导入Gitlab的项目&#xff0c;项目名称一一对应&…...

论区块链技术及应用

引言 区块链技术作为一种革命性的创新&#xff0c;近年来在全球范围内得到了广泛关注和应用。其去中心化、透明性和不可篡改的特性&#xff0c;使其在多个领域展现出了巨大的潜力。从金融到物联网&#xff0c;从医疗管理到政务监管&#xff0c;区块链正在改变我们处理信息和进…...

GPT避坑指南:如何辨别逆向、AZ、OpenAI官转

市面上有些说自己是官转&#xff0c;一刀只需要1块甚至几毛钱&#xff0c;并声称官方倍率的&#xff0c;很大可能就是使用的是 逆向或Azure。 如何鉴别逆向 逆向的种类很多&#xff0c;主要分为3类 逆向不知名A| 镜像站或偷的 key。成本约等于0&#xff0c;调用聊天数据可能在…...

Qt 文本文件读写与保存

Qt 文本文件读写与保存 开发工具&#xff1a;VS2013 QT5.8 设计UI界面&#xff0c;如下图所示 sample7_1QFile.h 头文件&#xff1a; #pragma once#include <QtWidgets/QMainWindow> #include "ui_sample7_1QFile.h"class sample7_1QFile : public QMainWin…...

Linux基础环境搭建(CentOS7)- 安装Scala和Spark

#Linux基础环境搭建&#xff08;CentOS7&#xff09;- 安装Scala和Spark Linux基础环境搭建&#xff08;CentOS7&#xff09;- 安装Scala和Spark 大家注意以下的环境搭建版本号&#xff0c;如果版本不匹配有可能出现问题&#xff01;&#xff08;spark不要下2.4版本的 会报错…...

SpringBoot 下的Excel文件损坏与内容乱码问题

序言 随着打包部署的方式的改变&#xff0c;原本正常运行的代码可能带来一些新的问题&#xff0c;比如我们现在使用SpringBoot 的方式生成Jar包直接运行&#xff0c;就会对我们再在Resource下的Excel文件产生影响&#xff0c;导入与预期不符的情况发生cuiyaonan2000163.com 比…...

官宣下代GPU存在缺陷,50系显卡或将迎来涨价

如果说 AMD 在 Ryzen 3000 系列还是和 intel 在 CPU 方面棋差一着的话&#xff0c;Ryzen 5000 系列就是打了个漂亮的翻身仗了。 凭借先进的 7nm 工艺制程和全新架构&#xff0c;让后来 intel 急忙推出「14nm」的 11 代酷睿也难以望其项背。 直到 intel 12 代发布的时候&#xf…...

使用pytorch实现LSTM预测交通流

原始数据&#xff1a; 免费可下载原始参考数据 预测结果图&#xff1a; 根据测试数据test_data的真实值real_flow&#xff0c;与模型根据测试数据得到的输出结果pre_flow 完整源码&#xff1a; #!/usr/bin/env python # _*_ coding: utf-8 _*_import pandas as pd import nu…...

C/C++(八)C++11

目录 一、C11的简介 二、万能引用与完美转发 1、万能引用&#xff1a;模板中的 && 引用 2、完美转发&#xff1a;保持万能引用左右值属性的解决方案 三、可变参数模板 1、可变参数模板的基本使用 2、push 系列和 emplace 系列的区别 四、lambda表达式&#xf…...

使用three.js 实现 自定义绘制平面的效果

使用three.js 实现 自定义绘制平面的效果 预览 import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControls.jsconst box document.getElementById(box)const scene new THREE.Scene()const camera new THREE.PerspectiveCam…...

玩转Docker | 使用Docker部署捕鱼网页小游戏

玩转Docker | 使用Docker部署捕鱼网页小游戏 一、项目介绍项目简介项目预览二、系统要求环境要求环境检查Docker版本检查检查操作系统版本三、部署捕鱼网页小游戏下载镜像创建容器检查容器状态下载项目内容查看服务监听端口安全设置四、访问捕鱼网页小游戏五、总结一、项目介绍…...

第2章 Android App开发基础

第 2 章 Android App开发基础 bilibili学习地址 github代码地址 本章介绍基于Android系统的App开发常识&#xff0c;包括以下几个方面&#xff1a;App开发与其他软件开发有什么不一 样&#xff0c;App工程是怎样的组织结构又是怎样配置的&#xff0c;App开发的前后端分离设计…...

通过 SYSENTER/SYSEXIT指令来学习系统调用

SYSENTER指令—快速系统调用 指令格式没有什么重要的内容,只有opcode ,没有后面的其他字段 指令的作用: 执行快速调用到特权级别0的系统过程或例程。SYSENTER是SYSEXIT的配套指令。该指令经过优化&#xff0c;能够为从运行在特权级别3的用户代码到特权级别0的操作系统或执行过程…...

Nginx开发实战——网络通信(一)

文章目录 Nginx开发框架信号处理函数的进一步完善(避免僵尸子进程)(续&#xff09;ngx_signal.cxxngx_process_cycle.cxx 网络通信实战客户端和服务端1. 解析一个浏览器访问网页的过程2.客户端服务器角色规律总结 网络模型OSI 7层网络模型TCP/IP 4层模型3.TCP/IP的解释和比喻 最…...

w外链如何跳转微信小程序

要创建外链跳转微信小程序&#xff0c;主要有以下几种方法&#xff1a; 使用第三方工具生成跳转链接&#xff1a; 注册并登录第三方外链平台&#xff1a;例如 “W外链” 等工具。前往该平台的官方网站&#xff0c;使用手机号、邮箱等方式进行注册并登录账号。选择创建小程序外…...

获取平台Redis各项性能指标

业务场景 在XXXX项目中把A网的过车数据传到B网中&#xff0c;其中做了一个业务处理&#xff0c;就是如果因为网络或者其他原因导致把数据传到B网失败&#xff0c;就会把数据暂时先存到redis里&#xff0c;并且执行定时任务重新发送失败的。 问题 不过现场的情况比较不稳定。出…...

STM32 HAL 点灯

首先从点灯开始 完整函数如下&#xff1a; #include "led.h" #include "sys.h"//包含了stm32f1xx.h&#xff08;包含各种寄存器定义、中断向量定义、常量定义等&#xff09;//初始化GPIO口 void led_init(void) {GPIO_InitTypeDef gpio_initstruct;//打开…...

【http作业】

1.关闭防火墙 [rootlocalhost ~]# systemctl stop firewalld #关闭防火墙 [rootlocalhost ~]# setenforce 0 2.下载nginx包 [rootlocalhost ~]# mount /dev/sr0 /mnt #挂载目录 [rootlocalhost ~]# yum install nginx -y #下载nginx包 3.增加多条端口 [rootlocalhost ~]# n…...

WPF+MVVM案例实战(十一)- 环形进度条实现

文章目录 1、运行效果2、功能实现1、文件创建与代码实现2、角度转换器实现3、命名空间引用3、源代码下载1、运行效果 2、功能实现 1、文件创建与代码实现 打开 Wpf_Examples 项目,在Views 文件夹下创建 CircularProgressBar.xaml 窗体文件。 CircularProgressBar.xaml 代码实…...

简述MCU微控制器

目录 一、MCU 的主要特点&#xff1a; 二、常见 MCU 系列&#xff1a; 三、应用场景&#xff1a; MCU 是微控制器&#xff08;Microcontroller Unit&#xff09;的缩写&#xff0c;指的是一种小型计算机&#xff0c;专门用于嵌入式系统。它通常集成了中央处理器&#xff08;…...

微服务的雪崩问题

微服务的雪崩问题&#xff1a; 微服务调用链路中的某个服务故障&#xff0c;引起整个链路种的所有微服务都不可用。这就是微服务的雪崩问题。&#xff08;级联失败&#xff09;&#xff0c;具体表现出来就是微服务之间相互调用&#xff0c;服务的提供者出现阻塞或者故障&#x…...

Java基础(4)——构建字符串(干货)

今天聊Java构建字符串以及其内存原理 我们先来看一个小例子。一个是String,一个是StringBuilder. 通过结果对比&#xff0c;StringBuilder要远远快于String. String/StringBuilder/StringBuffer这三个构建字符串有什么区别&#xff1f; 拼接速度上&#xff0c;StringBuilder…...

logback日志脱敏后异步写入文件

大家项目中肯定都会用到日志打印&#xff0c;目的是为了以后线上排查问题方便&#xff0c;但是有些企业对输出的日志包含的敏感(比如&#xff1a;用户身份证号&#xff0c;银行卡号&#xff0c;手机号等)信息要进行脱敏处理。 哎&#xff01;我们最近就遇到了日志脱敏的改造。可…...

电容的基本知识

1.电容的相关公式 2.电容并联和串联的好处 电容并联的好处: 增加总电容值: 并联连接的电容器可以增加总的电容值,这对于需要较大电容值来滤除高频噪声或储存更多电荷的应用非常有用。 改善频率响应: 并联不同的电容值可以设计一个滤波器,以在特定的频率范围内提供更好的滤…...

【Axure高保真原型】分级树筛选中继器表格

今天和大家分享分级树筛选中继器表格的原型模板&#xff0c;点击树的箭头可以展开或者收起子级内容&#xff0c;点击内容&#xff0c;可以筛选出该内容及子级内容下所有的表格数据。左侧的树和右侧的表格都是用中继器制作的&#xff0c;所以使用也很方便&#xff0c;只需要在中…...

STM32 I2C通信:硬件I2C与软件模拟I2C的区别

文章目录 STM32 I2C通信&#xff1a;硬件I2C与软件模拟I2C的区别。一、硬件I2C速度快&#xff1a;实现简单&#xff1a;稳定性好&#xff1a; 二、软件模拟I2C灵活性高&#xff1a;支持多路通信&#xff1a; 三、选择哪种方式&#xff1f; STM32 I2C通信&#xff1a;硬件I2C与软…...

山乙建设公司网站/百度舆情

设置vscode为中文ctrshiftp 输入 configure language 进 en更改为zh-cn , 重启vscode即可 , 如果还不行,就安装插件 转载于:https://www.cnblogs.com/enych/p/10550095.html...

网站的设计与开发论文/网站宣传方法

红黑树插入和删除结点的全程演示 作者&#xff1a;July、saturnman。时间&#xff1a;二零一一年三月二十八日。出处&#xff1a;http://blog.csdn.net/v_JULY_v。声明&#xff1a;版权所有&#xff0c;侵权必究。----------------------------------- 引言&#xff1a;目前国内…...

最专业的企业营销型网站建设价格/seo公司软件

千呼万唤始出来&#xff01;为了更好的迎接2021年&#xff0c;小编特汇总了四大运营商发布的5G资料供大家学习&#xff0c;欢迎下载。小编共汇总了94份资料&#xff0c;中国移动有45份&#xff0c;中国联通有28份&#xff0c;中国电信有15份&#xff0c;中国广电有6份。文件获取…...

富阳做网站公司/网站优化塔山双喜

一、Bootstrap 卡片(面板) 1.1 简单的卡片 我们可以通过 Bootstrap4 的 .card 与 .card-body 类来创建一个简单的卡片&#xff0c;实例如下: <div class"container"><div class"card"><div class"card-body">简单的卡片</…...

电子商务网站建设与维护期末/少儿培训

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼第一&#xff1a;数据库之对比&#xff1a;相对于&#xff0c;ifix中的过程数据库&#xff0c;.net更偏向于sqlserver,orcle,mysql&#xff0c;db2类型的关系数据库。ifix之向关系数据库中更多的是向access数据啼中传送相关报警的历…...

常宁seo外包/seo草根博客

知识点&#xff1a; &#xff08;1&#xff09;变量的地址就是变量的指针。 &#xff08;2&#xff09;变量的值和变量的地址是不同的概念&#xff0c;变量的值是该变量在内存单元中的数据。 &#xff08;3&#xff09;用来存放指针/地址的变量就称为“指针变量”。 &#xff0…...