Dev./Kubernetes & Helm

Kubernetes: svc - pod 구조 이해

Ivan'show 2023. 9. 17.
728x90
반응형

K8S: ingress - svc - pod 구조 이해

Mission: fortune pod 에 대해 서비스를 만들어서, 내부 클러스터 ip 로 호출

우선 서비스를 만든다.

# nodeport 로 서비스 생성 fortune-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: fortune-nodeport
spec:
  type: NodePort
  selector:
    app: fortune
  ports:
      # 기본적으로 그리고 편의상 `targetPort` 는 `port` 필드와 동일한 값으로 설정된다.
    - port: 80
      targetPort: 80
k create -f fortune-nodeport.yaml
kimminhyeok@Ivans-Mac 0905 % k get svc
NAME               TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)           AGE
fortune-nodeport   NodePort    10.100.85.23     <none>        80:32075/TCP      3s
...
...

서비스는 spec.selecto.app 에 명시된 내용을 레이블로 가지는 파드들을 서비스하니까

kimminhyeok@Ivans-Mac 0905 % k get po -L app
NAME            READY   STATUS    RESTARTS   AGE   APP
fortune         2/2     Running   0          18h   
lion-fvrw8      1/1     Running   0          19h   lion
lion-qlr4h      1/1     Running   0          19h   lion
lion-v2-j4njd   1/1     Running   0          20h   lion-v2
lion-v2-jmgv4   1/1     Running   0          20h   lion-v2
lion-v2-nf44r   1/1     Running   0          20h   lion-v2
lion-zh79z      0/1     Running   0          19h   lion

fortune 파드의 레이블을 서비스에 명시된 레이블로 바꿔주면 연결이 된다.

k label po fortune app=fortune

실수해서 잘못 넣었을 경우

k label po fortune app=fortune --overwrite

endpoints check

kimminhyeok@Ivans-Mac 0905 % k get endpoints fortune-nodeport      
NAME               ENDPOINTS         AGE
fortune-nodeport   10.244.0.218:80   16m

call

exec 로 컨테이너에 접속해서 ( -c ) curl 명령어로 ip 호출

k exec fortune -c web-server -- curl <http://10.100.85.23>

#
kimminhyeok@Ivans-Mac 0905 % k exec fortune -c web-server -- curl <http://10.100.85.23>
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0It's a very *UN*lucky week in which to be took dead.
                -- Churchy La Femme
100    79  100    79    0     0  57875      0 --:--:-- --:--:-- --:--:-- 79000

silence: -s

k exec fortune -c web-server -- curl -s <http://10.100.85.23>

#
kimminhyeok@Ivans-Mac 0905 % k exec fortune -c web-server -- curl -s <http://10.100.85.23>
Hell is empty and all the devils are here.
                -- Wm. Shakespeare, "The Tempest"

call via dns

Mission: dns 로 호출하기 “curl http://lion.fortune.com

DNS 로 호출을 하려면 DNS 가 먼저 정의되어야 하는 데, 이부분은 ingress 로 할 수 있다.

기존에 있는 ingress 를 수정하거나, 아니면 ingress 를 추가 해서 host 정보를 추가해 준다.

# fortune-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: fortune
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  # ingressClassName: nginx-example
  rules:
  - host: lion.fortune.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: fortune-nodeport
            port:
              number: 80
k get ingress
# result
kimminhyeok@Ivans-Mac 0905 % k get ingress
NAME      CLASS   HOSTS              ADDRESS        PORTS   AGE
fortune   nginx   lion.fortune.com   192.168.49.2   80      21m
lion      nginx   lion.example.com   192.168.49.2   80      20h

ip 호출 명령

—resolve 옵션을 사용하면, 특정 도메인과 포트에 대해 사용될 IP 주소를 수동으로 설정할 수 있다.

curl --resolve "lion.fortune.com:80:127.0.0.1" -i <http://lion.fortune.com>
  • “curl --resolve "lion.fortune.com:80:127.0.0.1" 설정하고
  • -i 옵션으로 HTTP 헤더 정보까지 포함해서 출력한다.
# result
kimminhyeok@Ivans-Mac 0905 % curl --resolve "lion.fortune.com:80:127.0.0.1" -i <http://lion.fortune.com>

HTTP/1.1 200 OK
Date: Tue, 05 Sep 2023 01:45:06 GMT
Content-Type: text/html
Content-Length: 49
Connection: keep-alive
Last-Modified: Tue, 05 Sep 2023 01:45:04 GMT
ETag: 
Accept-Ranges: bytes

You will be traveling and coming into a fortune.

Mission: resolve 옵션을 제외하고 바로 “curl http://lion.fortune.com” 로 호출하기

service 파일에 spec.selector.app 에 있는 레이블 정보를 가지고 endpoints 를 가져가기 때문에 설정을 맞춰준다.

apiVersion: v1
kind: Service
metadata:
  name: fortune-nodeport
spec:
  type: NodePort
  selector: # app 으로 레이블을 달아서 endpoints 에 넣어줄 수 있다.
    app: fortune
  ports:
      # 기본적으로 그리고 편의상 `targetPort` 는 `port` 필드와 동일한 값으로 설정된다.
    - port: 80
      targetPort: 80
k label po fortune app=fortune
sudo vi /etc/hosts
...

127.0.0.1       lion.example.com
127.0.0.1       lion.fortune.com
curl <http://lion.fortune.com>

#
kimminhyeok@Ivans-Mac 0905 % curl <http://lion.fortune.com>
Have a place for everything and keep the thing somewhere else; this is not
advice, it is merely custom.
                -- Mark Twain

Error check

만약 ingress 도 열렸고, svc 의 endpoint 가 잘 설정되어있는 데도 불구하고 계속해서 server connection error 가 발생한다면 Minikube tunnel 이 열려있는지 다시한번 확인하자

# error statement
kimminhyeok@Ivans-Mac configmap % curl <http://lion.fortune.com/>
curl: (7) Failed to connect to lion.fortune.com port 80 after 8 ms: Couldn't connect to server

Solution

sudo minikube tunnel
# result
kimminhyeok@Ivans-Mac 0904 % sudo minikube tunnel
Password:
✅  Tunnel successfully started

📌  NOTE: Please do not close this terminal as this process must stay alive for the tunnel to be accessible ...

❗  The service/ingress fortune requires privileged ports to be exposed: [80 443]
🔑  sudo permission will be asked for it.
❗  The service/ingress lion requires privileged ports to be exposed: [80 443]
🏃  Starting tunnel for service fortune.
🔑  sudo permission will be asked for it.
🏃  Starting tunnel for service lion.

Switch to another terminal

curl <http://lion.fortune.com/>
kimminhyeok@Ivans-Mac configmap % curl <http://lion.fortune.com/>
I got a hint of things to come when I overheard my boss lamenting, 'The
books are done and we still don't have an author! I must sign someone
today!
                -- Tamim Ansary, "Edutopia Magazine, Issue 2, November 2004"
                   on the topic of school textbooks

정상 출력 확인

 

Code Update: fortune

기존의 fortune 프로그램은 10 초 마다 한번씩 스크립트를 실행해서 문구를 바꿔주고 있다. 이 과정을 바꾸는 방법에 대해서 고민해보자.

인자를 받아서 입력값 대로 출력하는 코드

우선 fortune 경로 안에 args 폴더를 만들고 sh 파일과 Docker 파일을 복사해서 가져온다.

cp ../fortuneloop.sh ./

cp ../Dockerfile ./

이후 loop 파일에서 sleep 10 을 인자를 받아 그 시간만큼 sleep 하도록 변경한다.

# fortuneloop.sh

#!/bin/bash

INTERVAL=$1

echo "Generate new fortune every $INTERVAL seconds"

mkdir -p /var/www
while true
do
    echo $(date) Wrting fortune to /var/www/index.html
    /usr/games/fortune > /var/www/index.html
    sleep $INTERVAL
done
# Dockerfile
FROM ubuntu:latest

RUN apt-get update && apt-get -y install fortune
ADD fortuneloop.sh /bin/fortuneloop.sh
RUN chmod +x /bin/fortuneloop.sh

ENTRYPOINT ["/bin/fortuneloop.sh"]
CMD ["2"]

이미지로 빌드해서 올리기

docker build -t ivaninitworld/fortune:args .
docker push ivaninitworld/fortune:args

yaml 파일로 파드 만들어서 돌리기

# fortune-pod-args.yaml
apiVersion: v1
kind: Pod
metadata:
  name: fortune3s
spec:
  containers:
  - name: html-generator
    image: ivaninitworld/fortune:args # 이미지
    args: ["3"] # 인자 값 넘겨주기
    volumeMounts: 
    - name: html
      mountPath: /var/www

  - name: web-server
    image: nginx:alpine
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
  volumes:
  - name: html
    emptyDir: {}
k create -f fortune-pod-args.yaml
k get po
k logs fortune3s

#
kimminhyeok@Ivans-Mac configmap % k logs fortune3s
Defaulted container "html-generator" out of: html-generator, web-server
Generate new fortune every 3 seconds
Tue Sep 5 04:14:35 UTC 2023 Wrting fortune to /var/www/index.html
Tue Sep 5 04:14:38 UTC 2023 Wrting fortune to /var/www/index.html
Tue Sep 5 04:14:41 UTC 2023 Wrting fortune to /var/www/index.html
...

환경변수에서 인자를 받아 출력하는 코드

직접 입력해주는 args 를 써도 되지만 환경변수에 박아두고 가져다 쓰는 경우도 있다.

args 에서 필요한 부분들을 복사로 가져와 수정해주자.

# fortuneloop.sh
#!/bin/bash

echo "Generate new fortune every $INTERVAL seconds"

mkdir -p /var/www
while true
do
    echo $(date) Wrting fortune to /var/www/index.html
    /usr/games/fortune > /var/www/index.html
    sleep $INTERVAL
done
# Dockerfile
FROM ubuntu:latest

RUN apt-get update && apt-get -y install fortune
ADD fortuneloop.sh /bin/fortuneloop.sh
RUN chmod +x /bin/fortuneloop.sh

ENTRYPOINT ["/bin/fortuneloop.sh"]
docker build -t ivaninitworld/fortune:env .
docker push ivaninitworld/fortune:env
# fortune-pod-evn.yaml
apiVersion: v1
kind: Pod
metadata:
  name: fortune30s
spec:
  containers:
  - name: html-generator
    image: ivaninitworld/fortune:env # 이미지
    env:
    - name: INTERVAL
      value: "30"
    volumeMounts: 
    - name: html
      mountPath: /var/www

  - name: web-server
    image: nginx:alpine
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
  volumes:
  - name: html
    emptyDir: {}
k create -f fortune-pod-env.yaml
k get po
k logs 
# result
kimminhyeok@Ivans-Mac configmap % k logs fortune30s
Defaulted container "html-generator" out of: html-generator, web-server
Generate new fortune every 30 seconds
Tue Sep 5 04:14:25 UTC 2023 Wrting fortune to /var/www/index.html
Tue Sep 5 04:14:55 UTC 2023 Wrting fortune to /var/www/index.html

 

 

728x90
반응형

댓글