1、ConfigMap

  • ConfigMap 功能在 Kubernetes1.2 版本中引入,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。ConfigMap API 给我们提供了向容器中注入配置信息的机制,ConfigMap 可以被用来保存单个属性,也可以用来保存整个配置文件或者 JSON 二进制大对象
  • 相当于一个配置文件的注册中心,将数据保存在etcd中,让Pod以变量和volume挂载
  • 应用场景
    • 比如好几个Pod共用一个配置文件

1.1、目录创建

  • —from-file 指定在目录下的所有文件都会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容 (—from-file 指定目录)

  • # 创建game.properties 和 ui.properties 文件
    [root@k8smaster configmap]# cat properties/game.properties
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
    [root@k8smaster configmap]# cat properties/ui.properties
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice # 使用命令创建 并且查看 DATA 表示键的数量
    [root@k8smaster configmap]# kubectl create configmap game-config --from-file=/root/configmap/properties
    configmap/game-config created
    [root@k8smaster configmap]# kubectl get configmap
    NAME DATA AGE
    game-config 2 11s # 查看详细信息
    [root@k8smaster configmap]# kubectl get configmap game-config -o yaml
    apiVersion: v1
    data:
    game.properties: |
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
    ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
    kind: ConfigMap
    metadata:
    creationTimestamp: "2020-12-17T03:31:25Z"
    managedFields:
    - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
    f:data:
    .: {}
    f:game.properties: {}
    f:ui.properties: {}
    manager: kubectl
    operation: Update
    time: "2020-12-17T03:31:25Z"
    name: game-config
    namespace: default
    resourceVersion: "1357422"
    selfLink: /api/v1/namespaces/default/configmaps/game-config
    uid: 2085e855-4bf9-4cdb-9ee8-30f1385ae2c5

1.2、文件创建

  • 只要指定为一个文件就可以从单个文件中创建 ConfigMap

  • —from-file 这个参数可以使用多次,你可以使用两次分别指定上个实例中的那两个配置文件,效果就跟指定整个目录是一样的 (—from-file 指定文件)

  • # 创建configmap 并查看
    [root@k8smaster configmap]# kubectl create configmap game-config1 --from-file=/root/configmap/properties/ui.properties
    configmap/game-config1 created
    [root@k8smaster configmap]# kubectl get configmap game-config1
    NAME DATA AGE
    game-config1 1 22s # 查看详细信息 和目录创建效果一样
    [root@k8smaster configmap]# kubectl get configmap game-config1 -o yaml
    apiVersion: v1
    data:
    ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
    kind: ConfigMap
    metadata:
    creationTimestamp: "2020-12-17T03:37:30Z"
    managedFields:
    - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
    f:data:
    .: {}
    f:ui.properties: {}
    manager: kubectl
    operation: Update
    time: "2020-12-17T03:37:30Z"
    name: game-config1
    namespace: default
    resourceVersion: "1358296"
    selfLink: /api/v1/namespaces/default/configmaps/game-config1
    uid: 46e88eb8-1377-4710-abf6-a1d92273d5bf [root@k8smaster configmap]# kubectl describe configmap game-config1
    Name: game-config1
    Namespace: default
    Labels: <none>
    Annotations: <none> Data
    ====
    ui.properties:
    ----
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice

1.3、字面值创建

  • 使用文字值创建,利用 —from-literal 参数传递配置信息,该参数可以使用多次

  • # 创建configmap并查看
    [root@k8smaster configmap]# kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
    configmap/special-config created
    [root@k8smaster configmap]# kubectl describe configmap special-config
    Name: special-config
    Namespace: default
    Labels: <none>
    Annotations: <none> Data
    ====
    special.how:
    ----
    very
    special.type:
    ----
    charm
    Events: <none> # 查看详细信息 用cm也可以
    [root@k8smaster configmap]# kubectl get cm special-config -o yaml
    apiVersion: v1
    data:
    special.how: very
    special.type: charm
    kind: ConfigMap
    metadata:
    creationTimestamp: "2020-12-17T03:43:34Z"
    managedFields:
    - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
    f:data:
    .: {}
    f:special.how: {}
    f:special.type: {}
    manager: kubectl
    operation: Update
    time: "2020-12-17T03:43:34Z"
    name: special-config
    namespace: default
    resourceVersion: "1359169"
    selfLink: /api/v1/namespaces/default/configmaps/special-config
    uid: 96b10ac7-964d-4c49-8dec-9dfd1697be72

1.4、Pod中使用

  • 使用 ConfigMap 来替代环境变量

    • 资源清单示例

      • 如果创建ConfigMap是对应的name已经存在,则会更新其中的键值对,不会删除或创建失败

      • 如果使用不存在的configmap 会出现失败等错误

      • apiVersion: v1
        kind: ConfigMap
        metadata:
        name: special-config
        namespace: default
        # ConfigMap 中的键值对
        data:
        special.how: very
        special.type: charm
      • apiVersion: v1
        kind: ConfigMap
        metadata:
        name: log-config
        namespace: default
        # ConfigMap 中的键值对
        data:
        log_level: INFO
      • apiVersion: v1
        kind: Pod
        metadata:
        name: env-test-pod
        spec:
        containers:
        - name: test-container
        image: nginx
        # 打出环境变量
        command: [ "/bin/sh", "-c", "env" ]
        # 设置容器的环境变量 多个
        env:
        # 环境变量名称为 SPECIAL_LEVEL_KEY
        - name: SPECIAL_LEVEL_KEY
        # 对应的值从configmap中取 configmap的名称为special-config 取得是key为special.how的值 做为 环境变量的值
        valueFrom:
        configMapKeyRef:
        name: special-config
        key: special.how
        - name: SPECIAL_TYPE_KEY
        valueFrom:
        configMapKeyRef:
        name: special-config
        key: special.type
        - name: UI_PROPERTIES
        valueFrom:
        configMapKeyRef:
        name: game-config
        key: ui.properties
        # 将configmap所有的键值对作为 环境变量 key为名称 value为值
        envFrom:
        - configMapRef:
        name: log-config
        restartPolicy: Never
      • # 创建Pod 并查看日志
        [root@k8smaster configmap]# kubectl apply -f env-test-pod.yaml
        pod/env-test-pod created
        [root@k8smaster configmap]# kubectl get pod
        NAME READY STATUS RESTARTS AGE
        env-test-pod 0/1 Completed 0 54s # 查看日志后发现输出了我们设置的环境变量
        [root@k8smaster configmap]# kubectl logs env-test-pod SPECIAL_TYPE_KEY=charm UI_PROPERTIES=color.good=purple
        color.bad=yellow
        allow.textmode=true
        how.nice.to.look=fairlyNice SPECIAL_LEVEL_KEY=very log_level=INFO
  • 用 ConfigMap 设置命令行参数

    • 资源清单示例

      • apiVersion: v1
        kind: Pod
        metadata:
        name: linecommand-test-pod
        spec:
        containers:
        - name: test-container
        image: nginx
        # 在命令参数中 使用环境变量 用$(环境变量名)
        command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
        env:
        - name: SPECIAL_LEVEL_KEY
        valueFrom:
        configMapKeyRef:
        name: special-config
        key: special.how
        - name: SPECIAL_TYPE_KEY
        valueFrom:
        configMapKeyRef:
        name: special-config
        key: special.type
        restartPolicy: Never
      • # 创建 Pod 并查看
        [root@k8smaster configmap]# kubectl apply -f linecommand-test-pod.yaml
        pod/linecommand-test-pod created
        [root@k8smaster configmap]# vim linecommand-test-pod.yaml
        [root@k8smaster configmap]# kubectl get pod
        NAME READY STATUS RESTARTS AGE
        linecommand-test-pod 0/1 Completed 0 65s # 创建日志 发现输出了 环境变量
        [root@k8smaster configmap]# kubectl logs linecommand-test-pod
        very charm
  • 通过数据卷插件使用ConfigMap

    • 在数据卷里面使用这个 ConfigMap,有不同的选项。最基本的就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容

    • 资源清单示例

      • apiVersion: v1
        kind: Pod
        metadata:
        name: volume-test-pod
        spec:
        containers:
        - name: test-container
        image: nginx
        command: [ "/bin/sh", "-c", "cat /etc/config/special.how" ]
        # 容器挂载的数据卷
        volumeMounts:
        # 数据卷的名称 在Pod声明的数据卷中选择
        - name: config-volume
        # 挂载到容器内部的路径
        mountPath: /etc/config
        # Pod的数据卷
        volumes:
        # 数据卷的名称
        - name: config-volume
        # 数据卷挂载的地方 此处是来源configMap 名称是special-config
        # 也就是说哪个容器使用的数据卷 会在容器挂载的路径下生成多个文件(取决于configmap中key的数量) key为文件名,value为文件内容
        configMap:
        name: special-config
        restartPolicy: Never
      • # 创建Pod并查看
        [root@k8smaster configmap]# kubectl apply -f volume-test-pod.yaml
        pod/vloume-test-pod created
        [root@k8smaster configmap]# kubectl get pod
        volume-test-pod 0/1 Completed 0 24s # 查看日志 输出了文件内容
        [root@k8smaster configmap]# kubectl logs vloume-test-pod
        very

1.5、ConfigMap热更新

  • 更新 ConfigMap 后

    • 使用该 ConfigMap 挂载的 Env 不会同步更新

    • 使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新 (这样就可以实时修改配置文件,比如nginx的)

    • 虽然配置文件可以热更新,但是能不能起作用还要看具体情况,比如nginx,启动之后,就不会再去看配置文件了,我们需要手动重启nginx,来达到重新读取配置文件的目的,如果有的服务可以一直监测配置文件,我们则不用手动处理(这种情况很少)

    • 更新 ConfigMap 目前并不会触发相关 Pod 的滚动更新,可以通过修改 pod annotations 的方式强制触发滚动更新

      • $ kubectl patch deployment hot-update-test --patch '{"spec": {"template": {"metadata": {"annotations":{"version/config": "20201010" }}}}}'
      • 这个例子里我们在 .spec.template.metadata.annotations 中添加 version/config ,每次通过修改version/config 来触发滚动更新

  • 资源清单示例

    • apiVersion: apps/v1
      kind: Deployment
      metadata:
      name: hot-update-test
      spec:
      replicas: 1
      selector:
      matchLabels:
      app: nginx
      template:
      metadata:
      labels:
      app: nginx
      spec:
      containers:
      - name: my-nginx
      image: nginx
      ports:
      - containerPort: 80
      # 容器使用Pod的容器卷 并挂载在自己内部
      volumeMounts:
      - name: config-volume
      mountPath: /etc/config
      # 声明Pod的容器卷
      volumes:
      - name: config-volume
      configMap:
      name: log-config
    • # 创建Pod 并查看挂载目录下的文件 和文件内容
      [root@k8smaster configmap]# kubectl apply -f hot-update-test.yaml
      deployment.apps/hot-update-test created
      [root@k8smaster configmap]# kubectl get pod
      NAME READY STATUS RESTARTS AGE
      hot-update-test-6fd96995b6-jfw2w 1/1 Running 0 100s # 查看挂载目录下的文件 和文件内容
      [root@k8smaster configmap]# kubectl exec -it hot-update-test-6fd96995b6-jfw2w -- ls /etc/config
      log_level
      [root@k8smaster configmap]# kubectl exec -it hot-update-test-6fd96995b6-jfw2w -- cat /etc/config/log_level
      INFO
    • 修改 ConfigMap(log-config)中的内容 (将INFO改成DEBUD)

      • [root@k8smaster configmap]# kubectl edit configmap log-config
        configmap/log-config edited
        [root@k8smaster configmap]# kubectl describe configmap log-config
        Name: log-config
        Namespace: default
        Labels: <none>
        Annotations:
        Data
        ====
        log_level:
        ----
        DEBUG
        Events: <none>
      • # 查看log_level 文件内容发生了改变
        [root@k8smaster configmap]# kubectl exec -it hot-update-test-6fd96995b6-jfw2w -- cat /etc/config/log_level
        DEBUG

2、Secret

  • ConfigMap将数据以明文的方式存放,不太安全,Secret可以用Base64编码存放,比较安全
  • Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec中。Secret 可以以 Volume 或者环境变量的方式使用
  • Secret 有三种类型
    • Service Account :用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中,比如coredns、kube-proxy可以访问(不是什么都可以访问Kubernetes API)
    • Opaque :base64编码格式的Secret,用来存储密码、密钥等
    • kubernetes.io/dockerconfigjson :用来存储私有 docker registry 的认证信息

2.1、Service Account

  • # 查找系统的Pod
    [root@k8smaster secret]# kubectl get pod -n kube-system
    NAME READY STATUS RESTARTS AGE
    coredns-7ff77c879f-494fb 1/1 Running 2 46h
    coredns-7ff77c879f-tvgrz 1/1 Running 2 46h
    etcd-k8smaster 1/1 Running 3 6d19h
    kube-apiserver-k8smaster 1/1 Running 3 6d19h
    kube-controller-manager-k8smaster 1/1 Running 16 6d19h
    kube-flannel-ds-amd64-hflj8 1/1 Running 4 6d6h
    kube-flannel-ds-amd64-s9xhk 1/1 Running 3 6d6h
    kube-flannel-ds-amd64-wp7mp 1/1 Running 4 6d6h
    kube-proxy-5l8kb 1/1 Running 2 47h
    kube-proxy-6n8vp 1/1 Running 2 47h
    kube-proxy-lgcxp 1/1 Running 2 47h
    kube-scheduler-k8smaster 1/1 Running 17 6d19h # 查看 kube-proxy/run/secrets/kubernetes.io/serviceaccount 下的文件
    # ca.crt 是https的证书信息 namespace 是命名空间 token 是访问时携带的token
    [root@k8smaster secret]# kubectl exec -it -n kube-system kube-proxy-5l8kb -- ls /run/secrets/kubernetes.io/serviceaccount
    ca.crt namespace token

2.2、Opaque

  • Opaque 类型的数据是一个 map 类型,要求 value 是 base64 编码格式

    • [root@k8smaster secret]# echo admin | base64
      YWRtaW4K
      [root@k8smaster secret]# echo 123456 | base64
      MTIzNDU2Cg== # 解码
      [root@k8smaster secret]# echo YWRtaW4K | base64 -d
      admin
  • 资源清单示例

    • apiVersion: v1
      kind: Secret
      metadata:
      name: mysecret
      type: Opaque
      data:
      username: YWRtaW4=
      password: MTIzNDU2Cg==
    • # 创建 secret 并查看
      [root@k8smaster secret]# kubectl apply -f secret-test.yaml
      secret/mysecret created [root@k8smaster secret]# kubectl get secret
      NAME TYPE DATA AGE
      default-token-99w8n kubernetes.io/service-account-token 3 6d19h
      mysecret Opaque 2 8s
  • 将 Secret 挂载到 Volume 中

    • Secret中的键值对会以文件的方式存在在容器挂载的目录下 key为文件名 value为文件值(自动解码)

    • 资源清单示例

      • apiVersion: v1
        kind: Pod
        metadata:
        name: opaque-test
        labels:
        name: opaque-test
        spec:
        volumes:
        - name: secrets
        # 使用secret secret的名称是mysecret
        secret:
        secretName: mysecret
        containers:
        - image: nginx
        name: opaque-nginx
        volumeMounts:
        - name: secrets
        mountPath: /etc/opaque
        # 只读
        readOnly: true
      • # 创建Pod
        [root@k8smaster secret]# kubectl apply -f opaque-test.yaml
        pod/opaque-test created
        [root@k8smaster secret]# kubectl get pod
        NAME READY STATUS RESTARTS AGE
        hot-update-test-6fd96995b6-jfw2w 1/1 Running 0 60m
        opaque-test 1/1 Running 0 51s # 查看挂载目录下的文件
        [root@k8smaster secret]# kubectl exec -it opaque-test -- ls /etc/opaque
        password username # 查看挂载目录下的文件内容 自动解码
        [root@k8smaster secret]# kubectl exec -it opaque-test -- cat /etc/opaque/username
        admin
  • 将 Secret 导出到环境变量中

    • 资源清单示例

      • apiVersion: apps/v1
        kind: Deployment
        metadata:
        name: opaque-env
        spec:
        replicas: 2
        # 这个版本的Deployment不能省去selector
        selector:
        matchLabels:
        app: opaque-deployment
        template:
        metadata:
        labels:
        app: opaque-deployment
        spec:
        containers:
        - name: pod-1
        image: nginx
        ports:
        - containerPort: 80
        # 设置环境变量
        env:
        # 环境变量名称
        - name: TEST_USER
        # 环境变量值得来源为secret secret的名称是mysecret 用的是key为username的value
        valueFrom:
        secretKeyRef:
        name: mysecret
        key: username
        - name: TEST_PASSWORD
        valueFrom:
        secretKeyRef:
        name: mysecret
        key: password
      • # 创建deployment 并查看Pod
        [root@k8smaster secret]# kubectl apply -f opaque-env.yaml
        deployment.apps/opaque-env created
        [root@k8smaster secret]# kubectl get pod
        NAME READY STATUS RESTARTS AGE
        opaque-env-54d4fd67f4-9xrrs 1/1 Running 0 11s
        opaque-env-54d4fd67f4-h7689 1/1 Running 0 11s # 查看两个Pod中的环境变量 均已解码
        [root@k8smaster secret]# kubectl exec -it opaque-env-54d4fd67f4-9xrrs -- env TEST_USER=admin
        TEST_PASSWORD=123456 [root@k8smaster secret]# kubectl exec -it opaque-env-54d4fd67f4-h7689 -- env TEST_USER=admin
        TEST_PASSWORD=123456

2.3、kubernetes.io/dockerconfigjson

  • 用来存储私有 docker registry 的认证信息

  • 使用命令创建(docker信息换成自己的)

    • kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
    • # 查看 myregistrykey 查看具体信息也是编码过的
      [root@k8smaster secret]# kubectl get secret
      NAME TYPE DATA AGE
      default-token-99w8n kubernetes.io/service-account-token 3 6d20h
      myregistrykey kubernetes.io/dockerconfigjson 1 10s
      mysecret Opaque 2 50m
  • 使用docker的登录文件创建

    • cat ~/.docker/config.json 这个docker的登录文件登录docker的仓库后自动生成

    • # 将登录文件的内容进行base64编码
      cat ~/.docker/config.json | base64 # 将编码后的结果写入资源清单中
      cat > myregistrykey.yaml <<EOF
      apiVersion: v1
      kind: Secret
      metadata:
      name: myregistrykey
      data:
      .dockerconfigjson: docker的登录文件内容的base64编码
      type: kubernetes.io/dockerconfigjson
      EOF # 创建serret
      kubectl create -f myregistrykey.yaml
    • 资源清单示例

      • apiVersion: v1
        kind: Secret
        metadata:
        name: myregistrykey
        data:
        .dockerconfigjson: docker的登录文件内容的base64编码
        type: kubernetes.io/dockerconfigjson
  • 资源清单示例

    • apiVersion: v1
      kind: Pod
      metadata:
      name: docker-pod
      spec:
      containers:
      - name: foo
      # 这个镜像需要在自己的仓库中 需要身份认证
      image: registry.cn-hangzhou.aliyuncs.com/******/mytomcat:8.1.0
      # 使用镜像拉取的secret 包含镜像仓库的地址 用户名 密码等
      imagePullSecrets:
      - name: myregistrykey
    • # 查看pod 已经运行
      [root@k8smaster secret]# kubectl get pod
      NAME READY STATUS RESTARTS AGE
      docker-pod 1/1 Running 0 6m22s

3.k8s存储之ConfigMap、Secret的更多相关文章

  1. k8s配置中心-configmap,Secret密码

    目录 k8s配置中心-configmap,Secret 创建ConfigMap 使用ConfigMap subPath参数 Secret 官方文档 编写secret清单 使用secret 在 Pod ...

  2. k8s存储卷概述

    pod本身具有生命周期,故其内部运行的容器及其相关数据自身均无法持久存在.docker支持配置容器使用存储卷将数据持久存储于容器自身文件系统之外的存储空间中,它们可以是节点文件系统或网络文件系统之上的 ...

  3. 二十、Pod的存储之Configmap

    Pod 的存储之Configmap 一.Configmap介绍 ​ConfigMap 功能在 Kubernetes1.2 版本中引入,许多应用程序会从配置文件.命令行参数或环境变量中读取配置信息.Co ...

  4. 使用kubeseal加密和管理k8s集群的secret

    使用kubeseal加密和管理k8s集群的secret 在k8s的管理过程中,像secret这种资源并不好维护,kubeseal提供了一种相对简单的方式来对原始secret资源进行加密,并通过控制器进 ...

  5. kubernetes系列12—二个特色的存储卷configmap和secret

    本文收录在容器技术学习系列文章总目录 1.configmap 1.1 认识configmap ConfigMap用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件.ConfigMa ...

  6. k8s env、configmap、secret外部数据加载配置

    K8s提供了多种外部数据注入容器的方式,今天我们主要学习环境变量.ConfigMap以及Secret的使用和配置. 环境变量 在docker项目中,对一个容器添加环境变量可以在容器创建时通过-e EN ...

  7. K8S存储相关yaml

    一.ConfigMap 1.使用目录创建 vim game.properties vim ui.properties 在一个文件夹下创建两个文件,通过以下命令创建 kubectl create con ...

  8. k8s配置集ConfigMap详解

    ConfigMap介绍 ConfigMap和Secret是Kubernetes系统上两种特殊类型的存储卷,ConfigMap对象用于为容器中的应用提供配置文件等信息.但是比较敏感的数据,例如密钥.证书 ...

  9. 09-kubernetes configMap secret

    目录 配置容器化应用配置的方式 命令创建和测试configMap 创建一个Pod 挂在测试 命令行文件类创建方式 创建Pod测试 创建后测试 贴近实际进行测试 创建后测试 secret 举例测试 ge ...

随机推荐

  1. Scrum 冲刺 第一篇

    Scrum 冲刺 第一篇 每个成员认领的任务 人员 任务 周立 后台登录注册模块 邓富荣 后台首页模块 钟俊豪 博客圈模块 黄清山 个人界面模块 郑焕 首页以及博客圈界面 黄梓浩 个人界面以及登录注册 ...

  2. 串口数据监视-Bus Hound

    Bus Hound使用说明 一.打开该工具,会看到最上面的六个图标:1.Capture(捕捉按钮):按下它选择捕捉数据界面2.Save(保存按钮):按下它选择保存数据界面3.Setting(设置按钮) ...

  3. 重庆聚焦区块链应用,Panda Global觉得春天真的来了!

    近日,由2020中国智博会组委会主办.重庆市大数据应用发展管理局与渝中区人民政府联合承办.重庆市区块链应用创新产业联盟和四川省区块链行业协会联合执行的"2020线上智博会区块链应用创新大赛& ...

  4. CF873D Merge Sort

    其实最优的方法其他的题解已经讲得很好了,本题解仅用于记录和分享一个新的思路. 这道题是让你输出符合条件的序列,而序列的每个数之间具有一定的逻辑关系,很容易想到拓扑排序,于是此题就变为,如何找出满足条件 ...

  5. Springboot mini - Solon详解(四)- Solon的事务传播机制

    Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...

  6. PhotoSwipe用法

    1.自动识别data-size问题,添加以下代码 gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options) ...

  7. docker容器之间通过bridge进行通信

    创建用户自定义bridge docker network create my-net # 创建了一个名为"my-net"的网络 将容器加入到"my-net"中 ...

  8. uniapp保存图片到本地(APP和微信小程序端)

    uniapp实现app端和微信小程序端图片保存到本地,其它平台未测过,原理类似. 微信小程序端主要是权限需要使用button的开放能力来反复调起,代码如下: 首先是条件编译两个平台的按钮组件: < ...

  9. Electron安装打包指南

    当前环境Debian Linux-Deepin 安装Node 直接下载 命令下载 下载 wget https://nodejs.org/dist/v14.15.1/node-v14.15.1-linu ...

  10. DRF对Django请求响应做了技术升级

    Django视图是用来处理请求和响应的,Django默认是按Form和Template来设计的,如果要处理以JSON格式为主的RESTful API,那么就需要对Django请求和响应的处理代码进行优 ...