1、验证节点信息
1.1、查看控制平面组件的状态
[root@linux-servertwo software]# kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy {"health":"true"} #controller-manager: 控制器管理器,负责维护集群的状态,例如复制控制器、部署控制器等。
#scheduler: 调度器,负责决定将哪个 Pod 安排到哪个节点。
#etcd-0: 分布式键值存储,用于存储 Kubernetes 集群的所有数据。
1.2、查看节点信息
1.2.1、查看节点信息
#查看节点信息
[root@linux-servertwo software]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
linux-servertwo Ready control-plane,master,node 26h v1.20.9
1.2.2、查看更加充分的节点信息
#查看更加充分的节点信息
[root@linux-servertwo software]# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
linux-servertwo Ready control-plane,master,node 27h v1.20.9 10.0.4.16 <none> CentOS Linux 7 (Core) 3.10.0-1160.108.1.el7.x86_64 docker://26.1.3
1.2.3、查看节点详情
#查看节点详情:
[root@linux-servertwo software]# kubectl describe node linux-servertwo
Name: linux-servertwo
Roles: control-plane,master,node
Labels: beta.kubernetes.io/arch=amd64beta.kubernetes.io/os=linuxkubernetes.io/arch=amd64kubernetes.io/hostname=linux-servertwokubernetes.io/os=linuxnode-role.kubernetes.io/control-plane=node-role.kubernetes.io/master=node-role.kubernetes.io/node=
......
1.3、查看系统组件
# 集群中的各个组件也都是以Pod方式运行的
[root@linux-servertwo software]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-7f89b7bc75-2k74p 1/1 Running 0 27h
coredns-7f89b7bc75-6xrvb 1/1 Running 0 27h
etcd-linux-servertwo 1/1 Running 0 27h
kube-apiserver-linux-servertwo 1/1 Running 0 27h
kube-controller-manager-linux-servertwo 1/1 Running 0 25h
kube-proxy-bmfzr 1/1 Running 0 27h
kube-scheduler-linux-servertwo 1/1 Running 0 25h
1.4、查看所有Pod
1.4.1、查看所有Pod信息
[root@linux-servertwo software]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-flannel kube-flannel-ds-lbmdr 1/1 Running 0 5d
kube-system coredns-7f89b7bc75-47d56 1/1 Running 0 6d4h
kube-system coredns-7f89b7bc75-h4c9b 1/1 Running 0 6d4h
kube-system etcd-linux-servertwo 1/1 Running 0 6d4h
kube-system kube-apiserver-linux-servertwo 1/1 Running 0 6d4h
kube-system kube-controller-manager-linux-servertwo 1/1 Running 0 5d
kube-system kube-proxy-j7d4v 1/1 Running 0 6d4h
kube-system kube-scheduler-linux-servertwo 1/1 Running 0 5d
1.4.2、查看更充分的所有pod信息
# 查看更充分的所有pod详情信息
[root@linux-servertwo software]# kubectl get pods --all-namespaces -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-flannel kube-flannel-ds-lbmdr 1/1 Running 0 5d 10.0.4.16 linux-servertwo <none> <none>
kube-system coredns-7f89b7bc75-47d56 1/1 Running 0 6d4h 172.17.0.3 linux-servertwo <none> <none>
kube-system coredns-7f89b7bc75-h4c9b 1/1 Running 0 6d4h 172.17.0.2 linux-servertwo <none> <none>
kube-system etcd-linux-servertwo 1/1 Running 0 6d4h 10.0.4.16 linux-servertwo <none> <none>
kube-system kube-apiserver-linux-servertwo 1/1 Running 0 6d4h 10.0.4.16 linux-servertwo <none> <none>
kube-system kube-controller-manager-linux-servertwo 1/1 Running 0 5d 10.0.4.16 linux-servertwo <none> <none>
kube-system kube-proxy-j7d4v 1/1 Running 0 6d4h 10.0.4.16 linux-servertwo <none> <none>
kube-system kube-scheduler-linux-servertwo 1/1 Running 0 5d 10.0.4.16 linux-servertwo <none> <none>
1.5、查看节点日志
使用 journalctl -u kubelet 命令查看日志信息# 动态查看 kubelet 日志的命令
[root@linux-servertwo software]# journalctl -u kubelet -f
Mar 19 15:53:58 linux-servertwo kubelet[25155]: I0319 15:53:58.023328 25155 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "config-volume" (UniqueName: "kubernetes.io/configmap/9d6647d1-caeb-448a-9628-c5ac14821995-config-volume") pod "coredns-7f89b7bc75-47d56" (UID: "9d6647d1-caeb-448a-9628-c5ac14821995")
Mar 19 15:53:58 linux-servertwo kubelet[25155]: map[string]interface {}{"cniVersion":"0.3.1", "hairpinMode":true, "ipMasq":false, "ipam":map[string]interface {}{"ranges":[][]map[string]interface {}{[]map[string]interface {}{map[string]interface {}{"subnet":"172.17.0.0/24"}}}, "routes":[]types.Route{types.Route{Dst:net.IPNet{IP:net.IP{0xac, 0x11, 0x0, 0x0}, Mask:net.IPMask{0xff, 0xff, 0x0, 0x0}}, GW:net.IP(nil)}}, "type":"host-local"}, "isDefaultGateway":true, "isGateway":true, "mtu":(*uint)(0xc00001c928), "name":"cbr0", "type":"bridge"}
Mar 19 15:53:58 linux-servertwo kubelet[25155]: {"cniVersion":"0.3.1","hairpinMode":true,"ipMasq":false,"ipam":{"ranges":[[{"subnet":"172.17.0.0/24"}]],"routes":[{"dst":"172.17.0.0/16"}],"type":"host-local"},"isDefaultGateway":true,"isGateway":true,"mtu":1450,"name":"cbr0","type":"bridge"}
Mar 19 15:53:58 linux-servertwo kubelet[25155]: map[string]interface {}{"cniVersion":"0.3.1", "hairpinMode":true, "ipMasq":false, "ipam":map[string]interface {}{"ranges":[][]map[string]interface {}{[]map[string]interface {}{map[string]interface {}{"subnet":"172.17.0.0/24"}}}, "routes":[]types.Route{types.Route{Dst:net.IPNet{IP:net.IP{0xac, 0x11, 0x0, 0x0}, Mask:net.IPMask{0xff, 0xff, 0x0, 0x0}}, GW:net.IP(nil)}}, "type":"host-local"}, "isDefaultGateway":true, "isGateway":true, "mtu":(*uint)(0xc0000a28e8), "name":"cbr0", "type":"bridge"}
2、Namespaces
2.1、介绍
命名空间Namespaces主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。它能够将资源划分为不同的分组,帮助我们在一个集群中划分不同的项目、团队或者环境(如开发、测试和生产环境),从而提高资源的隔离性和管理效率。
2.2、查看创建的命名空间
[root@linux-servertwo software]# kubectl get namespaces
NAME STATUS AGE
default Active 24h
kube-flannel Active 19h
kube-node-lease Active 24h
kube-public Active 24h
kube-system Active 24h
2.3、创建命名空间
[root@linux-servertwo software]# kubectl create namespace blog-dev
namespace/blog-dev created# 再次查看-命名空间 blog-dev 创建成功
[root@linux-servertwo software]# kubectl get namespaces
NAME STATUS AGE
blog-dev Active 17s
default Active 24h
kube-flannel Active 19h
kube-node-lease Active 24h
kube-public Active 24h
kube-system Active 24h
2.4、删除命名空间
#删除
[root@linux-servertwo software]# kubectl delete namespace blog-dev
namespace "blog-dev" deleted#再次查看-发现已经删除
[root@linux-servertwo software]# kubectl get namespaces
NAME STATUS AGE
default Active 24h
kube-flannel Active 20h
kube-node-lease Active 24h
kube-public Active 24h
kube-system Active 24h
2.5、检索指定命名空间
# 查看-检索指定命名空间
[root@linux-servertwo software]# kubectl get namespaces blog-dev
NAME STATUS AGE
blog-dev Active 39s# 查看-指定命名空间详情
[root@linux-servertwo software]# kubectl describe namespace blog-dev
Name: blog-dev
Labels: <none>
Annotations: <none>
Status: ActiveNo resource quota.
No LimitRange resource.
2.6、查看命名空间中的资源
[root@linux-servertwo software]# kubectl get pods -n blog-dev
No resources found in blog-dev namespace.
[root@linux-servertwo software]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-7f89b7bc75-47d56 1/1 Running 0 6d4h
coredns-7f89b7bc75-h4c9b 1/1 Running 0 6d4h
etcd-linux-servertwo 1/1 Running 0 6d4h
kube-apiserver-linux-servertwo 1/1 Running 0 6d4h
kube-controller-manager-linux-servertwo 1/1 Running 0 5d1h
kube-proxy-j7d4v 1/1 Running 0 6d4h
kube-scheduler-linux-servertwo 1/1 Running 0 5d1h
2.7、输出yaml格式
# 查看-输出yaml格式
[root@linux-servertwo software]# kubectl get namespaces blog-dev -o yaml
apiVersion: v1
kind: Namespace
metadata:creationTimestamp: "2024-12-10T03:58:55Z"managedFields:- apiVersion: v1fieldsType: FieldsV1fieldsV1:f:status:f:phase: {}manager: kubectl-createoperation: Updatetime: "2024-12-10T03:58:55Z"name: blog-devresourceVersion: "106051"uid: 406d2440-b725-409f-9a01-2bf8c606e5cf
spec:finalizers:- kubernetes
status:phase: Active# 输出一个yaml创建命名空间的格式,但不运行
[root@linux-servertwo software]# kubectl create namespace blog-dev-1 --dry-run=client -o yaml
apiVersion: v1
kind: Namespace
metadata:creationTimestamp: nullname: blog-dev-1
spec: {}
status: {}# 输出一个yaml创建命名空间的格式,但不运行 ,输出到主机blog-dev-1.yaml文件中
[root@linux-servertwo software]# kubectl create namespace blog-dev-1 --dry-run=client -o yaml > blog-dev-1.yaml#查看输出的文件信息
[root@linux-servertwo software]# ls
blog-dev-1.yaml
[root@linux-servertwo software]# cat blog-dev-1.yaml
apiVersion: v1
kind: Namespace
metadata:creationTimestamp: nullname: blog-dev-1
spec: {}
status: {}
2.8、YAML创建
# 声明文件创建
[root@linux-servertwo software]# kubectl apply -f blog-dev-1.yaml
namespace/blog-dev-1 created
[root@linux-servertwo software]# kubectl get namespaces
NAME STATUS AGE
blog-dev Active 3h11m
blog-dev-1 Active 9s
default Active 27h
kube-flannel Active 23h
kube-node-lease Active 27h
kube-public Active 27h
kube-system Active 27h
nginx Active 37m
2.9、YAML删除
# 删除命名空间-以yml的形式
[root@linux-servertwo software]# kubectl delete -f blog-dev-1.yaml
namespace "blog-dev-1" deleted
[root@linux-servertwo software]# kubectl get namespaces
NAME STATUS AGE
blog-dev Active 3h13m
default Active 27h
kube-flannel Active 23h
kube-node-lease Active 27h
kube-public Active 27h
kube-system Active 27h
nginx Active 38m
2.10、切换命名空间
# 通过设置默认命名空间,可以在运行其他命令时避免每次都加上 -n <namespace-name>
[root@linux-servertwo software]# kubectl config set-context --current --namespace=kube-system
Context "kubernetes-admin@kubernetes" modified.# 查看pod
[root@linux-servertwo software]# kubectl get pods
NAME READY STATUS RESTARTS AGE
coredns-7f89b7bc75-47d56 1/1 Running 0 6d4h
coredns-7f89b7bc75-h4c9b 1/1 Running 0 6d4h
etcd-linux-servertwo 1/1 Running 0 6d4h
kube-apiserver-linux-servertwo 1/1 Running 0 6d4h
kube-controller-manager-linux-servertwo 1/1 Running 0 5d1h
kube-proxy-j7d4v 1/1 Running 0 6d4h
kube-scheduler-linux-servertwo 1/1 Running 0 5d1h# 查看当前使用的命名空间
[root@linux-servertwo software]# kubectl config view --minify | grep namespace:
namespace: kube-system# 设置为默认
[root@linux-servertwo software]# kubectl config set-context --current --namespace=default
Context "kubernetes-admin@kubernetes" modified.[root@linux-servertwo software]# kubectl config view --minify | grep namespace:
namespace: default[root@linux-servertwo software]# kubectl get pods
No resources found in default namespace.
3、Pod命令使用
3.1、介绍
Pod
是Kubernetes
中可以创建和管理的最小部署单元,也是Kubernetes
应用的基本运行单位,它封装了一个或多个容器和存储资源。Pod
中的所有容器共享相同的网络命名空间、IP 地址、端口空间以及存储卷。通常情况下不直接管理 Pod,而是通过更高层次的抽象(如 Deployment、StatefulSet 等)来管理 Pod 的生命周期。下面就以安装nginx
为例,单独介绍一下Pod的相关使用。
3.2、创建命名空间
首先创建好一个nginx
的命名空间,做好数据隔离。
# 创建命名空间nginx
[root@linux-servertwo software]# kubectl create namespace nginx
namespace/nginx created# 列出所有Pod: kubectl get pods -n <namespace-name>
[root@linux-servertwo software]# kubectl get pods -n nginx
No resources found in nginx namespace.
3.3、创建Pod
# 创建Pod 通过Pod控制器创建Pod
# 命令格式: kubectl run (pod控制器名称) [参数]
# --image 指定Pod的镜像
# --port 指定端口
# --namespace 指定namespace
[root@linux-servertwo nginx]# kubectl run nginx --image nginx:latest --port 80 --namespace nginx
pod/nginx created
3.4、查看Pod信息
# 查看Pods信息
[root@linux-servertwo nginx]# kubectl get pods -n nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 9m6s# 更详细得查看pods信息
[root@linux-servertwo nginx]# kubectl get pods -n nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 15m 172.17.0.68 linux-servertwo <none> <none># 查看详情Pod信息
[root@linux-servertwo nginx]# kubectl describe pods nginx -n nginx
Name: nginx
Namespace: nginx
Priority: 0
Node: linux-servertwo/10.0.4.16
Start Time: Wed, 11 Dec 2024 16:16:48 +0800
Labels: run=nginx
Annotations: <none>
Status: Running
IP: 172.17.0.68
IPs:IP: 172.17.0.68......
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 9m29s default-scheduler Successfully assigned nginx/nginx to linux-servertwoNormal Pulling 9m28s kubelet Pulling image "nginx:latest"Normal Pulled 8m36s kubelet Successfully pulled image "nginx:latest" in 52.683702042sNormal Created 8m35s kubelet Created container nginxNormal Started 8m35s kubelet Started container nginx
3.5、验证创建成功
# 根据IP访问nginx,发现nginx启动成功
[root@linux-servertwo nginx]# curl 172.17.0.68:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
3.6、删除Pod
# 删除Pod
[root@linux-servertwo nginx]# kubectl delete pods -n nginx nginx
pod "nginx" deleted
# 再次查看,发现已经删除
[root@linux-servertwo nginx]# kubectl get pod -n nginx
No resources found in nginx namespace.
# 上面只删除Pod,创建的命名空间还在
[root@linux-servertwo nginx]# kubectl get namespaces
NAME STATUS AGE
blog-dev Active 28h
default Active 2d4h
kube-flannel Active 2d
kube-node-lease Active 2d4h
kube-public Active 2d4h
kube-system Active 2d4h
kubernetes-dashboard Active 155m
nginx Active 26h
3.7、YAML创建Pod
接下来使用yaml
格式文件创建nginx
# 输出一个 nginx 的 yaml 格式 pod 到 nginx-pod.yaml 文件
[root@linux-servertwo nginx]# kubectl run nginx --image nginx:latest --port 80 --namespace nginx --dry-run=client -o yaml > nginx-pod.yaml# 查看 nginx-pod.yaml 文件
[root@linux-servertwo nginx]# cat nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: nginxname: nginxnamespace: nginx
spec:containers:- image: nginx:latestname: nginxports:- containerPort: 80resources: {}dnsPolicy: ClusterFirstrestartPolicy: Always
status: {}# pod 声明
[root@linux-servertwo nginx]# kubectl apply -f nginx-pod.yaml
pod/nginx created# 查看-发现创建成功
[root@linux-servertwo nginx]# kubectl get pod nginx -n nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 20s# 查看详情
[root@linux-servertwo nginx]# kubectl describe pod nginx -n nginx
Name: nginx
Namespace: nginx
Priority: 0
Node: linux-servertwo/10.0.4.16
Start Time: Wed, 11 Dec 2024 16:42:53 +0800
Labels: run=nginx
Annotations: <none>
Status: Running
IP: 172.17.0.69
IPs:IP: 172.17.0.69......
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 93s default-scheduler Successfully assigned nginx/nginx to linux-servertwoNormal Pulling 93s kubelet Pulling image "nginx:latest"Normal Pulled 91s kubelet Successfully pulled image "nginx:latest" in 2.213103384sNormal Created 91s kubelet Created container nginxNormal Started 91s kubelet Started container nginx
3.8、验证是否成功
# 访问
[root@linux-servertwo nginx]# curl 172.17.0.69:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
3.9、YAML删除Pod
#删除-通过yaml方式
[root@linux-servertwo nginx]# kubectl delete -f nginx-pod.yaml
pod "nginx" deleted#再次查看,发现和使用命令删除Pod一样,只删除Pod不删除namespaces
[root@linux-servertwo nginx]# kubectl get pod -n nginx
No resources found in nginx namespace.[root@linux-servertwo nginx]# kubectl get namespaces
NAME STATUS AGE
blog-dev Active 28h
default Active 2d5h
kube-flannel Active 2d
kube-node-lease Active 2d5h
kube-public Active 2d5h
kube-system Active 2d5h
kubernetes-dashboard Active 168m
nginx Active 26h
3.10、查看Pod日志
# 通过 kubectl logs <pod-name> -n <namespace-name> 进行查看特定命名空间中 Pod 的日志
[root@linux-servertwo software]# kubectl logs nginx -n nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2025/03/24 09:32:43 [notice] 1#1: using the "epoll" event method
2025/03/24 09:32:43 [notice] 1#1: nginx/1.27.4
2025/03/24 09:32:43 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2025/03/24 09:32:43 [notice] 1#1: OS: Linux 3.10.0-1160.108.1.el7.x86_64
2025/03/24 09:32:43 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 65536:65536
2025/03/24 09:32:43 [notice] 1#1: start worker processes
2025/03/24 09:32:43 [notice] 1#1: start worker process 29
2025/03/24 09:32:43 [notice] 1#1: start worker process 30
172.17.0.1 - - [24/Mar/2025:09:33:19 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
172.17.0.1 - - [24/Mar/2025:09:34:24 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
172.17.0.1 - - [24/Mar/2025:09:34:26 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"# 如果 Pod 包含多个容器,可以指定容器名称
# kubectl logs <pod-name> -c <container-name>
[root@linux-servertwo software]# kubectl logs nginx -n nginx -c nginx -f
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2025/03/24 13:01:13 [notice] 1#1: using the "epoll" event method
2025/03/24 13:01:13 [notice] 1#1: nginx/1.27.4
2025/03/24 13:01:13 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2025/03/24 13:01:13 [notice] 1#1: OS: Linux 3.10.0-1160.108.1.el7.x86_64
2025/03/24 13:01:13 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 65536:65536
2025/03/24 13:01:13 [notice] 1#1: start worker processes
2025/03/24 13:01:13 [notice] 1#1: start worker process 29
2025/03/24 13:01:13 [notice] 1#1: start worker process 30
172.17.0.1 - - [24/Mar/2025:13:01:40 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
172.17.0.1 - - [24/Mar/2025:13:03:47 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
172.17.0.1 - - [25/Mar/2025:02:24:58 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
3.11、进入容器
# 进入Pod容器:kubectl exec -it <pod-name> -- /bin/bash
[root@linux-servertwo software]# kubectl exec -it nginx -n nginx -- /bin/bash
root@nginx:/# ls
bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@nginx:/# nginx -V
nginx version: nginx/1.27.4
built by gcc 12.2.0 (Debian 12.2.0-14)
built with OpenSSL 3.0.11 19 Sep 2023 (running with OpenSSL 3.0.15 3 Sep 2024)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_v3_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -ffile-prefix-map=/data/builder/debuild/nginx-1.27.4/debian/debuild-base/nginx-1.27.4=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'
root@nginx:/# # 如果 Pod 中有多个容器,可以通过 -c 参数指定容器:kubectl exec -it <pod-name> -c <container-name> -- /bin/bash
[root@linux-servertwo software]# kubectl exec -it nginx -c nginx -n nginx -- /bin/bash
root@nginx:/# ls
bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@nginx:/#
3.12、查看 Pod 关联的事件
# 查看与 Pod 相关的事件,了解 Pod 的运行状态以及错误信息:
[root@linux-servertwo software]# kubectl get events --field-selector involvedObject.name=nginx -n nginx
LAST SEEN TYPE REASON OBJECT MESSAGE
5m42s Normal Scheduled pod/nginx Successfully assigned nginx/nginx to linux-servertwo
5m42s Normal Pulling pod/nginx Pulling image "nginx:latest"
5m32s Normal Pulled pod/nginx Successfully pulled image "nginx:latest" in 9.177513284s
5m32s Normal Created pod/nginx Created container nginx
5m32s Normal Started pod/nginx Started container nginx
3.13、Pod 的扩展和缩容
直接修改 Pod 数量需要使用副本集(ReplicaSet)或部署(Deployment)来管理。例如,使用以下命令扩展或缩容 Pod 副本数:
# kubectl scale --replicas=<num> deployment/<deployment-name>
kubectl scale --replicas=3 deployment/my-app-nginx
在 Kubernetes 中,Pod 的扩展和缩容通常是通过它们的资源来管理的。Deployment
允许定义多个副本(Pod 实例),并可以根据需要进行扩展和缩容。Deployment
会自动管理 Pod 的生命周期和状态,包括在需要时扩展和缩容 Pod 数量。下面就来介绍Deployment
的相关使用命令。
4、Deployment命令使用
4.1、介绍
在 Kubernetes
中,Pod
是最小的调度和管理单元,但Kubernetes
很少直接操作单个 Pod
。通常,Kubernetes
是通过 Pod 控制器 来间接管理 Pod
,实现对 Pod 的控制与维护,确保 Pod
的状态始终符合预期。这些控制器负责自动化创建、调度、更新和扩展 Pod
,并确保其高可用性和健康。当 Pod
发生故障或失效时,控制器会自动执行恢复操作,如重启或重新创建 Pod
,以确保应用的连续性和稳定性。Kubernetes
中常见的 Pod控制器 包括 Deployment、ReplicaSet、StatefulSet、DaemonSet、Job 和 CronJob,它们各自负责不同的用例和场景,提供了灵活的管理方式,满足不同的需求场景。通过这些控制器,Kubernetes
实现了强大的自愈能力、扩展性和灵活性,使得容器化应用的管理更加高效、可靠。下面介绍其中一个 Pod控制器 :Deployment
4.2、创建 Deployment
可以通过 kubectl create
或 kubectl apply
命令来创建 Deployment
# 创建deployment控制器
# 命令格式:
# kubectl create deployment 名称 [参数]
# 参数:
# -n/--namespace 指定创建的所属命名空间
# --image 指定pod的镜像
# --port 指定端口
# --replicas 指定创建pod数量 --replicas=3:指定该 Deployment 创建的 Pod 副本数量为 3,
# 该命令表示 Kubernetes 将确保始终有 3 个运行中的 nginx Pod 实例来提供服务,实现高可用性和负载均衡
[root@linux-servertwo software]# kubectl create deployment nginx -n nginx --image nginx:latest --port 80 --replicas=3
deployment.apps/nginx created# 查看命名空间下面的Pod
[root@linux-servertwo nginx]# kubectl get pods -n nginx
NAME READY STATUS RESTARTS AGE
nginx-585449566-6788b 1/1 Running 0 39s
nginx-585449566-bhbtp 1/1 Running 0 39s
nginx-585449566-gk2kl 1/1 Running 0 39s
4.3、查看 Deployment
# 查看deployment状态
[root@linux-servertwo nginx]# kubectl get deployment -n nginx
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 3/3 3 3 88s# 查看某一个 Deployment 信息 kubectl get deployment <deployment-name> <namespaces>
[root@linux-servertwo software]# kubectl get deployment nginx -n nginx
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 3/3 3 3 25m# 查看 Deployment 的 YAML 配置
[root@linux-servertwo software]# kubectl get deployment nginx -n nginx -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:annotations:deployment.kubernetes.io/revision: "1"generation: 1labels:app: nginx
......
status:availableReplicas: 3conditions:- lastTransitionTime: "2025-03-25T07:38:18Z"lastUpdateTime: "2025-03-25T07:38:18Z"message: Deployment has minimum availability.reason: MinimumReplicasAvailablestatus: "True"type: Available- lastTransitionTime: "2025-03-25T07:38:14Z"lastUpdateTime: "2025-03-25T07:38:18Z"message: ReplicaSet "nginx-585449566" has successfully progressed.reason: NewReplicaSetAvailablestatus: "True"type: ProgressingobservedGeneration: 1readyReplicas: 3replicas: 3updatedReplicas: 3# 更详细得查看deployment信息 UP-TO-DATE:成功升级的副本数量, AVAILABLE:可用副本的数量
[root@linux-servertwo nginx]# kubectl get deployment -n nginx -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 3/3 3 3 4m56s nginx nginx:latest app=nginx# 查看deployment详情
[root@linux-servertwo nginx]# kubectl describe deployment -n nginx
Name: nginx
Namespace: nginx
CreationTimestamp: Fri, 13 Dec 2024 10:26:15 +0800
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:Labels: app=nginxContainers:nginx:Image: nginx:latestPort: 80/TCPHost Port: 0/TCPEnvironment: <none>Mounts: <none>Volumes: <none>
Conditions:Type Status Reason---- ------ ------Available True MinimumReplicasAvailableProgressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-585449566 (3/3 replicas created)
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal ScalingReplicaSet 3m9s deployment-controller Scaled up replica set nginx-585449566 to 3
4.4、验证访问
# 查看每一个nginx启动的容器IP
[root@linux-servertwo nginx]# kubectl get pod -n nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-585449566-6788b 1/1 Running 0 9m33s 172.17.0.71 linux-servertwo <none> <none>
nginx-585449566-bhbtp 1/1 Running 0 9m33s 172.17.0.72 linux-servertwo <none> <none>
nginx-585449566-gk2kl 1/1 Running 0 9m33s 172.17.0.73 linux-servertwo <none> <none># 通过IP尝试访问 172.17.0.71
[root@linux-servertwo nginx]# curl 172.17.0.71
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
# 通过IP尝试访问 172.17.0.72
[root@linux-servertwo nginx]# curl 172.17.0.72
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html># 通过IP尝试访问 172.17.0.73
[root@linux-servertwo nginx]# curl 172.17.0.73
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
4.5、进入容器
# 进入其中一个POD的容器内部
[root@linux-servertwo nginx]# kubectl exec -it -n nginx nginx-585449566-6788b /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx-585449566-6788b:/#
# 上面命令提示已经准备弃用,使用新命令进入 需要加 --
[root@linux-servertwo nginx]# kubectl exec -it -n nginx nginx-585449566-6788b -- /bin/bash
root@nginx-585449566-6788b:/# nginx -v
nginx version: nginx/1.27.3
4.6、更新 Deployment
更新 Deployment 可以通过 kubectl set
或 kubectl apply
实现
# 将上面部署的 nginx 的 deployment 的容器镜像更新为 nginx:1.19.0
# kubectl set image deployment/<deployment-name> <container-name>=<new-image>
[root@linux-servertwo software]# kubectl set image deployment/nginx nginx=nginx:1.19 -n nginx
deployment.apps/nginx image updated# 查看是否更新-查看信息发现更新成功
[root@linux-servertwo software]# kubectl get deployment -n nginx -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 3/3 3 3 40m nginx nginx:1.19 app=nginx# 进入其中一个POD的容器内部 查看nginx版本
[root@linux-servertwo software]# kubectl exec -it -n nginx nginx-5479877cb4-2lpwv -- /bin/bash
root@nginx-5479877cb4-2lpwv:/# nginx -v
nginx version: nginx/1.19.10
4.7、查看和管理 Deployment 版本
# 查看 Deployment 的历史版本
[root@linux-servertwo software]# kubectl rollout history deployment/nginx -n nginx
deployment.apps/nginx
REVISION CHANGE-CAUSE
1 <none>
2 <none>
# 变更记录,REVISION 1: 初始部署的版本,REVISION 2: 更新后的版本,CHANGE-CAUSE: 每个修订版本的变更原因或描述。当前两个版本的 CHANGE-CAUSE 都为空。
# 这可以通过在 kubectl set image 命令中添加 --record 参数来实现,每次更新时提供 CHANGE-CAUSE 信息
# --record 参数会将命令记录到 Deployment 的变更历史中,方便后续查看和回滚。
# 如以上更新命令加上参数 kubectl set image deployment/nginx nginx=nginx:1.19 -n nginx --record# 查看 Deployment 的滚动更新状态
[root@linux-servertwo software]# kubectl rollout status deployment/nginx -n nginx
deployment "nginx" successfully rolled out
# 输出以上信息,表示 nginx Deployment 的滚动更新已经成功完成
4.8、回滚 Deployment 版本
如果更新后的应用出现问题,可以通过回滚命令恢复到先前的版本。
# 回滚到上一个版本:kubectl rollout undo deployment/<deployment-name>
[root@linux-servertwo software]# kubectl rollout undo deployment/nginx -n nginx
deployment.apps/nginx rolled back# 查看是否回滚成功
[root@linux-servertwo software]# kubectl get deployment -n nginx -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 3/3 3 3 68m nginx nginx:latest app=nginx
# 可以发现nginx版本已经变为部署时候的最新版本。# 回滚到某个特定版本:kubectl rollout undo deployment/<deployment-name> --to-revision=<revision-number>
[root@linux-servertwo software]# kubectl rollout undo deployment/nginx -n nginx --to-revision=2
deployment.apps/nginx rolled back# 查看是否回滚成功
[root@linux-servertwo software]# kubectl get deployment -n nginx -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 3/3 3 3 75m nginx nginx:1.19 app=nginx
# 发现又回到了更新之后的版本。
4.9、暂停和恢复 Deployment
# 暂停正在进行的更新操作:kubectl rollout pause deployment/<deployment-name>
[root@linux-servertwo software]# kubectl rollout pause deployment/nginx -n nginx
deployment.apps/nginx paused# 恢复暂停的更新操作:kubectl rollout resume deployment/<deployment-name>
[root@linux-servertwo software]# kubectl rollout resume deployment/nginx -n nginx
deployment.apps/nginx resumed
4.10、删除 Deployment
# 删除某个 Deployment:kubectl delete deployment <deployment-name>
[root@linux-servertwo software]# kubectl delete deployment nginx -n nginx
deployment.apps "nginx" deleted
# 再次查看deployment发现已经删除
[root@linux-servertwo software]# kubectl get deployment -n nginx
No resources found in nginx namespace.
# 删除 deployment后,Pod也自动删除了
[root@linux-servertwo software]# kubectl get pod -n nginx
No resources found in nginx namespace.
4.11、YAML创建
# 输出一个yaml创建nginx的Deployment格式文件,但不运行 ,输出到主机nginx-deployment.yml文件中
[root@linux-servertwo software]# kubectl create deployment nginx -n nginx --image nginx:latest --port 80 --replicas=3 --dry-run=client -o yaml > nginx-deployment.yml# 输出成功后,查看输出的yml文件
[root@linux-servertwo software]# cat nginx-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:creationTimestamp: nulllabels:app: nginxname: nginxnamespace: nginx
spec:replicas: 3selector:matchLabels:app: nginxstrategy: {}template:metadata:creationTimestamp: nulllabels:app: nginxspec:containers:- image: nginx:latestname: nginxports:- containerPort: 80resources: {}
status: {}# 运行nginx的YML文件
[root@linux-servertwo software]# kubectl apply -f nginx-deployment.yml
deployment.apps/nginx created# 查看是否创建成功
[root@linux-servertwo software]# kubectl get deployment -n nginx -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 3/3 3 3 2m29s nginx nginx:latest app=nginx# 查看运行的Pod
[root@linux-servertwo software]# kubectl get pod -n nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-585449566-46b9w 1/1 Running 0 5m31s 172.17.0.21 linux-servertwo <none> <none>
nginx-585449566-lcmlp 1/1 Running 0 5m31s 172.17.0.22 linux-servertwo <none> <none>
nginx-585449566-x6rcl 1/1 Running 0 5m31s 172.17.0.20 linux-servertwo <none> <none>
4.12、YAML删除
# 通过 kubectl delete 命令进行删除,删除 Deployment 会自动删除与之关联的所有 Pod。
[root@linux-servertwo software]# kubectl delete -f nginx-deployment.yml
deployment.apps "nginx" deleted# 查看Deployment
[root@linux-servertwo software]# kubectl get deployment -n nginx
No resources found in nginx namespace.# 查看Pod
[root@linux-servertwo software]# kubectl get pod -n nginx
No resources found in nginx namespace.
4.13、删除指定Pod
# 如果只需要删除其中一个Pod,而不删除Deployment,执行删除Pod的命令即可
[root@linux-servertwo nginx]# kubectl delete pods -n nginx nginx-585449566-lcmlp
pod "nginx-585449566-lcmlp" deleted
# 删除其中一个后,Deployment 会根据其配置,在自动创建一个新的 Pod 来保持所需的副本数量# 再次查看运行的Pod,发现还是保持3个副本数量,但是Ip地址已经更新了。
[root@linux-servertwo software]# kubectl get pod -n nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-585449566-46b9w 1/1 Running 0 5m31s 172.17.0.21 linux-servertwo <none> <none>
nginx-585449566-krqsh 1/1 Running 0 14s 172.17.0.26 linux-servertwo <none> <none>
nginx-585449566-x6rcl 1/1 Running 0 5m31s 172.17.0.20 linux-servertwo <none> <none>
5、Service命令使用
5.1、介绍
Service
是 Kubernetes
一种资源类型,它主要定义了一组Pod
的访问策略,并为这些Pod
提供一个稳定的固定网络地址,而无需了解这些Pod
的具体 IP 地址。Service
主要用于将一组 Pod 暴露给集群内的其他服务或外部用户,使其可以通过网络与其他应用程序之间提供一个更加可靠和灵活的通信。
5.2、创建 Service
首先执行nginx-deployment.yml
文件创建一个Deployment的nginx服务,
# 创建 Deployment nginx
[root@linux-servertwo software]# kubectl apply -f nginx-deployment.yml
deployment.apps/nginx created# 查看是否启动成功
[root@linux-servertwo software]# kubectl get deployment -n nginx -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 3/3 3 3 33s nginx nginx:latest app=nginx
[root@linux-servertwo software]# kubectl get pod -n nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-585449566-5lxwx 1/1 Running 0 40s 172.17.0.29 linux-servertwo <none> <none>
nginx-585449566-l9wvw 1/1 Running 0 40s 172.17.0.28 linux-servertwo <none> <none>
nginx-585449566-lfjgc 1/1 Running 0 40s 172.17.0.27 linux-servertwo <none> <none>
然后在进入每一个Pod的Nginx容器内部,配置一下html页面信息,方便后面查看
# 进入 nginx-585449566-5lxwx 容器内部
[root@linux-servertwo nginx]# kubectl exec -it -n nginx nginx-585449566-5lxwx -- bash
root@nginx-585449566-6788b:/# echo this is 172.17.0.29 nginx > /usr/share/nginx/html/index.html
root@nginx-585449566-6788b:/# cat /usr/share/nginx/html/index.html
this is 172.17.0.29 nginx
# 进入 nginx-585449566-l9wvw 容器内部
[root@linux-servertwo nginx]# kubectl exec -it -n nginx nginx-585449566-l9wvw -- bash
root@nginx-585449566-bhbtp:/# echo this is 172.17.0.28 nginx > /usr/share/nginx/html/index.html
root@nginx-585449566-bhbtp:/# cat /usr/share/nginx/html/index.html
this is 172.17.0.28 nginx
# 进入 nginx-585449566-lfjgc 容器内部
[root@linux-servertwo nginx]# kubectl exec -it -n nginx nginx-585449566-lfjgc -- bash
root@nginx-585449566-gk2kl:/# echo this is 172.17.0.27 nginx > /usr/share/nginx/html/index.html
root@nginx-585449566-gk2kl:/# cat /usr/share/nginx/html/index.html
this is 172.17.0.27 nginx# 验证访问
[root@linux-servertwo software]# curl 172.17.0.29
this is 172.17.0.29 nginx
[root@linux-servertwo software]# curl 172.17.0.28
this is 172.17.0.28 nginx
[root@linux-servertwo software]# curl 172.17.0.27
this is 172.17.0.27 nginx
接下来就可以创建一个集群内部可访问的Service
了
# 通过以下命令创建一个内部的Service服务访问Pods
# kubectl expose pod <pod-name> --name=<service-name> --port=<port> --target-port=<target-port> --type=<service-type>
[root@linux-servertwo nginx]# kubectl expose deployment -n nginx nginx --name=svc-nginx --type=ClusterIP --port=80 --target-port=80
service/svc-nginx exposed# type 类型:
# ClusterIP:默认类型,服务只在集群内部可访问。
# NodePort:在每个 Node 上打开一个端口,并通过该端口暴露服务。
# LoadBalancer:使用云服务提供商的负载均衡器来暴露服务,通常适用于云环境。
# ExternalName:通过 DNS 名称将外部服务映射到 Kubernetes 集群中的服务,适用于需要访问集群外部服务的情况。
5.3、查看 Service
# 查看创建的Service
[root@linux-servertwo software]# kubectl get service -n nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx ClusterIP 172.16.251.156 <none> 80/TCP 19s# 查看更充分的Service
[root@linux-servertwo software]# kubectl get service -n nginx -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx ClusterIP 172.16.251.156 <none> 80/TCP 56s app=nginx
# ClusterIP 此类型只允许集群内访问,这里生成了一个CLUSTER-IP的IP,这就是service的IP。在Service的生命周期中,这个地址是不会变动的,可以通过这个IP访问当前service对应的Pod# 详情查看 kubectl describe service <service-name>
[root@linux-servertwo software]# kubectl describe service svc-nginx -n nginx
Name: svc-nginx
Namespace: nginx
Labels: app=nginx
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP Families: <none>
IP: 172.16.251.156
IPs: 172.16.251.156
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 172.17.0.27:80,172.17.0.28:80,172.17.0.29:80
Session Affinity: None
Events: <none># 查看 Endpoint 信息-存储了Service对应的Pod的实际IP地址和端口信息
[root@linux-servertwo software]# kubectl get endpoints -n nginx svc-nginx
NAME ENDPOINTS AGE
svc-nginx 172.17.0.27:80,172.17.0.28:80,172.17.0.29:80 42m
5.4、验证访问
通过访问CLUSTER-IP
对应的IP
进行测试
[root@linux-servertwo software]# curl 172.16.251.156
this is 172.17.0.29 nginx
[root@linux-servertwo software]# curl 172.16.251.156
this is 172.17.0.28 nginx
[root@linux-servertwo software]# curl 172.16.251.156
this is 172.17.0.27 nginx
[root@linux-servertwo software]# curl 172.16.251.156
this is 172.17.0.28 nginx
[root@linux-servertwo software]# curl 172.16.251.156
this is 172.17.0.29 nginx
[root@linux-servertwo software]# curl 172.16.251.156
this is 172.17.0.29 nginx
[root@linux-servertwo software]# curl 172.16.251.156
this is 172.17.0.27 nginx
[root@linux-servertwo software]# curl 172.16.251.156
this is 172.17.0.27 nginx
[root@linux-servertwo software]# curl 172.16.251.156
this is 172.17.0.29 nginx
通过以上的多次访问,可以看到 Service IP 会随机将请求转发到其中一个 Pod 上的 Nginx 中,这表明内部实现了负载均衡。这个负载均衡通过 kube-proxy 在第四层(传输层)完成的,适用于 TCP 和 UDP 流量。无论是 ClusterIP 还是 NodePort 类型的 Service,kube-proxy 都会在集群内部创建路由规则,将请求转发到后端的 Pod。当客户端请求发送到 Service 的 Cluster IP 地址时,kube-proxy 会把请求转发到一个或多个 Pod。由于这种负载均衡是在第四层(传输层)进行的, 因此不需要理解更高层次的应用协议。
5.5、kube-proxy 实现负载均衡介绍
在 Kubernetes 中,kube-proxy 使用 iptables 规则来实现 Service 的负载均衡。通过查看 iptables 规则,可以了解访问 Service 的 Cluster IP 地址时的具体链路规则。以下是具体步骤和示例:
# 查看 iptables 规则
# iptables-save | grep KUBE 或者 iptables -L -t nat | grep KUBE
[root@linux-servertwo software]# iptables -L -t nat | grep KUBE# 只截取部署nginx的重要部分进行说明
# 通过注释可以查看 /* nginx/svc-nginx */ 表明这是与 nginx/svc-nginx 服务相关的流量
Chain KUBE-SEP-MEC45OHITDUK5UCI (1 references)
KUBE-MARK-MASQ all -- 172.17.0.27 anywhere /* nginx/svc-nginx */
Chain KUBE-SEP-OVGUVNLN5SZ5SJPC (1 references)
KUBE-MARK-MASQ all -- 172.17.0.28 anywhere /* nginx/svc-nginx */
Chain KUBE-SEP-Q7FC6ND2772R7A3Y (1 references)
KUBE-MARK-MASQ all -- 172.17.0.29 anywhere /* nginx/svc-nginx */# KUBE-SERVICES 链是 Kubernetes 服务暴露的入口。它是 Kubernetes 网络代理(kube-proxy)实现负载均衡的地方,可以看到IP:172.16.251.156 就是创建的nginx service的IP
Chain KUBE-SERVICES (2 references)
KUBE-MARK-MASQ tcp -- !linux-servertwo/16 172.16.251.156 /* nginx/svc-nginx cluster IP */ tcp dpt:http
KUBE-SVC-XDC2TBTFGP42ST2T tcp -- anywhere 172.16.251.156 /* nginx/svc-nginx cluster IP */ tcp dpt:http# 通过下面可以看出,使用了 加权随机负载均衡
KUBE-SEP-MEC45OHITDUK5UCI all -- anywhere anywhere /* nginx/svc-nginx */ statistic mode random probability 0.33333333349
KUBE-SEP-OVGUVNLN5SZ5SJPC all -- anywhere anywhere /* nginx/svc-nginx */ statistic mode random probability 0.50000000000
KUBE-SEP-Q7FC6ND2772R7A3Y all -- anywhere anywhere /* nginx/svc-nginx */
# statistic mode random 是一种概率机制,表示 Kubernetes 根据给定的概率将流量随机地发送到指定的 Pod。这里的概率是:
# 33% 的流量会被转发到 MEC45OHITDUK5UCI 这个 Pod。
# 50% 的流量会被转发到 OVGUVNLN5SZ5SJPC 这个 Pod。
# 剩余的流量会被转发到 Q7FC6ND2772R7A3Y 这个 Pod。
# 结合这些规则,Kubernetes 通过随机概率来实现加权负载均衡,确保流量按照一定的比例(33%、50%)分发到不同的后端 Pod。这样的方式可以根据服务负载或者其他策略调整流量分配比例。
5.6、创建外部可访问的Service
想要创建集群外部也可访问的Service ,只需要在创建 service 指定--type=
的类型为 NodePord 类型 即可。
# 查看 Service
[root@linux-servertwo software]# kubectl get service -n nginx -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx ClusterIP 172.16.251.156 <none> 80/TCP 169m app=nginx# 删除原先的 ClusterIP 类型的服务
[root@linux-servertwo software]# kubectl delete service -n nginx svc-nginx
service "svc-nginx" deleted# 再次查看,发现已经删除
[root@linux-servertwo software]# kubectl get service -n nginx
No resources found in nginx namespace.# 创建NodePord类型的服务
[root@linux-servertwo software]# kubectl expose deployment -n nginx nginx --name=svc-nginx --type=NodePort --port=80 --target-port=80
service/svc-nginx exposed# 查看是否创建成功
[root@linux-servertwo software]# kubectl get service -n nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx NodePort 172.16.237.241 <none> 80:31918/TCP 17s
# 通过以上输出可以发现PORT(S) 属性80端口映射到31918端口了, 然后就可以通过访问31918端口在外部访问 nginx 了,访问主机IP+指定端口号31918就可以访问的随机一个 Pod 的 Nginx。使用宿主机访问31918端口:
[root@linux-servertwo software]# curl localhost:31918
this is 172.17.0.29 nginx
[root@linux-servertwo software]# curl localhost:31918
this is 172.17.0.28 nginx
[root@linux-servertwo software]# curl localhost:31918
this is 172.17.0.29 nginx
[root@linux-servertwo software]# curl localhost:31918
this is 172.17.0.27 nginx
# 所以,如果是集群内部访问,可以通过 172.16.237.241:80 访问 svc-nginx。如果是集群外部访问,使用节点的 IP 地址和端口 31918 访问 svc-nginx
5.7、删除 Service
# 通过 kubectl delete service <service-name> 进行删除
[root@linux-servertwo software]# kubectl delete service -n nginx svc-nginx
service "svc-nginx" deleted# 再次查看发现已经删除
[root@linux-servertwo software]# kubectl get service -n nginx
No resources found in nginx namespace.
5.8、YAML创建
# 输出一个 yaml 创建 nginx 的 Service 格式文件但不运行,输出到主机nginx-service.yml文件中
[root@linux-servertwo software]# kubectl expose deployment -n nginx nginx --name=svc-nginx --type=NodePort --port=80 --target-port=80 --dry-run=client -o yaml > nginx-service.yml# 输出成功后,查看输出的yml文件
[root@linux-servertwo software]# cat nginx-service.yml
apiVersion: v1
kind: Service
metadata:creationTimestamp: nulllabels:app: nginxname: svc-nginx
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: nginxtype: NodePort
status:loadBalancer: {}# 在使用kubectl expose命令生成Service的YAML文件时,生成的YAML文件默认不会包含命名空间信息,需要手动在生成的YAML文件中添加命名空间。
# 编辑 nginx-service.yml 文件,添加需要创建的命名空间后,再次查看
[root@linux-servertwo software]# cat nginx-service.yml
apiVersion: v1
kind: Service
metadata:creationTimestamp: nulllabels:app: nginxname: svc-nginxnamespace: nginx # 添加命名空间信息
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: nginxtype: NodePort
status:loadBalancer: {}# 运行nginx的YML文件
[root@linux-servertwo software]# kubectl apply -f nginx-service.yml
service/svc-nginx created# 查看是否创建成功
[root@linux-servertwo software]# kubectl get service -n nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx NodePort 172.16.87.14 <none> 80:30501/TCP 17s# 验证访问
# 访问内部IP+端口
[root@linux-servertwo software]# curl 172.16.87.14
this is 172.17.0.28 nginx
[root@linux-servertwo software]# curl 172.16.87.14
this is 172.17.0.29 nginx
[root@linux-servertwo software]# curl 172.16.87.14
this is 172.17.0.28 nginx
# 访问主机节点IP+端口
[root@linux-servertwo software]# curl localhost:30501
this is 172.17.0.27 nginx
[root@linux-servertwo software]# curl localhost:30501
this is 172.17.0.28 nginx
5.9、YAML删除
# 删除
[root@linux-servertwo software]# kubectl delete -f nginx-service.yml
service "svc-nginx" deleted# 再次查看
[root@linux-servertwo software]# kubectl get service -n nginx
No resources found in nginx namespace.
6、ipvs配置
kube-proxy
支持多种模式来实现这种负载均衡,包括:
iptables
模式:这是默认的模式,kube-proxy
使用 iptables
规则来实现 Service 到 Pod 的负载均衡。
ipvs
模式:从Kubernetes 1.8
开始支持,使用 IPVS(IP Virtual Server)
代替iptables
来实现负载均衡,IPVS
通常被认为比iptables
更高效,尤其是在高并发场景下。
# 查看所有 iptables规则
iptables -t nat -nL | iptables -L -v -n# k8s开启ipvs,首先查看,发现没有该命令
[root@linux-servertwo software]# ipvsadm -ln
-bash: ipvsadm: command not found# 安装 ipvsadm 工具
yum install ipvsadm -y
# 再次执行
[root@linux-servertwo software]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags-> RemoteAddress:Port Forward Weight ActiveConn InActConn# 查看加载内核模快是否加载ipvs
[root@linux-servertwo software]# lsmod | grep ip_vs
ip_vs_sh 12688 0
ip_vs_wrr 12697 0
ip_vs_rr 12600 0
ip_vs 145458 6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack 143411 7 ip_vs,nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_netlink,nf_conntrack_ipv4
libcrc32c 12644 3 ip_vs,nf_nat,nf_conntrack# 由于kube-proxy默认是通过iptables来进行转发的,需要将iptables转换为ipvs(提高性能)
[root@linux-servertwo software]# kubectl edit -n kube-system configmaps kube-proxy
# 默认为空,加上 ipvs 修改成功后保存
mode: "" -> mode: "ipvs" # 查看系统运行的Pod
[root@linux-servertwo software]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-7f89b7bc75-47d56 1/1 Running 0 8d
coredns-7f89b7bc75-h4c9b 1/1 Running 0 8d
etcd-linux-servertwo 1/1 Running 0 8d
kube-apiserver-linux-servertwo 1/1 Running 0 8d
kube-controller-manager-linux-servertwo 1/1 Running 0 7d
kube-proxy-j7d4v 1/1 Running 0 8d
kube-scheduler-linux-servertwo 1/1 Running 0 7d# 删除包含 kube-proxy的Pod
[root@linux-servertwo software]# kubectl delete pod -n kube-system kube-proxy-j7d4v
pod "kube-proxy-j7d4v" deleted# 删除成功后,再次查看,发现会重新创建一个新的 kube-proxy 的pod
[root@linux-servertwo software]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-7f89b7bc75-47d56 1/1 Running 0 8d
coredns-7f89b7bc75-h4c9b 1/1 Running 0 8d
etcd-linux-servertwo 1/1 Running 0 8d
kube-apiserver-linux-servertwo 1/1 Running 0 8d
kube-controller-manager-linux-servertwo 1/1 Running 0 7d
kube-proxy-wbst6 1/1 Running 0 16s
kube-scheduler-linux-servertwo 1/1 Running 0 7d#重新查看-列出所有
[root@linux-servertwo nginx]# ipvsadm -ln
# 条件筛选
[root@linux-servertwo software]# ipvsadm -ln | grep -A 3 "127.0.0.1:30501"
TCP 127.0.0.1:30501 rr-> 172.17.0.27:80 Masq 1 0 0 -> 172.17.0.28:80 Masq 1 0 0 -> 172.17.0.29:80 Masq 1 0 0
# 输出以上信息,说明使用ipvs负载均衡成功
7、实践-部署nginx
7.1、描述
通过以上的命令介绍,已经会使用K8s部署一个简单的应用了,接下来就来通过使用Deployment+NodePort的模式 安装部署一个高可用的Nginx服务
。
7.2、创建YML
创建一个 ingress-nginx.yml
文件,配置Nginx
的部署信息
# 1、创建 Namespace
apiVersion: v1
kind: Namespace
metadata:creationTimestamp: nullname: nginx-proxy
spec: {}
status: {}
---
# 2、创建 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:creationTimestamp: nulllabels:app: nginx-proxyname: nginx-proxynamespace: nginx-proxy
spec:replicas: 3selector:matchLabels:app: nginx-proxystrategy: {}template:metadata:creationTimestamp: nulllabels:app: nginx-proxyspec:#hostNetwork: true 使用宿主机的网络接口nodeSelector:beta.kubernetes.io/os: linuxpriorityClassName: system-node-criticalcontainers:- image: nginx:1.23.1name: nginximagePullPolicy: IfNotPresentports:- containerPort: 80resources: limits:cpu: 300mmemory: 512Mrequests:cpu: 25mmemory: 32MvolumeMounts:- name: confmountPath: /etc/nginx/nginx.confreadOnly: true volumes:- name: confhostPath:path: /opt/software/k8s-deployment/nginx/conf/nginx.conf
status: {}
---
# 3、创建 Service
apiVersion: v1
kind: Service
metadata:creationTimestamp: nulllabels:app: nginx-proxyname: svc-nginxnamespace: nginx-proxy
spec:ports:- port: 80protocol: TCPtargetPort: 80nodePort: 31001selector:app: nginx-proxytype: NodePort
status:loadBalancer: {}
参数配置说明:
分隔符
--- 分隔符是 Kubernetes YAML 文件中的标准语法,用于区分同一文件中的多个资源定义,使得一个文件可以包含多个资源对象。Deployment、Service 和 Namespace 是三个不同的 Kubernetes 资源定义,因此需要使用 --- 进行分隔。通过将多个资源定义写在一个 YAML 文件中,并用 --- 分隔,kubectl apply 可以一次性创建或更新多个资源,而不需要分别写多个文件或执行多次命令。
Namespace 配置说明:
# kind:Namespace 表示yaml文件创建的是命名空间
# metadata 表示命名空间的元信息
# metadata.name 是命名空间的名称 取值nginx
# metadata.labels 是命名空间的标签 name=nginx
Deployment 配置说明
hostNetwork: true # 使用宿主机的网络接口priorityClassName: system-node-critical # 用来设置Pod优先级,确保其在集群中具有较高的优先权。
# 关于 priorityClassName 优先级说明
# Kubernetes 默认提供了以下几种优先级类:
# system-node-critical:关键节点服务,优先级最高。 主要作用:Pod 会在资源紧张时优先保留,不会被驱逐,确保它们在节点上保持运行。
# system-cluster-critical:集群级别的关键服务,优先级最高。确保关键组件(如控制平面组件)能够在资源不足的情况下继续运行,如 kube-apiserver、 kube-controller-manager、kube-scheduler 等
# default:普通的默认优先级类。它的优先级低于 system-node-critical 和 system-cluster-critical
# 可以根据需要自定义优先级类。beta.kubernetes.io/os: linux # 确保Pod只会在具有该标签的节点上运行,避免调度到不符合条件的节点上
Service 配置说明
# 创建 NodePort Service 时,可以指定范围为30000-32767的端口
7.3、启动YML
# 通过 kubectl apply -f 创建
[root@linux-servertwo nginx]# kubectl apply -f ingress-nginx.yml
namespace/nginx-proxy created
deployment.apps/nginx-proxy created
service/svc-nginx created
7.4、查看
# 查看命名空间
[root@linux-servertwo nginx]# kubectl get namespace nginx-proxy
NAME STATUS AGE
nginx-proxy Active 4m7s# 查看资源
[root@linux-servertwo nginx]# kubectl get deploy,svc,pod -n nginx-proxy
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-proxy 3/3 3 3 4m20sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/svc-nginx NodePort 172.16.44.247 <none> 80:31001/TCP 4m20sNAME READY STATUS RESTARTS AGE
pod/nginx-proxy-6966ffc86c-289vk 1/1 Running 0 4m20s
pod/nginx-proxy-6966ffc86c-f47vl 1/1 Running 0 4m20s
pod/nginx-proxy-6966ffc86c-hqjvp 1/1 Running 0 4m20s
7.5、验证是否成功
# 查看资源详情显示IP地址
[root@linux-servertwo nginx]# kubectl get deploy,svc,pod -n nginx-proxy -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/nginx-proxy 3/3 3 3 4m39s nginx nginx:1.23.1 app=nginx-proxyNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/svc-nginx NodePort 172.16.44.247 <none> 80:31001/TCP 4m39s app=nginx-proxyNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/nginx-proxy-6966ffc86c-289vk 1/1 Running 0 4m39s 172.17.0.58 linux-servertwo <none> <none>
pod/nginx-proxy-6966ffc86c-f47vl 1/1 Running 0 4m39s 172.17.0.59 linux-servertwo <none> <none>
pod/nginx-proxy-6966ffc86c-hqjvp 1/1 Running 0 4m39s 172.17.0.57 linux-servertwo <none> <none># 查看ipvs链路规则
[root@linux-servertwo nginx]# ipvsadm -ln | grep -A 3 "127.0.0.1:31001"
TCP 127.0.0.1:31001 rr-> 172.17.0.57:80 Masq 1 0 0 -> 172.17.0.58:80 Masq 1 0 0 -> 172.17.0.59:80 Masq 1 0 0 # 验证负载均衡-首先进入容器内部配置html页面
[root@linux-servertwo nginx]# kubectl exec -it -n nginx-proxy nginx-proxy-6966ffc86c-289vk -- bash
root@nginx-proxy-6966ffc86c-289vk:/# echo this is 172.17.0.58 nginx > /usr/share/nginx/html/index.html
root@nginx-proxy-6966ffc86c-289vk:/# cat /usr/share/nginx/html/index.html
this is 172.17.0.58 nginx# 进入容器 172.17.0.59
[root@linux-servertwo nginx]# kubectl exec -it -n nginx-proxy nginx-proxy-6966ffc86c-f47vl -- bash
root@nginx-proxy-6966ffc86c-f47vl:/# echo this is 172.17.0.59 nginx > /usr/share/nginx/html/index.html
root@nginx-proxy-6966ffc86c-f47vl:/# cat /usr/share/nginx/html/index.html
this is 172.17.0.59 nginx
# 进入容器 172.17.0.57
[root@linux-servertwo nginx]# kubectl exec -it -n nginx-proxy nginx-proxy-6966ffc86c-hqjvp -- bash
root@nginx-proxy-6966ffc86c-hqjvp:/# echo this is 172.17.0.57 nginx > /usr/share/nginx/html/index.html
root@nginx-proxy-6966ffc86c-hqjvp:/# cat /usr/share/nginx/html/index.html
this is 172.17.0.57 nginx# 访问服务service
root@nginx-proxy-6966ffc86c-hqjvp:/# curl 172.16.44.247
this is 172.17.0.59 nginx
root@nginx-proxy-6966ffc86c-hqjvp:/# curl 172.16.44.247
this is 172.17.0.58 nginx
root@nginx-proxy-6966ffc86c-hqjvp:/# curl 172.16.44.247
this is 172.17.0.57 nginx
root@nginx-proxy-6966ffc86c-hqjvp:/# curl 172.16.44.247
this is 172.17.0.59 nginx
7.6、删除YML
# 删除 ingress-nginx.yml
[root@linux-servertwo nginx]# kubectl delete -f ingress-nginx.yml
namespace "nginx-proxy" deleted
deployment.apps "nginx-proxy" deleted
service "svc-nginx" deleted# 再次查看 namespace
[root@linux-servertwo nginx]# kubectl get namespace nginx-proxy
Error from server (NotFound): namespaces "nginx-proxy" not found# 查看资源
[root@linux-servertwo nginx]# kubectl get deploy,svc,pod -n nginx-proxy -o wide
No resources found in nginx-proxy namespace.