1、资源管理介绍
在kubernetes中,所有的内容都抽象为资源,用户需要通过操作资源来管理kubernetes。
kubernetes的本质上就是一个集群系统,用户可以在集群中部署各种服务。
所谓的部署服务,其实就是在kubernetes集群中运行一个个的容器,并将指定的程序跑在容器中。
kubernetes的最小管理单元是pod而不是容器,只能将容器放在 Pod中。
kubernetes一般也不会直接管理Pod,而是通过 Pod控制器 来管理Pod的。
Pod中服务服务的访问是由kubernetes提供的 service 资源来实现。
Pod中程序的数据需要持久化是由kubernetes提供的各种存储系统来实现。
2、资源管理方式
命令式对象管理:直接使用命令去操作kubernetes资源
[root@k8s-master ~]# kubectl run nginx-pod --image lhd/nginx:latest --port=80
命令式对象配置:通过命令配置和配置文件去操作kubernetes资源
[root@k8s-master ~]# kubectl create/patch -f nginx-pod.yaml
声明式对象配置:通过apply命令和配置文件去操作kubernetes资源
[root@k8s-master ~]# kubectl apply -f nginx-pod.yaml
2.1 命令式对象管理
kubectl是kubernetes集群的命令行工具,通过它能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署
kubectl [command] [type] [name] [flags]
comand:指定要对资源执行的操作,例如create、get、delete
type:指定资源类型,比如deployment、pod、service
name:指定资源的名称,名称大小写敏感
flags:指定额外的可选参数
[root@k8s-master ~]# kubectl get pod #查看所有pod
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 6s
[root@k8s-master ~]# kubectl get pod nginx-pod #查看某个pod
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 20m
[root@k8s-master ~]# kubectl get pod nginx-pod -o yaml #查看某个pod以yaml格式展示
2.2 资源类型
2.3 基本命令示例
[root@k8s-master ~]# kubectl version #查看集群版本
Client Version: v1.30.0
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.30.0
[root@k8s-master ~]# kubectl cluster-info #查看集群信息
Kubernetes control plane is running at https://192.168.182.10:6443
CoreDNS is running at https://192.168.182.10:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxyTo further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
#创建一个webcluster控制器,控制器中pod数量为2
[root@k8s-master ~]# kubectl create deployment webcluster --image lhd/nginx --replicas 2
deployment.apps/webcluster created
[root@k8s-master ~]# kubectl get deployments.apps #查看控制器
NAME READY UP-TO-DATE AVAILABLE AGE
webcluster 2/2 2 2 8s
[root@k8s-master ~]# kubectl explain deployment #查看资源帮助[root@k8s-master ~]# kubectl explain deployment.spec #查看控制器参数帮助
[root@k8s-master ~]# kubectl edit deployments.apps #编辑控制器配置
#利用补丁更改控制器配置
[root@k8s-master ~]# kubectl patch deployments.apps webcluster -p '{"spec":{"replicas":4}}'
deployment.apps/webcluster patched
[root@k8s-master ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
webcluster 4/4 4 4 8m38s
#删除资源[root@k8s-master ~]# kubectl delete deployments.apps webcluster
deployment.apps "webcluster" deleted
2.4 运行和调试命令示例
[root@k8s-master ~]# kubectl run nginx-pod --image lhd/nginx
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 39m#端口暴漏
[root@k8s-master ~]# kubectl expose pod nginx-pod --port 80 --target-port 80
service/nginx-pod exposed
[root@k8s-master ~]# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d16h
nginx-pod ClusterIP 10.100.208.73 <none> 80/TCP 6s
[root@k8s-master ~]# curl 10.100.208.73
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
#查看资源详细信息[root@k8s-master ~]# kubectl describe pods nginx-pod
#查看资源日志[root@k8s-master ~]# kubectl logs pods/nginx-pod
#运行交互pod
[root@k8s-master ~]# kubectl run -it testpod --image lhd/busybox
If you don't see a command prompt, try pressing enter.
/ #
/ # #Ctrl + pq退出不停止pod#进入到已经运行的容器,且容器有交互环境
[root@k8s-master ~]# kubectl attach pods/testpod -it
If you don't see a command prompt, try pressing enter.
/ #
/ #
#在已经运行的pod中运行指定命令[root@k8s-master ~]# kubectl exec -it pods/nginx /bin/bash
#日志文件到pod中[root@k8s-master ~]# kubectl cp anaconda-ks.cfg nginx:/
[root@k8s-master ~]# kubectl exec -it pods/nginx /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx:/# ls
anaconda-ks.cfg dev etc lib64 opt run sys var
bin docker-entrypoint.d home media proc sbin tmp
boot docker-entrypoint.sh lib mnt root srv usr
root@nginx:/#
#复制pod中的文件到本机[root@k8s-master ~]# kubectl cp nginx:/anaconda-ks.cfg anaconda-ks.cfg
2.5 高级命令示例
#利用命令生成yaml模板文件
[root@k8s-master ~]# kubectl create deployment --image lhd/nginx webcluster --dry-run=client -o yaml > webcluster.yml
[root@k8s-master ~]# vim webcluster.yml
[root@k8s-master ~]# kubectl apply -f webcluster.yml
deployment.apps/webcluster create[root@k8s-master ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
webcluster 2/2 2 2 64s
[root@k8s-master ~]# kubectl delete -f webcluster.yml #删除控制器#管理资源标签
[root@k8s-master ~]# kubectl label pods nginx app=lhd #添加标签
pod/nginx labeled
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 18m app=lhd,run=nginx
#更改标签[root@k8s-master ~]# kubectl label pods nginx app=webcluster --overwrite
pod/nginx labeled
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 20m app=webcluster,run=nginx
#删除标签[root@k8s-master ~]# kubectl label pods nginx app-
pod/nginx unlabeled
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 21m run=nginx
#标签时控制器识别pod示例的标识[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 23m run=nginx
webcluster-75bfd95b8f-bqj57 1/1 Running 0 9s app=webcluster,pod-template-hash=75bfd95b8f
webcluster-75bfd95b8f-km9vs 1/1 Running 0 9s app=webcluster,pod-template-hash=75bfd95b8f
#删除pod上的标签
[root@k8s-master ~]# kubectl label pods webcluster-75bfd95b8f-bqj57 app-
pod/webcluster-75bfd95b8f-bqj57 unlabeled#控制器会重新启动新的pod
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 25m run=nginx
webcluster-75bfd95b8f-bqj57 1/1 Running 0 89s pod-template-hash=75bfd95b8f
webcluster-75bfd95b8f-jkcz5 1/1 Running 0 8s app=webcluster,pod-template-hash=75bfd95b8f
webcluster-75bfd95b8f-km9vs 1/1 Running 0 89s app=webcluster,pod-template-hash=75bfd95b8f
3、什么是pod
Pod是可以创建和管理Kubernetes计算的最小可部署单元。
个Pod代表着集群中运行的一个进程,每个pod都有一个唯一的ip。
个pod类似一个豌豆英,包含一个或多个容器(通常是docker)。
多个容器间共享IPC、Network和UTCnamespace。
3.1 创建自主式pod(生产环境不推荐)
#显示pod的较为详细的信息
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 35m 10.244.2.2 k8s-node2 <none> <none>
webcluster-75bfd95b8f-9ct4f 1/1 Running 0 6m46s 10.244.1.5 k8s-node1 <none> <none>
webcluster-75bfd95b8f-km9vs 1/1 Running 0 11m 10.244.2.4 k8s-node2 <none> <none>
3.2 利用控制器管理pod
#建立控制器并自动运行pod
[root@k8s-master ~]# kubectl create deployment lhd --image lhd/nginx
deployment.apps/lhd created
#为lhd扩容[root@k8s-master ~]# kubectl scale deployment lhd --replicas 6
deployment.apps/lhd scaled
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
lhd-8dfccfd4f-6j9jt 1/1 Running 0 2s
lhd-8dfccfd4f-6rgnk 1/1 Running 0 2s
lhd-8dfccfd4f-85624 1/1 Running 0 2s
lhd-8dfccfd4f-fb7jd 1/1 Running 0 70s
lhd-8dfccfd4f-jtnrr 1/1 Running 0 2s
lhd-8dfccfd4f-nph4w 1/1 Running 0 2s
#为lhd缩容[root@k8s-master ~]# kubectl scale deployment lhd --replicas 2
deployment.apps/lhd scaled
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
lhd-8dfccfd4f-fb7jd 1/1 Running 0 107s
lhd-8dfccfd4f-jtnrr 1/1 Running 0 39s
3.3 应用版本的更新
#利用控制器建立pod,暴漏端口并访问服务
[root@k8s-master ~]# kubectl create deployment lhd --image lhd/myapp:v1 --replicas 2
deployment.apps/lhd created
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
lhd-66c684b494-6lmm4 1/1 Running 0 6s
lhd-66c684b494-9kp7r 1/1 Running 0 6s
[root@k8s-master ~]# kubectl expose deployment lhd --port 80 --target-port 80
service/lhd exposed
[root@k8s-master ~]# curl 10.98.157.207
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
#查看历史版本[root@k8s-master ~]# kubectl rollout history deployment lhd
deployment.apps/lhd
REVISION CHANGE-CAUSE
1 <none>
#更新控制器镜像版本,查看历史版本[root@k8s-master ~]# kubectl set image deployments/lhd myapp=lhd/myapp:v2
deployment.apps/lhd image updated
[root@k8s-master ~]# kubectl rollout history deployment lhd
deployment.apps/lhd
REVISION CHANGE-CAUSE
1 <none>
2 <none>
#访问内容测试[root@k8s-master ~]# curl 10.98.157.207
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
#版本的回滚[root@k8s-master ~]# kubectl rollout undo deployment lhd --to-revision 1
deployment.apps/lhd rolled back
[root@k8s-master ~]# curl 10.98.157.207
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
3.4 利用yaml文件部署应用
3.4.1 如何获得资源帮助
[root@k8s-master ~]# kubectl explain pod.spec.containers
3.4.2 示例1:运行简单的单个容器pod
[root@k8s-master pod]# kubectl run lhd --image lhd/myapp:v1 --dry-run=client -o yaml > pod.yml
[root@k8s-master pod]# vim pod.yml[root@k8s-master pod]# kubectl apply -f pod.yml
pod/lhd created
[root@k8s-master pod]# kubectl get pods
NAME READY STATUS RESTARTS AGE
lhd 1/1 Running 0 22s
3.4.3 示例2:运行多个容器pod
注意若多个容器运行在一个pod中,资源共享的同时在使用相同资源时也会干扰,如端口
#在一个pod中开启多个容器时一定要确保容器彼此不能互相干扰
[root@k8s-master pod]# vim pod.yml
3.4.4 示例3:理解pod间的网络整合
[root@k8s-master pod]# vim pod2.yml
[root@k8s-master pod]# kubectl apply -f pod2.yml
pod/test created
[root@k8s-master pod]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test 2/2 Running 0 6s
[root@k8s-master pod]# kubectl exec test -c busyboxplus -- curl -s localhost
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
3.4.5 示例4:端口映射
[root@k8s-master pod]# vim pod3.yml
[root@k8s-master pod]# kubectl apply -f pod3.yml
pod/test created
[root@k8s-master pod]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test 1/1 Running 0 8s 10.244.1.22 k8s-node1 <none> <none>
[root@k8s-master pod]# curl k8s-node1
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
3.4.6 示例5:如何设定环境变量
[root@k8s-master pod]# vim pod4.yml
[root@k8s-master pod]# kubectl apply -f pod4.yml
pod/test created
[root@k8s-master pod]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test 1/1 Running 0 11s
[root@k8s-master pod]# kubectl logs pods/test busybox
timinglee
3.4.7 示例6:资源限制
[root@k8s-master pod]# vim pod5.yml
[root@k8s-master pod]# kubectl apply -f pod5.yml
pod/test created
[root@k8s-master pod]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test 1/1 Running 0 6s
[root@k8s-master pod]# kubectl describe pods test
3.4.8 示例7:容器启动管理
[root@k8s-master pod]# vim pod6.yml
Never表示容器重启后状态显示完成标识
3.4.9 示例8:选择运行节点
[root@k8s-master pod]# kubectl apply -f pod6.yml
pod/test created
[root@k8s-master pod]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test 1/1 Running 0 6s 10.244.1.29 k8s-node1 <none> <none>
3.4.10 示例9:共享宿主机网络
[root@k8s-master pod]# kubectl apply -f pod6.yml
pod/test created
[root@k8s-master pod]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test 1/1 Running 0 6s
[root@k8s-master pod]# kubectl exec -it pods/test -c busybox -- /bin/sh
/ #
/ # ifconfig
与宿主机网络相同
4、pod的生命周期
4.1 INIT容器
Pod 可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。
Init 容器与普通的容器非常像,除了如下两点:
它们总是运行到完成。
init 容器不支持 Readiness,因为它们必须在 Pod 就绪之前运行完成,每个Init 容器必须运行成功,下一个才能够运行。
如果Pod的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。但是,如果 Pod 对应的 restartPolicy 值为 Never,它不会重新启动。
4.1.1 INIT容器示例
[root@k8s-master pod]# vim pod6.yml
[root@k8s-master pod]# kubectl apply -f pod6.yml
pod/initpod created
[root@k8s-master pod]# kubectl get pods
NAME READY STATUS RESTARTS AGE
initpod 0/1 Init:0/1 0 5s
[root@k8s-master pod]# kubectl logs pods/initpod init-myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
[root@k8s-master pod]# kubectl exec pods/initpod -c init-myservice -- /bin/sh -c "touch /testfile"
[root@k8s-master pod]# kubectl get pods
NAME READY STATUS RESTARTS AGE
initpod 1/1 Running 0 2m56s
4.2 探针
探针是由 kubelet 对容器执行的定期诊断:
ExecAction:在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功。
TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
HTTPGetAction:对指定的端口和路径上的容器的IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。
livenessProbe:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其 重启策略 的影响。如果容器不提供存活探针,则默认状态为 Success。
readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。
startupProbe:指示容器中的应用是否已经启动。如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探测,则默认状态为成功Success。
StartupProbe与ReadinessProbe、LivenessProbe的区别
如果三个探针同时存在,先执行 StartupProbe 探针,其他两个探针将会被暂时禁用,直到 pod 满足 StartupProbe 探针配置的条件,其他2个探针启动,如果不满足按照规则重启容器。
另外两种探针在容器启动后,会按照配置,直到容器消亡才停止探测,而StartupProbe 探针只是在容器启动后按照配置满足一次后,不在进行后续的探测。
4.2.1 存活探针示例
为了演示效果将端口设定为8080
[root@k8s-master pod]# vim pod.yml
[root@k8s-master pod]# kubectl apply -f pod.yml
pod/liveness created
[root@k8s-master pod]# kubectl describe pods
Warning Unhealthy 1s (x8 over 14s) kubelet Liveness probe failed: dial tcp 10.244.2.26:8080: connect: connection refused可以看到存活探测失败,kubelet会杀死容器,并且容器将受到其重启策略的影响
[root@k8s-master pod]# kubectl get pods
NAME READY STATUS RESTARTS AGE
liveness 0/1 CrashLoopBackOff 4 (50s ago) 118s
4.2.2 就绪探针示例
[root@k8s-master pod]# vim pod.yml
测试:
[root@k8s-master pod]# kubectl expose pod readiness --port 80 --target-port 80
service/readiness exposed
[root@k8s-master pod]# kubectl get pods
NAME READY STATUS RESTARTS AGE
readiness 0/1 Running 0 2m57s没有准备好说明找不到/test.html这个文件,查看信息后报404
[root@k8s-master pod]# kubectl describe pods readiness
Warning Unhealthy 18s (x22 over 80s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 404因此就绪探测失败,端点控制器将从与pod匹配的所有service的端点中删除该pod的IP地址,
初始延迟之前的就绪状态为Failure
[root@k8s-master pod]# kubectl describe services readiness
Name: readiness
Namespace: default
Labels: name=readiness
Annotations: <none>
Selector: name=readiness
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.106.32.215
IPs: 10.106.32.215
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints:
Session Affinity: None
Events: <none>在pod中给出这个文件并赋予内容:
[root@k8s-master pod]# kubectl exec pods/readiness -c myapp -- /bin/sh -c "echo test > /usr/share/nginx/html/test.html"
[root@k8s-master pod]# kubectl get pods #可以看到就绪探测成功的运行起来
NAME READY STATUS RESTARTS AGE
readiness 1/1 Running 0 4m18s[root@k8s-master pod]# kubectl describe services readiness
Name: readiness
Namespace: default
Labels: name=readiness
Annotations: <none>
Selector: name=readiness
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.106.32.215
IPs: 10.106.32.215
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.2.27:80
Session Affinity: None
Events: <none>