CKAD考试实操指南(七)---网络纵横谋略:服务和网络实战要诀

原创
2023/10/08 15:20
阅读数 96

服务和网络实战

在这份CKAD考试实操指南中,我将为你详细介绍如何利用CKAD-exercises项目知十平台进行CKAD考试的准备和复习。通过CKAD-exercises提供的练习题,你可以在知十平台的云原生环境中进行实践和模拟。在这个过程中,你将熟悉Kubernetes的各种操作和场景,并在实践中加深对知识的理解。这种结合实践和理论的学习方式将为你在考试中取得优异成绩提供强有力的支持。

首先,打开浏览器,访问知十平台。在页面右上角点击“登录”,然后使用微信扫码登录即可。

在未登录状态下,每个环境只能体验15分钟,每天有5次机会使用。登录后,每个环境可用时长为1小时,每天登录也有5次的使用机会。

当选择好要进入环境后,通常只需要等待约一分钟左右,就能进入环境中。在等待期间,你可以浏览环境说明文档,了解该环境包含哪些组件及版本。

现在开始第六个主题----服务和网络的实操

官网链接及访问路径

这里使用到官网的链接及访问路径如下:

Kubernetes Documentation > Concepts > Services, Load Balancing, and Networking > Service

https://kubernetes.io/docs/concepts/services-networking/service/

kubernetes.io > Documentation > Concepts > Services, Load Balancing, and Networking > Network Policies

https://kubernetes.io/docs/concepts/services-networking/network-policies/

题目

服务和网络

1、Create a pod with image nginx called nginx and expose its port 80

译:创建一个名为nginx的使用镜像nginx的pod,并公开其端口80

# kubectl run nginx: 这部分命令表示要使用kubectl运行一个Pod,并将其命名为"nginx"。这会创建一个新的Pod,使用默认镜像(通常是一个空白镜像)。
# --image=nginx: 这部分命令指定了要在Pod中使用的容器镜像。在这种情况下,镜像名称是"nginx",这将使用官方的Nginx容器镜像。
# --restart=Never: 这部分命令指定了Pod的重启策略。"Never"表示当Pod终止时不会自动重启。这意味着如果Pod终止(例如,由于容器退出或节点故障),它不会自动重新启动。
# --port=80: 这部分命令指定了Pod中容器的一个端口,该端口将被公开以供访问。在这种情况下,容器的端口是80,这是HTTP通常使用的端口。
# --expose: 这部分命令会为创建的Pod创建一个Kubernetes服务。服务将允许其他Pod或外部客户端通过Kubernetes集群内部的IP和端口访问该Pod。如果没有指定服务类型,默认情况下将创建一个ClusterIP类型的服务,该服务仅在Kubernetes集群内部可用。

kubectl run nginx --image=nginx --restart=Never --port=80 --expose
# observe that a pod as well as a service are created

知识点

  • 服务类型 (Service Types) : Kubernetes支持不同类型的服务,包括:
    • ClusterIP: 创建一个仅在Kubernetes集群内部可用的服务。这是默认的服务类型。
    • NodePort: 创建一个服务,并在每个节点上开放一个固定的端口,允许从集群外部访问服务。
    • LoadBalancer: 创建一个云提供商特定的负载均衡器服务,用于将流量从集群外部引导到服务。
    • ExternalName: 将服务映射到外部名称,而不是集群内的其他Pod IP。

2、Confirm that ClusterIP has been created. Also check endpoints

译:确认ClusterIP已创建。并且检查端点

# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
# get: 这是kubectl命令的一个子命令,用于检索(获取)Kubernetes资源的信息。
# svc: 这是get子命令的参数,表示要获取服务(Service)资源的信息。
# nginx: 这是服务的名称。通过指定服务名称,可以获取与该名称匹配的服务的详细信息。
kubectl get svc nginx 

# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
# get: 这是kubectl命令的一个子命令,用于检索(获取)Kubernetes资源的信息。
# ep: 这是get子命令的参数,表示要获取Endpoints资源的信息。
kubectl get ep 

知识点

  • service(svc)和Endpoints(ep) :
    • Endpoints是Service的一部分,它包含了一个Service所关联的一组后端Pod的IP地址和端口信息。Endpoints资源是自动生成的,它们维护了与Service关联的后端Pod的列表。这些后端Pod是通过标签选择器与Service关联的。
    • Service使用Endpoints来路由流量。当有流量发送到Service的ClusterIP(或其他类型的服务IP)时,Service会查找Endpoints资源以确定哪些后端Pod应该接收流量,并将流量路由到这些Pod。

3、Get service's ClusterIP, create a temp busybox pod and 'hit' that IP with wget

译:获取服务的ClusterIP,创建一个临时busybox pod,并使用wget“命中”该IP

# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
# get: 这是kubectl命令的一个子命令,用于检索(获取)Kubernetes资源的信息。
# svc: 这是get子命令的参数,表示要获取服务(Service)资源的信息。
# nginx: 这是服务的名称。通过指定服务名称,可以获取与该名称匹配的服务的详细信息。
kubectl get svc nginx 

# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
# run: 这是kubectl命令的一个子命令,用于创建一个新的Pod或作业(Job)。
# busybox: 这是要创建的Pod的名称,它被命名为"busybox"。
# --rm: 这个选项表示在退出Pod后自动删除Pod。这是通过创建一个临时性的Pod来执行命令,并在命令执行完毕后将其删除,以避免残留的Pod。
# --image=busybox: 这个选项指定了要使用的容器镜像。在这种情况下,使用的是"busybox"镜像,这是一个轻量级的Linux发行版,通常用于临时任务或调试。
# -it: 这两个选项一起使用,分别表示要分配一个交互式的终端(TTY)以及将标准输入(stdin)绑定到终端。这使得可以与Pod中的Shell进行交互,就好像你直接连接到了Pod一样。
# --restart=Never: 这个选项指定了Pod的重启策略。"Never"表示当Pod终止时不会自动重启。这意味着如果Pod终止(例如,命令执行完毕),它不会自动重新启动。
# -- sh: 这是要在Pod中执行的命令。在这里,它表示要在Pod中启动一个Shell (sh),以便可以与Pod的Shell进行交互
kubectl run busybox --rm --image=busybox -it --restart=Never -- sh

# 对第一步获取到的ip执行 wget命令
wget -O- IP:80
# 退出pod
exit


#或
IP=$(kubectl get svc nginx --template={{.spec.clusterIP}}) 

# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
# run: 这是kubectl命令的一个子命令,用于创建一个新的Pod或作业(Job)。
# busybox: 这是要创建的Pod的名称,它被命名为"busybox"。
# --rm: 这个选项表示在退出Pod后自动删除Pod。这是通过创建一个临时性的Pod来执行命令,并在命令执行完毕后将其删除,以避免残留的Pod。
# --image=busybox: 这个选项指定了要使用的容器镜像。在这种情况下,使用的是"busybox"镜像,这是一个轻量级的Linux发行版,通常用于临时任务或调试。
# -it: 这两个选项一起使用,分别表示要分配一个交互式的终端(TTY)以及将标准输入(stdin)绑定到终端。这使得你可以与Pod中的Shell进行交互,就好像你直接连接到了Pod一样。
# --restart=Never: 这个选项指定了Pod的重启策略。"Never"表示当Pod终止时不会自动重启。这意味着如果Pod终止(例如,命令执行完毕),它不会自动重新启动。
# --env="IP=$IP": 这个选项用于设置环境变量,将变量"IP"设置为值"$IP"。这个命令中的"$IP"是一个占位符,可能在实际执行命令之前被替换为具体的IP地址值。
# --: 这是一个分隔符,用于将kubectl run命令的选项与要在Pod中执行的命令分开。
# wget -O- $IP:80 --timeout 2: 这是要在Pod中执行的命令。这个命令使用wget工具从指定的IP地址(可能是环境变量"IP"的值)的端口80下载内容,并在2秒内超时。具体来说:
# wget是一个用于从Web服务器下载文件的命令行工具。
# -O-选项指示将下载的内容输出到标准输出(stdout)。
# $IP:80表示要下载的目标URL,其中"$IP"将在运行时被替换为环境变量"IP"的值。
# --timeout 2指定了下载操作的超时时间为2秒。

kubectl run busybox --rm --image=busybox -it --restart=Never --env="IP=$IP" -- wget -O- $IP:80 --timeout 2

4、Convert the ClusterIP to NodePort for the same service and find the NodePort port. Hit service using Node's IP. Delete the service and the pod at the end.

译:将ClusterIP转换为同一服务的NodePort,并找到NodePort端口。使用Node的IP命中服务。最后删除服务和Pod。

# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
# edit: 这是kubectl命令的一个子命令,用于编辑Kubernetes资源的配置。
# svc: 这是edit子命令的参数,表示要编辑服务(Service)资源的配置。
# nginx: 这是服务的名称,指定了要编辑的服务的名称。
kubectl edit svc nginx

# 展示大概如下
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: 2018-06-25T07:55:16Z
  name: nginx
  namespace: default
  resourceVersion: "93442"
  selfLink: /api/v1/namespaces/default/services/nginx
  uid: 191e3dac-784d-11e8-86b1-00155d9f663c
spec:
  clusterIP: x.x.x.x
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: nginx
  sessionAffinity: None
  type: NodePort # 修改此处从ClusterIP为NodePort
status:
  loadBalancer: {}


# 或者
# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
# patch: 这是kubectl命令的一个子命令,用于对Kubernetes资源进行部分更新。通过部分更新,可以修改资源的某些属性而不必替换整个资源配置。
# svc: 这是patch子命令的参数,表示要对服务(Service)资源进行部分更新。
# nginx: 这是服务的名称,指定了要进行部分更新的服务的名称。
# -p '{"spec":{"type":"NodePort"}}': 这是一个选项,用于指定部分更新的内容。在这里,它指定了要对服务的"spec"字段中的"type"属性进行更改为"NodePort"。这表示要将服务的类型从默认的ClusterIP更改为NodePort类型。
kubectl patch svc nginx -p '{"spec":{"type":"NodePort"}}' 

#获取svc信息
kubectl get svc

# 结果类似如下:
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   x.x.x.x          <none>        443/TCP        1d
nginx        NodePort    x.x.x.x          <none>        80:30490/TCP   3m

wget -O- 172.18.0.1:30490

# 删除svc
kubectl delete svc nginx 
#删除pod
kubectl delete pod nginx

5、Create a deployment called foo using image 'dgkanatsios/simpleapp' (a simple server that returns hostname) and 3 replicas. Label it as 'app=foo'. Declare that containers in this pod will accept traffic on port 8080 (do NOT create a service yet)

译:使用镜像'dgkanatsios/simpleapp'(一个返回主机名的简单服务器),创建一个名为'foo'的工作负载(Deployment),并设置副本数为3。为其打上'app=foo'的标签。声明该Pod中的容器将在端口8080上接收流量(暂时不要创建服务)。

# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
# create deploy foo: 这部分命令指定了要创建的资源类型和名称。它表示要创建一个名为"foo"的部署(Deployment)。
# --image=dgkanatsios/simpleapp: 这部分命令指定了部署中要使用的容器镜像的名称。在这种情况下,使用的是"dgkanatsios/simpleapp"容器镜像。
# --port=8080: 这部分命令指定了容器在部署中使用的端口号。容器内的应用程序将在端口8080上监听连接。
# --replicas=3: 这部分命令指定了要创建的副本数。部署将管理3个副本的Pod,确保它们一直在运行,以维护所需的副本数量
kubectl create deploy foo --image=dgkanatsios/simpleapp --port=8080 --replicas=3

# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
# label deployment foo: 这部分命令指定了要操作的资源类型和名称。它表示要对名为"foo"的Deployment添加标签。
# --overwrite: 这是一个选项,指示要覆盖已存在的同名标签。如果Deployment已经具有名为"app"的标签,使用--overwrite选项将覆盖它。
# app=foo: 这是要添加到Deployment的标签的键值对。在这里,它指定了一个名为"app"的标签,其值为"foo"。这将标记Deployment为"app=foo"。
kubectl label deployment foo --overwrite app=foo 

6、Get the pod IPs. Create a temp busybox pod and try hitting them on port 8080

译:获取Pod的IP地址,创建一个临时busybox pod并尝试在端口8080上攻击它们

# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
# get pods: 这部分命令表示要获取Pod资源的信息。它告诉kubectl你要检索有关Pod的信息。
# -l app=foo: 这是一个选项,用于指定标签选择器。这个选择器告诉kubectl只返回具有标签"app=foo"的Pod。它用于过滤Pod,只返回符合该标签选择器条件的Pod。
# -o wide: 这是另一个选项,用于指定输出格式。"wide"输出格式显示更多的详细信息,包括每个Pod的IP地址、Node节点、状态和其他相关信息。
kubectl get pods -l app=foo -o wide

# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
# run: 这是kubectl命令的一个子命令,用于创建一个新的Pod或作业(Job)。
# busybox: 这是要创建的Pod的名称,它被命名为"busybox"。
# --rm: 这个选项表示在退出Pod后自动删除Pod。这是通过创建一个临时性的Pod来执行命令,并在命令执行完毕后将其删除,以避免残留的Pod。
# --image=busybox: 这个选项指定了要使用的容器镜像。在这种情况下,使用的是"busybox"镜像,这是一个轻量级的Linux发行版,通常用于临时任务或调试。
# -it: 这两个选项一起使用,分别表示要分配一个交互式的终端(TTY)以及将标准输入(stdin)绑定到终端。这使得你可以与Pod中的Shell进行交互,就好像你直接连接到了Pod一样。
# --restart=Never: 这个选项指定了Pod的重启策略。"Never"表示当Pod终止时不会自动重启。这意味着如果Pod终止(例如,命令执行完毕),它不会自动重新启动。
# -- sh: 这是要在Pod中执行的命令。在这里,它表示要在Pod中启动一个Shell (sh),以便可以与Pod的Shell进行交互
kubectl run busybox --image=busybox --restart=Never -it --rm -- sh

# 攻击8080端口
wget -O- <POD_IP>:8080 

#退出pod
exit

7、Create a service that exposes the deployment on port 6262. Verify its existence, check the endpoints

译:创建在端口6262上暴露工作负载的服务。验证它的存在,检查端点

# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
# expose deploy foo: 这部分命令表示要创建一个服务并公开名为"foo"的部署中的Pod。它告诉kubectl要执行服务公开操作,并指定了目标部署的名称,即"foo"。
# --port=6262: 这是一个选项,用于指定服务的端口号。这是服务监听的端口号。在这里,服务将监听端口6262,以便其他应用程序可以通过这个端口访问服务。
# --target-port=8080: 这是另一个选项,用于指定服务将流量路由到部署中Pod的哪个端口。在这里,它指定了将流量路由到部署中Pod的端口8080。
kubectl expose deploy foo --port=6262 --target-port=8080

# 获取service
kubectl get service foo

# 获取端点 
kubectl get endpoints foo

知识点

  • --port 选项--port选项用于指定服务要监听的端口号。这个端口号是服务的入口端口,其他应用程序可以通过访问该端口与服务通信。例如,--port=80表示服务将监听端口80。
  • --target-port 选项--target-port选项用于指定服务将流量路由到的后端Pod的哪个端口。这个端口是Pod内运行的应用程序的监听端口。当服务接收到流量时,它将流量路由到后端Pod的--target-port指定的端口。例如,--target-port=8080表示服务将流量路由到后端Pod的端口8080
  • 端口映射:服务的--port--target-port选项通常一起使用,以便在服务和Pod之间建立端口映射。服务监听指定的--port,并将流量路由到后端Pod的--target-port。这允许服务在外部公开一个端口,并将流量转发到内部的Pod,无需外部用户知道Pod的具体端口。
  • 多端口服务:Kubernetes支持创建多端口服务,其中一个服务可以监听多个端口,并将流量路由到不同的后端Pod端口。每个端口可以有不同的--target-port配置。

8、Create a temp busybox pod and connect via wget to foo service. Verify that each time there's a different hostname returned. Delete deployment and services to cleanup the cluster

译:创建一个临时busybox pod,并通过wget连接到foo服务。验证每次返回的主机名是否不同。删除工作负载和服务以清理集群。

# 查看现有的service
kubectl get svc

# 运行临时容器
kubectl run busybox --image=busybox -it --rm --restart=Never -- sh

# wget service名称
wget -O- foo:6262

#wget service的ip
wget -O- <SERVICE_CLUSTER_IP>:6262 

#删除service和deploy
kubectl delete svc foo
kubectl delete deploy foo

9、Create an nginx deployment of 2 replicas, expose it via a ClusterIP service on port 80. Create a NetworkPolicy so that only pods with labels 'access: granted' can access the deployment and apply it

译:创建2个副本的nginx工作负载,通过端口80上的ClusterIP服务暴露它。创建一个NetworkPolicy,以便只有具有标签“acccess:granted”的Pod才能访问可以访问工作负载。

# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
# create deployment nginx: 这部分命令指定了要创建的资源类型和名称。它表示要创建一个名为"nginx"的部署。
# --image=nginx: 这是一个选项,用于指定部署中要使用的容器镜像。在这种情况下,使用的是"nginx"容器镜像,这是一个流行的Web服务器和反向代理服务器的镜像。
# --replicas=2: 这是另一个选项,用于指定要创建的Pod副本的数量。在这里,它指定要创建2个副本的Pod。这意味着部署将维护2个相同配置的Pod副本,以确保应用程序的高可用性。
kubectl create deployment nginx --image=nginx --replicas=2

# kubectl: 这是Kubernetes命令行工具,用于与Kubernetes集群进行交互和管理。
#expose deployment nginx: 这部分命令表示要创建一个服务并公开名为"nginx"的部署中的Pod。它告诉kubectl要执行服务公开操作,并指定了目标部署的名称,即"nginx"。
# --port=80: 这是一个选项,用于指定服务要监听的端口号。这个端口号是服务的入口端口,其他应用程序可以通过访问该端口与服务通信。在这里,服务将监听端口80,通常用于HTTP流量。
kubectl expose deployment nginx --port=80

# 获取nginx service的信息
kubectl describe svc nginx

# 因flannel不支持NetworkPolicy,首先更换网络插件,示例使用calico
cd /root/Desktop/cni/calico && sh change flannel cni calico.sh

# 等待执行完成

# 创建策略yaml文件
vi policy.yaml

---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-nginx # policy的名称
spec:
  podSelector:
    matchLabels:
      app: nginx # 筛选并绑定到符合什么标签的pod
  ingress: # 允许的访问策略
  - from:
    - podSelector: # pod的筛选策略
        matchLabels: # pod的label
          access: granted
---


# 创建 NetworkPolicy
kubectl create -f policy.yaml

#  验证策略是否生效

# 创建不包含标签的pod
kubectl run busybox --image=busybox --rm -it --restart=Never -- wget -O- http://nginx:80 --timeout 2                          

# 创建包含access=granted标签的pod
kubectl run busybox --image=busybox --rm -it --restart=Never --labels=access=granted -- wget -O- http://nginx:80 --timeout 2  

知识点

NetworkPolicy主要包含以下内容

  • Pod选择器:NetworkPolicy使用Pod选择器来指定受策略保护的目标Pod。可以定义一个或多个标签选择器,以选择要应用策略的Pod。策略将仅影响这些Pod。
  • 策略规则:网络策略包含一组规则,用于指定允许或拒绝的流量。每个规则定义了一组允许或拒绝的源Pod、目标Pod、端口和协议。策略规则允许详细控制流量的行为。
    • 入站规则 (Ingress Rules) :入站规则定义了允许从其他Pod或IP地址到达受保护Pod的流量的条件。入站规则包括源选择器和端口规则。
      • 源选择器 (Source Selector) :源选择器定义了哪些Pod或IP地址可以作为流量的源。你可以使用Pod选择器或IP块来定义源选择器。例如,你可以允许来自特定标签的Pod的流量。
ingress:
- from:
  - podSelector:
      matchLabels:
        app: backend
  • 端口规则 (Port Rules) :端口规则定义了哪些端口和协议的流量允许通过。你可以指定一个或多个端口和协议。例如,你可以允许TCP端口80的流量。
ingress:
- ports:
  - port: 80
    protocol: TCP
  • 出站规则 (Egress Rules) :出站规则定义了从受保护Pod流向其他Pod或IP地址的流量的条件。出站规则也包括目标选择器和端口规则,类似于入站规则。
egress:
- to:
  - ipBlock:
      cidr: 10.0.0.0/24
- ports:
  - port: 5432
    protocol: TCP
  • 策略动作 (Policy Actions) :策略规则可以定义一种动作,即允许(allow)或拒绝(deny)流量。允许动作表示匹配的流量将被允许通过,而拒绝动作表示匹配的流量将被拒绝。
ingress:
- from:
  - podSelector:
      matchLabels:
        app: frontend
# Allow action:
- action: Allow

系列文章系列文章

我叫小十,关注我,我将继续更新 CKAD 考试攻略与实操指南文章系列

CKAD 考试实操指南(一)--- 登顶 CKAD:征服考试的完美蓝图

CKAD 考试实操指南(二)--- 深入核心:探秘 Kubernetes 核心实操秘技

CKAD 考试实操指南(三)--- 舞动容器:多容器 Pod 实践指南

CKAD 考试实操指南(四)--- 优雅设计:掌握 Pod 设计技巧

CKAD 考试实操指南(五)---定制你的舞台:配置实践要点

CKAD考试实操指南(六)---剖析系统:深入可观察性实践

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部