Infrastructure Container 基础容器
维护整个Pod网络空间
InitContainers 初始化容器
先于业务容器运行
Container 业务容器
并行启动
查看默认镜像拉取参数是否是IfNotPresent
1 | kubectl get deploy/nginx-deployment -o yaml |

没有认证的公共镜像仓库可以直接拉取,搭建私有镜像仓库Habor
本次搭建的主机为192.168.1.61,之前使用改主机搭建了nginx+keepalived为了不冲突需要关闭该主机的nginx即使用192.168.1.62来产生VIP192.168.1.60
搭建参考
https://www.cnblogs.com/minseo/p/8905736.html
登录Harbor创建一个私有项目project
默认用户名:admin 密码:Habor123456



私有仓库需要登录才能下载,Harbor不是http提供访问,需要在node 192.168.1.65 192.168.1.66配置可信任
1 2 3 4 5 | # cat /etc/docker/daemon.json{ "registry-mirrors": ["https://7sl94zzz.mirror.aliyuncs.com"], "insecure-registries": ["192.168.1.61"]} |
node上面登录,输入用户名和密码
1 | docker login 192.168.1.61 |

查看该node已有的镜像
1 | docker images |
下载一个tomcat镜像用于推送测试
1 | docker pull tomcat |
下载完毕打tag
1 | docker tag tomcat 192.168.1.61/project/tomcat |
查看

推送至harbor私有仓库
1 | docker push 192.168.1.61/project/tomcat |

推送成功在harbor上可以看到

排错,推送是出现提示,查看haabor该项目是否创建
1 | requested access to the resource is denied |
在另外一台node上拉取该镜像
1 | docker pull 192.168.1.61/project/tomcat |
PS:需要在该node节点至少登录过一次才能下载,否则会出现如下提示
1 2 3 | docker pull 192.168.1.61/project/tomcatUsing default tag: latestError response from daemon: pull access denied for 192.168.1.61/project/tomcat, repository does not exist or may require 'docker login': denied: requested access to the resource is denied |
推送至harbor的镜像是私有的,如果是通过k8s部署则是拉取公网的镜像无法拉取到私有的镜像,需要通过配置imagePullSecrets参数才能从私有仓库拉取镜像
示例
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 | # cat tomcat-deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata: labels: run: tomcat name: tomcatspec: replicas: 3 selector: matchLabels: run: tomcat template: metadata: labels: run: tomcat spec: containers: - image: tomcat name: tomcat ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: labels: run: tomcat name: tomcat-servicespec: ports: - port: 8080 protocol: TCP targetPort: 8080 selector: run: tomcat type: NodePort |
该yaml配置文件可以通过以下命令生成
1 2 3 4 5 6 7 8 | #生成deployment配置文件 kubectl run tomcat --replicas=3 --image=tomcat --port=8080 --dry-run -o yaml>>tomcat-deployment2.yaml#间隔符 多个配置需要间隔,否则创建时候部分不生效echo "---" >>tomcat-deployment2.yaml#生成service配置文件#生成该配置文件需要指定的deployment已经在运行中即要允许了命令 kubectl run tomcat --replicas=3 --image=tomcat --port=8080#可以先运行再删除该deploymentkubectl expose deployment tomcat --port=8080 --type=NodePort --target-port=8080 --name=nginx-service --dry-run -o yaml >> tomcat-deployment.yaml |
使用配置文件创建deployment和service
1 2 3 | # kubectl create -f tomcat-deployment.yamldeployment.apps/tomcat createdservice/tomcat-service created |
查看
1 2 3 4 5 6 7 8 9 | # kubectl get pod,svcNAME READY STATUS RESTARTS AGEpod/tomcat-5d6455cc4-lpwht 1/1 Running 0 36spod/tomcat-5d6455cc4-wnfsh 1/1 Running 0 36spod/tomcat-5d6455cc4-zgvbp 1/1 Running 0 36sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/kubernetes ClusterIP 10.10.10.1 <none> 443/TCP 6d2hservice/tomcat-service NodePort 10.10.10.105 <none> 8080:37426/TCP 36s |
通过node ip加NodePort端口即可访问tomcat默认页面
配置文件指定镜像是从docker hub拉取的,现在改成私有镜像的地址,因为默认的策略是优先拉取本机已有镜像所以拉取镜像策略改成Always
修改yaml配置文件,修改以下两处

应用更新
1 2 3 | # kubectl apply -f tomcat-deployment.yamldeployment.apps/tomcat configuredservice/tomcat-service unchanged |

查看pod事件
1 | kubectl describe pod tomcat-78876547c6-jn7c4 |

需要配置凭据才能拉取
在已经docker login过的node上面获取
1 | cat /root/.docker/config.json | base64 -w0 |

复制这串字符编辑配置文件
1 2 3 4 5 6 7 8 | #cat registry-pull-secret.yamlapiVersion: v1kind: Secretmetadata: name: registry-pull-secretdata: .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEuNjEiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2VyLUFnZW50IjogIkRvY2tlci1DbGllbnQvMTkuMDMuNiAobGludXgpIgoJfQp9type: kubernetes.io/dockerconfigjson |
应用
1 2 | # kubectl create -f registry-pull-secret.yamlsecret/registry-pull-secret created |
查看已经生成secret
1 2 3 4 | # kubectl get secretNAME TYPE DATA AGEdefault-token-pw8st kubernetes.io/service-account-token 3 6d2hregistry-pull-secret kubernetes.io/dockerconfigjson 1 22s |
修改tomcat-deployment.yaml增加认证

修改后完整的yaml文件如下
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 | # cat tomcat-deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata: labels: run: tomcat name: tomcatspec: replicas: 3 selector: matchLabels: run: tomcat template: metadata: labels: run: tomcat spec: imagePullSecrets: - name: registry-pull-secret containers: - image: 192.168.1.61/project/tomcat imagePullPolicy: Always name: tomcat ports: - containerPort: 8080---apiVersion: v1kind: Servicemetadata: labels: run: tomcat name: tomcat-servicespec: ports: - port: 8080 protocol: TCP targetPort: 8080 selector: run: tomcat type: NodePort |
应用更改
1 | kubectl apply -f tomcat-deployment.yaml |
查看
1 2 3 4 5 6 7 8 9 | # kubectl get pod,svcNAME READY STATUS RESTARTS AGEpod/tomcat-68c76b858d-5lq22 1/1 Running 0 4m41spod/tomcat-68c76b858d-ckrqr 1/1 Running 0 4m45spod/tomcat-68c76b858d-dctgt 1/1 Running 0 4m43sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/kubernetes ClusterIP 10.10.10.1 <none> 443/TCP 6d3hservice/tomcat-service NodePort 10.10.10.105 <none> 8080:37426/TCP 29m |
因为镜像拉取策略是Always所以从pod的运行时间即可看出是否拉取了私有仓库的镜像
登录Harbor查看也可以看到本次拉取镜像是从私有仓库拉取


拍错:访问tomcat出现404错误提示,原因是tomcat镜像根目录没有文件,解决办法
1 2 3 4 5 6 7 8 | #分别进入容器kubectl exec -it tomcat-68c76b858d-5lq22 -c tomcat bashkubectl exec -it tomcat-68c76b858d-ckrqr -c tomcat bashkubectl exec -it tomcat-68c76b858d-dctgt -c tomcat bash#复制根目录文件,默认webapps为空cd /usr/local/tomcatrm -rf webappsmv webapps.dist/ webapps |
为了防止某个Pod占用资源过多影响宿主机需要对Pod进行资源限制
Pod中的每个容器都可以指定一下一个或者多个值
1 2 3 4 | spec.containers[].resources.limits.cpuspec.containers[].resources.limits.memoryspec.containers[].resources.requests.cpuspec.containers[].resources.requests.memory |
示例,该示例可以在官方复制https://kubernetes.io/zh/docs/concepts/configuration/manage-compute-resources-container/
以下 Pod 有两个容器。每个容器的请求为 0.25 cpu 和 64MiB(226 字节)内存,每个容器的限制为 0.5 cpu 和 128MiB 内存。您可以说该 Pod 请求 0.5 cpu 和 128 MiB 的内存,限制为 1 cpu 和 256MiB 的内存。
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 | # cat pod2.yamlapiVersion: v1kind: Podmetadata: name: frontendspec: containers: - name: db image: mysql env: - name: MYSQL_ROOT_PASSWORD value: "password" resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" - name: wp image: wordpress resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" |
查看该pod分配到那一台node
1 | kubectl describe pod frontend |

查看资源限制是否生效
1 | kubectl describe nodes 192.168.1.66 |

restartPolicy
查看
1 | kubectl edit pods nginx-7cdbd8cdc9-ngpgr |

示例
1 2 3 4 5 6 7 8 9 10 11 12 13 | # cat pod3.yamlapiVersion: v1kind: Podmetadata: name: foospec: containers: - name: busybox image: busybox args: - /bin/sh - -c - sleep 30 ; exit 3 |
该yaml执行进入容器后等待30秒退出
应用
1 | kubectl apply -f pod3.yaml |
查看pod会从running状态,到退出会提示错误状态,因为策略是Always所以又重启一次


修改
1 2 3 4 5 6 7 8 9 10 11 12 13 | apiVersion: v1kind: Podmetadata: name: foospec: containers: - name: busybox image: busybox args: - /bin/sh - -c - sleep 10 restartPolicy: Never |
删除再应用
1 2 | kubectl delete -f pod3.yamlkubectl apply -f pod3.yaml |
查看状态,容器运行10秒以后正常退出了,策略为Never所以不再新启动一个pod 状态显示完成状态

Probe有以下两种类型
livenessProbe
如果检查失败,将杀死容器,根据Pod的restartPolicy来操作
readinessProbe
如果检查失败,Kubernetes会把Pod从service endpoint中剔除
查看endpoint使用命令
1 2 3 4 | # kubectl get epNAME ENDPOINTS AGEkubernetes 192.168.1.63:6443,192.168.1.64:6443 6d4htomcat-service 172.17.41.4:8080,172.17.55.2:8080,172.17.55.5:8080 131m |
Probe支持以下三种检查方法
HttpGet
发送HTTP请求,返回200-400范围状态码为成功
exec
执行shell命令返回状态码是0为成功
tcpSocket
发起TCP Socket建立成功
官方示例 下载地址https://kubernetes.io/zh/docs/concepts/configuration/manage-compute-resources-container/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | apiVersion: v1kind: Podmetadata: labels: test: liveness name: liveness-execspec: containers: - name: liveness image: busybox args: - /bin/sh - -c - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy livenessProbe: exec: command: - cat - /tmp/healthy #启动延时5秒以后开始健康检查 initialDelaySeconds: 5 #健康检查周期是5秒 periodSeconds: 5 |
应用
1 | kubectl apply -f pod4.yaml |
启动后创建了健康检查文件,等待30秒以后,删除了健康检查文件,健康检查没有发现该文件就重启容器了

查看pod的描述日志

企业生产环境中需要配置健康检查
可以让Pod放在指定节点上,例如A部门创建的Pod放在一台node,B部门创建的Pod放在另一台node
用户创建Pod过程

nodeName用于将Pod调度到指定的Node名称上
nodeSelector用于将Pod调度到匹配Label的Node上
1 2 3 4 5 6 7 8 9 10 11 12 | #cat pod5.yamlapiVersion: v1kind: Podmetadata: name: pod-example labels: app: nginxspec: nodeName: 192.168.1.65 containers: - name: nginx image: nginx |

设置标签
1 2 3 4 5 | #设置标签kubectl label nodes 192.168.1.65 team=akubectl label nodes 192.168.1.66 team=b#查看标签kubectl get nodes --show-labels |
删除标签
1 2 3 | #在标签后加-号即可删除标签kubectl label nodes 192.168.1.65 team-kubectl label nodes 192.168.1.66 team- |

在yaml文件里面设置标签
1 2 3 4 5 6 7 8 9 10 11 12 13 | # cat pod6.yamlapiVersion: v1kind: Podmetadata: name: pod-example labels: app: nginxspec: nodeSelector: team: b containers: - name: nginx image: nginx |
应用
1 | kubectl apply -f pod6.yaml |
查看


PS:如果调度约束配置不正确Pod会出现Pending状态查看描述会出现以下错误提示
1 | Warning FailedScheduling 27s (x2 over 27s) default-scheduler 0/2 nodes are available: 2 node(s) didn't match node selector. |
| 值 | 描述 |
| Pending | Pod创建已经提交k8s,但是因为,某种原因不能顺利创建。例如下载镜像慢,调度不成功 |
| Running | Pod已经绑定到一个节点,并且已经创建了所有容器。至少有一个容器在运行,或正在启动或重启 |
| Suceeded | Pod中所有容器都已成功终止,不会重新启动 |
| Failed | Pod中所有容器已终止,且至少有一个容器已在故障中终止,也就是说,容器要么已非零状态退出,要么被系统终止 |
| Unknown | 由于某种原因apiserver无法获取Pod的状态,通常是由于master与pod所在主机kubelet通信时出错 |
故障排查命令
1 2 3 4 5 6 | #查看pod事件kubectl describe TYPE/NAME#查看pod日志kubectl logs TYPE/NAME#登录容器查看kubectl exec POD [-c CONTAINER] -- COMMAND [args...] |