Pod是k8s上运行容器化应用及调度的最小原子单元,同一个Pod内可以运行多个容器,这些容器之间共享IPC、UTS和Network名称空间,并能够访问同一组存储卷。
Pod的资源规范文件如下:
apiVersion: v1
kind: Pod
metadata:
name: > #Pod名称
namespace: > #Pod所属名称空间
labels: #Pod的标签
label-key: label-value
annotations: #Pod注解信息
key: value
spec:
containers:#Pod中的容器信息,列表
- name: > #容器名称
image: > #容器镜像
imagePullPolicy: > #镜像拉取策略
ports: <[]Object> #声明容器暴露的端口
volumeMounts: <[]Object> #卷挂载信息
initContainers: <[]Object> #Pod中的初始化容器信息,格式同containers
volumes: <[]Object> #存储卷定义
上面仅列出了一些常用字段,更多字段信息可以参考官方文档:https://kubernetes.io/docs/concepts/workloads/pods/
示例,创建一个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
仅使用单Pod形式运行应用存在一些问题,需要用户手动执行一些操作,例如Pod规模伸缩,升级/回滚,Pod健康状态维护等,Pod控制器就是为了解决这些问题。Pod控制器是用于实现Pod管理的中间层,确保Pod资源符合预期的状态。
Pod控制器有多种类型:
相较于手动创建和管理Pod,ReplicaSet有以下优点:
ReplicaSet资源规范文件如下:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: ...
namespace: ...
spec:
replicas: > #期望的Pod副本数,默认为1
selector: #标签选择器,必须匹配template字段中Pod的标签
matchLabels:
示例,创建一个 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
Deployment的主要职责同样是确保Pod以期望状态运行,其大部分功能通过调用Replicaset实现,并添加了部分新特性:
Deployment的资源规范文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ...
namespace: ...
labels: ...
spec:
replicas: > #期望带外Pod数量
selector:
示例,创建一个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
Job控制器通常用于管理那些运行一段时间就可以结束的任务,例如计算或数据初始化等。容器中的进程正常退出后不需要重启,控制器会将该Pod置于Completed状态,并且会在用户指定的生存周期后被删除。如果容器中的进程非正常退出,则要根据Pod的重启策略来决定是否重启。
Job的资源规范文件如下:
apiVersion: batch/v1
kind: Job
metadata:
name: ...
namespace: ...
spec:
selector: > #标签选择器,用来匹配Pod
template: > #Pod模板
completions: > #期望成功运行的Pod数量,正常退出的Pod梳理
parallelism: > #任务的最大并行数,默认为1
ttlSecondsAfterFinished: > #终止状态的Pod的保存时长
activeDeadlineSeconds: > #任务启动后可以处于活动状态的时长
backoffLimit: > #将任务标记为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
CronJob用于管理Job资源的运行时间,可以指定在特定的时间或指定的间隔运行Job,它适合自动执行特定的任务,例如备份、清理类的任务和发送报告等。CronJob使用Job来完成任务,它每次运行都会创建一个Job并使用类似于Job资源的创建、管理和扩容方式。
CronJob的资源规范文件如下:
apiVersion: batch/v1
kind: CronJob
metadata:
name: ...
namespace: ...
spec:
jobTemplate: #Job资源模板
metadata: > #Job模板元数据
spec: > #Job的期望状态
schedule: > #调度时间设定,必选
concurrencyPolicy: > #并发策略,可用值有Allow、Forbid和Replace
failedJobsHistoryLimit: > #失败作业的历史记录数量,默认为1
successfulJobsHistoryLimit: > #成功作业的历史记录数量,默认为3
startingDeadlineSeconds: > #因错过时间点而未执行的作业的可超期时长
示例,创建一个名为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
Service是k8s的核心资源类型之一,它主要的作用是为一组Pod提供一个固定的访问入口。Service会把通过标签选择器筛选出的一组Pod定义成一个逻辑集合,并通过iptables或ipvs规则将请求转发给这组Pod。
本质上,一个Service对象就是节点上的一组iptables或ipvs规则,这些规则将访问Service对象ClusterIP+端口的流量转发至对应的后端Pod。每个节点上的kube-proxy就负责维护这些规则,kube-proxy通过API Server持续监视各Service对象及其关联得Pod对象,并将Service对象的创建或变动实时反应至当前节点上相应的iptales或ipvs规则中。
kube-proxy的代理模型有3种:
Service资源可根据其工作逻辑划分为4中类型:
Service的资源规范文件如下:
apiVersion: v1
kind: Service
metadata:
name: ...
namespace: ...
spec:
selector:
示例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
ConfigMap资源主要是用来存储配置数据,为Pod中的应用提供配置。一个ConfigMap就是一系列配置数据的集合,这些数据可以注入到Pod的容器内为应用提供配置信息,注入的方式主要有环境变量和存储卷两种形式。
创建ConfigMap可以通过命令行或者资源清单文件。
kubectl create configmap myconfig --from-literal=host=10.10.0.1 --from-literal=port=8080
kubectl create configmap static-file --from-file=test-file=./a.txt --from-file=./index.html
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有两种方式:
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
如果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资源可以通过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
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
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
Secret主要用来存储敏感数据,例如证书、密钥、ssh-key等,借助Secret,可以控制敏感数据的使用方式,减少暴露风险。
Secret也可以通过命令行和资源清单文件两种方式创建
和ConfigMap一样,创建Secret对象也支持直接使用键值创建、从文件创建和从目录创建。并且使用命令行创建时,可以将Secret分为3种类型:
generic类型secret
kubectl create secret generic secret-demo --from-literal=username=admin --from-literal=password=123456
docker-registry类型的Secret,创建此类型的secret需要指定下面3个选项:
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个字段:
apiVersion: v1
kind: Secret
metadata:
name: secret-basic-auth
stringData:
username: admin
password: Passw0rd
type: kubernetes.io/basic-auth
Pod通过环境变量方式引用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
关于挂载Secret中的所有键值对,可以参考:https://kubernetes.io/docs/concepts/configuration/secret/
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