Security
1) View Certificate Details
2) Certificates API
3) KubeConfig
4) Role Based Access Controls
5) Cluster Roles
6) Service Accounts
7) Image Security
8) Security Contexts
9) Network Policies
01. Inspect the environment and identify the authorization modes configured on the cluster.
Check the kube-apiserver settings.
Use the command
kubectl describe pod kube-apiserver-controlplane -n kube-system and look for --authorization-mode
ask : Node,RBAC
02. How many roles exist in the default namespace?
ask : 0
root@controlplane:~# kubectl get roles
root@controlplane:~# kubectl describe pod kube-apiserver-controlplane -n kube-system
Name: kube-apiserver-controlplane
Namespace: kube-system
Priority: 2000001000
Priority Class Name: system-node-critical
Node: controlplane/10.154.138.9
Start Time: Tue, 25 Jan 2022 07:53:55 +0000
Labels: component=kube-apiserver
tier=control-plane
Annotations: kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 10.154.138.9:6443
kubernetes.io/config.hash: d983107cfe3328f33026fdd1d3f6d368
kubernetes.io/config.mirror: d983107cfe3328f33026fdd1d3f6d368
kubernetes.io/config.seen: 2022-01-25T07:53:53.823816351Z
kubernetes.io/config.source: file
Status: Running
IP: 10.154.138.9
IPs:
IP: 10.154.138.9
Controlled By: Node/controlplane
Containers:
kube-apiserver:
Container ID: docker://bf0e2c98a8589d8203fe50b0691593ad4ed106cf0d21d52b6e692fbd5bd27c5c
Image: k8s.gcr.io/kube-apiserver:v1.20.0
Image ID: docker-pullable://k8s.gcr.io/kube-apiserver@sha256:8b8125d7a6e4225b08f04f65ca947b27d0cc86380bf09fab890cc80408230114
Port: <none>
Host Port: <none>
Command:
kube-apiserver
--advertise-address=10.154.138.9
--allow-privileged=true
--authorization-mode=Node,RBAC
--client-ca-file=/etc/kubernetes/pki/ca.crt
--enable-admission-plugins=NodeRestriction
--enable-bootstrap-token-auth=true
--etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
--etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
--etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
--etcd-servers=https://127.0.0.1:2379
--insecure-port=0
--kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
--kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
--proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
--proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
--requestheader-allowed-names=front-proxy-client
--requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
--requestheader-extra-headers-prefix=X-Remote-Extra-
--requestheader-group-headers=X-Remote-Group
--requestheader-username-headers=X-Remote-User
--secure-port=6443
--service-account-issuer=https://kubernetes.default.svc.cluster.local
--service-account-key-file=/etc/kubernetes/pki/sa.pub
--service-account-signing-key-file=/etc/kubernetes/pki/sa.key
--service-cluster-ip-range=10.96.0.0/12
--tls-cert-file=/etc/kubernetes/pki/apiserver.crt
--tls-private-key-file=/etc/kubernetes/pki/apiserver.key
State: Running
Started: Tue, 25 Jan 2022 07:53:39 +0000
Ready: True
Restart Count: 0
Requests:
cpu: 250m
Liveness: http-get https://10.154.138.9:6443/livez delay=10s timeout=15s period=10s #success=1 #failure=8
Readiness: http-get https://10.154.138.9:6443/readyz delay=0s timeout=15s period=1s #success=1 #failure=3
Startup: http-get https://10.154.138.9:6443/livez delay=10s timeout=15s period=10s #success=1 #failure=24
Environment: <none>
Mounts:
/etc/ca-certificates from etc-ca-certificates (ro)
/etc/kubernetes/pki from k8s-certs (ro)
/etc/ssl/certs from ca-certs (ro)
/usr/local/share/ca-certificates from usr-local-share-ca-certificates (ro)
/usr/share/ca-certificates from usr-share-ca-certificates (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
ca-certs:
Type: HostPath (bare host directory volume)
Path: /etc/ssl/certs
HostPathType: DirectoryOrCreate
etc-ca-certificates:
Type: HostPath (bare host directory volume)
Path: /etc/ca-certificates
HostPathType: DirectoryOrCreate
k8s-certs:
Type: HostPath (bare host directory volume)
Path: /etc/kubernetes/pki
HostPathType: DirectoryOrCreate
usr-local-share-ca-certificates:
Type: HostPath (bare host directory volume)
Path: /usr/local/share/ca-certificates
HostPathType: DirectoryOrCreate
usr-share-ca-certificates:
Type: HostPath (bare host directory volume)
Path: /usr/share/ca-certificates
HostPathType: DirectoryOrCreate
QoS Class: Burstable
Node-Selectors: <none>
Tolerations: :NoExecute op=Exists
Events: <none>
03.How many roles exist in all namespaces together?
ask : 12
wc -l 은 row 를 count 하는 커맨드인데, 첫줄은 Namespace 와 같은 타이틀명이므로 결과값에서 1을 빼준다.
root@controlplane:~# kubectl get roles --all-namespaces | wc -l
13
04. What are the resources the kube-proxy role in the kube-system namespace is given access to?
1) pods
2) deployments
3) configmaps
4) secrets
root@controlplane:~# k describe roles kube-proxy -n kube-system
Name: kube-proxy
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
configmaps [] [kube-proxy] [get]
05. What actions can the kube-proxy role perform on configmaps?
ask : Get
06. Which of the following statements are true?
1) kube-proxy role can get details of configmap object by the name kube-proxy
kube-proxy 역할은 kube-proxy라는 이름으로 configmap 객체의 세부 정보를 얻을 수 있습니다.
2) kube-proxy role can only view and update configmap object by the name kube-proxy
kube-proxy 역할은 kube-proxy라는 이름으로 configmap 개체를 보고 업데이트할 수만 있습니다.
3) kube-proxy role can delete the configmap it created
kube-proxy 역할은 생성한 configmap을 삭제할 수 있습니다.
07. Which account is the kube-proxy role assigned to it?
1) kube-system
2) ServiceAccount: kube-proxy
3) Group: system:bootstrappers:kubeadm:default-node-token
4) User: kube-proxy
5) admin user
root@controlplane:~# k describe configMap -n kube-system
Name: coredns
Namespace: kube-system
Labels: <none>
Annotations: <none>
Data
====
Corefile:
----
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
Events: <none>
Name: extension-apiserver-authentication
Namespace: kube-system
Labels: <none>
Annotations: <none>
Data
====
requestheader-group-headers:
----
["X-Remote-Group"]
requestheader-username-headers:
----
["X-Remote-User"]
client-ca-file:
----
-----BEGIN CERTIFICATE-----
MIIC5zCCAc+gAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl
cm5ldGVzMB4XDTIyMDEyNTA3NTMyOFoXDTMyMDEyMzA3NTMyOFowFTETMBEGA1UE
AxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN0q
uUnfdmK1Tv5wYF0pcqMk2FcglOylkq3tsNQKdwYToP/kDFaeXROv8n+cVK4IziJI
MPOqLsZydy0z/Y3D8KJ3C0hnHJRuqZE0I5f4K91cB2645nxR092Mz+KwpMLoaKU+
pzDmhecJ8Fk81dMEdCLDN7+3kLvk134CpB+2EAGdwgt8yiFiiqo48u70pfqtMAiv
FDMPLGuSDzRjjNZ6HFAqpQTv42Q92r0d4lUV2r//gFU7U7GBseqfhEaQ56ETd91i
k6oLXVy/5D0qzAp7sxy8ZZGpYq1ct/RuPgBg9L7V/xr6rCyRwSV7SDGcFxDIcayM
NDO50rSBClayOrEf5D0CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB
/wQFMAMBAf8wHQYDVR0OBBYEFPo7gyeudrBpqqyQWXYLHn8VS3bNMA0GCSqGSIb3
DQEBCwUAA4IBAQAdJK7OyKq2hJsV7X3k1gtnYUYtN7q4qOrBnkZbFlp7/X53JZh3
9Je1Du2y3OfTJW9pcwFBzbhIBDYoggqfuKEumBuiYkcrW3Yuqk10wRHm9yVRTeGm
KOwpboXhjkMhdBM5b2Lne5uahkyQRxFB2guyj40ozKzKD3zM39a7tAHcQQU5Peu1
n4YlfVAAeugdq8Ov5SCK9TyfAIiwsTvQdYp0uwtwvqHMEEjvoIKPubeUCWdHOsK4
RbL6krIE4mlLiTvd4l6XnIy8RcqBbEO0TBrlm/YEyUBCKq46BIJ8GoirqI7KogDh
Zo1tJSRJ2MUp8cBpLXhbu6wFr3Kswh8yZDn9
-----END CERTIFICATE-----
requestheader-allowed-names:
----
["front-proxy-client"]
requestheader-client-ca-file:
----
-----BEGIN CERTIFICATE-----
MIIC7zCCAdegAwIBAgIBADANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDEw5mcm9u
dC1wcm94eS1jYTAeFw0yMjAxMjUwNzUzMjlaFw0zMjAxMjMwNzUzMjlaMBkxFzAV
BgNVBAMTDmZyb250LXByb3h5LWNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAvhGofyRqcCeirdi+TgDXt/NB8MBGFnDDOFJfcQcN0KHSQlWdtQ2YQmLV
Yl7WleJ8CNCHBvGNoCazSjCKtKrKaaSOs3YJRPQiclx569sJubJSsu18eor/wc5q
5cmukwAusKJm6TTcloz5sas/9rAJVa6M0GaCwPi58R6OpHO2w0qUOQQhVoXiynKX
LnsKLtmSQcAX6y8ILY2vVzJHq536JOsPom1CbAFG5TGqq8ccv1L8yMvV52f1VFuK
9qmaN/oDwWzAswK5m2OQMtA2HhKbUQGkJFtp8tw8IgnsV3M7453hq0KiHQapVBhW
Qwmjkvvv/mZROxLx7hQBlQVsPDX7JQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAqQw
DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUsePwr/yIY+NXiVwjvCgfWp7jm18w
DQYJKoZIhvcNAQELBQADggEBAI2/KHVCnOBqjqP/jKCNBSQl0uZA1eXuaaJVwzeT
ptNISzl8jrpD3sdfPpCQIgY4QCjCyiJBlGuy3BYXNstzm65z7ihS68LDPbl3orHQ
UKa8I4tOE+Z+8CNjYjAj15Oz7IuvtA500QhkC7v5TKEEI5HMuVWRe4ZC90DnUXx2
6QQOlToeo3ZzdiTvtQ6sDTusq+cQT2iFs7iS4TP4npc1zzXdcoA8Q5VJ8fTyc/72
sM5qKUor74qPceYR+ixwheLqPhM7zHaM1/D37YzTeW2pBr5Aq5TfjwkzZvfNiheV
7ghLaEmELb5lDpepk34nrcuReyZ3nI5fWxQn3jwhrVuhRFI=
-----END CERTIFICATE-----
requestheader-extra-headers-prefix:
----
["X-Remote-Extra-"]
Events: <none>
Name: kube-flannel-cfg
Namespace: kube-system
Labels: app=flannel
tier=node
Annotations: <none>
Data
====
cni-conf.json:
----
{
"name": "cbr0",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json:
----
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
Events: <none>
Name: kube-proxy
Namespace: kube-system
Labels: app=kube-proxy
Annotations: kubeadm.kubernetes.io/component-config.hash: sha256:3c1c57a3d54be93d94daaa656d9428e3fbaf8d0cbb4d2221339c2d450391ee35
Data
====
config.conf:
----
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
bindAddressHardFail: false
clientConnection:
acceptContentTypes: ""
burst: 0
contentType: ""
kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
qps: 0
clusterCIDR: 10.244.0.0/16
configSyncPeriod: 0s
conntrack:
maxPerCore: null
min: null
tcpCloseWaitTimeout: null
tcpEstablishedTimeout: null
detectLocalMode: ""
enableProfiling: false
healthzBindAddress: ""
hostnameOverride: ""
iptables:
masqueradeAll: false
masqueradeBit: null
minSyncPeriod: 0s
syncPeriod: 0s
ipvs:
excludeCIDRs: null
minSyncPeriod: 0s
scheduler: ""
strictARP: false
syncPeriod: 0s
tcpFinTimeout: 0s
tcpTimeout: 0s
udpTimeout: 0s
kind: KubeProxyConfiguration
metricsBindAddress: ""
mode: ""
nodePortAddresses: null
oomScoreAdj: null
portRange: ""
showHiddenMetricsForVersion: ""
udpIdleTimeout: 0s
winkernel:
enableDSR: false
networkName: ""
sourceVip: ""
kubeconfig.conf:
----
apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
server: https://controlplane:6443
name: default
contexts:
- context:
cluster: default
namespace: default
user: default
name: default
current-context: default
users:
- name: default
user:
tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
Events: <none>
Name: kube-root-ca.crt
Namespace: kube-system
Labels: <none>
Annotations: <none>
Data
====
ca.crt:
----
-----BEGIN CERTIFICATE-----
MIIC5zCCAc+gAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl
cm5ldGVzMB4XDTIyMDEyNTA3NTMyOFoXDTMyMDEyMzA3NTMyOFowFTETMBEGA1UE
AxMKa3ViZXJuZXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN0q
uUnfdmK1Tv5wYF0pcqMk2FcglOylkq3tsNQKdwYToP/kDFaeXROv8n+cVK4IziJI
MPOqLsZydy0z/Y3D8KJ3C0hnHJRuqZE0I5f4K91cB2645nxR092Mz+KwpMLoaKU+
pzDmhecJ8Fk81dMEdCLDN7+3kLvk134CpB+2EAGdwgt8yiFiiqo48u70pfqtMAiv
FDMPLGuSDzRjjNZ6HFAqpQTv42Q92r0d4lUV2r//gFU7U7GBseqfhEaQ56ETd91i
k6oLXVy/5D0qzAp7sxy8ZZGpYq1ct/RuPgBg9L7V/xr6rCyRwSV7SDGcFxDIcayM
NDO50rSBClayOrEf5D0CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB
/wQFMAMBAf8wHQYDVR0OBBYEFPo7gyeudrBpqqyQWXYLHn8VS3bNMA0GCSqGSIb3
DQEBCwUAA4IBAQAdJK7OyKq2hJsV7X3k1gtnYUYtN7q4qOrBnkZbFlp7/X53JZh3
9Je1Du2y3OfTJW9pcwFBzbhIBDYoggqfuKEumBuiYkcrW3Yuqk10wRHm9yVRTeGm
KOwpboXhjkMhdBM5b2Lne5uahkyQRxFB2guyj40ozKzKD3zM39a7tAHcQQU5Peu1
n4YlfVAAeugdq8Ov5SCK9TyfAIiwsTvQdYp0uwtwvqHMEEjvoIKPubeUCWdHOsK4
RbL6krIE4mlLiTvd4l6XnIy8RcqBbEO0TBrlm/YEyUBCKq46BIJ8GoirqI7KogDh
Zo1tJSRJ2MUp8cBpLXhbu6wFr3Kswh8yZDn9
-----END CERTIFICATE-----
Events: <none>
Name: kubeadm-config
Namespace: kube-system
Labels: <none>
Annotations: <none>
Data
====
ClusterConfiguration:
----
apiServer:
certSANs:
- controlplane
extraArgs:
authorization-mode: Node,RBAC
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: controlplane:6443
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: v1.20.0
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
scheduler: {}
ClusterStatus:
----
apiEndpoints:
controlplane:
advertiseAddress: 10.154.138.9
bindPort: 6443
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterStatus
Events: <none>
Name: kubelet-config-1.20
Namespace: kube-system
Labels: <none>
Annotations: kubeadm.kubernetes.io/component-config.hash: sha256:306a726156f1e2879bedabbdfa452caae8a63929426a55de71c22fe901fde977
Data
====
kubelet:
----
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 0s
cacheUnauthorizedTTL: 0s
cgroupDriver: cgroupfs
clusterDNS:
- 10.96.0.10
clusterDomain: cluster.local
cpuManagerReconcilePeriod: 0s
evictionPressureTransitionPeriod: 0s
fileCheckFrequency: 0s
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 0s
imageMinimumGCAge: 0s
kind: KubeletConfiguration
logging: {}
nodeStatusReportFrequency: 0s
nodeStatusUpdateFrequency: 0s
resolvConf: /run/systemd/resolve/resolv.conf
rotateCertificates: true
runtimeRequestTimeout: 0s
shutdownGracePeriod: 0s
shutdownGracePeriodCriticalPods: 0s
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 0s
syncFrequency: 0s
volumeStatsAggPeriod: 0s
Events: <none>
08. A user dev-user is created. User's details have been added to the kubeconfig file.
Inspect the permissions granted to the user.
Check if the user can list pods in the default namespace.
Use the --as dev-user option with kubectl to run commands as the dev-user.
1) dev-user does not have permissions to list pods
2) dev-user has permissions to list pods
root@controlplane:~# kubectl get pods --as dev-user
Error from server (Forbidden): pods is forbidden: User "dev-user" cannot list resource "pods" in API group "" in the namespace "default"
09. Create the necessary roles and role bindings required for the dev-user
to create, list and delete pods in the default namespace.
dev-user가 기본 네임스페이스에서 포드를 생성, 나열 및 삭제하는 데 필요한 역할 및 역할 바인딩을 생성합니다.
Use the given spec:
- Role: developer
- Role Resources: pods
- Role Actions: list
- Role Actions: create
- Role Actions: delete
- RoleBinding: dev-user-binding
- RoleBinding: Bound to dev-user
Use the command kubectl create to create a role developer and rolebinding dev-user-binding in the default namespace.
pod 같은 resource 를 생성할때는 namespace 를 지정해주지않으면 자동으로 default 로 들어가지만
role 생성같은 경우에는 namespace 를 default 로 지정해줘야한다.
To create a Role:-
kubectl create role developer --namespace=default --verb=list,create,delete --resource=pods
To create a RoleBinding:-
kubectl create rolebinding dev-user-binding --namespace=default --role=developer --user=dev-user
OR
Solution manifest file to create a role and rolebinding in the default namespace:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: developer
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list", "create","delete"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dev-user-binding
subjects:
- kind: User
name: dev-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io
10. The dev-user is trying to get details about the dark-blue-app pod in the blue namespace.
Investigate and fix the issue.
We have created the required roles and rolebindings, but something seems to be wrong.
- Issue Fixed
root@controlplane:~# k get pod -n blue dark-blue-app --as dev-user
Error from server (Forbidden): pods "dark-blue-app" is forbidden: User "dev-user" cannot get resource "pods" in API group "" in the namespace "blue"
New roles and role bindings are created in the blue namespace.
Check it out the resourceNames configured on the role.
Run the command: kubectl edit role developer -n blue and correct the resourceNames field. You don't have to delete the role.
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: "2022-01-25T07:59:36Z"
name: developer
namespace: blue
resourceVersion: "4935"
uid: fa0770dc-7443-4876-b214-60b98781a5fa
rules:
- apiGroups:
- ""
resources:
- pods
resourceName: # resourceName 을 지워주면 됨
- blue-app
verbs:
- get
- watch
- create
- delete
11. Grant the dev-user permissions to create deployments in the blue namespace.
Remember to add both groups "apps" and "extensions".
- Create Deployments
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: "2022-01-25T07:59:36Z"
name: developer
namespace: blue
resourceVersion: "5277"
uid: fa0770dc-7443-4876-b214-60b98781a5fa
rules:
- apiGroups:
- ""
resources:
- pods
- deployments # 추가
verbs:
- get
- watch
- create
- delete
bookmark
https://kubernetes.io/docs/reference/access-authn-authz/rbac/
'CKA (Certified Kubernetes Administrator) > Kode Kloud' 카테고리의 다른 글
06. Security - ClusterRoles (0) | 2022.01.26 |
---|---|
10.Troubleshooting - Application Failure (0) | 2022.01.26 |
06.Security - KubeConfig (0) | 2022.01.25 |
07.Storage - Storage Class (0) | 2022.01.25 |
07.Storage - Persistent Volume Claims (0) | 2022.01.25 |