运维实战 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
- 创建
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 上;每个节点上的网段是不同的;默认情况下 k8s
的 master
不参加调度,网段应该是 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
内容器的名称,当容器中和只有一个容器时,此处可以不加容器名称;
- 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 的建立