티스토리 뷰
Longhorn
Kubernetes를 위한 가볍고, 신뢰할만한 그리고 손쉽게 분산된 Block Storage system이다.
Container 기반의 마이크로서비스형태의 volume 관리를 수행하고 각 disk 별 controller를 통해 replication을 수행한다.
Kubernetes 기반으로 Persistent volume 제공 및 사용에 초점이 맞추어진 분산 Block Storage이다.
실제 Longhorn maintainer의 이야기에 따르면 edge/hyperconverged 환경에 적합하게 설계된 storage로 보여지며
해당 환경에서 가볍게 동작될수 있는 특징을 가지는것으로 보인다.
Longhorn Deep dive
주요 기술
- sparse file : block storage engine을 추가로 생성하기보다는 Linux kernel에 builtin 된 sparse file 을 통해 파일을 관리
- iscsi : 네트워크 전송 매커니즘으로 사용
- NFS(option) : ReadWriteMany 형태의 다수의 client가 읽기 및 쓰기를 해야 하는 경우 사용된다.
아래 글에서 소개되었듯이 기존에 알려지고 이해도가 있는 기술을 그대로 사용함으로 위험을 최소화 한것이 컨셉이다.
구성 및 Architecture
먼저 Architecture diagram을 간단히 보면 pod내 연결되어 최종사용될 volume은 Engine을 통해 연결이 되며 Engine은 각 노드에 존재하는 replica(실제 volume)과 연결되는것을 볼수 있다.
위 그림상에는 언급되지 않았지만 Manager가 존재하며 Manager는 중앙에서 Enginer을 관리하는 최종 관리자 역할을 수행하게 된다. (중앙이라 표현은 했지만 실제 각 node마다 daemonset으로 동작하면서 node 하나에 대한 자원관리가 주이다.)
위 언급된 구성요소를 간단히 정리하면 다음과 같다.
- Manager : API handle 및 volume 생성 요청에 따른 Engine 생성, volume 관리 등 수행
- Engine : iscsi target으로 동작
- 실제 pod로 생성되는 engine은 두가지가 생성된다. (engine-manager-e-xxx : engine / engine-manager-r-xxx : replica)
- engine-manager-e-xxx : iscsi target으로 동작되는 pod이다.
- engine-manager-r-xxx : replica/sync-agent에 의한 데이터 복제및 동기화를 수행하게 된다.
(실제 /var/lib/longhorn/engine-binaries/longhornio-longhorn-engine-v1.1.0/longhorn 의 longhorn option중 replica/sync-agent로 동작되는 process를 확인해볼수 있다.)
- volume(replica) : sparse file 로 저장되는 파일들로 disk 경로(default : /var/lib/longhorn)에 replicas 디렉토리내에
revision.counter/volume-head-000.img/volume-head-000.img.meta/volume.meta 형태로 저장된다. - 출처 : https://longhorn.io/docs/1.0.0/concepts/#11-the-longhorn-manager-and-the-longhorn-engineCSI
추가적으로 CSI를 아래와 같이 제공한다.
- csi-snapshotter
- csi-attacher
- csi-provisioner
- csi-resizer
Install and Configure
Prerequiste
기본적으로 iscsi initiator가 설치되어 있어야 한다.
만약 iscsi initiator 설치가 안된 경우 설치과정중 아래와 같이 longhorn-manager 에러가 발생될수 있으니
필히 위 package를 설치하여야 한다./
jacob@jacob-laptop:~$ kubectl logs pod/longhorn-manager-2cxdc -n longhorn-system
time="2021-03-05T12:33:47Z" level=error msg="Failed environment check, please make sure you have iscsiadm/open-iscsi installed on the host"
time="2021-03-05T12:33:47Z" level=fatal msg="Error starting manager: Environment check failed: Failed to execute: nsenter [--mount=/host/proc/1/ns/mnt --net=/host/proc/1/ns/net iscsiadm --version], output , stderr, nsenter: failed to execute iscsiadm: No such file or directory\n, error exit status 1"
Install
기본적으로 아래와 같은 설치 방법을 제공한다.
- Rancher UI 상에서 설치
- yaml 파일을 이용한 설치
- helm chart를 이용한 설치
여기서는 helm chart를 이용해 설치하는 과정을 알아보도록 하겠다.
아래와 같이 helm chart repo를 추가하고 longhorn-system namespace를 생성하고 해당 NS에 longhorn을 설치하도록 한다.
또한 몇몇 defaultsetting을 custom 하게 추가하였다.
helm repo add longhorn https://charts.longhorn.io
helm repo update
kubectl create ns longhorn-system
helm install longhorn longhorn/longhorn -n longhorn-system \
--set defaultSettings.defaultDataPath="/data/longhorn" \
--set defaultSettings.defaultDataLocality="best-effort"
Longhorn 설치가 완료되면 다음과 같은 resources 들을 확인할 수 있다.
jacob@jacob-laptop:~$ kubectl get all -n longhorn-system
NAME READY STATUS RESTARTS AGE
pod/longhorn-ui-849c455d79-g6f55 1/1 Running 0 9m40s
pod/instance-manager-e-45e07c4d 1/1 Running 0 4m1s
pod/instance-manager-r-8a1376ac 1/1 Running 0 4m
pod/engine-image-ei-cf743f9c-psbxx 1/1 Running 0 4m2s
pod/longhorn-manager-ncpqh 1/1 Running 0 4m13s
pod/longhorn-driver-deployer-cdb7464c6-bdnsx 1/1 Running 0 9m40s
pod/csi-provisioner-5c9dfb6446-d74wz 1/1 Running 0 3m3s
pod/csi-attacher-5dcdcd5984-s2zkp 1/1 Running 0 3m4s
pod/csi-provisioner-5c9dfb6446-48vvb 1/1 Running 0 3m3s
pod/csi-provisioner-5c9dfb6446-l856l 1/1 Running 0 3m3s
pod/csi-attacher-5dcdcd5984-q4vb9 1/1 Running 0 3m4s
pod/longhorn-csi-plugin-6qbfh 2/2 Running 0 3m1s
pod/csi-resizer-54d484bf8-lv98q 1/1 Running 0 3m2s
pod/csi-snapshotter-96bfff7c9-5v44m 1/1 Running 0 3m1s
pod/csi-snapshotter-96bfff7c9-r6l88 1/1 Running 0 3m1s
pod/csi-resizer-54d484bf8-7lsnt 1/1 Running 0 3m2s
pod/csi-snapshotter-96bfff7c9-bl7hn 1/1 Running 0 3m2s
pod/csi-resizer-54d484bf8-wszlx 1/1 Running 0 3m2s
pod/csi-attacher-5dcdcd5984-jjrf4 1/1 Running 0 3m4s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/longhorn-backend ClusterIP 10.43.175.32 <none> 9500/TCP 9m40s
service/longhorn-frontend ClusterIP 10.43.45.197 <none> 80/TCP 9m40s
service/csi-attacher ClusterIP 10.43.157.114 <none> 12345/TCP 3m4s
service/csi-provisioner ClusterIP 10.43.59.240 <none> 12345/TCP 3m4s
service/csi-resizer ClusterIP 10.43.229.224 <none> 12345/TCP 3m3s
service/csi-snapshotter ClusterIP 10.43.8.35 <none> 12345/TCP 3m2s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/engine-image-ei-cf743f9c 1 1 1 1 1 <none> 4m2s
daemonset.apps/longhorn-manager 1 1 1 1 1 <none> 9m40s
daemonset.apps/longhorn-csi-plugin 1 1 1 1 1 <none> 3m2s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/longhorn-ui 1/1 1 1 9m40s
deployment.apps/longhorn-driver-deployer 1/1 1 1 9m40s
deployment.apps/csi-provisioner 3/3 3 3 3m3s
deployment.apps/csi-snapshotter 3/3 3 3 3m2s
deployment.apps/csi-resizer 3/3 3 3 3m3s
deployment.apps/csi-attacher 3/3 3 3 3m4s
NAME DESIRED CURRENT READY AGE
replicaset.apps/longhorn-ui-849c455d79 1 1 1 9m40s
replicaset.apps/longhorn-driver-deployer-cdb7464c6 1 1 1 9m40s
replicaset.apps/csi-provisioner-5c9dfb6446 3 3 3 3m3s
replicaset.apps/csi-snapshotter-96bfff7c9 3 3 3 3m2s
replicaset.apps/csi-resizer-54d484bf8 3 3 3 3m3s
replicaset.apps/csi-attacher-5dcdcd5984 3 3 3 3m4s
jacob@jacob-laptop:~$ kubectl get cm -n longhorn-system
NAME DATA AGE
longhorn-default-setting 1 9m54s
longhorn-storageclass 1 9m54s
jacob@jacob-laptop:~$ kubectl get secret -n longhorn-system
NAME TYPE DATA AGE
longhorn-service-account-token-4l8fx kubernetes.io/service-account-token 3 9m57s
default-token-dts2s kubernetes.io/service-account-token 3 9m57s
아래와 같이 longhorn을 default storage로 설정한다.
(기존에 다른 storage class를 사용중이었다면 longhorn으로 변경하면 별도의 storage class 지정없이도 pvc에 의한 pv 생성이 가능하다.)
root@deploy:~# kubectl patch storageclass longhorn -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
storageclass.storage.k8s.io/longhorn patched
root@deploy:~# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 42h
longhorn (default) driver.longhorn.io Delete Immediate true 24h
root@deploy:~# kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
storageclass.storage.k8s.io/local-path patched
root@deploy:~# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
longhorn (default) driver.longhorn.io Delete Immediate true 24h
local-path rancher.io/local-path Delete WaitForFirstConsumer false 42h
Configure
Disk
Longhorn은 기본 Disk(실제 pv가 생성되고 복제될 directory)로 /var/lib/longhorn/ 혹은 별도의 설정을 하였다면 별도의 directory가 기본 Disk로 사용된다. 즉, mount 된 FileSystem에 따라 용량 및 경로가 지정된다고 보면 된다.
Disk 추가는 아래와 같이 UI를 통해 제공하고 있다.
(가이드로 나온 내용으로는 UI를 통한 방식이 있었으며 별도의 방식은 찾지 못했다.)
- longhorn.io/docs/0.8.0/users-guide/settings/#default-data-path
- https://longhorn.io/docs/0.8.0/users-guide/multidisk/
Backup
Backup은 S3나 NFS 대상으로 진행될수 있으며 해당 Target을 지정하게되면 Backup을 사용할 수 있다.
Data workflow
pod와 pvc를 임의로 생성하여 실제 저장되는 파일 방식을 알아보기로 하자.
먼저 master로 동작되는 노드에서 확인한 결과이다.
root@service1:/var/lib/longhorn/replicas/pvc-46fbd659-5c9e-4484-9052-613dce20c29e-fc35026e# ls -alh
total 229M
drwx------ 2 root root 4.0K Mar 4 04:47 .
drwxr-xr-x 4 root root 4.0K Mar 5 13:09 ..
-rw------- 1 root root 4.0K Mar 4 04:47 revision.counter
-rw-r--r-- 1 root root 10G Mar 4 04:47 volume-head-000.img
-rw-r--r-- 1 root root 126 Mar 4 04:19 volume-head-000.img.meta
-rw-r--r-- 1 root root 144 Mar 4 04:47 volume.meta
root@service1:/var/lib/longhorn/replicas/pvc-46fbd659-5c9e-4484-9052-613dce20c29e-fc35026e# cd ../pvc-8902d360-508b-4154-be8f-bf7d16fb1735-49efc839/
root@service1:/var/lib/longhorn/replicas/pvc-8902d360-508b-4154-be8f-bf7d16fb1735-49efc839# ls -alh
total 49M
drwx------ 2 root root 4.0K Mar 5 13:09 .
drwxr-xr-x 4 root root 4.0K Mar 5 13:09 ..
-rw------- 1 root root 4.0K Mar 5 13:10 revision.counter
-rw-r--r-- 1 root root 1.0G Mar 5 13:10 volume-head-000.img
-rw-r--r-- 1 root root 126 Mar 5 13:09 volume-head-000.img.meta
-rw-r--r-- 1 root root 142 Mar 5 13:09 volume.meta
root@service1:/var/lib/longhorn/replicas/pvc-8902d360-508b-4154-be8f-bf7d16fb1735-49efc839# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
jenkins-backup Bound pvc-8467a1d8-6144-4322-9b34-39c9986835b6 5Gi RWO longhorn 2d10h
nfs-pvc Bound pvc-8902d360-508b-4154-be8f-bf7d16fb1735 1Gi RWX longhorn 84s
추가 worker node에서 확인한 결과
root@service2:/var/lib/longhorn/replicas/pvc-8902d360-508b-4154-be8f-bf7d16fb1735-2f569847# ls -alh
total 49M
drwx------ 2 root root 4.0K Mar 5 13:09 .
drwxr-xr-x 4 root root 4.0K Mar 5 13:09 ..
-rw------- 1 root root 4.0K Mar 5 13:10 revision.counter
-rw-r--r-- 1 root root 1.0G Mar 5 13:10 volume-head-000.img
-rw-r--r-- 1 root root 126 Mar 5 13:09 volume-head-000.img.meta
-rw-r--r-- 1 root root 142 Mar 5 13:09 volume.meta
root@service2:/var/lib/longhorn/replicas/pvc-8902d360-508b-4154-be8f-bf7d16fb1735-2f569847# cd ../pvc-46fbd659-5c9e-4484-9052-613dce20c29e-90e655a2/
root@service2:/var/lib/longhorn/replicas/pvc-46fbd659-5c9e-4484-9052-613dce20c29e-90e655a2# ls -alh
total 229M
drwx------ 2 root root 4.0K Mar 4 04:47 .
drwxr-xr-x 4 root root 4.0K Mar 5 13:09 ..
-rw------- 1 root root 4.0K Mar 4 04:47 revision.counter
-rw-r--r-- 1 root root 10G Mar 4 04:47 volume-head-000.img
-rw-r--r-- 1 root root 126 Mar 4 04:19 volume-head-000.img.meta
-rw-r--r-- 1 root root 144 Mar 4 04:47 volume.meta
revision을 비교하면 동일 한 값을 가지고 있다.
root@service2:/var/lib/longhorn/replicas/pvc-8902d360-508b-4154-be8f-bf7d16fb1735-2f569847# cat revision.counter
69
root@service1:/var/lib/longhorn/replicas/pvc-8902d360-508b-4154-be8f-bf7d16fb1735-49efc839# cat revision.counter
69
실제 생성된 pv들은 아래와 같이 보여진다. (RWO와 RWX access mode 모두 생성이 가능하다.)
root@service1:~# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-8467a1d8-6144-4322-9b34-39c9986835b6 5Gi RWO Delete Bound default/jenkins-backup longhorn 2d10h
pvc-46fbd659-5c9e-4484-9052-613dce20c29e 10Gi RWO Delete Bound secu/data-vault-0 longhorn 32h
pvc-8902d360-508b-4154-be8f-bf7d16fb1735 1Gi RWX Delete Bound default/nfs-pvc longhorn 7m39s
실제 생성된 pv list를 확인해보면 다음과 같이 앞서 생성된 pod의 이름이 포함된 pv가 생성되어 있음을 확인할 수 있다.
root@service2:~# ls -al /var/lib/longhorn/replicas/
total 24
drwxr-xr-x 6 root root 4096 Mar 10 11:25 .
drwxr-xr-x 4 root root 4096 Mar 3 08:59 ..
drwx------ 2 root root 4096 Mar 10 10:23 pvc-28d7e348-2f13-4056-9a1e-0bae532b1276-a4eaff5d
drwx------ 2 root root 4096 Mar 10 11:25 pvc-77d6c7aa-5057-4668-93e0-f7e79173b59d-a2e17942
drwx------ 2 root root 4096 Mar 10 11:25 pvc-990122b3-156d-451b-99c8-f84113c279fb-f49855b7
drwx------ 2 root root 4096 Mar 10 11:25 pvc-e860d683-f78c-4d0b-92ea-0e2cffe3e66f-f99410df
Access Mode 별 동작방식
RWO 사용
RWO access mode로 pvc를 생성하게 되면 아래와 같이 ext4로 mount 되게 된다.
root@service1:~# kubectl exec -it pod/nginx-longhorntest3 -- bash
root@nginx-longhorntest3:/# mount | grep pvc
/dev/longhorn/pvc-62bff559-c2e9-42e8-b376-0eb1b94cb170 on /usr/share/nginx/html type ext4 (rw,relatime)
좀더 깊게 확인해보면
instance-manager-xxx pod가 iscsi target으로 동작되고
root@service1:~/longhorntest# kubectl -n longhorn-system describe po/instance-manager-e-92e32ff2 | grep -E '^IP:'
IP: 10.42.0.19
root@service1:~/longhorntest# iscsiadm -m session
tcp: [7] 10.42.0.19:3260,1 iqn.2019-10.io.longhorn:pvc-62bff559-c2e9-42e8-b376-0eb1b94cb170 (non-flash)
host는 해당 instance-manager로 iscsi 연결을 수행하게 된다.
root@service1:~/longhorntest# kubectl -n longhorn-system exec -it po/instance-manager-e-92e32ff2 -- lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 67.8M 1 loop
loop2 7:2 0 55.4M 1 loop
loop3 7:3 0 31.1M 1 loop
loop4 7:4 0 55.5M 1 loop
loop5 7:5 0 69.9M 1 loop
loop6 7:6 0 32.3M 1 loop
sda 8:0 0 1G 0 disk
sr0 11:0 1 368K 0 rom
vda 252:0 0 20G 0 disk
|-vda1 252:1 0 19.9G 0 part /usr/local/bin
|-vda14 252:14 0 4M 0 part
`-vda15 252:15 0 106M 0 part
vdb 252:16 0 9.3G 0 disk
`-vdb1 252:17 0 9.3G 0 part
실제 instance-manager-xxx에서 제공하는 disk들이다.
실 Pod에서 연결된 정보를 보면 물리 disk 처럼 mount를 하여 ext4 format으로 사용중인것을 확인할 수 있다.
root@service1:~# mount | grep pvc
/dev/longhorn/pvc-62bff559-c2e9-42e8-b376-0eb1b94cb170 on /var/lib/kubelet/pods/3150d6c7-b41c-44b0-9003-f58d9d6a25f5/volumes/kubernetes.io~csi/pvc-62bff559-c2e9-42e8-b376-0eb1b94cb170/mount type ext4 (rw,relatime)
RWX 사용
RWX access mode로 persistent volume을 생성하는 경우는 NFSv4 를 통해 연결하도록 된다.
아래 링크에 관련 diagram이 있으니 참고하면 도움이 될것이다.
먼저 pvc를 생성하게 되면 아래와 같은 iscsi 연결이 이루어진다.
root@service2:~# iscsiadm --mode node
10.42.1.6:3260,1 iqn.2019-10.io.longhorn:pvc-77d6c7aa-5057-4668-93e0-f7e79173b59d
10.42.1.6:3260,1 iqn.2019-10.io.longhorn:pvc-990122b3-156d-451b-99c8-f84113c279fb
10.42.1.6:3260,1 iqn.2019-10.io.longhorn:pvc-28d7e348-2f13-4056-9a1e-0bae532b1276
이제 pod를 생성하여 pvc를 volume으로 사용하려 하면 다음과 같은 에러가 발생된다.
(앞서 이야기했듯이 nfs 로 mount를 수행하기에 추가적인 nfs package가 설치되지 않은 경우 아래와 같이 describe pod 를 수행해보면 mount error 가 발생될수 있다.)
Mounting command: /bin/systemd-run
Mounting arguments: [--description=Kubernetes transient mount for /var/lib/kubelet/pods/c8d8d543-939b-4718-96b8-89cf0e0c1c47/volumes/kubernetes.io~csi/pvc-0a946dc6-4d87-4b8a-a202-6bf9dfafd3c3/mount --scope -- /bin/mount -t nfs -o vers=4.1,noresvport,soft,sync,intr,timeo=7,retrans=3 10.43.131.239:/pvc-0a946dc6-4d87-4b8a-a202-6bf9dfafd3c3 /var/lib/kubelet/pods/c8d8d543-939b-4718-96b8-89cf0e0c1c47/volumes/kubernetes.io~csi/pvc-0a946dc6-4d87-4b8a-a202-6bf9dfafd3c3/mount]
Output: Running scope as unit: run-r5cca514f93be4dc99d7d50b225dcc289.scope
mount: /var/lib/kubelet/pods/c8d8d543-939b-4718-96b8-89cf0e0c1c47/volumes/kubernetes.io~csi/pvc-0a946dc6-4d87-4b8a-a202-6bf9dfafd3c3/mount: bad option; for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount.<type> helper program.
Warning FailedMount 51m kubelet Unable to attach or mount volumes: unmounted volumes=[vol], unattached volumes=[default-token-fjjsd vol]: timed out waiting for the condition
Warning FailedMount 51m kubelet MountVolume.SetUp failed for volume "pvc-0a946dc6-4d87-4b8a-a202-6bf9dfafd3c3" : rpc error: code = Internal desc = mount failed: exit status 32
아래 package를 설치한 후 다시 확인하면 정상적으로 mount 및 pod가 running 상태로 변경됨을 확인할수 있다.
root@service2:~# apt install nfs-common -y
이때 NFSv4 server로 동작되는 pod가 share-manager-xxx pod이며 longhorn의 concept에 맞춰 volume 생성시마다 share-manager(NFSv4 server)가 생성된다.
root@service1:~# kubectl get po -n longhorn-system | grep share-manager
share-manager-pvc-28d7e348-2f13-4056-9a1e-0bae532b1276 1/1 Running 0 102m
share-manager-pvc-77d6c7aa-5057-4668-93e0-f7e79173b59d 1/1 Running 0 41m
share-manager-pvc-990122b3-156d-451b-99c8-f84113c279fb 1/1 Running 0 41m
해당 NFS 접속주소는 kubernetes service resource로 노출시킨다.
root@service1:~# kubectl get svc -n longhorn-system | grep pvc
pvc-28d7e348-2f13-4056-9a1e-0bae532b1276 ClusterIP 10.43.60.32 <none> 2049/TCP 150m
pvc-77d6c7aa-5057-4668-93e0-f7e79173b59d ClusterIP 10.43.254.133 <none> 2049/TCP 88m
pvc-990122b3-156d-451b-99c8-f84113c279fb ClusterIP 10.43.238.32 <none> 2049/TCP 88m
실제 Pod에 mount 된 정보를 확인해보면 위에 노출된 service를 통해 nfs mount를 수행한것을 확인할 수 있다.
root@nginxtest:/# mount | grep pvc
10.43.60.32:/pvc-28d7e348-2f13-4056-9a1e-0bae532b1276 on /usr/share/nginx/html type nfs4 (rw,relatime,sync,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,soft,noresvport,proto=tcp,timeo=7,retrans=3,sec=sys,clientaddr=10.10.10.252,local_lock=none,addr=10.43.60.32)
Spec 고려사항
- 당연히 dedicated Disk 사용이 권장된다.
- over-provisioning이 200%로 최소 지정되며 설정이 가능하다.
performance benchmark
100% 신뢰되는 데이터는 아니지만 storage 선택시 참고사항으로 좋을듯하여 아래 링크를 첨부한다.
'Cloud > Kubernetes' 카테고리의 다른 글
ingress with subpath (0) | 2021.03.23 |
---|---|
Cluster-API (0) | 2021.03.20 |
kubernetes ingress (0) | 2021.03.15 |
K3s with calico (0) | 2021.03.05 |
K3s (0) | 2019.11.17 |
- Total
- Today
- Yesterday
- OpenStack
- minikube
- jenkins
- openstack backup
- boundary ssh
- GateKeeper
- nginx-ingress
- metallb
- kubernetes
- minio
- crashloopbackoff
- ansible
- kubernetes install
- Terraform
- open policy agent
- vmware openstack
- socket
- K3S
- openstacksdk
- ceph
- kata container
- hashicorp boundary
- Helm Chart
- wsl2
- mattermost
- macvlan
- azure policy
- DevSecOps
- Jenkinsfile
- aquasecurity
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |