이전글에 이어 문제풀이를 진행합니다.
https://webheck.tistory.com/entry/cka-killersh-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4-1-5
6. Use context: kubectl config use-context k8s-c1-H
6-1. Create a new PersistentVolume named safari-pv. It should have a capacity of 2Gi, accessMode ReadWriteOnce, hostPath /Volumes/Data and no storageClassName defined.
6-2. Next create a new PersistentVolumeClaim in Namespace project-tiger named safari-pvc . It should request 2Gi storage, accessMode ReadWriteOnce and should not define a storageClassName. The PVC should bound to the PV correctly.
6-3. Finally create a new Deployment safari in Namespace project-tiger which mounts that volume at /tmp/safari-data. The Pods of that Deployment should be of image httpd:2.4.41-alpine.
PV (Persistent Volume) 에 관련된 문제이다.
단순히 PV 와 그에 해당하는 PVC 를 만든후 deployment 의 VolumeMount 를 pvc 로 지정하여 생성하면 된다.
6-1 .
pv 생성에 관련된 docs 문서는 아래를 참조한다 ( docs 조회시 사용한 검색어 -> search 에서 pv 검색 -> 해당페이지에서 hostPath 검색)
문제에서 주어진 pv 조건:
1) pv name : safari-pv
2) capacity : 2Gi
3) accessMode: ReadWriteOnce
4) hostPath: /Volumes/Data
5) storageClassName 는 정의하지 않기.
apiVersion: v1
kind: PersistentVolume
metadata:
name: safari-pv
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/Volumes/Data"
6-2. 조건에 맞는 pvc 를 만들어준다.
pvc 조건
1) name: safari-pvc
2) namespace: project-tiger
3) request storage : 2Gi
4) accessMode : ReadWriteOnce
5) storageClassName 정의하지 않기.
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: safari-pvc
namespace: project-tiger
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
6-3. 이제 주어진 조건의 deploment 를 생성하되 위에서 생성한 pvc 가 할당되도록 설정한다.
pvc 의 할당은 pod 하위 설정에서 가능하며 spec.volumes 에 사용할 pvc를 명명하고 spec.containers 에서 pvc 를 사용할 pod 설정안에서 위에 설정한 volumes 의 이름으로 volume 을 마운트 해주면 된다.
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: safari
name: safari
namespace: project-tiger
spec:
replicas: 1
selector:
matchLabels:
app: safari
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: safari
spec:
volumes: # 생성한 pvc 값을 할당한다.
- name: data
persistentVolumeClaim:
claimName: safari-pvc
containers:
- image: httpd:2.4.41-alpine
name: container
volumeMounts: # 위에 volumes 에 정의한 값을 맞춘다.
- name: data
mountPath: /tmp/safari-data
7. Use context: kubectl config use-context k8s-c1-H
The metrics-server has been installed in the cluster. Your college would like to know the kubectl commands to:
- show Nodes resource usage
- show Pods and their containers resource usage
Please write the commands into /opt/course/7/node.sh and /opt/course/7/pod.sh.
7번 문제는 kubectl 의 명령어를 작성하는 문제이다. 1,2 각각 Node 와 Pod 의 usage 를 확인하는 명령어를 물어보고 있다.
해당 명령어는 kubectl top 명령어를 통해 확인이 가능하다.
https://kubernetes.io/docs/reference/kubectl/generated/kubectl_top/
7-1. show Nodes resource usage
단순하게 노드의 사용정보들을 가져오면 된다.
kubectl top node
7-2. show Pods and their containers resource usage
여기서는 추가적인 조건이 붙은점으로 각 컨테이너의 리소스 사용량까지 가져와야 한다. 해당 내용은 kubectl top --help 를 사용해보면
-- containers 옵션을 추가하면 pod 와 해당 컨테이너의 사용량 까지 표현이 된다고 정의 되어있다.
kubectl top pod --containers
위 명령어들을 문제에서 주어진 파일경로에 command 를 작성해 준다.
8. Use context: kubectl config use-context k8s-c1-H
Ssh into the controlplane node with ssh cluster1-controlplane1. Check how the controlplane components kubelet, kube-apiserver, kube-scheduler, kube-controller-manager and etcd are started/installed on the controlplane node. Also find out the name of the DNS application and how it's started/installed on the controlplane node.
Write your findings into file /opt/course/8/controlplane-components.txt. The file should be structured like:
# /opt/course/8/controlplane-components.txt
kubelet: [TYPE]
kube-apiserver: [TYPE]
kube-scheduler: [TYPE]
kube-controller-manager: [TYPE]
etcd: [TYPE]
dns: [TYPE] [NAME]
Choices of [TYPE] are: not-installed, process, static-pod, pod
8번 문제는 특정 노드로 접속하여 kubelet 의 API 들의 상태를 체크하는 문제이다.
1) kubelet 의 상태를 체크한다.
kubelet 상태 체크방법은 노드에 ssh를 이용하여 접속한 이후 ps 명령어를 통해 kubelet 이 동작중인지 확인할 수 있다.
➜ ssh cluster1-controlplane1
root@cluster1-controlplane1:~# ps aux | grep kubelet # shows kubelet process
해당명령어를 통해 kubelet 이 동작중인것을 확인할 수 있다.
/usr/lib/systemd 경로에 있는 kube 관련 파일들을 확인해 보면 다음과 같이 결과가 나타나는데
➜ root@cluster1-controlplane1:~# find /usr/lib/systemd | grep kube
/usr/lib/systemd/system/kubelet.service
/usr/lib/systemd/system/kubelet.service.d
/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
➜ root@cluster1-controlplane1:~# find /usr/lib/systemd | grep etcd
이를 통해 kubelet 은 systemd 를 통해 동작중인 서비스임을 확인할수 있고, 나머지 컴포넌트들은 kubeadm 을 통해 생성된 컴포넌트임을 알수있다.
보통 다른 컴포넌트들은 static-pod 로 존재하게 되는데 해당 경로를 확인함으로써 다른 컴포넌트들은 static-pod 로 동작되는것을 확인할 수 있다. ( static-pod 경로 : /etc/kubernetes/manifests )
➜ root@cluster1-controlplane1:~# find /etc/kubernetes/manifests/
/etc/kubernetes/manifests/
/etc/kubernetes/manifests/kube-controller-manager.yaml
/etc/kubernetes/manifests/etcd.yaml
/etc/kubernetes/manifests/kube-apiserver.yaml
/etc/kubernetes/manifests/kube-scheduler.yaml
➜ root@cluster1-controlplane1:~# kubectl -n kube-system get pod -o wide | grep controlplane1
coredns-5644d7b6d9-c4f68 1/1 Running ... cluster1-controlplane1
coredns-5644d7b6d9-t84sc 1/1 Running ... cluster1-controlplane1
etcd-cluster1-controlplane1 1/1 Running ... cluster1-controlplane1
kube-apiserver-cluster1-controlplane1 1/1 Running ... cluster1-controlplane1
kube-controller-manager-cluster1-controlplane1 1/1 Running ... cluster1-controlplane1
kube-proxy-q955p 1/1 Running ... cluster1-controlplane1
kube-scheduler-cluster1-controlplane1 1/1 Running ... cluster1-controlplane1
weave-net-mwj47 2/2 Running ... cluster1-controlplane1
또한 static-pod 는 naming 규칙으로 파드명-노드명 으로 파드가 생성되기 때문에 kube-system 네임스페이스의 파드들을 확인해 보았을때 이름만으로도 해당 파드들이 static-pod 라는 것을 유추할수 있다.
마지막으로 dns 를 확인해 보자.
dns 는 주로 DaemonSets 또는 Deployments로 배포를 진행한다. 보통은 Deployments 를 많이 사용한다.
➜ root@cluster1-controlplane1$ kubectl -n kube-system get ds
NAME DESIRED CURRENT ... NODE SELECTOR AGE
kube-proxy 3 3 ... kubernetes.io/os=linux 155m
weave-net 3 3 ... <none> 155m
➜ root@cluster1-controlplane1$ kubectl -n kube-system get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
coredns 2/2 2 2 155m
문제에서도 두가지를 확인했으며 결과로 deployemt 에서 coredns 가 실행중인것을 알수 있었다.
이를통해 문제의 정답을 정리하면 다음과 같다.
# /opt/course/8/controlplane-components.txt
kubelet: process
kube-apiserver: static-pod
kube-scheduler: static-pod
kube-controller-manager: static-pod
etcd: static-pod
dns: pod coredns
9. Use context: kubectl config use-context k8s-c2-AC
9-1. Ssh into the controlplane node with ssh cluster2-controlplane1. Temporarily stop the kube-scheduler, this means in a way that you can start it again afterwards.
9-2. Create a single Pod named manual-schedule of image httpd:2.4-alpine, confirm it's created but not scheduled on any node.
9-3. Now you're the scheduler and have all its power, manually schedule that Pod on node cluster2-controlplane1. Make sure it's running.
9-4. Start the kube-scheduler again and confirm it's running correctly by creating a second Pod named manual-schedule2 of image httpd:2.4-alpine and check if it's running on cluster2-node1.
kube-scheduler 의 동작을 확인해 보는 문제이다.
9-1) 먼저 ssh 를 통해 cluster2-controlplane1 에 접속하여 kube-scheduler 를 종료시켜야 한다. kube-scheduler는 static-pod 로 동작중이기 때문에 /etc/kubernetes/manifests 안에 존재하는 kube-scheduler.yaml 파일을 다른 경로로 이동시켜 준다.
➜ root@cluster2-controlplane1:~# cd /etc/kubernetes/manifests/
➜ root@cluster2-controlplane1:~# mv kube-scheduler.yaml ..
9-2) 주어진 조건으로 pod를 실행시킨다.
k run manual-schedule --image=httpd:2.4-alpine
➜ k get pod manual-schedule -o wide
NAME READY STATUS ... NODE NOMINATED NODE
manual-schedule 0/1 Pending ... <none> <none>
하지만 해당 pod는 계속 Pending 상태로 실행되지 않고 있다. 왜냐하면 Pending 중인 pod를 실행할수 있는 node를 선택하여 파드가 실행될수 있도록 스케쥴링 해주는 역할인 kube-scheduler 가 실행중이지 않기 때문이다.
9-2) 그렇다면 해당 pod는 영원히 실행이 불가능 할까?
아니다. 파드가 실행될때 nodeName 을 명시적으로 적어준다면 해당 파드는 해당 노드에서 무조건 실행하게 된다.
https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodename
k get pod manual-schedule -o yaml > 9.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2020-09-04T15:51:02Z"
labels:
run: manual-schedule
managedFields:
...
manager: kubectl-run
operation: Update
time: "2020-09-04T15:51:02Z"
name: manual-schedule
namespace: default
resourceVersion: "3515"
selfLink: /api/v1/namespaces/default/pods/manual-schedule
uid: 8e9d2532-4779-4e63-b5af-feb82c74a935
spec:
nodeName: cluster2-controlplane1 # add the controlplane node name
containers:
- image: httpd:2.4-alpine
imagePullPolicy: IfNotPresent
name: manual-schedule
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-nxnc7
readOnly: true
dnsPolicy: ClusterFirst
...
실행중인 pod의 정보를 가져와 nodeName 을 명시해 준 이후 실행한다.
현재 실행중이기 때문이 kubectl replace -f <file-name>.yaml --force 를 이용하여 강제로 실행시킨다.
9-4) 다시 kube-scheduler 를 재실행 시키고 주어진 파드 정보로 파드가 실행되는지 확인하자.
➜ root@cluster2-controlplane1:~# cd /etc/kubernetes/manifests/
➜ root@cluster2-controlplane1:~# mv ../kube-scheduler.yaml .
➜ root@cluster2-controlplane1:~# kubectl -n kube-system get pod | grep schedule
kube-scheduler-cluster2-controlplane1 1/1 Running 0 16s
k run manual-schedule2 --image=httpd:2.4-alpine
10. Use context: kubectl config use-context k8s-c1-H
Create a new ServiceAccount processor in Namespace project-hamster. Create a Role and RoleBinding, both named processor as well. These should allow the new SA to only create Secrets and ConfigMaps in that Namespace.
RBAC(Role-based access control) 문제이다
https://kubernetes.io/docs/reference/access-authn-authz/rbac/
주어진 조건대로 serviceaccount, role, rolebinding 을 생성해주면 된다.
# ServiceAccount 생성하기
k -n project-hamster create sa processor
# role 생성하기. 조건 - create / secrets, configmaps
k -n project-hamster create role processor \
--verb=create \
--resource=secret,configmap
# rolebinding 생성하기 -> sa 에게 role 부여
k -n project-hamster create rolebinding processor \
--role processor \
--serviceaccount project-hamster:processor
# 권한 확인해보기
➜ k -n project-hamster auth can-i create secret \
--as system:serviceaccount:project-hamster:processor
yes
➜ k -n project-hamster auth can-i create configmap \
--as system:serviceaccount:project-hamster:processor
yes
➜ k -n project-hamster auth can-i create pod \
--as system:serviceaccount:project-hamster:processor
no
➜ k -n project-hamster auth can-i delete secret \
--as system:serviceaccount:project-hamster:processor
no
➜ k -n project-hamster auth can-i get configmap \
--as system:serviceaccount:project-hamster:processor
no
11. Use context: kubectl config use-context k8s-c1-H
Use Namespace project-tiger for the following. Create a DaemonSet named ds-important with image httpd:2.4-alpine and labels id=ds-important and uuid=18426a0b-5f59-4e10-923f-c0e078e82462. The Pods it creates should request 10 millicore cpu and 10 mebibyte memory. The Pods of that DaemonSet should run on all nodes, also controlplanes.
ds(DaemonSets)을 생성하라는 문제이다.
데몬셋은 보통 모든 노드에서 실행되게 만드는 파드를 생성할때 사용한다.
단 여기 문제 조건에서 중요하게 볼 점은 마지막 문장에 있는 also controlplanes 이다.
보통 데몬셋은 모든 노드에서 생성되지만 마스터노드에는 보통 Taints 옵션이 부여되어있기 때문에 해당 Taints 에 대한 Toleration 이 ds에 작성되지 않는다면 해당 데몬셋은 마스터 노드를 제외한 모든 노드에서 동작하게 된다.
즉 이문제는 ds를 만들되 마스터노드의 Toleration 또한 작성해 주어야 하는것이 핵심이다.
apiVersion: apps/v1
kind: DaemonSet # change from Deployment to Daemonset
metadata:
creationTimestamp: null
labels: # add
id: ds-important # add
uuid: 18426a0b-5f59-4e10-923f-c0e078e82462 # add
name: ds-important
namespace: project-tiger # important
spec:
#replicas: 1 # remove
selector:
matchLabels:
id: ds-important # add
uuid: 18426a0b-5f59-4e10-923f-c0e078e82462 # add
#strategy: {} # remove
template:
metadata:
creationTimestamp: null
labels:
id: ds-important # add
uuid: 18426a0b-5f59-4e10-923f-c0e078e82462 # add
spec:
containers:
- image: httpd:2.4-alpine
name: ds-important
resources:
requests: # add
cpu: 10m # add
memory: 10Mi # add
tolerations: # add
- effect: NoSchedule # add
key: node-role.kubernetes.io/control-plane # add
17.
Use context: kubectl config use-context k8s-c1-H
Use Namespace project-tiger for the following. Create a Deployment named deploy-important with label id=very-important (the Pods should also have this label) and 3 replicas. It should contain two containers, the first named container1 with image nginx:1.17.6-alpine and the second one named container2 with image google/pause.
There should be only ever one Pod of that Deployment running on one worker node. We have two worker nodes: cluster1-node1 and cluster1-node2. Because the Deployment has three replicas the result should be that on both nodes one Pod is running. The third Pod won't be scheduled, unless a new worker node will be added. Use topologyKey: kubernetes.io/hostname for this.
In a way we kind of simulate the behaviour of a DaemonSet here, but using a Deployment and a fixed number of replicas.
복합적인 내용이 포함된 deployment 문제이다. 조건을 정리해보면 다음과 같다.
1. deployments 를 생성한다.
ns: project-tiger / name: deploy-important / replicas: 3
2. 생성되는 pod 는 멀티컨테이너이다.
1번 container ) name: container1 / image: nginx:1.17.6-alpine
2번 container ) name: container2 / image: google/pause
3. 생성된 deployments 에서 1번 컨테이너는 각 워커노드에서만 한개씩만 존재해야 한다. (즉 3번째 replicas 에서 생성된 파드는 1번 컨테이너가 실행되지 않아야 한다.) 새로운 노드는 생성하면 안됨!
위 문제는 deployment 에서 생성한 파드가 각 노드에 균일하게 배정되도록 설정하는 문제이며 해당 문제는 Affinity 또는 TopologySpreadConstraints 를 통해 설정할 수 있다.
특징 | Pod Anti-Affinity | Topology Spread Constraints |
목적 | 특정 파드가 같은 노드에 함께 배치되지 않도록 방지 | 파드들이 노드 간에 균등하게 분산되도록 보장 |
적용방식 | 같은 노드에 파드를 배치하지 않음 | 각 노드에 파드가 일정하게 분산되도록 배치 |
topologyKey | 노드(또는 다른 토폴로지 키)에 기반해 배치 금지 | 노드(또는 다른 토폴로지 키)에 기반해 균등하게 분산 |
스케쥴링 실패 시 행동 | 규칙을 충족하지 않으면 스케쥴링이 실패함 | 분산 규칙을 충족하지 못할 경우 DoNotSchedule에 따라 스케쥴링 방지 |
maxSkew 설정 여부 | 없음 | maxSkew로 각 노드 간의 파드 수 차이를 제한 |
주로 사용되는 시나리오 | 특정 파드 간의 결리가 필요할 때 | 파드를 클러스터 내 노드에 고르게 분산시키고 싶을 때 |
PodAntiAffinity 사용
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
id: very-important # change
name: deploy-important
namespace: project-tiger # important
spec:
replicas: 3 # change
selector:
matchLabels:
id: very-important # change
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
id: very-important # change
spec:
containers:
- image: nginx:1.17.6-alpine
name: container1 # change
resources: {}
- image: google/pause # add
name: container2 # add
affinity: # add
podAntiAffinity: # add
requiredDuringSchedulingIgnoredDuringExecution: # add
- labelSelector: # add
matchExpressions: # add
- key: id # add
operator: In # add
values: # add
- very-important # add
topologyKey: kubernetes.io/hostname # add
status: {}
TopologySpreadConstraints 사용
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
id: very-important # change
name: deploy-important
namespace: project-tiger # important
spec:
replicas: 3 # change
selector:
matchLabels:
id: very-important # change
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
id: very-important # change
spec:
containers:
- image: nginx:1.17.6-alpine
name: container1 # change
resources: {}
- image: google/pause # add
name: container2 # add
topologySpreadConstraints: # add
- maxSkew: 1 # add
topologyKey: kubernetes.io/hostname # add
whenUnsatisfiable: DoNotSchedule # add
labelSelector: # add
matchLabels: # add
id: very-important # add
status: {}
13. Use context: kubectl config use-context k8s-c1-H
13-1. Create a Pod named multi-container-playground in Namespace default with three containers, named c1, c2 and c3. There should be a volume attached to that Pod and mounted into every container, but the volume shouldn't be persisted or shared with other Pods.
13-2. Container c1 should be of image nginx:1.17.6-alpine and have the name of the node where its Pod is running available as environment variable MY_NODE_NAME.
13-3. Container c2 should be of image busybox:1.31.1 and write the output of the date command every second in the shared volume into file date.log. You can use while true; do date >> /your/vol/path/date.log; sleep 1; done for this.
13-4. Container c3 should be of image busybox:1.31.1 and constantly send the content of file date.log from the shared volume to stdout. You can use tail -f /your/vol/path/date.log for this.
Check the logs of container c3 to confirm correct setup.
sidecar 관련 문제이다.
https://kubernetes.io/docs/concepts/cluster-administration/logging/
c1 파드를 동작시키면서 c2, c3 를 통해 로그파일을 로깅 시키는 사이드카 패턴으로 multi-conatiner 파드를 생성하면 된다.
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: multi-container-playground
name: multi-container-playground
spec:
containers:
- image: nginx:1.17.6-alpine
name: c1 # change
resources: {}
env: # add
- name: MY_NODE_NAME # add
valueFrom: # add
fieldRef: # add
fieldPath: spec.nodeName # add
volumeMounts: # add
- name: vol # add
mountPath: /vol # add
- image: busybox:1.31.1 # add
name: c2 # add
command: ["sh", "-c", "while true; do date >> /vol/date.log; sleep 1; done"] # add
volumeMounts: # add
- name: vol # add
mountPath: /vol # add
- image: busybox:1.31.1 # add
name: c3 # add
command: ["sh", "-c", "tail -f /vol/date.log"] # add
volumeMounts: # add
- name: vol # add
mountPath: /vol # add
dnsPolicy: ClusterFirst
restartPolicy: Always
volumes: # add
- name: vol # add
emptyDir: {} # add
status: {}
사이드카 패턴을 사용할때 중요한 점은 각 파드의 마운트를 emptyDir 를 통해 마운트 함으로써 파드생성과 동시에 임시 파일로 로그파일이 생성되고 파드가 삭제될 때는 사라지게 하는것이 핵심이다. 이로써 3개의 파드는 동일한 emptyDir 임시공간을 마운트 함으로써 서로 데이터 공유가 가능하게 되었으며 logs -c 컨테이너명 을 통해 각 파드들의 로그정보 또한 확인할수 있게 된다.
위 pods 에서는 c3 컨테이너를 통해 해당 파드의 로깅정보를 계속 확인할수 있게 된다.
14. Use context: kubectl config use-context k8s-c1-H
You're ask to find out following information about the cluster k8s-c1-H :
- How many controlplane nodes are available?
- How many worker nodes are available?
- What is the Service CIDR?
- Which Networking (or CNI Plugin) is configured and where is its config file?
- Which suffix will static pods have that run on cluster1-node1?
Write your answers into file /opt/course/14/cluster-info, structured like this:
# /opt/course/14/cluster-info
1: [ANSWER]
2: [ANSWER]
3: [ANSWER]
4: [ANSWER]
5: [ANSWER]
클러스터 정보를 확인하는 문제이다.
1) k get nodes 에서 controlplane 노드 갯수를 확인한다. - 1
2) k get nodes 에서 contolplane 노드 이외의 갯수를 확인한다. - 2
➜ k get node
NAME STATUS ROLES AGE VERSION
cluster1-controlplane1 Ready control-plane 27h v1.30.1
cluster1-node1 Ready <none> 27h v1.30.1
cluster1-node2 Ready <none> 27h v1.30.1
3) controlplane 노드의 describe 정보에서 CIDR 를 확인하거나 해당 노드에서 cluster-ip-range 정보를 확인한다.
➜ ssh cluster1-controlplane1
➜ root@cluster1-controlplane1:~# cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep range
- --service-cluster-ip-range=10.96.0.0/12
4) CNI 정보는 마스터노드의 /etc/cni/net.d 경로에 보통 위치한다.
➜ root@cluster1-controlplane1:~# find /etc/cni/net.d/
/etc/cni/net.d/
/etc/cni/net.d/10-weave.conflist
➜ root@cluster1-controlplane1:~# cat /etc/cni/net.d/10-weave.conflist
{
"cniVersion": "0.3.0",
"name": "weave",
...
5) static-pod 의 suffix 는 해당 "-노드명" 으로 붙게 된다.
'IT 기술 > k8s' 카테고리의 다른 글
[cka] CKA 취득 후기 - 늦은 정리... (0) | 2024.10.08 |
---|---|
[cka] NetworkPolicy (0) | 2024.09.17 |
[cka] killer.sh 문제풀이 - (1-5) (2) | 2024.09.14 |
[cka] TroubleShooting - Worker Node Failure (0) | 2024.08.25 |
[cka] TroubleShooting - Control Plane Failure (0) | 2024.08.25 |
댓글