kubeadm 이용 Ubuntu 20.04에 Kubernetes 클러스터 설치

Kubernetes는 온프레미스 서버 또는 하이브리드 클라우드 환경에서 대규모로 컨테이너화된 애플리케이션을 오케스트레이션 및 관리하기 위한 도구입니다. Kubeadm은 사용자가 모범 사례 시행을 통해 프로덕션 준비 Kubernetes 클러스터를 설치할 수 있도록 Kubernetes와 함께 제공되는 도구입니다. 이 튜토리얼은 kubeadm을 사용하여 Ubuntu 20.04에 Kubernetes 클러스터를 설치하는 방법을 보여줍니다.

Kubernetes 클러스터 배포에는 두 가지 서버 유형이 사용됩니다.

  • 마스터 : Kubernetes 마스터는 Kubernetes 클러스터의 포드, 복제 컨트롤러, 서비스, 노드 및 기타 구성 요소에 대한 제어 API 호출이 실행되는 곳입니다.
  • Node : Node는 컨테이너에 런타임 환경을 제공하는 시스템입니다. 컨테이너 포드 세트는 여러 노드에 걸쳐 있을 수 있습니다.

실행 가능한 설정을 위한 최소 요구 사항은 다음과 같습니다.

  • 메모리: 컴퓨터당 2GiB 이상의 RAM
  • CPU: 컨트롤 플레인 머신에 최소 2개의 CPU 가 있습니다.
  • 컨테이너 풀링을 위한 인터넷 연결 필요(개인 레지스트리도 사용할 수 있음)
  • 클러스터의 머신 간 전체 네트워크 연결 – 개인 또는 공용입니다.

Ubuntu 20.04에 Kubernetes 클러스터 설치

My Lab 설정에는 3개의 서버가 있습니다. 컨테이너화된 워크로드를 실행하는 데 사용할 하나의 컨트롤 플레인 머신과 두 개의 노드. 예를 들어 HA용 제어 평면 노드 3개 를 사용하여 원하는 사용 사례 및 부하에 맞게 노드를 더 추가할 수 있습니다 .

서버 유형 서버 호스트 이름 명세서
주인 k8s-master01.computingforgeeks.com 4GB 램, 2vcpus
노동자 k8s-worker01.computingforgeeks.com 4GB 램, 2vcpus
노동자 k8s-worker02.computingforgeeks.com 4GB 램, 2vcpus

1단계: Kubernetes 서버 설치

Ubuntu 20.04에서 Kubernetes 배포에 사용할 서버를 프로비저닝합니다. 설정 프로세스는 사용 중인 가상화 또는 클라우드 환경에 따라 다릅니다.

서버가 준비되면 업데이트하십시오.

sudo apt update
sudo apt -y upgrade && sudo systemctl reboot

2단계: kubelet, beadm 및 kubectl 설치

서버가 재부팅되면 Ubuntu 20.04용 Kubernetes 저장소를 모든 서버에 추가하십시오.

sudo apt update
sudo apt -y install curl apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

그런 다음 필요한 패키지를 설치합니다.

sudo apt update
sudo apt -y install vim git curl wget kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

kubectl 버전을 확인하여 설치를 확인합니다.

$ kubectl version --client && kubeadm version
Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.2", GitCommit:"8b5a19147530eaac9476b0ab82980b4088bbc1b2", GitTreeState:"clean", BuildDate:"2021-09-15T21:38:50Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}
kubeadm version: &version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.2", GitCommit:"8b5a19147530eaac9476b0ab82980b4088bbc1b2", GitTreeState:"clean", BuildDate:"2021-09-15T21:37:34Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}

3단계: 스왑 비활성화

스왑과 방화벽을 끕니다.

sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
sudo swapoff -a
sudo ufw disable

crontab -e
@reboot sudo swapoff -a 

커널 모듈을 활성화하고 sysctl을 구성합니다.

# Enable kernel modules
sudo modprobe overlay
sudo modprobe br_netfilter

# Add some settings to sysctl
sudo tee /etc/sysctl.d/kubernetes.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

# Reload sysctl
sudo sysctl --system

4단계: 컨테이너 런타임 설치

Pod에서 컨테이너를 실행하기 위해 Kubernetes는 컨테이너 런타임을 사용합니다. 지원되는 컨테이너 런타임은 다음과 같습니다.

  • 도커
  • CRI-O
  • 컨테이너

참고 : 한 번에 하나의 런타임을 선택해야 합니다 .

도커 런타임 설치:

# Add repo and Install packages
sudo apt update
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

sudo apt update
sudo apt install -y containerd.io docker-ce docker-ce-cli

# Create required directories
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo mkdir -p /etc/docker

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

# Start and enable Services
sudo systemctl daemon-reload 
sudo systemctl restart docker
sudo systemctl enable docker

CRI-O 설치:

# Ensure you load modules
sudo modprobe overlay
sudo modprobe br_netfilter

# Set up required sysctl params
sudo tee /etc/sysctl.d/kubernetes.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

# Reload sysctl
sudo sysctl --system

# Add Cri-o repo
sudo su -
OS="xUbuntu_20.04"
VERSION=1.22
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list
curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/Release.key | apt-key add -
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | apt-key add -

# Update CRI-O CIDR subnet
sudo sed -i 's/10.85.0.0/192.168.0.0/g' /etc/cni/net.d/100-crio-bridge.conf

# Install CRI-O
sudo apt update
sudo apt install cri-o cri-o-runc

# Start and enable Service
sudo systemctl daemon-reload
sudo systemctl restart crio
sudo systemctl enable crio
sudo systemctl status crio

컨테이너 설치:

# Configure persistent loading of modules
sudo tee /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF

# Load at runtime
sudo modprobe overlay
sudo modprobe br_netfilter

# Ensure sysctl params are set
sudo tee /etc/sysctl.d/kubernetes.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

# Reload configs
sudo sysctl --system

# Install required packages
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates

# Add Docker repo
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

# Install containerd
sudo apt update
sudo apt install -y containerd.io

# Configure containerd and start service
sudo su -
mkdir -p /etc/containerd
containerd config default>/etc/containerd/config.toml

# restart containerd
sudo systemctl restart containerd
sudo systemctl enable containerd
systemctl status  containerd

 cgroup 드라이버 설치

systemd cgroup 드라이버를 사용하려면 에서 plugins.cri.systemd_cgroup = true 를 설정 /etc/containerd/config.toml하십시오. kubeadm을 사용할 때 kubelet 용 cgroup 드라이버를 수동으로 구성하십시오.

5단계: 마스터 노드 초기화

마스터로 사용할 서버에 로그인하고 br_netfilter 모듈이 로드되었는지 확인합니다.

$ lsmod | grep br_netfilter
br_netfilter           22256  0 
bridge                151336  2 br_netfilter,ebtable_broute

컨테이너 이미지 가져오기:

$ sudo kubeadm config images pull
[config/images] Pulled k8s.gcr.io/kube-apiserver:v1.22.2
[config/images] Pulled k8s.gcr.io/kube-controller-manager:v1.22.2
[config/images] Pulled k8s.gcr.io/kube-scheduler:v1.22.2
[config/images] Pulled k8s.gcr.io/kube-proxy:v1.22.2
[config/images] Pulled k8s.gcr.io/pause:3.5
[config/images] Pulled k8s.gcr.io/etcd:3.5.0-0
[config/images] Pulled k8s.gcr.io/coredns/coredns:v1.8.4

kubelet 서비스를 활성화합니다.

sudo systemctl enable kubelet

이제 etcd (클러스터 데이터베이스)와 API 서버를 포함하는 컨트롤 플레인 구성 요소를 실행할 시스템을 초기화하려고 합니다.

 

CRI 소켓이 여러 개인 경우 다음 --cri-socket중 하나를 선택 하는 데 사용하십시오.

# CRI-O
sudo kubeadm config images pull --cri-socket /var/run/crio/crio.sock

# Containerd
sudo kubeadm config images pull --cri-socket /run/containerd/containerd.sock

# Docker
sudo kubeadm config images pull --cri-socket /var/run/dockershim.sock

kubeadm init클러스터를 부트스트랩하는 데 사용되는 기본 옵션입니다.

--control-plane-endpoint : 모든 제어 평면 노드에 대한 공유 끝점을 설정합니다. DNS/IP일 수 있음
 --pod-network-cidr : 포드 네트워크 추가 기능을 설정하는 데 사용됨 CIDR
 --cri-socket : 런타임 소켓 경로를 설정하기 위해 컨테이너 런타임이 둘 이상인 경우 사용
 --apiserver-advertise-address : 이 특정 제어 평면 노드의 API 서버에 대한 광고 주소 설정

공유 엔드포인트가 없는 부트스트랩 (Worker 초기 설정 시 진행)

DNS 엔드포인트를 사용하지 않고 클러스터를 부트스트랩하려면 다음을 실행합니다.

sudo kubeadm init \
  --pod-network-cidr=192.168.0.0/16

공유 엔드포인트가 있는 부트스트랩(제어 평면 API의 DNS 이름)

클러스터 엔드포인트 DNS 이름을 설정하거나 /etc/hosts 파일에 레코드를 추가합니다.

$ sudo vim /etc/hosts
172.29.20.5 k8s-cluster.computingforgeeks.com

클러스터 생성: (Master Node 경우)

sudo kubeadm init \
  --pod-network-cidr=192.168.0.0/16 \
  --upload-certs \
  --control-plane-endpoint=k8s-cluster.computingforgeeks.com

참고 : 192.168.0.0/16 이 이미 네트워크 내에서 사용 중인 경우 위 명령에서 192.168.0.0/16을 대체하여 다른 포드 네트워크 CIDR을 선택해야 합니다.

컨테이너 런타임 소켓:

실행 시간 Unix 도메인 소켓 경로
도커 /var/run/docker.sock
용기에 담긴 /run/containerd/containerd.sock
만들기 /var/run/crio/crio.sock

선택적으로 런타임용 소켓 파일을 전달하고 설정에 따라 주소를 알릴 수 있습니다.

# CRI-O
sudo kubeadm init \
  --pod-network-cidr=192.168.0.0/16 \
  --cri-socket /var/run/crio/crio.sock \
  --upload-certs \
  --control-plane-endpoint=k8s-cluster.computingforgeeks.com

# Containerd
sudo kubeadm init \
  --pod-network-cidr=192.168.0.0/16 \
  --cri-socket /run/containerd/containerd.sock \
  --upload-certs \
  --control-plane-endpoint=k8s-cluster.computingforgeeks.com

# Docker
sudo kubeadm init \
  --pod-network-cidr=192.168.0.0/16 \
  --cri-socket /var/run/docker.sock \
  --upload-certs \
  --control-plane-endpoint=k8s-cluster.computingforgeeks.com

다음은 초기화 명령의 출력입니다.

....
[init] Using Kubernetes version: v1.22.2
[preflight] Running pre-flight checks
	[WARNING Firewalld]: firewalld is active, please ensure ports [6443 10250] are open or your cluster may not function correctly
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Using existing ca certificate authority
[certs] Using existing apiserver certificate and key on disk
[certs] Using existing apiserver-kubelet-client certificate and key on disk
[certs] Using existing front-proxy-ca certificate authority
[certs] Using existing front-proxy-client certificate and key on disk
[certs] Using existing etcd/ca certificate authority
[certs] Using existing etcd/server certificate and key on disk
[certs] Using existing etcd/peer certificate and key on disk
[certs] Using existing etcd/healthcheck-client certificate and key on disk
[certs] Using existing apiserver-etcd-client certificate and key on disk
[certs] Using the existing "sa" key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Using existing kubeconfig file: "/etc/kubernetes/admin.conf"
[kubeconfig] Using existing kubeconfig file: "/etc/kubernetes/kubelet.conf"
[kubeconfig] Using existing kubeconfig file: "/etc/kubernetes/controller-manager.conf"
[kubeconfig] Using existing kubeconfig file: "/etc/kubernetes/scheduler.conf"
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
W0611 22:34:23.276374    4726 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[control-plane] Creating static Pod manifest for "kube-scheduler"
W0611 22:34:23.278380    4726 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 8.008181 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.21" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node k8s-master01.computingforgeeks.com as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node k8s-master01.computingforgeeks.com as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: zoy8cq.6v349sx9ass8dzyj
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:

  kubeadm join k8s-cluster.computingforgeeks.com:6443 --token sr4l2l.2kvot0pfalh5o4ik \
    --discovery-token-ca-cert-hash sha256:c692fb047e15883b575bd6710779dc2c5af8073f7cab460abd181fd3ddb29a18 \
    --control-plane 

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join k8s-cluster.computingforgeeks.com:6443 --token sr4l2l.2kvot0pfalh5o4ik \
    --discovery-token-ca-cert-hash sha256:c692fb047e15883b575bd6710779dc2c5af8073f7cab460abd181fd3ddb29a18

출력의 명령을 사용하여 kubectl을 구성합니다.

mkdir -p $HOME/.kube
sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

echo 'export KUBECONFIG=$HOME/.kube/config' >> $HOME/.bashrc

클러스터 상태 확인:

$ kubectl cluster-info
Kubernetes master is running at https://k8s-cluster.computingforgeeks.com:6443
KubeDNS is running at https://k8s-cluster.computingforgeeks.com:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

설치 출력의 명령을 사용하여 마스터 노드를 추가할 수 있습니다.

kubeadm join k8s-cluster.computingforgeeks.com:6443 --token sr4l2l.2kvot0pfalh5o4ik \
    --discovery-token-ca-cert-hash sha256:c692fb047e15883b575bd6710779dc2c5af8073f7cab460abd181fd3ddb29a18 \
    --control-plane 

6단계: 마스터에 네트워크 플러그인 설치

이 가이드에서는 Calico 를 사용 합니다. 지원되는 다른 네트워크 플러그인 을 선택할 수 있습니다 .

kubectl create -f https://docs.projectcalico.org/manifests/tigera-operator.yaml 
kubectl create -f https://docs.projectcalico.org/manifests/custom-resources.yaml

다음 출력이 표시되어야 합니다.

customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/apiservers.operator.tigera.io created
customresourcedefinition.apiextensions.k8s.io/imagesets.operator.tigera.io created
customresourcedefinition.apiextensions.k8s.io/installations.operator.tigera.io created
customresourcedefinition.apiextensions.k8s.io/tigerastatuses.operator.tigera.io created
namespace/tigera-operator created
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy/tigera-operator created
serviceaccount/tigera-operator created
clusterrole.rbac.authorization.k8s.io/tigera-operator created
clusterrolebinding.rbac.authorization.k8s.io/tigera-operator created
deployment.apps/tigera-operator created
.....
installation.operator.tigera.io/default created
apiserver.operator.tigera.io/default created

모든 포드가 실행 중인지 확인합니다.

$ watch kubectl get pods --all-namespaces
NAMESPACE     NAME                                                         READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-76d4774d89-nfqrr                     1/1     Running   0          2m52s
kube-system   calico-node-kpprr                                            1/1     Running   0          2m52s
kube-system   coredns-66bff467f8-9bxgm                                     1/1     Running   0          7m43s
kube-system   coredns-66bff467f8-jgwln                                     1/1     Running   0          7m43s
kube-system   etcd-k8s-master01.computingforgeeks.com                      1/1     Running   0          7m58s
kube-system   kube-apiserver-k8s-master01.computingforgeeks.com            1/1     Running   0          7m58s
kube-system   kube-controller-manager-k8s-master01.computingforgeeks.com   1/1     Running   0          7m58s
kube-system   kube-proxy-bt7ff                                             1/1     Running   0          7m43s
kube-system   kube-scheduler-k8s-master01.computingforgeeks.com            1/1     Running   0          7m58s

마스터 노드가 준비되었는지 확인합니다.

# CRI-O
$ kubectl get nodes -o wide
NAME     STATUS   ROLES                  AGE   VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
ubuntu   Ready    control-plane,master   38s   v1.22.2   143.198.114.46   <none>        Ubuntu 20.04.3 LTS   5.4.0-88-generic   cri-o://1.22.0

# Containerd
$ kubectl get nodes -o wide
NAME     STATUS   ROLES                  AGE   VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
ubuntu   Ready    control-plane,master   15m   v1.22.2   143.198.114.46   <none>        Ubuntu 20.04.3 LTS   5.4.0-88-generic   containerd://1.4.11

# Docker
$ kubectl get nodes -o wide
NAME           STATUS   ROLES    AGE   VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE           KERNEL-VERSION     CONTAINER-RUNTIME
k8s-master01   Ready    master   64m   v1.22.2   135.181.28.113   <none>        Ubuntu 20.04 LTS   5.4.0-37-generic   docker://20.10.8

7단계: 작업자 노드 추가

제어 플레인이 준비되면 예약된 워크로드를 실행하기 위해 클러스터에 작업자 노드를 추가할 수 있습니다.

엔드포인트 주소가 DNS에 없으면 /etc/hosts 에 레코드를 추가 합니다 .

$ sudo vim /etc/hosts
172.29.20.5 k8s-cluster.computingforgeeks.com

주어진 조인 명령은 클러스터에 작업자 노드를 추가하는 데 사용됩니다.

kubeadm join k8s-cluster.computingforgeeks.com:6443 \
  --token sr4l2l.2kvot0pfalh5o4ik \
  --discovery-token-ca-cert-hash sha256:c692fb047e15883b575bd6710779dc2c5af8073f7cab460abd181fd3ddb29a18

산출:

[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.21" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

제어 플레인에서 아래 명령을 실행하여 노드가 클러스터에 합류했는지 확인합니다.

$ kubectl get nodes
NAME                                 STATUS   ROLES    AGE   VERSION
k8s-master01.computingforgeeks.com   Ready    master   10m   v1.22.2
k8s-worker01.computingforgeeks.com   Ready    <none>   50s   v1.22.2
k8s-worker02.computingforgeeks.com   Ready    <none>   12s   v1.22.2

$ kubectl get nodes -o wide

조인 토큰이 만료된 경우 작업자 노드에 조인하는 방법에 대한 가이드를 참조하십시오.

8단계: 클러스터에 애플리케이션 배포

단일 노드 클러스터만 있는 경우 마스터 노드에서 컨테이너 포드를 실행하는 방법에 대한 가이드를 확인하세요.

애플리케이션을 배포하여 클러스터가 작동하는지 확인해야 합니다.

kubectl apply -f https://k8s.io/examples/pods/commands.yaml

포드가 시작되었는지 확인

$ kubectl get pods
NAME           READY   STATUS      RESTARTS   AGE
command-demo   0/1     Completed   0          16s

9단계: Kubernetes 대시보드 설치(선택 사항)

Kubernetes 대시보드는 컨테이너화된 애플리케이션을 Kubernetes 클러스터에 배포하고, 컨테이너화된 애플리케이션의 문제를 해결하고, 클러스터 리소스를 관리하는 데 사용할 수 있습니다.

설치 가이드를 참조하십시오: NodePort로 Kubernetes 대시보드를 설치하는 방법

10단계: Metrics Server 설치(Pod 및 노드 리소스 사용량 확인용)

Metrics Server  는 리소스 사용량 데이터의 클러스터 전체 집계 도구입니다.  각 노드에서 Kubelet 에 의해 노출된  요약 API 에서 메트릭을 수집  합니다. 아래 가이드를 사용하여 배포하세요.

11단계: Prometheus/Grafana 모니터링 배포

Prometheus는 Kubernetes 클러스터의 고급 메트릭 기능에 액세스할 수 있는 완전한 솔루션입니다. Grafana는 Prometheus 데이터베이스에 수집 및 저장되는 메트릭의 분석 및 대화형 시각화에 사용됩니다. Kubernetes 클러스터에서 전체 모니터링 스택을 설정하는 방법에 대한 완전한 가이드가 있습니다.

12단계: 영구 저장소 구성 아이디어(선택 사항)

Kubernetes용 영구 스토리지 솔루션도 찾고 있다면 다음을 확인하십시오.

13. Nginx 인그레스 컨트롤러 설치

Nginx가 Kubernetes 워크로드용으로 선호하는 Ingress 컨트롤러인 경우 설치 프로세스에 대한 가이드를 사용할 수 있습니다.

더 많은 가이드:

유사한 Kubernetes 배포 가이드:

Docker Registry V2 Installation

소개

이 글에서는 기본적인 Docker Registry 설치법에 대해 다룰 것이다. 정말 자세한 내용은 공식 홈페이지를 참조하면 된다. Docker Registry란 Docker Image를 관리하는 Docker Hub 같은 Respository를 말한다. 개별적으로 Docker Image를 관리 할 일이 생기면 필수라고 생각된다. Docker Registry를 설치하기 위해서, docker와 docker-compose가 필요하다. 설치는 아래 글을 참고하자.

간단한 설치

공식홈페이지에 보면 아래처럼 단 한 줄로 Registry를 설치 할 수 있다고 나와있다.
$ docker run -d -p 5000:5000 registry:2.6
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
860c11dc6921        registry:2.6        "/entrypoint.sh /e..."   48 seconds ago      Up 47 seconds       0.0.0.0:5000->5000/tcp   brave_ptolemy
위 명령어로 설치된 Registry 기본 설정은 아래 명령어로 확인 할 수 있다.
$ docker exec 860c11dc6921 cat /etc/docker/registry/config.yml
version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3
기본 설정대로 사용하면 제약사항이 너무 많다. 꼭 필요하다고 생각되는 부분만 변경해보도록 하겠다.

log

로그는 공식 홈페이지를 보고 입맛에 맞게 설정하면 된다. 지금 단계에서 크게 중요하지 않다.

storage

기본 설정대로면 container안에 디스크에 Docker Image가 저장된다. 이렇게되면 docker registry가 삭제되면 데이터가 같이 날아가게되므로, 설정은 그대로 두고 host에 있는 디렉토리를 mount 해줄 필요가 있다. 혹은 cloud storage를 사용하면 좋은데 대표적인 예로 AWS S3가 있다. 다른 옵션을 더 보고싶으면 공식 홈페이지 문서를 참고하자.
기본 설정대로면 캐쉬를 메모리에 하도록 되어있다. 이는 쓸데 없이 메모리를 사용하게 된다고 생각이 되는데, 다른 옵션으로 redis를 사용 할 수 있다. 캐쉬를 redis로 사용하기 위해서는 redis를 실행하고 설정을 따로 해줘야하는데, redis image를 사용하도록하자.
storage 부분이 redis 설정까지 추가해 이렇게 변경된다. redis addr에 redis:6379를 쓴 것은 redis를 docker container로 실행하고 link로 연결해 줄 것이기 때문이다.
storage:
  cache:
    blobdescriptor: redis
  filesystem:
    rootdirectory: /var/lib/registry
redis:
  addr: redis:6379

auth

기본 설정대로면 Docker Registry에 접근하기 위해서 그 어떤 인증도 필요하지 않다. Docker Registry V2부터 3rd party 인증시스템을 도입 할 수 있도록 JWT Token Base 인증 서버를 별도로 구현 할 수 있다. 이 부분은 여기서 함께 다루기엔 너무 복잡하므로 상대적으로 간단한 Basic Authorization을 이용하여 인증 시스템을 설정해보도록 하자.
설정을 살펴보면 realm, path를 지정하도록 되어있다. realm은 원하는 값을 넣어주고 path에는 .htpasswd 파일 경로를 넣어준다. docker registry에서 사용 할 .htpasswd 파일은 아래 명령어를 이용해 만들 수 있다. 아이디가 admin, 비밀번호가 1234인 경우이다.
$ docker run --rm --entrypoint htpasswd registry:2.6 -Bbn admin 1234 > .htpasswd
$ cat .htpasswd
admin:$2y$05$WmcysuiS7ZW7jyXMuZS9W.evGsOsnF3yz4o38Xy1KDMLkJbomZEm2

최종적으로 인증 정보가 들어간 설정이 아래와 같이 추가된다.
auth:
  realm: dgoh-registry
  path: /etc/docker/registry/.htpasswd

최종적인 config.yml

version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: redis
  filesystem:
    rootdirectory: /var/lib/registry
redis:
  addr: redis:6379
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
auth:
  htpasswd:
    realm: dgoh-registry
    path: /etc/docker/registry/.htpasswd 
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3

docker-compose.yml 작성

자세히 하려면 봐야 할 설정이 더 있겠지만, 정말 기본적인 설정은 끝났다. 이제 docker-compose.yml을 작성하고 디플로이를 하자.
version: 3
services:
  registry:
    image: registry:2.6
    volumes:
      - /var/lib/registry:/var/lib/registry # host filesystem을 mount
      - ./config.yml:/etc/docker/registry/config.yml:ro # 설정 파일 변경
      - ./.htpasswd:/etc/docker/registry/.htpasswd:ro # htpasswd mount
    links:
      - redis:redis # cache에 사용 할 redis container 연결
    ports:
      - 5000:5000 # 5000번을 이용해 통신
    depends_on:
      - redis # redis가 실행된 후, registry가 실행된다.

  redis:
    image: redis:3.0.7
docker-compose를 이용하여 실행한다.
$ docker-compose up
Starting registry_redis_1 ...
Starting registry_redis_1 ... done
Starting registry_registry_1 ...
Starting registry_registry_1 ... done
Attaching to registry_redis_1, registry_registry_1
마지막으로 registry에 제대로 접속 되는지 docker cli를 통해 확인한다.
$ docker login 127.0.0.1:5000
Username: admin
Password:
Login Succeeded

linux LVM(PV, VG, LV) (Create, delete, query, add) method

Linux에서 파티션 중 우리가 가장 흔히 사용하는 것이 바로 File System이다. File System에 워낙 익숙
해지기도 했고 디스크 추가 후 사용이 간편하여 가장 널리사용한다는게 필자 생각이다.
Linux File System은 흔히 우리가 알고 있는 ext1부터시작하여 현재 ext4까지 사용중이며 그 기능과
성능이 버전이 업그레이드되면서 함께 발전해왔다.
하지만 이런 ext file system을 사용할 경우 공간이 꽉 찼을 경우 더 큰 file system으로 교체하거나 심
지어는 새로운 파티션 조정을 위한 Linux 재설치까지 가는 경우가 있을 수 있다.
LVM 이런 수고를 덜 수 있는 강력한 기능을 덜 수 있는 녀석이다. 즉, LVM을 사용하면 유동적인 공간
할당을 통하여 Mount Point 관리를 더 효율적으로 할 수 있다고 하겠다.
 Oracle에서 ASM Disk를 생성할 때에도 이 LVM을 사용하여 Disk를 던져줄 수 있다. 오늘은 LVM 관리
방법에 대하여 이야기해본다.
 Step 1. LVM에 사용될 Disk 추가
일단 이번 테스트에 사용될 디스크는
20G * 2 = 40G
40G * 1 = 40G
총 80G Disk를 사용할 예정이다.
 Step 2. Disk Format & PV / VG / LV 생성
[root@localhost ~]# fdisk -l

추가된 3개의 Disk를 확인할 수 있다. 위에 언급한데로 20G * 2, 40G 하나를 추가하여 총 80G 용량의 하디드스크를 추가하였다. fdisk 명령을 통해 확인이 가능하다.

[root@localhost ~]# fdisk /dev/sdb       // sdc, sdd 까지 진행
 

여기서 주의 할 것은 Hex code는 Linux에서 사용되는 Linux LVM file system으로 사용하기 위한 코드명은 8e가 된다.

[root@localhost ~]# fdisk -l /dev/sdb     // sdc, sdd도 확인가능

위와 같이 사용 가능한 포멧으로 생성됐읗며 System이 Linux LVM인 것을 확인할 수 있다.

 

* LVM을 통한 Disk 생성
 – PV(Physical Volume)을 생성한다.
[root@localhost ~]# pvcreate /dev/sdb1 /dev/sdc1 /dev/sdd1
  Physical volume “/dev/sdb1” successfully created.
  Physical volume “/dev/sdc1” successfully created.
  Physical volume “/dev/sdd1” successfully created.
 – VG(Volume Group)을 생성한다.
[root@localhost ~]# vgcreate ASMDISK /dev/sdb1 /dev/sdc1 /dev/sdd1
  Volume group “ASMDISK” successfully created

 

 – LV(Logical Volume)을 생성한다.
[root@localhost ~]# lvcreate -L 40g -n DATA01 ASMDISK
  Logical volume “DATA01” created.
[root@localhost ~]# lvcreate -L 39.5g -n DATA02 ASMDISK
  Logical volume “DATA02” created.
 Step 3. PV / VG / LV 조회
 생성구문의 create 대신 display 명령을 붙여주면 조회가 가능하다.
[root@localhost ~]# pvdisplay
  — Physical volume —
  PV Name               /dev/sdb1
  VG Name               ASMDISK
  PV Size               <20.00 GiB / not usable 3.00 MiB
  Allocatable           yes
  PE Size               4.00 MiB
  Total PE              5119
  Free PE               125
  Allocated PE          4994
  PV UUID               Y16fLb-fmBl-Qga0-Vt0Q-xYGm-0YfF-L2HRz2
  — Physical volume —
  PV Name               /dev/sdc1
  VG Name               ASMDISK
  PV Size               <20.00 GiB / not usable 3.00 MiB
  Allocatable           yes (but full)
  PE Size               4.00 MiB
  Total PE              5119
  Free PE               0
  Allocated PE          5119
  PV UUID               eyCU5C-Bzuj-DXBg-qVZX-uhM2-y7Hc-5AxKlZ
  — Physical volume —
  PV Name               /dev/sdd1
  VG Name               ASMDISK
  PV Size               <40.00 GiB / not usable 3.00 MiB
  Allocatable           yes (but full)
  PE Size               4.00 MiB
  Total PE              10239
  Free PE               0
  Allocated PE          10239
  PV UUID               ODoaFo-qV2G-T2EE-28mT-S1Sh-DGou-2IZcZz
[root@localhost ~]# vgdisplay
  — Volume group —
  VG Name               ASMDISK
  System ID
  Format                lvm2
  Metadata Areas        3
  Metadata Sequence No  3
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                2
  Open LV               0
  Max PV                0
  Cur PV                3
  Act PV                3
  VG Size               <79.99 GiB
  PE Size               4.00 MiB
  Total PE              20477
  Alloc PE / Size       20352 / 79.50 GiB
  Free  PE / Size       125 / 500.00 MiB
  VG UUID               LzMB5j-IChS-RByT-pFNR-OJZk-opt8-hz6rdf
[root@localhost ~]# lvdisplay
  — Logical volume —
  LV Path                /dev/VG01/oracle
  LV Name                oracle
  VG Name                VG01
  LV UUID                02j5sM-lYwm-jOWj-Koc3-nprv-Y4TT-S1HGE0
  LV Write Access        read/write
  LV Creation host, time localhost, 2017-12-11 12:15:01 -0500
  LV Status              available
  # open                 1
  LV Size                <79.98 GiB
  Current LE             20474
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  – currently set to     8192
  Block device           249:0
  — Logical volume —
  LV Path                /dev/ASMDISK/DATA01
  LV Name                DATA01
  VG Name                ASMDISK
  LV UUID                HBQT0M-VEzf-XjPm-ZH05-MrRT-AK8V-NaMNwq
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2017-12-11 16:09:06 -0500
  LV Status              available
  # open                 0
  LV Size                40.00 GiB
  Current LE             10240
  Segments               2
  Allocation             inherit
  Read ahead sectors     auto
  – currently set to     8192
  Block device           249:1
  — Logical volume —
  LV Path                /dev/ASMDISK/DATA02
  LV Name                DATA02
  VG Name                ASMDISK
  LV UUID                S7eJc5-nQQ0-6vn7-yVis-zC7J-AK8r-AlcbQB
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2017-12-11 16:09:33 -0500
  LV Status              available
  # open                 0
  LV Size                39.50 GiB
  Current LE             10112
  Segments               2
  Allocation             inherit
  Read ahead sectors     auto
  – currently set to     8192
  Block device           249:2
 Step 4. PV / VG / LV 삭제
create, display 명령 대신 remove를 붙여 사용가능하다.
[root@localhost sbin]# pvremove /dev/sdb1
  Labels on physical volume “/dev/sdb1” successfully wiped.
[root@localhost sbin]# pvremove /dev/sdc1
  Labels on physical volume “/dev/sdc1” successfully wiped.
[root@localhost sbin]# pvremove /dev/sdd1
  Labels on physical volume “/dev/sdd1” successfully wiped.
[root@localhost sbin]# vgremove ASMDISK
Do you really want to remove volume group “ASMDISK” containing 1 logical volumes? [y/n]: y
Do you really want to remove active logical volume ASMDISK/DATA1? [y/n]: y
  Logical volume “DATA1” successfully removed
  Volume group “ASMDISK” successfully removed
 vg 삭제시에는 삭제하겠느냐는 물음과 함께 vg에 포함된 lv도 삭제되니 유의하도록 하자.
 Step 5. 기존 VG에 PV 추가
 기존에 사용하던 Volume Group이 공간이 부족해 추가를 원할때 사용이 가능하다. 일단 해당 Virture Machine에 Disk를 추가하고 포멧을 진행한다. 포멧은 Step 2의 절차를 따라하면 된다.
[root@localhost ~]# fdisk -l /dev/sde1
Disk /dev/sde: 128.8 GB, 128849018880 bytes, 251658240 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x625d1896
   Device Boot      Start         End      Blocks   Id  System
/dev/sde1            2048   251658239   125828096   8e  Linux LVM
 – VG에 추가 될 해당 Disk를 PV를 생성해준다.
[root@localhost ~]# pvcreate /dev/sde1
  Physical volume “/dev/sde1” successfully created.
 
 – 생성된 PV를 VG에 추가 할당 해준다.
[root@localhost sbin]# vgextend ASMDISK /dev/sde1
  Volume group “ASMDISK” successfully extended
 – 추가할당 해준 VG을 확인한다.
[root@localhost sbin]# vgdisplay
VG Name               ASMDISK
  System ID
  Format                lvm2
  Metadata Areas        4
  Metadata Sequence No  10
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                8
  Open LV               4
  Max PV                0
  Cur PV                4
  Act PV                4
  VG Size               199.98 GiB
  PE Size               4.00 MiB
  Total PE              51196
  Alloc PE / Size       20352 / 79.50 GiB
  Free  PE / Size       30844 / 120.48 GiB
  VG UUID               1M7FrH-e23z-216o-Hf5n-Ad8g-nJXk-WRF1Uf
 VG의 Size가 기존 80G에서 200G가 됐음을 확인할 수 있다.

VirtualBox에 VMware ESXi 설치 방법

중요:  IntelCPU를 소유하고 있는 경우VirtualBox에서실행되는 VM ESXi 호스트에서 새 VM 시스템을 시작할 수 없다는점에 유의하십시오. 

이것은 VirtualBox가 Intel CPU에 대한 중첩 가상화를 지원하지 않기 때문에 발생합니다. 

(VM 머신을 시작하려고 하면 “이 호스트는 Intel VT-x를 지원하지 않습니다.”라는 오류가 표시됩니다.) 따라서 Intel CPU를 소유하고 있다면VMware 플레이어에 ESXi설치하는것이 좋습니다.

VirtualBox에 ESXi vSphere Hypervisor를 설치하기 위한 하드웨어 요구 사항:

CPU: 호스트 시스템에는 최소 2개의 CPU 코어가 있어야 하고 CPU는 하드웨어 가상화 기능(Intel VT-x 또는 AMD RVI)을 지원해야 합니다. 시스템이 가상화를 지원하는지 확인하려면 CPUID CPU-Z 유틸리티를사용하십시오. *

* 참고:
1. 가상화 지원을 활성화하려면 BIOS 설정으로 이동 하여 Intel-VD(Intel VT-x) 또는 AMD VT 기술/기능을 활성화 합니다 .

RAM: ESXi에는 최소 2GB의 물리적 RAM이 필요합니다. VirtualBox에 ESXi를 설치하려면 최소 4GB(4096MB)의 RAM을 할당해야 합니다.

VirtualBox에 ESXi vSphere Hypervisor 6.7을 설치하기 위한 소프트웨어 요구 사항.

1. 이동 링크 및 작성 VM웨어 계정을 (당신이 이미 하나를 가지고 있지 않은 경우).
2. VMware vSphere Hypervisor(ESXi ISO) 이미지(VMware 도구 포함) 이미지를 다운로드 합니다 .

3. 평가판 라이센스(60일)를 무료(만료되지 않음)로 변환하려면 평가판 기간이 끝날 때 필요하므로 VMware vSphere Hypervisor 6 라이센스 키를 기록해 둡니다 . (기사의 끝을 참조하십시오).

4. VirtualBox에 ESXi VSphere Hypervisor를 설치하려면 여기 에서 Windows 호스트용 Virtualbox의 최신 릴리스를 다운로드하여 설치해야 합니다 .

영상

VirtualBox 호스트에 VMware vSphere Hypervisor(ESXi 서버)를 설치하는 방법.

1단계. ESXI용 가상 머신 생성 및 구성 *

1.   Oracle VM Virtual Box Manager를 시작하고 새로 만들기 를 클릭 합니다 .

vmware esxi 설치 virtualbox

2. 가상 머신의 이름(예: “eSXI vSphere”)을 지정하고 다음을 선택합니다.

유형: 리눅스

버전: Linux 2.6/3.x/4.x(64비트)

메모리 크기: 4096MB

하드 디스크: 지금 가상 디스크 만들기

3. 완료되면 만들기를 클릭 합니다.

VirtualBox에 VMware ESXi 6.7을 설치하는 방법.

4. 다음 화면에서 원하는 디스크 크기(예: 30GB)를 지정하고 ‘하드 디스크 파일 유형’: VDI(VirtualBox 디스크 이미지) 및 ‘실제 하드 디스크에 저장’: 동적 할당 의 기본 옵션을 그대로 두고 클릭합니다. 생성 .

VirtualBox에 ESXi 설치

5. 이제 새 가상 머신을 강조 표시하고 설정 을 클릭 합니다 .

영상

6a. 왼쪽에서 시스템 을 선택 하고 마더보드 탭에서 다음을 선택합니다.

  • 칩셋: ICH9
  • 포인팅 장치: PS/2 마우스

영상

6b. 그런 다음 프로세서 탭을 선택 하고…

  • 2개의   CPU를 할당합니다 .
  • PAE/NX 활성화 확인

영상

7. 그런 다음 스토리지를 선택 하고 광학 드라이브 추가  기호 를 클릭합니다 .

영상

8. 디스크 선택 을 선택한 다음 다운로드한 ‘vSphere Hypervisor(ESXi ISO)’ 파일을 선택합니다.

영상

9a. 마지막으로 네트워크 를 선택하고 호스트 전용 어댑터 를 선택한 다음 확인 을 클릭 합니다.

영상

9b. 마법사 기반 생성 프로세스 후에 가상화 기술을 실행할 수 있도록 생성된 VM을 수정해야 합니다.

이는 CLI(PowerShell/CMD)를 통해서만 가능합니다.

cd 'C:\Program Files\Oracle\VirtualBox\'
.\VBoxManage.exe modifyvm "VMwareESXi" --nested-hw-virt on

 

10. 시작 버튼을 클릭하고 아래로 진행하여 가상 머신에 ESXi vSphere Hypervisor를 설치합니다.

영상

2단계. VIRTUALBOX VM 머신에 VMWARE ESXI VSPHERE HYPERVISOR 6.7을 설치합니다.

* 참고: 물리적 시스템에 ESXi vSphere Hypervisor를 설치하는 경우 ESXi vSphere Hypervisor 설치 CD 미디어에서 시스템을 부팅하십시오.

1. 첫 화면에서 Enter 를 눌러 설치를 시작합니다.

VirtualBox 호스트에 ESXi vSphere Hypervisor를 설치하는 방법

2. VMware ESXI 설치 프로그램이 시작되어야 합니다…

영상

3. 시작 화면에서 Enter 키 를 누릅니다 .

영상

4. F11 키 를 눌러 사용권 계약에 동의합니다.

영상

5. 스토리지 옵션에서 Enter 키를 누릅니다 .

영상

6. 원하는 키보드 레이아웃을 선택하거나 기본값(미국)을 그대로 두고 Enter 키를 누릅니다 .

영상

7. 이제 원하는 비밀번호*를 두 번 입력 하고 Enter 키를 누릅니다 .

* 참고: 비밀번호는 최소 7자 이상이어야 하며 일반 및 대문자, 기호 및 숫자의 조합이어야 합니다.

영상

8. 마지막으로 F11 키 를 눌러 설치를 중단합니다. *

* VirtualBox 설치 참고 사항: ESXi 설치 시점에서 Intel 프로세서를 소유하고 있는 경우 화면에 다음 경고 메시지가 표시됩니다. “하드웨어 가상화 경고: 하드웨어 가상화는 이 CPU의 기능이 아니거나 BIOS에서 활성화되지 않았습니다.” 이 메시지를 무시하고 Enter 키를 눌러 계속하십시오. (이 기사의 시작 부분에서 말했듯이 VirtualBox는 Intel 프로세서에 대한 중첩 가상화를 지원하지 않기 때문에 이 메시지가 나타납니다.)

영상

9. 설치가 완료되면 설치 미디어를 제거하고 Enter 키 를 눌러 시스템을 재부팅합니다. *

영상

* 참고: VirtualBox에서 ESXi 설치 미디어(.ISO 파일)를 제거하려면 

  A.재부팅 후 VM 창을 닫고컴퓨터의 전원을 끕니다 .

영상

B. 그런 다음 VM 머신 스토리지 설정을 열고 ISO 파일을 제거한 다음 확인을 클릭 합니다.
C. 마지막으로 시작 버튼을 클릭하여 VMware ESXi 머신을 시작합니다.

영상

10. VMware ESXi 서버가 시작되면 DHCP에서 할당된 IP 주소를 “가져옵니다”. 아래 지침에 따라 ESXi 서버에 이 IP 주소를 사용하거나 새 고정 IP 주소를 설정할 수 있습니다.

영상

11. ESXi에서 IP 주소를 변경하려면 위 화면에서 F2 를 누른다 .
12. 루트 암호를 입력하고 Enter 키를 누릅니다.
13. 화살표 키를 사용하여 관리 네트워크 구성으로 이동 하고 Enter 키 를 누릅니다 .

image_thumb[1]_thumb[2]

14. IPv4 구성으로 이동 하고 Enter 키를 누릅니다 .

 image_thumb[3]_thumb[3]

(15) 로 이동 한 세트 정적 IPv4 주소 및 네트워크 구성 및 히트 공간 을 선택할 수 있습니다.
16. 고정 IP 주소, 서브넷 마스크 및 게이트웨이를 입력 하고 Enter 키를 누릅니다 .

image_thumb[5]_thumb[3]

17. 그런 다음 선택 DNS 구성 및 히트 입력합니다 .

image_thumb[7]_thumb[3]

18. 이동 정보는 다음의 제품에 다음 DNS 서버 주소 및 호스트 이름을 사용 하고 공격 공간 을 선택할 수 있습니다.
19. 유형 DNS 서버 주소 및 선택적으로 다른 호스트 이름을 지정합니다. 완료되면 Enter 키를 누릅니다 .

image_thumb[9]_thumb[1]

20. ESC 를 눌러 종료한 다음 Y 를 눌러 변경 사항을 적용하고 관리 네트워크를 다시 시작합니다.

image_thumb[11]_thumb[1]

(21) 이어서 프레스 ESC 로그 아웃 한 후 프레스 F12 및 종료 ESXi 서버.
22. VirtualBox Manager에서 새 가상 머신을 강조 표시하고 설정 을 클릭 합니다 .

영상

(23) 에서 네트워크 : 옵션에 첨부를 선택 브리지 어댑터를 클릭하고 OK

영상

24. VM ESXi 머신을 시작합니다.
25. ESXi 서버가 시작되면 웹 브라우저(호스트 컴퓨터에서)를 열고 ESXi 서버의 IP 주소로 이동하여 VMWare ESXi vShere 서버 관리를 시작합니다.

영상

추가 도움말: VMware ESXi Hypervisor 평가 라이센스를 무료로 변환하려면.

* 참고: 60일 동안(평가 기간 종료 시까지) ESXi의 모든 기능을 탐색하고 테스트할 수 있습니다. 따라서 평가 기간이 종료되기 전에 평가 라이센스를 무료로 변환하지 마십시오.

1. 관리 -> 라이선스로 이동 한 다음 라이선스 할당 을 클릭 합니다 .

image_thumb17_thumb[2]

2. vSphere Hypervisor 6 라이센스 키를 복사하여 붙여넣은 다음 라이센스 확인 을 클릭합니다.

image_thumb15_thumb

3. 마지막으로 라이선스 할당을 클릭 합니다.

image_thumb16_thumb[1]

4. 이제 ‘만료 날짜’ 상태가 “Never”인 화면이 표시되어야 합니다.

image_thumb18_thumb[2]

그게 다야!

Oracle Delete문 사용 후 Tablespace 정리하기

일단 Tablespace 용량 확인 쿼리

select substr(a.tablespace_name,1,30) tablespace,
round(sum(a.total1)/1024/1024,1) “TotalMB”,
round(sum(a.total1)/1024/1024,1)-round(sum(a.sum1)/1024/1024,1) “UsedMB”,
round(sum(a.sum1)/1024/1024,1) “FreeMB”,
round((round(sum(a.total1)/1024/1024,1)-round(sum(a.sum1)/1024/1024,1))/round(sum(a.total1)/1024/1024,1)*100,2) “Used%”
from
(select tablespace_name,0 total1,sum(bytes) sum1,max(bytes) MAXB,count(bytes) cnt
from dba_free_space
group by tablespace_name
union
select tablespace_name,sum(bytes) total1,0,0,0
from dba_data_files
group by tablespace_name) a
group by a.tablespace_name
order by tablespace;

 

위 쿼리로 조회하면 UsedMB와 FreeMB를 조회 할 수 있다.

나는 UsedMB를 처리해야 하는 것.

데이터를 지우기에 앞서 Tablespace가 아닌 해당 Table에서 사용 중인 block를 확인해보았다.

select count(distinct dbms_rowid.rowid_block_number(rowid)) blocks from person;
select blocks, extents from user_segments where segment_name = ‘PERSON’;

 

 

 

person 테이블에서 사용 중인 block는 1241개고, 할당된 block는 1280개.

 

이제 Delete 문으로 데이터를 삭제한다.

DELETE FROM [TABLENAME] WHERE [COLUMN] = [VALUE]

 

27319개의 row를 삭제하였다.

다시 block 사용량을 확인하였다.

 

Delete 문으로 데이터를 지웠으나 다들 알다시피 delete 문으로는 Tablespace 용량이 줄어들지 않는다.

(삭제 조건을 줘야하기 때문에 truncate는 사용 불가능)

사용한 block는 줄어들었으나 hwm은 줄어들지 않았다.

 

이제 shrink를 실행해보았다.

ALTER TABLE PERSON SHRINK SPACE
ALTER TABLE PERSON SHRINK SPACE CASCADE

 

 

HWM도 줄어들고 Tablespace 사용량도 줄어들었다.

 

★ ORA-10636: ROW MOVEMENT is not enabled 에러 발생 시

row movement 기능이 꺼져 있는 것이니 켜줘야 한다.

ALTER TABLE PERSON ENABLE ROW MOVEMENT;

row movement 기능을 끄려면 아래 쿼리를 수행한다.

ALTER TABLE [테이블명] DISABLE ROW MOVEMENT;

 

★ SHRINK 차이점

우측 설명은 그냥 내가 이해한대로 작성한 것임

CASCADE의 이해도가 부족한데 좀 더 찾아봐야겠음.

 

 

SHRINK SPACE HWM 축소
SHRINK SPACE COMPACT Block 정리는 수행하지만 HWM을 건드리지 않음
SHRINK SPACE CASCADE 연관된 인덱스 정리

 

공식 URL : http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_3001.htm#i2192484

CIDR(Classless Inter-Domain Routing) 표기법

인터넷 주소 체계인 IP는 간혹 ‘1.1.1.1/32’와 같은 형태로 표기됩니다. 앞부분인 1.1.1.1이 IP인것은 알겠는데 /32이 무엇을 의미 하는지 모르는 분들을 위해 오늘은 /32이 무엇을 의미하는지 알려 드리겠습니다.

IP는 마침표로 구분되는 4개의 영역을 가지고 있습니다. 각각의 영역을 옥텟이라고 부르며 1개의 옥텟에 1byte의 크기를 가집니다. 0~255까지 표현이 가능하며 총 4byte(32bit)의 크기를 가집니다.

이러한 구성의 가진 IP는 효율적으로 사용하기 위해 Net ID와 Host ID로 나누어 사용합니다.

Net ID는 네트워크 영역을 식별하기 위한 값이며 Host ID는 하나의 네트워크 영역에서 호스트를 식별하기 위한 값입니다.

위에 그림처럼 Net ID는 좌측 비트부터 사용하게 되는데 옥텟과 마침표만 을 사용하면 어디까지가 Net ID이고 Host ID인지 알수 있는 방법이 없습니다.
때문에 보편적으로 CIDR(Classless Inter-Domain Routing)의 유연성있는 서브넷 마스크 표기법을 이용하여 표현합니다.

Subnet mask 표기법 -> 1.1.1.1 (255.255.255.255)
CIDR(prefix) 표기법 -> 1.1.1.1/32

위에서 표현한 1.1.1.1/32는 좌측부터 32비트가 전부 Net ID라는 뜻이며 1.1.1.1은 하나의 호스트 IP를 나타냅니다.
만약 1.1.1.0/24와 같이 표현된다면 좌측에서 부터 24비트, 즉 1.1.1까지는 Net ID라는 뜻이며 1.1.1.0 ~ 1.1.1.255가 1.1.1.0대역 네트워크에서 보유한 호스트 들이 됩니다.

해당 내용을 이용하여 방화벽을 설정할 경우 1.1.1.0/24로 설정하여 1.1.1.0~1.1.1.255에 해당 하는 256개의 ip를 CIDR표현식 한 줄로 설정할 수 있게 됩니다.

시놀로지 NAS의 OpenVPN 서버 설정하기

Synology NAS의 PPTP VPN 서버 설정 방법을 이전 포스트에서 설명했는데 한가지 설명을 빠트렸었다. 무엇인고 하니 설명한 환경에서 NAS를 SuperDMZ 또는 DMZ(NAT) 기능을 이용해 집의 인터넷 공유기에 할당되는 공인IP를 통채로 NAS에 할당한 경우에만 가능한 방법이다.

그렇지 않고 통신사에 연결되는 인터넷 공유기에는 공인IP가 할당되고 NAS에는 192.X.X.X로 표시되는 사설IP가 할당될 경우에는 PPTP, IPSEC 등의 VPN은 정상동작시키기 쉽지 않다. 인터넷 공유기에서 포트포워딩을 해줘야할 포트도 여러개인데다 설정을 하더라도 제대로 동작하지 않는 경우가 많기 때문이다.

그래서 오늘은 하나의 포트만 포트포워딩 하면 사용할 수 있는 OpenVPN 서버의 설정방법을 포스팅한다.

1. 인터넷 공유기에서 OpenVPN에서 사용할 통신포트를 포트포워딩 하기

통신사에서 제공하는 인터넷 공유기의 경우 다음과 같이 “포트포워딩(Port Forwarding)” 기능을 제공하는 경우가 대부분이다.

2. 시놀로지 NAS에서 새 인증서 만들기

많은 시놀로지 사용자들이 OpenVPN 서버를 설정하면서 부닥치는 가장 큰 난관은 바로 인증서 설정과 관련된 부분이다. 일단 “인증서”가 뭔지 제대로 이해를 하지 못하고 있기 때문이다.

(기존의 기본 인증서로 설정해도 관계 없다. 생성하는 과정만 건너 뛰면 모든 작업은 동일하다.)

먼저 “제어판”에서 “보안” 메뉴를 선택하면 표시되는 “인증서” 탭을 선택한다.

 

synology nas의 Certificate tab
Synology NAS의 제어판-보안 메뉴의 인증서 탭

 

“추가” 버튼을 누르고 “인증서 생성” 창이 실행되면 “새 인증서 추가” 를 선택한 다음 “다음” 버튼을 누른다.

“설명” 에는 적당한 설명을 넣는다. 그리고 “자체 서명 인증서 생성”을 선택한다.

 

synology nas에서 self-sign certificate 만들기
자체 서명 인증서 생성

 

다음과 같이 루트(CA) 인증서 생성에 필요한 기본값을 입력한다. 대충 입력해도 된다.

 

시놀로지 NAS의 셀프사인 인증서 생성
루트 인증서(CA) 생성

 

루트(CA) 인증서를 만들 정보를 입력하고 나면 실제 통신 시 사용할 인증서를 만들게 된다. 입력하는 정보가 아주 조금 다른데… 대충~ 에러가 나지 않도록만 입력하면 된다.

 

시놀로지 NAS에 인증서 만들기

 

“적용” 버튼을 누르면 다음과 같이 인증서가 반들어진다. 그리고 인증서의 유효기간은 생성한 날로부터 1년이다.

 

Synology NAS에 만들어진 Self-sign Certificate
Synology NAS에 만들어진 자체 서명 인증서

 

3. VPN 서버가 새로 만든 인증서를 사용하도록 설정하기

“제어판” – “보안” – “인증서” 탭에서 “구성” 버튼을 누르면 인증서를 사용하는 서비스가 사용할 인증서를 선택할 수 있는 화면이 표시된다.

아래 화면처럼 “VPN Server”가 앞에서 새로 생성한 인증서를 사용하도록 선택해준다.

 

VPN Server가 사용할 인증서 선택하기

 

4. OpenVPN 서버 설정하기

이제 OpenVPN 서버를 설정해줘야 한다.  VPN Server를 설정하기 위해서 VPN Server를 실행하고 “OpenVPN” 메뉴를 선택한다.

그리고 “OpenVPN 서버 활성화”를 체크해준 뒤 다음과 같이 설정한다.

 

 Synology NAS의 OpenVPN Server
Synology NAS의 OpenVPN 서버

 

여기서 중요한 것은 “포트” 항목에 앞의 인터넷 공유기에서 NAS의 IP인 192.168.219.102의 포트포워딩 포트인 10472를 “포트” 항목에 입력하는 것이다.

그리고 나서 “적용” 버튼을 눌러 OpenVPN 서버를 실행한다.

 

OpenVPN 서버 실행

 

OpenVPN 서버를 실행하면 화면 아래에 보이는 “내보내기 구성” 버튼이 활성화된다.

이 버튼을 눌러 OpenVPN 클라이언트에서 OpenVPN 서버에 접속할 때 사용할 “설정 파일”을 저장한다.

 

OpenVPN 설정 내보내기

 

이 OpenVPN 접속 설정 파일을 적당한 이름으로 저장한다. 위에서는 synology-openvpn(10472).zip 파일로 저장했다. 그리고 하나의 파일을 더 저장해야 한다. 바로 인증서 파일이다.

5. 인증서를 파일로 저장하기

다시 인증서 화면으로 간 뒤 아래 화면처럼 새로 생성한 인증서 파일을 “인증서 내보내기” 버튼을 눌러 PC에 저장한다.

 

Synology NAS의 인증서 내보내기

 

인증서 파일은 기본적으로 archive.zip 파일로 저장된다.

지금가지 두개의 파일을 PC에 저장했다. OpenVPN 클라이언트에서 사용할 접속 설정 파일과 인증서 파일 두 개다. 이제 이 두개 파일의 압축을 해제한 뒤 편집해야 한다.

6. OpenVPN 클라이언트 구성 파일 편집

Synology에서 제공하는 VPN 서버의 버그인지… 아니면 원래 그런 것인지 모르겠지만 앞에서 다운로드 받은 OpenVPN 클라이언트 접속 용 구성 파일은 인증서 정보가 제대로 설정되어 다운로드 되지 않는다. 그래서 수동으로 인증서 내용을 편집해 넣어줘야 한다.

먼저 다음과 같이 인증서가 저장된 archive.zip과 OpenVPN 접속 설정파일인 synology-open….zip 파일의 압축을 해제한다.

 

인증서 파일과 OpenVPN 접속 구성파일 압축해제

 

인증서 압축파일을 해제하면 4개의 파일이 표시되는데 cert.pem 파일과 prikey.pem 파일의 내용을 OpenVPN 접속 구성 파일에 추가해줘야 한다.

 

인증서 압축파일 해제하면 표시되는 4개의 파일

 

OpenVPN 접속 구성 파일이 포함된 zip 파일을 압축해제하면 VPNConfig.ovpn 이라는 OpenVPN 접속 용 구성파일이 보인다. 이 파일을 Notepad 등으로 열어준다.

 

OpenVPN 접속 용 구성파일 열기

 

먼저 상단에 위치한 YOUR_SERVER_IP를 인터넷 공유기에 할당된 외부 공인IP로 수정한다. 만약 시놀로지의 DDNS를 이용해 xxx.synology.me 와 같은 도메인주소를 사용한다면 그 도메인주소를 입력해주면 된다.

 

ovpn파일 편집하기

 

다음은 새로운 Notepad을 열어 인증서 파일들 중 cert.pem 파일을 다음과 같이 연다.

 

cert.pem
cert.pem 파일

 

위의 cert.pem 파일의 내용 전체를 다음과 같이 VPNConfig.ovpn 파일을 열고 가장 아래부분의 </ca> 뒷 부분에 <cert> 태그를 추가하고 그 뒤에 붙여넣는다.

 

.ovpn 파일의 가장 뒤에 cert.pem 파일의 내용을 붙여 넣는다.

 

그리고 가장 뒷 부분에 </cert>을 추가한다.

마찬가지로 인증서 파일들 중 prikey.pem 파일의 내용을 모두 복사해 VPNConfig.ovpn 파일의 맨 뒷 부분에 <key> 태그를 추가한 뒤 붙여넣는다.

 

.ovpn 파일의 끝에 prikey.pem 파일의 내용을 추가한다.

 

그리고 맨 끝에 </key>를 추가해준 뒤 저장한다.

여기까지 진행하면 OpenVPN 클라이언트 프로그램이 OpenVPN 서버에 접속할 때 사용할 구성파일이 완성된다.

7. OpenVPN Client 설치하고 접속 구성 파일 복사하기

OpenVPN 서버에 접속하여 암호화 된 안전한 Private(사설) 네트워크를 만들기 위해서는 OpenVPN GUI라는 클라이언트 프로그램을 설치하여야 한다. 다운로드는 여기에서 받으면 된다.

기본 옵션으로 설치한 뒤 앞에서 편집한 VPNConfig.ovpn 파일을 아래와 같이 기본 config 경로에 복사한다.

 

.ovpn 파일 복사하기

 

이 때 관리자권한이 필요한데 관리자 권한을 부여하여 복사해 넣으면 된다.

8. OpenVPN 서버에 OpenVPN GUI로 접속하기

설치하고 나면 VPNConfig 라는 접속 구성이 보인다. 아래와 같이 “연결”을 눌러 OpenVPN 서버에 접속하면 된다.

 

OpenVPN GUI를 통해 접속하기

 

ID와 비밀번호를 묻는 창이 실행되면 시놀로지의 접소계정을 입력하면 된다. 다만 해당 계정은 시놀로지 DSM에서 OpenVPN 접속이 허용된 계정이어야 한다.

 

OpenVPN 서버에 접속하기
시롤로지 OpenVPN 서버에 접속하기

 

접속이 되면 다음과 같이 접속상태를 확인할 수 있고 “연결해제” 버튼을 눌러 VPN 네트워크를 파괴하여 접속을 끊을 수도 있다.

 

Synology NAS 오픈VPN 접속 상태

DNS TXT Record 로 Let’s Encrypt SSL 인증서 발급 받기

TXT 레코드 요청

  1. certbot 을 실행할 때 –manual 옵션과 –preferred-challenges dns 을 주어서 실행합니다.
    certbot certonly -d new.lesstif.com --manual --preferred-challenges dns
  2. IP 로깅을 허용하겠냐고 묻는 화면에서 Y 를 입력합니다.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NOTE: The IP of this machine will be publicly logged as having requested this
    certificate. If you're running certbot in manual mode on a machine that is not
    your server, please ensure you're okay with that.
    
    Are you OK with your IP being logged?
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    (Y)es/(N)o: Y
  3. TXT 에 등록할 내용이 출력되면 복사해 둡니다.
    Please deploy a DNS TXT record under the name
    _acme-challenge.new.lesstif.com with the following value:
    
    slqQSBrs4rToROM7LyEeBVvI92YXi3JJ-RK6S5OBKNc
    
    Before continuing, verify the record is deployed.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Press Enter to Continue
  4.  DNS 서버에 TXT 레코드를 등록합니다. DNS 서비스 제공자에 따라 화면이 다를 수 있습니다.
  5. 새로운 터미널을 열고 정상적으로 등록됐는지 확인합니다.
    $ nslookup -q=TXT _acme-challenge.new.lesstif.com
    
    
    Server:         168.126.63.1
    Address:        168.126.63.1#53
    
    Non-authoritative answer:
    _acme-challenge.new.lesstif.com text = "slqQSBrs4rToROM7LyEeBVvI92YXi3JJ-RK6S5OBKNc"
    
    Authoritative answers can be found from:
  6. 기존 let’s encrypt 발급 터미널로 간 후에 엔터를 입력합니다.
  7. 정상 발급되었는지 확인하고 웹 서버를 설정합니다.
    Waiting for verification...
    Cleaning up challenges
    
    IMPORTANT NOTES:
     - Congratulations! Your certificate and chain have been saved at:
       /etc/letsencrypt/live/new.lesstif.com/fullchain.pem
       Your key file has been saved at:
       /etc/letsencrypt/live/new.lesstif.com/privkey.pem

Boot2Docker Volume Disk Resize

Boot2Docker에서 “장치에 남은 공간 없음” 오류가 발생합니까?

많은 수의 이미지와 함께 Boot2Docker를 사용하거나 작업 중인 이미지가 매우 큰 경우 Boot2Docker VM의 볼륨 공간이 부족하면 문제가 발생할 수 있습니다. 솔루션은 먼저 볼륨을 복제한 다음 디스크 파티셔닝 도구를 사용하여 크기를 조정하여 볼륨 크기를 늘리는 것입니다. (GParted)[ http://gparted.sourceforge.net/download.php/index.php ]는 무료 ISO이고 VirtualBox와 잘 작동하기 때문에 사용하겠습니다.

1. Boot2Docker의 VM을 중지합니다.

$ boot2docker stop 

Boot2Docker는 VirtualBox의 기본 도구로 크기를 조정할 수 없는 VMDK 이미지와 함께 제공됩니다. 대신 VDI 볼륨을 만들고 VMDK 볼륨을 여기에 복제합니다.

2. VirtualBox 명령줄 도구를 사용하여 VMDK 이미지를 VDI 이미지로 복제합니다.

$ vboxmanage clonehd /full/path/to/boot2docker-hd.vmdk /full/path/to/<newVDIimage>.vdi —format VDI —variant Standard

3. 필요에 적합한 크기를 선택하여 새 복제 볼륨의 크기를 조정합니다. 많은 컨테이너를 회전하거나 컨테이너가 특히 큰 경우 더 큰 것이 좋습니다.

$ vboxmanage modifyhd /full/path/to/<newVDIimage>.vdi —resize <size in MB>

4. (GParted)[ http://gparted.sourceforge.net/download.php/ ] 와 같은 디스크 파티션 도구 ISO를 다운로드합니다 . Boot2Docker VM의 IDE 버스에 ISO를 추가합니다. ISO를 추가하기 전에 버스를 생성해야 할 수도 있습니다.

5. VirtualBox의 Boot2Docker 이미지에 새 VDI 이미지를 추가합니다.

6. Boot2Docker VM에 대한 설정에서 CD/DVD가 부팅 순서 목록 의 맨 위에 있는지 확인 합니다.

7. VirtualBox에서 Boot2Docker VM을 시작하면 디스크 파티션 ISO가 시작됩니다. 

GParted를 사용하여 GParted Live(기본 설정) 옵션을 선택합니다. 기본 키보드, 언어 및 XWindows 설정을 선택하면 GParted 도구가 시작되고 생성한 새 VDI 볼륨이 표시됩니다. VDI를 마우스 오른쪽 버튼으로 클릭하고 크기 조정/이동 을 선택합니다 . 볼륨을 나타내는 슬라이더를 최대 크기로 끌어 크기 조정/이동 을 클릭 한 다음 적용 을 클릭 합니다. GParted를 종료하고 VM을 종료합니다. VirtualBox의 Boot2Docker VM용 IDE 컨트롤러에서 GParted ISO를 제거합니다.

8. VirtualBox에서 또는 명령줄( boot2docker start)을 사용하여 Boot2Docker VM을 시작하여 볼륨 변경 사항이 적용되었는지 확인합니다.

Apache에서 gzip을 이용한 압축전송하기

웹서비스 최적화 방법중에 하나로 gzip 압축전송이 있습니다.
gzip은 파일 압축에 쓰이는 응용 소프트웨어로 GNU zip의 준말이며 무료 소프트웨어이다(출처: 위키백과)
이를 사용하기 위해서는 사용하는 브라우저가 지원을 해야합니다.
(브라우저에서 request headers > “Accept-Encoding”에 gzip이 포함되어 있어야 합니다.)

마찬가지로 서버에서도 gzip으로 전송해야 합니다.
(response headers > “Content-Encodding:gzip”)

배경

일반적인 Http Request & Response와 gzip사용시 차이점을 간단히 설명하면 다음과 같습니다.

1.브라우저에서 index.html을 서버에 요청합니다.

2.서버는 해당 파일을 찾습니다.

3.파일을 요청한 브라우저로 전송합니다(100KB).

4.브라우저는 해당 파일을 표시합니다.

 

 

1.브라우저에서 index.html을 서버로 요청시 gzip을 지원한다는 내용을 서버로 전달합니다.

2.서버는 해당 파일을 찾습니다.

3.gzip으로 파일을 압축해서 보냅니다(30KB).

4.브라우저에서 압축된 파일을 풀고 표시합니다.

테스트 환경

  • 서버 OS: Windows7
  • 웹서버: Apache 2.4
  • 브라우저: IE9, 크롬, Firefox, Safari
환경설정

1.Apache httpd.conf 파일 열기
2.LoadModule 영역에서 아래내용에 주석처리 되었으면 해제합니다.

LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
LoadModule filter_module modules/mod_filter.so
3.적당한 위치에 아래 내용을 추가합니다.
<IfModule mod_deflate.c>

        AddOutputFilterByType DEFLATE text/plain
        AddOutputFilterByType DEFLATE text/html
        AddOutputFilterByType DEFLATE text/xml
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE application/xml
        AddOutputFilterByType DEFLATE application/xhtml+xml
        AddOutputFilterByType DEFLATE application/rss+xml
        AddOutputFilterByType DEFLATE application/javascript
        AddOutputFilterByType DEFLATE application/x-javascript

        DeflateCompressionLevel 9

        BrowserMatch ^Mozilla/4 gzip-only-text/html  # Netscape 4.xx에는 HTML만 압축해서 보냄
        BrowserMatch ^Mozilla/4\.0[678] no-gzip  # Netscape 4.06~4.08에는 압축해서 보내지 않음
        BrowserMatch \bMSIE !no-gzip !gzip-only-text/html  # 자신을 Mozilla로 알리는 MSIE에는 그대로 압축해서 보냄
        
        ##예외 설정
        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|bmp|zip|gz|rar|7z)$ no-gzip dont-vary
        
        ####로그설정.
        ##DeflateFilterNote Input instream
        ##DeflateFilterNote Output outstream
        ##DeflateFilterNote Ratio ratio
        ##
        ##LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
        ##CustomLog logs/deflate_log deflate

4.아파치를 restart 시킨 후 아래 사이트에서 gzip전송이 정상동작하는지 테스트 합니다.

http://www.whatsmyip.org/http-compression-test/

 

위 결과 페이지에서는 특정페이지가 84.5% 절감되고 있습니다.

Response Headers 내용은 아래와 같습니다.

 

 

 

 

 

※ 3번 “로그설정” 주석해제 후 apache logs폴더에 생성된 deflate_log파일을 보면 압축률을 확인할 수 있습니다.

.

"GET /nexacro14lib/framework/SystemBase.js HTTP/1.1" 23987/176486 (13%)
"GET /nexacro14lib/framework/Platform_HTML5.js HTTP/1.1" 18786/138984 (13%)
"GET /nexacro14lib/framework/ErrorDefine.js HTTP/1.1" 4886/18684 (26%)
"GET /nexacro14lib/framework/CssObjs.js HTTP/1.1" 25266/271916 (9%)
"GET /nexacro14lib/framework/BasicObjs.js HTTP/1.1" 9152/50003 (18%)
"GET /nexacro14lib/framework/Platform.js HTTP/1.1" 58726/370077 (15%)
"GET /nexacro14lib/framework/SystemBase_HTML5.js HTTP/1.1" 50261/334443 (15%)
"GET /nexacro14lib/component/CompBase/CompBase.js HTTP/1.1" 28574/167299 (17%)
"GET /nexacro14lib/component/CompBase/CompEventBase.js HTTP/1.1" 17397/255753 (6%)

미리 gzip으로 압축후 사용할 순 없을까?
gzip 사용시 단점은 요청시 gzip으로 압축하는 과정으로 인해
서버의 CPU사용량이 gzip을 사용하지 않을 때 보다 증가한다는 것이다.
그렇다면 거의 변할 일이 없는 file은 미리 압축해서 사용하는것도 괜찮지 않을까?
1.gzip으로 압축하기
Online YUI Compressor에 접속 후 아래그림 처럼 소스를 gz파일로 변환한다.
① 원하는 소스를 붙여넣기 한다.
② 결과는 “Redirect to gzipped output”을 선택한다.
③ “Compress”버튼을 누르면 잠시 후 파일을 저장할 수 있는 팝업창이 표시된다.
④ “gz”확장자로 원하는 위치와 파일명으로 저장합니다.

 

 

2.해당 파일을 영역안에 포함시킵니다.
<script type="text/javascript" src="./pkg/EcoBasic.js.gz"></script>
3.위와 같이 하고 해당페이지에 접속하면 아래처럼 log가 발생하고 정상적으로 load되지 않습니다(크롬).
Content-Encoding:gzip
Content-Type:application/x-gzip

Resource interpreted as Script but transferred with MIME type application/x-gzip: "http:// ~ /pkg/EcoBasic.js.gz". 
4.Apache httpd.conf 파일의 LoadModule 영역에서 아래내용에 주석처리 되었으면 해제합니다.
​LoadModule dir_module modules/mod_dir.so
  아래 2줄을 주석처리 되어있으면 해제합니다.
AddEncoding x-compress .Z
AddEncoding x-gzip .gz .tgz
  아래 2줄을 주석처리 합니다.
#AddType application/x-compress .Z
#AddType application/x-gzip .gz .tgz
  아래 내용도 추가해야 한다고 나와있었는데 실제로 해보니 적용하지 않아도 처리되었습니다(참고하세요).
  :gz 확장자에 대해서 강제로 content-encoding을 설정하는 내용입니다.
# root .
<Directory /~/EcoPkg>
    Options Indexes MultiViews FollowSymLinks
    #AllowOverride None
    #Order deny,allow
    #Deny from all
    #Allow from 127.0.0.0/255.0.0.0::1/128 

    AddEncoding gzip gz
    <FilesMatch "\.gz$">
      ForceType text/plain
      Header set Content-Encoding: gzip
    FilesMatch>
    
##   <FilesMatch "\.css\.gz$">
##        ForceType text/css
##        Header set Content-Encoding: gzip
##    FilesMatch>
Directory>
5.설정 후 아파치 restart후에 Response Headers를 확인하면 다음과 같습니다.

 

 

 

 

 

마치며…

※ RUNTIME(2014,9,3,1 버전 기준)에서는 지원하지 않습니다.
이미지와 PDF파일은 gzip으로 압축하지 않는다(이미 압축되어 있음).
gzip을 지원하는 브라우저 목록(출처: webmasters.stackexchange.com, 참고: schroepl.net)
  • Netscape 6+ (Netscape 4-5 does, but with some bugs).
  • Internet Explorer 5.5+ (July 2000) and IE 4 if set to HTTP/1.1.
  • Opera 5+ (June 2000)
  • Firefox 0.9.5+ (October 2001)
  • Chrome since forever
  • Safari since forever (as far as I can tell)
이 글에서는 Apache httpd.conf 파일을 이용한 예제가 작성되었지만 .htaccess 파일을 이용할 수 도 있다.