본문 바로가기

메가존 클라우드 2기 교육/실무 특화

Kubernetes - CLI, 템플릿, 멀티 노드, 멀티 컨테이너

Kubernetes

VM 세팅



master1, worker1, worker2 총 3개의 VM을 준비.

 세 VM의 맥 주소를 확인해서 기존 아이피와 겹치지 않도록 해준다


## 생성한 세 개의 VM에 모두 적용
# MobaXterm에서 세팅 
yum update -y

# 각자 호스트 네임 설정
hostnamectl set-hostname [각자의 이름]

# 호스트에 아이피 정보 입력
cat <<EOF >> /etc/hosts
192.168.2.95 master1
192.168.2.76 worker1
192.168.2.82 worker2
EOF

# 도커 설치
curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo
sed -i -e "s/enabled=1/enabled=0/g" /etc/yum.repos.d/docker-ce.repo
yum --enablerepo=docker-ce-stable -y install docker-ce-19.03.15-3.el7
mkdir /etc/docker

cat <<EOF | sudo tee /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

# 설정 세팅
systemctl enable --now docker
systemctl daemon-reload
systemctl restart docker
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

## 스왑 기능 비활성화 (쿠버네티스 설치에 필수)
# Swap 기능은 본래 가용된 메모리보다 더 큰 메모리 할당을 가능하도록 하기 위함인데,
# 쿠버네티스는 주어진 인스턴스의 자원을 100% 최대한 사용하는 것이 목표이다.
# 그러므로 스왑 메모리를 켜놓으면 인스턴스 자원이 일관되지 않아 쿠버네티스의 목표에 부합되지 않기 때문.
swapoff -a
sed -i '/ swap / s/^/#/' /etc/fstab

# 쿠버네티스에 브리지 기능 활성화
cat <<EOF > /etc/sysctl.d/k8s.conf # kubernetes
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

# 커널에 적용
sysctl --system
reboot

Kubeadm 설치 (Multi Node: Master Node, Worker Node)

# 쿠버네티스 리포지토리 정보 입력
cat <<'EOF' > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

# kubeadm, kubelet, kubectl 설치
yum -y install kubeadm-1.19.16-0 kubelet-1.19.16-0 kubectl-1.19.16-0 --disableexcludes=kubernetes

systemctl enable kubelet
poweroff
각각의 VM에서 설치한 환경을 스냅샷으로 남겨준다.

Master Node

# 마스터 노드 init 
kubeadm init --apiserver-advertise-address=192.168.2.95 --pod-network-cidr=10.244.0.0/16

# 자격증명
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

# 사이트로부터 kube-flannel.yml 파일을 가져와서 파드를 생성
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

# 자동 완성 설치(자동시작도 함께)
yum install -y bash-completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

# 재시작
exit

# 자동 완성 확인
kubectl get pods --all-namespaces
init에 성공하면 자격증명과 키가 출력된다.

 Worker Node

# 워커 노드에 위에서 발급받은 키 입력
kubeadm join 192.168.2.95:6443 --token b2shwr.lggzpgfjvgelgtk9 \
    --discovery-token-ca-cert-hash sha256:26b0ceb68bab02ffb1ab60f1cc15c15c1e509fcbea3b9eb72f8bdc068aa81434

# 마스터 노드에서 노드 상태 확인
kubectl get nodes

모든 노드가 'Ready' 상태여야 한다.

Kubernetes - CLI

기본 사용법

# 폴더 생성 후 이동
mkdir workspace && cd $_

# kubectl [명령어] [유형] [자원 이름] [옵션]

# 네임스페이스 생성
kubectl create namespace kyounggu

# 노드 확인
kubectl get node

# 파드 생성 ('-n': namespace)
kubectl run nginx-pod -n kyounggu --image=kyounggu/web-site:aws
kubectl run nginx-pod2 -n kyounggu --image=kyounggu/web-site:aws
노드 확인.

파드 생성 확인
네임 스페이스에 2개의 노드(worker1, worker2)가 생겼다

# 클러스터 아이피 추가
kubectl expose pod nginx-pod -n kyounggu --name clusterip --type ClusterIP --port 80

# 해당 네임스페이스의 서비스 확인
kubectl get svc -n kyounggu
클러스터 아이피. 클러스터 안(내부)에서만 접속 가능

# 노드 포트 추가
kubectl expose pod nginx-pod -n kyounggu  --name nodeport --type NodePort --port 80
노드 포트 아이피.
'워커1아이피:노드포트' 로 접속 가능
'워커2아이피:노드포트' 로 접속 가능
'마스터1아이피:노드포트' 로 접속 가능

 이처럼, 노드포트는 아무 노드의 아이피에 노드 포트를 통해 외부에서 접속이 가능하게 해준다.


# 로드 밸런서 추가
kubectl expose pod nginx-pod -n kyounggu --name loadbalancer --type LoadBalancer --external-ip [마스터1 아이피] --port 80
로드 밸런서 아이피.


## 현재 context의 namespace 수정 방법 (매번 명령어마다 namespace를 입력하지 않아도 되게 해준다.) 
# 현재 context 확인
kubectl config current-context

# context 정보 확인
kubectl config get-contexts kubernetes-admin@kubernetes

# namespace 정보 확인
kubectl get ns kyounggu

# context의 namespace 수정
kubectl config set-context kubernetes-admin@kubernetes --namespace kyounggu

네임 스페이스 변경 완료.
네임스페이스가 'kyounggu'로 고정되어 있으므로, 서비스 확인을 하면 자동으로 'kyounggu' 네임스페이스의 서비스 목록을 가져온다.
반대로 기본으로 뜨던 서비스는 'default'네임스페이스로 해야 나온다.

# 워커1 접속
kubectl exec -it nginx-pod nginx-pod

# 워커2 접속
kubectl exec -it nginx-pod2 nginx-pod

# 테스트를 위해 워커1,2의 웹페이지 수정
//nginx
kubectl exec -it nginx-pod -- sh -c 'echo "<h1>web01</h1>" > /usr/share/nginx/html/index.html'
kubectl exec -it nginx-pod2 -- sh -c 'echo "<h1>web02</h1>" > /usr/share/nginx/html/index.html'
//apache
kubectl exec -it nginx-pod -- sh -c 'echo "<h1>web01</h1>" > /var/www/html/index.html'
kubectl exec -it nginx-pod2 -- sh -c 'echo "<h1>web02</h1>" > /var/www/html/index.html'

# 로드 밸런서 수정
kubectl edit svc loadbalancer
// selector의 라벨 부분 변경
    run: nginx-pod2
//

웹페이지를 수정하고 'master1'의 아이피로 접속

로드밸런서의 selector를 pod2(worker2)로 변경
셀렉터의 라벨에 맞는 파드로 연결된다.(worker2)

 


템플릿으로 Service

nginx-pod

# nginx-pod 템플릿 생성
vi nginx-pod.yaml
//
apiVersion: v1
kind: Pod
metadata:
  namespace: kyounggu
  name: nginx-pod
  labels:
    app: nginx-pod
spec:
  containers:
  - name: nginx-pod-container
    image: nginx
    ports:
    - containerPort: 8080
//

# kubectl apply -f nginx-pod.yaml
## 중복된 이름이 있을 경우 삭제한다. kubectl delete all --all

# 포트 번호를 생략하면, nginx-pod의 템플릿의 컨테이너 포트를 따라간다 (8080)
kubectl expose pod nginx-pod --name clusterip --type ClusterIP

# 다시 삭제
kubectl delete svc clusterip
포트 번호를 생략하면, 컨테이너 포트를 사용한다.

clusterip-pod

# clusterip-pod 템플릿 작성
vi clusterip-pod.yaml
//
apiVersion: v1
kind: Service
metadata:
  name: clusterip-pod
spec:
  type: ClusterIP
#  externalIPs:
#  - 192.168.56.101
  selector:
    app: nginx-pod
  ports:
  - protocol: TCP
    port: 80  # 변경이 되면 밑에 타겟포트를 80포트로 지정해야 한다.
#    targetPort: 80
//
## port:80/targetport:x (o)
## port:8080/targetport:x (x)
## port:8080/targetport:80 (o)

# kubectl apply -f clusterip-pod.yaml
# kubectl get svc -o wide
# kubectl describe svc clusterip-service-pod
# kubectl edit svc clusterip-service-pod
외부 아이피와 타겟 그룹을 따로 지정하지 않아도 접속 가능.
CLI와 달리 라벨을 따로 지정하지 않았다.

nodeport-pod

# nodeport-pod 템플릿 작성 
vi nodeport-pod.yaml
//
apiVersion: v1
kind: Service
metadata:
  name: nodeport-service-pod
spec:
  type: NodePort
  selector:
    app: nginx-pod
  ports:
  - name: http-port
    protocol: TCP
    port: 6789
    targetPort: 80 # 컨테이너 포트가 맞다.
    nodePort: 30080
//

# kubectl apply -f nodeport-pod.yaml
# kubectl get svc -o wide
# kubectl describe svc nodeport-service-pod
# kubectl edit svc nodeport-service-pod

loadbalancer-pod

# loadbalancer-pod 템플릿 작성
vi loadbalancer-pod.yaml
//
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service-pod
  labels:   # metadata에 서비스의 라벨을 붙여줄 수도 있다.
    svc: nignx-pod-slb
spec:
  type: LoadBalancer
  externalIPs:
  - [마스터1 아이피]
  - [워커1 아이피]
  - [워커2 아이피]
  selector:
    app: nginx-pod
  ports:
  - protocol: TCP
    port: 7890	# -p 7890:80	
    targetPort: 80
//

# kubectl apply -f loadbalancer-pod.yaml
# kubectl get svc -o wide
# kubectl describe svc loadbalancer-service-pod
7890포트로만 접속 가능.

 


ReplicaSet

replicaset

# replicaset 템플릿 작성
vi replicaset.yaml
//
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset
  labels:
    app: replicaset
spec:
  replicas: 3 # desired state (kube-controller-manager)
  selector:
    matchLabels:
      app: nginx-replicaset

  template:
    metadata:
      name: nginx-replicaset
      labels:
        app: nginx-replicaset
    spec:
      containers:
      - name: nginx-replicaset-container
        image: nginx
        ports:
        - containerPort: 80
          name: 
//

# kubectl apply -f replicaset.yaml
# kubectl get replicasets.apps -o wide
# kubectl describe replicasets.apps nginx-replicaset

 

레플리카셋으로 만들어진 3개의 파드

clusterip-replicaset

# clusterip-replicaset 템플릿 생성
vi clusterip-replicaset.yaml
//
apiVersion: v1
kind: Service
metadata:
  name: clusterip-service-replicaset
spec:
  type: ClusterIP
  selector:
    app: nginx-replicaset
  ports:
  - protocol: TCP
    port: 20080
    targetPort: http-web-svc	# 포트 번호가 아닌 라벨로도 가능
//

# kubectl apply -f clusterip-replicaset.yaml
# kubectl get svc -o wide
# kubectl describe svc clusterip-service-replicaset

nodeport-replicaset

# nodeport-replicaset 템플릿 생성
vi nodeport-replicaset.yaml
//
apiVersion: v1
kind: Service
metadata:
  name: nodeport-service-replicaset
spec:
  type: NodePort
  externalIPs:      # 노드 포트는 안됨
  - 192.168.2.95
  - 192.168.2.76
  - 192.168.2.82
  selector:
    app: nginx-replicaset
  ports:
  - protocol: TCP
    port: 10080
    targetPort: http-web-svc
    nodePort: 32080
//

# kubectl apply -f nodeport-replicaset.yaml
# kubectl get svc -o wide
# kubectl describe svc nodeport-service-replicaset

# clusterip-pod에 외부 아이피 추가
vi clusterip-pod.yaml
// 다음 항목을 spec에 추가
  externalIPs:
  - 192.168.2.95
  - 192.168.2.76
  - 192.168.2.82
//

# clusterip-service-replicaset에 외부 아이피 추가
kubectl edit svc clusterip-service-replicaset
// 다음 항목을 spec에 추가
  externalIPs:
  - 192.168.2.95
  - 192.168.2.76
  - 192.168.2.82
//
이렇게 되도록 수정

loadbalancer-replicaset

# loadbalancer-replicaset 템플릿 생성
vi loadbalancer-replicaset.yaml
//
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service-replicaset
spec:
  type: LoadBalancer
  externalIPs:
  - 192.168.2.95
  - 192.168.2.76
  - 192.168.2.82
  selector:
    app: nginx-replicaset
  ports:
  - protocol: TCP
    port: 8080
    targetPort: http-web-svc
//

# kubectl apply -f loadbalancer-replicaset.yaml
# kubectl get svc -o wide
# kubectl describe svc loadbalancer-service-replicaset

 

 

Deployment

deployment

# deployment 템플릿 작성
vi deployment.yaml
//
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx-deployment

  template:
    metadata:
      name: nginx-deployment
      labels:
        app: nginx-deployment
    spec:
      containers:
      - name: nginx-deployment-container
        image: kyounggu/web-site:aws
        ports:
        - containerPort: 80
//

# kubectl apply -f deployment.yaml
# kubectl get deployments.apps -o wide
# kubectl describe deployments.apps nginx-deployment
디플로이먼트 확인.
디플로이먼트가 생성됨에 따라 레플리카셋도 따라 생긴다.
4개의 파드도 생성된다.

clusterip-deployment

# clusterip-deployment 템플릿 생성
vi clusterip-deployment.yaml
//
apiVersion: v1
kind: Service
metadata:
  name: clusterip-service-deployment
spec:
  type: ClusterIP
  externalIPs:
  - 192.168.2.95	# 클러스터 아이피 하나만
  selector:
    app: nginx-deployment
  ports:
  - protocol: TCP
    port: 81
    targetPort: 80
//

# kubectl apply -f clusterip-deployment.yaml
# kubectl get svc -o wide
# kubectl describe svc clusterip-service-deployment
노드 포트에도 외부 아이피를 매핑해주면 외부 아이피로 접속 가능.

nodeport-deployment

# nodeport-deployment 템플릿 생성
vi nodeport-deployment.yaml
//
apiVersion: v1
kind: Service
metadata:
  name: nodeport-service-deployment
spec:
  type: NodePort
  selector:
    app: nginx-deployment
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30080
//

# kubectl apply -f nodeport-deployment.yaml
# kubectl get svc -o wide
# kubectl describe svc nodeport-service-deployment

새로 생성하지 않고 기존의 서비스를 재활용하여 사용할 수도 있다.

# 기존 노드 포트 서비스의 셀럭터 라벨 변경
kubectl edit svc nodeport-service-pod
// selector의 app을 변경
  selector:
    app: nginx-deployment
//

loadbalancer-replicaset

## 해당 과정은 생략했음
# vi loadbalancer-replicaset.yaml # 로드밸런서 야믈
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service-replicaset
spec:
  type: LoadBalancer
  externalIPs:
  - 192.168.1.188
  - 192.168.1.211
  - 192.168.1.216
  selector:
    app: nginx-replicaset
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

# kubectl apply -f loadbalancer-replicaset.yaml
# kubectl get svc -o wide
# kubectl describe svc loadbalancer-service-replicaset

 


삭제 및 변경

원할한 테스트를 위해 deployment를 제외한 모든 것들을 제거 

# 파드 삭제 ('--grace-period': 정상 종료 시간. 즉 0은 바로 종료, '--force': 강제)
kubectl delete pod --grace-period 0 --force nginx-pod

# 레플리카셋 삭제
kubectl delete rs nginx-replicaset

# 현재 4개의 scale을 5개로 증가
kubectl scale --current-replicas=4 --replicas=5 deployment/nginx-deployment

# 현재 값을 몰라도 무방하다.
kubectl scale --replicas=6 deployment/nginx-deployment

# scale in도 가능
kubectl scale --replicas=4 deployment/nginx-deployment
워커들에게 균등하게 배치된다.
Scale In

Deployment 롤링 업데이트 제어

# 이미지 변경
kubectl set image deployment.apps/nginx-deployment nginx-deployment-container=halilinux/web-site:v1.0

# 다시 이미지 변경
kubectl set image deployment/nginx-deployment nginx-deployment-container=nginx

# 히스토리 확인
kubectl rollout history deployment nginx-deployment

# 히스토리의 리비전 정보 확인
kubectl rollout history deployment nginx-deployment --revision 2 # 리비전2 상세보기

# 롤백(전 단계로 복원)
kubectl rollout undo deployment nginx-deployment

# 롤백(원하는 리비전으로 복원)
kubectl rollout undo deployment nginx-deployment --to-revision 1 # 리비전2로 복원
현재 deployment의 이름을 사용한다.
이미지를 변경하면 하나씩 종료하고 새로 생성하여 이미지를 변경한다.

81번 포트로 접속.
이미지가 변경되어 웹사이트도 변경됐다.

다시 이미지 변경.

히스토리
리비전 상세 정보
직전으로 롤백
2번이 4번으로 이동

1번이 5번으로 이동

 


멀티 컨테이너

VM설정

worker1, 2, docker의 메모리를 2048MB, 프로세서 개수를 1개로 줄인다.


초기화

## docker에 만일 남아있는 컨테이너, 이미지가 있으면 삭제
# 컨테이너 확인
docker ps -a

# 컨테이너 삭제
docker rm -f [컨테이너 이름]

# 이미지 확인
docker images

# 이미지 삭제
docker rmi -f [이미지 이름]

사설 레지스트리 이용

# docker에서 사설 레지스트리 컨테이너 생성 (자동 시작)
docker run -d -p 5000:5000 --restart=always --name private-docker-registry registry

# worker1,2, master1에서 도커 데몬 설정 수정
vi /etc/docker/daemon.json
//
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "insecure-registries":["docker 아이피:5000"]
}
//

# 도커 재시작
systemctl restart docker

# 태그를 달고 이미지 전송
//nginx (worker1)에서
docker tag nginx:latest 192.168.1.158:5000/nginx:latest
docker push 192.168.1.158:5000/nginx:latest
//aws   (worker2)에서
docker tag kyounggu/web-site:was 192.168.1.158:5000/web-site:aws
docker push 192.168.1.158:5000/web-site:aws
//food  (worker3)에서
docker tag kyounggu/web-site:food 192.168.1.158:5000/web-site:food
docker push 192.168.1.158:5000/web-site:food

# 사설 레지스트리의 이미지를 확인하는 방법
curl -X GET http://192.168.1.158:5000/v2/_catalog

# 사설 레지스트리의 해당 이미지의 태그 확인
curl -X GET http://192.168.1.158:5000/v2/nginx/tags/list
전송하는 모습
사설 레지스트리에서의 조회

miltipod

# master1, worker1, 2에서 도커 로그인
docker login
----------
# master1에서 폴더 이동
cd workspace

# master에서 multipod 템플릿 생성 (사설 레지스트리 사용)
vi multipod.yaml
//
apiVersion: v1
kind: Pod
metadata:
  name: multipod
spec:
  containers:
  - name: nginx-container        #1번째 컨테이너
    image: 192.168.1.158:5000/nginx:latest
    ports:
    - containerPort: 80
  - name: centos-container       #2번째 컨테이너
    image: 192.168.1.158:5000/centos:7
    command:
    - sleep
    - "10000"
//

# 사설 레지스트리에 이미지 전송
docker tag centos:7 192.168.1.158:5000/centos:7
docker push 192.168.1.158:5000/centos:7

# kubectl apply -f multipod.yaml

# 멀티 파드에 접속 (첫번째 컨테이너로 접속됨)
kubectl exec -it multipod -- bash

# 현재 접속중인 컨테이너 정보 확인
cat /etc/os-release

# 나오기
exit
-----------
# 원하는 컨테이너로 접속 ( '-c': connect 명령어에 컨테이너 이름)
kubectl exec -it multipod -c centos-container -- bash

# 현재 접속중인 컨테이너 정보 확인
cat /etc/os-release
debian이므로 현재 nginx이다. 즉 1번째 컨테이너
centos7이므로 2번째 컨테이너가 맞다.

centos7에서 'curl 127.0.0.1'을 타이핑하면 nginx가 뜬다. 즉, 서로 통신 중이다.
또한 'multipod'로 핑이 찍힌다. 즉, 도메인 처럼 사용 가능.(같은 파드 내에서만)
curl도 마찬가지

 


멀티 컨테이너 - wordpress

사설 저장소를 이용해 워드프레스 구축

# master1에서 mysql5.7 내려받기
docker pull mysql:5.7

# 저장소에 mysql5.7 업로드
docker tag mysql:5.7 192.168.1.158:5000/mysql:5.7
docker push 192.168.1.158:5000/mysql:5.7

# 최신 버전의 워드프레스 내려받기
docker pull wordpress

# 저장소에 워드프레스 업로드
docker tag wordpress:latest 192.168.1.158:5000/wordpress:latest
docker push 192.168.1.158:5000/wordpress:latest

# wp-multi-container 템플릿 생성
vi wp-multi-container.yaml
//
apiVersion: v1
kind: Pod
metadata:
  name: wordpress-pod
  labels:
    app: wordpress-pod
spec:
  containers:
  - name: mysql-container
    image: 192.168.1.158:5000/mysql:5.7
    env:
    - name: MYSQL_ROOT_HOST
      value: '%' # wpuser@%
    - name: MYSQL_ROOT_PASSWORD
      value: mode1752
    - name: MYSQL_DATABASE
      value: wordpress
    - name: MYSQL_USER
      value: wpuser
    - name: MYSQL_PASSWORD
      value: wppass
    ports:
    - containerPort: 3306
  - name: wordpress-container
    image: 192.168.1.158:5000/wordpress
    env:
    - name: WORDPRESS_DB_HOST
      value: wordpress-pod:3306
    - name: WORDPRESS_DB_USER
      value: wpuser
    - name: WORDPRESS_DB_PASSWORD
      value: wppass 
    - name: WORDPRESS_DB_NAME
      value: wordpress
    ports:
    - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service-deployment-wordpress
spec:
  type: LoadBalancer
  externalIPs:
  - 192.168.2.95
  selector:
    app: wordpress-pod
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
//

# 만일 파드 중에서 80포트를 사용하는 것이 있다면 externalIP 삭제
# kubectl edit svc clusterip-pod

# kubectl apply -f wp-multi-container.yaml
80포트 충돌을 피하기 위해, externalIP 제거

 

생성 완료.
생성된 로드밸런서의 주소로 접속(80포트)
접속 결과. 워드프레스 설치가 다 된 것을 알 수 있다. (환경 변수로 미리 설정을 해서 언어만 설정하면 된다.)
테스트를 위해 댓글을 달아본다.

# HeidiSQL을 쓰기 위해 3306 포트도 추가
vi wp-multi-container.yaml
// 로드밸런스 서비스 부분의 포트를 다음과 같이 수정
  ports:
  - name: web-port
    protocol: TCP
    port: 80
    targetPort: 80
  - name: db-port
    protocol: TCP
    port: 3306
    targetPort: 3306
//

# 변경사항 적용
kubectl apply -f wp-multi-container.yaml
작성했던 댓글 'Hello'를 확인 가능
새로운 댓글도 즉각적으로 반영된다.

# ClusterIP의 외부 아이피에 워커1을 추가하고 3306포트 개방, 셀렉터 변경
# 워커1을 통해 DB에 접속하기 위해
kubectl edit svc clusterip-pod
// 다음 항목을 수정
spec:
  clusterIP: 10.104.122.251
  externalIPs:
  - 192.168.2.76
  ports:
  - name: web-port
    port: 80
    protocol: TCP
    targetPort: 80
  - name: db-port
    port: 3306
    protocol: TCP
    targetPort: 3306
  selector:
    app: wordpress-pod
//
워커1의 아이피와 3306포트가 열린 것을 확인
똑같이 접속 가능