Deployment为Pod和Replica Set下一代Replication Controller)提供声明式更新html
apiVersion: apps/v1 # 1.9.0 以前的版本使用 apps/v1beta2,可经过命令 kubectl api-versions 查看 kind: Deployment #指定建立资源的角色/类型 metadata: #资源的元数据/属性 name: nginx-deployment #资源的名字,在同一个namespace中必须惟一 namespace: xxxx #命名空间 labels: app: demo #标签 spec: replicas: 3 #副本数量3 strategy: rollingUpdate: ##因为replicas为3,则整个升级,pod个数在2-4个之间 maxSurge: 1 #滚动升级时会先启动1个pod maxUnavailable: 1 #滚动升级时容许的最大Unavailable的pod个数 selector: #定义标签选择器,部署须要管理的pod(带有该标签的的会被管理)需在pod 模板中定义 matchLabels: app: web-server template: #这里Pod的定义 metadata: labels: #Pod的label app: web-server spec: # 模板的规范 containers: - name: nginx #容器的名字 image: nginx:1.12.1 #容器的镜像地址 command: [ "/bin/sh","-c","cat /etc/config/path/to/special-key" ] #启动命令 args: #启动参数 - '-storage.local.retention=$(STORAGE_RETENTION)' - '-storage.local.memory-chunks=$(STORAGE_MEMORY_CHUNKS)' - '-config.file=/etc/prometheus/prometheus.yml' - '-alertmanager.url=http://alertmanager:9093/alertmanager' - '-web.external-url=$(EXTERNAL_URL)' #若是command和args均没有写,那么用Docker默认的配置。 #若是command写了,但args没有写,那么Docker默认的配置会被忽略并且仅仅执行.yaml文件的command(不带任何参数的)。 #若是command没写,但args写了,那么Docker默认配置的ENTRYPOINT的命令行会被执行,可是调用的参数是.yaml中的args。 #若是若是command和args都写了,那么Docker默认的配置被忽略,使用.yaml的配置。 imagePullPolicy: IfNotPresent # IfNotPresent :默认值,本地有则使用本地镜像,不拉取,若是不存在则拉取 # Always: 老是拉取 # Never: 只使用本地镜像,从不拉取 livenessProbe: #表示container是否处于live状态。若是LivenessProbe失败,LivenessProbe将会通知kubelet对应的container不健康了。随后kubelet将kill掉container,并根据RestarPolicy进行进一步的操做。默认状况下LivenessProbe在第一次检测以前初始化值为Success,若是container没有提供LivenessProbe,则也认为是Success; httpGet: path: /health #若是没有心跳检测接口就为/ port: 8080 scheme: HTTP initialDelaySeconds: 60 ##启动后延时多久开始运行检测 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 readinessProbe: readinessProbe: httpGet: path: /health #若是没有心跳检测接口就为/ port: 8080 scheme: HTTP initialDelaySeconds: 30 ##启动后延时多久开始运行检测 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 resources: ##CPU内存限制 requests: cpu: 2 memory: 2048Mi limits: cpu: 2 memory: 2048Mi env: ##经过环境变量的方式,直接传递pod=自定义Linux OS环境变量 - name: LOCAL_KEY #本地Key value: value - name: CONFIG_MAP_KEY #局策略可以使用configMap的配置Key, valueFrom: configMapKeyRef: name: special-config #configmap中找到name为special-config key: special.type #找到name为special-config里data下的key ports: - name: http containerPort: 8080 #对service暴露端口 volumeMounts: #挂载volumes中定义的磁盘 - name: log-cache mount: /tmp/log - name: sdb #普通用法,该卷跟随容器销毁,挂载一个目录 mountPath: /data/media - name: nfs-client-root #直接挂载硬盘方法,如挂载下面的nfs目录到/mnt/nfs mountPath: /mnt/nfs - name: example-volume-config #高级用法第1种,将ConfigMap的log-script,backup-script分别挂载到/etc/config目录下的一个相对路径path/to/...下,若是存在同名文件,直接覆盖。 mountPath: /etc/config - name: rbd-pvc #高级用法第2中,挂载PVC(PresistentVolumeClaim) #使用volume将ConfigMap做为文件或目录直接挂载,其中每个key-value键值对都会生成一个文件,key为文件名,value为内容, volumes: # 定义磁盘给上面volumeMounts挂载 - name: log-cache emptyDir: {} - name: sdb #挂载宿主机上面的目录 hostPath: path: /any/path/it/will/be/replaced - name: example-volume-config # 供ConfigMap文件内容到指定路径使用 configMap: name: example-volume-config #ConfigMap中名称 items: - key: log-script #ConfigMap中的Key path: path/to/log-script #指定目录下的一个相对路径path/to/log-script - key: backup-script #ConfigMap中的Key path: path/to/backup-script #指定目录下的一个相对路径path/to/backup-script - name: nfs-client-root #供挂载NFS存储类型 nfs: server: 10.42.0.55 #NFS服务器地址 path: /opt/public #showmount -e 看一下路径 - name: rbd-pvc #挂载PVC磁盘 persistentVolumeClaim: claimName: rbd-pvc1 #挂载已经申请的pvc磁盘
一个典型的用例以下:
使用Deployment来建立ReplicaSet。ReplicaSet在后台建立pod。检查启动状态,看它是成功仍是失败。
而后,经过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。这会建立一个新的ReplicaSet,Deployment会按照控制的速率将pod从旧的ReplicaSet移动到新的ReplicaSet中。
若是当前状态不稳定,回滚到以前的Deployment revision。每次回滚都会更新Deployment的revision。
扩容Deployment以知足更高的负载。
暂停Deployment来应用PodTemplateSpec的多个修复,而后恢复上线。
根据Deployment 的状态判断上线是否hang住了。
清除旧的没必要要的ReplicaSetnode
建立deploymentmysql
kubectl create -f nginx-deployment.yaml --record ##--record 为True 在annotation中记录当前命令建立或者升级了该资源,如查看在每一个Deployment revision中执行了哪些命令 kubectl get deployments kubectl get rs #Replica Set的名字老是<Deployment的名字>-<pod template的hash值> kubectl get pods -n xxxx #命名空间 kubectl get pods --show-labels #查看标签
更新deployment
注意: Deployment的rollout当且仅当Deployment的pod template(例如.spec.template)中的label更新或者镜像更改时被触发。其余更新,例如扩容Deployment不会触发rollout.nginx
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 #更新镜像 或使用edit命令来编辑Deployment,修改 .spec.template.spec.containers[0].image ,将nginx:1.7.9 改写成 nginx:1.9.1 kubectl edit deployment/nginx-deployment kubectl rollout status deployment/nginx-deployment #rollout状态
回退deploymentweb
kubectl describe deployment #查看状态 kubectl rollout history deployment/nginx-deployment #检查升级记录 kubectl rollout history deployment/nginx-deployment --revision=2 #查看version信息
暂停和恢复redis
kubectl get deploy
kubectl rollout pause deployment/nginx-deployment kubectl set image deploy/nginx nginx=nginx:1.9.1 kubectl rollout history deploy/nginx
service 的做用
防止Pod失去联系(服务发现)
定义一组Pod的访问策略(负载均衡)
支持ClusterIP,NodePort以及LoadBalancer三种类型
Service的底层实现主要有iptables和ipvs两种网络模式算法
pod 与service的关系
经过lable-selector相关联
经过Service实现Pod的负载均衡(TCP/UDP 4层)sql
[root@k8s-master-128 dome]# cat deploy-nginx.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: # 这里是定义Deployment的标签 app: nginx spec: replicas: 3 selector: matchLabels: app: nginx # 选择关联Deployment标签 template: metadata: labels: # 给Pod定义一个标签,方便其余服务关联这个Pod app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: # Service 的selector 指定标签 app:nginx 来进行对Pod进行关联 ;(这里的app:nginx就是上面Deployment配置里labels定义的标签 ) app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: NodePort
发布的服务类型有三种:ClusterIP、NodePort和LoadBalancer
官网地址:https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-typesdocker
分配一个内部集群IP地址,只能在集群内部访问(同Namespaces内的Pod),不对外提供访问服务!默认ServiceTpye
kubectl get svc 暴露的集群ip和集群端口,只能在k8s集群内部访问
Node节点上能查看到建立的iptables规则shell
分配一个内网集群IP地址,并在内个节点上启用一个端口来暴露服务,能够在集群外部访问
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: MyApp ports: - protocol: TCP port: 80 # 须要暴露的集群端口(service暴露的) targetPort: 9376 # 容器的端口(后端容器提供服务的端口) nodePort: 30000 type: NodePort
映射到物理机的端口范围为:The range of valid ports is 30000-32767
kubectl get svc -o wide 暴露的端口在node 节点上由kube-proxy来启动并监听的,可经过NodeIP+端口的方式直接进行访问,由于kube-proxy进行了代理。
kube-proxy是如何代理访问到容器的呢?由于kube-proxy在启动的时候经过--proxy-mode=ipvs能够指定底层内核代理模式,默认是iptables进行代理转发,kube-proxy经过这两种模式来代理直接对外提供服务
参考的写法
apiVersion: v1 kind: Pod metadata: name: eureka labels: ccb: eureka spec: containers: - name: test-container image: eureka ports: - name: eureka containerPort: 8082 protocol: TCP imagePullPolicy: Never volumeMounts: - name: appconfig mountPath: /jar/application.yml subPath: application.yml volumes: - name: appconfig configMap: name: insight-application items: - key: registry-application.yml path: application.yml restartPolicy: Never --- apiVersion: v1 kind: Service metadata: name: eureka labels: ccb: eureka spec: ports: - port: 8082 targetPort: 8082 protocol: TCP nodePort: 30000 type: NodePort selector: ccb: eureka
分配一个内部集群IP地址,并在每一个节点上启用一个端口来暴露服务。
除此以外,Kubernetes会请求底层云平台上的负载均衡器,将每一个Node([NodeIP]:[NodePort])做为后端添加进去。
LoadBalancer只适用于云平台,AWS默认就支持,阿里云社区开发也支持
service有三组代理模式:userspace、iptables和ipvs
kubectl get svc -o wide kubectl describe pod nginx-deployment-6dd86d77d-kxkmt #注意命名空间
来源:https://nicksors.cc/2019/06/21/kubernetes%E7%B3%BB%E5%88%97%E4%B9%8B%E3%80%8AService%E3%80%8B.html
apiVersion: v1 kind: Pod metadata: name: eureka labels: ccb: eureka spec: containers: - name: test-container image: eureka ports: - name: eureka containerPort: 8082 protocol: TCP imagePullPolicy: Never #使用本地镜像 volumeMounts: - name: appconfig mountPath: /jar/application.yml subPath: application.yml volumes: - name: appconfig configMap: name: insight-application items: - key: registry-application.yml path: application.yml restartPolicy: Never --- apiVersion: v1 kind: Service metadata: name: eureka labels: ccb: eureka spec: ports: - port: 8082 #集群开放的的端口 targetPort: 8082 #后端容器开放的端口 protocol: TCP nodePort: 30000 #宿主机开放的端口,范围大于30000 type: NodePort #指定service类型为暴露物理节点的端口,必须 selector: ccb: eureka #service 管理的pod
用户经过kubectl命令建立一个Pod的流程:
客户端提交建立请求,能够经过API Server的Restful API,也可使用kubectl工具,支持json和yaml格式;
Api Server处理用户请求,存储Pod信息数据到etcd集群中;
Scheduler调度器经过API Server查看未绑定的Pod,尝试为Pod进行分配主机,经过调度算法选择主机后,绑定到这台机器上而且把调度信息写入etcd集群;
kubelet根据调度结果执行Pod建立操做,成功后将信息经过Api Server更新到etcd集群中;
整个Pod建立过程完成,每一个组件都在于Api Server进行交互,Api Server就是k8s集群的中间者,组件之间的协同者,是一个集群访问入口
2,Pod的多种控制器
ReplicaSet: 代用户建立指定数量的pod副本数量,确保pod副本数量符合预期状态,而且支持滚动式自动扩容和缩容功能。
ReplicaSet主要三个组件组成:
用户指望的pod副本数量
标签选择器,判断哪一个pod归本身管理
当现存的pod数量不足,会根据pod资源模板进行新建帮助用户管理无状态的pod资源,精确反应用户定义的目标数量,可是RelicaSet不是直接使用的控制器,而是使用Deployment。
Deployment:工做在ReplicaSet之上,用于管理无状态应用,目前来讲最好的控制器。支持滚动更新和回滚功能,还提供声明式配置。 参考文章:https://blog.csdn.net/bbwangj/article/details/82011573
DaemonSet:用于确保集群中的每个节点只运行特定的pod副本,一般用于实现系统级后台任务,好比ingress,elk.服务是无状态的,服务必须是守护进程。参考文章:https://www.cnblogs.com/xzkzzz/p/9553321.html
Job:只要任务或程序运行完成就当即退出,不须要重启或重建。 参考文章:https://blog.csdn.net/bbwangj/article/details/82011610
Cronjob:周期性任务控制,执行后就退出, 不须要持续后台运行, 参考文章:https://blog.csdn.net/bbwangj/article/details/82867830
StatefulSet:管理有状态应用,好比redis,mysql
3,POD管理
# 建立Pod资源 $ kubectl create -f pod.yaml # 查看pods $ kubectl get pods nginx-pod # 查看pod描述 $ kubectl describe pod/nginx-pod # 更新资源 $ kubectl apply -f pod.yaml # 删除资源 $kubectl delete -f pod.yaml or $kubectl delete pods nginx-pod
4,资源限制
apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: containers: - name: nginx image: nginx resources: # 资源限制标签 requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"
requests和limits都是作资源限制的,他们的区别在于:
requests # pod在建立时向k8s请求的资源大小;
limits # 限制了这个Pod运行的最大资源空间;
5,调度约束
Pod.spec.nodeName # 强制约束Pod调度到指定Node节点上
Pod.spec.nodeSelector # 经过lable-selector机制选择节点
apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: # nodeName:node01 nodeSelector: env_role: dev containers: - name: nginx image: nignx
经过label给Node主机设置标签:
kubectl label nodes k8s-node-129 env_role=dev
经过–show-labels查看Node的标签:
$ kubectl get node --show-labels
6,重启策略
Always: 当容器中止,老是重建容器,默认策略。
OnFailure: 当容器异常退出(退出状态码非0)时,才重启容器。
Never:当容器终止退出,从不重启容器。
apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: containers: - name: nginx image: nginx restartPolicy: OnFailure
7,镜像拉取策略
IfNotPresent:默认值,镜像不存在宿主机上时才拉取
Always:每次建立Pod时都会从新拉取一次镜像
Never:Pod永远不会主动拉取这个镜像
apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent
8,健康检查
提供Probe机制,有如下两种类型:
livenessProbe 若是检查失败,将容器杀死,根据Pod的restartPolicy来操做。 readinessProbe 若是检查失败,Kubeneres会把Pod从service endpoints中剔除。
robe支持如下三种检查方法:
httpGet
发送HTTP请求,返回200-400范围状态码为成功。
exec
执行Shell命令返回状态码是0为成功。
tcpSocket
发起TCP Socket创建成功。
9,问题定位
kubectl describe type/name kubectl logs type/name [-c container] kubectl exec --namespace=xxx -it pod -C 容器名称 -- bash
来源:https://nicksors.cc/2019/06/18/kubernetes%E7%B3%BB%E5%88%97%E4%B9%8B%E3%80%8APod%E3%80%8B.html
1,命令生成
$ kubectl run --image=nginx my-deploy -o yaml --dry-run >my-deploy.yaml $ kubectl create -f deploy-nginx.yaml -o yaml --dry-run >my-deploy.yaml $ kubectl create -f deploy-nginx.yaml -o json --dry-run >my-deploy.json # 指定输出json格式 – image # 指定模板镜像 my-deploy # 运行标签名称 –dry-run # 只测试运行,不会实际运行pod -o yaml # 指定输出格式
2,get导出
kubectl get deploy/my-deploy -o=yaml --export > my-deploy.yaml
3,查询Pod容器的字段资源内部文档
使用kubectl explain –help 查询pod字段内部说明
$ kubectl explain pods # 每个层级的指令都会有字段信息 $ kubectl explain pods.spec $ kubectl explain pods.spec.containers