๐ 05. ๋คํธ์ํฌ ์๋น์ค
1. ๋คํฐ์ํฌ ์๋น์ค ๊ฐ๋
2. Telepresense ์ค์น
์ค์น ๊ฐ์ด๋ (Install Client, Install Trafiic Manager ์ฐธ๊ณ )
- Telepresense CLI ๋ก์ปฌ ์ค์น
- Linux ์ค์น
# 1. Download the latest binary (~95 MB):
# AMD
sudo curl -fL https://github.com/telepresenceio/telepresence/releases/latest/download/telepresence-linux-amd64 -o /usr/local/bin/telepresence
# ARM
sudo curl -fL https://github.com/telepresenceio/telepresence/releases/latest/download/telepresence-linux-arm64 -o /usr/local/bin/telepresence
# 2. Make the binary executable:
sudo chmod a+x /usr/local/bin/telepresence
- AMD(intel) Mac ์ค์น
# 1. Download the binary.
sudo curl -fL https://github.com/telepresenceio/telepresence/releases/latest/download/telepresence-darwin-amd64 -o /usr/local/bin/telepresence
# 2. Make the binary executable:
sudo chmod a+x /usr/local/bin/telepresence
- ARM(Apple Silicon) Mac ์ค์น
# 1. Ensure that no old binary exists. This is very important because Silicon macs track the executable's signature
# and just updating it in place will not work.
sudo rm -f /usr/local/bin/telepresence
# 2. Download the binary.
sudo curl -fL https://github.com/telepresenceio/telepresence/releases/latest/download/telepresence-darwin-arm64 -o /usr/local/bin/telepresence
# 3. Make the binary executable:
sudo chmod a+x /usr/local/bin/telepresence
- Windows ์ค์น
# To install Telepresence, run the following commands
# from PowerShell as Administrator.
# 1. Download the latest windows zip containing telepresence.exe and its dependencies (~60 MB):
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest https://github.com/telepresenceio/telepresence/releases/latest/download/telepresence-windows-amd64.zip -OutFile telepresence.zip
# 2. Unzip the telepresence.zip file to the desired directory, then remove the zip file:
Expand-Archive -Path telepresence.zip -DestinationPath telepresenceInstaller/telepresence
Remove-Item 'telepresence.zip'
cd telepresenceInstaller/telepresence
# 3. Run the install-telepresence.ps1 to install telepresence's dependencies. It will install telepresence to
# C:\telepresence by default, but you can specify a custom path by passing in -Path C:\my\custom\path
powershell.exe -ExecutionPolicy bypass -c " . '.\install-telepresence.ps1';"
# 4. Remove the unzipped directory:
cd ../..
Remove-Item telepresenceInstaller -Recurse -Confirm:$false -Force
# 5. Telepresence is now installed and you can use telepresence commands in PowerShell.
- Telepresense Server๋ฅผ K8s ํด๋ฌ์คํฐ์ ์ค์น
# Telepresence namespace ์์ฑ
kubectl create namespace telepresense
# Telepresense ์๋ฒ๋ฅผ ์ฟ ๋ฒ๋คํฐ์ค์ ์ค์น
telepresence helm install -n telepresense
### - ์ค์น ํ์ธ
kubectl get all -n telepresence
- ์ฐ๊ฒฐ ํ๊ณ ์ํ ํ์ธํ๊ธฐ
# Telepresense ํ๋ก์ ์ฐ๊ฒฐ
telepresence connect --manager-namespace telepresense
# ์ฐ๊ฒฐ ์ํ ํ์ธ
telepresence status
3. ClusterIP
- nodes app ์์ฑ
- ์ ํ๋ฆฌ์ผ์ด์ ์์ฑ
- app.js
const http = require('http');
const os = require('os');
console.log("Kubia server starting...");
var handler = function(request, response) {
console.log("Received request from " + request.connection.remoteAddress);
response.writeHead(200);
response.end("You've hit " + os.hostname() + "\n");
};
var www = http.createServer(handler);
www.listen(8080);
- Dockerfile ์์ฑ
# FROM ์ผ๋ก BASE ์ด๋ฏธ์ง ๋ก๋
FROM node:7
# ADD ๋ช
๋ น์ด๋ก ์ด๋ฏธ์ง์ app.js ํ์ผ ์ถ๊ฐ
ADD app.js /app.js
# ENTRYPOINT ๋ช
๋ น์ด๋ก node ๋ฅผ ์คํํ๊ณ ๋งค๊ฐ๋ณ์๋ก app.js ๋ฅผ ์ ๋ฌ
ENTRYPOINT ["node", "app.js"]
- ์ปคํ ์ด๋ ๋น๋ ๋ฐ ํธ์
docker build -t <DOCKER ID>/nodeapp . --push
- POD ์์ฑ
- pod ์์ฑ
- nodeapp-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp-deploy
spec:
replicas: 3
selector:
matchLabels:
app: nodeapp-pod
template:
metadata:
labels:
app: nodeapp-pod
spec:
containers:
- name: nodeapp-container
image: dangtong/nodeapp
ports:
- containerPort: 8080
- ClusterIP ์๋น์ค ์์ฑ
- ์๋น์ค ์์ฑ
- nodeapp-svc.yml
apiVersion: v1
kind: Service
metadata:
name: nodeapp-service
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: nodeapp-pod
- ์๋น์ค ํ์ธ
- ์กฐํ
kubectl get po,deploy,svc
- Deployment ์์ฑ
kubectl apply -f ./nodeapp-deploy.yml
- ์๋น์ค ์์ฑ
kubectl apply -f ./nodeapp-svc.yml
- port-forward to service
kubectl port-forward service/nodeapp-service 8080:80
- port-forward to pod
[์ฐ์ต๋ฌธ์ ] 5-1. ClusterIP
- nginx:1.8.9 ์ด๋ฏธ์ง๋ฅผ ์ด์ฉํ์ฌ Replica=3 ์ธ Deployment ๋ฅผ ์์ฑํ์ธ์
- nginx ์๋น์ค๋ฅผ ๋ก๋๋ฐธ๋ ์ฑ ํ๋ ์๋น์ค๋ฅผ ClusterIP ๋ก ์์ฑํ์ธ์
- kubernetes port-forward๋ฅผ ์ด์ฉํด์ ๋คํธ์ํฌ๋ฅผ ์ฐ๊ฒฐํ๊ณ curl ๋ช
๋ น์ด๋ก ์น์ฌ์ดํธ๋ฅผ ์กฐํ ํ์ธ์
4. NodePort (๋ก์ปฌ ์ฟ ๋ฒ๋คํฐ์ค์์ ์คํ)
- ์ ํ๋ฆฌ์ผ์ด์ ์์ฑ
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp-deploy
spec:
replicas: 3
selector:
matchLabels:
app: nodeapp-pod
template:
metadata:
labels:
app: nodeapp-pod
spec:
containers:
- name: nodeapp-container
image: dangtong/nodeapp
ports:
- containerPort: 8080
- NodePort ์์ฑ
apiVersion: v1
kind: Service
metadata:
name: node-nodeport
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 30123
selector:
app: nodeapp-pod
kubectl apply -f ./nodeapp-nodeport.yml
- ๋ฆฌ์์ค ์กฐํ
kubectl get po,rs,svc
- ๋ ธ๋ ์กฐํ
kubectl get no -o wide
๋ก์ปฌ ์ฟ ๋ฒ๋คํฐ์ค ๋ ธ๋์ ํธ์คํธ IP ํ์ธํ๊ธฐ
docker inspect kind
- ์๋น์ค ์ ์ (์ฌ๋ฌ๋ฒ ์ํ)
curl http://<host-ip>:30123
curl http://<host-ip>:30123
curl http://<host-ip>:30123
curl http://<host-ip>:30123
curl http://<host-ip>:30123
5. LoadBalancer
- Deployment ์์ฑ
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp-deployment
labels:
app: nodeapp
spec:
replicas: 3
selector:
matchLabels:
app: nodeapp-pod
template:
metadata:
labels:
app: nodeapp-pod
spec:
containers:
- name: nodeapp-container
image: dangtong/nodeapp
ports:
- containerPort: 8080
- LoadBalancer ์์ฑ (AWS)
- AWS Load Balancer ์์ฑ
apiVersion: v1
kind: Service
metadata:
name: nodeapp-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:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: nodeapp-pod
- GCP Loadbalancer ์์ฑ
apiVersion: v1
kind: Service
metadata:
name: nodeapp-lb
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: nodeapp-pod
- LoadBalancer ํ์ธ ๋ฐ ์ ์
EXTERNAL-IP ์ ํด๋นํ๋ URL๋ก ๋ธ๋ผ์ฐ์ ์์ HTTP๋ก ์ ์
kubectl get svc
6. Ingress
Ingress๋ ํด๋ฌ์คํฐ ์ธ๋ถ์์ ํด๋ฌ์คํฐ ๋ด๋ถ ์๋น์ค๋ก HTTP/HTTPS ํธ๋ํฝ์ ๋ผ์ฐํ ํ๋ ๊ท์น์ ์ ์ํฉ๋๋ค.
- Ingress Controller ํ์ธ
kubectl get deploy -n kube-system
- ๊ธฐ๋ณธ Ingress ์์
1. Deployment ์์ฑ
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
2. Service ์์ฑ
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
3. Ingress ์์ฑ
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: alb-ingress-class
spec:
controller: ingress.k8s.aws/alb
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
ingressClassName: "alb-ingress-class"
rules:
- host: nginx.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
- Ingress ํ ์คํธ
1. ๋ฆฌ์์ค ์์ฑ
kubectl apply -f nginx-deployment.yaml
kubectl apply -f nginx-service.yaml
kubectl apply -f nginx-ingress.yaml
2. Ingress ์ํ ํ์ธ
aws elbv2 describe-load-balancers
kubectl get ingress
kubectl describe ingress nginx-ingress
3. ์ ์ ํ ์คํธ
# Ingress IP ํ์ธ
kubectl run test-dns --image=busybox:1.28 --rm -it --restart=Never -- nslookup k8s-default-nginxing-d8df56bf3a-1927562401.ap-northeast-2.elb.amazonaws.com
# ํธ์คํธ ํ์ผ์ ๋๋ฉ์ธ ์ถ๊ฐ (๋ก์ปฌ ํ
์คํธ์ฉ)
echo "<Ingress-Public-IP> nginx.example.com" >> /etc/hosts
# ์ ์ ํ
์คํธ
curl -H "nginx.example.com" http://nginx.example.com
- ๊ฒฝ๋ก ๊ธฐ๋ฐ ๋ผ์ฐํ Ingress
1. ์ฌ๋ฌ ์๋น์ค ์์ฑ
# app1-deploy.yml
# app1 ์๋น์ค
apiVersion: apps/v1
kind: Deployment
metadata:
name: app1-deployment
spec:
replicas: 2
selector:
matchLabels:
app: app1
template:
metadata:
labels:
app: app1
spec:
containers:
- name: app1
image: nginx
ports:
- containerPort: 80
---
# app1-svc.yml
apiVersion: v1
kind: Service
metadata:
name: app1-service
spec:
selector:
app: app1
ports:
- port: 80
targetPort: 80
# app2-deploy.yml
# app2 ์๋น์ค
apiVersion: apps/v1
kind: Deployment
metadata:
name: app2-deployment
spec:
replicas: 2
selector:
matchLabels:
app: app2
template:
metadata:
labels:
app: app2
spec:
containers:
- name: app2
image: httpd:2.4
ports:
- containerPort: 80
---
# app2-svc.yml
apiVersion: v1
kind: Service
metadata:
name: app2-service
spec:
selector:
app: app2
ports:
- port: 80
targetPort: 80
2. ๊ฒฝ๋ก ๊ธฐ๋ฐ Ingress
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: alb-ingress-class
spec:
controller: ingress.k8s.aws/alb
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-based-ingress
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: "alb-ingress-class"
rules:
- host: nginx.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- host: apache.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
3. ์ ์ ํ ์คํธ
# Ingress ์ํ ํ์ธ
```bash
aws elbv2 describe-load-balancers
Ingress domain ํ์ธ
kubectl get ingress
Ingress IP ํ์ธ
kubectl run test-dns --image=busybox:1.28 --rm -it --restart=Never -- nslookup <ingress-domain>
ํธ์คํธ ํ์ผ์ ๋๋ฉ์ธ ์ถ๊ฐ (๋ก์ปฌ ํ ์คํธ์ฉ)
echo "<Ingress-Public-IP> nginx.example.com apache.example.com" >> /etc/hosts
์ ์ ํ ์คํธ
curl -H "Host: nginx.example.com" http://nginx.example.com/
curl -H "Host: apache.example.com" http://apache.example.com/
- TLS/HTTPS Ingress
1. TLS Secret ์์ฑ
# ์์ฒด ์๋ช
์ธ์ฆ์ ์์ฑ
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=vhost.example.com/O=example.com"
# Kubernetes Secret ์์ฑ
kubectl create secret tls tls-secret --key tls.key --cert tls.crt
2. TLS Ingress ์์ฑ
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
tls:
- hosts:
- vhost.example.com
secretName: tls-secret
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
- [์ฐ์ต๋ฌธ์ ] 5-3. Ingress ์ค์ต
1. ๊ธฐ๋ณธ Ingress ์์ฑ
์๋ ์กฐ๊ฑด์ ๋ง์กฑํ๋ Ingress๋ฅผ ์์ฑํ์ธ์:
- Ingress ์ด๋ฆ: my-ingress
- ํธ์คํธ: myapp.local
- ์๋น์ค: nginx-service
- ๊ฒฝ๋ก: /
2. ๊ฒฝ๋ก ๊ธฐ๋ฐ ๋ผ์ฐํ Ingress ์์ฑ
์๋ ์กฐ๊ฑด์ ๋ง์กฑํ๋ Ingress๋ฅผ ์์ฑํ์ธ์:
- Ingress ์ด๋ฆ: path-ingress
- ํธ์คํธ: example.com
- /api ๊ฒฝ๋ก โ api-service
- /web ๊ฒฝ๋ก โ web-service
3. Ingress ํ ์คํธ
์์ฑ๋ Ingress๋ฅผ ํ ์คํธํ์ธ์.
- Ingress Controller ์ค์น (ํ์์)
Nginx Ingress Controller ์ค์น
# Helm์ ์ฌ์ฉํ ์ค์น
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx
# ๋๋ kubectl์ ์ฌ์ฉํ ์ค์น
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml
- ์ ๋ฆฌ
# ๋ฆฌ์์ค ์ญ์
kubectl delete ingress my-ingress
kubectl delete ingress path-ingress
kubectl delete service nginx-service
kubectl delete deployment nginx-deployment
7. Headless Service
Headless Service๋ ClusterIP๊ฐ ์๋ ์๋น์ค๋ก, DNS ์กฐํ ์ ๋ชจ๋ Pod์ IP ์ฃผ์๋ฅผ ์ง์ ๋ฐํํฉ๋๋ค.
- Headless Service ์์ฑ
- StatefulSet ์์ฑ (Headless Service์ ํจ๊ป ์ฌ์ฉ)
# nginx-sts.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
- Headless Service ์์ฑ
# headless-svc.yml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
- Headless Service ํ ์คํธ
- ๋ฆฌ์์ค ์์ฑ
kubectl apply -f statefulset.yaml
kubectl apply -f headless-service.yaml
- Pod ์ํ ํ์ธ
kubectl get po,svc
- DNS ์กฐํ ํ ์คํธ
# ์์ Pod ์์ฑํ์ฌ DNS ํ
์คํธ
kubectl run test-dns --image=busybox:1.28 --rm -it --restart=Never -- nslookup nginx
# ๋๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ
kubectl run test-dns --image=busybox:1.28 --rm -it --restart=Never -- sh
# nslookup nginx
# exit
- ๊ฐ๋ณ Pod DNS ์กฐํ
# ํน์ Pod์ DNS ์ด๋ฆ์ผ๋ก ์กฐํ
kubectl run test-dns --image=busybox:1.28 --rm -it --restart=Never -- nslookup web-0.nginx
kubectl run test-dns --image=busybox:1.28 --rm -it --restart=Never -- nslookup web-1.nginx
kubectl run test-dns --image=busybox:1.28 --rm -it --restart=Never -- nslookup web-2.nginx
- ์ผ๋ฐ Service vs Headless Service ๋น๊ต
- ์ผ๋ฐ Service ์์ฑ (ClusterIP)
# plain-svc.yml
apiVersion: v1
kind: Service
metadata:
name: nginx-clusterip
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
- DNS ์กฐํ ๊ฒฐ๊ณผ ๋น๊ต
- ์ผ๋ฐ Service DNS ์กฐํ
kubectl run test-dns --image=busybox:1.28 --rm -it --restart=Never -- nslookup nginx-clusterip
# ๊ฒฐ๊ณผ: ๋จ์ผ IP ์ฃผ์ ๋ฐํ (Service์ ClusterIP)
- Headless Service DNS ์กฐํ
kubectl run test-dns --image=busybox:1.28 --rm -it --restart=Never -- nslookup nginx-headless
# ๊ฒฐ๊ณผ: ๋ชจ๋ Pod์ IP ์ฃผ์ ๋ฐํ
- [์ฐ์ต๋ฌธ์ ] 5-2. Headless Service ์ค์ต
1. Redis StatefulSet๊ณผ Headless Service ์์ฑ
์๋ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ๋ฆฌ์์ค๋ฅผ ์์ฑํ์ธ์:
- StatefulSet ์ด๋ฆ: redis-sts
- Replica: 3๊ฐ
- ์ด๋ฏธ์ง: redis:7.2
- Headless Service ์ด๋ฆ: redis-headless
- ํฌํธ: 6379
2. DNS ์กฐํ ํ ์คํธ
Headless Service์ DNS ์กฐํ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ์ธ์.
3. Redis ํด๋ผ์ด์ธํธ๋ก ์ฐ๊ฒฐ ํ ์คํธ
Headless Service๋ฅผ ํตํด Redis์ ์ฐ๊ฒฐํด๋ณด์ธ์.
- Headless Service ์ฌ์ฉ ์ฌ๋ก
- StatefulSet๊ณผ ํจ๊ป ์ฌ์ฉ: ๊ฐ Pod๊ฐ ๊ณ ์ ํ ID๋ฅผ ๊ฐ์ ธ์ผ ํ ๋
- ์๋น์ค ๋์ค์ปค๋ฒ๋ฆฌ: ํด๋ผ์ด์ธํธ๊ฐ ๋ชจ๋ Pod์ ์ง์ ์ฐ๊ฒฐํด์ผ ํ ๋
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ํด๋ฌ์คํฐ: ๊ฐ ๋ ธ๋๊ฐ ๋ค๋ฅธ ๋ ธ๋๋ฅผ ์ง์ ์์์ผ ํ ๋
- ๋ฉ์์ง ์์คํ : ๊ฐ ๋ ธ๋๊ฐ ๋ค๋ฅธ ๋ ธ๋์ ์ง์ ํต์ ํด์ผ ํ ๋
- ์ ๋ฆฌ
# ๋ฆฌ์์ค ์ญ์
kubectl delete statefulset redis-sts
kubectl delete service redis-headless
kubectl delete service nginx
kubectl delete statefulset web