Pod和Deployment的使用(k8s实践-3)

使用Pod

Pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: hello-pod
  labels:
    zone: prod
    version: v1
spec:
  containers:
  - name: hello-ctr
    image: nigelpoulton/k8sbook:latest
    ports:
    - containerPort: 8080

创建Pod

root@lzl:/home/lzl# kubectl apply -f ./WorkSpace/k8s/pod/Pod.yml 
pod/hello-pod created
root@lzl:/home/lzl# kubectl get Pods
NAME        READY   STATUS              RESTARTS   AGE
hello-pod   0/1     ContainerCreating   0          12s

# 要等一会,因为有拉取镜像的时间
root@lzl:/home/lzl# kubectl get Pods
NAME        READY   STATUS    RESTARTS   AGE
hello-pod   1/1     Running   0          110s

获取Pod信息

获取Pod详细信息:

  • kubectl get Pods hello-pod -o yaml
root@lzl:/home/lzl# kubectl get Pods hello-pod -o yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"version":"v1","zone":"prod"},"name":"hello-pod","namespace":"default"},"spec":{"containers":[{"image":"nigelpoulton/k8sbook:latest","name":"hello-ctr","ports":[{"containerPort":8080}]}]}}
  creationTimestamp: "2022-01-19T10:26:35Z"
  labels:
    version: v1
    zone: prod
  name: hello-pod
  namespace: default
  resourceVersion: "29553"
  uid: 1f41e62a-a951-4593-83f7-f3e7398b9d24
spec:	# 这部分是Pod的期望状态
  containers:
  - image: nigelpoulton/k8sbook:latest
    imagePullPolicy: Always
    name: hello-ctr
    ports:
    - containerPort: 8080
      protocol: TCP
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-5kwmz
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: lzl-c
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: kube-api-access-5kwmz
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
status:	# 这部分是Pod的当前状态
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2022-01-19T10:26:35Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2022-01-19T10:26:58Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2022-01-19T10:26:58Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2022-01-19T10:26:35Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://a7cc9815fc32e3f99f57553c6c28aa264576dbc3076784fee485a4306a1f4fcb
    image: nigelpoulton/k8sbook:latest
    imageID: docker-pullable://nigelpoulton/k8sbook@sha256:a983a96a85151320cd6ad0cd9fda3b725a743ed642e58b0597285c6bcb46c90f
    lastState: {}
    name: hello-ctr
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2022-01-19T10:26:58Z"
  hostIP: 192.168.230.13
  phase: Running
  podIP: 10.5.2.2
  podIPs:
  - ip: 10.5.2.2
  qosClass: BestEffort
  startTime: "2022-01-19T10:26:35Z"
  • kubectl describe Pods hello-pod
root@lzl:/home/lzl# kubectl describe Pods hello-pod
Name:         hello-pod
Namespace:    default
Priority:     0
Node:         lzl-c/192.168.230.13
Start Time:   Wed, 19 Jan 2022 18:26:35 +0800
Labels:       version=v1
              zone=prod
Annotations:  <none>
Status:       Running
IP:           10.5.2.2
IPs:
  IP:  10.5.2.2
Containers:
  hello-ctr:
    Container ID:   docker://a7cc9815fc32e3f99f57553c6c28aa264576dbc3076784fee485a4306a1f4fcb
    Image:          nigelpoulton/k8sbook:latest
    Image ID:       docker-pullable://nigelpoulton/k8sbook@sha256:a983a96a85151320cd6ad0cd9fda3b725a743ed642e58b0597285c6bcb46c90f
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Wed, 19 Jan 2022 18:26:58 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-5kwmz (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-5kwmz:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:	# Pod生命周期中的一些重要事件
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  6m56s  default-scheduler  Successfully assigned default/hello-pod to lzl-c
  Normal  Pulling    6m54s  kubelet            Pulling image "nigelpoulton/k8sbook:latest"
  Normal  Pulled     6m33s  kubelet            Successfully pulled image "nigelpoulton/k8sbook:latest" in 21.212884013s
  Normal  Created    6m33s  kubelet            Created container hello-ctr
  Normal  Started    6m33s  kubelet            Started container hello-ctr

进入Pod中的容器内部

  • 还可以进入容器执行命令,来查看Pod的信息:kubectl exec hello-pod -- ps aux
root@lzl:/home/lzl# kubectl exec hello-pod -- ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 node ./app.js
   13 root      0:00 ps aux
  • 登录到运行容器内部:kubectl exec -it hello-pod -- sh
root@lzl:/home/lzl# kubectl exec -it hello-pod -- sh
/src # ls
Dockerfile         app.js             package-lock.json  views
README.md          node_modules       package.json

/src # exit
root@lzl:/home/lzl# 

当Pod中有多个容器时,需要使用--container参数指定想要创建交互式会话的容器,不指定的话默认是第一个容器。

使用exit退出当前容器。

删除Pod

  • kubectl delete -f pod.yaml
root@lzl:/home/lzl# kubectl delete -f ./WorkSpace/k8s/pod/Pod.yml 
pod "hello-pod" deleted
root@lzl:/home/lzl# kubectl get Pods
No resources found in default namespace.

使用Deployment部署Pod

Deployment为Kubernetes带来自愈、自动扩缩容、滚动升级以及基于版本的回滚的能力。实际上在底层Deployment是使用的ReplicaSet来完成的,可以理解为,Deployment管理ReplicaSet,而ReplicaSet管理Pod。

部署Deployment

本次部署的文件deploy.yaml如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deploy
spec:                       # spec下的内容都与Pod有关
  replicas: 10
  selector:                 # 表示该Deployment所管理的Pod必须要有的标签
    matchLabels:
      app: hello-world
  minReadySeconds: 10
  strategy:                 # 表示更新策略
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  template:                 # 所管理的Pod的模板,这里只有一个容器
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: hello-pod
        image: nigelpoulton/k8sbook:latest
        ports:
        - containerPort: 8080

进行部署:

root@lzl:/home/lzl# kubectl apply -f ./WorkSpace/k8s/deployment/deploy.yaml 
deployment.apps/hello-deploy created

查看Deployment

  • 使用kubectl get
root@lzl:/home/lzl# kubectl get deploy hello-deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
hello-deploy   10/10   10           10          2m29s
  • 使用kubectl describe
root@lzl:/home/lzl# kubectl describe deploy hello-deploy
Name:                   hello-deploy
Namespace:              default
CreationTimestamp:      Wed, 19 Jan 2022 19:18:16 +0800
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=hello-world
Replicas:               10 desired | 10 updated | 10 total | 10 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        10
RollingUpdateStrategy:  1 max unavailable, 1 max surge
Pod Template:
  Labels:  app=hello-world
  Containers:
   hello-pod:
    Image:        nigelpoulton/k8sbook:latest
    Port:         8080/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   hello-deploy-65cbc9474c (10/10 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  4m17s  deployment-controller  Scaled up replica set hello-deploy-65cbc9474c to 10

可以使用kubectl get rs来查看ReplicaSet的状态,以及kubectl describe rs来查看其详细信息

root@lzl:/home/lzl# kubectl get rs
NAME                      DESIRED   CURRENT   READY   AGE
hello-deploy-65cbc9474c   10        10        10      5m55s

root@lzl:/home/lzl# kubectl describe rs hello-deploy-65cbc9474c
Name:           hello-deploy-65cbc9474c
Namespace:      default
Selector:       app=hello-world,pod-template-hash=65cbc9474c
Labels:         app=hello-world
                pod-template-hash=65cbc9474c
Annotations:    deployment.kubernetes.io/desired-replicas: 10
                deployment.kubernetes.io/max-replicas: 11
                deployment.kubernetes.io/revision: 1
Controlled By:  Deployment/hello-deploy
Replicas:       10 current / 10 desired
Pods Status:    10 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=hello-world
           pod-template-hash=65cbc9474c
  Containers:
   hello-pod:
    Image:        nigelpoulton/k8sbook:latest
    Port:         8080/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  7m39s  replicaset-controller  Created pod: hello-deploy-65cbc9474c-plhwm
  Normal  SuccessfulCreate  7m39s  replicaset-controller  Created pod: hello-deploy-65cbc9474c-8fdqs
  Normal  SuccessfulCreate  7m39s  replicaset-controller  Created pod: hello-deploy-65cbc9474c-dlv5g
  Normal  SuccessfulCreate  7m39s  replicaset-controller  Created pod: hello-deploy-65cbc9474c-x2ddb
  Normal  SuccessfulCreate  7m39s  replicaset-controller  Created pod: hello-deploy-65cbc9474c-qgffd
  Normal  SuccessfulCreate  7m39s  replicaset-controller  Created pod: hello-deploy-65cbc9474c-67nlw
  Normal  SuccessfulCreate  7m39s  replicaset-controller  Created pod: hello-deploy-65cbc9474c-gg4r2
  Normal  SuccessfulCreate  7m39s  replicaset-controller  Created pod: hello-deploy-65cbc9474c-b2v4v
  Normal  SuccessfulCreate  7m39s  replicaset-controller  Created pod: hello-deploy-65cbc9474c-vbzrd
  Normal  SuccessfulCreate  7m39s  replicaset-controller  (combined from similar events): Created pod: hello-deploy-65cbc9474c-pjwsh

访问部署的应用

对于Pod来说,其IP会由于销毁或者重建而改变,Pod的IP是一个变量,通常不能直接使用Pod的IP作为通讯。在K8s中,Kubernetes Service对象则解决了这一问题,它为一组Pod提供了一个固定的DNS域名和IP地址。

下面定义一个Service与上述Pod进行协同工作。

svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: hello-svc
  labels:
    app: hello-world
spec:
  type: NodePort
  ports:
  - port: 8080
    nodePort: 30001
    protocol: TCP
  selector:
    app: hello-world

部署Service:

root@lzl:/home/lzl# kubectl apply -f ./WorkSpace/k8s/service/svc.yaml
service/hello-svc created

这样我们有两种方式可以访问该应用:

  1. 在集群内部使用DNS名称hello-svc和端口8080访问
  2. 在集群外部通过集群的任意节点和端口号30001访问

首先我们查看我们刚部署的这10个Pod实例的具体信息:

root@lzl:/home/lzl# kubectl get pods -l app=hello-world -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP         NODE    NOMINATED NODE   READINESS GATES
hello-deploy-65cbc9474c-67nlw   1/1     Running   0          72m   10.5.1.4   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-8fdqs   1/1     Running   0          72m   10.5.2.6   lzl-c   <none>           <none>
hello-deploy-65cbc9474c-b2v4v   1/1     Running   0          72m   10.5.2.4   lzl-c   <none>           <none>
hello-deploy-65cbc9474c-dlv5g   1/1     Running   0          72m   10.5.2.7   lzl-c   <none>           <none>
hello-deploy-65cbc9474c-gg4r2   1/1     Running   0          72m   10.5.2.5   lzl-c   <none>           <none>
hello-deploy-65cbc9474c-pjwsh   1/1     Running   0          72m   10.5.2.3   lzl-c   <none>           <none>
hello-deploy-65cbc9474c-plhwm   1/1     Running   0          72m   10.5.1.5   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-qgffd   1/1     Running   0          72m   10.5.1.2   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-vbzrd   1/1     Running   0          72m   10.5.1.6   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-x2ddb   1/1     Running   0          72m   10.5.1.3   lzl-b   <none>           <none>

k8s自动为这些Pod分配了IP地址。

引自官方文档:

Kubernetes Service 从逻辑上定义了运行在集群中的一组 Pod,这些 Pod 提供了相同的功能。 当每个 Service 创建时,会被分配一个唯一的 IP 地址(也称为 clusterIP)。 这个 IP 地址与一个 Service 的生命周期绑定在一起,当 Service 存在的时候它也不会改变。 可以配置 Pod 使它与 Service 进行通信,Pod 知道与 Service 通信将被自动地负载均衡到该 Service 中的某些 Pod 上。

我们查看创建的Service的信息:

root@lzl:/home/lzl# kubectl get svc hello-svc
NAME        TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
hello-svc   NodePort   10.110.196.234   <none>        8080:30001/TCP   19m
root@lzl:/home/lzl# kubectl describe svc hello-svc
Name:                     hello-svc
Namespace:                default
Labels:                   app=hello-world
Annotations:              <none>
Selector:                 app=hello-world
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.110.196.234
IPs:                      10.110.196.234
Port:                     <unset>  8080/TCP
TargetPort:               8080/TCP
NodePort:                 <unset>  30001/TCP
Endpoints:                10.5.1.2:8080,10.5.1.3:8080,10.5.1.4:8080 + 7 more...
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

这里我遇到了集群内部和集群外部都无法访问应用的情况

  • 集群内部无法访问
    • 在Pod运行的节点上可以访问,但是在集群其他节点上无法访问
    • 无法访问Service
  • 集群外部无法访问:可以通过运行Pod的主机地址访问,而无法通过没有运行Pod的集群主机地址进行访问

解决方案在下一节

将问题解决后,我们来看。

root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl get pods -o wide
NAME                           READY   STATUS    RESTARTS        AGE   IP          NODE    NOMINATED NODE   READINESS GATES
hello-deploy-59866ff45-2hp8j   1/1     Running   1 (8m20s ago)   39m   10.5.1.4    lzl-b   <none>           <none>
hello-deploy-59866ff45-4lhld   1/1     Running   1 (8m20s ago)   38m   10.5.1.11   lzl-b   <none>           <none>
hello-deploy-59866ff45-7pn94   1/1     Running   1 (8m20s ago)   35m   10.5.1.5    lzl-b   <none>           <none>
hello-deploy-59866ff45-9d444   1/1     Running   1 (8m20s ago)   35m   10.5.1.3    lzl-b   <none>           <none>
hello-deploy-59866ff45-lhx2j   1/1     Running   1 (8m20s ago)   37m   10.5.1.9    lzl-b   <none>           <none>
hello-deploy-59866ff45-nwcp8   1/1     Running   1 (8m20s ago)   36m   10.5.1.2    lzl-b   <none>           <none>
hello-deploy-59866ff45-prwwd   1/1     Running   1 (8m19s ago)   36m   10.5.1.7    lzl-b   <none>           <none>
hello-deploy-59866ff45-rflnv   1/1     Running   1 (8m19s ago)   34m   10.5.1.6    lzl-b   <none>           <none>
hello-deploy-59866ff45-tbpt2   1/1     Running   1 (8m19s ago)   37m   10.5.1.10   lzl-b   <none>           <none>
hello-deploy-59866ff45-z88ct   1/1     Running   1 (8m19s ago)   39m   10.5.1.8    lzl-b   <none>           <none>

root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE   SELECTOR
hello-svc    NodePort    10.101.13.201   <none>        8080:30001/TCP   18h   app=hello-world
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          18h   <none>

从集群内访问

以服务实例hello-deploy-59866ff45-2hp8j为例,其地址为10.5.1.4:8080。因此,在集群内部任何一台机器访问该地址都可以访问到这个应用。

同样的,hello-svc的地址是10.101.13.201:8080,加入集群的任何一台主机都可以通过该地址访问到应用。

**特别的,与Pod的IP不同,Service的IP是固定不变的,而Pod的IP会跟随Deployment的更新、扩缩容等操作改变。**Service实际上相当于所有Pod的一个网关,它有固定的IP地址,并且将请求Pod的流量负载均衡到不同的Pod上,并在Pod地址改变时完成服务发现。

从集群外访问

如果在集群外,那么访问集群内的任何一台主机的30001端口都可以连接到该应用,因为前面svc.yaml

 ports:
  - port: 8080
    nodePort: 30001
    protocol: TCP

帮我们做了集群内到集群外的端口映射。

解决由于iptables版本差异导致的K8s网络问题

如上文,我是用Ubuntu18.04搭建K8s1.22.4集群,在启动Service做应用网络入口时,出现了上述问题。找了很久的资料之后认为是k8s1.22.4在使用iptables配置网络规则时由于版本较新,其使用的配置命令在Ubuntu18.04版本上的iptables无法解析,导致网络出现问题。

所以我将虚拟机换为Ubuntu20.04后,该问题得到解决。由此看出,K8s对于环境版本一致性的要求还是比较高的。

解决由于虚拟机挂起,恢复虚拟机后集群网络异常的问题

在虚拟机挂起,再恢复之后,集群网络出现了问题,具体表现在:

  1. 无法通过Pod地址访问应用
  2. 无法通过Service地址访问应用
  3. 集群间Pod无法联通

在一篇博文中找到了解决方法:https://blog.csdn.net/weixin_43293361/article/details/114731838

首先,查看Master Node的网络,发现原本的cni0flannel.1网络均不存在了:

然后查看了Work Node的网络,上述两个网络也是不存在的。所以按照博文给出的方法:

1)在Master Node删除flannel网络组件:

kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

2)在Master Node和Work Node上重置集群网络配置(集群所有节点上):

ifconfig cni0 down
ip link delete cni0
ifconfig flannel.1 down
ip link delete flannel.1
rm -rf /var/lib/cni/flannel/*
rm -rf /var/lib/cni/networks/cbr0/*
rm -rf /var/lib/cni/cache/*
rm -f /etc/cni/net.d/*
systemctl restart kubelet
systemctl restart docker
chmod a+w /var/run/docker.sock

3)最后在Master Node重新安装flannel网络组件:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

4)查看集群各个节点的网络情况,cni0flannel.1网络均正常出现,然后等待Deployment的Pod自愈,这样集群网络就可以正常恢复。

滚动升级与回滚

滚动升级

在升级使用的deploy.yaml文件中:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deploy
spec:
  replicas: 10
  selector:
    matchLabels:
      app: hello-world
  minReadySeconds: 10
  strategy:
    type: RollingUpdate	# 滚动更新
    rollingUpdate:
      maxUnavailable: 1	# 集群中最多有一个不可用Pod
      maxSurge: 1		# 集群中Pod最多超过预期值1个
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: hello-pod
        image: nigelpoulton/k8sbook:edge	# 使用了另一个版本的镜像
        ports:
        - containerPort: 8080

与上一个deploy.yaml不同,这里使用了另一个版本的镜像,更新策略由strategy下的内容决定。

进行滚动升级:

root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl apply -f deploy.yaml --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/hello-deploy configured
root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl rollout status deployment hello-deploy
Waiting for deployment "hello-deploy" rollout to finish: 2 out of 10 new replicas have been updated...
^Croot@lzl-a:/home/lzl/WP/k8s/deploy# kubectl get deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
hello-deploy   10/10   2            9           17h
root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl get deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
hello-deploy   10/10   3            9           17h
root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl get deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
hello-deploy   9/10    5            9           17h

可以看到,如Docker Swarm一样,在升级过程中,同时存在新版本与旧版本的应用,直至整个升级过程结束。

root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl get deploy hello-deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
hello-deploy   10/10   10           10          17h

回滚

Kubernetes会维护Deployment的版本历史记录:

root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl rollout history deployment hello-deploy
deployment.apps/hello-deploy 
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl apply --filename=deploy.yaml --record=true

对于Deployment依赖的ReplicaSet来说,每次更新都会保留旧版本的ReplicaSet同时创建一个新的ReplicaSet:

root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl get rs
NAME                      DESIRED   CURRENT   READY   AGE
hello-deploy-59866ff45    10        10        10      158m
hello-deploy-65cbc9474c   0         0         0       20h
root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl describe rs
Name:           hello-deploy-59866ff45
Namespace:      default
Selector:       app=hello-world,pod-template-hash=59866ff45
Labels:         app=hello-world
                pod-template-hash=59866ff45
Annotations:    deployment.kubernetes.io/desired-replicas: 10
                deployment.kubernetes.io/max-replicas: 11
                deployment.kubernetes.io/revision: 2
                kubernetes.io/change-cause: kubectl apply --filename=deploy.yaml --record=true
Controlled By:  Deployment/hello-deploy
Replicas:       10 current / 10 desired
Pods Status:    10 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=hello-world
           pod-template-hash=59866ff45
  Containers:
   hello-pod:
    Image:        nigelpoulton/k8sbook:edge
    Port:         8080/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:           <none>


Name:           hello-deploy-65cbc9474c
Namespace:      default
Selector:       app=hello-world,pod-template-hash=65cbc9474c
Labels:         app=hello-world
                pod-template-hash=65cbc9474c
Annotations:    deployment.kubernetes.io/desired-replicas: 10
                deployment.kubernetes.io/max-replicas: 11
                deployment.kubernetes.io/revision: 1
Controlled By:  Deployment/hello-deploy
Replicas:       0 current / 0 desired
Pods Status:    0 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=hello-world
           pod-template-hash=65cbc9474c
  Containers:
   hello-pod:
    Image:        nigelpoulton/k8sbook:latest
    Port:         8080/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:           <none>

通过ReplicaSet的信息,可以清楚的知道两个ReplicaSet所做的操作,并且由于旧版本ReplicaSet的存在,回滚操作变得更加简单。下面将应用回滚到版本1,同时别忘记再更新一下yaml文件:

root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl rollout undo deployment hello-deploy --to-revision=1
deployment.apps/hello-deploy rolled back
root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl get pods -o wide
NAME                            READY   STATUS              RESTARTS       AGE    IP          NODE    NOMINATED NODE   READINESS GATES
hello-deploy-59866ff45-2hp8j    1/1     Running             1 (135m ago)   166m   10.5.1.4    lzl-b   <none>           <none>
hello-deploy-59866ff45-4lhld    1/1     Running             1 (135m ago)   165m   10.5.1.11   lzl-b   <none>           <none>
hello-deploy-59866ff45-7pn94    1/1     Running             1 (135m ago)   162m   10.5.1.5    lzl-b   <none>           <none>
hello-deploy-59866ff45-9d444    1/1     Running             1 (135m ago)   162m   10.5.1.3    lzl-b   <none>           <none>
hello-deploy-59866ff45-lhx2j    1/1     Terminating         1 (135m ago)   164m   10.5.1.9    lzl-b   <none>           <none>
hello-deploy-59866ff45-nwcp8    1/1     Running             1 (135m ago)   163m   10.5.1.2    lzl-b   <none>           <none>
hello-deploy-59866ff45-prwwd    1/1     Running             1 (135m ago)   163m   10.5.1.7    lzl-b   <none>           <none>
hello-deploy-59866ff45-rflnv    1/1     Running             1 (135m ago)   161m   10.5.1.6    lzl-b   <none>           <none>
hello-deploy-59866ff45-tbpt2    1/1     Running             1 (135m ago)   165m   10.5.1.10   lzl-b   <none>           <none>
hello-deploy-59866ff45-z88ct    1/1     Running             1 (135m ago)   166m   10.5.1.8    lzl-b   <none>           <none>
hello-deploy-65cbc9474c-98bh2   0/1     ContainerCreating   0              10s    <none>      lzl-b   <none>           <none>
hello-deploy-65cbc9474c-d4g24   0/1     ContainerCreating   0              10s    <none>      lzl-b   <none>           <none>
root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl rollout status deployment hello-deploy
Waiting for deployment "hello-deploy" rollout to finish: 2 out of 10 new replicas have been updated...
^Croot@lzl-a:/home/lzl/WP/k8s/deploy# kubectl get pods -o wide
NAME                            READY   STATUS              RESTARTS       AGE    IP          NODE    NOMINATED NODE   READINESS GATES
hello-deploy-59866ff45-2hp8j    1/1     Running             1 (136m ago)   167m   10.5.1.4    lzl-b   <none>           <none>
hello-deploy-59866ff45-4lhld    1/1     Running             1 (136m ago)   166m   10.5.1.11   lzl-b   <none>           <none>
hello-deploy-59866ff45-7pn94    1/1     Running             1 (136m ago)   163m   10.5.1.5    lzl-b   <none>           <none>
hello-deploy-59866ff45-9d444    1/1     Running             1 (136m ago)   162m   10.5.1.3    lzl-b   <none>           <none>
hello-deploy-59866ff45-nwcp8    1/1     Running             1 (136m ago)   164m   10.5.1.2    lzl-b   <none>           <none>
hello-deploy-59866ff45-prwwd    1/1     Running             1 (136m ago)   164m   10.5.1.7    lzl-b   <none>           <none>
hello-deploy-59866ff45-rflnv    1/1     Terminating         1 (136m ago)   162m   10.5.1.6    lzl-b   <none>           <none>
hello-deploy-59866ff45-tbpt2    1/1     Running             1 (136m ago)   165m   10.5.1.10   lzl-b   <none>           <none>
hello-deploy-59866ff45-z88ct    1/1     Running             1 (136m ago)   167m   10.5.1.8    lzl-b   <none>           <none>
hello-deploy-65cbc9474c-98bh2   1/1     Running             0              47s    10.5.1.12   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-d4g24   0/1     ContainerCreating   0              47s    <none>      lzl-b   <none>           <none>
hello-deploy-65cbc9474c-kglhr   0/1     ContainerCreating   0              2s     <none>      lzl-b   <none>           <none>
root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl rollout status deployment hello-deploy
Waiting for deployment "hello-deploy" rollout to finish: 3 out of 10 new replicas have been updated...
^[[AWaiting for deployment "hello-deploy" rollout to finish: 3 out of 10 new replicas have been updated...
^Croot@lzl-a:/home/lzl/WP/k8s/deploykubectl get deploy hello-deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
hello-deploy   10/10   3            9           20h
root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl get deploy hello-deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
hello-deploy   10/10   10           10          20h
root@lzl-a:/home/lzl/WP/k8s/deploy# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP          NODE    NOMINATED NODE   READINESS GATES
hello-deploy-65cbc9474c-7jrwq   1/1     Running   0          4m32s   10.5.1.19   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-98bh2   1/1     Running   0          7m56s   10.5.1.12   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-d4g24   1/1     Running   0          7m56s   10.5.1.13   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-hkr5r   1/1     Running   0          6m39s   10.5.1.15   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-jdwsr   1/1     Running   0          3m29s   10.5.1.21   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-kglhr   1/1     Running   0          7m11s   10.5.1.14   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-n4mqz   1/1     Running   0          4m1s    10.5.1.20   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-p7zgs   1/1     Running   0          6m7s    10.5.1.16   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-rqtrg   1/1     Running   0          5m36s   10.5.1.17   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-xxk2n   1/1     Running   0          5m4s    10.5.1.18   lzl-b   <none>           <none>

和滚动升级一样,回滚过程中也同时存在新旧版本的应用。由于回滚是命令操作,没有使用到deploy.yaml文件,因此要注意应用版本与部署文件中镜像版本不一致的问题,可以手动更改部署文件。

删除Deployment和Service

不再使用该Service和Pod时,将这两个对象删除,使用命令:kubectl delete -f

root@lzl-a:/home/lzl/WP/k8s# kubectl delete -f ./deploy/deploy.yaml 
deployment.apps "hello-deploy" deleted
root@lzl-a:/home/lzl/WP/k8s# kubectl delete -f ./service/svc.yaml 
service "hello-svc" deleted
root@lzl-a:/home/lzl/WP/k8s# kubectl get pods -o wide
NAME                            READY   STATUS        RESTARTS   AGE     IP          NODE    NOMINATED NODE   READINESS GATES
hello-deploy-65cbc9474c-7jrwq   1/1     Terminating   0          10m     10.5.1.19   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-98bh2   1/1     Terminating   0          13m     10.5.1.12   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-d4g24   1/1     Terminating   0          13m     10.5.1.13   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-hkr5r   1/1     Terminating   0          12m     10.5.1.15   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-jdwsr   1/1     Terminating   0          9m19s   10.5.1.21   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-kglhr   1/1     Terminating   0          13m     10.5.1.14   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-n4mqz   1/1     Terminating   0          9m51s   10.5.1.20   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-p7zgs   1/1     Terminating   0          11m     10.5.1.16   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-rqtrg   1/1     Terminating   0          11m     10.5.1.17   lzl-b   <none>           <none>
hello-deploy-65cbc9474c-xxk2n   1/1     Terminating   0          10m     10.5.1.18   lzl-b   <none>           <none>
root@lzl-a:/home/lzl/WP/k8s# kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   20h   <none>
root@lzl-a:/home/lzl/WP/k8s# kubectl get pods -o wide
No resources found in default namespace.
自认为是幻象波普星的来客
Built with Hugo
主题 StackJimmy 设计