2021-01-11

博客园Logo
首页
新闻
博问
专区
闪存
班级
代码改变世界
搜索
注册
登录
返回主页xiaokantianse
博客园首页新随笔联系订阅管理随笔 - 30 文章 - 0 评论 - 4
3.k8s存储之ConfigMap、Secret
目录

1、ConfigMap
1.1、目录创建
1.2、文件创建
1.3、字面值创建
1.4、Pod中使用
1.5、ConfigMap热更新
2、Secret
2.1、Service Account
2.2、Opaque
2.3、kubernetes.io/dockerconfigjson

正文

回到顶部
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:
Annotations:

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:
Annotations:

Data

special.how:

very
special.type:

charm
Events:

查看详细信息 用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:
Annotations:
Data

log_level:

DEBUG
Events:

查看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
分类: k8s
好文要顶 关注我 收藏该文
xiaokantianse
关注 - 0
粉丝 - 1
+加关注
00
« 上一篇: 2.k8sPod、控制器、service
posted @ 2021-01-11 11:13 xiaokantianse 阅读(78) 评论(1) 编辑 收藏

评论列表
#1楼 2021-01-11 11:52 Angel_IT
在线揭露贩卖盗版诈骗者
诈骗者QQ:346877235、475658354 、46362580
诈骗者姓名:李俊杰
诈骗者微信id: qq46362580
诈骗者淘宝Id:taobaouser2017
诈骗者百度账号:lijunjie005、lijunjie006
利用QQ群 淘宝和贴吧 发布贩卖盗版不全的课程到处诈骗
诈骗者微信:

支持(0) 反对(0)
刷新评论刷新页面返回顶部
登录后才能发表评论,立即 登录 或 注册, 访问 网站首页
【推荐】阿里出品,对标P7!限时免费,七天深入MySQL实战营报名开启
【推荐】大型组态、工控、仿真、CADGIS 50万行VC++源码免费下载
【推荐】AWS携手博客园为开发者送福利,注册立享12个月免费套餐
【推荐】第一个NoSQL数据库,在大规模和一致性之间找到了平衡
【推荐】七牛云新老用户同享 1 分钱抢 CDN 1TB流量大礼包!
【推荐】了不起的开发者,挡不住的华为,园子里的品牌专区
【推荐】未知数的距离,毫秒间的传递,声网与你实时互动

相关博文:
· ConfigMap-k8s
· K8S中ConfigMap
· Codeforces1263D-SecretPasswords
· k8sdashboard解决secret自建证书导致浏览器访问限制
· k8s开船记-首航:博客站点从dockerswarm切换到k8s
» 更多推荐…

最新 IT 新闻:
· 为什么贝壳、百度、蔚来值得放在一起研究?
· 能刷好评也能删差评 大众点评变味了?
· 前懂球帝CTO许立强日前正式加入字节跳动 曾担任百度主任架构师
· 82万的新车一月连撞两车 女司机称刹车失灵!特斯拉:你去告我们
· 比宝马5系贵2万多!秦力洪:蔚来ET7订单达预期 不会降价
» 更多新闻…
公告
昵称: xiaokantianse
园龄: 6个月
粉丝: 1
关注: 0
+加关注
< 2021年1月 >
日 一 二 三 四 五 六
27 28 29 30 31 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 1 2 3 4 5 6
搜索

常用链接
我的随笔
我的评论
我的参与
最新评论
我的标签
随笔分类
docker(1)
java技术(1)
java设计模式(17)
k8s(3)
数据结构及算法(8)
随笔档案
2021年1月(1)
2020年12月(5)
2020年11月(16)
2020年8月(8)
最新评论

  1. Re:3.k8s存储之ConfigMap、Secret
    在线揭露贩卖盗版诈骗者 诈骗者QQ:346877235、475658354 、46362580 诈骗者姓名:李俊杰 诈骗者微信id: qq46362580 诈骗者淘宝Id:taobaouser2017…
    –Angel_IT
  2. Re:1.k8s概述、安装、名词解释、资源清单
    不关防火墙的情况下,要开放哪些端口?

–runliuv
3. Re:12.java设计模式之代理模式
8错啊

–fen儿
4. Re:12.java设计模式之代理模式
学习,学习

–河北泊腾
5. Re:9.java设计模式之组合模式
您好,看您很多技术文章写的都挺好的,能否加下您好友跟你沟通交流下

–爱吃甜品的女孩
阅读排行榜

  1. 8.java设计模式之装饰者模式(276)
  2. 14.java设计模式之命令模式(234)
  3. 1.使用javax.mail, spring的JavaMailSender,springboot发送邮件(232)
  4. 12.java设计模式之代理模式(200)
  5. 15.java设计模式之访问者模式(168)
    评论排行榜
  6. 12.java设计模式之代理模式(2)
  7. 3.k8s存储之ConfigMap、Secret(1)
  8. 1.k8s概述、安装、名词解释、资源清单(1)
  9. 9.java设计模式之组合模式(1)
    推荐排行榜
  10. 14.java设计模式之命令模式(2)
  11. 1.k8s概述、安装、名词解释、资源清单(1)
  12. 1.docker介绍、命令、容器、镜像、数据卷、Dockerfile、常用软件安装、推送阿里云(1)
  13. 15.java设计模式之访问者模式(1)
  14. 8.java设计模式之装饰者模式(1)
    Copyright © 2021 xiaokantianse
    Powered by .NET 5.0 on Kubernetes
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值