kubectl cheat sheet

링크텍스트

💡 컨테이너로 접속하지 않고 명령주기

kubectl exec <컨테이너 이름> -- sh -c "echo '<h1>WEB01</h1>' > /usr/share/nginx/html/index.html"

💡 k8s RESET

  • NAT네트워크와 호스트 전용 어댑터 2개의 어댑터를 사용하면 IP충돌을 줄이며 어디서든 K8S를 활용할 수 있다.
# kubeadm reset
# kubeadm init --apiserver-advertise-address=master ip --pod-network-cidr=10.244.0.0/16
# mkdir -p $HOME/.kube
# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# chown $(id -u):$(id -g) $HOME/.kube/config
# kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

init 후 나온 토큰을 worker들에게 입력해준다.
# kubeadm join 192.168.56.104:6443 --token 30wnm4.gtujz6nuefecizs9 \
    --discovery-token-ca-cert-hash sha256:dfbeaf6fe8d3da8ce0ae280d814d97b896e0f66eb7bad23b3af234e375c648e3
  • join이나 전에 했던 ks8작업 리셋 후 새로운 토큰 부여

💡 pv/pvc

# pv-pvc-pod.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Mi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle  
  hostPath:
    path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Mi
  selector:
    matchLabels:
      type: local
---
apiVersion: v1
kind: Pod
metadata:
  name: task-pv-pod
  labels:
    app: task-pv-pod
spec:
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: task-pv-claim
  containers:
    - name: task-pv-container
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage

💡 accessModes:

  • ReadWriteOnce = 하나의 노드에서 해당 볼륨이 읽기-쓰기로 마운트 될 수 있다.
    ReadWriteOnce 접근 모드에서도 파드가 동일 노드에서 구동되는 경우에는 복수의 파드에서 볼륨에 접근할 수 있다.
  • ReadOnlyMany = 볼륨이 다수의 노드에서 읽기 전용으로 마운트 될 수 있다.
  • ReadWriteMany = 볼륨이 다수의 노드에서 읽기-쓰기로 마운트 될 수 있다.
  • ReadWriteOncePod = 볼륨이 단일 파드에서 읽기-쓰기로 마운트될 수 있다.
    전체 클러스터에서 단 하나의 파드만 해당 PVC를 읽거나 쓸 수 있어야하는 경우 ReadWriteOncePod 접근 모드를 사용한다. 이 기능은 CSI 볼륨과 쿠버네티스 버전 1.22+ 에서만 지원된다.

💡 persistentVolumeReclaimPolicy:

  • Retain(보존)
    Retain 반환 정책은 리소스를 수동으로 반환할 수 있게 한다.
    퍼시스턴트볼륨클레임이 삭제되면 퍼시스턴트볼륨은 여전히 존재하며 볼륨은 "릴리스 된" 것으로 간주된다.
    그러나 이전 요청자의 데이터가 여전히 볼륨에 남아 있기 때문에 다른 요청에 대해서는 아직 사용할 수 없다.
    관리자는 다음 단계에 따라 볼륨을 수동으로 반환할 수 있다.
  1. 퍼시스턴트볼륨을 삭제한다. PV가 삭제된 후에도 외부 인프라(예: AWS EBS, GCE PD, Azure Disk 또는 Cinder 볼륨)의 관련 스토리지 자산이 존재한다.
  2. 관련 스토리지 자산의 데이터를 수동으로 삭제한다.
  3. 연결된 스토리지 자산을 수동으로 삭제한다.

동일한 스토리지 자산을 재사용하려는 경우, 동일한 스토리지 자산 정의로 새 퍼시스턴트볼륨을 생성한다

  • Delete(삭제)
    Delete 반환 정책을 지원하는 볼륨 플러그인의 경우, 삭제는 쿠버네티스에서 퍼시스턴트볼륨 오브젝트와 외부 인프라(예: AWS EBS, GCE PD, Azure Disk 또는 Cinder 볼륨)의 관련 스토리지 자산을 모두 삭제한다.
    동적으로 프로비저닝된 볼륨은 스토리지클래스의 반환 정책을 상속하며 기본값은 Delete이다. 관리자는 사용자의 기대에 따라 스토리지클래스를 구성해야 한다.
  • Recycle(재활용)
    경고: Recycle 반환 정책은 더 이상 사용하지 않는다.
    대신 권장되는 방식은 동적 프로비저닝을 사용하는 것이다.
    기본 볼륨 플러그인에서 지원하는 경우 Recycle 반환 정책은 볼륨에서 기본 스크럽(rm -rf /thevolume/*)을 수행하고 새 클레임에 다시 사용할 수 있도록 한다.

그러나 관리자는 레퍼런스에 설명된 대로 쿠버네티스 컨트롤러 관리자 커맨드라인 인자(command line arguments)를 사용하여 사용자 정의 재활용 파드 템플릿을 구성할 수 있다.
사용자 정의 재활용 파드 템플릿에는 아래 예와 같이 volumes 명세가 포함되어야 한다.

그러나 volumes 부분의 사용자 정의 재활용 파드 템플릿에 지정된 특정 경로는 재활용되는 볼륨의 특정 경로로 바뀐다.


💡 Volume

# yum install -y nfs-utils.x86_64
# mkdir /nfs_shared
# echo '/nfs_shared 192.168.0.0/21(rw,sync,no_root_squash)' >> /etc/exports
# systemctl enable --now nfs
# vi nfs-pv.yaml
  • NFS를 이용한 PV 설치
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: 100Mi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: 192.168.0.192
    path: /nfs_shared

# kubectl apply -f nfs-pv.yaml
# kubectl get pv
# vi nfs-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Mi

# kubectl apply -f nfs-pvc.yaml
# kubectl get pvc
# kubectl get pv
# vi nfs-pvc-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-pvc-deploy
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nfs-pvc-deploy
  template:
    metadata:
      labels:
        app: nfs-pvc-deploy
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: nfs-vol
          mountPath: /usr/share/nginx/html
      volumes:
      - name: nfs-vol
        persistentVolumeClaim:
          claimName: nfs-pvc

# kubectl apply -f nfs-pvc-deploy.yaml
# kubectl get pod
# kubectl exec -it nfs-pvc-deploy-76bf944dd5-6j9gf -- /bin/bash
# kubectl expose deployment nfs-pvc-deploy --type=LoadBalancer --name=nfs-pvc-deploy-svc1 --port=80

💡 multi-container

1pod 2container

# vi multipod.yaml
apiVersion: v1
kind: Pod
metadata:
 name: multipod
spec:
 containers:
 - name: nginx-container        #1번째 컨테이너
   image: 192.168.56.104:5000/nginx:latest
   ports:
   - containerPort: 80
 - name: centos-container       #2번째 컨테이너
   image: 192.168.56.104:5000/centos:7:latest
   command:
   - sleep
   - "10000"
# kubectl exec -it multipod -c nginx-container -- bash
  • multipod의 nginx-container의 터미널로 간다.

💡 wordpress-pod-svc.yaml

apiVersion: v1
kind: Pod
metadata:
  name: wordpress-pod
  labels:
    app: wordpress-pod
spec:
  containers:
  - name: mysql-container
    image: mysql:5.7
    env:
    - name: MYSQL_ROOT_HOST
      value: '%' # wpuser@%
    - name: MYSQL_ROOT_PASSWORD
      value: kosa0401
    - name: MYSQL_DATABASE
      value: wordpress
    - name: MYSQL_USER
      value: wpuser
    - name: MYSQL_PASSWORD
      value: wppass
    ports:
    - containerPort: 3306
  - name: wordpress-container
    image: wordpress
    env:
    - name: WORDPRESS_DB_HOST
      value: wordpress-pod:3306
    - name: WORDPRESS_DB_USER
      value: wpuser
    - name: WORDPRESS_DB_PASSWORD
      value: wppass 
    - name: WORDPRESS_DB_NAME
      value: wordpress
    ports:
    - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service-deployment-wordpress
spec:
  type: LoadBalancer
  externalIPs:
  - 192.168.56.104
  selector:
    app: wordpress-pod
  ports:
  - protocol: TCP
    port: 80

[Persistent Volume에 Wordpress 배포하기] 괜찮은거 같음


💡 metallb (DHCP)

# kubectl apply -f /root/_Book_k8sInfra/ch3/3.3.4/metallb.yaml
# kubectl get pods -n metallb-system -o wide
# vi metallb-l2config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: nginx-ip-range
      protocol: layer2
      addresses:
      - 192.168.56.200-192.168.56.250

# kubectl apply -f metallb-l2config.yaml
# kubectl describe configmaps -n metallb-system
# kubectl get pod -n metallb-system
  • namespace를 꼭 지정해줘야한다.
# kubectl delete -f metallb-l2config.yaml
  • config도 지워 깨끗하게 지운다.

💡 ConfigMap

  • ConfigMap은 키-값 쌍으로 기밀이 아닌 데이터를 저장하는 데 사용하는 API 오브젝트다.
  • 파드는 볼륨에서 환경 변수, 커맨드-라인 인수 또는 구성 파일로 Configmap을 사용할 수 있다.
  • ConfigMap을 사용하면 컨테이너 이미지에서 환경별 구성을 분리하여, 애플리케이션을 쉽게 이식할 수 있다.

sleep 이렇게 쓰는거 같은딩?

spec:
  containers:
    - name: demo
      image: alpine
      command: ["sleep", "3600"]

😈 k8s images 제한 시 😈

# kubectl create secret generic rldnjsdlsi --from-file=.dockerconfigjson=/root/.docker/config.json --type=kubernetes.io/dockerconfigjson
# kubectl patch -n default serviceaccount/default -p '{"imagePullSecrets":[{"name": "rldnjsdlsi"}]}'
# kubectl describe serviceaccount default -n default
  • namespace를 따라가기 때문에 ns를 바꾸면 제한을 다시 풀어줘야한다..

💡 여러 deploy.yaml 합쳐서 한번에 실행하기

# kustomization.yaml
resources:
  - mysql-deploy.svc.yaml
  - wordpress-deploy-svc.yaml
  • 사용할 deploy.yaml 파일을 kustomization.yaml에 묶어 놓는다.
# kubectl apply -k ./

=> 로 실행 하면 2개의 deploy.yaml이 같이 실행된다.


💡 configmap-wordpress.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: config-wordpress
  namespace: default
data:
  MYSQL_ROOT_HOST: '%'
  MYSQL_ROOT_PASSWORD: mode1752
  MYSQL_DATABASE: wordpress
  MYSQL_USER: wpuser
  MYSQL_PASSWORD: wppass

💡 mysql-deploy-svc.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deploy
  labels:
    app: mysql-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql-deploy
  template:
    metadata:
      labels:
        app: mysql-deploy
    spec:
      containers:
      - name: mysql-container
        image: mysql:5.7
        envFrom:
        - configMapRef:
            name: config-wordpress
        ports:
        - containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-svc
spec:
  type: ClusterIP
  selector:
    app: mysql-deploy
  ports:
  - protocol: TCP
    port: 3306
    targetPort: 3306

💡 wordpress-deploy-svc.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress-deploy
  labels:
    app: wordpress-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress-deploy
  template:
    metadata:
      labels:
        app: wordpress-deploy
    spec:
      containers:
      - name: wordpress-container
        image: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: mysql-svc:3306
        - name: WORDPRESS_DB_USER
          valueFrom:
            configMapKeyRef:
              name: config-wordpress
              key: MYSQL_USER
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            configMapKeyRef:
              name: config-wordpress
              key: MYSQL_PASSWORD
        - name: WORDPRESS_DB_NAME
          valueFrom:
            configMapKeyRef:
              name: config-wordpress
              key: MYSQL_DATABASE
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: wordpress-svc
spec:
  type: LoadBalancer
 # externalIPs:
 # - 192.168.2.0
  selector:
    app: wordpress-deploy
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  • configmap-wordpress에 저장된 DB정보를 불러온다.
  • metallb로 인해 svc externalIPs를 주석처리 해도 받을 수 있다.
  • LoadBalancer type으로 인해 metallb를 불러오는 것과 같다.
    (LB는 뿌려주는 IP를 받아먹고 metallb는 지정된 범위의 IP를 뿌려준다.)

💡 namespace

  • 약간 AZ같은 너낌적인 너낌..
  • 평소에는 default namespace를 뒤져서 정보를 알려준다.
# kubectl get namespaces
# kubectl config get-contexts kubernetes-admin@kubernetes
# kubectl config set-context kubernetes-admin@kubernetes --namespace=kube-system
# kubectl config get-contexts kubernetes-admin@kubernetes
# kubectl config set-context kubernetes-admin@kubernetes --namespace=default
# kubectl create namespace test-namespace
- 내가 만드는 내 namespace

# kubectl get namespace
# kubectl config set-context kubernetes-admin@kubernetes --namespace=test-namespace
- k8s 관리자를 통해 test-namespace를 default namespace로 지정

# kubectl config set-context kubernetes-admin@kubernetes --namespace=default
- 다시 k8s 관리자를 통해 default를 default namespace로 지정

# kubectl delete namespaces test-namespace
- namespaces를 다 쓰고 지우면 해당 ns안에 있는 내용이 싹 다 삭제된다.

그럼 현재 ns를 확인하는 방법은..?


💡 ResourceQuota

sample-resourcequota.yaml

# vi sample-resourcequota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: sample-resourcequota
  namespace: default
spec:
  hard:
    count/pods: 5

# kubectl describe resourcequotas sample-resourcequota
# kubectl run pod new-nginx --image=nginx

💡 sample-resourcequota-usable.yaml

apiVersion: v1
kind: ResourceQuota
metadata:
  name: sample-resourcequota-usable
  namespace: default
spec:
  hard:
    requests.memory: 2Gi
    requests.storage: 5Gi
    sample-storageclass.storageclass.storage.k8s.io/requests.storage: 5Gi
    requests.ephemeral-storage: 5Gi
    requests.nvidia.com/gpu: 2
    limits.cpu: 4
    limits.ephemeral-storage: 10Gi
    limits.nvidia.com/gpu: 4

💡 sample-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
spec:
  containers:
  - name: nginx-container
    image: nginx:1.16
    resources:
      requests:
        memory: "1Gi"
        cpu: "50m"
      limits:
        memory: "6Gi"
        cpu: "100m"
  • 미리 제한을 걸어둔 후 pod 자원을 변경할 수 없다
  • pod를 삭제하고 다시 자원을 설정해줘야한다
# kubectl describe node worker1
  • 노드들의 자원도 확인해야한다

LimitRange

💡 sample-limitrange-container.yaml

apiVersion: v1
kind: LimitRange
metadata:
  name: sample-limitrange-container
  namespace: default
spec:
  limits: # 최대 2개 파드 생성, 1개 더하면 생성 안됨
  - type: Container # 컨테이너에 대한
    default: # 기본 최대 Limits, 정한 리소스가 부족하면 컨테이너가 생성되지 않는다.
      memory: 512Mi
      cpu: 500m
    defaultRequest: # 직접 정하지 않은 경우 최소 용량, 최소 확보 용량
      memory: 256Mi
      cpu: 250m
    max: # 직접 설정할 경우 값
      memory: 1024Mi
      cpu: 1000m
    min:
      memory: 128Mi
      cpu: 125m
    maxLimitRequestRatio: # Requests와 Limit의 차이 허용 비율 2배, 오버 커밋을 피할 수 있다.
      memory: 2
      cpu: 2

💡 sample-pod-overrequest.yaml

apiVersion: v1
kind: Pod
metadata:
  name: sample-pod-overrequest
spec:
  containers:
  - name: nginx-container
    image: nginx:1.16
    resources:
      requests:
        cpu: 100m
      limits:
        cpu: 100m
  • sample-limitrange-container.yaml의 최소 cpu용량이 125를 넘어야 하는데 100으로 설정되어 있어 pod가 생성되지 않는다.

👁‍🗨 Pod Schedule (자동 배치)

# vi pod-schedule.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-schedule-metadata
  labels:
    app: pod-schedule-labels
spec:
  containers:
  - name: pod-schedule-containers
    image: nginx
    ports:
    - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: pod-schedule-service
spec:
  type: NodePort
  selector:
    app: pod-schedule-labels
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

👁‍🗨 Pod NodeName(수동 배치)

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodename-metadata
  labels:
    app: pod-nodename-labels
spec:
  containers:
  - name: pod-nodename-containers
    image: nginx
    ports:
    - containerPort: 80
  nodeName: worker2
---
apiVersion: v1
kind: Service
metadata:
  name: pod-nodename-service
spec:
  type: NodePort
  selector:
    app: pod-nodename-labels
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  • Pod가 만들어지는 node 지정

👁‍🗨 Node Selector(수동 배치)

# kubectl label nodes worker1 tier=dev
- worker1 node에 dev라는 label을 달아준다.

# kubectl get nodes --show-labels
- node들의 label까지 모두 출력한다.

# vi pod-nodeselector.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeselector-metadata
  labels:
    app: pod-nodeselector-labels
spec:
  containers:
  - name: pod-nodeselector-containers
    image: nginx
    ports:
    - containerPort: 80
  nodeSelector:
    tier: dev
---
apiVersion: v1
kind: Service
metadata:
  name: pod-nodeselector-service
spec:
  type: NodePort
  selector:
    app: pod-nodeselector-labels
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    
# kubectl label nodes worker1 tier-
- 지정해줬던 label을 기본값으로 돌려놓는다.

# kubectl get nodes --show-labels
  • node에 label을 tier로 달아준다.

taint와 toleration

  • taint
    자동 스케쥴을 못하게 만들어 (pod가 생성되지 않는다.) 수동으로만 설정하게 만든다.

  • toleration
    taint되어 있는 node에 강제로 pod을 생성한다.

# kubectl taint node worker1 tier=dev:NoSchedule
# kubectl describe nodes worker1
# vi pod-taint.yaml

0개의 댓글