赞
踩
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
再次创建一个 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
/ #
[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 时指定类型.
此时外部主机在访问时可以指定端口:
[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
回收:
[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 时,如果两个 pod 用的是一个端口,只能启动一个;
同一个 pod 中使用的是同一个网络接口。
如以下清单文件在生成 pod 时;当两个 pod 占用一个端口时,会有一个启动失败;
[root@server2 k8s]# kubectl delete -f pod.yaml pod "demo" deleted [root@server2 k8s]# vim pod.yaml [root@server2 k8s]# cat pod.yaml --- apiVersion: v1 kind: Pod metadata: name: demo spec: containers: - name: demo image: myapp:v1 - name: demo2 image: myapp:v2 [root@server2 k8s]# kubectl apply -f pod.yaml pod/demo created [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE demo 1/2 Error 1 9s [root@server2 k8s]# kubectl describe pod demo Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 27s default-scheduler Successfully assigned default/demo to server3 Normal Pulled 26s kubelet Container image "myapp:v1" already present on machine Normal Created 26s kubelet Created container demo Normal Started 25s kubelet Started container demo Normal Pulled 7s (x3 over 25s) kubelet Container image "myapp:v2" already present on machine Normal Created 6s (x3 over 25s) kubelet Created container demo2 Normal Started 6s (x3 over 25s) kubelet Started container demo2 Warning BackOff 3s (x2 over 19s) kubelet Back-off restarting failed container
再次修改清单文件,来测试同一个 pod 中的容器使用的是同一个网络接口;
[root@server2 k8s]# kubectl delete -f pod.yaml pod "demo" deleted [root@server2 k8s]# vim pod.yaml [root@server2 k8s]# cat pod.yaml --- apiVersion: v1 kind: Pod metadata: name: demo spec: containers: - name: demo image: myapp:v1 - name: busybox image: busyboxplus stdin: true tty: true [root@server2 k8s]# kubectl apply -f pod.yaml pod/demo created [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE demo 2/2 Running 0 12s [root@server2 k8s]# kubectl attach demo -c busybox -it ##加入进去 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@if15: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue link/ether 92:89:66:28:58:09 brd ff:ff:ff:ff:ff:ff inet 10.244.2.11/24 brd 10.244.2.255 scope global eth0 valid_lft forever preferred_lft forever / # curl localhost Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> ##可以看到虽然连的是 busybox ,但是访问到的是 myapp的信息
清单文件的参数:
always
;[root@server2 k8s]# kubectl delete -f pod.yaml pod "demo" deleted [root@server2 k8s]# vim pod.yaml [root@server2 k8s]# cat pod.yaml --- apiVersion: v1 kind: Pod metadata: name: demo spec: containers: - name: demo image: myapp:v1 imagePullPolicy: IfNotPresent #- name: busybox # image: busyboxplus # stdin: true # tty: true [root@server2 k8s]# kubectl apply -f pod.yaml pod/demo created [root@server2 k8s]# kubectl describe pod demo Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 26s default-scheduler Successfully assigned default/demo to server4 Normal Pulled 25s kubelet Container image "myapp:v1" already present on machine Normal Created 25s kubelet Created container demo Normal Started 25s kubelet Started container demo
[root@server2 k8s]# kubectl delete -f pod.yaml pod "demo" deleted [root@server2 k8s]# vim pod.yaml [root@server2 k8s]# cat pod.yaml --- apiVersion: v1 kind: Pod metadata: name: demo spec: containers: - name: demo image: myapp:v1 imagePullPolicy: IfNotPresent hostNetwork: true #- name: busybox # image: busyboxplus # stdin: true # tty: true [root@server2 k8s]# kubectl apply -f pod.yaml pod/demo created [root@server2 k8s]# kubectl get pod -o wide ##可以看到和宿主机使用相同的网路 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES demo 1/1 Running 0 10s 172.25.25.4 server4 <none> <none> [root@westos ~]# curl 172.25.25.4 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@server2 k8s]# kubectl delete -f pod.yaml pod "demo" deleted [root@server2 k8s]# vim pod.yaml [root@server2 k8s]# cat pod.yaml --- apiVersion: v1 kind: Pod metadata: name: demo spec: containers: - name: demo image: myapp:v1 imagePullPolicy: IfNotPresent resources: limits: ##上限 cpu: 1 memory: 100Mi requests: ##下线 cpu: 0.5 memory: 50Mi #hostNetwork: true #- name: busybox # image: busyboxplus # stdin: true # tty: true [root@server2 k8s]# kubectl apply -f pod.yaml pod/demo created [root@server2 k8s]# kubectl describe pod demo Restart Count: 0 Limits: cpu: 1 memory: 100Mi Requests: cpu: 500m memory: 50Mi Environment: <none>
server4
可以通过主机名来将其调度到server3
,优先级最高,但是当server3 不存在时就有问题;[root@server2 k8s]# vim pod.yaml [root@server2 k8s]# cat pod.yaml --- apiVersion: v1 kind: Pod metadata: name: demo spec: containers: - name: demo image: myapp:v1 imagePullPolicy: IfNotPresent resources: limits: cpu: 1 memory: 100Mi requests: cpu: 0.5 memory: 50Mi nodeName: server3 #hostNetwork: true #- name: busybox # image: busyboxplus # stdin: true # tty: true [root@server2 k8s]# kubectl apply -f pod.yaml pod/demo created [root@server2 k8s]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES demo 1/1 Running 0 10s 10.244.1.9 server3 <none> <none>
当调度到的主机名不存在时,此时就会失败;
下面来使用标签:
[root@server2 k8s]# kubectl delete -f pod.yaml pod "demo" deleted [root@server2 k8s]# kubectl get node --show-labels NAME STATUS ROLES AGE VERSION LABELS server2 Ready control-plane,master 3d3h v1.21.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=server2,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers= server3 Ready <none> 3d3h v1.21.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=server3,kubernetes.io/os=linux server4 Ready <none> 3d3h v1.21.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=server4,kubernetes.io/os=linux [root@server2 k8s]# kubectl label nodes server3 app=demo node/server3 labeled [root@server2 k8s]# kubectl label nodes server4 app=demo node/server4 labeled [root@server2 k8s]# kubectl get node --show-labels NAME STATUS ROLES AGE VERSION LABELS server2 Ready control-plane,master 3d3h v1.21.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=server2,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers= server3 Ready <none> 3d3h v1.21.1 app=demo,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=server3,kubernetes.io/os=linux server4 Ready <none> 3d3h v1.21.1 app=demo,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=server4,kubernetes.io/os=linux
为server3
和server4
都加上标签,当一个退出时,会自动调度到另外一个上;
[root@server2 k8s]# cat pod.yaml --- apiVersion: v1 kind: Pod metadata: name: demo spec: containers: - name: demo image: myapp:v1 imagePullPolicy: IfNotPresent resources: limits: cpu: 1 memory: 100Mi requests: cpu: 0.5 memory: 50Mi nodeSelector: app: demo #nodeName: server3 #hostNetwork: true #- name: busybox # image: busyboxplus # stdin: true # tty: true [root@server2 k8s]# kubectl apply -f pod.yaml pod/demo created [root@server2 k8s]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES demo 1/1 Running 0 34s 10.244.1.10 server3 <none> <none> [root@server2 k8s]# kubectl delete -f pod.yaml pod "demo" deleted [root@server2 k8s]# kubectl label nodes server3 app=test error: 'app' already has a value (demo), and --overwrite is false [root@server2 k8s]# kubectl label nodes server3 app=test --overwrite node/server3 labeled [root@server2 k8s]# kubectl apply -f pod.yaml pod/demo created [root@server2 k8s]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES demo 1/1 Running 0 9s 10.244.2.14 server4 <none> <none>
除了写的方式以外,官网还有许多例子贡参考学习。
将之前的pod回收:
[root@server2 k8s]# kubectl get pod
NAME READY STATUS RESTARTS AGE
busybox 0/1 Completed 0 154m
[root@server2 k8s]# kubectl delete pod busybox
pod "busybox" deleted
[root@server2 k8s]# kubectl get pod
No resources found in default namespace.
创建svc
服务:
[root@server2 k8s]# vim svc.yaml [root@server2 k8s]# cat svc.yaml --- apiVersion: v1 kind: Service metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 80 [root@server2 k8s]# kubectl apply -f svc.yaml service/myservice created [root@server2 k8s]# kubectl get svc ##服务成功创建 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d4h myservice ClusterIP 10.110.126.152 <none> 80/TCP 9s [root@server2 k8s]# kubectl describe svc myservice Name: myservice Namespace: default Labels: <none> Annotations: <none> Selector: <none> Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10.110.126.152 IPs: 10.110.126.152 Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: <none> Session Affinity: None Events: <none>
[root@server2 k8s]# kubectl delete -f svc.yaml service "myservice" deleted [root@server2 k8s]# vim pod.yaml [root@server2 k8s]# cat pod.yaml --- apiVersion: v1 kind: Pod metadata: name: demo spec: containers: - name: demo image: myapp:v1 imagePullPolicy: IfNotPresent resources: limits: cpu: 1 memory: 100Mi requests: cpu: 0.5 memory: 50Mi initContainers: - name: busybox image: busyboxplus command: ['sh','-c', "until nslookup myservice.default.svc.cluster.local; do echo waiting for myservice; sleep 2; done"] [root@server2 k8s]# kubectl apply -f pod.yaml pod/demo created [root@server2 k8s]# kubectl get pod ##一直在初始化状态 NAME READY STATUS RESTARTS AGE demo 0/1 Init:0/1 0 7s [root@server2 k8s]# kubectl logs demo ##看其日志是等待初始化完成 Error from server (BadRequest): container "demo" in pod "demo" is waiting to start: PodInitializing [root@server2 k8s]# kubectl logs demo -c busybox waiting for myservice nslookup: can't resolve 'myservice.default.svc.cluster.local' [root@server2 k8s]# kubectl apply -f svc.yaml service/myservice created [root@server2 k8s]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d4h myservice ClusterIP 10.98.229.110 <none> 80/TCP 10s [root@server2 k8s]# kubectl logs demo [root@server2 k8s]# kubectl logs demo -c busybox Name: myservice.default.svc.cluster.local Address 1: 10.98.229.110 myservice.default.svc.cluster.local [root@server2 k8s]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d4h myservice ClusterIP 10.98.229.110 <none> 80/TCP 2m11s [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE demo 1/1 Running 0 5m4s
在运行结束之后,即使删除初始化容器,pod 也还是运行,因为运行pod 是在初始化结束之后进行的。
kubelet
对容器执行的定期诊断:ExecAction
:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。TCPSocketAction
:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。HTTPGetAction
:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。Kubelet
可以选择是否执行在容器上运行的三种探针执行和做出反应:livenessProbe
:指示容器是否正在运行。如果存活探测失败,则 kubelet
会杀死容器,并且容器将受到其重启策略的影响。如果容器不提供存活探针,则默认状态为 Success。readinessProbe
:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。startupProbe
: 指示容器中的应用是否已经启动。如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet 将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探测,则默认状态为成功Success。PodSpec
中有一个 restartPolicy 字段,可能的值为 Always、OnFailure 和 Never。默认为 Always。ReplicationController
、ReplicaSet
和 Deployment
,例如 Web 服务器。 ReplicationController
仅适用于具有 restartPolicy 为 Always 的 Pod。DaemonSet
为每台机器运行一个 Pod 。[root@server2 k8s]# vim deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: deployment-example spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: myapp:v1 livenessProbe: ##存活探针 tcpSocket: port: 80 ##检测端口信息 initialDelaySeconds: 2 ##初始化完成之后2s再开始检测 periodSeconds: 3 ##每隔3s检测一次 timeoutSeconds: 1 ##检测超时 [root@server2 k8s]# kubectl apply -f deployment.yaml deployment.apps/deployment-example created [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE deployment-example-857bf7b8d7-gstst 1/1 Running 0 16s [root@server2 k8s]# kubectl describe pod deployment-example-857bf7b8d7-5smfw Ready: True Restart Count: 0 Liveness: tcp-socket :80 delay=2s timeout=1s period=3s #success=1 #failure=3 Environment: <none>
修改为一个不正确的端口再次检测一下:
[root@server2 k8s]# kubectl delete -f deployment.yaml deployment.apps "deployment-example" deleted [root@server2 k8s]# vim deployment.yaml [root@server2 k8s]# cat deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: deployment-example spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: myapp:v1 livenessProbe: tcpSocket: port: 8080 initialDelaySeconds: 2 periodSeconds: 3 timeoutSeconds: 1 [root@server2 k8s]# kubectl apply -f deployment.yaml deployment.apps/deployment-example created [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE deployment-example-5d4c89ff67-glrrk 1/1 Running 3 50s [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE deployment-example-5d4c89ff67-glrrk 0/1 CrashLoopBackOff 4 76s
此时错误的端口会一直报错,检测不到启动信息,会一直尝试重启;
[root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE deployment-example-857bf7b8d7-9d8wl 1/1 Running 0 7s [root@server2 k8s]# vim deployment.yaml readinessProbe: ##加入就绪探针 httpGet: path: /test.html port: 80 initialDelaySeconds: 1 periodSeconds: 3 timeoutSeconds: 1 [root@server2 k8s]# kubectl apply -f deployment.yaml deployment.apps/deployment-example configured [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE deployment-example-7c8698d5bb-s97dq 0/1 Running 0 60s deployment-example-857bf7b8d7-9d8wl 1/1 Running 0 115s [root@server2 k8s]# kubectl describe pod deployment-example-7c8698d5bb-s97dq ##404错误,页面访问不到 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 77s default-scheduler Successfully assigned default/deployment-example-7c8698d5bb-s97dq to server4 Normal Pulled 77s kubelet Container image "myapp:v1" already present on machine Normal Created 77s kubelet Created container nginx Normal Started 77s kubelet Started container nginx Warning Unhealthy 12s (x22 over 75s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 404 [root@server2 k8s]# kubectl exec -it deployment-example-7c8698d5bb-s97dq -- sh ##进入容器中,编写发布页面信息 / # cd /usr/share/nginx/html/ /usr/share/nginx/html # ls 50x.html index.html /usr/share/nginx/html # echo www.westos.org > test.html /usr/share/nginx/html # cat test.html www.westos.org /usr/share/nginx/html # [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE deployment-example-7c8698d5bb-s97dq 1/1 Running 0 5m31s [root@server2 k8s]# kubectl describe pod deployment-example-7c8698d5bb-s97dq Liveness: tcp-socket :80 delay=2s timeout=1s period=3s #success=1 #failure=3 Readiness: http-get http://:80/test.html delay=1s timeout=1s period=3s #success=1 #failure=3
Replication Controller
和ReplicaSet
Deployment
DaemonSet
[root@server2 k8s]# kubectl -n kube-system get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
coredns 2/2 2 2 3d6h
[root@server2 k8s]# kubectl -n kube-system get daemonsets.apps
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-flannel-ds 3 3 3 3 3 <none> 3d6h
kube-proxy 3 3 3 3 3 kubernetes.io/os=linux 3d6h
StatefulSet
Job
CronJob
HPA
,必须要有指标参数;默认的只有cpu和内存,其他的需要第三方软件提供。[root@server2 k8s]# vim rs.yaml [root@server2 k8s]# cat rs.yaml apiVersion: apps/v1 kind: ReplicaSet metadata: name: replicaset-example spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: myapp:v1 [root@server2 k8s]# kubectl apply -f rs.yaml replicaset.apps/replicaset-example created [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE replicaset-example-fgsz7 1/1 Running 0 16s replicaset-example-p94zg 1/1 Running 0 16s replicaset-example-vt8t7 1/1 Running 0 16s
由于 rs
能确保任何时间都有指定数量的 Pod 副本在运行,当修改其中一个标签之后,会检测到少于指定数量会再次拉起一个 pod 来;当发现多于指定数量时,会立即会收掉多余的 pod;rs
在控制副本时,是通过标签来实现的;
[root@server2 k8s]# kubectl get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS replicaset-example-fgsz7 1/1 Running 0 32s app=nginx replicaset-example-p94zg 1/1 Running 0 32s app=nginx replicaset-example-vt8t7 1/1 Running 0 32s app=nginx [root@server2 k8s]# kubectl label pod replicaset-example-fgsz7 app=myapp --overwrite pod/replicaset-example-fgsz7 labeled [root@server2 k8s]# kubectl get pod --show-labels ##此时被改过标签的pod 并不在 rs 的管理范围内 NAME READY STATUS RESTARTS AGE LABELS replicaset-example-fgsz7 1/1 Running 0 2m19s app=myapp replicaset-example-p94zg 1/1 Running 0 2m19s app=nginx replicaset-example-rwbxk 1/1 Running 0 10s app=nginx replicaset-example-vt8t7 1/1 Running 0 2m19s app=nginx [root@server2 k8s]# kubectl get rs NAME DESIRED CURRENT READY AGE replicaset-example 3 3 3 2m8s [root@server2 k8s]# kubectl delete -f rs.yaml replicaset.apps "replicaset-example" deleted [root@server2 k8s]# kubectl get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS replicaset-example-fgsz7 1/1 Running 0 6m23s app=myapp [root@server2 k8s]# kubectl delete pod replicaset-example-fgsz7 ##将其看做自主式的pod来删除 pod "replicaset-example-fgsz7" deleted [root@server2 k8s]# kubectl get pod No resources found in default namespace.
[root@server2 k8s]# kubectl apply -f rs.yaml
replicaset.apps/replicaset-example created
[root@server2 k8s]# kubectl get pod
NAME READY STATUS RESTARTS AGE
replicaset-example-bt6gs 1/1 Running 0 7s
replicaset-example-c55p7 1/1 Running 0 7s
replicaset-example-vh7sl 1/1 Running 0 7s
[root@server2 k8s]# kubectl delete pod replicaset-example-bt6gs
pod "replicaset-example-bt6gs" deleted
[root@server2 k8s]# kubectl get pod
NAME READY STATUS RESTARTS AGE
replicaset-example-c55p7 1/1 Running 0 44s
replicaset-example-jkslv 1/1 Running 0 18s
replicaset-example-vh7sl 1/1 Running 0 44s
此时在让Deployment
控制器生效时,还有一个 rs
;
[root@server2 k8s]# vim deployment.yaml [root@server2 k8s]# cat deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: deployment-example spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: myapp:v1 livenessProbe: tcpSocket: port: 80 initialDelaySeconds: 2 periodSeconds: 3 timeoutSeconds: 1 readinessProbe: httpGet: path: /hostname.html port: 80 initialDelaySeconds: 1 periodSeconds: 3 timeoutSeconds: 1 [root@server2 k8s]# kubectl apply -f deployment.yaml deployment.apps/deployment-example created [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE deployment-example-5b768f7647-tjkkk 1/1 Running 0 4s [root@server2 k8s]# kubectl get all NAME READY STATUS RESTARTS AGE pod/deployment-example-5b768f7647-tjkkk 1/1 Running 0 12s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d7h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/deployment-example 1/1 1 1 12s NAME DESIRED CURRENT READY AGE replicaset.apps/deployment-example-5b768f7647 1 1 1 12s [root@server2 k8s]# kubectl get rs NAME DESIRED CURRENT READY AGE deployment-example-5b768f7647 1 1 1 5m32s
来修改Deployment
控制器来观察 rs
的效果:
[root@server2 k8s]# vim deployment.yaml
replicas: 3
selector:
[root@server2 k8s]# kubectl apply -f deployment.yaml
deployment.apps/deployment-example configured
[root@server2 k8s]# kubectl get pod
NAME READY STATUS RESTARTS AGE
deployment-example-5b768f7647-4l244 1/1 Running 0 16s
deployment-example-5b768f7647-7456n 1/1 Running 0 16s
deployment-example-5b768f7647-tjkkk 1/1 Running 0 4m26s
[root@server2 k8s]# kubectl get rs
NAME DESIRED CURRENT READY AGE
deployment-example-5b768f7647 3 3 3 4m56s
更新镜像,更新完成之后,前面的还在方便回滚。
[root@server2 k8s]# vim deployment.yaml
- name: nginx
image: myapp:v2
[root@server2 k8s]# kubectl apply -f deployment.yaml
[root@server2 k8s]# kubectl get rs
NAME DESIRED CURRENT READY AGE
deployment-example-5b768f7647 0 0 0 7m25s
deployment-example-65d9654644 3 3 3 18s
[root@server2 k8s]# curl 10.244.2.27
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@server2 k8s]# vim daemonset.yaml [root@server2 k8s]# cat daemonset.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: daemonset-example labels: k8s-app: zabbix-agent spec: selector: matchLabels: name: zabbix-agent template: metadata: labels: name: zabbix-agent spec: containers: - name: zabbix-agent image: myapp:v1 [root@server2 k8s]# kubectl apply -f daemonset.yaml daemonset.apps/daemonset-example created [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE daemonset-example-8zwbg 1/1 Running 0 20s daemonset-example-vtftj 1/1 Running 0 20s [root@server2 k8s]# kubectl get node NAME STATUS ROLES AGE VERSION server2 Ready control-plane,master 3d7h v1.21.1 server3 Ready <none> 3d7h v1.21.1 server4 Ready <none> 3d7h v1.21.1 [root@server2 k8s]# kubectl describe nodes server2 | grep Tain ##由于server2默认是不参加调度的 Taints: node-role.kubernetes.io/master:NoSchedule [root@server2 k8s]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES daemonset-example-8zwbg 1/1 Running 0 105s 10.244.2.29 server4 <none> <none> daemonset-example-vtftj 1/1 Running 0 105s 10.244.1.24 server3 <none> <none>
用控制器来做一次计算pi
的值,计算到小数点后1000位;
[root@server2 k8s]# vim job.yaml [root@server2 k8s]# cat job.yaml apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers: - name: pi image: perl command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(1000)"] restartPolicy: Never backoffLimit: 4 [root@server2 k8s]# kubectl apply -f job.yaml job.batch/pi created [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE pi-nt9vb 0/1 ContainerCreating 0 10s [root@server2 k8s]# kubectl describe pod pi Normal Pulled 9s kubelet Successfully pulled image "perl" in 1m2.625821525s Normal Created 9s kubelet Created container pi Normal Started 9s kubelet Started container pi [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE pi-nt9vb 0/1 Completed 0 98s [root@server2 k8s]# kubectl logs pi-nt9vb ##查看 pi 的计算结果 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420199
[root@server2 k8s]# vim cronjob.yaml [root@server2 k8s]# cat cronjob.yaml apiVersion: batch/v1beta1 kind: CronJob metadata: name: cronjob-example spec: schedule: "* * * * *" ##每分钟做一次 jobTemplate: spec: template: spec: containers: - name: cronjob image: busybox args: - /bin/sh - -c - date; echo Hello from k8s cluster restartPolicy: OnFailure [root@server2 k8s]# kubectl apply -f cronjob.yaml Warning: batch/v1beta1 CronJob is deprecated in v1.21+, unavailable in v1.25+; use batch/v1 CronJob cronjob.batch/cronjob-example created [root@server2 k8s]# kubectl get cronjobs.batch NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE cronjob-example * * * * * False 0 <none> 55s [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE cronjob-example-27051133-zxdxs 0/1 ContainerCreating 0 1s [root@server2 k8s]# kubectl get cronjobs.batch NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE cronjob-example * * * * * False 0 <none> 21s [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE cronjob-example-27048096-8h5zs 0/1 Completed 0 10s [root@server2 k8s]# kubectl logs cronjob-example-27048096-8h5zs Sat Jun 5 09:36:00 UTC 2021 Hello from k8s cluster [root@server2 k8s]# kubectl get pod NAME READY STATUS RESTARTS AGE cronjob-example-27048096-8h5zs 0/1 Completed 0 82s cronjob-example-27048097-258jf 0/1 Completed 0 22s [root@server2 k8s]# kubectl logs cronjob-example-27048096-8h5zs Sat Jun 5 09:36:00 UTC 2021 Hello from k8s cluster
当一分钟之后,才会再次更新
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。