运维实战 kubernetes(k8s) 之 pod 的建立

Posted 123坤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了运维实战 kubernetes(k8s) 之 pod 的建立相关的知识,希望对你有一定的参考价值。

运维实战 kubernetes(k8s)之 pod 的建立

1. Pod管理

  • Pod 是可以创建和管理Kubernetes计算的最小可部署单元,一个Pod代表着集群中运行的一个进程,每个pod都有一个唯一的ip。
  • 一个 pod 类似一个豌豆荚,包含一个或多个容器(通常是docker),多个容器间共享IPC、Network和UTC namespace。
  • kubectl 命令指南:https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
  1. 创建 Pod 应用:
[root@server2 ~]# kubectl run demo --image=myapp:v1
pod/demo created
[root@server2 ~]# kubectl get pod	##查看pod 信息
NAME   READY   STATUS    RESTARTS   AGE
demo   1/1     Running   0          15s
[root@server2 ~]# kubectl get pod -o wide	##查看 pod 详细信息
NAME   READY   STATUS    RESTARTS   AGE   IP           NODE      NOMINATED NODE   READINESS GATES
demo   1/1     Running   0          21s   10.244.2.2   server4   <none>           <none>
[root@server2 ~]# curl 10.244.2.2
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
 ##集群内部任意节点可以访问Pod,但集群外部无法直接访问。
[root@server2 ~]# kubectl get all
NAME       READY   STATUS    RESTARTS   AGE
pod/demo   1/1     Running   0          5m53s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   2d22h

可以看到此时集群给 pod 分配的 ip 是 10.244.2.2 ,该地址在初始化集群时是定义过的;此时运行在 server4 上;每个节点上的网段是不同的;默认情况下 k8smaster 不参加调度,网段应该是 0 网段;
在用 kuectl get all 查看时,可以看到通过 run 来运行的 pod 并没有使用控制器,这种 pod 称为自主式 pod ;

这种自主式的 pod ,在删除时便会彻底删除;而通过控制器运行的 pod 在删除之后,控制器会自动再次新建一个 pod

[root@server2 ~]# kubectl delete pod demo 
pod "demo" deleted
[root@server2 ~]# kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   2d23h

常用操作:
参数 --restart=Never表示退出不重启;默认是会重启服务的。

[root@server2 ~]# kubectl run -i -t busybox --image=busybox --restart=Never
If you don't see a command prompt, try pressing enter.
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
3: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue 
    link/ether 8e:95:86:15:0e:38 brd ff:ff:ff:ff:ff:ff
    inet 10.244.2.3/24 brd 10.244.2.255 scope global eth0
       valid_lft forever preferred_lft forever
       
[root@server2 ~]# kubectl get pod	
##此时退出之后就不再重启
NAME      READY   STATUS      RESTARTS   AGE
busybox   0/1     Completed   0          26s
[root@server2 ~]# kubectl delete pod busybox 
pod "busybox" deleted
[root@server2 ~]# kubectl get pod
No resources found in default namespace.

[root@server2 ~]# kubectl run -i -t busybox --image=busybox
##不加参数时
If you don't see a command prompt, try pressing enter.
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
3: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue 
    link/ether 9a:d4:c9:6f:14:e9 brd ff:ff:ff:ff:ff:ff
    inet 10.244.2.4/24 brd 10.244.2.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # 
Session ended, resume using 'kubectl attach busybox -c busybox -i -t' command when the pod is running
[root@server2 ~]# kubectl get pod
##退出之后,自动重启,用命令可以进入 pod;
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   1          31s
[root@server2 ~]# kubectl attach busybox -c busybox -it
If you don't see a command prompt, try pressing enter.
/ # 
Session ended, resume using 'kubectl attach busybox -c busybox -i -t' command when the pod is running
[root@server2 ~]# kubectl get pod
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   2          2m11s

在用参加入 pod 时,第一个busybox 表示 pod 的名称,第二个表示 pod 内容器的名称,当容器中和只有一个容器时,此处可以不加容器名称;

  1. service
    service 是一个抽象概念,定义了一个服务的多个 pod 逻辑合集和访问 pod 的策略,一般把 service 称为微服务。

创建 service
再次创建一个 pod ,其还是运行在之前的主机上;k8s 的策略就是最小化原则,之前调度的节点已经完成了镜像的下载,所以会优先调度,不用再次下载;k8s 的镜像拉取策略时always,不管镜像存在与否,都会尝试去拉取,当检测到存在时,就不再拉取。有更新时便会更新。

[root@server2 ~]# kubectl run demo --image=myapp:v1
pod/demo created
[root@server2 ~]# kubectl get pod -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP           NODE      NOMINATED NODE   READINESS GATES
demo   1/1     Running   0          11s   10.244.2.5   server4   <none>           <none>

对于 ip 的动态变化,外部访问容器需要微服务;

deployment 控制器来新建 pod:此时创建的 pod 如果只删除 pod 是删不掉的,删除之后,控制器会再次拉起一个 pod,除非删除控制器。

[root@server2 ~]# kubectl delete pod demo
pod "demo" deleted
[root@server2 ~]# kubectl create deployment demo --image=myapp:v1
deployment.apps/demo created
[root@server2 ~]# kubectl get all
NAME                        READY   STATUS    RESTARTS   AGE
pod/demo-5b4fc8bb88-dvdkt   1/1     Running   0          7s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   2d23h

NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/demo   1/1     1            1           7s

NAME                              DESIRED   CURRENT   READY   AGE
replicaset.apps/demo-5b4fc8bb88   1         1         1       7s
[root@server2 ~]# kubectl delete pod demo-5b4fc8bb88-dvdkt
pod "demo-5b4fc8bb88-dvdkt" deleted
[root@server2 ~]# kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
demo-5b4fc8bb88-flfq8   1/1     Running   0          18s

动态拉伸:之前是一份,此时拉伸到

[root@server2 ~]# kubectl scale deployment --replicas=2 demo 
deployment.apps/demo scaled
[root@server2 ~]# kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
demo-5b4fc8bb88-flfq8   1/1     Running   0          3m1s
demo-5b4fc8bb88-g4vz8   1/1     Running   0          5s

暴露控制器的端口信息;

[root@server2 ~]# kubectl expose deployment demo --port 80 --target-port 80
service/demo exposed
[root@server2 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
demo         ClusterIP   10.111.253.254   <none>        80/TCP    10s
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   2d23h
[root@server2 ~]# kubectl describe svc demo
Name:              demo
Namespace:         default
Labels:            app=demo
Annotations:       <none>
Selector:          app=demo
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.111.253.254
IPs:               10.111.253.254
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.3:80,10.244.2.6:80
Session Affinity:  None
Events:            <none>
[root@server2 ~]# kubectl get pod -o wide
NAME                    READY   STATUS    RESTARTS   AGE    IP           NODE      NOMINATED NODE   READINESS GATES
demo-5b4fc8bb88-flfq8   1/1     Running   0          9m2s   10.244.2.6   server4   <none>           <none>
demo-5b4fc8bb88-g4vz8   1/1     Running   0          6m6s   10.244.1.3   server3   <none>           <none>

[root@server2 ~]# kubectl scale deployment --replicas=3 demo 
deployment.apps/demo scaled
[root@server2 ~]# kubectl describe svc demo
Name:              demo
Namespace:         default
Labels:            app=demo
Annotations:       <none>
Selector:          app=demo
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.111.253.254
IPs:               10.111.253.254
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.3:80,10.244.2.6:80,10.244.2.7:80
Session Affinity:  None
Events:            <none>
[root@server2 ~]# kubectl get pod -o wide
NAME                    READY   STATUS    RESTARTS   AGE     IP           NODE      NOMINATED NODE   READINESS GATES
demo-5b4fc8bb88-fkz6v   1/1     Running   0          86s     10.244.2.7   server4   <none>           <none>
demo-5b4fc8bb88-flfq8   1/1     Running   0          11m     10.244.2.6   server4   <none>           <none>
demo-5b4fc8bb88-g4vz8   1/1     Running   0          8m39s   10.244.1.3   server3   <none>           <none>

此时 pod 客户端可以通过 service 的名称访问后端的两个 Pod;
ClusterIP: 默认类型,自动分配一个仅集群内部可以访问的虚拟IP.

此时在访问时,三个后端是负载均衡的:

[root@server2 ~]# curl 10.111.253.254 
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@server2 ~]# curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-fkz6v
[root@server2 ~]# curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-flfq8
[root@server2 ~]# curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-fkz6v
[root@server2 ~]# curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-flfq8
[root@server2 ~]# curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-g4vz8
[root@server2 ~]# curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-fkz6v

缩减:

[root@server2 ~]# kubectl scale deployment --replicas=2 demo 
deployment.apps/demo scaled
[root@server2 ~]# kubectl describe svc demo
Name:              demo
Namespace:         default
Labels:            app=demo
Annotations:       <none>
Selector:          app=demo
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.111.253.254
IPs:               10.111.253.254
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.3:80,10.244.2.6:80
Session Affinity:  None
Events:            <none>
[root@server2 ~]# curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-g4vz8
[root@server2 ~]# curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-g4vz8
[root@server2 ~]# curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-flfq8
[root@server2 ~]# curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-flfq8

此时的 ClusterIP 只允许集群内访问;用镜像 busyboxplus来测试;
可以看到其内部是可以访问的,并且是负载均衡;

[root@server2 ~]# kubectl delete pod busybox 
pod "busybox" deleted
[root@server2 ~]# kubectl run -i -t busybox --image=busyboxplus --restart=Never
If you don't see a command prompt, try pressing enter.
/ # curl 10.111.253.254
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
/ # curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-g4vz8
/ # curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-g4vz8
/ # curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-flfq8
/ # curl 10.111.253.254/hostname.html
demo-5b4fc8bb88-g4vz8
/ # 
  • 使用 NodePort 类型暴露端口,让外部客户端访问 Pod;
[root@server2 ~]# kubectl edit svc demo  
service/demo edited

     28   sessionAffinity: None
     29   type: NodePort	##修改service的type为NodePort

[root@server2 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
demo         NodePort    10.111.253.254   <none>        80:30448/TCP   31m
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        3d

kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort 也可以在创建 service 时指定类型.

  • NodePort: 在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过 NodeIP:NodePort 来访问该服务;

此时外部主机在访问时可以指定端口:

[root@westos ~]# curl 172.25.25.2:30448
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@westos ~]# curl 172.25.25.2:30448/hostname.html
demo-5b4fc8bb88-g4vz8
##此时在访问集群中的任何一个节点都是可以的,并且是负载均衡的。
[root@westos ~]# curl 172.25.25.3:30448/hostname.html
demo-5b4fc8bb88-flfq8
[root@westos ~]# curl 172.25.25.3:30448/hostname.html
demo-5b4fc8bb88-g4vz8

扩容和所容必须是在控制器的基础上来做,自主式 pod 是不能做扩容和所容的。

更新pod镜像

在更新之后此时的 rc 就已经改变了;

[root@server2 ~]# kubectl set image deployment demo myapp=myapp:v2
deployment.apps/demo image updated
[root@server2 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
demo         NodePort    10.111.253.254   <none>        80:30448/TCP   37m
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        3d
[root@server2 ~]# curl 10.111.253.254
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@server2 ~]# kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
demo-7bd47bddfc-cr2bq   1/1     Running   0          30s
demo-7bd47bddfc-sslpv   1/1     Running   0          27s
```
回滚:
查看历史版本:

```php
[root@server2 ~]# kubectl rollout history deployment demo 
deployment.apps/demo 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

回滚版本:

[root@server2 ~]# kubectl rollout undo deployment demo --to-revision 1
deployment.apps/demo rolled back
[root@server2 ~]# curl 10.111.253.254
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@server2 ~]# kubectl get all
NAME                        READY   STATUS    RESTARTS   AGE
pod/demo-5b4fc8bb88-k9rc4   1/1     Running   0          14s
pod/demo-5b4fc8bb88-tdtng   1/1     Running   0          16s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/demo         NodePort    10.111.253.254   <none>        80:30448/TCP   40m
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        3d

NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/demo   2/2     2            2           49m

NAME                              DESIRED   CURRENT   READY   AGE
replicaset.apps/demo-5b4fc8bb88   2         2         2       49m
replicaset.apps/demo-7bd47bddfc   0         0         0       3m

2. 资源清单

回收:

[root@server2 ~]# kubectl delete svc demo 
service "demo" deleted
[root@server2 ~]# kubectl delete deployments.apps demo 
deployment.apps "demo" deleted
[root@server2 ~]# kubectl get pod
No resources found in default namespace.

建立自主式 pod 的清单文件:

[root@server2 ~]# mkdir k8s
[root@server2 ~]# cd k8s/
[root@server2 k8s]# kubectl api-versions  	##查看版本
[root@server2 k8s]# kubectl explain pod		##查看帮助
[root@server2 k8s]# kubectl explain pod.spec
[root@server2 k8s]# vim pod.yaml 
[root@server2 k8s]# cat pod.yaml 
---
apiVersion: v1	
##指明api资源属于哪个群组和版本,同一个组可以有多个版本
kind: Pod
##标记创建的资源类型,k8s主要支持以下资源类别:       (Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet,Job,Cronjob)
metadata:		##元数据
  name: demo	##对像名称
spec:			##定义目标资源的期望状态
  containers:	##容器
  - name: demo
    image: myapp:v1

其中还有一些常用参数如:namespace表示对象属于哪个命名空间;labels表示指定资源标签,标签是一种键值数据。
以上在书写的过程中都可以用帮助命令来查看:kubectl explain pod
使清单生效:

[root@server2 k8s]# kubectl apply -f pod.yaml 
pod/demo created
[root@server2 k8s]# kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
demo   1/1     Running   0          2m17s
[root@server2 k8s]# kubectl get all
NAME       READY   STATUS    RESTARTS   AGE
pod/demo   1/1     Running   0          2m19s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   3d2h
[root@server2 k8s]# kubectl delete -f pod.yaml 	##删除pod
pod "demo" deleted

注:同一个清单文件中,写入两个 pod 时,如果

以上是关于运维实战 kubernetes(k8s) 之 pod 的建立的主要内容,如果未能解决你的问题,请参考以下文章

运维实战 kubernetes(k8s) 之 pod 的建立

运维实战 kubernetes(k8s) 之 pod 的建立

Kubernetes/K8s运维架构师实战

运维实战 kubernetes(k8s) 的简介和部署

Kubernetes/K8s CKA 认证实战班(K8s运维工程师) 李振良

Kubernetes/K8s CKA 认证实战班(K8s运维工程师) 李振良