https://kubernetes.io/ko/docs/concepts/services-networking/ingress-controllers/
설치를 확인한 것이 인그레스 컨트롤러이다.
경로를 보고 원하는 서비스로 라우팅을 해줌
class는 우리가 선택할 수 있는 개념..
라우팅 정책을 집중해서 구성할 예정임
TLS는 https임
이거는 도메인이 실제로 있어야함 그래서 AWS할때 실제로 해볼꺼고 지금은 가짜 도메인을 만들어서 해볼 예정
뒤에가 경로가 정확한 경로인지 다양하게 올 수 있는지의 차이
이거 순서가 중요해서 먼저 걸리는거 부터 연결시켜줌
https://kubernetes.io/ko/docs/concepts/services-networking/ingress/
apiVersion: v1
kind: Service
metadata:
name: myweb-svc-np
spec:
type: NodePort
selector:
app: web
ports:
- port: 80
targetPort: 8080
nodePort: 31313
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myweb-rs
spec:
replicas: 3
selector:
matchLabels:
app: web
env: dev
template:
metadata:
labels:
app: web
env: dev
spec:
containers:
- name: myweb
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myweb-ing
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myweb-svc-np
port:
number: 80
kubectl create -f myweb-svc-np.yaml
kubectl create -f myweb-ing.yaml
kubectl get all #여기에 인그레스는 없음
kubectl get ing
각 노드마다 ingress-nginx가 만들어져 있음
그래서 확인해보면
이렇게 바꿔보면
여기서 host를 지워보면
모든 host를 받음
>
는 요청
<
는 응답
다시 없는 호스트를 설정 해보고
replace하고
404 Not Found가 뜸
이렇게 없는 도메인을 어떻게 테스트 해볼 것인가?
curl --resolve www.encore.xyz:80:192.168.100.100 http://www.encore.xyz
두 번째 방법
순서임 hosts파일을 먼저 보고 resolv.conf 파일을 봄
윈도우도 똑같음 c드라이브/windows/system32/drivers/etc/hosts
예를들어 크랙을 설치하면 window시스템에 precess가 하나뜨고..
아무리 DNS를 잘 설정해놔도 hosts파일을 들어가게 되게 해서 가짜 ip를 접속하게 해서 그렇게 정보를 빼간다고 한다..
vi /etc/hosts
이렇게도 할 수 있다
마지막 방법
https://nip.io/
wildcard DNS라는 것임
뭘 요청해도 응답을 돌려주는 DNS 서버라고함
host 10.10.10.10.npi.io
host www.10.10.10.10.npi.io
host 10-10-10-10.npi.io
항상 주소 중간에 있는 ip를 리턴해줌
그래서..
vi myweb-ing.yaml
kubectl replace ce -f myweb-ing.yaml
sslip.io라는 것도 있음
이건 ipv6도 지원함
wildcard dns service라고 부름
L7라서 이런 주소가 중요한거임
L4면 당연히 이런걸 테스트할 수 없음
도커없이 빌드할 수 있는 방법
https://buildah.io/
https://podman.io/
https://github.com/containers/skopeo
docker login
docker push
docker push
### docker image를 별도의 가상머신에서 퍼블릭에 올려준다
### c1t1d0s7/hello:one
### c1t1d0s7/hello:two
### 강사님꺼 이미지임
kubectl create -f .
curl http://192-168-100-100.nip.io/one
curl http://192-168-100-100.nip.io/two
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-ing
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
이 둘의 차이를 확인해보자
기본적으로 루트 밑에 index.html파일을 불러오는거라서 notfound가 떴던거임
경로가 루트가 아니었던거를 루트로 재작성해주는 작업이 필요함
결과를 확인해보면..
apiVersion: v1
kind: Service
metadata:
name: myweb-svc-lb
spec:
type: LoadBalancer
selector:
app: web
ports:
- port: 80
targetPort: 8080
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myweb-rs
spec:
replicas: 3
selector:
matchLabels:
app: web
env: dev
template:
metadata:
labels:
app: web
env: dev
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb:alpine
ports:
- containerPort: 8080
protocol: TCP
kubectl explain rs.spec.template.spec.containers
### readinessProbe가 있음 이걸 구성해볼 예정
중요한건 /tmp/ready는 없음
그래서 실패할 예정
ready가 안되어있는 상태
이렇게 상태체크를 해서 해당 컨테이너를 활성화 시키고 비활성화시키게 해준다.
만약 readinessProbe를 설정하지 않으면 무조건 success가 뜸
readinessProbe는 endpoint에 등록을 시키고 해제시키는 기능으로 비정상 컨테이너에 대해서 라우팅을 안시키게 만든다.
추가적으로
이번 실습에서는 alpine리눅스 기반으로 만든 이미지라서 shell도 있었던거임
https://kubernetes.io/ko/docs/concepts/workloads/pods/init-containers/
gitRepo(사용중지) -> initContainer(초기화컨테이너)
Pod가 생성되고 딱 1번만 실행된다. userdata같은 느낌
https://hub.docker.com/r/alpine/git
alpine에 git을 설치한 이미지이다.
쉘을 계속 띄워놓기 위한 꼼수..
apiVersion: v1
kind: Pod
metadata:
name: init-pod
spec:
initContainers:
- name: gitpull
image: alpine/git
args:
- clone
- -b
- v2.18.1
- https://github.com/kubernetes-sigs/kubespray.git
- /repo
volumeMounts:
- name: gitrepo
mountPath: /repo
containers:
- name: gituse
image: busybox
args:
- tail
- -f
- /dev/null
volumeMounts:
- name: gitrepo
mountPath: /kube
volumes:
- name: gitrepo
emptyDir: {}
kubectl get po
### init하는 과정을 볼 수 있다
이렇게 로그를 보면 image를 먼저 띄우고 이후에 종료되고 없어지는 것을 볼 수 있다.
이렇게 저장소에 저장이 되어 있는 것을 확인할 수 있다.
bind방식과 유사하다. 어떤 볼륨을 채워서 제공하는 방식임
knode: /mnt/web_contents/index.html
<h1> Hello hostPath </h1>
이걸 가지고 httpd 이미지 RS 생성
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myweb-rs-hp
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: myweb
image: httpd
volumeMounts:
- name: web-contents
mountPath: /usr/local/apache2/htdocs/
volumes:
- name: web-contents
hostPath:
type: Directory
path: /web_contents
쓸데 없는 Pod를 지우고
방금 한 실습에서는 디렉토리가 네트워크 스토리지가 아니라서 node2와 node3에서는 오류가 났던거임
이렇게 다시 만들어주고
다시 생성해주면 됨
참고사항
로컬스토리지: 다른 호스트에 스토리지 볼륨을 제공할 수 없다.
- emptyDir
- hostPath
- gitRepo
- local
sudo mkdir /a
echo "hello world" > /a/a.txt #에러
>
는 뒤에 그게 명령어가 아니라서 sudo가 안됨 그런데 |
는 sudo가 됨 그래서 tee를 사용해서 루트권한을 사용할 수 있게 해주는것임
pv는 말그대로 영구 볼륨이다
pvc는 영구 볼륨 요청
개발자가 Pod를 다루면 스토리지는 인프라엔지니어가 다룰 수 있게 영역을 나누어 놓았음
이게 k8s의 철학임
그래서 직접 스토리지를 설정하는 경우는 거의 없음
PV는 스토리지 볼륨을 정의
PVC는 PV요청을 정의
스토리지를 지정하는 방식은 총 3가지 있음
이런 방식임
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: httpd
volumeMounts:
- name: myvol
mountPath: /tmp
volumes:
- name: myvol
persistentVolumeClaim:
name: mypvc
PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
spec:
volumeName: mypv
PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv
spec:
hostPath:
path: /web_contents
type: DirectoryCreate
파드를 정의할 때 PVC를 가리키고 PVC를 정의할 때 PV를 맵핑시킨다
그리고 PV에 디렉토리를 가리킴
이렇게 스토리지와 파드를 분리시킴
https://kubernetes.io/ko/docs/concepts/storage/persistent-volumes/
PV <- 1:1 -> PVC
물론 여러 개의 Pod가 PVC를 참조하는건 가능하다.
한 번 PVC와 PV가 연결된 상태에서 PVC를 삭제하고 남아있는 다른 PVC를 연결했을 때 연결이 안됨
삭제 정책은 PVC를 제거하면 PV와 스토리지가 다 삭제됨
재사용은 스토리지의 데이터를 다 삭제해서 PV를 다시 사용 가능한 상태로 만드는 것임 근데 스토리지를 삭제하는 방법이 스토리지마다 다 달라서 쿠버네티스가 이 부분을 다루기가 어려움
RWOnce Pod 여러 개 하지만 Node는 1개
RWMany는 Pod 여러 개
RWOncePod는 1개의 Pod만
그리고 이렇게 지원하는 볼륨 플러그인이 다 다름
그리고 밑에 더 많은 표 자료 있음 확인
node1: NFS 서버
sudo apt install nfs-kurnel-server -y
sudo mkdir /nfsvolume
echo "<h1> Hello NFS Volume </h1>" | sudo tee /nfsvolume/index.html
sudo vi /etc/exports
/nfsvolume 192.168.100.0(rw,sync,no_subtree_check)
### 모든 호스트 노드에 대해서 허용허려고 .0번대를 사용한거임
sudo systemctl restart nfs-kernel-server
systemctl status nofs-kernel-server
cd ~
mkdir nfs
cd nfs
vi mypv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv
spec:
accessModes:
- ReadWriteMany
capacity:
storage: 1G
persistentVolumeReclaimPolicy: Retain
nfs:
path: /nfsvolume
server: 192.168.100.100
만들기 전에 다 지우고..
PVC가 연결되면 CLAIM에 나옴
vi mypvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1G
storageClassName: '' # For Static Provisioning
volumeName: mypv
동적 프로비저닝을 안할꺼면 그냥 비워놓아야함
이제 Pod든 rs든 만들면 됨
vi myweb-rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myweb-rs
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: myweb
image: httpd
volumeMounts:
- name: myvol
mountPath: /usr/local/apache2/htdocs
volumes:
- name: myvol
persistentVolumeClaim:
claimName: mypvc
kubectl create..
kubectl get rs,po,pv,pvc
마운팅이 안됨
sudo api install nfs-common
### censtos는 nfs-utils이고
### ubuntu는 nfs-commen이 NFS클라이언트 패키지임
mount [tab][tab] #nfs 확인
다시 node1으로 와서..
sudo systemctl
/nfsvolume 192.168.100.0/24(rw,sync,no_subtree_check,no_root_squash)
### 이렇게 수정
ansible all -i ~/kubespray/inventory/mycluster/inventory.ini -m apt -a 'name=nfs-common' -b
vi
apiVersion: v1
kind: Service
metadata:
name: myweb-svc-lb
spec:
type: LoadBalancer
이렇게 권한을 세팅하고 마무리..
내일 할 동적 프로비저닝은 PVC를 만들면 PV가 자동으로 만들어지는 것임