source <(kubectl completion bash) # bash-completion 패키지를 먼저 설치한 후, bash의 자동 완성을 현재 셸에 설정한다
echo "source <(kubectl completion bash)" >> ~/.bashrc # 자동 완성을 bash 셸에 영구적으로 추가한다
source <(kubectl completion bash) echo "source <(kubectl completion bash)" >> ~/.bashrc
alias k=kubectl
complete -o default -F __start_kubectl k
kuberntes doc - etcdctl backup
https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/
- built in stnapshot
#ETCDCTL_API=3 etcdctl etcdctl --endpoints $ENDPOINT snapshot save snapshot.db
controlplane ~ ➜ #ETCDCTL_API=3 etcdctl etcdctl --endpoints $ENDPOINT snapshot save snapshot.db
controlplane ~ ➜ ETCDCTL_API=3 etcdctl snapshot save -h
NAME:
snapshot save - Stores an etcd node backend snapshot to a given file
USAGE:
etcdctl snapshot save <filename>
GLOBAL OPTIONS:
--cacert="" verify certificates of TLS-enabled secure servers using this CA bundle
--cert="" identify secure client using this TLS certificate file
--command-timeout=5s timeout for short running command (excluding dial timeout)
--debug[=false] enable client-side debug logging
--dial-timeout=2s dial timeout for client connections
-d, --discovery-srv="" domain name to query for SRV records describing cluster endpoints
--endpoints=[127.0.0.1:2379] gRPC endpoints
--hex[=false] print byte strings as hex encoded strings
--insecure-discovery[=true] accept insecure SRV records describing cluster endpoints
--insecure-skip-tls-verify[=false] skip server certificate verification
--insecure-transport[=true] disable transport security for client connections
--keepalive-time=2s keepalive time for client connections
--keepalive-timeout=6s keepalive timeout for client connections
--key="" identify secure client using this TLS key file
--user="" username[:password] for authentication (prompt if password is not supplied)
-w, --write-out="simple" set the output format (fields, json, protobuf, simple, table)
매개변수를 파악하기 위해 서버 매니페스트 파일을 살펴본다
controlplane ~ ➜ cat /etc/kubernetes/manifests/etcd.yaml | grep file
- --cert-file=/etc/kubernetes/pki/etcd/server.crt
- --key-file=/etc/kubernetes/pki/etcd/server.key
- --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt
- --peer-key-file=/etc/kubernetes/pki/etcd/peer.key
- --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
- --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
seccompProfile:
✅ 엔드포인트를 확인
controlplane ~ ➜ vi /etc/kubernetes/manifests/etcd.yaml
controlplane ~ ✖ ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 snapshot save snapshot.db --cacert=/etc/kubernetes/pki/etcd/ca.crt \
> --cert=/etc/kubernetes/pki/etcd/server.crt \
> --key=/etc/kubernetes/pki/etcd/server.key
Snapshot saved at snapshot.db
## 정답
export ETCDCTL_API=3
etcdctl snapshot save --endpoints https://[127.0.0.1]:2379 --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key /opt/etcd-backup.db
emptyDir
https://kubernetes.io/docs/concepts/storage/volumes/volumes: - name: cache-volume emptyDir: sizeLimit: 500Mi
emptyDir은 Kubernetes에서 사용하는 Volume 타입으로, Pod이 생성될 때 빈 디렉토리로 시작하고, Pod의 생명 주기 동안만 존재합니다. Pod이 삭제되면 emptyDir Volume에 저장된 데이터도 함께 삭제됩니다. 이 Volume은 컨테이너 간 데이터 공유 및 임시 데이터 저장에 유용합니다. 데이터는 노드의 로컬 디스크에 저장됩니다.
## pod yaml 생성
controlplane ~ ✖ k run redis-storage --image=redis:alpine --dry-run=client -o yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: redis-storage
name: redis-storage
spec:
containers:
- image: redis:alpine
name: redis-storage
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
controlplane ~ ➜ k run redis-storage --image=redis:alpine --dry-run=client -o yaml > redis.yaml
## pv 추가
controlplane ~ ➜ vi redis.yaml
controlplane ~ ➜ cat redis.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: redis-storage
name: redis-storage
spec:
containers:
- image: redis:alpine
name: redis-storage
resources: {}
volumeMounts: ⭐️
- mountPath: /data/redis
name: cache-volume
dnsPolicy: ClusterFirst
restartPolicy: Always
volumes: ⭐️
- name: cache-volume
emptyDir: {}
status: {}
controlplane ~ ➜ k create -f redis.yaml
pod/redis-storage created
controlplane ~ ➜ k get po
NAME READY STATUS RESTARTS AGE
redis-storage 0/1 ContainerCreating 0 3s
controlplane ~ ➜ k describe po redis-storage
Name: redis-storage
Namespace: default
Priority: 0
Service Account: default
Node: node01/192.21.81.12
Start Time: Sat, 10 Aug 2024 14:23:34 +0000
Labels: run=redis-storage
Annotations: <none>
Status: Running
IP: 10.244.192.1
IPs:
IP: 10.244.192.1
Containers:
redis-storage:
Container ID: containerd://4ed7364200a01b46a5464056b5856c3c33deda24c2fb0afd1f368db98031cd34
Image: redis:alpine
Image ID: docker.io/library/redis@sha256:eaea8264f74a95ea9a0767c794da50788cbd9cf5223951674d491fa1b3f4f2d2
Port: <none>
Host Port: <none>
State: Running
Started: Sat, 10 Aug 2024 14:23:37 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/data/redis from cache-volume (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pbplj (ro)
Conditions:
Type Status
PodReadyToStartContainers True
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
cache-volume:
Type: ✅ EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
kube-api-access-pbplj:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 80s default-scheduler Successfully assigned default/redis-storage to node01
Normal Pulling 79s kubelet Pulling image "redis:alpine"
Normal Pulled 77s kubelet Successfully pulled image "redis:alpine" in 1.388s (1.388s including waiting). Image size: 17173585 bytes.
Normal Created 77s kubelet Created container redis-storage
Normal Started 77s kubelet Started container redis-storage
docs: security capability
https://kubernetes.io/docs/tasks/configure-pod-container/security-context/apiVersion: v1 kind: Pod metadata: name: security-context-demo-4 spec: containers: - name: sec-ctx-4 image: gcr.io/google-samples/hello-app:2.0 securityContext: capabilities: add: ["NET_ADMIN", "SYS_TIME"]
controlplane ~ ➜ k run super-user-pod --image=busybox:1.28 --command --dry-run=client -o yaml -- sleep 4800
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: super-user-pod
name: super-user-pod
spec:
containers:
- command:
- sleep
- "4800"
image: busybox:1.28
name: super-user-pod
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
controlplane ~ ➜ k run super-user-pod --image=busybox:1.28 --command --dry-run=client -o yaml -- sleep 4800 > busy.yaml
controlplane ~ ➜ vi busy.yaml
controlplane ~ ➜ cat busy.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: super-user-pod
name: super-user-pod
spec:
containers:
- command:
- sleep
- "4800"
image: busybox:1.28
name: super-user-pod
resources: {}
securityContext: ✅ 추가 Sys_time
capabilities:
add: ["SYS_TIME"]
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
controlplane ~ ➜ k create -f busy.yaml
pod/super-user-pod created
controlplane ~ ➜ k get po
NAME READY STATUS RESTARTS AGE
redis-storage 1/1 Running 0 8m12s
super-user-pod 1/1 Running 0 3s
mountPath: /data
persistentVolumeClaim Name: my-pvc
이 작업은 /root/CKA/use-pv.yaml 파일을 사용하여 파드를 정의하고, pv-1이라는 퍼시스턴트 볼륨을 /data 경로에 마운트하도록 하는 것. 또한, 파드가 정상적으로 실행 중인지, PVC가 퍼시스턴트 볼륨에 바인딩되었는지 확인하는 것이 중요함
PV, PVC
- Persistent Volume (PV): 관리자가 사전에 프로비저닝한 실제 스토리지를 나타냅니다. Kubernetes 클러스터에서 사용할 수 있는 스토리지 리소스.
- Persistent Volume Claim (PVC): 사용자가 필요로 하는 스토리지 요구 사항을 정의한 요청서. PVC가 제출되면, Kubernetes는 요구 사항에 맞는 PV를 할당(바인딩)한다.
- 따라서, PV는 실제 스토리지 리소스이고, PVC는 그 스토리지를 요청하는 선언이다
PVC doc: PersistentBolumeClaims
https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: myclaim spec: accessModes: - ReadWriteOnce volumeMode: Filesystem resources: requests: storage: 8Gi
1. pvc 생성
controlplane ~ ➜ cat /root/CKA/use-pv.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: use-pv
name: use-pv
spec:
containers:
- image: nginx
name: use-pv
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
controlplane ~ ➜ k get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pv-1 10Mi RWO Retain Available <unset> 4m51s
controlplane ~ ➜ k get pvc
No resources found in default namespace.
controlplane ~ ➜ vi pvc.yaml
controlplane ~ ➜ cat pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Mi
controlplane ~ ➜ k create -f pvc.yaml
persistentvolumeclaim/my-pvc created
controlplane ~ ➜ k get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
my-pvc Bound pv-1 10Mi RWO <unset> 3s
PV 사양 추가
volumeMounts: - mountPath: "/var/www/html" name: mypd volumes: - name: mypd persistentVolumeClaim: claimName: myclaim
2. 포드 내의 볼륨 마운트로 설정
controlplane ~ ➜ cat /root/CKA/use-pv.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: use-pv
name: use-pv
spec:
containers:
- image: nginx
name: use-pv
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
controlplane ~ ➜ vi /root/CKA/use-pv.yaml
controlplane ~ ➜ vi /root/CKA/use-pv.yaml
controlplane ~ ➜ cat /root/CKA/use-pv.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: use-pv
name: use-pv
spec:
containers:
- image: nginx
name: use-pv
resources: {}
volumeMounts:
- mountPath: "/data"
name: mypd
dnsPolicy: ClusterFirst
restartPolicy: Always
volumes:
- name: mypd
persistentVolumeClaim:
claimName: my-pvc
status: {}
controlplane ~ ➜ k create -f /root/CKA/use-pv.yaml
pod/use-pv created
controlplane ~ ➜ k get po
NAME READY STATUS RESTARTS AGE
redis-storage 1/1 Running 0 28m
super-user-pod 1/1 Running 0 20m
use-pv 1/1 Running 0 5s
sage:
kubectl create deployment NAME --image=image -- [COMMAND] [args...] [options]
Use "kubectl options" for a list of global command-line options (applies to all
commands).
controlplane ~ ➜ k create deploy nginx-deploy --image=nginx:1.16 --replicas=1
deployment.apps/nginx-deploy created
controlplane ~ ➜ k get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deploy 0/1 1 0 5s
이미지 버전 업데이트
k set image --help
controlplane ~ ➜ k set image --help Update existing container image(s) of resources. Possible resources include (case insensitive): pod (po), replicationcontroller (rc), deployment (deploy), daemonset (ds), statefulset (sts), cronjob (cj), replicaset (rs) Examples: # Set a deployment's nginx container image to 'nginx:1.9.1', and its busybox container image to 'busybox' kubectl set image deployment/nginx busybox=busybox nginx=nginx:1.9.1
도움말중
kubectl set image deployment/nginx busybox=busybox nginx=nginx:1.9.1
명령어를 사용
controlplane ~ ➜ # kubectl set image deployment/nginx-deploy nginx=nginx:1.9.1
controlplane ~ ➜ k describe deploy nginx-deploy
Name: nginx-deploy
Namespace: default
CreationTimestamp: Sun, 11 Aug 2024 08:19:00 +0000
Labels: app=nginx-deploy
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=nginx-deploy
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx-deploy
Containers:
nginx:
Image: nginx:1.16 ✅
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deploy-858fb84d4b (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 3m36s deployment-controller Scaled up replica set nginx-deploy-858fb84d4b to 1
## 🛑 명령어를 맞게 수정
controlplane ~ ➜ kubectl set image deployment/nginx-deploy nginx=nginx:1.17
deployment.apps/nginx-deploy image updated
controlplane ~ ➜ k describe deploy nginx-deploy
Name: nginx-deploy
Namespace: default
CreationTimestamp: Sun, 11 Aug 2024 08:19:00 +0000
Labels: app=nginx-deploy
Annotations: deployment.kubernetes.io/revision: 2
Selector: app=nginx-deploy
Replicas: 1 desired | 1 updated | 2 total | 1 available | 1 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx-deploy
Containers:
nginx:
Image: nginx:1.17 ✅
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True ReplicaSetUpdated
OldReplicaSets: nginx-deploy-858fb84d4b (1/1 replicas created)
NewReplicaSet: nginx-deploy-58f87d49 (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 4m25s deployment-controller Scaled up replica set nginx-deploy-858fb84d4b to 1
Normal ScalingReplicaSet 4s deployment-controller Scaled up replica set nginx-deploy-58f87d49 to 1
Important Note: As of kubernetes 1.19, the CertificateSigningRequest object expects a signerName.
Please refer the documentation to see an example. The documentation tab is available at the top right of terminal.
요약
- CSR 생성 및 승인: signerName을 포함한 CSR을 생성하고 승인하여 john 사용자의 클라이언트 인증서를 발급받습니다.
- 사용자 추가: 발급된 인증서를 사용해 kubectl에 john 사용자 정보를 추가합니다.
- Role 및 RoleBinding 설정: john 사용자가 development 네임스페이스에서 파드를 관리할 수 있도록 Role 및 RoleBinding을 설정합니다.
- 이 작업을 통해 john 사용자는 development 네임스페이스에서 파드를 생성, 조회, 가져오기, 업데이트, 삭제할 수 있는 권한을 가지게 됩니다.