技术标签: kubernetes 配置分离 ConfigMap K8S Kubernetes
创建语法:使用命令参数 --from-literal=key=value 定义一个配置项,可以定义一个或多个配置项。配置项中的 key 会成为 ConfigMap 中的 key,配置项中的 value 会成为 ConfigMap 中的 value。
kubectl create configmap configmap_name --from-literal=key1=value1 --from-literal=key2=value2
创建示例:
kubectl create configmap cm1 --from-literal=username=admin --from-literal=password=123456
创建结果:执行以下命令,即可查看到创建结果如下图所示。
kubectl get configmap cm1 -o yaml
创建语法:使用命令参数 --from-file=dir 定义一个配置项,可以定义一个或多个配置项。dir 目录下的文件的名称会成为 ConfigMap 中的 key,dir 目录下的文件的内容会成为 ConfigMap 中的 value。
kubectl create configmap configmap_name --from-file=dir1 --from-file=dir2
创建示例:
kubectl create configmap cm2 --from-file=config
# config/application-dev.yml
env: dev
msg: dev profile
# config/application-test.yml
env: test
msg: test profile
# config/application-prod.yml
env: prod
msg prod profile
创建结果:执行以下命令,即可查看到创建结果如下图所示。
kubectl get configmap cm2 -o yaml
创建语法:使用命令参数 --from-file=file 定义一个配置项,可以定义一个或多个配置项。file 文件的名称会成为 ConfigMap 中的 key,file 文件的内容会成为 ConfigMap 中的 value。
kubectl create configmap configmap_name --from-file=file1 --from-file=file2
创建示例:
kubectl create configmap cm3 --from-file=application-dev.yml --from-file=application-test.yml
# config/application-dev.yml
env: dev
msg: dev profile
# config/application-test.yml
env: test
msg: test profile
创建结果:执行以下命令,即可查看到创建结果如下图所示。
kubectl get configmap cm3 -o yaml
创建语法:使用命令参数 --from-env-file=file 定义配置项,如果定义了多个配置项,则只有最后一个配置项生效。file 文件的内容的每一行都必须是 key=value 的形式,file 文件中每行的 key 会成为 ConfigMap 中的 key,file 文件中每行的 value 会成为 ConfigMap 中的 value。
kubectl create configmap configmap_name --from-env-file=file
创建示例:
kubectl create configmap cm4 --from-env-file=application.properties
# application.properties
username=admin
password=123456
创建结果:执行以下命令,即可查看到创建结果如下图所示。
kubectl get configmap cm4 -o yaml
配置文件:创建一个名称为 simple-cm-demo.yaml 的配置文件,内容如下所示。使用该配置文件创建的 ConfigMap 与 1.1.1节或1.1.4节中的方式创建的 ConfigMap 的形式一致。
apiVersion: v1
kind: ConfigMap
metadata:
name: simple-cm
data:
username: admin
password: "123456"
创建命令:
kubectl apply -f simple-cm-demo.yaml
创建结果:执行以下命令,即可查看到创建结果如下图所示。
kubectl get configmap simple-cm -o yaml
配置文件:创建一个名称为 complex-cm-demo.yaml 的配置文件,内容如下所示。使用该配置文件创建的 ConfigMap 与 1.1.2节或1.1.3节中的方式创建的 ConfigMap 的形式一致。
apiVersion: v1
kind: ConfigMap
metadata:
name: complex-cm
data:
application-dev.yml: |
env: dev
msg: dev profile
application-test.yml: |
env: test
msg: test profile
创建命令:
kubectl apply -f complex-cm-demo.yaml
创建结果:执行以下命令,即可查看到创建结果如下图所示。
kubectl get configmap complex-cm -o yaml
配置文件:创建一个名称为 single-cm-demo.yaml 的配置文件,内容如下所示。该配置文件中定义了一个名称为 env-cm 的ConfigMap,并把其中的 DEPLOYMENT_ENV:test 配置项以环境变量的形式传给名称为 single-cm-deployment 的 Deployment。
apiVersion: v1
kind: ConfigMap
metadata:
name: env-cm
data:
DEPLOYMENT_ENV: test
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: single-cm-deployment
labels:
app: single-cm
spec:
replicas: 1
selector:
matchLabels:
app: single-cm
template:
metadata:
labels:
app: single-cm
spec:
containers:
- name: test-container
image: my-app:latest
imagePullPolicy: IfNotPresent
args: ["--spring.profiles.active=$(DEPLOYMENT_ENV_KEY)"]
ports:
- containerPort: 8080
env:
- name: DEPLOYMENT_ENV_KEY
valueFrom:
configMapKeyRef:
name: env-cm
key: DEPLOYMENT_ENV
部署配置:执行以下命令即可使用该部署文件进行部署。
kubectl apply -f single-cm-demo.yaml
部署结果:该 Deployment 中接收一个名称为 spring.profiles.active 的命令行参数,而传给该命令行参数的值则为名称为 DEPLOYMENT_ENV_KEY 的环境变量的值,即实际传的值为 test,由于该配置文件中使用的镜像 my-app:latest 是一个Spring Boot 程序应用,所以通过这个环境变量即是指定使用 test 配置环境来启动该应用时。
部署文件:创建一个名称为 multi-cm-demo.yaml 的配置文件,内容如下所示。该配置文件中定义了两个名称分别为 app-cm 和 log-cm 的ConfigMap,并把其中的 APPLICATION_NAME: smart-classroom 配置项 和 LOG_LEVEL: INFO 配置项以环境变量的形式传给名称为 multi-cm-deployment 的 Deployment。
apiVersion: v1
kind: ConfigMap
metadata:
name: app-cm
data:
APPLICATION_NAME: SMART-CLASSROOM
---
apiVersion: v1
kind: ConfigMap
metadata:
name: log-cm
data:
LOG_LEVEL: INFO
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: multi-cm-deployment
labels:
app: multi-cm
spec:
replicas: 1
selector:
matchLabels:
app: multi-cm
template:
metadata:
labels:
app: multi-cm
spec:
containers:
- name: test-container
image: busybox:latest
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "echo $(APPLICATION_NAME_KEY) $(LOG_LEVEL_KEY)" ]
env:
- name: APPLICATION_NAME_KEY
valueFrom:
configMapKeyRef:
name: app-cm
key: APPLICATION_NAME
- name: LOG_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: log-cm
key: LOG_LEVEL
部署配置:执行以下命令即可使用该部署文件进行部署。
kubectl apply -f multi-cm-demo.yaml
部署结果:该 Deployment 会在创建的 POD 内部的日志中打印出名称分别为 APPLICATION_NAME_KEY 和 LOG_LEVEL_KEY 的环境变量的值,即会打印出以下结果。
SMART-CLASSROOM INFO
部署文件:创建一个名称为 one-cm-multi-key-demo.yaml 的配置文件,内容如下所示。该配置文件中定义了一个名称为 db-cm 的 ConfigMap,并把其中的所有配置项以环境变量的形式传给名称为 one-cm-multi-key-deployment 的 Deployment。
apiVersion: v1
kind: ConfigMap
metadata:
name: db-cm
data:
HOST: 127.0.0.1
PORT: "3306"
USERNAME: admin
PASSWORD: "123456"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: one-cm-multi-key-deployment
labels:
app: one-cm-multi-key
spec:
replicas: 1
selector:
matchLabels:
app: one-cm-multi-key
template:
metadata:
labels:
app: one-cm-multi-key
spec:
containers:
- name: test-container
image: busybox:latest
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- configMapRef:
name: db-cm
部署配置:执行以下命令即可使用该部署文件进行部署。
kubectl apply -f one-cm-multi-key-demo.yaml
部署结果:该 Deployment 会在创建的 POD 内部的日志中打印出所有环境变量的名称和值,即打印结果中会包含以下内容。
HOST=127.0.0.1
PORT=3306
USERNAME=admin
PASSWORD=123456
部署文件:创建一个名称为 mount-no-path-demo.yaml 的配置文件,内容如下所示。该配置文件中定义了一个名称为 mount-no-path-cm 的 ConfigMap,并把其中的所有配置项以挂载的形式挂载到了名称为 mount-no-path-deployment 的 Deployment的 /etc/config 目录下,即在 /etc/config 目录下会生成一个 log.config 文件和一个 db.config 文件。
apiVersion: v1
kind: ConfigMap
metadata:
name: mount-no-path-cm
data:
log.config: |
LOG_LEVER: INFO
LOG_FILE: /var/logs/test.log
db.config: |
HOST: 127.0.0.1
PORT: "3306"
USERNAME: admin
PASSWORD: "123456"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mount-no-path-deployment
labels:
app: mount-no-path
spec:
replicas: 1
selector:
matchLabels:
app: mount-no-path
template:
metadata:
labels:
app: mount-no-path
spec:
containers:
- name: test-container
image: busybox:latest
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "/bin/sh", "-c", "ls /etc/config/ && echo --- && cat /etc/config/log.config && echo --- && cat /etc/config/db.config" ]
volumeMounts:
- name: mount-no-path-volume
mountPath: /etc/config
volumes:
- name: mount-no-path-volume
configMap:
name: mount-no-path-cm
部署配置:执行以下命令即可使用该部署文件进行部署。
kubectl apply -f mount-no-path-demo.yaml
部署结果:该 Deployment 会在创建的 POD 内部的日志中打印出 /etc/config 目录下的所有文件和子目录列表,并且会打印出 /etc/config/log.config 文件和 /etc/config/db.config 文件的内容,结果如下图所示。
部署文件:创建一个名称为 mount-path-demo.yaml 的配置文件,内容如下所示。该配置文件中定义了一个名称为 mount-path-cm 的 ConfigMap,并把其中的两个配置项以挂载的形式分别挂载到了名称为 mount-no-path-deployment 的 Deployment的 /etc/config 目录下的 log/log.config 文件和 db/db.config 文件,即在 /etc/config 目录下会生成一个 log/log.config 文件和一个 db/db.config 文件。
apiVersion: v1
kind: ConfigMap
metadata:
name: mount-path-cm
data:
log.config: |
LOG_LEVER: INFO
LOG_FILE: /var/logs/test.log
db.config: |
HOST: 127.0.0.1
PORT: "3306"
USERNAME: admin
PASSWORD: "123456"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mount-path-deployment
labels:
app: mount-path
spec:
replicas: 1
selector:
matchLabels:
app: mount-path
template:
metadata:
labels:
app: mount-path
spec:
containers:
- name: test-container
image: busybox:latest
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "ls /etc/config/ && echo --- && cat /etc/config/log/log.config && echo --- && cat /etc/config/db/db.config" ]
volumeMounts:
- name: mount-path-volume
mountPath: /etc/config
volumes:
- name: mount-path-volume
configMap:
name: mount-path-cm
items:
- key: log.config
path: log/log.config
- key: db.config
path: db/db.config
部署配置:执行以下命令即可使用该部署文件进行部署。
kubectl apply -f mount-path-demo.yaml
部署结果:该 Deployment 会在创建的 POD 内部的日志中打印出 /etc/config 目录下的所有文件和子目录列表,并且会打印出 /etc/config/log/log.config 文件和 /etc/config/db/db.config 文件的内容,结果如下图所示。
创建项目:创建一个名称为 k8s-configmap 的 Spring Boot 项目,项目结构如下图所示:
pom文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.k8s.configmap</groupId>
<artifactId>k8s-configmap</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>k8s-configmap</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
K8sConfigmapApplication文件内容:
package com.k8s.configmap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class K8sConfigmapApplication {
public static void main(String[] args) {
SpringApplication.run(K8sConfigmapApplication.class, args);
}
}
ConfigController:
package com.k8s.configmap.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class ConfigController {
@Value("${env}")
private String env;
@Value("${msg}")
private String msg;
@GetMapping("/config")
public Map<String, Object> getConfig() {
Map<String, Object> config = new HashMap<>();
config.put("env", env);
config.put("msg", msg);
return config;
}
}
application.yaml文件内容:
server:
port: 8080
spring:
profiles:
active: dev
application-dev.yaml文件内容:
env: dev
msg: dev profile
application-test.yaml文件内容:
env: test
msg: test profile
运行并访问项目:在本地运行该项目,并在浏览器中访问以下地址,结果如下图所示,可以看出本地直接启动该项目时,使用的是 application-dev.yaml 这个配置文件。
项目打包:把项目打包成 Jar 包(方法请百度),并把生成的 Jar 包复制到安装有 Docker 环境的 Linux 操作系统中,本文生成的 Jar 包的名称为 k8s-configmap.jar 。
Dockerfile文件:在 Linux 操作系统中 k8s-configmap.jar 文件的同一级目录中,创建一个名称为 Dockerfile 的文件,文件内容如下所示。
FROM openjdk:8
EXPOSE 8080
COPY ./k8s-configmap.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
构建镜像:在 Linux 操作系统的命令行工具中,切换到 Dockerfile 文件所在的目录,并执行以下命令,即可构建 Docker 镜像。
docker build -t k8s-configmap:latest .
推送或复制镜像:如果有可推送的镜像仓库,可以把上一步中构建的 k8s-configmap:latest 镜像推送到自己的镜像仓库中,如果没可推送的镜像仓库,则需要提前把上一步中构建的 k8s-configmap:latest 镜像导入到 K8S 集群的所有的 worker 节点中。注意:由于本文没有可推送的镜像仓库,所以选择后面一种方式,把构建的镜像导入到了 K8S 集群的所有的 worker 节点中。
情况说明:Spring Boot项目在启动时,可以通过命令行参数 spring.config.location 指定配置文件的路径,如果通过命令行参数指定了配置文件的路径,则优先加载指定路径的配置文件。如果没有通过命令行参数 spring.config.location 指定配置文件的路径,则按照优先级高低依次从四个位置加载配置文件。
加载顺序:在没有通过命令行参数 spring.config.location 指定配置文件的路径的情况下,Spring Boot项目优先从项目根目录下的 config 目录中加载配置文件;如果项目根目录下的 config 目录中没有配置文件,则从项目根目录下加载配置文件;如果项目根目录下也没有配置文件,则从项目 resources 目录下的 config 目录中加载配置文件;如果项目 resources 目录下的 config 目录中也没有配置文件,则从项目 resources 目录下加载配置文件。 四种加载位置的优先级如下图所示。
部署文件:在 K8S 集群的 Master 节点中创建一个名称为 env-config-app.yaml 的配置文件,内容如下所示。
apiVersion: v1
kind: ConfigMap
metadata:
name: env-config-cm
data:
DEPLOYMENT_ENV: test
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: env-config-deployment
labels:
app: env-config
spec:
replicas: 1
selector:
matchLabels:
app: env-config
template:
metadata:
labels:
app: env-config
spec:
containers:
- name: env-config-container
image: k8s-configmap:latest
imagePullPolicy: IfNotPresent
args: ["--spring.profiles.active=$(DEPLOYMENT_ENV_KEY)"]
ports:
- containerPort: 8080
env:
- name: DEPLOYMENT_ENV_KEY
valueFrom:
configMapKeyRef:
name: env-config-cm
key: DEPLOYMENT_ENV
---
apiVersion: v1
kind: Service
metadata:
name: env-config-service
labels:
app: env-config
spec:
selector:
app: env-config
type: NodePort
ports:
- protocol: TCP
port: 8081
targetPort: 8080
nodePort: 30001
文件说明:上述部署文件中先是定义了一个名为 env-config-cm 的 ConfigMap ,其中定义了一个名称为 DEPLOYMENT_ENV 值为 test 的配置项。然后定义了一个名称为 env-config-deployment 的 Deployment,其中使用前面构建的 k8s-configmap:latest 镜像创建 Pod,并且把 env-config-cm 这个 ConfigMap 中的 DEPLOYMENT_ENV 配置项的值以命令行参数的形式传给了Pod中的镜像,并且是传给了 spring.profiles.active 这个命令行参数,因此是指定使用 application-test.yaml 这个环境配置文件来启动项目。然后定义了一个名称为 env-config-service 的 Service,其中指定使用 NodePort 的形式把宿主机的 30001 端口映射到Pod中的容器的 8080 端口,即通过访问宿主机的 30001 端口即可访问创建的 Pod。
执行部署:在 K8S 集群的 Master 节点中执行以下命令,即可部署项目,以及查看部署结果,执行结果如下图所示。
# 执行部署
kubectl apply -f env-config-app.yaml
# 查看生成的 Pod
kubectl get pods -o wide
# 查看生成的 Service
kubectl get service -o wide
访问项目:由于使用 NodePort 的方式,把宿主机的 30001 端口映射到了生成的 Pod 内容器的 8080 端口,因此可以通过在浏览器中访问 宿主机IP地址:30001/config ,即可访问项目中的接口,由于本文宿主机的IP地址是 192.168.1.169,所以访问地址和访问结果如下所示。
http://192.168.1.169:30001/config
结果说明:从接口的返回信息可以看出,该项目部署的时候使用的是 application-test.yaml 配置文件,因为达到了通过把 ConfigMap 中的配置项 (DEPLOYMENT_ENV) 设置成环境变量 (DEPLOYMENT_ENV_KEY),并把环境变量的值 (test) 传给命令行参数 (spring.profiles.active) 的形式实现了使用指定的配置文件的目的。
部署文件:在 K8S 集群的 Master 节点中创建一个名称为 mount-config-app.yaml 的配置文件,内容如下所示。
apiVersion: v1
kind: ConfigMap
metadata:
name: mount-config-cm
data:
application-prod.yaml: |
env: prod
msg: prod profile
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mount-config-deployment
labels:
app: mount-config
spec:
replicas: 1
selector:
matchLabels:
app: mount-config
template:
metadata:
labels:
app: mount-config
spec:
containers:
- name: mount-config-container
image: k8s-configmap:latest
imagePullPolicy: IfNotPresent
args: ["--spring.config.location=/etc/config/application.yaml"]
ports:
- containerPort: 8080
volumeMounts:
- name: mount-config-volume
mountPath: /etc/config
volumes:
- name: mount-config-volume
configMap:
name: mount-config-cm
items:
- key: application-prod.yaml
path: application.yaml
---
apiVersion: v1
kind: Service
metadata:
name: mount-config-service
labels:
app: mount-config
spec:
selector:
app: mount-config
type: NodePort
ports:
- protocol: TCP
port: 8082
targetPort: 8080
nodePort: 30002
文件说明:上述部署文件中先是定义了一个名为 mount-config-cm 的 ConfigMap ,其中定义了一个名称为 application-prod.yaml 的配置文件。然后定义了一个名称为 mount-config-deployment 的 Deployment,其中使用前面构建的 k8s-configmap:latest 镜像创建 Pod,并且把 mount-config-cm 这个 ConfigMap 中的 application-prod.yaml 配置文件的配置项全部添加到数据卷中的 application.yaml 文件中,然后把数据卷中的 application.yaml 文件挂载到创建的 Pod 的容器内部的 /etc/config 目录下,最后通过命令行参数 spring.config.location 指定容器启动时的配置文件为容器内部的 /etc/config/application.yaml 文件。然后定义了一个名称为 mount-config-service 的 Service,其中指定使用 NodePort 的形式把宿主机的 30002 端口映射到Pod中的容器的 8080 端口,即通过访问宿主机的 30002 端口即可访问创建的 Pod。
执行部署:在 K8S 集群的 Master 节点中执行以下命令,即可部署项目,以及查看部署结果,执行结果如下图所示。
kubectl apply -f mount-config-app.yaml
kubectl get pods -o wide
kubectl get service -o wide
访问项目:由于使用 NodePort 的方式,把宿主机的 30002 端口映射到了生成的 Pod 内容器的 8080 端口,因此可以通过在浏览器中访问 宿主机IP地址:30002/config ,即可访问项目中的接口,由于本文宿主机的IP地址是 192.168.1.169,所以访问地址和访问结果如下所示。
http://192.168.1.169:30002/config
结果说明:从接口的返回信息可以看出,该项目部署的时候使用的是 application-prod.yaml 配置文件,因此达到了通过把 ConfigMap 中的配置文件添加到数据卷,并把数据卷中的文件挂载到容器内部,然后通过命令行参数指定配置文件路径的形式实现了使用镜像外部的配置文件的目的。
优点:这种方式的优点是把多个配置文件都放在源码中,并和源码一起打包构建镜像,从而只需要使用一个简单的环境变量就可以指定项目启动时使用哪个配置文件,不需要把配置文件添加到ConfigMap中。
缺点:这种方式的缺点是把配置文件打包到了镜像中,如果配置文件需要修改,则需要重新打包并构建镜像。此外,通过环境变量的形式无法实现项目配置热更新的效果,即 ConfigMap 被更新了之后,新的配置不会被项目应用,必需重新部署才可会使用新的配置文件。
应用场景:这种方式适用于配置文件很少变化、且不要求配置文件热更新的情况。
优点:这种方式的优点是把配置文件放到了镜像外部,把项目和配置文件分离开来,使得构建的镜像是一个纯净的镜像,能够在任何环境中使用。而且,通过文件挂载的形式可以实现项目配置热更新的效果,即 ConfigMap 被更新了之后,新的配置会立即被项目应用,从而不需要重新部署即可达到修改配置文件的目的。
缺点:这种方式的缺点是把配置文件放到了 ConfigMap 中,每次修改配置,都需要重新维护 ConfigMap。
应用场景:这种方式适用于配置文件经常变化、且要求配置文件热更新的情况。
文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib
文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang
文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些
文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器
文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距
文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器
文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn
文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios
文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql
文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...
文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120
文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数