복습
image pull limit Error
- docker login
- kubectl patch -n default serviceaccount/default -p '{"imagePullSecrets":[{"name": "jo1132"}]}'
- 도커 로그인처럼 쿠버네티스도 도커 계정으로 로그인하는 것이다.
- kubectl describe serviceaccount default -n default
- 쿠버네티스에 내 계정이 잘 들어갔는지 확인
- 여기서 인증이 제대로 안되면 (Not Found)메세지가 추가된다.
Multycontainer
- 하나의 pod에서 여러개의 컨테이너를 한번에 초기화
- depend on을 사용할 수 있고, 혹은 필요한만큼 지연시켜서 순서를 맞춰 컨테이너 생성
- 그러나 보통은 하나의 pod에 하나의 컨테이너를 사용하는 편이다. (마이크로 서비스)
ConfigMap
- 기밀이 아닌 데이터를 저장하는데 사용하는 API오브젝트
- 키 - 값 쌍
오전강의
ConfigMap
vi configmap-dev.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: config-dev
namespace: default
data:
DB_URL: localhost
DB_USER: myuser
DB_PASS: mypass
DEBUG_INFO: debug
- kubectl apply -f configmap-dev.yaml
- kubectl describe configmaps config-dev
vi deployment-config01.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: configapp
labels:
app: configapp
spec:
replicas: 1
selector:
matchLabels:
app: configapp
template:
metadata:
labels:
app: configapp
spec:
containers:
- name: testapp
image: 192.168.56.101:5000/nginx:latest
ports:
- containerPort: 8080
env:
- name: DEBUG_LEVEL
valueFrom:
configMapKeyRef:
name: config-dev
key: DEBUG_INFO
---
apiVersion: v1
kind: Service
metadata:
labels:
app: configapp
name: configapp-svc
namespace: default
spec:
type: NodePort
ports:
- nodePort: 30800
port: 8080
protocol: TCP
targetPort: 80
selector:
app: configapp
- kubectl exec -it configapp-c9bb7b748-lczsz -- bash
- env
- DEBUG-LEVEL은 deployment-config01에서 정의된 환경변수이다.
- 그 값인 debug는 configmap-deb에서 data에 선언되어있다.
configmap - wordpress
vi configmap-wordpress.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: config-wordpress
namespace: default
data:
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: kosa0401
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppass
- kubectl describe configmaps config-wordpress
- configmap타입으로 이름을주고, data로 변수들을 저장한다.
vi mysql-pod-svc.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod
labels:
app: mysql-pod
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-pod
ports:
- protocol: TCP
port: 3306
targetPort: 3306
- kubectl apply -f mysql-pod-svc.yaml
- ClusterIP와 함께 잘 서비스 되고있다.
vi wordpress-pod-svc.yaml
apiVersion: v1
kind: Pod
metadata:
name: wordpress-pod
labels:
app: wordpress-pod
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-pod
ports:
- protocol: TCP
port: 80
targetPort: 80
- kubectl apply -f wordpress-pvc-pod.yaml
vi 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
- kubectl apply -f mysql-deploy-svc.yaml
vi 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.56.101:
selector:
app: wordpress-deploy
ports:
- protocol: TCP
port: 80
targetPort: 80
- kubectl apply -f wordpress-deploy-svc.yaml
네트워크 에러
- LoadBalancer는 IP를 자동으로 받아야한다.
- 그래서 metallb(DHCP)에서 IP를 받아야하는데, 현재 오류로 인해 metallb를 다 내렸다. 그래서 Pending이 나오고 있다.
- 따라서 새로 External IP 를 부여해야한다.
name space
namespace 관리
- 리소스그룹이라고도 볼 수 있다.
- Azure에서 리소스그룹을 사용할 때, 리소스 그룹안에서 모든 작업을 하고, 이후 작업을 정리할 때, 리소스그룹을 한번에 지우면 되었다.
- 네임스페이스는 쿠버네티스 클러스터를 논리적으로 나눠서 사용하는 것이다.
- 클러스터 하나를 여러개 팀이나 사용자가 공유할 수 있다.
- 네임스페이스를 명시하지 않으면 default 네임스페이스에서 작업하게 된다.
- 따라서 지금까지 우리는 default 네임스페이스에서 작업 한 것이다.
- 또, default 네임스페이스를 우리가 따로 설정할 수 있다.
namespace
kubectl get namespaces
- 현재 우리가 가지고 있는 namespace들을 보여준다.
kubectl get all -n metallb-system
- 이전에 metallb로 생성한 네임스페이스의 정보를 볼 수 있다.
kubectl config get-contexts kubernetes-admin@kubernetes
- 오른쪽에 namespace가 없는것은 기본값이 default로 되어있기 때문이다.
kubectl create namespace test-namespace
- 새로 namespace를 생성했다.
- -n 옵션으로 namespace를 지정하여 pod를 생성하니 그냥 kubectl get pod으로는 나오지 않는다.
- 이렇게 -n을 굳이 쳐줘야 생성한 pod가 나왔다.
kubectl config set-context kubernetes-admin@kubernetes --namespace=test-namespace
kubectl config get-contexts kubernetes-admin@kubernetes
- 오른쪽 NAMESPACE부분에 test-namespace로 잘 출력된다.
kubectl delete namespaces test-namespace
- 생성한 네임스페이스를 다시 삭제해준다.
- 삭제하고, get all명령어를 입력하니 namespace를 찾을 수 없다는 에러가 출력된다.
kubectl config set-context kubernetes-admin@kubernetes --namespace=default
- 기본 namespace를 다시 default로 바꿔준다.
kubectl create namespace test-namespace
kubectl get namespace
kubectl config set-context kubernetes-admin@kubernetes --namespace=test-namespace
kubectl config set-context kubernetes-- admin@kubernetes --namespace=default
ns
- ns는 namespace의 줄임말이다.
- kubectl create ns my-ns
- my-ns라는 namespace를 만들어준다.
- 잘 생성되었다.
ResourceQuota
- 한 팀에서 리소스를 모두 가져갈 수 없도록, 리소스의 제한을 주는 것이다.
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
vi 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
- kubectl apply -f sample-resourcequota.yaml
- hard, pod제한이 5개로 제한된것을 볼 수 있다.
- kubectl run pod new-nginx1 --image=nginx
- kubectl run pod new-nginx2 --image=nginx
- kubectl run pod new-nginx3 --image=nginx
- kubectl run pod new-nginx4 --image=nginx
- kubectl run pod new-nginx5 --image=nginx
- 4개째에서 막혔다. 최대 pod개수 5개중 5개를 사용했기때문에 더이상 생성이 안된다.
vi sample-resourcequota-usable.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: sample-resourcequota-usable
namespace: my-ns
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
vi sample-resource.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-resource
spec:
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.16
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
limit늘리는 방법
- edit명령어를 사용해 올려준다.
kubectl apply -f sample-pod.yaml
kubectl get pod
- pod의 상태가 pending상태이다.
- CPU의 한계에 걸린 것 같다.
- cpu자원을 limit: 1000mi, request: 950mi로 낮춰서 다시 해본다.
kubectl delete pod,deploy --all
- vi sample-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
spec:
containers:
- name: nginx-container
image: nginx:1.16
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "1000m"
- requsts와 limits를 이렇게 저렇게 수정했지만, 잘 running되는 조건을 찾기가 매우 힘들었다.
- limits는 하나의 resource quota를 보겠지만, 물론 기본으로 돌아가는 kubelet같은 시스템의 자원점유를 무시할 수 없기 때문인 것 같다.
vi sample-resource.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-resource
spec:
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.16
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
- 다행히 리소스의 한도 걱정없이 잘 실행되고 잇다.
vi new-sample-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: new-sample-pod
spec:
containers:
- name: nginx-container
image: nginx:1.16
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
- worker들 사이의 업무분담을 확인해본다.
- 각 2개의 pod씩 잘 작동하고잇다.
LimitRange
vi sample-limitrange-container.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: sample-limitrange-container
namespace: my-ns
spec:
limits:
- type: Container
default:
memory: 512Mi
cpu: 500m
defaultRequest:
memory: 256Mi
cpu: 250m
max:
memory: 1024Mi
cpu: 1000m
min:
memory: 128Mi
cpu: 125m
maxLimitRequestRatio:
memory: 2
cpu: 2
kubectl apply -f sample-limitrange-container.yaml
kubectl describe limitranges sample-limitrange-container
- 메모리 최대: 1G, 최소: 128M 디폴트: 256~512
- CPU 최대: 250m, 최소: 125m 디폴트 250~500m
vi sample-pod-limitrange.yaml
apiVersion: v1
kind: Pod
metadata:
name: sample-pod-limitrange
spec:
containers:
- name: nginx-container
image: nginx:1.16
kubectl apply -f sample-pod-limitrange.yaml
kubectl get pod -o wide
kubectl describe pod sample-pod-limitrange.yaml
vi 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
- minimum cpu usage poer Container 12 125m이라고 에러와함께 경고해주고있다.
- 그렇다면 경고에 맞에 맞춰보도록 하자
vi 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: 125m
limits:
cpu: 125m
- 에러가 나오지는 않았다.
- 잘 만들어졌다.
vi sample-pod-overratio.yaml
apiVersion: v1
kind: Pod
metadata:
name: sample-pod-overratio
spec:
containers:
- name: nginx-container
image: nginx:1.16
resources:
requests:
cpu: 125m
limits:
cpu: 500m
- CPU max limit to request ratio per Container is 2, but provided ratio is 4 라는 에러 메세지가 출력된다.
- 요청 CPU리소스의 한계는 그의 2배여야 하는데 4배의 자원을 주었다는 뜻이다. limits를 250으로 설정하여 다시 시도해본다.
- limits를 250m으로 낮추니 잘 실행하고 있다.
Prometheus
- Prometheus는 CNCF가 호스트하는 오픈소스 소프트웨어 모니터링 도구이다.
- 운영 비용이나, 서버 측 머신 리소스가 필요하다.
- 여러 메트릭을 수집, 그래프화, 모니터링 할 수 있다.
- Grafana와 같이 사용할 것이다
- 아직 준비가 덜되어 이후에 학습할 것이다.
Grafana
- 오픈소스 메트릭 데이터 시각화 도구로, 메트릭 분석 플랫폼을 지향한다.
파드 스케쥴 (자동 배치)
- 노드에 파드를 배치시키는 것 = 스케쥴
- 지금까지 우리가 했던 내용들이다.
먼저 이전 자원 정리
- kubectl delete pod,deploy --all
- pod,deploy들을 지운다.
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
ad-hoc으로 만들어본다.
- kubectl run ad-hoc1 --image=nginx
- 현재 2개의 pod을 생성했는데 각각 worker1과 2에 골고루 들어갔다.
vi pod-nodename-service.yaml(수동배치)
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-nodename-metadata pod가 worker2에서 running중이다.
- 이렇게 노드를 지정할 수 있다.
노드 셀렉터(수동배치)
- 노드에게 label을 주는 것이다.
kubectl label nodes worker1 tier=dev
- tier라는 키와 def라는 값을 주는 것이다.
- 오타가 들어가서 overwrite를 한번 해줬다.
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-
- worker1의 tier를 지우는 방법이다.
- worker의 tier를
-
로 넣음으로 tier를 지우는 것이다.
kubectl get nodes --show-labels
taint와 toleration
- taint : 더러움
kubectl get pod -o wide
- 현재 worker1과 2가 작업중인데, 만약 수치상으로는 괜찮지만, worker1이 불안정한 상황이라면, taint를 걸어 스케쥴을 부여하지 않는 것이다.
- taint는 수동으로만 container를 부여받고, 자동으로는 받지 않는 것이다.
- 현재 node들의 상황이다.
kubectl taint node worker1 tier=devLNoSchedule
- worker1이 taint되었다고 출력된다.
- 현재 kubectl get node에서는 관련 정보가 나오지 않는다.
kubectl describe node worker1
- taint로 dev:NoSchedule, 스케쥴을받지 않는다는 것이다.
toleration
- taint된 node에 작업을 주는것이 toleration이다.