반응형

 

ctr image import image.tar 시 아무런 응답이 없고 실제로 업로드가 안될 때

1. 해당 image.tar 파일을 압축해제하고  manifest.json 파일을 오픈다

2. 오픈시 RepoTags 부분을 확인하면 null값으로 들어가있으며, 이를 수정하면 된다.

 

"RepoTags" : null, -> "RepoTags": ["이미지 URL"]

 

이후 ctr image import 명령어를 수행하면 image가 import 되는 것을 확인할 수 있다.

반응형
반응형

 

kubernetes-dashboard 는 기본적으로 localhost 에서 https 를 권장하지만 Ingress 를 적용하여 접속할 수도 있다.

kubernetes-dashboard-kong-proxy를 기준으로 https ingress 접속하는 방법이다.

 

 

1. 인증서 생성

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=dashboard.wky.kr/O=Kubernetes"
또는
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=dashboard.wky.kr/O=Kubernetes" -addext "subjectAltName = DNS:dashboard.wky.kr"

 

 

2. secret 생성

kubectl create secret tls tls-dashboard --key tls.key --cert tls.crt -n kubernetes-dashboard

 

 

3. Ingress 생성 및 적용

# vi ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
spec:
  ingressClassName: nginx
  rules:
  - host: dashboard.wky.kr
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard-kong-proxy
            port:
              number: 443
  tls:
  - hosts:
    - dashboard.wky.kr
    secretName: tls-dashboard
 
 # 적용
 kubectl apply -f ingress.yaml -n kubernetes-dashboard

 

 

4. 접속할 pc 의 hosts에 등록

vi /etc/hosts

172.1.1.1 dashboard.wky.kr

 

 

5. 확인

 

 

기타. ssl-passthrough

ssl-passthrough 를 적용하기 위해선 deployment에 --enable-ssl-passthrough 플래그를 추가한다.

kubectl edit deploy -n ingress-nginx ingress-nginx-controller

...
spec:
  containers:
  - args:
    - /nginx-ingress-controller
    - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
    - --election-id=ingress-nginx-leader
    - --controller-class=k8s.io/ingress-nginx
    - --ingress-class=nginx
    - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
    - --validating-webhook=:8443
    - --validating-webhook-certificate=/usr/local/certificates/cert
    - --validating-webhook-key=/usr/local/certificates/key
    - --enable-ssl-passthrough=true
...

 

ingress 설정

# vi ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /dash(/|$)(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: kubernetes-dashboard-kong-proxy
            port:
              number: 443
 
 # 적용
 kubectl apply -f ingress.yaml -n kubernetes-dashboard

 

확인

반응형
반응형

 

k8s 인증서가 갱신되더라도 전에 사용하고 있던 config파일 내에 client-certificate-data 항목이 만료가 되지 않았으면,

그대로 정상동작하며, 해당 데이터에 대한 만료일자를 확인하는 방법이다.

 

root@master:~/tmp $ cat ~/.kube/config # client-certificate-data 값 확인
root@master:~/tmp $ echo "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tL~~~~~" | base64 --decode > client.crt
root@master:~/tmp $ ls
client.crt
root@master:~/tmp $ openssl x509 -in client.crt -noout -enddate
notAfter=Apr  7 13:49:20 2025 GMT

 

 

반응형
반응형

 

serviceAccount 를 현재 사용하고 있는 pod 들을 조회하기 위해서는 --field-selector 옵션을 통해 조회 가능하다.

$ kubectl get pods -n kube-system --field-selector spec.serviceAccountName=cilium -o wide
NAME           READY   STATUS    RESTARTS   AGE   IP             NODE      NOMINATED NODE   READINESS GATES
cilium-2nrnz   1/1     Running   0          13m   172.16.1.1   worker1   <none>           <none>
cilium-ldsn5   1/1     Running   0          13m   172.16.1.2   worker2   <none>           <none>
cilium-pcm6x   1/1     Running   0          13m   172.16.1.3   master    <none>           <none>

 

serviceAccount 뿐만아니라 여러 field 선택을 통해 다른것들도 조회가능하다.

https://kubernetes.io/ko/docs/concepts/overview/working-with-objects/field-selectors/

 

필드 셀렉터

필드 셀렉터 는 한 개 이상의 리소스 필드 값에 따라 쿠버네티스 리소스를 선택하기 위해 사용된다. 필드 셀렉터 쿼리의 예시는 다음과 같다. metadata.name=my-service metadata.namespace!=default status.phase=Pe

kubernetes.io

 

반응형
반응형

 

k8s cluster scale out 시 kubeadm token이 필요하다.

kubeadm token의 경우 만료일자가 있어 어느정도 기한이 지나면 사라지기 때문에 재생성이 필요하다.

방법이 2개 정도 있으며, 생성 후 사용하는 법과 생성과 동시에 명령어를 생성하는 법이 있다.

 

1. 기존 토큰이 있을 경우 kubeadm token list 명령어를 통해 token 조회 가능

kubeadm token list​

 

기존 토큰을 사용하거나 토큰이 없어서 재생성 후 사용할 경우 기존 토큰이 없을 경우는 토큰 생성

kubeadm token create

root@master:~# kubeadm token create
ck9j53.uiwl5qd5s9vwdevzv

 

 

discovery-token-ca-cert-hash 조회

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

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

 

 

조회 후 kubeadm join 옵션을 통해 신규 Node 추가

kubeadm join 127.0.0.1:6443 --token ck9j53.uiwl5qd5s9vwdevzv \
--discovery-token-ca-cert-hash sha256:c8158df76056620db625ba08a4faaf47f795e4bf0517d6a296657dc6f59192e3

 

 

2. --print-join-command 로 바로 출력

kubeadm token create --print-join-command

root@master:~# kubeadm token create --print-join-command
kubeadm join 127.0.0.1:6443 --token ae46ls.ggne5zqvxtyv2153 --discovery-token-ca-cert-hash sha256:c8158df76056620db625ba08y4fabf37f715e4af0517d6x296657dc6f59194e2

 

반응형
반응형

 

서버 작업 중 kubelet.service 재기동시 계속 종료되는 현상이 발생되어 journalctl -xeu kubelet를 통해 로그를 확인하였으나, 그 당시 엄청 많은 쓸데없는 에러로 인해서 해당 문제를 해결하는데 시간을 많이 허비 하였다.

(로그찾을때 E(Error) 만 보느라 F(Fatal)을 놓쳤었음.)

 

아래 에러로 인하여 kubelet이 재기동 되지 않은 것을 확인하였으며, kenel panic을 재조정하여 해결하였다.

Failed to start ContainerManager invalid kernel flag: kenrnel/panic, expected valued: 10, actual value :0

 

이 문제는 kubeadm으로 k8s 설치시 발생하진 않지만, kubespray로 k8s를 설치하게되면,  기본적으로 kernel.panic=10으로 들어가게된다.

해당 옵션은 kubelet 기동 인자 전달시 예상한값과 다를 경우 패스하거나 실패 시키는 옵션인데, 누군가 kernel.panic=0 으로 변경하여 에러가 발생하였다.

 

조치방법은 /etc/sysctl.conf 내 kernel.panic 옵션의 값을 변경하면된다.

# vi /etc/sysctl.conf
kernel.panic=10

 

 

기타.

kubespray로 k8s를 설치할 경우 kubelet service파일(/etc/systemd/system/kubelet.service)에 인자들이 들어간다.

적용된 kernel.panic 옵션을 통해 해당 인자들이 탐지되어 정상기동하거나 실패하는 듯 하다.

# cat /etc/systemd/system/kubelet.service

[Service]
EnvironmentFile=-/etc/kubernetes/kubelet.env
ExecStart=/usr/local/bin/kubelet \
                $KUBE_LOGTOSTDERR \
                $KUBE_LOG_LEVEL \
                $KUBELET_API_SERVER \
                $KUBELET_ADDRESS \
                $KUBELET_PORT \
                $KUBELET_HOSTNAME \
                $KUBELET_ARGS \
                $DOCKER_SOCKET

 

반응형
반응형

 

해당 가이드는 지속적으로 수정 예정. 동작 및 코드 문의시 댓글 부탁드립니다.

 

k8s 를 이용하다보면 Node들에 container image들이 쌓이게 되는데 이를 정리하는 CronJob 이다

CronJob에 이용되는 image는 아래 dokcer hub에서 확인 할 수 있다.(amd64, arm64 아키텍쳐 사용가능)

https://hub.docker.com/r/pangyeons/image-prune

 

https://hub.docker.com/r/pangyeons/image-prune

 

hub.docker.com

 

현재버전 - 1.1

 

기능은 옵션을 통해 docker 뿐만아니라 crictl 명령어를 이용하여 image pruning 을 진행할 수 있으며,

Control Plane 도 정리할지 안할지 옵션을 통해 선택할 수 있다.

 

사용방법은 아래와 같다.

 

1. 아래는 기본적인 yaml 파일이며 command 배열과 mountPath, API_TOKEN, API_URL, KEY_NAME, defaultMode는 필수 옵션이다.

apiVersion: batch/v1
kind: CronJob
metadata:
  name: image-prune
spec:
  schedule: "0 0 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: image-prune
            image: pangyeons/image-prune:1.1
            imagePullPolicy: IfNotPresent
            command: # 아래 command 배열 수정 및 삭제 금지
            - /bin/sh
            - -c
            - chmod +x image_prune.sh; /image_prune.sh
            volumeMounts:
            - mountPath: /etc/sshkey # 수정 및 삭제 금지
              name: secret-sshkey
            env:
            - name: API_TOKEN # 수정 및 삭제 금지
              valueFrom:
                secretKeyRef:
                  key:
                  name: 
            - name: API_URL # 수정 및 삭제 금지
              value: ""
            - name: KEY_NAME # 수정 및 삭제 금지
              value: ""
            - name: CRI_TYPE
              value: ""
            - name: CONTROL_PLANE
              value: ""
            - name: OS_USER
              value: ""
            - name: PORT
              value: "6443"
          restartPolicy: OnFailure
          volumes:
          - name: secret-sshkey
            secret:
              defaultMode: 0600 # 수정 및 삭제 금지
              secretName:

 

2. ssh key 생성 및 등록

ssh-keygen 을 통해 ssh key 생성

ssh-keygen -t rsa # ex) id_rsa, id_rsa.pub 생성

 

 

생성 후 나온 public key 모든 node에 등록

# id_rsa.pub 등록
vi ~/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDNbPyWARlsD1OmjgHcQAewXvmTbAJYAYMlRgjgUKu69uVyKB8ZS0n3KuLJy9JoTF4y/VOL5DTCU2TFb1A1eIhM4Ox5sPoNTWIG7h/crH

 

생성한 ssh private key를 k8s secret에 등록

kubectl create secret generic sshkey --from-file=privatekey=./id_rsa

 

 

3. k8s API를 사용할 API Token 생성(현재 Ready 중인 Node 및 Master/Worker Node 구분을 위함)

API Token 생성을 위한 Serivce Account 생성 및 API 조회에 필요한 Role 부여

vi test-token.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-token
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: read-nodes
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-nodes-binding
subjects:
- kind: ServiceAccount
  name: test-token
  namespace: default
roleRef:
  kind: ClusterRole
  name: read-nodes
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
  name: test-token-secret
  namespace: default
  annotations:
    kubernetes.io/service-account.name: test-token

 

 

생성한 계정에 대한 API Token 조회

API_TOKEN=$(kubectl get secret test-token-secret -o jsonpath="{.data.token}" | base64 --decode)

 

4. 생성한 API Token을 k8s secret 으로 생성

kubectl create secret generic apitoken --from-literal=apitoken=$API_TOKEN

 

5. CronJob 생성

API_TOKEN secret으로 생성한 apitoken key: apitoken
name: apitoken
필수
API_URL Control Plane API URL 127.0.0.1 필수
KEY_NAME secret으로 생성한 ssh key privatekey 필수
OS_USER Node들에 접속할 OS계정 user 기본값 : root
CRI_TYPE 컨테이너 런타임 인터페이스 docker/crictl 기본값 : root
CONTROL_PLANE CONTROL PLANE 도 정리 true/false 기본값 : true
PORT k8s API PORT 6443 기본값 : 6443

 

apiVersion: batch/v1
kind: CronJob
metadata:
  name: image-prune
spec:
  schedule: "0 0 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: image-prune
            image: pangyeons/image-prune:1.1
            imagePullPolicy: IfNotPresent
            command: # 아래 command 배열 수정 및 삭제 금지
            - /bin/sh
            - -c
            - chmod +x image_prune.sh; /image_prune.sh
            volumeMounts:
            - mountPath: /etc/sshkey # 수정 및 삭제 금지
              name: secret-sshkey
            env:
            - name: API_TOKEN # 수정 및 삭제 금지
              valueFrom:
                secretKeyRef:
                  key: apitoken # 위에 가이드대로 생성한 token
                  name: apitoken # 위에 가이드대로 생성한 token
            - name: API_URL # 수정 및 삭제 금지
              value: "172.1.1.1" # Control Plane API IP
            - name: KEY_NAME # 위에 가이드대로 생성한 SSH KEY Secret
              value: "privatekey"
            - name: CRI_TYPE # Container Runtime이 crictl일 경우
              value: "crictl"
            - name: CONTROL_PLANE # Control Plane에서는 동작안함.
              value: "false"
            - name: PORT
              value "6443"
          restartPolicy: OnFailure
          volumes:
          - name: secret-sshkey
            secret:
              defaultMode: 0600 # 수정 및 삭제 금지
              secretName: sshkey # 위에 가이드대로 생성한 SSH KEY Secret

 

반응형
반응형

 

docker 명령어가 아닌 buildah를 이용하여 multiarch build 후 docker hub에 push하는 방법이다.

우선, 원활한 multiarch build를 위해 아래 글을 먼저 참고한다.

2024.04.28 - [Develop/기타 작업] - exec container process `/bin/sh`: Exec format error

 

1. manifest 생성

buildah manifest create multi-test

 

 

2. buildah 를 이용한 이미지 빌드

amd64 빌드

buildah build --arch=amd64 -f Dockerfile -t docker.io/name/multi-test:1.0 --manifest multi-test .

 

arm64 빌드

buildah build --arch=arm64 -f Dockerfile -t docker.io/name/multi-test:1.0 --manifest multi-test .

 

 

3. 잘 되었는지 manifest 조회

buildah manifest inspect multi-test
# result
{
    "schemaVersion": 2,
    "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
    "manifests": [
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "size": 498,
            "digest": "sha256:ba89775d01a87554befd5cb4067cee02a81e28fbd575e458c7da8de269251475",
            "platform": {
                "architecture": "arm64",
                "os": "linux"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "size": 498,
            "digest": "sha256:1ac1ba96e89b9b2184e1b21a9bdbe22ba8c5d9e3433e692482ab53e9a816383b",
            "platform": {
                "architecture": "amd64",
                "os": "linux"
            }
        }
    ]
}

 

 

4. docker hub login

docker hub 의 ID와 PW를 이용하여 로그인

buildah login -u ID -p PW docker.io

 

 

5. docker hub 에서 생성한 repository에 push

buildah manifest push --all multi-test "docker://docker.io/name/multi-test:1.0"

 

 

6. docker hub에 접속하여 확인

반응형
반응형

 

buildah 를 이용하여 arm 아키텍처에서 amd 로 multi platform 빌드를 수행하는 도중 계속 아래와 같은 에러가 발생했다.

exec container process `/bin/sh`: Exec format error

 

docker 또는 buildah로 multi platform 빌드할 경우 아키텍처 옵션을 주면 해결된다고 하였으나, 되지않았고

qemu-user-static 을 설치해주니 잘동작하였다.

qemu-user-static 은 다양한 아키텍처를 실행해주는 소프트웨어이다.

apt-get update -y
apt-get install qemu-user-static

 

설치 후 다른 사용법은 없으며, 그냥 아키텍쳐 옵션을 주면 빌드가된다.

 buildah build --arch=amd64 -f Dockerfile -t wky.kr/test:latest .

 

또한, amd64로 이미지를 생성한 후 arm 아키텍처에서 해당 amd64 이미지 k8s에서 실행하여도

qemu-user-static 으로 인하여 실행이된다.

 

참고 : https://github.com/multiarch/qemu-user-static

https://github.com/containers/buildah/blob/main/docs/buildah-build.1.md

반응형
반응형

 

shell script 작성 후 shell script를 실행 시키는 image 를 Alpine linux 로 이미지 생성 후 Pod 실행시

No such file or directory 에러가 발생하였다.

 

확인해보니 shell script 제일 상단에 #!/bin/bash 가 문제였고

Alpine linux 의 경우 shell script 제일 상단에 #!/bin/sh 로 해주어야한다.

#!/bin/bash -> #!bin/sh

 

bash를 사용해야하는 경우라면 bash를 추가해서 사용하면 된다.

apk add bash

 

반응형

+ Recent posts