Kubernetes 引入Pod的目的: 1、可管理性(提供了比容器更高层次的抽象,将他们封装在一个部署单元) 2、通信和资源共享(Pod中的容器在一个网络命名空间下,相同的IP地址和Port空间,可以通过localhost通信,可以共享存储)
Pod使用方式:
满足不同的应用场景,Kubernetes提供了多种Controller(Deployment、ReplicaSet、DaemonSet、StatefulSet、Job等)
Kubernetes 运行容器和访问容器的任务分布由Controller和Service执行。
Namespace:将一个物理的Cluster逻辑上会分为多个Cluster
kubernetes 默认有两个Namespace:
Kubernetes Cluster由Master和Node组成,节点上运行着若干Kubernetes服务
运行的Daemon服务包括:
提供HTTP/HTTPS RESTful API,是集群的前端接口,各种客户端工具(CLI或UI)以及Kubernetes其他组件可以通过它管理集群的各种资源
负责决定将Pod放在哪个Node上运行,Scheduler在调度时会充分考虑网络拓扑结构,当前各节点负载,以及应用对高可用,性能和数据亲和性的需求。
管理集群各种资源,保证资源处于预期状态
Controller Manager由多种Controller组成:
controller | 作用 |
---|---|
replication Controller | 管理Deployment、StatefulSet、DaemonSet的生命周期 |
namespace Controller | 管理Namespace资源 |
保存集群的配置信息和各种资源的状态信息,当数据发生变化时,etcd会快速通知Kubernetes的相关组件
Pod要能够正常通信,Kubernetes 集群必须部署Pod网络,flannel为其中一个可选方案
kubernetes支持Docker 、 rkt等容器Runtime,Node上运行的Daemon服务包括:
是Node的agent,当scheduler确定在某个Node上运行Pod后,将Pod具体的配置信息(image、volume等)发送给该节点的kubelet,kubelet根据这些信息创建并运行容器,并向Master报告运行状态
Service在逻辑上代表了后端的多个pod,外界通过service访问pod。kube-proxy负责将访问Service的TCP/UDP数据流转发到后端的容器,如果有多个副本,kube-proxy会实现负载均衡
同上
部署完成的Kubernetes集群中运行如下pod:
这些pod都是运行在kube-system命名空间中,kube-dns组件是为集群提供DNS服务,只有kubelet没有容器化,通过systemd服务进行管理,如下图所示:
[root@tdc-01 ~]# systemctl status kubelet.service
● kubelet.service - Kubernetes Kubelet
Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
Active: active (running) since 五 2018-10-12 02:07:46 CST; 13h ago
Main PID: 2586 (kubelet)
CGroup: /system.slice/kubelet.service
├─2586 /opt/kubernetes/bin/kubelet --logtostderr=true --v=4 --address=0.0.0.0 --cluster_dns=10.10.0.10 --cluster_domain=transwarp.local --port=10250 --hostname_override=172.16...
└─2671 journalctl -k -f
kubernetes 支持两种创建资源的方式:
kubectl run Nginx-deployment --image=nginx:1.7.9 --replicas=2
基于命令的方式简单、直观、快捷、适合临时测试或实验 基于配置文件的方式描述详细,模板可重复部署,适合正式的跨环境的规模化部署
apiVersion: extensions/v1beta1 //当前配置格式的版本
kind: Deployment //资源的类型
metadata: //资源的元数据
name: wdg4f
namespace: kube-system
spec: //该Deployment的规格
replicas: 3 //副本数
template: //pod的模板
metadata: //pod的元数据
labels: //至少定义一个labels
app:server
spec: //该pod的规格,pod的名字和镜像地址等
containers:
- name:
images:
nodeSelector: ①
type:gpu
比如,不同的节点上配置不同的资源,不同的pod调度到对应的node上,使用对应的资源
kubectl lable node node-1 type=gpu //给node贴label
kubectl get node --show-labels //查看node的label
kubectl label node node-1 type- //删除对应的label
node已经贴好对应的标签,在deployment中定义的pod中配置好对应的nodeSelector即可,如上配置文件中的①位置。
每个Node上最多只能运行一个副本,典型的应用场景如下:
kubernetes 自己就在用DaemonSet运行系统组件,如kube-proxy和kube-fannel-ds
容器按照持续运行的时间可以分为:服务类容器和工作类容器
如果希望同时执行多个pod来提高执行效率,在Job的配置文件中添加parallelism参数,类设置并发数,该参数添加在Job配置文件的spec中。
apiVersion: extensions/v1beta1 //当前配置格式的版本
kind: Job //资源的类型
metadata: //资源的元数据
name: jobs
spec: //该Job的规格
parallelism:3 //并行数,默认为1
completions:9 //设置Job成功完成pod的总数,默认为1
template: //pod的模板
以上配置文件的意思,每次并发运行3个pod,直到总共有9个pod成功完成。
在Linux中有一个cron程序定时执行任务,kubernetes中的cronJob提供类似功能
apiVersion: extensions/v1beta1 //当前配置格式的版本
kind: CronJob //资源的类型
metadata: //资源的元数据
name: jobs
spec: //该Job的规格
scheduler: "*/****" //与Linux中cron的语法一致
jobTemplate: //pod的模板
spec:
template:
kubernetes默认没有开启定时任务功能,需要在kube-apiserver中添加配置,修改配置文件/etc/kubernetes/manifests/kube-apiserver.yaml,在command中添加
--runtime-config=batch/v2alpha1=true
或者在kube-apiserver这个pod启动的时候以启动参数的形式添加,并重启kubelet服务
Service 从逻辑上代表了一组pod,通过label来选择对应pod。
客户端只需要访问Service的IP,kubernetes负责建立和维护Service和Pod的映射关系。
apiVersion: v1 //当前配置格式的版本
kind: Service //资源的类型
metadata: //资源的元数据
name: svc
spec: //该Service的规格
selector:
run:httpd
ports:
- protocol:TCP
port:8080 //service暴露端口
targetPort:80 //映射的pod的端口
cluster-IP和pod-IP通过iptables实现映射
cluster-ip是一个虚拟的IP,有kubernetes节点上的iptabels规则管理。
iptables将访问Service的流量转发到后端Pod,使用类似轮询的负载均衡策略。
kubernetes集群中的每一个节点都配置了相同的iptables规则,这样确保整个集群都能够通过Service的Cluster IP访问到Service
在集群中除了通过Cluster IP访问Service还可以通过DNS访问,在kube-system命名空间中运行着kube-dns组件,这是一个DNS服务器,当有新的Service创建时,kube-dns会添加该Service的DNS记录。
集群中的pod可以通过
wget SVC.default:8080
nslookup svc.default //查看service的DNS
Server: 10.96.0.10
Address: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: SVC
Address: 10.99.229.179 svc.default.svc.cluster.local
除了集群内部可以访问Service,很多时候希望应用的Service能够暴露给集群外部,kubernetes提供了多种类型的Service,默认的是ClusterIP。
NodePort
apiVersion: v1
kind: Service
metadata
name: svc
spec
type:NodePort
selector:
run:httpd
ports:
- protocol:TCP
nodeport:3000 //配置这个参数,则指定了service的nodeport 【节点监听的端口】
port:8080 //service暴露端口 【cluster IP 监听的端口】
targetPort:80 //映射的pod的端口 【pod监听的端口】
以上配置文件创建的Service中不但有cluster IP,同时还有External IP 为Nodes 并且将service的8080端口和节点的静态端口进行绑定,kubernetes会从30000~32767中随机分配一个,每个节点都会监听这个端口,并将请求转发给Service。
同样,通过iptables将访问节点端口的流量转发给service的后台pod。
强大的自愈能力是Kubernetes这类容器编排引擎的重要特性,默认的实现是自动重启发生故障的容器。也可以使用Liveness和Readiness 探测机制设置更精细的健康检查,从而实现如下需求:
每个容器启动时都会执行一个进程,此进程由Dockerfile的CMD或ENTRYPOINT指定。如果该进程退出时的返回码非零,则认为容器发生故障,Kubernetes就根据restartPolicy重启容器。
restartPolicy:
以上情况适用于,pod发生故障后进程退出,且退出码不为0。但是存在一些情况,pod发生故障,但是进程并没有退出,比如系统超负载或者资源死锁等,此时进程并没有异常退出的,在这种情况下重启容器是最直接有效的解决方案。
处理以上情况使用Liveness探测。
Liveness探测让用户可以自定义判断容器是否健康的条件。
apiVersion: v1
kind: Pod
metadata
labels:
test:liveness
name: liveness
spec
restartPolicy:OnFailure
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
以上pod的配置文件中,启动进程首先创建文件/tmp/healthy 30秒后删除; 判断条件为如果文件存在,则任务容器正常。
livenessProbe部分定义了如何执行Liveness操作:
kubectl describe pod liveness //查看liveness日志
Liveness探测 告诉kubernetes什么时候通过重启容器实现自愈
Readiness探测 告诉kubernetes什么时候可以将容器加入到Service负载均衡池中,对外提供服务。
Readiness语法和Liveness完全一致:
apiVersion: v1
kind: Pod
metadata
labels:
test:readiness
name: readiness
spec
restartPolicy:OnFailure
containers:
- name: readiness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
以上配置文件创建的pod 在经过initialDelaySeconds+periodSeconds之后开始进行Readiness探测,探测成功后pod状态被设置为Ready
kubectl describe pod readiness //查看readiness日志
如果不进行特殊的配置,kubernetes将对这两个探测采取相同的默认行为,通过判断容器启动进程的返回值是否为零来判断探测是否成功。
两者的配置方法一样,支持的配置参数一样,不同之处在于:
liveness探测和readiness探测是独立运行的,两者之间没有依赖:
容器销毁时,保存在容器内部文件系统中的数据会被清除,为了持久化保存容器中的数据,使用kubernetes Volume。Volume的生命周期独立于容器,Pod中的容器可能被销毁和重建,但是volume会被保留。
本质上Volume是一个目录,当volume被mount到pod中时,pod中的所有容器都可以访问这个volume。
volume支持多种backend:
volume提供了对各种backend的抽象,容器在使用volume读写数据时不需要关心数据到底是存放在本地节点的文件系统,还是云硬盘上。所有类型的volume都只是一个目录。
最基础的volume类型,是host上的一个空目录,对于容器是持久化的,对于pod不是持久化的。当pod从节点删除时volume 的内容也会被删除。
emptyDir Volume的生命周期与Pod一致。pod中所有容器可以共享volume,它们可以指定各自的mount路径
emptyDir是Docker Host文件系统里的目录,其效果相当于执行了docker -v /dir ,通过docker inscept 可以查看到容器的详细配置
/var/lib/kubelet/pods/062b215e-c0b4-11e8-badb-0cc47aa57eee/volumes/kubernetes.io~empty-dir/dir
这个是emptyDir在host上的真正路径。
hostPath的作用是将Docker Host文件系统中已经存在的目录mount给pod的容器。
大部分应用都不会使用hostPath(这实际上增加了pod与节点的耦合程度),限制了Pod的使用。那些需要访问kubernetes或docker内部数据(配置文件或二进制库)的应用需要使用hostPath。
如kube-apiserver和kube-controller-manager就是这样的应用。
当pod销毁,hostPath对应的目录还是会被保留的,只有当节点奔溃才会导致hostPath不可用。
有了PVC用户只需要告诉kubernetes需要什么样的存储资源,而不关心真正的空间从哪里分配,如何访问等底层细节。
apiVersion: v1
kind: PersistentVolume
metadata
name:mypv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
StorageClassName: nfs //指定PV的class的分类,pvc可以指定class申请相应class的PV
nfs:
path: /nfs/data
server: 192.168.1.1
PV 支持的类型:
PV有三种访问模式(accessModes):
PV有三种回收策略(persistentVolumeReclaimPolicy):
apiVersion: v1
kind: PersistentVolumeClaim
metadata
name:mypvc1
spec:
accessModes:
- ReadWriteOnce
resources:
request:
storage:1Gi
StorageClassName:nfs //pvc指定class申请相应class的PV
在pod的配置文件中使用对应的pvc即可,就像使用普通Volume的格式那样使用。
当不需要使用PV时,删除PVC然后回收PV
PV的状态:
上面的例子都是手动创建PV,然后手动创建PVC去bound对应的PV,然后pod手动mount对应的pvc,以上过程,成为静态供给
动态供给的意思是,如果没有满足PVC条件的PV,会动态创建PV,相比于静态供给的优势在于++不需要提前创建好PV++,减少工作量,提高效率。
动态供给是通过StorageClass实现的,在StorageClass中定义好如何创建PV,如下:
StrorageClass standard:
apiVersion:storage.k8s.io/v1
kind:StorageClass
metadata:
name:standard
provisioner:kubernetes.io/aws-ebs
parameters:
type:gp2
reclaimPolicy:Retain
StorageClass slow:
apiVersion:storage.k8s.io/v1
kind:StorageClass
metadata:
name:slow
provisioner:kubernetes.io/aws-ebs
parameters:
type:io1
zones: us-east-1d,us-east-1c
iopsPerGB: "10"
StorageClass 支持delete和retain两种reclaimPolicy,默认为Delete,PVC配置文件中只需要指定storageClassName:standard/slow,其他都一样
kubernetes支持动态供给PV的provisioner如下: https://kubernetes.io/docs/concepts/storage/storage-classes/ 官网中有表格
应用启动过程中可能需要一些敏感数信息,如访问数据库的用户名,密码等,将这些信息直接保存在容器镜像中显然不妥。Secret会以密文的方式存储数据,避免了直接在配置文件中保存敏感信息。
Secret会以Volume的形式mount到pod,容器可以通过文件的形式使用Secret中的敏感数据,容器㛑能够以环境变量的形式使用这些数据。
每个--from-literal对应一个信息条目
kubectl ceate secret generic mysecret --from-literal=username=admin --from-literal=password=123456
每个文件内容对应一个条目
kubectl ceate secret generic mysecret --from-file=./username --from-file=./password
文件env.txt中每一行key=value对应一个信息条目
kubectl ceate secret generic mysecret --from-env-file=env.txt
apiVersion: v1
kind: secret
metadata:
name: mysecret
data:
username: YWRtaW4=
password: MTIzNDU2
文件中的敏感数据必须通过base64编码,然后执行kubectl apply 创建secret
apiVersion:v1
kind:Pod
metadata:
name:mypod
spec:
containers:
- name:mypod
image:busybox
volumeMounts:
- name:foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name:foo
secret:
secretName:mysecret
items: //自定义敏感数据的存储路径
- key:username
path: my-group/my-username
- key: password
path: my-group/my-password
kubernetes会在指定的路径下为每一条敏感数据创建一个文件,文件名就是敏感数据条目的key值,value则以明文存放在对应的文件中,Secret动态更新,容器中的数据也会动态更新。
piVersion:v1
kind:Pod
metadata:
name:mypod
spec:
containers:
- name:mypod
image:busybox
env:
- name: SECRET_USERNAME
valueFrom:
secretkeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretkeyRef:
name: mysecret
key: password
pod 通过环境变量SECRET_USERNAME和SECRET_PASSWORD成功读取到Secret中的数据。以环境变量的方式虽然读取方便,但是无法动态更新。
Secret可以为Pod提供敏感数据,对于非敏感数据,如配置信息,可以使用ConfigMap。
每个--from-literal对应一个信息条目
kubectl ceate configmap generic myconfigmap --from-literal=config1=xxx --from-literal=config2=yyy
每个文件内容对应一个条目
kubectl ceate configmap generic myconfigmap --from-file=./config1 --from-file=./config2
文件env.txt中每一行key=value对应一个信息条目
kubectl ceate configmap generic myconfigmap --from-env-file=env.txt
apiVersion: v1
kind: configmap
metadata:
name: myconfigmap
data:
config1: xxx
config2: yyy
文件数据直接以明文输入,然后执行kubectl apply 创建configmap
apiVersion:v1
kind:Pod
metadata:
name:mypod
spec:
containers:
- name:mypod
image:busybox
volumeMounts:
- name:foo
mountPath: "/etc" //将volume mount到/etc路径下
readOnly: true
volumes:
- name: foo
configmap:
name:myconfigmap
items:
- key: logging.conf
path: myapp/logging.conf //在volume中指定存放配置文件的相对路径
这种方式配置文件支持动态更新。
piVersion:v1
kind:Pod
metadata:
name:mypod
spec:
containers:
- name:mypod
image:busybox
env:
- name: CONFIG_1
valueFrom:
configMapkeyRef:
name: myconfigmap
key: config1
- name: CONFIG_2
valueFrom:
configMapkeyRef:
name: myconfigmap
key: config2
pod 通过环境变量CONFIG_1和CONFIG_2成功读取到ConfigMap中的数据。
大多数情况下,配置信息以文件的形式提供,使用--from-file或YAML方式创建ConfigMap,读取ConfigMap通常采用Volume的方式
Pod、 Service、 外部组件之间需要一种可靠的方式找到彼此并进行通信,kubernetes网络负责提供这个保障。
采用基于扁平地址的网络模型,每个pod都要自己的IP,相互之间不需要配置NAT(网络地址转换)就能够直接通信,同一个Pod中的容器共享pod的IP,能够通过Localhost通信。
这种网络模型可以很方便的迁移传统应用到Kubernetes,每个pod可以被看做一个独立的系统,而Pod中的容器可以被看作同一系统中的不同进程。
当pod被调度到节点后,pod中的所有容器都运行在这个节点上,这些容器共享本地文件系统,IPC和网络命名空间等。
不同pod之间不存在端口冲突问题,每个pod有自己独立的IP地址。当某个容器使用localhost时,意味着使用的是容器所属pod的地址空间。
Pod的IP地址是集群可见的,任何其他Pod和节点都可以通过IP直接与Pod通信,这种通信不需要借助任何网络地址转换、隧道或代理技术。Pod内部和外部使用的是同一个IP,这也意味着标准的命名服务和法发现机制,比如DNS都可以直接使用。
Pod会被频繁的销毁和创建,因此pod的IP是不固定的,Service提供了访问pod的抽象层,无论后端Pod如何变化,Service都作为稳定的前端对外提供服务,同时,Service还提供了高可用和负载均衡功能,Service负责将请求转发给正确的Pod。
无论Pod的IP还是Service的Cluster IP 都是集群内部的私有IP,kubernetes提供以下两种方式让外界能够与Pod通信:
为了保证网络方案的标准化、扩展性、灵活性,采用CNI规范,使用插件模型创建容器的网络栈。
CNI的优点是支持多种容器runtime,CNI的插件模型支持不同组织和公司开发的第三方插件,可以灵活选择合适的网络方案。
目前已经有多种支持Kubernetes的网络方案,比如Flannel、Calico、Canal、Weave Net等,这些不同的方案底层实现不同,有的基于VxLAN的Overlay,有的采用Underlay,性能上有区别。
Network Policy是kubernetes的一种资源,通过Label来选择Pod,并制定其他Pod或外界如何与这些Pod通信。
默认情况下,所以Pod是非隔离的,即任何来源的网络流量都能够访问Pod,没有任何限制。当为Pod定义了Network Policy后,只有Policy允许的流量才能够访问Pod。
不是所有的网络方案都支持Network Policy,(Fannel不支持,calico支持)。
apiVersion: networing.k8s.io/v1
kind:NetworkPolicy
metadata:
name: access-httpd
spec:
podSelector:
matchLabels:
run: httpd //规则应用到有这个label的pod上
ingress:
- from:
- podSelector
matchLabels:
access: "true" //只有label为access:"true"的pod能访问
ports:
- protocol: TCP
port: 80 //只能访问端口80
开启ServiceAccount Admission Controller后:
Service Account为服务提供了一种方便的认证机制,但它不关心授权的问题。可以配合RBAC来为Service Account鉴权:
Security Context的目的是限制不可信容器的行为,保护系统和其他容器不受其影响。
Kubernetes提供了三种配置Security Context的方法:
Container-level Security Context仅应用到指定的容器上,并且不会影响Volume。比如设置容器运行在特权模式。
Pod-level Security Context应用到Pod内所有容器,并且还会影响Volume(包括fsGroup和selinuxOptions)。
Pod Security Policies(PSP)是集群级的Pod安全策略,自动为集群内的Pod和Volume设置Security Context。
使用PSP需要API Server开启extensions/v1beta1/podsecuritypolicy,并且配置PodSecurityPolicyadmission控制器。
支持的控制项 控制项| 说明 ---|--- privileged |运行特权容器 defaultAddCapabilities| 可添加到容器的Capabilities requiredDropCapabilities| 会从容器中删除的Capabilities volumes |控制容器可以使用哪些volume hostNetwork| host网络 hostPorts |允许的host端口列表 hostPID |使用host PID namespace hostIPC |使用host IPC namespace seLinux |SELinux Context runAsUser| user ID supplementalGroups| 允许的补充用户组 fsGroup| volume FSGroup readOnlyRootFilesystem |只读根文件系统
资源配额(Resource Quotas)是用来限制用户资源用量的一种机制。
它的工作原理为:
首先,在API Server启动时配置ResourceQuota adminssion control;然后在namespace中创建ResourceQuota对象即可。
默认情况下,Kubernetes中所有容器都没有任何CPU和内存限制。LimitRange用来给Namespace增加一个资源限制,包括最小、最大和默认资源。
每个配额在创建时可以指定一系列的范围
范围 | 说明 |
---|---|
Terminating | podSpec.ActiveDeadlineSeconds>=0的Pod |
NotTerminating | podSpec.activeDeadlineSeconds=nil的Pod |
BestEffort | 所有容器的requests和limits都没有设置的Pod(Best-Effort) |
NotBestEffort | 与BestEffort相反 |
通常情况下,service和pod的IP仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到service在Node上暴露的NodePort上,然后再由kube-proxy将其转发给相关的Pod。
而Ingress就是为进入集群的请求提供路由规则的集合,如下图所示:
graph LR
Internet--> Ingress
Ingress--> Service
Ingress可以给service提供集群外部访问的URL、负载均衡、SSL终止、HTTP路由等。为了配置这些Ingress规则,集群管理员需要部署一个Ingress controller,它监听Ingress和service的变化,并根据规则配置负载均衡并提供访问入口。
Ingress格式:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort: 80
每个Ingress都需要配置rules,目前Kubernetes仅支持http规则。上面的示例表示请求/testpath时转发到服务test的80端口。
根据Ingress Spec配置的不同,Ingress可以分为以下几种类型:
单服务Ingress即该Ingress仅指定一个没有任何规则的后端服务。
注:单个服务还可以通过设置Service.Type=NodePort或者Service.Type=LoadBalancer来对外暴露。
路由到多服务的Ingress即根据请求路径的不同转发到不同的后端服务上,比如
graph LR
foo.bar.com --> 178.91.123.132
178.91.123.132 --> /foo.s1:80
178.91.123.132 --> /bar.s2:80
可以通过下面的Ingress来定义:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
backend:
serviceName: s1
servicePort: 80
- path: /bar
backend:
serviceName: s2
servicePort: 80
TLS Ingress通过Secret获取TLS私钥和证书(名为tls.crt和tls.key),来执行TLS终止。如果Ingress中的TLS配置部分指定了不同的主机,则它们将根据通过SNI TLS扩展指定的主机名(假如Ingress controller支持SNI)在多个相同端口上进行复用。
ConfigMap用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件。ConfigMap跟secret很类似,但它可以更方便地处理不包含敏感信息的字符串。
可以使用kubectl create configmap从文件、目录或者key-value字符串创建等创建ConfigMap。
$ kubectl create configmap special-config --from-literal=special.how=very
configmap "special-config" created
$ kubectl get configmap special-config -o go-template='{{.data}}'
map[special.how:very]
$ echo -e "a=b\nc=d" | tee config.env
a=b
c=d
$ kubectl create configmap special-config --from-env-file=config.env
configmap "special-config" created
$ kubectl get configmap special-config -o go-template='{{.data}}'
map[a:b c:d]
$ mkdir config
$ echo a>config/a
$ echo b>config/b
$ kubectl create configmap special-config --from-file=config/
configmap "special-config" created
$ kubectl get configmap special-config -o go-template='{{.data}}'
map[a:a
b:b
]
ConfigMap可以通过多种方式在Pod中使用,比如设置环境变量、设置容器命令行参数、在Volume中创建配置文件等。
注意