/ [pdf]



1. EmptyDir

- Docker ์ด๋ฏธ์ง€ ๋งŒ๋“ค๊ธฐ

  • ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ
  $ mkdir -p ./fortune/docimg
$ mkdir -p ./fortune/kubetmp
  

์•„๋ž˜์™€ ๊ฐ™์ด docker ์ด๋ฏธ์ง€๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด bash ๋กœ Application์„ ์ž‘์„ฑ ํ•ฉ๋‹ˆ๋‹ค.

  • fortuneloop.sh ๋งŒ๋“ค๊ธฐ
  #!/bin/bash
trap "exit" SIGINT
mkdir /var/htdocs
while :
do
    echo $(date) Writing fortune to /var/htdocs/index.html
    /usr/games/fortune  > /var/htdocs/index.html
    sleep 10
done
  
  • Dockerfile ์ž‘์„ฑ
  # docimg/Dockerfile
FROM ubuntu:latest
RUN apt-get update; apt-get -y install fortune
ADD fortuneloop.sh /bin/fortuneloop.sh
RUN chmod 755 /bin/fortuneloop.sh
ENTRYPOINT /bin/fortuneloop.sh
  
  • Docker ์ด๋ฏธ์ง€ ์ƒ์„ฑ
  docker build -t <DOCKER-ID>/fortune .
docker login -u <DOCKER-ID>
docker push <DOCKER-ID>/fortune
  
  • Deployment ์ž‘์„ฑ
    html ๋ณผ๋ฅจ์„ html-generator ๋ฐ web-seerver ์ปจํ…Œ์ด๋„ˆ์— ๋ชจ๋‘ ๋งˆ์šดํŠธ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
    html ๋ณผ๋ฅจ์—๋Š” /var/htdocs ๋ฐ /usr/share/nginx/html ์ด๋ฆ„ ์œผ๋กœ ์„œ๋กœ ๋”ฐ๋ฅธ ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋ฐ”๋ผ ๋ณด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
    ๋‹ค๋งŒ, web-server ์ปจํ…Œ์ด๋„ˆ๋Š” ์ฝ๊ธฐ ์ „์šฉ(reeadOnly) ์œผ๋กœ๋งŒ ์ ‘๊ทผ ํ•˜๋„๋ก ์„ค์ • ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  # kubetmp/fortune-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: fortune-deployment
  labels:
    app: fortune
spec:
  replicas: 3
  selector:
    matchLabels:
      app: fortune
  template:
    metadata:
      labels:
        app: fortune
    spec:
      containers:
      - image: dangtong/fortune
        name: html-generator
        volumeMounts:
        - name: html
          mountPath: /var/htdocs
      - image: nginx:alpine
        name: web-server
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
          readOnly: true
        ports:
          - containerPort: 80
            protocol: TCP
      volumes:
      - name: html
        emptyDir: {}
  
  kubectl apply -f ./fortune-deploy.yml
  

EmptyDir ์„ ์„ฑ๋Šฅ์„ ์œ„ํ•ด ๋ฉ”๋ชจ๋ฆฌ์— ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๋ฐ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

    volumes:
    - name: cache-volume
      emptyDir:
        medium: Memory
        sizeLimit: 64Mi
  
  • LoadBalancer ์ƒ์„ฑ
  # fortune-lb.yml
apiVersion: v1
kind: Service
metadata:
  name: fortune-lb
spec:
  selector:
    app: fortune
  ports:
    - port: 80
      targetPort: 80
  type: LoadBalancer
  externalIPs:
  - 192.168.0.2
  
  kubectl apply -f ./fortune-lb.yaml
  
  • ์„œ๋น„์Šค ํ™•์ธ
  kubectl get svc 
  

์„œ๋น„์Šค ๋„๋ฉ”์ธ์„ ํ™•์ธํ•ด์„œ ๋ธŒ๋ผ์šฐ์ €๋กœ ์ ‘์† ํ•ด๋ด…๋‹ˆ๋‹ค.

2. Init Container์— ์˜ํ•œ Git ๋ณผ๋ฃธ๊ตฌ์„ฑ

  • Git ๊ณ„์ • ์ƒ์„ฑ
    GitHub.com ์— ์ž์‹ ์˜ ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธํ•˜์—ฌ ‘k8s-web’ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

  • ์†Œ์Šค ํŒŒ์ผ ์ž‘์„ฑ

  mkdir -p ./gitvolume/html
mkdir -p ./gitvolume/kubetmp
  
  <!-- gitvolume/html/index.html -->
<!DOCTYPE html>
<html>
<body>

<h1>K8s Landing Page</h1>

<p>Hello Kubernetes !!!</p>

</body>
</html>
  
  • ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ƒ์„ฑ ๋ฐ ์ดˆ๊ธฐํ™”
  # gitvolume/html ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ์ˆ˜ํ–‰
git init
git add .
git commit -a -m "first commit"
git remote add origin https://github.com/<๊ณ„์ •๋ช…>/k8s-web.git
git remote -v
git branch -M main
git push origin main
git status
  
  • ์›น์„œ๋ฒ„ Deployment ์ž‘์„ฑ
  # givolume/kubetmp/gitvolume-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitvolume-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:alpine
        name: web-server
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
          readOnly: true
        ports:
          - containerPort: 80
            protocol: TCP
      volumes:
      - name: html
        gitRepo:
          repository: https://github.com/<Your-Repository-ID>/k8s-web.git
          revision: master
          directory: .
  
  kubectl apply -f ./gitvolume-deploy.yaml
  
  • LoadBalancer ์ƒ์„ฑ
  # givolume/kubetmp/gitvolume-lb.yml
apiVersion: v1
kind: Service
metadata:
  name: gitvolume-lb
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: external
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
  type: LoadBalancer
  
  kubectl apply -f ./gitvolume-lb.yaml
  

3. Persistent DISK ์ƒ์„ฑ

  • AWS EBS ์ƒ์„ฑ
  # AWS
$ aws ec2 create-volume --volume-type gp2 --size 80 --availability-zone ap-northeast-2a

## ์‚ญ์ œ
## aws ec2 delete-volume --volume-id vol-038a54dff454064f6

## ์กฐํšŒ
## aws ec2 describe-volumes --filters Name=status,Values=available Name=availability-zone,Values=ap-northeast-2a
  
  • GCP ํด๋Ÿฌ์Šคํ„ฐ ์กฐํšŒ
  gcloud container clusters list
  
  • ๋””์Šคํฌ ์ƒ์„ฑ
  gcloud compute disks create --size=16GiB --zone asia-northeast1-b  mongodb
  
  • ๋””์Šคํฌ ์‚ญ์ œ
  ## ์‚ญ์ œ
## gcloud compute disks delete mongodb --zone asia-northeast1-b
  

4. PV with PVC

- PV ์ƒ์„ฑํ•˜๊ธฐ

  • AWS ์ƒ์„ฑํ•˜๊ธฐ
  # pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
   name: mongodb-pv
spec:
  capacity:
    storage: 1Gi
  csi:
    driver: ebs.csi.aws.com
    fsType: ext4
    volumeHandle: vol-xxxxxxxxxxxxx
  accessModes:
  - ReadWriteOnce
  - ReadOnlyMany
  persistentVolumeReclaimPolicy: Retain
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: topology.ebs.csi.aws.com/zone
              operator: In
              values:
                - ap-northeast-2a
  

AWS์˜ ๊ฒฝ์šฐ ebs csi ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์„ค์น˜ ํ–ˆ๋‹ค๋ฉด ๋…ธ๋“œ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ผ๋ฒจ์ด ์ž๋™์œผ๋กœ ์ถ”๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
topology.ebs.csi.aws.com/zone=ap-northeast-2b
์•„๋ž˜ ๋ช…๋ น์–ด๋กœ ํ™•์ธํ•ด์„œ ebs csi ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ์„ค์น˜ ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ ํ•ฉ๋‹ˆ๋‹ค.

  kubectl get no
  
  kubectl describe no <node-name>
  
  • GCP ์ƒ์„ฑํ•˜๊ธฐ
  # pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
   name: mongodb-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteOnce
  - ReadOnlyMany
  persistentVolumeReclaimPolicy: Retain
  gcePersistentDisk:
   pdName: mongodb
   fsType: ext4
  

- PVC ์ƒ์„ฑํ•˜๊ธฐ

  # pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongodb-pvc
spec:
  resources:
    requests:
      storage: 1Gi
  accessModes:
  - ReadWriteOnce
  storageClassName: ""
  

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๊ฒƒ์€ storageClassName: “” ์„ ๋ฐ˜๋“œ์‹œ ๋ช…๊ธฐ ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ช…๊ธฐ ํ•˜์ง€ ์•Š์œผ๋ฉด Default StorageClass ์ธ gp2 ๊ฐ€ ์ž๋™ ํ• ๋‹น ๋ฉ๋‹ˆ๋‹ค.

  kubectl apply -f ./pvc.yml
  
  kubectl get pvc
  

- PV,PVC๋ฅผ ์ด์šฉํ•œ Pod ์ƒ์„ฑ

  # pv-pvc-mongo.yml
apiVersion: v1
kind: Pod
metadata:
  name: mongodb
spec:
  containers:
  - image: mongo
    name: mongodb
    volumeMounts:
    - name: mongodb-data
      mountPath: /data/db
    ports:
    - containerPort: 27017
      protocol: TCP
  volumes:
  - name: mongodb-data
    persistentVolumeClaim:
      claimName: mongodb-pvc
  
  kubectl apply -f ./pv-pvc-mongo.yml
  
  kubectl get po,pv,pvc
  

- MongoDB ์ ‘์† ๋ฐ ๋ฐ์ดํ„ฐ ์ธ์„œํŠธ

  kubectl exec -it mongodb -- mongo
  
  use mystore
  
  db.foo.insert({"first-name" : "dangtong"})
  
  db.foo.find()
  

- MongoDB ์žฌ๊ฐ€๋™ ๋ฐ ๋ฐ์ดํ„ฐ ํ™•์ธ

  • MongdoDB ์ค‘๋‹จ
  kubectl delete pod mongodb
  
  • MongoDB Pod ์žฌ์ƒ์„ฑ
  kubectl apply -f ./pv-pvc-mongo.yml
  
  • MongoDB ์ ‘์† ๋ฐ ํ™•์ธ
  kubectl exec -it mongodb -- mongo
  
  use mystore
  
  db.foo.find()
  
  • MongoDB ์‚ญ์ œ
  kubectl delete po mongodb
  

5. SC with PVC

- SC ํ™•์ธ

ํด๋ผ์šฐ๋“œ์—์„œ ์ œ๊ณตํ•˜๋Š” Default Storage Class ํ™•์ธ ํ•ด๋ณด๊ธฐ

  kubectl get sc
  

์ƒ์„ธ๋‚ด์—ญ ํ™•์ธ

  kubectl describe sc gp2
  

- SC ์ƒ์„ฑ

  • AWS ์ƒ์„ฑ
  # sc.yml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
# volumeBindingMode: Immediate
reclaimPolicy: Delete
parameters:
  csi.storage.k8s.io/fstype: ext4
  type: gp2
allowedTopologies:
  - matchLabelExpressions:
    - key: topology.ebs.csi.aws.com/zone
      values:
      - ap-northeast-2a
      - ap-northeast-2b
      - ap-northeast-2c
  

volumeBindingMode: Immediate ๋Š” PVC๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ฆ‰์‹œ EBS๊ฐ€ ์•„๋ฌด AZ๋‚˜ ๋žœ๋ค์œผ๋กœ ์ƒ์„ฑ๋˜๋ฉฐ, ์ดํ›„ Pod์ด ํ•ด๋‹น AZ์— ์—†๋Š” ๋…ธ๋“œ์— ์Šค์ผ€์ค„๋˜๋ฉด AZ mismatch ์—๋Ÿฌ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
WaitForFirstConsumer ๋กœ ์„ค์ •ํ•˜๋ฉด Pod์ด ๋จผ์ € ์Šค์ผ€์ค„๋œ ํ›„, ํ•ด๋‹น ๋…ธ๋“œ์˜ AZ๋ฅผ ๊ธฐ์ค€์œผ๋กœ EBS ์ƒ์„ฑ ๋ฉ๋‹ˆ๋‹ค.

  • GCP ์ƒ์„ฑ
  # sc.yml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: pd.csi.storage.gke.io
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
parameters:
  type: pd-ssd
  replication-type: none
allowedTopologies:
  - matchLabelExpressions:
      - key: topology.gke.io/zone
        values:
          - asia-northeast3-a
          - asia-northeast3-b
  

- PVC ์ƒ์„ฑํ•˜๊ธฐ

  # pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
   name: mongodb-pvc
spec:
  storageClassName: fast
  resources:
    requests:
      storage: 2Gi
  accessModes:
    - ReadWriteOnce
  
  kubectl apply -f ./pvc.yaml
  
  kubectl get pv,pvc
  

- PVC,SC ์ด์šฉํ•œ Pod ์ƒ์„ฑ

  # pvc-sc-mongodb-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: mongodb
spec:
  containers:
  - image: mongo
    name: mongodb
    volumeMounts:
    - name: mongodb-data
      mountPath: /data/db
    ports:
    - containerPort: 27017
      protocol: TCP
  volumes:
  - name: mongodb-data
    persistentVolumeClaim:
      claimName: mongodb-pvc