掌握Kubernetes,需要我们有扎实的docker基础。
深入了解pods之前,我们需要:
使用Kubernetes的最终目标是将应用程序以容器的形式部署在配置为集群中工作节点的一组机器上。
Kubernetes不会直接在工作节点上部署容器。容器被封装到称为pods的Kubernetes对象中。pod是应用程序的单个实例。pod是您可以在Kubernetes中创建的最小对象。在这里,我们看到了最简单的情况,即您有一个单节点Kubernetes集群,其中您的应用程序的单个实例在单个Docker容器中运行,封装在pod中。
Pod是kubernetes的最小调度单元,也是最基础的概念。
容器的本质是一个隔离的进程;而Pod则是一组相互联系的进程。Pod可以包含一个或者多个容器。
我们可以通过kubectl run
来启动Pod,默认image会从docker hub拉取
kubectl run nginx-pod --image=nginx
# pod/nginx created
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# nginx 1/1 Running 0 50s
kubectl describe pod nginx-pod
# Name: nginx
# Namespace: default
# Priority: 0
# Node: node2/192.168.0.7
# Start Time: Thu, 02 Feb 2023 06:44:13 +0000
# Labels: run=nginx
# Annotations:
# Status: Running
# IP: 10.5.1.2
# IPs:
# IP: 10.5.1.2
# Containers:
# nginx:
# Container ID: docker://40f5485d27cce5862a6424645a01c962aa3f9c4ae85dc5db7273cfbc4c717cdf
# Image: nginx
# Image ID: docker-pullable://nginx@sha256:b8f2383a95879e1ae064940d9a200f67a6c79e710ed82ac42263397367e7cc4e
# Port:
# Host Port:
# State: Running
# Started: Thu, 02 Feb 2023 06:44:27 +0000
# Ready: True
# Restart Count: 0
# Environment:
# Mounts:
# /var/run/secrets/kubernetes.io/serviceaccount from default-token-69hgb (ro)
# Conditions:
# Type Status
# Initialized True
# Ready True
# ContainersReady True
# PodScheduled True
# Volumes:
# default-token-69hgb:
# Type: Secret (a volume populated by a Secret)
# SecretName: default-token-69hgb
# Optional: false
# QoS Class: BestEffort
# Node-Selectors:
# Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
# node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
# Events:
# Type Reason Age From Message
# ---- ------ ---- ---- -------
# Warning FailedScheduling 49s (x5 over 63s) default-scheduler 0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 node(s) had taint {node.kubernetes.io/not-ready: }, that the pod didn't tolerate.
# Normal Scheduled 39s default-scheduler Successfully assigned default/nginx to node2
# Normal Pulling 37s kubelet Pulling image "nginx"
# Normal Pulled 26s kubelet Successfully pulled image "nginx" in 11.258745578s
# Normal Created 25s kubelet Created container nginx
# Normal Started 25s kubelet Started container nginx
kubectl get pods -o wide
# NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
# nginx 1/1 Running 0 103s 10.5.1.2 node2
kubectl get pods命令可以帮助我们查看集群中的pod列表
Kubernetes不推荐使用命令行的方式直接运行容器(kubectl run),而是用 YAML 文件的方式:kubectl create -f file.yml
kubernetes使用yaml文件来描述API对象,kubectl run nginx --image=nginx
等价于
vim myapp-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
type: myservice
spec:
containers:
- name: nginx
image: nginx
之前在docker章节,我们已经见过用yaml声明对象的方式。在这个yaml文件中,它要求kubernetes创建一个Pod,使用nginx镜像,开放端口80。
Kubernetes使用YAML文件作为创建对象的输入,如Pod、Replica、Deployment、Service等等。所有这些都遵循类似的结构。Kubernetes定义文件总是包含四个顶级字段:API版本、种类、元数据和规格spec。这些也是必须的字段.
我们可以使用kubectl apply
来创建对象
kubectl apply -f myapp-pod.yml
# pod/myapp-pod created
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# myapp-pod 1/1 Running 0 29s
# kubectl describe pod myapp-pod
# kubectl delete -f myapp-pod.yml
kubectl get从Kubernetes里面获取指定的 API 对象。
Pod可以通过控制器来管理。控制器是Kubernetes的大脑,它们监测Kubernetes对象并作出相应反应。
ReplicationController 确保在任何时候都有特定数量的 Pod 副本处于运行状态:
场景:有一个单一的pod运行应用程序。如果由于某种原因,应用程序崩溃了,pod失败了怎么办?
需要Replication Controller的另一个原因是创建多个pod来分担它们的负载。例如,在这个简单的场景中,有一个单一的pod为一组用户服务。当用户数量增加时,部署额外的pod来平衡两部分的负载。如果需求进一步增加,如果在第一个节点上耗尽资源,可以在集群的其他节点上部署额外的部分。
Replication Controller是旧的技术,正在被Replica Set取代。Replica Set是新推荐的设置副本的方式。
创建一个Replication Controller的定义文件。我们将其命名为myapp-rc.yml:有四个部分:API版本、种类、元数据和规格。
vim myapp-rc.yml
apiVersion: v1
kind: ReplicationController
metadata:
name: myapp-rc
labels:
app: myapp
type: myservice
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: nginx
image: nginx
replicas: 3
从nginx-pod.yml复制spec中的内容到template,然后设置replicas为3
kubectl create -f myapp-rc.yml
# replicationcontroller/myapp-rc created
# kubectl get replicationcontroller
kubectl get rc
# NAME DESIRED CURRENT READY AGE
# myapp-rc 3 3 3 20s
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# myapp-rc-ngbhp 1/1 Running 0 44s
# myapp-rc-qskjr 1/1 Running 0 44s
# myapp-rc-tk8lx 1/1 Running 0 44s
Replica Set与Replication Controller非常相似。ReplicaSet则相当于ReplicationController的升级版,它的作用也是控制pod的数量始终维持在预设的个数。
vim myapp-rs.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp-rs
labels:
app: myapp
type: myservice
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: myservice
spec:
containers:
- name: nginx
image: nginx
replicas: 3
selector:
matchLabels:
type: myservice
apiVersion
需要设置为apps/v1
,否则会无法识别ReplicaSetselector
可以用来匹配已有对象的label标签kubectl create -f myapp-rs.yml
# replicaset.apps/myapp-rc created
kubectl get replicaset
# NAME DESIRED CURRENT READY AGE
# myapp-rc 3 3 3 23s
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# myapp-rc-j29gh 1/1 Running 0 34s
# myapp-rc-pf9sx 1/1 Running 0 34s
# myapp-rc-vlgl7 1/1 Running 0 34s
kubectl delete pod myapp-rc-j29gh
kubectl get pods
kubectl describe replicaset myapp-rs
kubectl describe命令,查看一个 API 对象的细节。所有重要操作,会被记录在Events里,并且显示在 kubectl describe 指令返回的结果中。
从myapp-pod新建一个pod,会发现因为存在replicaset,新建的pod被自动终止了
kubectl apply -f myapp-pod.yml
kubectl get pods
kubectl describe replicaset myapp-rs
kubectl apply命令进行Kubernetes对象的创建和更新操作。Kubernetes会根据 YAML文件的内容变化,自动进行具体的处理。
尝试将replicaset的副本扩容成6个
kubectl scale replicaset myapp-rs --replicas=6
官方推荐不要直接使用ReplicaSet,用Deployments。Deployment可以通过selector来匹配labels字段,过滤出它所关心的被控制对象。
Deployment不直接管理Pod对象,而是由Deployment管理ReplicaSet,再由ReplicaSet负责管理Pod对象。
Deployment是一个Kubernetes对象,在层次结构中更高。
Deployment为我们提供了使用滚动更新无缝升级底层实例的能力,e.g.撤销变化,暂停,并根据需要恢复变化。
创建一个Deployment定义文件。Deployment定义文件的内容与ReplicaSet定义文件完全相似。(在这里ReplicaSet和Deployment之间还没有太大的区别,除了Deployment创建了一个新的Kubernetes对象,叫做deployment)
kubectl create deployment my-nginx --image nginx
# deployment.apps/my-nginx created
kubectl get all
vim myapp-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
type: myservice
spec:
selector:
matchLabels:
type: myservice
replicas: 3
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: myservice
spec:
containers:
- name: nginx
image: nginx
创建deployment
kubectl create -f myapp-deploy.yml
kubectl get deployments
kubectl get replicaset
kubectl get pods
升级策略
# kubectl create -f myapp-deploy.yml
kubectl delete deployment myapp-deployment
kubectl create -f myapp-deploy.yml && \
kubectl rollout status deployment/myapp-deployment
# deployment.apps/myapp-deployment created
# Waiting for deployment "myapp-deployment" rollout to finish: 0 of 3 updated replicas are available...
# Waiting for deployment "myapp-deployment" rollout to finish: 1 of 3 updated replicas are available...
# Waiting for deployment "myapp-deployment" rollout to finish: 2 of 3 updated replicas are available...
# deployment "myapp-deployment" successfully rolled out
kubectl rollout history deployment/myapp-deployment
# deployment.apps/myapp-deployment
# REVISION CHANGE-CAUSE
# 1
可以看见所有的pod被挨个启动,change cause为空。我们重新执行这次部署
kubectl delete deployment myapp-deployment
kubectl get pods
kubectl create -f myapp-deploy.yml --record
kubectl rollout status deployment/myapp-deployment
kubectl describe deployment myapp-deployment
# 在annotation中出现
kubectl edit deployment myapp-deployment --record
# 修改使用nginx:alpine
kubectl rollout status deployment/myapp-deployment
# Waiting for deployment "myapp-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
# Waiting for deployment "myapp-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
# Waiting for deployment "myapp-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
# Waiting for deployment "myapp-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
# Waiting for deployment "myapp-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
# Waiting for deployment "myapp-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
# Waiting for deployment "myapp-deployment" rollout to finish: 1 old replicas are pending termination...
# Waiting for deployment "myapp-deployment" rollout to finish: 1 old replicas are pending termination...
kubectl describe deployment myapp-deployment
# 注意annotation 和 events
kubectl set image deployment myapp-deployment nginx=nginx:perl --record
kubectl rollout status deployment/myapp-deployment
kubectl rollout history deployment/myapp-deployment
kubectl describe deployment myapp-deployment | grep nginx
kubectl rollout undo deployment/myapp-deployment
kubectl set image deployment myapp-deployment nginx=nginx:3 --record
kubectl rollout status deployment/myapp-deployment
kubectl get deployment myapp-deployment
# NAME READY UP-TO-DATE AVAILABLE AGE
# myapp-deployment 3/3 1 3 18m
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# myapp-deployment-56b894845f-7pm9v 1/1 Running 0 4m25s
# myapp-deployment-56b894845f-rs699 1/1 Running 0 4m18s
# myapp-deployment-56b894845f-svjs5 1/1 Running 0 4m22s
# myapp-deployment-67c8cfbf79-p4j6j 0/1 ImagePullBackOff 0 77s
kubectl rollout undo deployment/myapp-deployment
kubectl get pods
vim myapp-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
type: myservice
spec:
selector:
matchLabels:
type: myservice
replicas: 3
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: myservice
spec:
containers:
- name: nginx
image: nginx
kubectl api-resources
# NAME SHORTNAMES APIVERSION NAMESPACED KIND
# bindings v1 true Binding
# componentstatuses cs v1 false ComponentStatus
# configmaps cm v1 true ConfigMap
# endpoints ep v1 true Endpoints
# events ev v1 true Event
# limitranges limits v1 true LimitRange
# namespaces ns v1 false Namespace
# nodes no v1 false Node
# persistentvolumeclaims pvc v1 true PersistentVolumeClaim
# persistentvolumes pv v1 false PersistentVolume
# pods po v1 true Pod
# podtemplates v1 true PodTemplate
# replicationcontrollers rc v1 true ReplicationController
# resourcequotas quota v1 true ResourceQuota
# secrets v1 true Secret
# serviceaccounts sa v1 true ServiceAccount
# services svc v1 true Service
# mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration
# validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration
# customresourcedefinitions crd,crds apiextensions.k8s.io/v1 false CustomResourceDefinition
# apiservices apiregistration.k8s.io/v1 false APIService
# controllerrevisions apps/v1 true ControllerRevision
# daemonsets ds apps/v1 true DaemonSet
# deployments deploy apps/v1 true Deployment
# replicasets rs apps/v1 true ReplicaSet
# statefulsets sts apps/v1 true StatefulSet
# tokenreviews authentication.k8s.io/v1 false TokenReview
# localsubjectaccessreviews authorization.k8s.io/v1 true LocalSubjectAccessReview
# selfsubjectaccessreviews authorization.k8s.io/v1 false SelfSubjectAccessReview
# selfsubjectrulesreviews authorization.k8s.io/v1 false SelfSubjectRulesReview
# subjectaccessreviews authorization.k8s.io/v1 false SubjectAccessReview
# horizontalpodautoscalers hpa autoscaling/v1 true HorizontalPodAutoscaler
# cronjobs cj batch/v1beta1 true CronJob
# jobs batch/v1 true Job
# certificatesigningrequests csr certificates.k8s.io/v1 false CertificateSigningRequest
# leases coordination.k8s.io/v1 true Lease
# endpointslices discovery.k8s.io/v1beta1 true EndpointSlice
# events ev events.k8s.io/v1 true Event
# ingresses ing extensions/v1beta1 true Ingress
# flowschemas flowcontrol.apiserver.k8s.io/v1beta1 false FlowSchema
# prioritylevelconfigurations flowcontrol.apiserver.k8s.io/v1beta1 false PriorityLevelConfiguration
# ingressclasses networking.k8s.io/v1 false IngressClass
# ingresses ing networking.k8s.io/v1 true Ingress
# networkpolicies netpol networking.k8s.io/v1 true NetworkPolicy
# runtimeclasses node.k8s.io/v1 false RuntimeClass
# poddisruptionbudgets pdb policy/v1beta1 true PodDisruptionBudget
# podsecuritypolicies psp policy/v1beta1 false PodSecurityPolicy
# clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding
# clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
# rolebindings rbac.authorization.k8s.io/v1 true RoleBinding
# roles rbac.authorization.k8s.io/v1 true Role
# priorityclasses pc scheduling.k8s.io/v1 false PriorityClass
# csidrivers storage.k8s.io/v1 false CSIDriver
# csinodes storage.k8s.io/v1 false CSINode
# storageclasses sc storage.k8s.io/v1 false StorageClass
# volumeattachments storage.k8s.io/v1 false VolumeAttachment