p. 198
- 이를 통해 StatefulSet 과 같은 상태를 가지는 오브젝트를 선택적으로 외부에 노출할 수 있다. 만약, 전부 외부에 노출하고 싶다면, NodePort 나 LB 서비스를 사용해야 한다
- 일반적으로 Pod 는 Cluster 내의 Pod 간 통신만을 위한 Cluster Ip 를 가지며, 외부와의 통신은 불가능하다
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
replicas: 3
serviceName: nginx # cluster-ip: none
selector:
matchLabels:
app: nginx
template: # Pod
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: nfs-vol
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-vol
persistentVolumeClaim:
claimName: nfs-pvc
이때, Cluster Ip 가 없으므로 CoreDNS 를 통해 도메인 이름을 통해 Cluster 내에서 통신이 가능하게 한다
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Mi
root@manager:~/k8slab/etc# showmount -e localhost
Export list for localhost:
/shared 211.183.3.0/24
/root/k8slab/rapalab/news 211.183.3.0/24
/root/k8slab/rapalab/shop 211.183.3.0/24
/root/k8slab/rapalab/default 211.183.3.0/24
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 100Mi
accessModes:
- ReadWriteMany
nfs:
server: 211.183.3.100
path: /shared
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
ports:
- port: 80
clusterIP: None
root@manager:~/k8slab/etc# k apply -f pv.yaml
persistentvolume/nfs-pv created
root@manager:~/k8slab/etc# k apply -f nfs-pvc.yaml
persistentvolumeclaim/nfs-pvc created
root@manager:~/k8slab/etc# k get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/nfs-pv 100Mi RWX Retain Bound default/nfs-pvc 4m16s
persistentvolume/pvc-0823d965-9a82-44aa-bc31-8023e3e4548d 50Mi RWX Delete Released default/nfs-pvc-test nfs-storageclass 5d22h
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/nfs-pvc Bound nfs-pv 100Mi RWX 4m10s
root@manager:~/k8slab/etc# k apply -f sfs.yaml
statefulset.apps/web created
root@manager:~/k8slab/etc# k apply -f svc.yaml
root@manager:~/k8slab/etc# k get pod,svc
NAME READY STATUS RESTARTS AGE
pod/web-0 1/1 Running 0 40s
pod/web-1 1/1 Running 0 27s
pod/web-2 0/1 ContainerCreating 0 1s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d23h
service/nginx ClusterIP None <none> 80/TCP 4m4s
root@manager:~/k8slab/etc# k describe svc nginx
Name: nginx
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: None
IPs: None
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 192.168.182.52:80,192.168.189.67:80,192.168.235.132:80
Session Affinity: None
Events: <none>
root@manager:~/k8slab/etc# k run -it --image busybox testdns --restart Never --rm /bin/sh
- it : 대화 창구를 열고 인터렉티브하게 통신하겠다
- name 은 testdns 이다
- restart Never 은 배포 실패시 더 이상 시도하지 말라는 옵션이다
- rm 은 사용을 다 하고 나오면 삭제하라는 옵션
- /bin/sh 는 it 를 통해 상호 통신을 하기 위하여 shell 을 실행하라는 명령어이다
/ # exit
pod "testdns" deleted
pod default/testdns terminated (Error)
root@manager:~/k8slab/etc# k run net --image=sysnet4admin/net-tools --restart Never --rm -it -- nslookup web-1.nginx
Server: 10.96.0.10 # CoreDNS 주소
Address: 10.96.0.10#53
Name: web-1.nginx.default.svc.cluster.local
Address: 192.168.235.132
pod "net" deleted
- Server 주소는 CoreDNS 주소이다
- Domain 이름을 통해 web-1 Pod 의 Ip 를 확인할 수 있다
- nslookup 할 때, 앞에는 Pod 이름, 뒤에는 연결된 Service 이름이다
root@manager:~/k8slab/etc# k run net --image=sysnet4admin/net-tools --restart Never --rm -it -- nslookup nginx
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: nginx.default.svc.cluster.local
Address: 192.168.235.132
Name: nginx.default.svc.cluster.local
Address: 192.168.182.52
Name: nginx.default.svc.cluster.local
Address: 192.168.189.67
주기적으로 실행하는 K8S 오브젝트이고, 특정 시간 간격으로 지정된 업무를 반복적으로 실행하게 해준다
apiVersion: batch/v1
kind: CronJob
metadata:
name: testcron
spec:
schedule: "*/1 * * * * " # by 1min
jobTemplate: #work
spec:
template:
spec:
restartPolicy: Never
containers:
- name: tesstcronctn
image: busybox
args: ["sh","-c","date"]
- 우리는 1 분마다 busybox 를 배포하여 시간을 출력하게 설정했다. -c 는 실행하라는 옵션이다
root@manager:~/k8slab/etc# k get pod,jobs
NAME READY STATUS RESTARTS AGE
pod/testcron-27718752-qkwzz 0/1 Completed 0 21s
NAME COMPLETIONS DURATION AGE
job.batch/testcron-27718752 1/1 6s 21s
root@manager:~/k8slab/etc# k get jobs
NAME COMPLETIONS DURATION AGE
testcron-27718752 1/1 6s 90s
testcron-27718753 1/1 4s 30s
root@manager:~/k8slab/etc# k get pod
NAME READY STATUS RESTARTS AGE
testcron-27718752-qkwzz 0/1 Completed 0 100s
testcron-27718753-5sbvg 0/1 Completed 0 40s
root@manager:~/k8slab/etc# k get jobs
NAME COMPLETIONS DURATION AGE
testcron-27718753 1/1 4s 2m12s
testcron-27718754 1/1 5s 72s
testcron-27718755 1/1 4s 12s
root@manager:~/k8slab/etc# k get daemonset
No resources found in default namespace.
root@manager:~/k8slab/etc# k get daemonset -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
calico-node 4 4 4 4 4 kubernetes.io/os=linux 7d
kube-proxy 4 4 4 4 4 kubernetes.io/os=linux 7d
default Namespace 에는 없다. kube-system Namespace 에는 calico 와 kube-proxy 가 있는 것을 확인할 수 있다
- 우리는 이런 DaemonSet 을 만든 적이 없다. 이 DaemonSet 의 실체는 Pod 이다. 단, DaemonSet 으로 생성된 Pod 는 모든 Node 에 일괄적으로 하나씩 자동 배포가 된다. 주로, log 확인, 모니터링, 노드간 Network ( Overlay ) 등을 위한 Agent 로 활용된다
대표적으로 kube-proxy, calico 등의 네트워크 플러그인을 들 수 있다
- 각 Node 에 백업을 위한 볼륨 포드를 하나씩 배포하고 싶은 경우에도 사용할 수 있다
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: test
spec:
selector:
matchLabels:
name: test
template:
metadata:
labels:
name: test
spec:
tolerations:
- key: node-role.kubernetes.io/master # 마스터도 배포
effect: NoSchedule
containers:
- name: test
image: busybox
args: ["tail", "-f", "/dev/null"] # 포드가 중지되지 않게 설정
resources:
limits:
cpu: 100m # cpu 0.1 개
memory: 200Mi
DaemonSet 에서 matchLabels 를 통해 해당 label 의 Pod 들을 DaemonSet 으로 동작하게 해준다
tolerations 는 Node 에 지정된 Taints 를 무시하고, 아래에 적용한 부분에 따라 Pod 가 배포된다. 즉, Master 에도 배포할 수 있는 것이다. 즉, tolerations 에 작성된 taints 를 무시해주는 것이다
key 가 node-role.kubernetes.io/master 이고, effect 가 NoSchedule 인 Node 에 대해 Pod 배치를 용인해주는 것이다. 따라서 master Node 에도 Pod 가 배치된다
root@manager:~/k8slab/etc# k get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-7tl8p 1/1 Running 0 16s 192.168.235.133 worker1 <none> <none>
test-jw86q 1/1 Running 0 16s 192.168.189.78 worker2 <none> <none>
test-k69sv 1/1 Running 0 16s 192.168.102.67 manager <none> <none>
test-n9qp2 1/1 Running 0 16s 192.168.182.53 worker3 <none> <none>
root@manager:~/k8slab/etc# k delete pod test-k69sv
pod "test-k69sv" deleted
root@manager:~/k8slab/etc# k get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-7tl8p 1/1 Running 0 7m25s 192.168.235.133 worker1 <none> <none>
test-jkm9s 0/1 ContainerCreating 0 2s <none> manager <none> <none>
test-jw86q 1/1 Running 0 7m25s 192.168.189.78 worker2 <none> <none>
test-n9qp2 1/1 Running 0 7m25s 192.168.182.53 worker3 <none> <none>
root@manager:~/k8slab/rapalab# k get node
NAME STATUS ROLES AGE VERSION
manager Ready control-plane,master 7d1h v1.21.0
worker1 Ready <none> 7d1h v1.21.0
worker2 Ready <none> 7d1h v1.21.0
worker3 Ready <none> 6d23h v1.21.0
root@manager:~/k8slab/rapalab# k describe node manager
Name: manager
Roles: control-plane,master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=manager
kubernetes.io/os=linux
node-role.kubernetes.io/control-plane=
node-role.kubernetes.io/master=
node.kubernetes.io/exclude-from-external-load-balancers=
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
node.alpha.kubernetes.io/ttl: 0
projectcalico.org/IPv4Address: 211.183.3.100/24
projectcalico.org/IPv4IPIPTunnelAddr: 192.168.102.64
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Wed, 07 Sep 2022 11:43:53 +0900
Taints: node-role.kubernetes.io/master:NoSchedule
- master node 에는 master 와 control-plane 이라는 role 과 label 이 지정되어 있다
- Taints 는 Pod 배포에 대한 스케쥴을 관리한다. 해당 Node 는 NoSchedule 이므로 Pod 가 배포되지 않는다
- Taints 가 None 인 Node 는 Pod 가 무조건 배포된다