본문으로 건너뛰기

Kubernetes Foundation #1

nginx-deployment.yaml
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.27-alpine
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "100m"
            memory: "64Mi"
          limits:
            cpu: "500m"
            memory: "64Mi"
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 3
          periodSeconds: 5
bash
kubectl apply -f nginx-deployment.yaml
kubectl expose deployment nginx --port=80 --type=NodePort

kubectl get all

kubectl get deployments
kubectl get pods
kubectl get svc

kubectl get nodes
kubectl get nodes -o wide
kubectl get pods -n kube-system

kubectl describe deployment nginx

kubectl replace --force -f nginx-deployment.yaml

run (deployment)

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      run: nginx
  template:
    metadata:
      labels:
        run: nginx
    spec:
      containers:
      - image: nginx
        name: nginx

expose (service)

yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: NodePort
  selector:
    run: nginx
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    nodePort: 3xxxx  # 실제 생성되면 랜덤 포트로 부여됨

create deployment

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx

create service

yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 3xxxx  # 자동으로 할당됨

pod edit

bash
kubectl edit pod NAME

즉시 수정됨.

sleep

bash
kubectl run web-pod --image=busybox --command sleep 3200 --dry-run=client -o yaml > busybox.yml
bash
kubectl get pods
kubectl describe pods  web-pod

rolling update

bash
kubectl create deployment myproject \
--image=nginx:1.16 --dry-run=client -o yaml > nginx116.yml
bash
kubectl get deployment
kubectl describe deployments myproject
bash
kubectl set image deployment/myproject nginx=nginx:1.17 --record
bash
kubectl rollout history deployment

replication

bash
kubectl create deployment my-deployment \
 --image=nginx --replicas=3 --dry-run=client \
 -o yaml > replication
bash
kubectl run web-nginx --image=image:1.17 --labels tier=web-app

static pod

bash
kubectl get nodes

ssh ...
bash
ps aux | grep kubelet
cat /etc/kubernetes/kubelet-config.yaml | grep static
~~~
cd /etc/kubernetes/manifests
vi static-pod.yml
yaml
apiVersion: v1
kind: Pod
metadata:
  name: static-pod
spec:
  containers:
  - name: nginx-container
    image: nginx

mutiple pods

bash
kubectl run pod-multi --image=nginx -o yaml \
 --dry-run=client > pod-multi.yaml
yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod-multi
  name: pod-multi
spec:
  containers:
  - image: nginx
    name: container1
  - name: container2
    image: busybox
    command: ['sh', '-c', 'sleep 3600']
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
bash
kubectl get pods

namespace

bash
kubectl create namespace custom
kubectl get namespaces
bash
kubectl run test-pod --image=nginx:1.17 -n custom \
-l env=test --dry-run=client -o yaml > test-pod.yaml
yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    env: test
    tier: backend
  name: test-pod
  namespace: custom
spec:
  containers:
  - image: nginx:1.17
    name: test-pod
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
bash
kubectl apply -f test-pod.yaml
kubectl get pods
kubectl get pods -A

config print

bash
kubectl get nodes
kubectl get node oc-prv-k8s-sprag-1 -o json > node-info.json

scale out

bash
kubectl scale --replicas=5 rs/new-replica-set

deployment

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd-frontend
  labels:
    app: httpd
spec:
  replicas: 3
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd
        image: httpd:2.4-alpine
        ports:
        - containerPort: 80
bash
kubectl apply -f ~~~
bash
kubectl create deployment webapp \
--image=kodekloud/webapp-color --replicas=3

service

bash
kubectl run httpd --image=httpd:alpine --port=80 --expose
  • run : pod 또는 deployment 생성
  • --expose : service까지 생성

cluster upgrade

Control plane upgrade

bash
kubeadm upgrade plan

kubeadm upgrade apply v1.xx.x

kubelet / kubectl upgrade

bash
apt-mark unhold kubelet kubectl
apt-get install -y kubelet=1.xx.x-00 kubectl=1.xx.x-00

apt-mark hold kubelet kubectl
systemctl restart kubelet

Woker node upgrade

bash
kubectl drain worker1 --ignore-daemonsets
apt-mark unhold kubeadm kubelet kubectl
apt-get install -y kubelet=1.28.3-00 kubeadm=1.28.3-00 kubectl=1.28.3-00

apt-mark hold kubeadm kubelet kubectl

systemctl restart kubelet
kubectl uncordon worker1

ETCD Backup/Restore

backup

bash
ETCDCTL_API=3 etcdctl \
  --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 \
  snapshot save /tmp/etcd-backup.db

restore

bash
ETCDCTL_API=3 etcdctl \
  snapshot restore /tmp/etcd-backup.db \
  --data-dir=/var/lib/etcd-restore

/etc/kubernetes/manifests/etcd.yaml

yaml
command:
  - etcd
  - --data-dir=/var/lib/etcd-restore

User Authenticate / Authorize

bash
# 개인 키 생성
openssl genrsa -out user.key 2048

# 인증서 요청서 (CSR) 생성
openssl req -new -key user.key -out user.csr -subj "/CN=dev-user/O=dev-group"

# 인증서 서명 (cluster CA로)
openssl x509 -req -in user.csr \
 -CA /etc/kubernetes/pki/ca.crt \
  -CAkey /etc/kubernetes/pki/ca.key \
  -CAcreateserial \
  -out user.crt \
  -days 365

# kubeconfig에 사용자 추가
kubectl config set-credentials dev-user --client-certificate=user.crt --client-key=user.key

# context에 사용자 적용
kubectl config set-context dev-context --cluster=kubernetes --user=dev-user

# context 전환
kubectl config use-context dev-context

예제: dev-user에게 default 네임스페이스에서 pod 읽기 권한 부여

yaml
# role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: default
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]
yaml
# binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-binding
  namespace: default
subjects:
- kind: User
  name: dev-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
bash
kubectl apply -f role.yaml
kubectl apply -f binding.yaml

Context

bash
# 컨텍스트 확인
kubectl config get-contexts

# 현재 컨텍스트 확인
kubectl config current-context

# 컨텍스트 전환
kubectl config use-context dev-context

# 컨텍스트 추가
kubectl config set-context dev-context --cluster=kubernetes --user=dev-user --namespace=default

instant command

bash
kubectl run ping-job --image=busybox \
  --restart=Never \
  --command -- ping -c 4 google.com && kubectl delete pod ping-job

taint

bash
kubectl taint nodes NODE_NAME KEY=BALUE:EFFECT

EFFECT

  • NoSchedule
  • PreferNoSchedule
  • NoExecute : toleration 없는 pod는 스케줄 못함. 기존 파드도 eviction

예제: taint 추가

bash
kubectl taint nodes node01 dedicated=frontend:NoSchedule

예제: toleration 파드 만들기

yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  tolerations:
  - key: "dedicated"
    operator: "Equal"
    value: "frontend"
    effect: "NoSchedule"
  containers:
  - name: nginx
    image: nginx

예제: taint 제거

bash
kubectl taint nodes node01 dedicated=frontend:NoSchedule-

toleration

taint가 있는 노드에도 pod가 스케줄 될 수 있도록 허용하는 설정

  • 시험에서 노드에 taint가 있는 상태로 주어지고 → 그 노드에 파드를 스케줄하라는 문제 자주 나옴
  • 이럴 땐 tolerations 필드를 정확히 작성해야 함
  • tolerationSeconds를 주고 NoExecute 테스트하는 문제도 출제 가능성 있음

NetworkPolicy

  • NetworkPolicy는 Pod 간의 통신 제어를 담당하는 리소스
  • 기본적으로 쿠버네티스는 모든 Pod 간의 통신을 허용
  • NetworkPolicy를 적용하면, 명시된 트래픽만 허용하고 나머지는 차단

기본 요소

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-nginx
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: nginx
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          access: granted

필수 요소 설명:

  • podSelector: 이 정책의 대상 Pod를 지정
  • policyTypes: Ingress, Egress 또는 둘 다
  • ingress: 들어오는 트래픽 제어
  • egress: 나가는 트래픽 제어
  • from / to: podSelector, namespaceSelector, ipBlock 등으로 정의

예제: 모든 Pod 간 통신을 막고, app=frontend만 app=backend에 접근 가능하게 설정

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend

예제: “모든 통신을 막고 싶다” (Ingress, Egress 모두)

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

DNS

bash
kubectl run dns-resolver --image=nginx
bash
kubectl expose pod dns-resolver \
--name=dns-resolver-service \
--port=80 \
--target-port=80 \
--type=ClusterIP

확인하는 코드 (쉘과 상호작용)

bash
kubectl run test-nslookup \
--image=busybox:1.28 --rm -it --restart=Never \
-- nslookup dns-resolver-service
bash
kubectl run test-nslookup \
--image=busybox:1.28 --rm -it --restart=Never \
-- nslookup dns-resolver-service \
> /root/nginx.svc

확인하는 코드 (단순 실행)

bash
kubectl run ping-job \
--image=busybox:1.28 \
--restart=Never \
--command \
-- nslookup dns-resolver-service \
&& kubectl delete pod ping-job

T/S

bash
kubectl get pods

Pending 또는 그에 준하는 상태일때 이슈를 파악하고 조치하는 방법

bash
kubectl describe pod appychip

Event 항목 참고

taint 관련..

bash
kubectl get nodes
kubectl describe nodes node01 | grep taint
bash
kubectl get pod appychip -o yaml > appychip.yml

pod 설정을 보고 tolerations 밑에 key-operator-value-effect를 지정한다.

bash
kubectl apply -f appychip.yml

replica 관련..

bash
kubectl get pods

복제본의 확인

networking관련

1~2개 사이의 질문. 난이도 있음. 나중에 풀 것

https://kubernetes.io/docs/concepts/services-networking/network-policies

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978
bash
kubectl apply -f network.yml
kubectl get networkpolicy appychip
kubectl describe networkpolicy appychip

context 출력 관련..

bash
kubectl config get-contexts -o name > contexts

kubectl config current-context
bash
cat ~/.kube/config | grep current

pod 출력 관련..

bash
kubectl get pod -A --sort-by=.metadata.creationTimestamp
kubectl get pod -A --sort-by=.metadata.uid

controlplane 관련..

bash
kubectl get nodes
ssh controlplane
bash
find /etc/systemd/system | grep kube
find /etc/kubernetes/manifests/
kibectl -n kube-system get pod -o wide | grep controlplane
kubectl -n kube-system get ds
kubectl -n kube-system get deploy

updated..

deployments

두 배포가 있음. NS는 분리되어있음. NS간 상호작용을 위해 네트워크 정책을 지정해야함.

  • 여러개의 yaml 중에 가장 적합한것은 무엇인가?

ConfigMap

nginx with TLS v1.3

bash
 kubectl get configmap
yaml
## test-configmap.yml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  nginx.conf: |
    events {}
    http {
      server {
        listen 443 ssl;
        server_name example.com;
        ssl_certificate /etc/nginx/certs/tls.crt;
        ssl_certificate_key /etc/nginx/certs/tls.key;
        ssl_protocols TLSv1.2 TLSv1.3;
        location / {
          root /usr/share/nginx/html;
          index index.html;
        }
      }
    }
bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt -subj "/CN=example.com"
bash
kubectl create secret tls nginx-tls --cert=tls.crt --key=tls.key
bash
kubectl apply -f test-configmap.yml 

kubectl create deployment nginx --image=nginx --replicas=1
yaml
## nginx-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
          - containerPort: 443
          volumeMounts:
          - name: config
            mountPath: /etc/nginx/nginx.conf
            subPath: nginx.conf
          - name: certs
            mountPath: /etc/nginx/certs
      volumes:
      - name: config
        configMap:
          name: nginx-config
      - name: certs
        secret:
          secretName: nginx-tls          
bash
kubectl apply -f nginx-deployment.yml
kubectl expose deployment nginx --port=443 --target-port=443 --type=NodePort

문제 풀이

bash
kubectl get cm
kubectl edit cm nginx-config

배포 규모를 0으로 줄이고 다시 늘리기

bash
kubectl scale deployment nginx --replicas=0
kubectl get deployment nginx
kubectl scale deployment nginx --replicas=1
kubectl rollout restart deployment nginx

ingress

bash
kubectl get namespace
kubectl get deployment
bash
kubectl create ns sound-repeater
kubectl create deployment echoserver --image=nginx --replicas=1 -n sound-repeater
bash
kubectl expose deployment echoserver \
--name=echoserver-service --port=80 \
--target-port=8080 --type=NodePort \
--namespace sound-repeater
bash
kubectl get deployment -A
kubectl get svc -A
bash
kubectl get ingressclass
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echoserver-service-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx-example
  rules:
  - host: www.example.org
    http:
      paths:
      - path: /echo
        pathType: Prefix
        backend:
          service:
            name: echoserver-service
            port:
              number: 8080
태그
댓글0