Kubernetes 기본 설치(Version 1.28)

구성 내역

Kubernetes 1.28.2
Ubuntu 22.04.3 LTS
Container : cri-dockerd
CNI : calico
구성용 계정 : ubuntuadm
Master node : k8s-master-01
Worker node : k8s-worker-01 ~ 02

구성전 모든 노드의 swap은 off 처리…

[공통]

cri-docker 설치 시작

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo systemctl enable –now docker && sudo systemctl status docker –no-pager
sudo usermod -aG docker ubuntuadm
sudo docker container ls

cri-docker Install
VER=$(curl -s https://api.github.com/repos/Mirantis/cri-dockerd/releases/latest|grep tag_name | cut -d ‘”‘ -f 4|sed ‘s/v//g’)
echo $VER
wget https://github.com/Mirantis/cri-dockerd/releases/download/v${VER}/cri-dockerd-${VER}.amd64.tgz
tar xvf cri-dockerd-${VER}.amd64.tgz
sudo mv cri-dockerd/cri-dockerd /usr/local/bin/

cri-docker Version Check
cri-dockerd –version

wget https://raw.githubusercontent.com/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.service
wget https://raw.githubusercontent.com/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.socket
sudo mv cri-docker.socket cri-docker.service /etc/systemd/system/
sudo sed -i -e ‘s,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,’ /etc/systemd/system/cri-docker.service

sudo systemctl daemon-reload
sudo systemctl enable cri-docker.service
sudo systemctl enable –now cri-docker.socket

cri-docker Active Check
sudo systemctl restart docker && sudo systemctl restart cri-docker
sudo systemctl status cri-docker.socket –no-pager

Docker cgroup Change Require to Systemd
sudo 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

sudo systemctl restart docker && sudo systemctl restart cri-docker
sudo docker info | grep Cgroup

환경 설정

Kernel Forwarding
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

sudo sysctl –system

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

필요한 sysctl 파라미터를 설정하면, 재부팅 후에도 값이 유지된다.
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF

재부팅하지 않고 sysctl 파라미터 적용하기
sudo sysctl –system

Package 설치

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl

sudo curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

sudo curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://dl.k8s.io/apt/doc/apt-key.gpg && \
echo “deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main” | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

sudo systemctl daemon-reload
sudo systemctl restart kubelet

[Master node]

sudo kubeadm config images pull –cri-socket unix:///run/cri-dockerd.sock
sudo kubeadm init –cri-socket /var/run/cri-dockerd.sock

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

kubectl get nodes -o wide
kubectl get pods -A
kubectl describe node k8s-master-01

Calico CNI 설치
curl https://projectcalico.docs.tigera.io/manifests/calico.yaml -O

curl https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml -O
kubectl apply -f calico.yaml

kubectl get nodes
kubectl get pod –all-namespaces

[worker node]

kubeadm init 실행시 마지막 출력되는 명령어 사용
sudo kubeadm join 192.168.0.101:6443 –token xxxxxxxxxxxx \
–discovery-token-ca-cert-hash sha256:xxxxxxxxxxxx \
–cri-socket /var/run/cri-dockerd.sock

kubectl get nodes

kubectl 명령어 자동 완성

https://kubernetes.io/ko/docs/tasks/tools/included/optional-kubectl-configs-bash-linux/

echo ‘source <(kubectl completion bash)’ >>~/.bashrc
echo ‘alias k=kubectl’ >>~/.bashrc
echo ‘complete -o default -F __start_kubectl k’ >>~/.bashrc

Kubernetes 기본 설치(Version 1.28) 더 읽기"

특수 문자(Special Character) 문제(&#65279)

cvc-complex-type.2.3 오류

09:52:06,504 WARNING [com.hazelcast.web.ClusteredSessionService] (default task-1) Cannot connect to Hazelcast server: cvc-complex-type.2.3: Element 'near-cache' cannot have character [children], because the type's content type is element-only. 
09:52:06,962 WARNING [com.hazelcast.web.HazelcastHttpSession] (default task-1) Unexpected error occurred.: java.lang.NullPointerException 
 at com.hazelcast.web.ClusteredSessionService.updateAttributes(ClusteredSessionService.java:285) 
 at com.hazelcast.web.HazelcastHttpSession.sessionDeferredWrite(HazelcastHttpSession.java:300) 
 at com.hazelcast.web.WebFilter.doFilter(WebFilter.java:303) 
 at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) 
 at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) 
 at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) 
 at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) 
 at io.undertow.jsp.JspFileHandler.handleRequest(JspFileHandler.java:32) 
 at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) 
 at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) 
 ...
  • 일반적인 오류 해결법
  1. XML 태그 정보 누락 여부 재확인
<?xml version="1.0" encoding="UTF-8" ?>
  1. IDE 문제 – 이클립스 또는 STS 재기동
  2. 오타 여부 재확인 – 특수문자의 오기입 또는 오탈자로 인해 발생 가능 합니다.
  • 그게 아니면…..
  1. UTF-8 인코딩의 BOM(Byte Order Mark) 문제….
  2. UTF-8, UTF-16 등의 유니코드 인코딩 방식을 알리기 위한 사인(Signature)으로 사용하기 위한 용도 입니다.
  3. UTF-8은 BOM 없이도 인코딩 인식이 가능하지만 노트패드등의 윈도우 환경의 일부 에디터가 BOM을 자동으로 추가 하게 되며 눈에 보이지 않는 특수 문자(여백 문자)가 추가 되게 됩니다. 이로 인해 UNIX 환경에서 예상치 않은 cvc-complex-type.2.3 오류가 발생할 수 있습니다.
  • 해결 방안
  1. Notepad++, Ultraeditor, EditPlus 등의 에디터를 이용해 ‘UTF-8 without BOM’ (BOM 없는 UTF-8) 으로 저장
  2. 개인적으로는 BOM 없는 UTF-8로 저장이 안되어서 태그 앞의 여백 부분을 모두 삭제하여 해결 하였습니다.
  3. 윈도우에서 코드를 저장할 때는 항상 인코딩에 주의를 해야할 듯 합니다. 🙂

출처

http://blog.wystan.net/2007/08/18/bom-byte-order-mark-problem

https://ko.wikipedia.org/wiki/%EB%B0%94%EC%9D%B4%ED%8A%B8_%EC%88%9C%EC%84%9C_%ED%91%9C%EC%8B%9D

특수 문자(Special Character) 문제(&#65279) 더 읽기"

Hazelcast WEB Session Clustering

  • Concept

기본 목적은 로드 밸런싱으로 묶인 WAS 그룹간의 세션 정보의 공유이며 그룹내의 임의의 WAS가 Fail over되어도 세션 정보를 유실하지 않고 다른 WAS에서 세션 연결을 가능케 하는 것입니다.

그로 인해 부가적으로 이기종 WAS간에도 세션 공유를 가능케 할 수 있다는 큰 이점이 있습니다.

  • 구동 방식
  1. 사용자의 request가 was에 도달(servlet container)
  2. request의 session id를 대조 하는 절차 진행시(WAS에서 세션 정보 조회 전)
  3.  webfilter를 통해 request의 쿠키가 가진 session id를 IMDG의 맵에서 조회
  4. 조회 값을 반환 할 경우 기존 session으로 할당 처리( 후 request 응답 처리)
  5. 조회 값이 없을 경우 webfilter를 통해 지정된 형식으로 session id 생성 후 그 id로 sessionlistener를 통해 httpsession 생성
  6. request가 완료되면 생성된 session 정보를 IMDG 맵에 저장
  • IMDG

노드들을 클러스터 구성 하여 여러 서버의 메모리를 파티셔닝 또는 샤딩이라는 기술을 통해 하나의 메모리 공간처럼 활용, 데이터를 임의의 노드 메모리에 분산 저장시 실시간 또는 비동기로 생성된 백업 데이터는 원본 데이터를 소유한 노드 이외의 다른 노드에 분산 저장됩니다.
이 기능을 이용하여 세션 정보의 손실을 방지 하며 빠른 I/O 성능을 보장합니다.

https://www.sierracloud.kro.kr/imdg-overview/

  • 구성 ( hazelcast 3.12 기준, JDK 1.8 )
  1. WEB-INF에 web.xml 및 hazelcast-client.xml 설정
  2. WEB-INF/lib 또는 Classpath에 hazelcast-wm.jar(hazelcast-all.jar 가능) 위치
  • web.xml 설정
<!-- hazelcast filter start -->
<filter>
    <filter-name>hazelcast-filter</filter-name>
    <filter-class>com.hazelcast.web.WebFilter</filter-class>
    <init-param>
        <param-name>map-name</param-name>
        <param-value>hazelcast-sessions</param-value>
    </init-param>
    <init-param> <!-- Embedded only -->
        <param-name>session-ttl-seconds</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>keep-remote-active</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>sticky-session</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>cookie-name</param-name>
        <param-value>hazelcast.sessionId</param-value>
    </init-param>
    <init-param> <!-- 도메인 없을 때 비울것 -->
        <param-name>cookie-domain</param-name>
        <param-value>www.example.com</param-value>
    </init-param>
    <init-param>
        <param-name>cookie-secure</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>cookie-http-only</param-name>
        <param-value>false</param-value><!-- default false -->
    </init-param>
    <init-param>
        <param-name>debug</param-name>
        <param-value>true</param-value><!-- default false -->
    </init-param>
    <init-param>
        <param-name>shutdown-on-destroy</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>    <!--    이부분이 설정파일의 위치(Embaded 설정)    -->
        <param-name>config-location</param-name>
        <param-value>/WEB-INF/config/spring/my-hazelcast.xml</param-value>
    </init-param>
    <init-param>
        <param-name>instance-name</param-name>
        <param-value>hazel-ses</param-value>
    </init-param>
    <init-param> <!-- Client mode only -->
        <param-name>use-client</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>  <!-- Client Configuration(or hazelcast-client.xml) -->
        <param-name>client-config-location</param-name>
        <param-value>/WEB-INF/classes/hazelcast-client.properties</param-value>
    </init-param>
    <init-param>
        <param-name>deferred-write</param-name>
        <param-value>true</param-value><!-- default false -->
    </init-param>
    <init-param>
        <param-name>cookie-path</param-name>
        <param-value>/</param-value>
    </init-param>
    <init-param>
        <param-name>cookie-max-age</param-name>
        <param-value>-1</param-value>
    </init-param>
    <init-param>
        <param-name>use-request-parameter</param-name>
        <param-value>false</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>hazelcast-filter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

<listener>
    <listener-class>com.hazelcast.web.SessionListener</listener-class>
</listener>
<!-- hazelcast filter end -->
TopicDescDefault
map-name세션 오브젝트가 저장될 분산맵의 이름 선언
session-ttl-seconds세션 오브젝트가 저장될 분산맵의 수명(초) 설정, 0이상의 정수형(최대2147483647)으로 설정1800(30분)
sticky-sessiontrue 설정시, 모든 세션 요청이 세션이 처음 만들어진 멤버로 라우팅 됨. 더 좋은 성능을 제공함. false 설정시, 세션이 멤버상에서 업데이트 될 때, 모든 멤버상의 이 세션 엔트리는 무효화 됨.
이 파라메터를 설정하기 전에 로드 밸런서(L4) 구성상황을 알 필요가 있음
true
Generic Parameter 의미
  • Client config 구성 ( hazelcast-client.xml )
<hazelcast-client>
...
    <group>
        <name>dev</name>
        <password>dev-pass</password>
    </group>

    <network>
        <cluster-members>
            <!--MEMBERS-->
            <address>192.168.0.101</address>
            <address>192.168.0.102</address>
            <address>192.168.0.103</address>
        </cluster-members>
    </network>
    <load-balancer type="round-robin"/>

...
</hazelcast-client>

Hazelcast WEB Session Clustering 더 읽기"

위로 스크롤