본문 바로가기
  • 지요미의 IT성장일기
Kubernetes

쿠버네티스 2

by 지요미=P 2024. 2. 2.
728x90
도커허브에 접속이 안되는 이슈.
아무리 쿠버네티스 다운로드해도 도커허브의 정책이기 때문에 어쩔 수 없음.
nginx 구동 안되는 부분은 메모리부분을 늘려보도록 하쟈

 

centos7minimal.ova

 

도커 설치하기

# 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
# systemctl disable --now firewalld
# setenforce 0
# sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

# 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

 

 

쿠버네티스 설치하기

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

# yum -y install kubeadm-1.19.16-0 kubelet-1.19.16-0 kubectl-1.19.16-0 --disableexcludes=kubernetes
# systemctl enable --now kubelet
# poweroff

 


worker1,2,3 만들기

clone으로 만든 worker1

 

요롷게 만들어줌~!

 

# cat <<EOF >> /etc/hosts
172.25.0.156 master1
172.25.0.157 worker1
172.25.0.158 worker2
172.25.0.159 worker3
EOF
hostnamectl set-hostname master1 && exec bash
hostnamectl set-hostname worker1 && exec bash
hostnamectl set-hostname worker2 && exec bash
hostnamectl set-hostname worker3 && exec bash

 

--- Master ---

# kubeadm init --apiserver-advertise-address=172.25.0.156 --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
# kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# kubectl get pods --all-namespaces
# source <(kubectl completion bash)
# echo "source <(kubectl completion bash)" >> ~/.bashrc
# yum install -y bash-completion

# exit

 

 

kubeadm token create --print-join-command

kubeadm join 172.25.0.156:6443 --token is5pah.cln478gdk2aa5ihy     --discovery-token-ca-cert-hash sha256:176c6c8ba5fae76f8b94f34c9bd8c6ee8ec0e9349fb262924bd9eaed6193f6ec

 

 

--- Node ---
# kubeadm join 172.25.0.149:6443 --token r47zye.ye93ffmcm52769a9 \
    --discovery-token-ca-cert-hash sha256:50670fd667c74b723028c7a09dc40de3b0bd1b448a271947853689e32222909f

--- Master ---
# kubectl get nodes

 

k get no
k get po --all-namespaces

 

kubectl create secret docker-registry dockersecret --docker-username=<id> --docker-password=<password> --docker-email=<email>

 

kubectl run nginx-pod --image=nginx
kubectl get pod

pending > ContainerCreating > Running

 

kubectl get service

여기서 말하는 서비스는 네트워크 서비스!! 

외부에서 접속하기 위한 정보를 서비스라는 이름으로 제공해줌

CLUSTER-IP? 클러스터 안에서 서로 통신하기 위해서 있는 자체 IP임. 일종의 API로 자동으로 설정된다.

(클러스터 안? master1,worker1,2,3들을 묶어서 클러스터라고 함)

 

 

kubectl get service
kubectl get po -o wide
kubectl expose pod nginx-pod --name clusterip --type=ClusterIP --port 80

여기서 port 80은 컨테이너 앞단의 포트 = 누군가가 접근해오는 포트 번호

 

 

접속테스트!!!

cluster ip로 어떤 노드에 가도 모두 접속이 가능하다!!

 

 

 

 

클러스터 내부 접속 포트와 외부 접속 포트가 모두 8080이라면..?

 k expose pod nginx-pod --name clusterip8080 --type=ClusterIP --port 8080
 k describe svc clusterip8080

접속이 안됨....

 

외부도 접속이 안됨...

 

 

 

클러스터 ip의 특징!!!

포트번호가 같다고 하더라도 IP는 달라진다.

클러스터 IP가 자동으로 바뀌기 때문에 굳이 port번호를 바꿀 필요가 없다.

 

 

node port

kubectl expose pod nginx-pod --name nodeport --type=NodePort --port 80

80 : 클러스터의 포트

32493 : 외부에서 접근할 수 있는 포트

 

노드포트 = 클러스터 ip의 포트 + 노드포트

 

마스터 ip & worker ip 모두 접속이 가능함.

마스터가 죽더라도 워커들이 일한다는 것을 여기서도 볼 수 있다.

 

node port?

노드포트 = worker node's port

외부사용자가 들어올 수 있는 포트이다.

온프레미스에서는 이게 물리적 서버(예.컴퓨터)이다.

public cloud에서도 VM이다.

pod에도 포트가 있는데 이건 container port와 같게 설정이 됨

 

 

 

Loadbalancer

kubectlexpose pod nginx-pod --name loadbalancer-master --type LoadBalancer --external-ip 172.25.0.156 --port 80

클러스터 port 와 노드 port 두개 다 가지고 있음.

노드포트로는 사용자가 꼭 포트번호를 가지고 접속을 해야하는 불편함이 있는데 그런 불편함을 로드밸런서가 해결해준다.

 

접근방법이 3개가 된다.

1. 내부접근

2. 외부접근) master ip

2. 외부접근) master ip:31072

 

 

아래 그림과 같이 실습을 해보장

 

kubectl get pod
kubectl run test-pod --image=nginx
kubectl expose pod test-pod --name test-clusterip --type ClusterIP --port 80

첫번째 테스트 파드를 생성함!!

 

 

마스터에서 테스트를 해보고

마스터 복제해서.. 상태를 확인해보자.

kubectl get pod
kubectl exec -it test-pod -- bash

 

nginx 클러스터 ip로 접근이 가능하다.

 

파드 안에서도 바깥에 있는 다른 파드와 연결이 되는 것을 확인할 수 있었음!!

그런데 파드의 ip는 바뀔 수 있으니 클러스터 ip를 사용하는 것이 좋다.

 

 

노드의 IP는 cluster의 IP가 아니다.

 

node ip -> cluster ip -> endpoint ip -> container ports

 

 

node ip를 통해서 외부에서 들어오지만 cluster ip를 거쳐야만 내부로 접속이 가능한 것이다.

이해가나요?!

 

mkdir html
mkdir html/images
kubectl cp html nginx-pod:/usr/share/nginx

 

 

파드 지우기

k delete po test-pod
k delete pod nginx-pod --grace-period 0 --force

 

서비스 지우기

k delete svc --all
k get svc

서비스는 아무리 모두 지운다고 하더라도 필요한 서비스는 즉시 다시 생기는 특징이 있다.

 

 

kubectl 옵션들~

kubectl options
kubectl api-resources
kubectl get nodes -o wide
kubectl get nodes -o wide --no-headers
kubectl get nodes -o wide --no-headers | awk '{print $6}'

 

 

task를 2개 이상 만들 때

kubectl create deployment nginx-app --replicas=2 --image=nginx
kubectl get deployments.apps
kubectl get replicasets.apps
kubectl get pods

 


파드 삭제

k get po -o wide
k delete po nginx-app-d6ff45774-hhq99

 

kubectl edit sa default
imagePullSecrets:
- name: dockersecret

 

kubectl expose deployment nginx-app --name clusterip-app --type=ClusterIP --port 80
k get -o wide
k exec -it nginx-app-d6ff45774-gz6gz -- bash
echo "<h1>pod1</h1>" > /usr/share/nginx/html/index.html
echo "<h1>pod2</h1>" > /usr/share/nginx/html/index.html
exit
k get svc
curl 10.107.80.106

 

 

 kubectl expose deployment nginx-app --name nodeport-app --type=NodePort --port 80

워커들에 포트가 열려있는 것을 확인할 수 있당

 

worker2의 ip 넣어서 로드밸런서

kubectl expose deployment nginx-app --name loadbalancer-app --type=LoadBalancer --external-ip 172.25.0.158 --port 80

 

 

만약, external-ip를 넣지 않고 로드밸런서를 한다면? 

 kubectl expose deployment nginx-app --name loadbalancer-app2 --type=LoadBalancer --port 80
 k get svc

퍼블릭 ip 부여가 됨

우리가 꾸며놓은 것은 자동으로 ip를 줄 수가 없다.

외부ip를 자동으로 부여해주는 거는 cloud-controller-ip임.

추후에 배울 metallb에서 넣어줄 수 있다. 

기본적으로는 외부ip를 설정하는 기능이 제공되지 않기 때문에 pending이 된다.

 

kubectl edit svc loadbalancer-app
kubectl edit svc loadbalancer-app2

kubectl edit svc loadbalancer-app

 

kubectl edit svc loadbalancer-app2 으로 접근해서 위에서 복사한 externalIPs를 삽입해 넣어주었다.

놀랍게도 pending상태였던 external-ip가 지정되었다!!

 

이렇다구~!

 

 

scale in/out

kubectl scale deployment nginx-app --replicas=3
k get pod -o wide
kubectl scale deployment nginx-app --replicas=2
k get pod -o wide

 


모두 지우기!

아까 선언했던  kubectl get replicasets.apps 때문에 pod는 지워도 다시 생길 것이다.

k delete deploy,svc --all
k get svc

+서비스는 지워도 필수 서비스는 어차피 다시 생기니 걱정 nonononono~

 

 

--- 템플릿으로 컨테이너 실행하기--- 

# mkdir test && cd $_
# vi nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx-pod
spec:
  containers:
  - name: nginx-pod-container
    image: nginx
    ports:
    - containerPort: 8080 # 별도 지정된 포트가 없다면 8080으로 지정하라 (docker -P 유사)
  imagePullSecrets:
  - name: dockersecret
  
# kubectl apply -f nginx-pod.yaml

 

-> pod ip로 접속이 가능함!!!

 

cluster ip 꾸며보기

# vi clusterip-pod.yaml
apiVersion: v1
kind: Service
metadata:
  name: clusterip-pod
spec:
  type: ClusterIP
  selector:
    app: nginx-pod
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

# kubectl apply -f clusterip-pod.yaml
# kubectl get svc -o wide

 

내가 설정했던 컨테이너 정보는 여기에 없당..

접속까지 완료!

 

 

포트정보와 파트정보가 모두 80임

endpoint의 포트정보도 80임

이 정보를 한번 변경해보자..

# kubectl describe svc clusterip-pod
# kubectl edit svc clusterip-pod

 

 

 

 

이번엔 타겟포트를 8080으로 변경해보았음.

 

 

curl 10.107.192.186:88로 통신 X

 

 

but....

클러스터 포트가 80이라면 정의할 필요가 없는데

8080으로 바뀌게 되면 그것이 타겟포트가 정해져있지 않으면 8080포트가 타겟포트가 되기 때문에 지정해주어야 함.

port(=cluster port)가 80포트가 아닌 포트라면 무조건 포트를 지정해주어야 함.

 

 

# vi nodeport-pod.yaml
apiVersion: v1
kind: Service
metadata:
  name: nodeport-pod
spec:
  type: NodePort
  selector:
    app: nginx-pod
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30080

노드포트는 내가 임의로 지정할 수 있다.

30000-32767 안에서!

 

 

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

 

노드포트 부분을 변경해볼까?

vi nodeport-pod.yaml
k apply -f nodeport-pod.yaml

vi nodeport-pod.yaml

 

 

node port 범위 밖의 port로 지정한다면?

kubectl edit svc nodeport-pod

범위가 아니라서 자동으로 수정이 안된다.

 

# vi loadbalancer-pod.yaml
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-pod
spec:
  type: LoadBalancer
  externalIPs:
  - 172.25.0.156
  - 172.25.0.157
  - 172.25.0.158
  - 172.25.0.159
  selector:
    app: nginx-pod
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 80
    nodePort: 32767

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


* 타겟포트 = 컨테이너 포트

타겟포트를 지운다면 자동으로 포트번호와 동일하게 지정될 것임.

타겟포트를 변경하고 싶으면 타겟포트를 지금 지정해주어야 함.

 

* 노드포트도 지정해주지 않으면 랜덤으로 지정을 받게 된당.

 

접속테스트

156 157 158 159 모두 접속 완료!

 

 

728x90

'Kubernetes' 카테고리의 다른 글

Kubernetes-volume  (1) 2024.02.19
쿠버네티스- MetalLB  (0) 2024.02.19
쿠버네티스 3  (0) 2024.02.05
쿠버네티스 1  (0) 2024.02.01
쿠버네티스란?  (0) 2024.02.01