主要用于工作便利
ConfigMap 创建 1 2 3 4 5 ## 命令式参数创建ConfigMap kubectl create configmap configmap_name --from-literal=key-1=value-1 … ## 命令行加载文件创建ConfigMap,键名即为文件的基名,“|”是键名及多行键值的分割符,多行键值要进行固定缩进 kubectl create configmap nginx-confs --from-file=./nginx-conf.d/myserver.conf --from-file=status.cfg=./nginx-conf.d/myserver-status.cfg
通过环境变量引用ConfigMap键值 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 apiVersion: v1 kind: ConfigMap metadata: name: demoapp-config data: demoapp.port: "8080" demoapp.host: 0.0.0.0 --- apiVersion: v1 kind: Pod metadata: name: configmaps-env-demo spec: containers: - image: xxx/xxx 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
ConfigMap存储卷 基于configMap卷插件关联至Pod资源上的ConfigMap对象可由内部的容器挂载为一个目录,该ConfigMap对象的每个键名将转为容器挂载点路径下的一个文件名,键值则映射为相应文件的内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 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: false
ResourceQuota ResourceQuota资源能够定义名称空间级别的资源配额,从而在名称空间上限制聚合资源消耗的边界,它支持以资源类型为类型来限制用户可在本地名称空间中创建的相关资源类型的对象数量,以及这些对象可消耗的计算资源总量等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 apiVersion: v1 kind: ResourceQuota metadata: name: resourcequota-demo spec: hard: pods: "5" count/services: "5" count/configmaps: "5" count/secrets: "5" count/cronjobs.batch: "2" requests.cpu: "2" requests.memory: "4Gi" limits.cpu: "4" limits.memory: "8Gi" count/deployments.apps: "2" count/statefulsets.apps: "2" persistentvolumeclaims: "6" requests.storage: "20Gi"
1 kubectl describe resourcequotas/resourcequota-demo
Secret 根据其存储格式及用途的不同,Secret对象会划分为如下三种大的类别。
generic:基于本地文件、目录或字面量值创建的Secret,一般用来存储密码、密钥、信息、证书等数据;
docker-registry:专用于认证到Docker Registry的Secret,以使用私有容器镜像;
tls:基于指定的公钥/私钥对创建TLS Secret,专用于TLS通信中;指定公钥和私钥必须事先存在,公钥证书必须采用PEM编码,且应该与指定的私钥相匹配;
1 2 3 4 5 6 7 8 9 ## generic kubectl create secret generic mysql-root-authn --from-literal=username=root --from-literal=password=xxxxxx ## tls openssl rand -writerand $HOME/.rnd kubectl create secret tls nginx-ssl-secret --key=./nginx.key --cert=./nginx.crt ## docker-registry kubectl create secret docker-registry local-registry --docker-username=Ops --docker-password=Opspass --docker-email=123@qq.com
Secret存储卷 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 apiVersion: v1 kind: Pod metadata: name: secrets-volume-demo spec: containers: - image: nginx:alpine name: ngxserver volumeMounts: - name: nginxcerts mountPath: /etc/nginx/certs/ readOnly: true - name: nginxconfs mountPath: /etc/nginx/conf.d/ readOnly: true volumes: - name: nginxcerts secret: secretName: nginx-ssl-secret - name: nginxconfs configMap: name: nginx-sslvhosts-confs optional: false
存活探针\就绪探针 容器exec存活探针 1 2 3 4 5 6 7 8 9 10 11 12 13 14 apiVersion: v1 kind: Pod metadata: name: liveness-exec-demo spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent livenessProbe: exec: command: ['/bin/sh', '-c', '[ "$(curl -s 127.0.0.1/livez)" == "OK" ]'] initialDelaySeconds: 5 periodSeconds: 5
1 2 ## 手动将/livez的响应内容修改为OK之外的其他值,例如FAIL,以便于测试健康探针失败的后果 kubectl exec liveness-exec-demo -- curl -s -X POST -d 'livez=FAIL' 127.0.0.1/livez
容器httpGet存活探针 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 apiVersion: v1 kind: Pod metadata: name: liveness-httpget-demo spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent livenessProbe: httpGet: path: '/livez' # 请求的主机地址,默认为pod IP;也可以在httpHeaders使用“Host: ”来定义 port: 80 # 请求的端口,必选字段 scheme: HTTP # 建立连接使用的协议,仅可为HTTP或HTTPS,默认为HTTP initialDelaySeconds: 5
1 2 ## 为了测试存活状态检测的效果,同样可以手动将/livez的响应内容修改为OK之外的其他值,例如FAIL。 kubectl exec liveness-httpget-demo -- curl -s -X POST -d 'livez=FAIL' 127.0.0.1/livez
容器tcpSocket存活探针 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 apiVersion: v1 kind: Pod metadata: name: liveness-tcpsocket-demo spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 securityContext: capabilities: add: - NET_ADMIN livenessProbe: tcpSocket: port: http periodSeconds: 5 initialDelaySeconds: 20
1 2 ## 为了测试效果,可使用下面的命令在Pod的Network名称空间中设置iptables规则以阻止对80端口的请求 kubectl exec liveness-tcpsocket-demo -- iptables -A INPUT -p tcp --dport 80 -j REJECT
容器的httpGet就绪探针 就绪状态探测是用来判断容器应用就绪与否周期性(默认周期为10秒钟)操作,它用于探测容器是否已经初始化完成并可服务于客户端请求。与存活探针触发的操作不同,探测失败时,就绪探针不会杀死或重启容器来确保其健康状态,而仅仅是通知其尚未就绪,并触发依赖于其就绪状态的其他操作(例如从Service对象中移除此Pod对象)以确保不会有客户端请求接入此pod对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 apiVersion: v1 kind: Pod metadata: name: readiness-httpget-demo spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent readinessProbe: httpGet: path: '/readyz' port: 80 scheme: HTTP initialDelaySeconds: 15 timeoutSeconds: 2 periodSeconds: 5 failureThreshold: 3 restartPolicy: Always
1 2 ## 为了测试就绪状态探测效果,下面修改/readyz响应以非‘OK’内容。 kubectl exec readiness-httpget-demo -- curl -s -X POST -d 'readyz=FAIL' 127.0.0.1/readyz
preStart和postStop钩子 容器生命周期钩子使它能够感知其自身生命周期管理中的事件,并在相应的时刻到来时运行由用户指定的处理程序代码。kubernetes为容器提供了PostStart和PreStop两种生命周期挂钩。postStart和preStop处理器定义在容器的lifecycle字段中,其内部一次仅支持嵌套使用一种处理器类型。
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 apiVersion: v1 kind: Pod metadata: name: lifecycle-demo spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent securityContext: capabilities: add: - NET_ADMIN livenessProbe: httpGet: path: '/livez' port: 80 scheme: HTTP initialDelaySeconds: 5 lifecycle: postStart: exec: command: ['/bin/sh','-c','iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-ports 80'] preStop: exec: command: ['/bin/sh','-c','while killall python3; do sleep 1; done'] restartPolicy: Always
Deployment 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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 apiVersion: apps/v1 kind: Deployment metadata: name: deployment-demo spec: strategy: # 自定义更新策略; rollingUpdate: maxSurge: 1 # 允许超出期望值1个; maxUnavailable: 0 # 不允许低于期望值; type: RollingUpdate replicas: 4 selector: matchLabels: app: demoapp release: stable template: metadata: labels: app: demoapp release: stable spec: containers: - name: demoapp image: ikubernetes/demoapp:v1.1 ports: - containerPort: 80 name: http livenessProbe: httpGet: path: '/livez' port: 80 initialDelaySeconds: 5 readinessProbe: httpGet: path: '/readyz' port: 80 initialDelaySeconds: 15 --- apiVersion: v1 kind: Service metadata: name: demoapp spec: type: ClusterIP selector: # 将发往该服务的请求流量调度至由replicaset-demo管控的Pod副本之上; app: demoapp release: stable ports: - name: http port: 80 protocol: TCP targetPort: 80
1 2 3 4 5 ## 创建一个临时的客户端Pod以发起持续性的请求测试,以验证单批次更新过程中是否会发生服务中断 kubectl run pod-$RANDOM --image=ikubernetes/admin-box:v1.2 -it --restart=Never --rm --command -- /bin/bash ## 临时Pod的交互式接口中运行如下循环进行请求测试 while true; do curl --connect-timeout 1 demoapp; sleep .5; done
Job 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 apiVersion: batch/v1 kind: Job metadata: name: job-demo spec: template: spec: containers: - name: myjob image: ikubernetes/admin-toolbox:v1.0 imagePullPolicy: IfNotPresent command: ["/bin/sh", "-c", "sleep 60"] restartPolicy: Never completions: 3 ttlSecondsAfterFinished: 3600 # Job的留存时长,超过该时长将被自动删除; backoffLimit: 3 # 将作业标记为失败状态之前的重试次数,默认值为6; activeDeadlineSeconds: 300 # Job的最大活动时长,超过该时长仍未成功结束时将被标记为失败;
1 2 ## 动态修改Job资源的作业并行度,改变parallelism属性的值提升作业并行度即可实现Job资源扩容之目的 kubectl patch jobs/job-para-demo -p '{"spec":{"parallelism":5}}'
Cronjob 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 apiVersion: batch/v1beta1 kind: CronJob metadata: name: cronjob-demo spec: schedule: "*/2 * * * *" jobTemplate: metadata: labels: app: mycronjob-jobs spec: parallelism: 1 completions: 1 ttlSecondsAfterFinished: 3600 backoffLimit: 3 activeDeadlineSeconds: 60 template: metadata: labels: app: cronjob-demo-pod spec: containers: - name: myjob image: "ikubernetes/admin-toolbox:v1.0" command: - /bin/sh - -c - date; echo Hello from CronJob, sleep a while…; sleep 10; restartPolicy: OnFailure startingDeadlineSeconds: 300
由CronJob资源通过模板创建的Job对象的名称以CronJob自身的名称为前缀,以Job创建时的时间戳为后缀,而各Job对象相关的Pod对象的名称则随机生成。已完成的CronJob资源相关Pod的状态为Completed,而失败的作业状态则存在RunContainerError、CrashLoopBackOff 或其他表示失败的状态。
1 2 3 4 ## 下面的命令将会得到几个已经完成的作业的Pod $ kubectl get pods | awk '/^cronjob-demo/{print $0}' cronjob-demo-1624409400-nm5wx 0/1 Completed 0 38s
自Kubernetes v1.21版开始,由CronJob资源通过模板创建的Job对象的名称以CronJob自身的名称为前缀,以Job创建时的时间戳和5个随机字符为后缀。
DNS Kubernetes支持如下DNS解析策略,它们定义在spec.dnsPolicy字段上。
Default:从运行在的节点继承DNS名称解析相关的配置;
ClusterFirst:于集群DNS服务上解析集群域内的名称,其他域名的解析则交由从节点继承而来的上游名称服务器;
ClusterFirstWithHostNet:专用于在设置了hostNetwork的Pod对象上使用的ClusterFirst策略,任何配置了hostNetwork的Pod对象都应该显式使用该策略;
None:用于忽略Kubernetes集群的默认设定,而仅使用由dnsConfig自定义的配置;
Pod资源的自定义DNS配置要通过嵌套于spec.dnsConfig字段中
nameservers <[]string>:DNS名称服务器列表,它附加于由dnsPolicy生成的DNS名称服务器之后;
searches <[]string>:DNS名称解析时的搜索域,它附加由于dnsPolicy生成的搜索域之后;
options <[]Object>:DNS解析选项列表,它将会同dnsPolicy生成的解析选项合并成最终生效的定义;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 apiVersion: v1 kind: Pod metadata: name: pod-with-customed-dnspolicy spec: containers: - name: demo image: ikubernetes/demoapp:v1.0 imagePullPolicy: IfNotPresent dnsPolicy: None dnsConfig: nameservers: - 172.21.0.10 searches: - svc.cluster.local - cluster.local options: - name: ndots value: "5"
Service External Service Kubernetes将那些ClusterIP字段值为“None”的Service资源称为Headless Service,该类Service的请求流量无须kube-proxy处理,也不会有负载均衡和路由相关的iptables或ipvs规则。至于ClusterDNS如何自动配置Headless Service,则取决于Service标签选择器的定义。
配置有标签选择器:由端点控制器自动创建与Service同名的Endpoint资源,而ClusterDNS则将Service名称的A记录直接解析为后端各端点的IP而非ClusterIP;
无标签选择器: ClusterDNS的配置分为两种情形:对ExternalName类型的服务(配置了spec.externalName字段)创建CNAME记录,而对于存在与该Service同名的Endpoint对象上的每个端点创建一个A记录。
通常,我们把无标签选择器的第一种情形(使用CNAME记录)的Headless Service当作一种独立的Service类型使用,即ExternalName Service,而将那些把Service名称使用A记录解析为端点IP地的情况则统一称为Headless Service。
ExternalName Service是一种特殊类型的Service资源,它不需要使用标签选择器关联任何的Pod对象,也无须定义任何端口或Endpoints,但必须要使用spec.externalName属性定义一个CNAME记录用于返回真正提供服务的服务名称的别名。
1 2 3 4 5 6 7 8 9 10 11 12 kind: Service apiVersion: v1 metadata: name: externalname spec: type: ExternalName externalName: www.xxx.com ports: - protocol: TCP port: 80 targetPort: 80 selector: {}
Headless Service 除了为每个Service资源对象在创建时自动指派一个遵循..svc.格式的DNS名称,ClusterDNS还会为Headless Service中的每个端点指派一个遵循...svc.格式的DNS名称。定义Service资源时,只需要将其ClusterIP字段的值显式设置为None即可将其定义为Headless 类型
1 2 3 4 5 6 7 8 9 10 11 12 kind: Service apiVersion: v1 metadata: name: demoapp-headless-svc spec: clusterIP: None selector: app: demoapp ports: - port: 80 targetPort: 80 name: http
1 2 3 4 5 6 7 8 ## 开启一个pod kubectl run pod-$RANDOM --image="ikubernetes/admin-box:v1.2" --restart=Never --rm -it --command -- /bin/bash ## Headless Service的名称会解析为其后端各端点的IP地址。 nslookup -query=A demoapp-headless-svc ## 而各端点的IP地址,将反解为端点自己的名称标识,每个端点将拥有独立的标识,格式为“<hostname>.<service>.<namespace>.svc.cluster.local”。 for ip in $(host -t A demoapp-headless-svc | awk '{print $4}'); do host -t PTR $ip; done
Exit Code 1 2 3 Last State: Terminated Reason: Error Exit Code: 137
退出码为137的错误信息,它表示进程是被外部信号所终止。137事实上由两部分数字之和生成:128+signum,其中signum是导致进程终止的信号的数字标识,9表示SIGKILL,这意味着进程是被强行终止。