반응형

 

kubernetes는 보통 node당 110개의 pod 할당이 가능합니다. (CIDR이 24인 경우)

 

 

maxPod값인 110의 숫자는 아래의 명령어를 통해 확인할 수 있습니다 (노드별로 보여줍니다)

kubectl get nodes -o=custom-columns=NAME:.metadata.name,CAPACITY:.status.capacity.pods

 

그리고 현재 노드별로 할당된 pod의 개수는 다음의 명령어로 알 수 있습니다.

kubectl describe node | grep -E "(^Name:|^Non-terminated)"

 

이 max pods의 값을 바꾸는 방법은 아래의 파일을 편집합니다.

vi /var/lib/kubelet/config.yaml

파일 내용중 maxPods 라는 값이 있으면 변경하면 되지만 없으면

맨 아래 (보통 volumeStatsAggPeriod: 0s 값 아래에 적습니다) 에 maxPods: 값을 넣습니다

 

애초에 네트워크 할당 범위가 CIDR 24로 되어 있기 때문에 200이상의 숫자는 의미 없을 수 있지만 어쨋든 조정이 가능합니다.

반응형
반응형

한국에서 사용하기 적합하게 수정된 ubuntu 기반의 Docker Container 입니다. 다음의 버전들을 지원합니다.

  • 16.04 (ghcr.io/declue/docker_ubuntu:16.04)
  • 18.04 (ghcr.io/declue/docker_ubuntu:18.04)
  • 20.04 (ghcr.io/declue/docker_ubuntu:20.04)
  • 22.04 (ghcr.io/declue/docker_ubuntu:22.04)

이미 만들어진 이미지를 사용하겠다면 아래와 같은 형태로 명령어를 입력해보세요

docker pull ghcr.io/declue/docker_ubuntu:20.04

 

배포된 이미지에 대한 pakcage 정보는 다음과 같습니다.

주요 변경 사항

  • Locale을 한국으로 변경
  • Encoding을 ko_KR.UTF-8로 변경
  • Nanum 폰트 적용
  • Timezone을 한국으로 변경

기본 설치 프로그램

  • vim
  • net-tools
  • ip-utils
  • wget
  • curl
  • apt-utils
  • language-pack-ko
  • tree
  • jq

 

아래는 Dockerfile의 구성 내용입니다.

(2023-01-26 기준, 최신 코드는 https://github.com/declue/docker_ubuntu에 있습니다.)

 

ARG BASE_IMAGE

FROM $BASE_IMAGE

ENV DEBIAN_FORNTEND="noninteractive"

RUN apt-get update && \ 
    apt-get install -y --no-install-recommends apt-utils && \
    apt upgrade -y
 
# for Hangul
RUN apt-get install -y language-pack-ko && \
    dpkg-reconfigure locales && \
    locale-gen ko_KR.UTF-8 && \
    /usr/sbin/update-locale LANG=ko_KR.UTF-8  && \
    apt-get install -y fonts-nanum fonts-nanum-coding 

ENV LANG=ko_KR.UTF-8 
ENV LANGUAGE=ko_KR.UTF-8 
ENV LC_ALL=ko_KR.UTF-8

# Timezone
ENV TZ Asia/Seoul 
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get install -y vim net-tools iputils-ping curl wget tree jq
반응형
반응형

클러스터 안에 있는 jenkins pod에서 플러그인을 설치할려 했더니 다음과 같은 에러가 발생하였습니다

 

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
	at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434)
Caused: sun.security.validator.ValidatorException: PKIX path building failed
	at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439)
	at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
	at java.base/sun.security.validator.Validator.validate(Validator.java:264)
	at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:313)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:222)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1341)
Caused: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 

 

아니 회사의 프록시 환경도 아닌데 왜 이런 에러가 나지? 해서 원인을 분석했더니 

self signed certificate 라고 잡히네요.

#  curl https://google.com -v
*   Trying 12.34.56.78:443...
* Connected to google.com (12.34.56.78) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: self signed certificate
* Closing connection 0
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.se/docs/sslcerts.htmlcurl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

회사와 같이 프록시와 사내 인증서가 적용된 환경이 아닌데 왜 이런 현상이 발생하는지 계속 분석해보니

어떨때는 또 통신이 되기도 합니다.

그래서 무슨 차이인가 하여 traceroute를 시도해봤습니다.

 

정상적인 상황에서는 아래와 같이 통신을 하지만

# traceroute google.com
traceroute to google.com (172.217.25.174), 30 hops max, 60 byte packets
 1  12-34-56-78.etcd.kube-system.svc.cluster.local (12.34.56.78)  0.689 ms  0.579 ms  0.541 ms
 2  12.34.56.78 (12.34.56.78)  2.570 ms  2.532 ms  2.502 ms
 3  * * *
 4  100.82.171.49 (100.82.171.49)  1.135 ms 100.82.171.45 (100.82.171.45)  0.883 ms  0.844 ms
 5  10.67.252.254 (10.67.252.254)  1.199 ms 10.67.252.250 (10.67.252.250)  4.219 ms 10.67.252.254 (10.67.252.254)  1.131 ms
 6  10.222.35.212 (10.222.35.212)  2.253 ms 10.222.22.240 (10.222.22.240)  2.288 ms 10.222.18.160 (10.222.18.160)  1.949 ms
 7  10.222.8.175 (10.222.8.175)  4.351 ms 10.222.20.25 (10.222.20.25)  6.528 ms 10.222.23.203 (10.222.23.203)  2.034 ms
 8  72.14.203.90 (72.14.203.90)  30.108 ms 142.250.163.48 (142.250.163.48)  29.981 ms
 72.14.216.72 (72.14.216.72)  36.144 ms
 9  * * *
10  108.170.242.193 (108.170.242.193)  32.943 ms 108.170.242.129 (108.170.242.129)  35.381 ms 142.250.208.146 (142.250.208.146)  39.221 ms11  108.170.242.146 (108.170.242.146)  32.762 ms 108.170.242.209 (108.170.242.209)  39.643 ms 108.170.242.208 (108.170.242.208)  34.475 ms
12  209.85.246.213 (209.85.246.213)  36.130 msc 216.239.43.157 (216.239.43.157)  34.211 ms 209.85.241.107 (209.85.241.107)  34.799 ms
13  142.250.229.250 (142.250.229.250)  34.535 ms  37.353 ms sin01s16-in-f14.1e100.net (172.217.25.174)  29.530 ms

 

비정상적인 상황에서는 클러스터의 ip에서 통신이 멈춥니다

# traceroute google.com
traceroute to google.com (12.34.56.78), 30 hops max, 60 byte packets

아니 google.com의 IP가 왜 12.34.56.78이지??? 이상한 의문이 들어 172.217.25.174(제대로된 google.com의 IP)로

통신을 해보니 이건 또 잘되군요

 

여기에서 DNS 쪽이 뭔가 문제가 있구나 생각이 되어 확인을 해봤더니..

그게 원인이 맞았습니다.

 

/etc/resolv.conf의 내용을 보니 아래와 같이 되어 있는데

search infra-jenkins.svc.cluster.local svc.cluster.local cluster.local mycluster.internal

mycluster.internal 에 대한 nslookup 수행시 간헐적으로 master node의 ip가 리턴이 되고 있더군요

 

이에 대해 원인을 분석해보니 

cluster 내부의 pod 들에게 ingress 설정을 위해 *.mycluster.internal 의 주소를 cluster의 master node의 IP로 하였더니

이로 인해 pod 내부에서 mycluster.internal에 대한 NXDOMAIN에 대한 DNS 쿼리 호출 시 

mycluster.internal.mycluster.internal 로 접근을 시도 하였고 이를 다시 mater node의 IP로 반환이 되어

mater node에 있는 리버스 프록시 목적의 nginx 인증서를 사용하고 있었던 겁니다.

 

좀 어이 없는 상황이긴 한데.. pod 내부의 resolv.conf의 내용을 제대로된 도메인으로 접근할 수 있게

ns.mycluster.internal 로 변경하였습니다.

 

그랬더니 문제가 해결이 되네요.

 

좀 이상하게 해결되긴 했지만 통신이 잘되니.. 나중에 잊을 수 있는 트러블 슈팅 과정이라 이 과정을 남깁니다

반응형
반응형

ubuntu에서 helm 설치

sudo snap install helm --classic

맥(osx)에서 helm 설치

brew install helm

helm chart 생성하기

helm create default

default라는 폴더가 생성되고 하위에 다음과 같은 파일이 자동 생성됩니다

.
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

helm package 파일 생성

helm package default

default라는 폴더를 대상으로 packaing을 하여 default-0.1.0.tgz 라는 파일이 생성됩니다

 

helm index 생성

helm repo index .

index.yaml을 생성합니다. 이를 통해 helm chart 사용이 가능해집니다

 

helm chart 검증

helm lint default

default 패키지에 대해 lint 검사를 합니다

 

helm template 검증

helm template default

default 패키지에 대해 values.yaml의 내용을 template 폴더의 오브젝트에 반영하여 보여줍니다.

 

공식 helm repo

helm repo add stable https://charts.helm.sh/stable
반응형
반응형

kubernetes에서 cluster에 join을 할 경우 다음과 같은 명령어를 해야 합니다

 

kubeadm join <Kubernetes API Server:PORT> --token <2. Token 값> --discovery-token-ca-cert-hash sha256:<3. Hash 값>

예시)
kubeadm join 12.34.56.78:6443 --token xojh9n.xbz82ulgr2obqncf --discovery-token-ca-cert-hash sha256:991d9c483402c7109460b9c9aad65923d502075d522b1c7853bbc5f060ef1a60

 

하지만 토큰 값은 시간이 지나면 사라집니다. 이러한 토큰이 실제 존재하는지 확인하는 명령은 아래와 같습니다.

kubeadm token list

만약 아무것도 안뜨면 다음의 명령어를 입력하여 토큰을 생성합니다

kubeadm token create

 

해시값을 모를 경우 다음의 명령을 통해 확인 할 수 있습니다

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

 

클러스터의 포트는 보통 6443이지만 만약 다를 경우 다음의 명령을 통해 확인할 수 있습니다

kubectl cluster-info
반응형
반응형

Helm Repo를 등록합니다

sudo helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/

nfs-subdir-external-provisioner를 설치합니다

sudo helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
    --set nfs.server=202.202.202.168 \
    --set nfs.path=/volume1/nfs_volume \
    --kubeconfig ~/.kube/config

nfs-subdir-external-provisioner를 default storage class로 선언합니다

kubectl patch storageclass nfs-client \
    -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

 

반응형

'인프라 관리 > ▷ Docker & Kubernetes' 카테고리의 다른 글

helm 사용법  (0) 2023.01.22
kubernetes에서 join을 위한 token 생성  (0) 2023.01.22
Kubernetes 설치  (0) 2023.01.22
cri-o 설치  (1) 2023.01.22
kubernetes에서 JIRA 구성  (0) 2022.04.18
반응형

먼저 사전에 다음의 패키지를 설치해야 합니다

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

그리고 swapoff를 해줘야 합니다

sudo swapoff -a

# 매번 재부팅하면 swapoff 명령어를 입력할 수 없으니 /etc/fstab에 자동으로 반영되도록 합니다
sudo sed -i.bak '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

 

kubernetes 설치는 다음의 명령어로 수행 됩니다 (ubuntu 기준)

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF

# 설치 (=1.24.0-00을 하는 이유는 kubesphere 때문, 그게 아니라면 최신버전 설치 추천)
sudo apt update
sudo apt -y install kubelet=1.24.0-00 kubeadm=1.24.0-00 kubectl=1.24.0-00
sudo apt-mark hold kubelet kubeadm kubectl

네트워크 플러그인(CNI)를 설치합니다. 여기서는 calico를 추천합니다

curl https://docs.projectcalico.org/archive/v3.25/manifests/calico.yaml -O
kubectl apply -f calico.yaml

 

 

모든 과정이 정상 설치되었다면 다음과 같이 표시되야 합니다

$ kubectl get nodes
NAME        STATUS   ROLES           AGE     VERSION
vm-master   Ready    control-plane   2m28s   v1.24.0

$ kubectl get pod --all-namespaces
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-84c476996d-txcns   1/1     Running   0          91s
kube-system   calico-node-hdvwp                          1/1     Running   0          91s
kube-system   coredns-6d4b75cb6d-m4lw7                   1/1     Running   0          2m30s
kube-system   coredns-6d4b75cb6d-wsnh8                   1/1     Running   0          2m30s
kube-system   etcd-vm-master                             1/1     Running   0          2m33s
kube-system   kube-apiserver-vm-master                   1/1     Running   0          2m33s
kube-system   kube-controller-manager-vm-master          1/1     Running   0          2m33s
kube-system   kube-proxy-9t8hh                           1/1     Running   0          2m30s
kube-system   kube-scheduler-vm-master                   1/1     Running   0          2m33s

 

기본적으로 control-plane (master 노드)는 pod의 스케쥴링이 할당되지 않습니다

이를 해제합니다

kubectl taint nodes --all node-role.kubernetes.io/control-plane-
kubectl taint nodes --all node-role.kubernetes.io/master-

 

반응형
반응형

CRI-O

- Redhat에서 개발

- Kubernetes 통합 목적으로 CRI (Container Runtime Interface) 표준 컴포넌트를 최소한의 런타임으로 구현한 것

 

CRI-O 설치

CRI-O를 설치하기 위에서는 네트워크 설정이 필요

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

sudo modprobe overlay
sudo modprobe br_netfilter

cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

sudo sysctl --system

CRI-O 설치

sudo -i

export OS=xUbuntu_20.04 # OS 버전
export VERSION=1.19     # cri-o 버전

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 -

sudo apt-get update

sudo apt-get -y install cri-o cri-o-runc cri-tools

sudo systemctl daemon-reload
sudo systemctl enable crio --now

 

CRI-O를 설치할 경우 crictl를 설치하여야 docker처럼 컨테이너를 제어할 수 있습니다

VERSION="v1.19.0"
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz

 

그런데 docker에 익숙한 경우라면 crictl이 불편할 수 있습니다. (커맨드가 거의 유사하지만)

이럴땐 cri-docker를 설치함으로써 해결 할 수 있습니다. (기존에 docker가 설치되어 있어야 합니다)

wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.0/cri-dockerd_0.3.0.3-0.ubuntu-focal_amd64.deb

sudo dpkg -i cri-dockerd_0.3.0.3-0.ubuntu-focal_amd64.deb
반응형
반응형

# Namespace

이미 구성된 "devops" 사용

참고) Jenkins 구성하기 https://clued.tistory.com/49

 

# PV 생성

apiVersion: v1
kind: PersistentVolume
metadata:
  namespace: devops
  name: jira-pv
spec:
  storageClassName: nfs-sc
  capacity:
    storage: 100Gi
  persistentVolumeReclaimPolicy: Retain  
  accessModes:
  - ReadWriteMany
  nfs:
    server: 12.34.56.78
    path: '/volume1/nfs_root/jira'
    readOnly: false

 

# PVC 생성

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jira-pvc
  namespace: devops
spec:
  storageClassName: nfs-sc
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 100Gi

# Deployment 생성

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jira
  namespace: devops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jira
  template:
    metadata:
      labels:
        app: jira
    spec:
      containers:
      - name: jira
        image: atlassian/jira-software
        imagePullPolicy: IfNotPresent
        ports:
          - name: http-port
            containerPort: 8080
        volumeMounts:
          - name: jira-volume
            mountPath: /var/atlassian/application-data/jira
      volumes:
        - name: jira-volume
          persistentVolumeClaim:
            claimName: jira-pvc

# Service 생성

apiVersion: v1
kind: Service
metadata:
  name: jira-svc
  namespace: devops
spec:
  ports:
    - port: 8080
      targetPort: 8080
      protocol: TCP
      name: http
  selector:
    app: jira

 

# Ingress 생성

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: jira-ingress
  namespace: devops
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/cors-allow-headers: Authorization, origin, accept
    nginx.ingress.kubernetes.io/cors-allow-methods: GET, OPTIONS
    nginx.ingress.kubernetes.io/enable-cors: "true"
spec:
  rules:
  - host: jira.devops.lan
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: jira-svc
            port:
              number: 8080

 

# DB 구성하기

- 사전에 postgresql 구성이 끝나야 한다

- 참고) Postgresql 구성하기 https://clued.tistory.com/50 

root@postgresql-statefulset-0:~# psql -U devops
psql (11.14 (Debian 11.14-1.pgdg90+1))
Type "help" for help.

devops=# CREATE database jira WITH ENCODING 'UNICODE' LC_COLLATE 'C' LC_CTYPE 'C' TEMPLATE template0 OWNER devops;
CREATE DATABASE
devops=#

 

# DB 설정 (참고)

반응형
반응형

많은 devops 서비스는 postgresql을 많이 쓰는 편이다. (jira, confluence, sonarqube 등)

 

그렇기 때문에 postgrsql 데이터베이스를 statefulset으로 구성하고자 한다

 

# PV 생성

apiVersion: v1
kind: PersistentVolume
metadata:
  namespace: devops
  name: postgresql-pv
spec:
  storageClassName: nfs-sc
  capacity:
    storage: 50Gi
  persistentVolumeReclaimPolicy: Retain  
  accessModes:
  - ReadWriteMany
  nfs:
    server: 12.34.56.78
    path: '/volume1/nfs_root/postgresql'
    readOnly: false

# PVC 생성

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgresql-pvc
  namespace: devops
spec:
  storageClassName: nfs-sc
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 50Gi

 

# StatefulSet 생성

kind: StatefulSet
metadata:
  namespace: devops
  name: postgresql-statefulset
spec:
  serviceName: postgresql-statefulset
  replicas: 1
  selector:
    matchLabels:
      app: postgresql-statefulset
  template:
    metadata:
      labels:
        app: postgresql-statefulset
    spec:
      containers:
        - name: postgresql-statefulset
          image: postgres:11
          env:
            - name: POSTGRES_PASSWORD
              value: "!admin06"
            - name: POSTGRES_USER
              value: "devops"
            - name: POSTGRES_ENCODING
              value: "UNICODE"
            - name: POSTGRES_COLLATE
              value: "C"
            - name: POSTGRES_COLLATE_TYPE
              value: "C"
          resources:
            requests:
              cpu: 2
              memory: 4Gi
            limits:
              cpu: 2
              memory: 4Gi
          ports:
            - containerPort: 5432
          volumeMounts:
            - mountPath: "/var/lib/postgresql/data/"
              name: postgresql-pv
      volumes:
        - name: postgresql-pv
          persistentVolumeClaim:
            claimName: postgresql-pvc

# Service 생성

- 앞으로 다른 pod에서 postgresql 접근시 postgresql-svc:5432 로 접근하면 된다

apiVersion: v1
kind: Service
metadata:
  name: postgresql-svc
  namespace: devops
spec:
  ports:
    - port: 5432
      targetPort: 5432
      protocol: TCP
      name: http
  selector:
    app: postgresql-statefulset

 

 

반응형
반응형

참고: 아래 yaml들은 kubernetes 1.23.5 환경에서 진행하였다

 

 

# Namespace 생성 

- 앞으로 devops라는 namespace에 각종 서비스를 올릴 예정이다. 

kubectl create namespace devops

 

# PV 생성

- synology의 NFS를 사용하기 위해 아래와 같이 pv를 선언

apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins-pv
spec:
  storageClassName: nfs-sc
  capacity:
    storage: 50Gi
  persistentVolumeReclaimPolicy: Retain
  accessModes:
    - ReadWriteMany
  nfs:
    server: 12.34.56.78
    path: '/volume1/nfs_root/jenkins'
    readOnly: false

# PVC 생성

-

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-pvc
  namespace: devops
spec:
  storageClassName: nfs-sc
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 50Gi

# Deployment 생성

- jenkins lts 이미지를 사용하게 적용하였다

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
  namespace: devops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      securityContext:
        fsGroup: 1000
        runAsUser: 0
      containers:
      - name: jenkins
        image: jenkins/jenkins:lts
        ports:
          - name: http-port
            containerPort: 8080
          - name: jnlp-port
            containerPort: 50000
        volumeMounts:
          - name: jenkins-volume
            mountPath: /var/jenkins_home
      volumes:
        - name: jenkins-volume
          persistentVolumeClaim:
            claimName: jenkins-pvc

 

# Service 생성

- 8080포트와 50000 포트를 서비스 포트로 등록

apiVersion: v1
kind: Service
metadata:
  name: jenkins-svc
  namespace: devops
spec:
  ports:
    - port: 8080
      targetPort: 8080
      protocol: TCP
      name: http
  selector:
    app: jenkins

---

apiVersion: v1
kind: Service
metadata:
  name: jenkins-jnlp-svc
  namespace: devops
spec:
  ports:
    - port: 50000
      targetPort: 50000
      protocol: TCP
      name: jnlp
  selector:
    app: jenkins

 

# Ingress 생성

- jenkins.devops.svc 라는 도메인으로 접속을 하기 위해 ingress 설정을 아래와 같이 하였다

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: jenkins-ingress
  namespace: devops
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: jenkins.devops.svc
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: jenkins-svc
            port:
              number: 8080

 

여기까지 모든 구성이 완료되면 /etc/hosts에 master node의 ip를 등록하자

 

그리고 브라우저에서 해당 주소로 접속을 하면 정상적으로 jenkins가 뜬것을 확인할 수 있다.

http://jenkins.devops.svc:31039 

(31039는 앞에 post에서 ingress 서비스를 조회하였을때 알아뒀던 node port이다)

 

반응형
반응형

 

PV를 준비한것에 이어 igress controller를 구성하고자 한다.

가장 만만한것이 nginx이니 여기서 받아오자

https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml

 

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml -o nginx-ingress.yaml

 

해당 yaml 파일은 namespace가 이미 지정되어 있기 때문에 (ingress-nginx)

그냥 바로 apply하면 된다.

 

kubectl apply -f ingress-nginx.yaml
------------------------------------------------------------------------
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created

 

이제 ingress-nginx의 NodePort를 알아두자

kubectl get svc -n ingress-nginx
------------------------------------------------------------------------
NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.105.81.137   <none>        80:31039/TCP,443:31171/TCP   60s
ingress-nginx-controller-admission   ClusterIP   10.100.14.244   <none>        443/TCP                      59s



31039 포트이니 접속 테스트를 해본다 (master node에서 테스트)

curl http://127.0.0.1:31039
------------------------------------------------------------------------
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
반응형
반응형

 

NAS에서 공유 폴더를 다음과 같이 생성하였다. (무결성 체크 옵션, 휴지통등 nfs에 어울리지 않는건 모두 비활성화)

그리고 nfsuser라는 별도의 사용자 계정을 만들어 이 공유 폴더에 대한 읽기/쓰기 권한을 부여하였다

 

아직은 공유폴더와 사용자만 할당하였기 때문에 이제 본격적으로 nfs 설정을 해보자

 

파일 서비스에서 NFS 서비스를 활성화한다

 

 

공유 폴더에서 NFS 권한을 추가하자 

(IP 대역을 지정하여 최소한의 보안을 걸어둠)

 

이제 NAS에서의 모든 설정이 끝났다

 

그리고 이제 master node, worker node에 다음의 설정을 진행 한다.

# nfs 관련 패키지 설치
sudo apt-get install nfs-common nfs-kernel-server rpcbind portmap

# nfs 활성화
systemctl enable nfs-kernel-server
systemctl start nfs-kernel-server

 

 

다음 포스트에서 실제 Jenkins를 kubernetes cluster에 올리면서 이 NFS 기반의 PV를 연결할 예정이다.

반응형
반응형

https://k8slens.dev/

이전 GUI 도구를 조사하여 kubernetes-dashboard와 lens를 골랐는데..

(참고 : https://clued.tistory.com/44)

결국 사용성 측면에서 lens가 훨씬 좋아서 lens를 쓰기로 하였다. 

이에 대한 설치 및 구성 과정을 정리해보고자 한다

 

lens 공홈에서 설치를 하고 실행을 하면 다음과 같이 뜬다

로그인을 하길 유도하는데.. 아래 skip 버튼이 있어서 로그인을 안해도 되지만 그냥 google 계정으로 로그인을 하였다

 

로그인을 하고 나면 위와 같은 기본 화면이 나오게 된다. 

아래 파란색 + 버튼을 눌러 .kube 폴더를 연결해야 한다

.kube는 kubernetes의 master node에 생성이 되어 있는데 그 폴더를 lens가 설치된 PC의 home 폴더에 복사를 하였다

리스트에서 맨 밑에 내 kubernetes cluster 항목이 생긴것을 확인할 수 있다. (file은 앞에서 말한것럼 ~/.kube/config)로 연결됨

이 항목을 더블클릭하여 들어가게 되면 다음과 같은 화면이 나오게 된다

 

확실히 lens가 kubernetes-dashboard보다 사용하기 훨씬 좋은것 같다.

어차피 혼자만의 환경인만큼 앞으로 lens를 기반으로 cluster를 운영할 계획이다.

반응형
반응형

master에서 아래 명령을 수행하면 설치된다.

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.1/aio/deploy/recommended.yaml

명령 수행 후 아래와 같이 나옴

생성된 웹서비스에 접근하는 방법은 여러가지가 있지만 가장 대표적인 방법을 쓰면 proxy를 쓰는 방법이다.

kubectl proxy

위와 같이 떳다면 아래와 같은 url로 접근하자. 여기서 ip는 master node의 ip이다.

http://127.0.0.1:8081/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

 

반응형
반응형

아래 링크의 내용을 참고하여 조사를 하였다.

 

https://medium.com/dictcp/kubernetes-gui-clients-in-2020-kube-dashboard-lens-octant-and-kubenav-ce28df9bb0f0#b5ce

여기서 소개하는 GUI 도구는 4종이다.

 

  Kubernetes Dashboard Lens Octant Kubenav
License Apache License 2.0 MIT license Apache License 2.0 MIT license
사이트 github link github link github link github link
마지막 업데이트
(2022-04-08기준)
2.5.1
(2022-03-10)
5.4.5
(2022-04-06)
0.25.1
(2022-02-26)
3.9.0
(2021-12-21)
제공 형태 Web App Web App
장점 가장 널리 쓰이는 만큼 안정적임 Helm3 지원 클러스터 환경을 쉽게 파악할 수 있게 노드를 시각화 해서 표현해줌 모바일 지원
단점 계정을 통한 로그인 접근이 아니라 token 또는 .kube 파일을 활용해야 함
세밀한 label filter 적용이 안됨
메모리 leak이 존재함 kubernetes 설정 파일인 yaml을 읽기만 하며 변경은 못함 YAML 편집 불가
Cluster 연결 방법 cluster 내부 서비스 .kube/config .kube/config .kube/config
         

 

반응형
반응형

 

앞서 Synology VM에 Master Node를 만들었다.

기본적으로는  MasterNode에서는 실제적인 Docker 컨테이너를 제공하지 않는다. (설정을 한다면 Master Node도 컨테이너 사용 가능)

 

애초에 VM의 환경인 만큼 Master Node는 단순 Master 역할에만 집중하게 하고

이 Node에 연결할 Slave 구성을 다음과 같이 진행했다.

 

# Master와 과정이 동일하다. 보기 편하게 하기 위해 내용을 복붙함.


# 기존 설치된 docker가 없으면 아래 명령어는 생략해도 됨
sudo apt-get remove docker docker-engine docker.io containerd runc

# ubuntu package 최신 정보 받아오기
sudo apt-get update
 
# docker 설치를 위한 기본 패키지 설치
sudo apt-get install -y ca-certificates curl gnupg lsb-release


# apt로 내려 받을 수 있게 docker registry 설정
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

# docker 설치
sudo apt-get install -y docker-ce docker-ce-cli containerd.io

# docker 명령어를 편하게 사용하기 위해 sudo 권한 부여 (shell 재시작 필요)
sudo usermod -aG docker $USER 

# 설치하기전 환경 구성
sudo swapoff -a 
sudo sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab

# kubernetes registry 등록 
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

# kubernetes 설치
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

 

# master node 설정시 아래의 내용을 잘 기록 해놨다면 다행이지만..

sudo kubeadm join 123.456.678.910:6443 --token nt4zj2.vbtcn33333t19zpzv \
        --discovery-token-ca-cert-hash sha256:0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
        
        
        
# 혹시 기록이 안되어 있다면? 걱정할 필요가 없다. 아래 명령을 수행하면 나온다.
# 각각 token과 hash 값을 확인할 수 있는 명령어이다.
kubeadm token list
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

# 만약 token list가 없다면? 걱정하지 말자 다시 만들면 된다
kubeadm token create

# 그리고 다시 hash를 조회하면 된다
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

 

 

 

위 과정을 진행하면 아래와 같은 메시지를 볼 수 있다.

이제 master에서 kubectl get nodes를 치면 다음과 같이 나오게 된다.

 

기본적인 클러스터 구성은 끝났고 이제 네트워크 addon을 추가로 설치하자

curl https://docs.projectcalico.org/manifests/calico.yaml -O --insecure
kubectl apply -f calico.yaml

 

반응형
반응형

Synology의 VM을 Master로 하는 Kubernetes 환경을 구성하고자 한다.

 

이렇게 하고자 하는 목적은 

 

- VM인 만큼 Snapshot을 통한 OS 백업이 간편하여 Master 노드를 안정적으로 운영

- Persistent Volume을 NAS로 구성을 하여 데이터의 안정성을 확보

- Synology를 게이트웨이 역할을 하게 수행하여 서비스에 대한 외부 접근시 보안성을 강화

 

위와 같은 이유로 아래와 같은 설정으로 Kubernetes 환경을 구성하였다.

VM의 구성 사양
가상 디스크의 크기

 

기본 네트워크 사용

 

Ubuntu 20.04.03 server 버전 설치 후 다음의 패키지 설치

sudo apt install ssh
sudo apt install net-tools

 

 

Docker는 최신버전으로 설치

# 기존 설치된 docker가 없으면 아래 명령어는 생략해도 됨
sudo apt-get remove docker docker-engine docker.io containerd runc

# ubuntu package 최신 정보 받아오기
sudo apt-get update
 
# docker 설치를 위한 기본 패키지 설치
sudo apt-get install -y ca-certificates curl gnupg lsb-release


# apt로 내려 받을 수 있게 docker registry 설정
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

# docker 설치
sudo apt-get install -y docker-ce docker-ce-cli containerd.io

# docker 명령어를 편하게 사용하기 위해 sudo 권한 부여 (shell 재시작 필요)
sudo usermod -aG docker $USER 

 

Kubernetes 설치

# 설치하기전 환경 구성
sudo swapoff -a 
sudo sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab

# kubernetes registry 등록 
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

# kubernetes 설치
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

 

Kubernetes Master 설정전 확인 사항

# cgroup driver 확인하기
sudo docker info | grep -i cgroup

# 만약 cgroup driver가 cgroupfs이면 다음 명령어 수행하여 해당 문구 수정

sudo vi /usr/lib/systemd/system/docker.service
# <Before>
# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd

# vi 편집 후 systemctl 초기화 수행
sudo systemctl daemon-reload
sudo systemctl restart docker

 

Master Node 설정하기

# master node 초기화하기 (시간이 좀 걸림)
sudo kubeadm init
# 만약 설정 도중 꼬인게 있다면 초기화 하는 명령은 다음과 같다
sudo kubeadm reset



# 정상적으로 수행되면 아래의 문구를 만나야 한다.
Your Kubernetes control-plane has initialized successfully!


# 일반 유저로 다음의 명령어를 수행한다.
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 정상적으로 설정되었는지 확인하기 위해 master 노드의 상태를 조회한다.
kubectl get node
----------------------------------------------------------------------
NAME           STATUS     ROLES                  AGE     VERSION
devopsmaster   NotReady   control-plane,master   4m17s   v1.23.5
----------------------------------------------------------------------

 

여기까지 Synology의 VM을 위한 Kubernetes Master Node 구성이 모두 끝났다.

 

지금까지 깔끔한 구성을 하였으니 이 VM에 대한 스냅샷을 설정한다. (이건 귀찮으면 안해도 된다)

Synology Virtual Machine Manager에서 스냅샷 촬영 선택
스냅샷 저장 (설명을 넣고 잠금을 체크하자)
촬영된 스냅샷

다음 포스팅에서는 이 VM에 Slave Node 로서 접근하는 내용을 정리할 예정이다.

 

 

https://clued.tistory.com/43

 

 

 

 

 

반응형

+ Recent posts