ConfigMap和Secret是Kubernetes系统上两种特殊类型的存储卷
ConfigMap用于为容器中的应用提供配置数据以定制程序的行为,而敏感的配置信息,例如密钥、证书等则通常由Secret来配置
ConfigMap和Secret将相应的配置信息保存于资源对象中,而后在Pod对象上支持以存储卷的形式将其挂载并加载相关的配置,从而降低了配置与镜像文件的耦合关系,提高了镜像复用能力
Kubernetes借助于ConfigMap对象实现了将配置文件从容器镜像中解耦,从而增强了工作负载的可移植性,使其配置更易于更改和管理,并避免了将配置数据硬编码到Pod配置清单中
此二者都属于名称空间级别,只能被同一名称空间中的Pod引用
Config资源
创建ConfigMap对象
创建ConfigMap对象的方法有两种
命令式命令(建议使用 --dry-run=client -o yaml )
1. 字面量: kubectl create configmap NAME --from-literal=key1=value1 2. 从文件加载: kubectl create configmap NAME --from-file=[key=]/PATH/TO/FILE 3. 从目录加载: kubectl create configmap NAME --from-file=[key=]/PATH/TO/DIR/配置文件
1. 命令式: kubectl create -f 2. 声明式: kubectl apply -f
提示:基于文件内容生成时,可以使用命令式命令以dry-run模式生成并保存
示例:
#命令式命令 --- 一般建议在命令后加上 --dry-run=client -o yaml ,生成对应的配置文件去apply加载使用
kubectl create configmap nginx-confs --from-file=./nginx-conf.d/myserver.conf --from-file=status.cfg=./nginx-conf.d/myserver-status.cfg
#示例
apiVersion: v1
data:
myserver.conf: |
server {
listen 8080;
server_name www.ik8s.io;
include /etc/nginx/conf.d/myserver-*.cfg;
location / {
root /usr/share/nginx/html;
}
}
status.cfg: |
location /nginx-status {
stub_status on;
access_log off;
}
kind: ConfigMap
metadata:
creationTimestamp: null
name: nginx-confs
#myserver.conf
server {
listen 8080;
server_name www.ik8s.io;
include /etc/nginx/conf.d/myserver-*.cfg;
location / {
root /usr/share/nginx/html;
}
}
#myserver-status.cfg
location /nginx-status {
stub_status on;
access_log off;
}引用ConfigMap对象
ConfigMap资源对象中以key-value保存的数据,在Pod中引用的方式通常有两种
环境变量
1.引用ConfigMap对象上特定的key,以valueFrom赋值给Pod上指定的环境变量
2.在Pod上使用envFrom一次性导入ConfigMap对象上的所有key-value,key(也可以统一附加特定前缀)即为环境变量名,value自动成为相应的变量值
configMap卷
1.在Pod上将ConfigMap对象引用为存储卷,而后整体由容器mount至某个目录下
- key转为文件名,value即为相应的文件内容
2.在Pod上定义configMap卷时,仅引用其中的部分key,而后由容器mount至目录下
3.在容器上仅mount configMap卷上指定的key
示例:
#通过环境变量引用
apiVersion: v1
kind: Pod
metadata:
name: configmaps-env-demo
spec:
containers:
- image: registry.cn-zhangjiakou.aliyuncs.com/image_packs/demoapp:v1.0
name: demoapp
env:
- name: PORT
valueFrom:
configMapKeyRef:
name: demoapp-config
key: demoapp.port
optional: false
- name: HOST
valueFrom:
configMapKeyRef:
name: demoapp-config
key: demoapp.host
optional: true
#通过存储卷引用
apiVersion: v1
kind: Pod
metadata:
name: configmaps-volume-demo
spec:
containers:
- image: nginx:alpine
name: nginx-server
volumeMounts:
- name: ngxconfs
mountPath: /etc/nginx/conf.d/
readOnly: true
volumes:
- name: ngxconfs
configMap:
name: nginx-config-files
optional: falsesecret资源
Secret主要用于存储密钥、OAuth令牌和 SSH 密钥等敏感信息,这些敏感信息采用base64编码保存,略好于明文存储
Secret根据其用途等,还有类型上的区分
创建Secret资源
支持类似于ConfigMap的创建方式,但Secret有类型子命令,而且不同类型在data或stringData字段中支持嵌套使用的key亦会有所不同
命令式命令
generic
kubectl create secret generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1]
除了后面docker-registry和tls命令之外的其它类型,都可以使用该命令中的--type选项进行定义,但有些类型有key的特定要求
tls
kubectl create secret tls NAME --cert=path/to/cert/file --key=path/to/key/file
通常,其保存cert文件内容的key为tls.crt,而保存private key的key为tls.key
docker-registry
kubectl create secret docker-registry NAME --docker-username=user --docker-password=password --docker-email=email [--docker-server=string] [--from-file=[key=]source]
通常,从已有的json格式的文件加载生成的就是dockerconfigjson类型,命令行直接量生成的也是该类型
示例:
#命令式命令 --- 一般建议在命令后加上 --dry-run=client -o yaml ,生成对应的配置文件去apply加载使用
kubectl create secret generic mysql-root-authn --from-literal=username=root --from-literal=password=123456
apiVersion: v1
data:
password: MTIzNDU2Cg==
username: cm9vdA==
kind: Secret
metadata:
creationTimestamp: null
name: mysql-root-authn
#tls
kubectl create secret tls nginx-tls --cert=certs.d/nginx.crt --key=certs.d/nginx.key
apiVersion: v1
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURsVENDQW4yZ0F3SUJBZ0lVR2Zya05FeGZiS2N5Yy9LYkpLUXJ5MzRTcHI0d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1dqRUxNQWtHQTFVRUJoTUNRMDR4RURBT0JnTlZCQWdNQjBKbGFXcHBibWN4RURBT0JnTlZCQWNNQjBKbAphV3BwYm1jeER6QU5CZ05WQkFvTUJrUmxkazl3Y3pFV01CUUdBMVVFQXd3TmQzZDNMbWxzYVc1MWVDNXBiekFlCkZ3MHlNREEwTVRVd05UQXdORE5hRncweU1EQTFNVFV3TlRBd05ETmFNRm94Q3pBSkJnTlZCQVlUQWtOT01SQXcKRGdZRFZRUUlEQWRDWldscWFXNW5NUkF3RGdZRFZRUUhEQWRDWldscWFXNW5NUTh3RFFZRFZRUUtEQVpFWlhaUApjSE14RmpBVUJnTlZCQU1NRFhkM2R5NXBiR2x1ZFhndWFXOHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRRE1pNSsyUStZTlNxeS9vVVhNQzAraklqc2puS2M5SzdjVzYweFhrQzZOa3lSY3BZSmwKdWM4ckFYRUxyZjUxMmJUWGhxb0hqVG5JeFExVFROeDNRbE9oTHBYVjJCbGtObVNzY0w0Uy9IL1VEWTlQayt0cwpiOGlEZSszdlBEQ1ZiQytvOEFYYUhUaktaQ0pXc0oxY0RJY0JGenQ0MFQzUWswL1hQcVYrM1pERWFNcW9LYklJCmRvbENLLzZiN1BlaElXVVFWeFVDK3NoZ0xVbjJReXJmK0UrRC9TQmZFOVd3UGp0YXdCeHdxaDZOczV1dEVsL0cKVmltbEMxM2tsWTNGQ1RMWEhFU3hNKzdGNlU2VUdpYm1CWFRsLzZlV1I2bmlVdW1kMjhyU2NneXVDTnA1NGY2cAp1VGFMK0ZNbG0wN0NiS3lLWHhDZHpVNXVrSFlOYXlqa3p3ck5BZ01CQUFHalV6QlJNQjBHQTFVZERnUVdCQlE1ClhNbkhJanZYZFVCb1BEd3BpbjdiVWN6SHJqQWZCZ05WSFNNRUdEQVdnQlE1WE1uSElqdlhkVUJvUER3cGluN2IKVWN6SHJqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQlVwU1pSNUE5Rgo2bVZhSU16TUl0anZadXFpRDNpeG9PN3NEdEZCcGVsYVZNV0dIaTZ3cFlTL21kNkNmS0hQQ3pySDhnNmpWTGhaClRpRWd5OVREUG5wMmU0VWNBUzdYMVBPM21GWTVscGpVakxJZjR4bUZrUy9FdFQ1ZE5TbUF1NGxGN2ZrRkEraEYKc244b2s5bk9DNk05OVBxbmQ1SlpVR1pwRFJCK1NQblpIVzZ3R2JiSVd3R3hPQmNtejBBMHNJNTkyVm9POThYKwoxK2w4MEVmdkhjRDJQRmdmSzhqS3g5eEl0UjEwcnBtVE4yQmtPQlBiREZ4SHZEcTNjRlRBSVVhMGhWS04xT0xJCk1oSEsvVnJmRUxHanJvY0pTZEFxcGpPTFl0R2JQN09sWURHTzFPRDk2ZEVTYStWWTRXYnFqYzc5S0luREQrWnkKWVlqbkJKR2F5VExyCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBekl1ZnRrUG1EVXFzdjZGRnpBdFBveUk3STV5blBTdTNGdXRNVjVBdWpaTWtYS1dDClpiblBLd0Z4QzYzK2RkbTAxNGFxQjQwNXlNVU5VMHpjZDBKVG9TNlYxZGdaWkRaa3JIQytFdngvMUEyUFQ1UHIKYkcvSWczdnQ3end3bFd3dnFQQUYyaDA0eW1RaVZyQ2RYQXlIQVJjN2VORTkwSk5QMXo2bGZ0MlF4R2pLcUNteQpDSGFKUWl2K20rejNvU0ZsRUZjVkF2cklZQzFKOWtNcTMvaFBnLzBnWHhQVnNENDdXc0FjY0tvZWpiT2JyUkpmCnhsWXBwUXRkNUpXTnhRa3kxeHhFc1RQdXhlbE9sQm9tNWdWMDVmK25sa2VwNGxMcG5kdkswbklNcmdqYWVlSCsKcWJrMmkvaFRKWnRPd215c2lsOFFuYzFPYnBCMkRXc281TThLelFJREFRQUJBb0lCQUNjeWpvMndIMUxtdjRvTgpqc0dXWFZHR3lzeDlSYk04UUY3ZEFvazVNU0tpVXZLS0tSM3phSmIyTk1Lbk9qODlWQ0dGUmVvaWp6TkJSOWR4CndFSCtiT1pUZGhVL3owWGNBcGpsRmhldldaTzZjWDh2ZW9zU05OdTFrUmdxY2FrQXpYVlRZZHUxZzkrTkp1TnoKL3dQWHhydFh4MmJVdWtMUktCaTRnYUI1TnpmY0FSdzBIWG9aUjExbVRydkhLSWRSQUx4Q21KR09aTlg5RjhGMQpsQ1dCN2hjWVNkRVg5MTBkT2VFTlRzUUNMeVJvaDdXWkJSejBEUVBYNnNJd2FJTGtFT0puSVQ0K3JYNldCZGdkCmRkRjN3L0ZYcGxFdW9BSVplSDJmZnkvMzNyTFpSSXlSZWFEVnJUeHFUMnVOQlVkbkJPN1NFa2VYV25kUEh2V2MKaUpRUGxTRUNnWUVBOXdGQmpzOGk2a0YrWDM1N09ueFpuZXB4WnVZMGhqRk5BcVdPSGlUMWsvcWt6T2pRSG1kMgpHSnJZZjc0OUc3VHB2R2Y2TytzalIvZm96ODVsdFViSnh5Wk1IK2JqQzgwM0VUeXp2TmlXZzE2MVp6Nyt5NGpKClI5dlhCS05vd0NlazVFYVRyZ3owZkp5bjJ1WlRDak1aUE1WVVFBRmlYc0RtUTAybUp6dVdwTmtDZ1lFQTAvNkkKTjg2a2szalRzaHhvTEM5VUR0K0x4VTVaUE8vS0t0a21SUEorYU1IbS9uUXJYazZ6a1pJVUF2OHIrOWZXVXdHbQpYUmd2QjVlaHAvT1htdkxLWEhSVmhhVjc3QTZvMEVQVFRrcU5iZU5GSHg1cVFObU85ZHdIVTNSTW5PeWk0TnluCmFJNlljNGIvMWJXdXlBYlVlc0tEdXI3L0FMOFo5UU1XVUVUb2pSVUNnWUF2bzY1aFBOSWZIRUtqYUdHY0JoL0MKdFZUcDQ3eDlwVVNWSGhrcTl6WG1OSkZVZEJLdnlvU2Nla0VIWWttbTdsMm1XT2VLWnUrSEVlbDFLdm15M05STgo5TFQ1OGk0WU9KeEdWczdUdlhKS0pCb1lyNjIwMDh6K2J3Z3BmTnJYTk00NHVPUUN6YnpaeTkwVCt4aEkvMUgrCnhwQlpSK3NSRzJOTjE4d1VCUW9wQVFLQmdFdnNHWDdiRytmUTJ3Z3Iwa2NZd0NML2ZvQXdPaGR2elZpaEltcUkKNmlxOFh1ejhUOWZibWNYbHFoTVVyZnpvNU5JZmdpUlBGL0RCSmwwUENWbXQ0RGxTVkpxamxJa0xDdnhqZmhiSQo3blBQZEI3YjlyTzQ5dEVvZHRzMWlJYWUzUXBwRys5L09pd055aXdRZ0VNVTV4Mzc4Yzk4dmJqWHVBVWVrT3c0CmNZeXRBb0dBTEtNazBwMUUrZHJtVzVuS3VMa2dyNDYzbmtlenBld2Y4eVJ2UHZQcUo4UkdobTBGblphOW1mQ0YKd1JCMDh1MkZ6YTRHSldEY0p2VG9kV3NtSmpCVHRMQ0wzaFlCSmNNQXNVNEdEbXBCZDdQMVBQQ1ZCb0JMeVJjbApyK2VTOFJzZTRwTERjOWdpQk9ZSGp4Q2hsVktSdVhESmh2V2k0azZVNGY5bStBNmp4STg9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
kind: Secret
metadata:
creationTimestamp: null
name: nginx-tls
type: kubernetes.io/tls引用Secret对象
Secret资源在Pod中引用的方式同样有两种
环境变量
引用Secret对象上特定的key,以valueFrom赋值给Pod上指定的环境变量
在Pod上使用envFrom一次性导入Secret对象上的所有key-value,key(也可以统一附加特定前缀)即为环境变量名,value自动成为相应的变量值
secret卷
在Pod上将Secret对象引用为存储卷,而后整体由容器mount至某个目录下
key转为文件名,value即为相应的文件内容
在Pod上定义Secret卷时,仅引用其中的部分key,而后由容器mount至目录下
在容器上仅mount Secret卷上指定的key
注意:容器很可能会将环境变量打印到日志中,因而不建议以环境变量方式引用Secret中的数据
在Pod 上引用 Secret 的示例
apiVersion: v1
kind: Pod
metadata:
name: secrets-volume-demo
spec:
containers:
- name: ngxserver
image: nginx:alpine
volumeMounts:
- name: nginxcerts
mountPath: /nginx/
readOnly: true
- name: nginxconfs
mountPath: /nginx/conf.d/
readOnly: true
volumes:
- name: nginxcerts
secret:
secretName: nginx-ssl-secret
- name: nginxconfs
configMap:
name: nginx-ssl-vhosts-confs
optional: falsedocker-registry
apiVersion: v1
kind: Pod
metadata:
name: private-image-pod
spec:
containers:
- name: my-container
image: registry.example.com/private-image:latest
imagePullSecrets:
- name: my-registry-secret # 引用 Secret