1、权限控制RBDC
题目
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Context
为部署流水线创建一个新的 ClusterRole 并将其绑定到范围为特定的 namespace 的特定 ServiceAccount。
Task
创建一个名为 deployment-clusterrole 且仅允许创建以下资源类型的新 ClusterRole:
Deployment
StatefulSet
DaemonSet
在现有的 namespace app-team1 中创建一个名为 cicd-token 的新 ServiceAccount。
限于 namespace app-team1 中,将新的 ClusterRole deployment-clusterrole 绑定到新的 ServiceAccount cicd-token。
操作
#考试必做步骤
candidate@node01:~$ kubectl config use-context k8s #必做,形成肌肉记忆
candidate@node01:~$ kubectl create clusterrole deployment-clusterrole --verb=create --resource=deployments,statefulsets,daemonsets
clusterrole.rbac.authorization.k8s.io/deployment-clusterrole created
candidate@node01:~$ kubectl -n app-team1 create serviceaccount cicd-token
serviceaccount/cicd-token created
# 题目中写了“限于 namespace app-team1 中”,则创建 rolebinding(为特定角色)。没有写的话,则创建clusterrolebinding(集群角色)。rolebinding 后面的名字 cicd-token-rolebinding 随便起的,因为题目中没有要求,如果题目中有要求,就不能随便起了。
candidate@node01:~$ kubectl -n app-team1 create rolebinding cicd-token-rolebinding --clusterrole=deployment-clusterrole --serviceaccount=app-team1:cicd-token
rolebinding.rbac.authorization.k8s.io/cicd-token-rolebinding created
#检查
candidate@node01:~$ kubectl -n app-team1 describe rolebinding cicd-token-rolebinding
Name: cicd-token-rolebinding
Labels: <none>
Annotations: <none>
Role:
Kind: ClusterRole
Name: deployment-clusterrole
Subjects:
Kind Name Namespace
---- ---- ---------
ServiceAccount cicd-token app-team1
candidate@node01:~$ kubectl auth can-i create deployment --as system:serviceaccount:app-team1:cicd-token
no
candidate@node01:~$ kubectl auth can-i create deployment -n app-team1 --as system:serviceaccount:app-team1:cicd-token
yes
2、查看 pod 的 CPU
考题
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Task
通过 pod label name=cpu-loader,找到运行时占用大量 CPU 的 pod,
并将占用 CPU 最高的 pod 名称写入文件 /opt/KUTR000401/KUTR00401.txt(已存在)
考点:kubectl top -l 命令的使用
操作
#考试必做步骤
candidate@node01:~$ kubectl config use-context k8s #必做,形成肌肉记忆
candidate@node01:~$ kubectl top pod -l name=cpu-loader --sort-by=cpu -A
NAMESPACE NAME CPU(cores) MEMORY(bytes)
cpu-top redis-test-5db498bbd-h2mfj 2m 7Mi
cpu-top nginx-host-c58757c-q6k74 0m 5Mi
cpu-top test0-784f495b5c-2dqdv 0m 4Mi
candidate@node01:~$ echo "redis-test-5db498bbd-h2mfj" >> /opt/KUTR000401/KUTR00401.txt
candidate@node01:~$ cat /opt/KUTR000401/KUTR00401.txt
redis-test-5db498bbd-h2mfj
3、配置网络策略 NetworkPolicy
考题
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Task
在现有的 namespace my-app 中创建一个名为 allow-port-from-namespace 的新 NetworkPolicy。
确保新的 NetworkPolicy 允许 namespace echo 中的 Pods 连接到 namespace my-app 中的 Pods 的 9000 端口。
进一步确保新的 NetworkPolicy:
不允许对没有在监听端口 9000 的 Pods 的访问
不允许非来自 namespace echo 中的 Pods 的访问
双重否定就是肯定,所以最后两句话的意思就是:
仅允许端口为 9000 的 pod 方法。
仅允许 echo 命名空间中的 pod 访问。
考点:NetworkPolicy 的创建
操作
#查看有无要求的名称标签,如访问者的 namespace 没有标签 label,则需要手动打一个。如果有一个独特的标签 label,则也可以直接使用
candidate@node01:~$ kubectl get ns --show-labels
NAME STATUS AGE LABELS
app-team1 Active 271d kubernetes.io/metadata.name=app-team1
calico-apiserver Active 271d kubernetes.io/metadata.name=calico-apiserver,name=calico-apiserver,pod-security.kubernetes.io/enforce-version=latest,pod-security.kubernetes.io/enforce=privileged
calico-system Active 271d kubernetes.io/metadata.name=calico-system,name=calico-system,pod-security.kubernetes.io/enforce-version=latest,pod-security.kubernetes.io/enforce=privileged
cpu-top Active 271d kubernetes.io/metadata.name=cpu-top
default Active 271d kubernetes.io/metadata.name=default
echo Active 271d kubernetes.io/metadata.name=echo,project=echo
ing-internal Active 271d kubernetes.io/metadata.name=ing-internal
ingress-nginx Active 271d kubernetes.io/metadata.name=ingress-nginx
internal Active 271d kubernetes.io/metadata.name=internal
kube-node-lease Active 271d kubernetes.io/metadata.name=kube-node-lease
kube-public Active 271d kubernetes.io/metadata.name=kube-public
kube-system Active 271d kubernetes.io/metadata.name=kube-system
my-app Active 271d kubernetes.io/metadata.name=my-app
tigera-operator Active 271d kubernetes.io/metadata.name=tigera-operator,name=tigera-operator
#手动打一个标签
candidate@node01:~$ kubectl label ns echo project=echo
namespace/echo labeled
candidate@node01:~$ kubectl get ns echo --show-labels
NAME STATUS AGE LABELS
echo Active 271d kubernetes.io/metadata.name=echo,project=echo
candidate@node01:~$ cat networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-port-from-namespace
namespace: my-app
spec:
podSelector: {
}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
project: echo
ports:
- protocol: TCP
port: 9000
candidate@node01:~$ kubectl apply -f networkpolicy.yaml
networkpolicy.networking.k8s.io/allow-port-from-namespace created
#检查
candidate@node01:~$ kubectl describe networkpolicies -n my-app
Name: allow-port-from-namespace
Namespace: my-app
Created on: 2024-02-16 16:43:37 +0800 CST
Labels: <none>
Annotations: <none>
Spec:
PodSelector: <none> (Allowing the specific traffic to all pods in this namespace)
Allowing ingress traffic:
To Port: 9000/TCP
From:
NamespaceSelector: project=echo
Not affecting egress traffic
Policy Types: Ingress
4、暴露服务 service
考题
设置配置环境:
[candidate@node-1] $ kubectl config use-context k8s
Task
请重新配置现有的 deployment front-end 以及添加名为 http 的端口规范来公开现有容器 nginx 的端口 80/tcp。
创建一个名为 front-end-svc 的新 service,以公开容器端口 http。
配置此 service,以通过各个 Pod 所在的节点上的 NodePort 来公开他们。
考点:将现有的 deploy 暴露成 NodePort 的 service。
操作
candidate@node01:~$ kubectl get deployment front-end -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
front-end 1/1 1 1 271d nginx vicuu/nginx:hello app=front-end
candidate@node01:~$ kubectl edit deployment front-end
deployment.apps/front-end edited
......
template:
metadata:
creationTimestamp: null
labels:
app: front-end
spec:
containers:
- image: vicuu/nginx:hello
imagePullPolicy: IfNotPresent
name: nginx #找到此位置。添加以下四行
ports:
- name: http
containerPort: 80
protocol: TCP
resources: {
}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {
}
terminationGracePeriodSeconds: 30
status:
availableReplicas: 1
conditions:
- lastTransitionTime: "2023-08-27T04:41:17Z"
lastUpdateTime: "2023-08-27T04:41:17Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
#暴露对应端口,注意考试中需要创建的是 NodePort,还是 ClusterIP。如果是 ClusterIP,则应为--type=ClusterIP --port 是 service 的端口号,--target-port 是 deployment 里 pod 的容器的端口号。
candidate@node01:~$ kubectl expose deployment front-end --type=NodePort --port=80 --target-port=80 --name=front-end-svc
service/front-end-svc exposed
#暴露服务后,检查一下 service 的 selector 标签是否正确,这个要与 deployment 的 selector 标签一致的。
candidate@node01:~$ kubectl get pod,svc -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/11-factor-app 1/1 Running 6 (158m ago) 271d 10.244.196.182 node01 <none> <none>
pod/foo 1/1 Running 6 (158m ago) 271d 10.244.196.178 node01 <none> <none>
pod/front-end-55f9bb474b-mx49g 1/1 Running 0 83m 10.244.196.184 node01 <none> <none>
pod/presentation-856b8578cd-gd28p 1/1 Running 6 (158m ago) 271d 10.244.140.124 node02 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/front-end-svc NodePort 10.111.50.109 <none> 80:31203/TCP 76m app=front-end
service/kubern