文章目录
- Pod
- Pod控制器
- ReplicaSet
- Deployment
- Job
- CronJob
- Service
- kube-proxy代理模型
- Service资源的类型
- Service应用
- ConfigMap
- ConfigMap创建
- 命令行
- 资源配置清单文件
- ConfigMap使用
- 环境变量
- 存储卷
- Secret
- Secret创建
- 命令行
- 资源配置清单文件
- Secret使用
- 环境变量
- 存储卷
Pod
Pod是k8s上运行容器化应用及调度的最小原子单元,同一个Pod内可以运行多个容器,这些容器之间共享IPC、UTS和Network名称空间,并能够访问同一组存储卷。
Pod的资源规范文件如下:
apiVersion: v1
kind: Pod
metadata:
name: <string> #Pod名称
namespace: <string> #Pod所属名称空间
labels: #Pod的标签
label-key: label-value
annotations: #Pod注解信息
key: value
spec:
containers:#Pod中的容器信息,列表
- name: <string> #容器名称
image: <string> #容器镜像
imagePullPolicy: <string> #镜像拉取策略
ports: <[]Object> #声明容器暴露的端口
volumeMounts: <[]Object> #卷挂载信息
initContainers: <[]Object> #Pod中的初始化容器信息,格式同containers
volumes: <[]Object> #存储卷定义
示例,创建一个nginx Pod:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
创建完成后访问nginx测试
Pod控制器
仅使用单Pod形式运行应用存在一些问题,需要用户手动执行一些操作,例如Pod规模伸缩,升级/回滚,Pod健康状态维护等,Pod控制器就是为了解决这些问题。Pod控制器是用于实现Pod管理的中间层,确保Pod资源符合预期的状态。
Pod控制器有多种类型:
- ReplicationCOntroller(RC):k8s早期使用的一种Pod控制器,可以确保Pod的副本数量符合预期,但仅支持基于等值的标签选择器,现在已经被ReplicaSet取代
- ReplicaSet(RS):其功能基本和RC一致,但支持基于集合的标签选择器
- Deployment:最常用的Pod控制器,工作与Replicaset之上,用于管理无状态应用,支持滚动更新和回滚等高级功能
- DaemonSet:用于确保集群中的每一个节点只运行特定的pod副本,通常用于实现系统级后台任务。比如日志收集服务
- Job:负责运行一次性任务
- CronJob:负责运行周期性任务
- StatefulSet:负责管理有状态应用
ReplicaSet
相较于手动创建和管理Pod,ReplicaSet有以下优点:
- 确保Pod对象的数量符合期望值:RS会确保由其控制的Pod数量符合配置中定义的期望值,多了就删除少了就创建
- 确保Pod处于健康运行状态:RS检测到由其管控的Pod健康检测失败或因节点故障不可用时,会重启或者重建Pod
- 弹性伸缩:只需要修改RS定义中Pod副本的数量就可以实现Pod的伸缩
ReplicaSet资源规范文件如下:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: ...
namespace: ...
spec:
replicas: <int> #期望的Pod副本数,默认为1
selector: #标签选择器,必须匹配template字段中Pod的标签
matchLabels: <map[string]string> #map格式标签选择器
matchExpressions: <[]Object> #标签选择器表达式列表,多个列表项之间为与关系
minReadySeconds: <int> #Pod就绪多少秒内,任一容器无崩溃方可视为“就绪”。默认值为0,表示一旦就绪性探测成功,即被视作可用
template: #Pod模板
metadata: #Pod对象元数据
labels: .... #由模板创建出的Pod对象的标签,必须匹配前面定义的标签选择器
spec: #Pod规范
....
示例,创建一个 nginx rs,副本数量为2::
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-rs
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
查询Pod验证
Deployment
Deployment的主要职责同样是确保Pod以期望状态运行,其大部分功能通过调用Replicaset实现,并添加了部分新特性:
- 事件和状态查看
- 版本记录
- 回滚
- 升级过程的暂停和启动
- 多种更新方案
Deployment的资源规范文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ...
namespace: ...
labels: ...
spec:
replicas: <int> #期望带外Pod数量
selector: <Object> #标签选择器,用来匹配Pod对象
template: <Object> #Pod模板
minReadySeconds: <int> #Pod就绪多少秒内任意容器无崩溃方可视为“就绪”
revisionHistroyLimit: <int> #滚动更新历史记录数量,默认为10
startegy: <Object> #Deployment更新策略配置
示例,创建一个deployment,运行nginx,副本数为3:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
app: nginx
spec:
replicas: 3
selector:
matchExpressions:
- {key: "app", operator: In, values: ["nginx"]}
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: http
containerPort: 80
查询Pod验证
Job
Job控制器通常用于管理那些运行一段时间就可以结束的任务,例如计算或数据初始化等。容器中的进程正常退出后不需要重启,控制器会将该Pod置于Completed状态,并且会在用户指定的生存周期后被删除。如果容器中的进程非正常退出,则要根据Pod的重启策略来决定是否重启。
Job的资源规范文件如下:
apiVersion: batch/v1
kind: Job
metadata:
name: ...
namespace: ...
spec:
selector: <Object> #标签选择器,用来匹配Pod
template: <Object> #Pod模板
completions: <int> #期望成功运行的Pod数量,正常退出的Pod梳理
parallelism: <int> #任务的最大并行数,默认为1
ttlSecondsAfterFinished: <int> #终止状态的Pod的保存时长
activeDeadlineSeconds: <int> #任务启动后可以处于活动状态的时长
backoffLimit: <int> #将任务标记为Failed之前重试的次数,默认为6
示例,创建一个名为job-mysql-init的Job资源,只运行一次即可,负责向指定的文件echo一条数据:
apiVersion: batch/v1
kind: Job
metadata:
name: job-mysql-init
spec:
template:
spec:
containers:
- name: mysql-init-data
image: centos:7.8.2003
command: ["/bin/sh"]
args: ["-c", "echo run data init job at `date +%Y%m%d%H%M%S` >>/cache/data.log"]
volumeMounts:
- name: cache
mountPath: /cache
volumes:
- name: cache
hostPath:
path: /tmp/jobdata
restartPolicy: Never
ttlSecondsAfterFinished: 600
backoffLimit: 2
activeDeadlineSeconds: 300
completions: 1
查看Pod验证
查看数据是否写入成功
CronJob
CronJob用于管理Job资源的运行时间,可以指定在特定的时间或指定的间隔运行Job,它适合自动执行特定的任务,例如备份、清理类的任务和发送报告等。CronJob使用Job来完成任务,它每次运行都会创建一个Job并使用类似于Job资源的创建、管理和扩容方式。
CronJob的资源规范文件如下:
apiVersion: batch/v1
kind: CronJob
metadata:
name: ...
namespace: ...
spec:
jobTemplate: #Job资源模板
metadata: <Object> #Job模板元数据
spec: <Object> #Job的期望状态
schedule: <string> #调度时间设定,必选
concurrencyPolicy: <string> #并发策略,可用值有Allow、Forbid和Replace
failedJobsHistoryLimit: <int> #失败作业的历史记录数量,默认为1
successfulJobsHistoryLimit: <int> #成功作业的历史记录数量,默认为3
startingDeadlineSeconds: <int> #因错过时间点而未执行的作业的可超期时长
示例,创建一个名为cronjob-mysql-data-backup的CronJob资源,每隔一分钟运行一次,负责向指定的文件echo数据:
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob-mysql-data-backup
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: mysql-data-backup
image: centos:7.8.2003
command: ["/bin/sh"]
args: ["-c", "echo run mysql data backup job at `date +%Y%m%d%H%M%S` >> /cache/data.log"]
volumeMounts:
- name: cache
mountPath: /cache
volumes:
- name: cache
hostPath:
path: /tmp/cronjob-data
restartPolicy: OnFailure
parallelism: 1
completions: 1
ttlSecondsAfterFinished: 600
backoffLimit: 3
activeDeadlineSeconds: 30
查询Pod验证
查看数据是否写入成功
Service
Service是k8s的核心资源类型之一,它主要的作用是为一组Pod提供一个固定的访问入口。Service会把通过标签选择器筛选出的一组Pod定义成一个逻辑集合,并通过iptables或ipvs规则将请求转发给这组Pod。
kube-proxy代理模型
本质上,一个Service对象就是节点上的一组iptables或ipvs规则,这些规则将访问Service对象ClusterIP+端口的流量转发至对应的后端Pod。每个节点上的kube-proxy就负责维护这些规则,kube-proxy通过API Server持续监视各Service对象及其关联得Pod对象,并将Service对象的创建或变动实时反应至当前节点上相应的iptales或ipvs规则中。
kube-proxy的代理模型有3种:
- userspace:k8s1.1版本前默认使用,此模型中,对于每个Service对象,会随机打开一个本地端口,由kube-peoxy负责监听,任何到达此端口的请求都会被转发至当前Service对象的后端Pod。另外,此类Service对象还会创建iptables规则以捕获任何到达ClusterIP和端口的流量。在此模型下,请求报文会在内核空间和用户空间来回转发,导致效率不高。
- iptables:创建Serrvice对象的操作会触发每个节点上的kube-proxy将其转换为iptables规则,用于转发工作接口接收到的与此Service资源ClusterIP和端口相关的流量。客户端的请求直接由iptables规则经过DNAT后转发至后端Pod,而无需经过kube-proxy处理,大大提升了效率
- ipvs:k8s1.11版本起成为默认设置。在此模型中,kube-proxy跟踪API Server上Service和Endpoints对象的变动,并据此来调用netlink接口创建或变更ipvs(NAT)规则,它和iptables规则的不同之处仅在于客户端请求流量的调度功能由ipvs实现,余下的功能仍由iptables规则实现
Service资源的类型
Service资源可根据其工作逻辑划分为4中类型:
- ClusterIP:通过集群内部IP地址暴露服务,ClusterIP仅能在集群内部访问,是默认的Service类型
- NodePort:NodePort可以看作是对ClusterIP的扩展,它支持通过在节点上打开一个特定端口来接入集群外部请求,并转发给后端Pod处理。因此这种类型的Service即可以被集群内部通过ClusterIP访问,也可以通过nodeIP:NodePort被集群外部客户端访问。
- LoadBalancer:LoadBalancer类型构建在NodePort类型之上,通过云服务商提供的软件负载均衡器将服务暴露到集群外部,因此它也会具有ClusterIP和NodePort。简单说,创建LoadBalancer类型的Service会在集群上创建一个NodePort类型的Service,并额外触发k8s调用底层的Iaas服务的API创建一个软件负载均衡器,而集群外部的流量会先路由至该负载均衡器,并由该负载均衡器调度至各节点上该Service对象的NodePort
- ExternalName:通过将Service映射至由externalName字段的内容指定的主机名来暴露服务,简单来说,此种类型通过DNS CNAME的方式将集群外部的服务引入集群内部,让Pod可以访问集群外部的服务
Service应用
Service的资源规范文件如下:
apiVersion: v1
kind: Service
metadata:
name: ...
namespace: ...
spec:
selector: <map[string]string> #标签选择器,用来筛选Service对应的后端Pod
type: <string> #Service类型
ports: #定义Service暴露的端口
- name: <string> #端口名称
port: <int> #端口号
protocol: <string> #协议,默认TCP,支持TCP、UDP和SCTP
targetPort: <int> #对应后端Pod的端口号
nodePort: <int> #节点开放的端口号,仅支持NodePort和LoadBalancer类型Service
clusterIP: <string> #Service的IP,默认是自动分配
externalTrafficPolicy: <string> #外部流量处理方式,Local表示由当前节点处理,Cluster表示在集群范围内调度
loadBalancerIP: <string> #外部负载均衡器IP,仅支持LoadBalancer类型Service
externalName: <string> #外部服务域名,该名称作为Service的DNS CNAME值,仅支持ExternalName类型Service
示例1,ClusterIP类型Service:
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
查看service和service对应的Endpoint验证:
访问service测试
示例2,NodePort类型Service,指定NodePort为31666:
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
nodePort: 31666
查看Service验证
访问测试
ConfigMap
ConfigMap资源主要是用来存储配置数据,为Pod中的应用提供配置。一个ConfigMap就是一系列配置数据的集合,这些数据可以注入到Pod的容器内为应用提供配置信息,注入的方式主要有环境变量和存储卷两种形式。
ConfigMap创建
创建ConfigMap可以通过命令行或者资源清单文件。
命令行
- 直接指定键值,使用–form-literal指定键值,重复使用传递多个键值
kubectl create configmap myconfig --from-literal=host=10.10.0.1 --from-literal=port=8080
- 从文件创建,使用–from-file选项一次加载一个文件为指定键的值,多个文件的加载重复使用–form-file选项完成。省略键名时,键名默认是指定的文件名。
kubectl create configmap static-file --from-file=test-file=./a.txt --from-file=./index.html
- 从目录创建,在配置文件较多的场景下为–from-file选项指定一个目录,就可以把该目录下的所有文件保存到同一个ConfigMap中,文件名就是键名。
kubectl create configmap html-file --from-file=./html/
资源配置清单文件
基于资源配置清单文件创建ConfigMap时,主要使用4个字段apiVersion、kind、metadata和data。
apiVersion: v1
kind: ConfigMap
metadata:
name: configmap-demo
data:
host: 0.0.0.0
port: "1080"
app.conf: |
[DEFAULT]
timeout=30
username=admin
password=123456
logdir=/data/log/
ConfigMap使用
ConfigMap可以通过环境变量和存储卷的方式引用。一般情况下对于单个键值对使用环境变量的方式引入,对于文件使用存储卷方式挂载使用。
环境变量
通过环境变量引用ConfigMap有两种方式:
- 通过Pod资源中容器的env.valueFrom.ConfigMapKeyRef引入指定的键值对
- 通过Pod资源中容器的envFrom.configMapRef引入所有键值对
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-with-configmap-env
spec:
replicas: 1
selector:
matchLabels:
app: configmap-env
template:
metadata:
labels:
app: configmap-env
spec:
containers:
- name: test-env-pod
image: centos:7.8.2003
command: ["/bin/sh", "-c", "sleep 3600"]
env:
- name: HOST
valueFrom:
configMapKeyRef:
name: configmap-demo
key: host
optional: false
- name: PORT
valueFrom:
configMapKeyRef:
name: configmap-demo
key: port
optional: false
进入Pod查看环境变量验证
如果ConfigMap中有较多键值数据,且大部分键值数据都需要被引用为环境变量,这个时候逐一配置每个变量比较耗时,可以使用Pod资源中容器的envFrom.configMapRef将一个或多个ConfigMap的键值数据全部引用为变量。
需要注意: 在这种方式下,ConfigMap中的键名就是容器里的环境变量名,因此键名和和容器引用的环境变量名保持一致。
apiVersion: v1
kind: ConfigMap
metadata:
name: demoapp-config
namespace: default
data:
HOST: 0.0.0.0
PORT: '8090'
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: configmap-envfrom-demo
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: configmap-envfrom-demo
template:
metadata:
labels:
app: configmap-envfrom-demo
spec:
containers:
- image: centos:7.8.2003
name: pod-demo
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "sleep 3600"]
envFrom:
- prefix: HTTP_ #为引用的ConfigMap中的所有键命名添加一个前缀名,防止不同ConfigMap中的键名冲突
configMapRef:
name: demoapp-config
optional: false
进入Pod查看环境变量验证
存储卷
Pod资源可以通过configMap存储卷插件以存储卷的形式直接引用ConfigMap中的数据。从挂载方式来区分,可以分为下面三种情况:
- 挂载整个存储卷
将ConfigMap挂载到一个目录,该ConfigMap对象中的每个键值将会转换为挂载目录下的一个文件,键名为文件名,键值为文件内容。
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-confs
namespace: default
data:
myserver-gzip.cfg: |
gzip on;
gzip_comp_level 5;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/xml text/javascript;
myserver-status.cfg: |
location /nginx-status {
stub_status on;
access_log off;
}
myserver.conf: |
server {
listen 8080;
server_name www.ik8s.io;
include /etc/nginx/conf.d/myserver-*.cfg;
location / {
root /usr/share/nginx/html;
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-with-configmap-volume
spec:
replicas: 2
selector:
matchLabels:
app: deploy-with-configmap-volume
template:
metadata:
labels:
app: deploy-with-configmap-volume
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: http
containerPort: 80
volumeMounts:
- name: nginx-confs
mountPath: /etc/nginx/conf.d/
volumes:
- name: nginx-confs
configMap:
name: nginx-confs
optional: false
进入容器查看ConfigMap中的文件是否已挂载
- 挂载部分键值
在某些场景下,通过一个ConfigMap向一个Pod内的多个容器提供配置,这时候仅希望容器只挂载ConfigMap中要使用的键值而不是全部键值,这可以通过Pod资源的volumes.configMap.items字段实现,items字段是一个对象列表,可通过嵌套下面3个字段来指定要挂载的键值:
- key:要引用的键名称,必选
- path:键在挂载点目录下的文件名称,可以喝和键名不一致,必选
- mode:文件权限,0-0777
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-with-configmap-volume2
spec:
replicas: 2
selector:
matchLabels:
app: deploy-with-configmap-volume2
template:
metadata:
labels:
app: deploy-with-configmap-volume2
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: http
containerPort: 80
volumeMounts:
- name: nginx-confs
mountPath: /etc/nginx/conf.d/
volumes:
- name: nginx-confs
configMap:
name: nginx-confs
items:
- key: myserver.conf
path: myserver.conf
mode: 0600
进入Pod查看文件验证
- 挂载单个键值
有些场景下,容器中的挂载点已经存在一些文件,并且不希望覆盖这些文件,这种情况下可以通过volumeMounts.subPath字段实现,该字段支持从存储卷挂载单个目录或单个文件而非整个存储卷。
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-with-configmap-volume3
spec:
replicas: 3
selector:
matchLabels:
app: deploy-with-configmap-volume3
template:
metadata:
labels:
app: deploy-with-configmap-volume3
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: http
containerPort: 80
volumeMounts:
- name: nginx-confs
mountPath: /etc/nginx/conf.d/myserver.conf
subPath: myserver.conf
volumes:
- name: nginx-confs
configMap:
name: nginx-confs
进入Pod查看文件验证
Secret
Secret主要用来存储敏感数据,例如证书、密钥、ssh-key等,借助Secret,可以控制敏感数据的使用方式,减少暴露风险。
Secret创建
Secret也可以通过命令行和资源清单文件两种方式创建
命令行
和ConfigMap一样,创建Secret对象也支持直接使用键值创建、从文件创建和从目录创建。并且使用命令行创建时,可以将Secret分为3种类型:
- generic:一般用来存储密码、密钥等数据
- docker-registry:用来存储Docker Registry的认证信息,用于拉取私有镜像
- tls:用来存储证书公钥和私钥,用于TLS通信,公钥必须是pem格式
generic类型secret
kubectl create secret generic secret-demo --from-literal=username=admin --from-literal=password=123456
docker-registry类型的Secret,创建此类型的secret需要指定下面3个选项:
- –docker-server:Docker Registry服务器的地址
- –doker-usrname:连接Registry的用户名
- –docker-password:连接Registry的密码
kubectl create secret docker-registry harbor-secret --docker-username=admin --docker-password=Passw0rd --docker-server=https://harbor-server.linux.io
另外也可以使用–from-file选项直接通过dockerconfig类型的文件创建docker-registry类型的Secret。
tls类型的secret,创建此类型的Secret需要指定–cert和–key选项,前者表示证书公钥,后者表示证书私钥
kubectl create secret tls k8s-cert --cert=/etc/kubernetes/ssl/ca.pem --key=/etc/kubernetes/ssl/ca-key.pem
资源配置清单文件
使用资源清单文件创建Secret时,除了apiVersion、kind、metadata个字段外,还可以使用下面3个字段:
- data <map[string]string>:Secret中存储的数据,key:value格式,需要提前使用base64加密
- stringData <map[string]string>:和data字段作用相同,但数据不需要事先base64编码,和data字段二选一
- type:Secret的类型,不同类型存储不同的数据
apiVersion: v1
kind: Secret
metadata:
name: secret-basic-auth
stringData:
username: admin
password: Passw0rd
type: kubernetes.io/basic-auth
Secret使用
环境变量
Pod通过环境变量方式引用Secret时也存在两种方式:
- 通过Pod资源中容器的env.valueFrom.secretKeyRef引入指定的键值对
- 通过Pod资源中容器的envFrom.secretRef引入Secret中的所有键值对
apiVersion: v1
kind: Secret
metadata:
name: mysql-auth
stringData:
password: Passw0rd
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
spec:
selector:
matchLabels:
app: mysql
replicas: 1
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mariadb
ports:
- name: mysql-port
containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-auth
key: password
optional: false
进入Pod登录mysql验证
Pod资源也可以通过secret存储卷插件将Secret挂载到Pod的容器中使用,和ConfigMap一样也支持使用挂载整个存储卷、只挂载存储卷中的指定键值以及独立挂载存储卷中的单个键值等使用方式。
apiVersion: apps/v1
kind: Deployment
metadata:
name: secret-volume-demo
spec:
replicas: 1
selector:
matchLabels:
app: secret-volume-demo
template:
metadata:
labels:
app: secret-volume-demo
spec:
containers:
- name: centos
image: centos:7.8.2003
command: ["/bin/sh", "-c", "sleep 3600"]
volumeMounts:
- name: certs
mountPath: /etc/certs/
volumes:
- name: certs
secret:
secretName: k8s-cert
进入Pod查看文件验证