Skip to main content

네트워크 정책을 통한 Google Kubernetes Engine(GKE)에서 송수신 트래픽 제어

· 14 min read

image

Google Kubernetes Engine(GKE)에서는 컨테이너화된 애플리케이션을 보호하기 위해 포드 간 보안 통신을 유지하는 것이 중요합니다. 네트워크 정책은 클러스터 내 트래픽 흐름에 대한 세부적인 제어를 설정하여 이러한 목표를 달성할 수 있는 강력한 도구를 제공합니다.

다음은 GKE에서 네트워크 정책을 사용하여 인그레스 및 이그레스 트래픽을 제어하는 ​​방법을 간략하게 소개합니다.

1. 개념 이해:

  • 수신: 외부 서비스, 클러스터 내의 다른 포드 또는 로드 밸런서를 포함하여 다양한 소스에서 포드로 전달되는 수신 네트워크 트래픽을 나타냅니다.
  • 송신: 일반적으로 데이터베이스, API 또는 컨테이너 레지스트리와 같은 외부 서비스로 향하는 포드에서 발생하는 나가는 네트워크 트래픽을 나타냅니다.

2. 네트워크 정책 구현:

네트워크 정책은 GKE 클러스터 내의 YAML 리소스로 정의됩니다. 그들은 다음을 지정합니다:

  • 대상 포드: 라벨 또는 네임스페이스로 식별되어 정책이 적용되는 포드를 결정합니다.
  • 트래픽 유형: 정책이 수신, 송신 또는 둘 다를 관리하는지 여부입니다.
  • 허용된 트래픽: 대상 Pod와 통신하도록 허용된 소스 또는 대상 Pod, IP 주소 또는 서비스 계정을 지정하여 정의됩니다.

3. 네트워크 정책의 이점:

  • 보안 강화: 네트워크 정책은 무단 트래픽을 제한함으로써 클러스터 내 데이터 침해 및 무단 액세스 위험을 완화합니다.
  • 최소 권한 원칙: 세분화된 액세스 제어를 시행하여 포드가 올바르게 작동하는 데 필요한 네트워크 액세스만 갖도록 보장할 수 있습니다.
  • 향상된 네트워크 가시성: 네트워크 정책은 허용된 통신 경로에 대한 명확한 이해를 제공하여 문제 해결 및 보안 감사를 용이하게 합니다.

본질적으로 네트워크 정책은 GKE 클러스터 내에서 보안 체크포인트 역할을 하여 데이터 흐름을 규제하고 잠재적인 보안 위협으로부터 애플리케이션을 보호합니다.

구현 세부정보

이 개념 증명에서는 네임스페이스 생성에 대한 초기 단계와 해당 네임스페이스 내의 세 가지 배포를 통해 Kubernetes 환경에 대한 구성 및 설정 세부 정보를 간략하게 설명합니다.

1. 네임스페이스 생성:

Kubernetes 클러스터 내의 리소스를 격리하고 구성하기 위해 "sample"이라는 네임스페이스가 생성되었습니다.

2. 배포 개요:

세 개의 배포가 "sample" 네임스페이스 내에 설정되었으며 각각 이름은 다음과 같습니다.

  • "sample-app-1"
  • "sample-app-2"
  • "sample-app-3"

3. 이미지 선택:

배포에서는 컨테이너화를 위해 'gcloud-slim' Docker 이미지를 활용합니다. 이 이미지는 리소스 효율성 및 최적화에 대한 특정 요구 사항을 충족하기 위해 선택되었습니다.

4. YAML 파일:

sample-app-1, 2, 3의 배포 YAML은 아래와 같습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-app-1
namespace: sample
spec:
replicas: 1
selector:
matchLabels:
app: sample-app-1
template:
metadata:
labels:
app: sample-app-1
spec:
containers:
- image: google/cloud-sdk:slim
name: gcloud-test-app
command: ["sleep", "infinity"]

---

apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-app-2
namespace: sample
spec:
replicas: 1
selector:
matchLabels:
app: sample-app-2
template:
metadata:
labels:
app: sample-app-2
spec:
containers:
- image: google/cloud-sdk:slim
name: gcloud-test-app
command: ["sleep", "infinity"]

---

apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-app-3
namespace: sample
spec:
replicas: 1
selector:
matchLabels:
app: sample-app-3
template:
metadata:
labels:
app: sample-app-3
spec:
containers:
- image: google/cloud-sdk:slim
name: gcloud-test-app
command: ["sleep", "infinity"]

네트워크 정책은 YAML 매니페스트를 사용하여 설정되었으며 "샘플" 네임스페이스 내에서 통신 권한을 구성합니다. 특히 "sample-app-1"은 "sample-app-2"와, "sample-app-2"는 "sample-app-3"과 양방향으로 통신할 수 있으며 그 반대의 경우도 마찬가지입니다. 그러나 “sample-app-3”에서 “sample-app-1”로의 통신은 정의된 정책에 따라 제한됩니다. 설명된 설정은 제어되고 선택적인 포드 간 통신을 보장합니다.

그래픽적으로 다음과 같이 나타낼 수 있습니다.

그림 1: 기술 아키텍처 | 네트워크 정책의 도식적 표현

image

네트워크 정책 YAML 파일:

우리는 네트워크 정책을 사용하여 시행되는 클러스터 내 트래픽을 제어하기 위해 특정 수신 및 송신 정책을 적용했습니다. 외부 트래픽의 경우 Istio 서비스 항목을 사용하고 있습니다.

수신 허용 트래픽:

  • GCP 외부 HTTPS 부하 분산기 상태 확인 IP 범위는 포트 80,443에서만 130.211.0.0/22, 35.191.0.0/16입니다.
  • 포트 80 및 443에서만 샘플 네임스페이스의 샘플-앱-2 배포에서.
  • 모든 포트의 kube-system 및 istio-system 네임스페이스 배포에서.

송신 허용 트래픽:

  • GCP의 메타데이터 서버 — 포트 988의 169.254.169.252/32 및 포트 80의 169.254.169.254/32
  • 포트 80 및 443의 네임스페이스 샘플에 샘플-앱-2를 배포합니다.
  • 모든 포트의 kube-system 및 istio-system 네임스페이스에 배포됩니다.

그림 2: 기술 아키텍처 | sample-app-1에 대한 네트워크 정책의 그래픽 표현

image

sampl-app-1의 네트워크 정책 yaml은 아래와 같습니다.

## For sample-app1, below network polciy yaml is applied

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: sample-app-1-nw-policy
namespace: sample
spec:
podSelector:
matchLabels:
app: sample-app-1
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: sample-app-2
ports:
- port: 80
- port: 443
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: istio-system
- from:
- ipBlock:
cidr: 130.211.0.0/22
ports:
- port: 80
- port: 443
- from:
- ipBlock:
cidr: 35.191.0.0/16
ports:
- port: 80
- port: 443
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: istio-system
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
- to:
- podSelector:
matchLabels:
app: sample-app-2
ports:
- port: 80
- port: 443
- to:
- ipBlock:
cidr: 169.254.169.254/32
ports:
- port: 80
- to:
- ipBlock:
cidr: 169.254.169.252/32
ports:
- port: 988

확인

  1. 아래 명령을 사용하여 세 개의 포드 모두에 실행합니다.
kubectl exec -it <pod-name> -n sample -- bash

Sample output:

kubectl get pods -n sample
NAME READY STATUS RESTARTS AGE
sample-app-1-7f4c69bc85-wr5mq 1/1 Running 0 39s
sample-app-2-59dfd44fcd-pwpct 1/1 Running 0 32s
sample-app-3-5c8f7c9d4c-zs2p2 1/1 Running 0 26s

root@ganesh-instance-02:~/policies/sample# kubectl exec -it sample-app-1-7f4c69bc85-wr5mq -n sample -- bash

2. 세 포드 모두에 nginx, 컬, 핑 및 기타 유틸리티를 설치합니다.

apt install dnsutils
apt install net-tools
apt install iputils-ping
apt install nginx
service nginx start

sample output:


root@sample-app-1-7f4c69bc85-wr5mq:/# apt install dnsutils
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
bind9-dnsutils bind9-host bind9-libs libfstrm0 libicu72 libjemalloc2 libjson-c5 liblmdb0 libmaxminddb0 libprotobuf-c1 libuv1 libxml2
Suggested packages:
mmdb-bin
The following NEW packages will be installed:
bind9-dnsutils bind9-host bind9-libs dnsutils libfstrm0 libicu72 libjemalloc2 libjson-c5 liblmdb0 libmaxminddb0 libprotobuf-c1 libuv1 libxml2
0 upgraded, 13 newly installed, 0 to remove and 0 not upgraded.
Need to get 13.0 MB of archives.
After this operation, 45.8 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y


root@sample-app-1-7f4c69bc85-wr5mq:/# apt install net-tools
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
net-tools
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 243 kB of archives.
After this operation, 1001 kB of additional disk space will be used.
Get:1 http://deb.debian.org/debian bookworm/main amd64 net-tools amd64 2.10-0.1 [243 kB]
Fetched 243 kB in 0s (1259 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package net-tools.
(Reading database ... 61295 files and directories currently installed.)
Preparing to unpack .../net-tools_2.10-0.1_amd64.deb ...
Unpacking net-tools (2.10-0.1) ...
Setting up net-tools (2.10-0.1) ...


root@sample-app-1-7f4c69bc85-wr5mq:/# apt install iputils-ping
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
libcap2-bin libpam-cap
The following NEW packages will be installed:
iputils-ping libcap2-bin libpam-cap
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 96.2 kB of archives.
After this operation, 311 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://deb.debian.org/debian bookworm/main amd64 libcap2-bin amd64 1:2.66-4 [34.7 kB]
Get:2 http://deb.debian.org/debian bookworm/main amd64 iputils-ping amd64 3:20221126-1 [47.1 kB]
Get:3 http://deb.debian.org/debian bookworm/main amd64 libpam-cap amd64 1:2.66-4 [14.5 kB]
Fetched 96.2 kB in 0s (340 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package libcap2-bin.
(Reading database ... 61350 files and directories currently installed.)
Preparing to unpack .../libcap2-bin_1%3a2.66-4_amd64.deb ...
Unpacking libcap2-bin (1:2.66-4) ...
Selecting previously unselected package iputils-ping.
Preparing to unpack .../iputils-ping_3%3a20221126-1_amd64.deb ...
Unpacking iputils-ping (3:20221126-1) ...
Selecting previously unselected package libpam-cap:amd64.
Preparing to unpack .../libpam-cap_1%3a2.66-4_amd64.deb ...
Unpacking libpam-cap:amd64 (1:2.66-4) ...
Setting up libcap2-bin (1:2.66-4) ...
Setting up libpam-cap:amd64 (1:2.66-4) ...
debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 78.)
debconf: falling back to frontend: Readline
Setting up iputils-ping (3:20221126-1) ...


root@sample-app-1-7f4c69bc85-wr5mq:/# apt install nginx
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
iproute2 libatm1 libbpf1 libelf1 libmnl0 libxtables12 nginx-common
Suggested packages:
iproute2-doc fcgiwrap nginx-doc ssl-cert
The following NEW packages will be installed:
iproute2 libatm1 libbpf1 libelf1 libmnl0 libxtables12 nginx nginx-common
0 upgraded, 8 newly installed, 0 to remove and 0 not upgraded.
Need to get 2116 kB of archives.
After this operation, 7010 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://deb.debian.org/debian bookworm/main amd64 libelf1 amd64 0.188-2.1 [174 kB]
Get:2 http://deb.debian.org/debian bookworm/main amd64 libbpf1 amd64 1:1.1.0-1 [145 kB]
Get:3 http://deb.debian.org/debian bookworm/main amd64 libmnl0 amd64 1.0.4-3 [12.5 kB]
Get:4 http://deb.debian.org/debian bookworm/main amd64 libxtables12 amd64 1.8.9-2 [30.8 kB]
Get:5 http://deb.debian.org/debian bookworm/main amd64 iproute2 amd64 6.1.0-3 [1046 kB]
Get:6 http://deb.debian.org/debian bookworm/main amd64 libatm1 amd64 1:2.5.1-4+b2 [68.3 kB]
Get:7 http://deb.debian.org/debian bookworm/main amd64 nginx-common all 1.22.1-9 [112 kB]
Get:8 http://deb.debian.org/debian bookworm/main amd64 nginx amd64 1.22.1-9 [527 kB]
Fetched 2116 kB in 0s (5728 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package libelf1:amd64.
(Reading database ... 61386 files and directories currently installed.)
Preparing to unpack .../0-libelf1_0.188-2.1_amd64.deb ...
Unpacking libelf1:amd64 (0.188-2.1) ...
Selecting previously unselected package libbpf1:amd64.
Preparing to unpack .../1-libbpf1_1%3a1.1.0-1_amd64.deb ...
Unpacking libbpf1:amd64 (1:1.1.0-1) ...
Selecting previously unselected package libmnl0:amd64.
Preparing to unpack .../2-libmnl0_1.0.4-3_amd64.deb ...
Unpacking libmnl0:amd64 (1.0.4-3) ...
Selecting previously unselected package libxtables12:amd64.
Preparing to unpack .../3-libxtables12_1.8.9-2_amd64.deb ...
Unpacking libxtables12:amd64 (1.8.9-2) ...
Selecting previously unselected package iproute2.
Preparing to unpack .../4-iproute2_6.1.0-3_amd64.deb ...
Unpacking iproute2 (6.1.0-3) ...
Selecting previously unselected package libatm1:amd64.
Preparing to unpack .../5-libatm1_1%3a2.5.1-4+b2_amd64.deb ...
Unpacking libatm1:amd64 (1:2.5.1-4+b2) ...
Selecting previously unselected package nginx-common.
Preparing to unpack .../6-nginx-common_1.22.1-9_all.deb ...
Unpacking nginx-common (1.22.1-9) ...
Selecting previously unselected package nginx.
Preparing to unpack .../7-nginx_1.22.1-9_amd64.deb ...
Unpacking nginx (1.22.1-9) ...
Setting up nginx-common (1.22.1-9) ...
debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 78.)
debconf: falling back to frontend: Readline
Setting up libatm1:amd64 (1:2.5.1-4+b2) ...
Setting up libmnl0:amd64 (1.0.4-3) ...
Setting up libxtables12:amd64 (1.8.9-2) ...
Setting up libelf1:amd64 (0.188-2.1) ...
Setting up libbpf1:amd64 (1:1.1.0-1) ...
Setting up iproute2 (6.1.0-3) ...
debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 78.)
debconf: falling back to frontend: Readline
Setting up nginx (1.22.1-9) ...
invoke-rc.d: could not determine current runlevel
invoke-rc.d: policy-rc.d denied execution of start.
Processing triggers for libc-bin (2.36-9+deb12u4) ...

root@sample-app-2-59dfd44fcd-pwpct:/# service nginx start
Starting nginx: nginx.

3. SSH를 통해 샘플-1 포드의 설정을 확인합니다.

1. curl <sampl-app-2-pod-ip> 80

# Expected Output - nginx welcome page must open

Sample Actual output:
root@ganesh-instance-02:~/policies/sample# kubectl get pods -n sample -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
sample-app-1-7f4c69bc85-wr5mq 1/1 Running 0 15m 10.32.0.44 gke-sample-test-nw-poli-e2-node-medium-p-ed273764-51g2 <none> <none>
sample-app-2-59dfd44fcd-pwpct 1/1 Running 0 15m 10.32.0.45 gke-sample-test-nw-poli-e2-node-medium-p-ed273764-51g2 <none> <none>
sample-app-3-5c8f7c9d4c-zs2p2 1/1 Running 0 15m 10.32.0.46 gke-sample-test-nw-poli-e2-node-medium-p-ed273764-51g2 <none> <none>
root@ganesh-instance-02:~/policies/sample# kubectl exec -it sample-app-1-7f4c69bc85-wr5mq -n sample -- bash
root@sample-app-1-7f4c69bc85-wr5mq:/# curl 10.32.0.45 80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>


2. Connect to app-3 from app-1: curl <sampl-app-3-pod-ip> 80

# Expected Output - connection should time out.

Sample Actual output:
root@ganesh-instance-02:~/policies/sample# kubectl get pods -n sample -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
sample-app-1-7f4c69bc85-wr5mq 1/1 Running 0 15m 10.32.0.44 gke-sample-test-nw-poli-e2-node-medium-p-ed273764-51g2 <none> <none>
sample-app-2-59dfd44fcd-pwpct 1/1 Running 0 15m 10.32.0.45 gke-sample-test-nw-poli-e2-node-medium-p-ed273764-51g2 <none> <none>
sample-app-3-5c8f7c9d4c-zs2p2 1/1 Running 0 15m 10.32.0.46 gke-sample-test-nw-poli-e2-node-medium-p-ed273764-51g2 <none> <none>

root@sample-app-1-7f4c69bc85-wr5mq:/# curl 10.32.0.46 80
curl: (28) Failed to connect to 10.32.0.46 port 80 after 131344 ms: Couldn't connect to server


3. Connect to Metadata server:

curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/email

Expected Output:
# If workload identity is setup, GCP SA must be the output. Else Cluster Service Account must be displayed. Basically, the connection must happen.

Sample Actual Output:

root@sample-app-1-7f4c69bc85-wr5mq:/# curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/email
test-demo-410111.svc.id.goog




4. nslookup google.com

Expected output: Must connect to nameserver and display DNS server address which is kubeDNS service IP.

Sample Actual output:

root@sample-app-1-7f4c69bc85-wr5mq:/# nslookup google.com
Server: 10.36.0.10
Address: 10.36.0.10#53

Non-authoritative answer:
Name: google.com
Address: 173.194.206.113
Name: google.com
Address: 173.194.206.101
Name: google.com
Address: 173.194.206.100
Name: google.com
Address: 173.194.206.139
Name: google.com
Address: 173.194.206.102
Name: google.com
Address: 173.194.206.138
Name: google.com
Address: 2607:f8b0:4001:c07::8b
Name: google.com
Address: 2607:f8b0:4001:c07::64
Name: google.com
Address: 2607:f8b0:4001:c07::65
Name: google.com
Address: 2607:f8b0:4001:c07::71

제한 사항

표준 GKE 클러스터에는 다음 요구사항 및 제한사항이 적용됩니다.

  • GKE용 워크로드 아이덴티티 제휴를 사용하여 네트워크 정책을 구현하는 경우 메타데이터 서버로의 이그레스를 허용해야 합니다 .
  • 네트워크 정책 적용을 활성화하면 kube-system 프로세스의 메모리 공간이 약 128MB 증가하고 약 300밀리코어의 CPU가 필요합니다. 즉, 기존 클러스터에 네트워크 정책을 사용 설정하면 예약된 작업 부하를 계속 실행하기 위해 GKE 클러스터에서 클러스터 크기를 늘려야 할 수도 있습니다 .
  • 네트워크 정책 시행을 사용 설정하려면 GKE 노드를 다시 만들어야 합니다. 클러스터에 활성 유지 관리 기간이 있는 경우 다음 유지 관리 기간까지 노드가 자동으로 다시 생성되지 않습니다.
  • 네트워크 정책 시행을 실행하기 위해 GCP에서 권장하는 최소 클러스터 크기는 e2-medium 인스턴스 3개입니다.

리소스 요구 사항이 너무 높기 때문에 노드가 f1-micro 또는 g1-small 인스턴스인 클러스터에는 네트워크 정책이 지원되지 않습니다.

결론

네트워크 정책은 GKE 클러스터 내에서 수신 및 송신 트래픽을 제어하는 ​​강력하고 유연한 접근 방식을 제공합니다. 이러한 정책을 효과적으로 정의하고 활용함으로써 우리는 다음을 달성할 수 있습니다.

  • 보안 강화: 무단 트래픽을 제한함으로써 클러스터 내에서 데이터 침해 및 무단 액세스의 위험을 크게 줄입니다.
  • 향상된 제어 및 규정 준수: 네트워크 통신에 대한 세부적인 제어는 최소 권한 원칙에 부합하며 보안 규정 준수를 용이하게 합니다.
  • 단순화된 네트워크 관리: 네트워크 정책은 허용된 통신 경로에 대한 명확한 가시성을 제공하여 문제 해결을 돕고 보안 감사를 단순화합니다.

네트워크 정책 구현에 능숙해지면 GKE 내에서 컨테이너화된 애플리케이션을 위한 보다 안전하고 잘 정의된 환경을 만들 수 있습니다. 이를 통해 우리는 잠재적인 보안 위험을 완화하면서 자신 있게 애플리케이션을 배포하고 관리할 수 있습니다.

React의 useState에서 피해야 할 4 가지 실수 🚫

· 5 min read

image

소개

React.js는 구성 요소 내에서 상태를 관리하는 고유한 접근 방식을 통해 현대 웹 개발의 초석이 되었습니다. 일반적인 후크 중 하나 useState는 기본이지만 종종 오용됩니다. 이러한 일반적인 실수를 이해하고 피하는 것은 효율적이고 버그 없는 애플리케이션을 만드는 것을 목표로 하는 초보자와 숙련된 개발자 모두에게 중요합니다.

useState이 블로그에서는 React에서 사용할 때 피해야 할 네 가지 중요한 실수에 대해 알아볼 것입니다 . 함께 React 기술을 향상시켜 봅시다!

실수 1: 이전 상태를 고려하는 것을 잊음 😨

React의 useState후크로 작업할 때 흔히 저지르는 실수는 업데이트할 때 가장 최근 상태를 고려하지 않는 것입니다. 이러한 방식은 특히 신속하거나 여러 상태 업데이트를 처리할 때 예기치 않은 동작으로 이어질 수 있습니다.

❌ 문제 이해

React에서 카운터를 구축한다고 가정해 보겠습니다. 당신의 목표는 버튼을 클릭할 때마다 횟수를 늘리는 것입니다. 간단한 접근 방식은 단순히 현재 상태 값에 1을 추가하는 것입니다. 그러나 이는 문제가 될 수 있습니다.

import React, { useState } from 'react';

const CounterComponent = () => {
const [counter, setCounter] = useState(0);

const incrementCounter = () => {
setCounter(counter + 1); // Might not always work as expected
};

return (
<div>
<p>Counter: {counter}</p>
<button onClick={incrementCounter}>Increment</button>
</div>
);
};

export default CounterComponent;

위 코드에서는 incrementCounter현재 값을 기준으로 카운터를 업데이트합니다. 이는 간단해 보이지만 문제가 발생할 수 있습니다. React는 여러 setCounter호출을 일괄적으로 일괄 처리하거나 다른 상태 업데이트가 방해를 받아 counter매번 올바르게 업데이트되지 않을 수 있습니다.

✅ 수정사항:

이 문제를 방지하려면 메서드의 기능적 형식을 사용하세요 setCounter. 이 버전은 React가 가장 최근의 상태 값으로 호출하는 함수를 인수로 사용합니다. 이렇게 하면 항상 최신 상태 값으로 작업할 수 있습니다.

import React, { useState } from 'react';

const CounterComponent = () => {
const [counter, setCounter] = useState(0);

const incrementCounter = () => {
setCounter(prevCounter => prevCounter + 1); // Correctly updates based on the most recent state
};

return (
<div>
<p>Counter: {counter}</p>
<button onClick={incrementCounter}>Increment</button>
</div>
);
};

export default CounterComponent;

이 수정된 코드에서는 incrementCounter함수를 사용하여 상태를 업데이트합니다. 이 함수는 가장 최근 상태( prevCounter)를 수신하고 업데이트된 상태를 반환합니다. 이 접근 방식은 특히 업데이트가 빠르게 또는 연속해서 여러 번 발생할 때 훨씬 더 안정적입니다.

실수 2: 상태 불변성 무시 🧊

❌ 문제 이해

React에서 상태는 불변으로 취급되어야 합니다. 일반적인 실수는 특히 객체 및 배열과 같은 복잡한 데이터 구조의 경우 상태를 직접 변경하는 것입니다.

상태 저장 객체에 대한 다음과 같은 잘못된 접근 방식을 고려해보세요.

import React, { useState } from 'react';

const ProfileComponent = () => {
const [profile, setProfile] = useState({ name: 'John', age: 30 });

const updateAge = () => {
profile.age = 31; // Directly mutating the state
setProfile(profile);
};

return (
<div>
<p>Name: {profile.name}</p>
<p>Age: {profile.age}</p>
<button onClick={updateAge}>Update Age</button>
</div>
);
};

export default ProfileComponent;

이 코드는 profile개체를 직접 잘못 변경합니다. 이러한 변형은 다시 렌더링을 유발하지 않으며 예측할 수 없는 동작으로 이어지지 않습니다.

✅ 수정사항:

불변성을 유지하기 위해 상태를 업데이트할 때 항상 새 개체나 배열을 만듭니다. 이 목적으로 스프레드 연산자를 사용하십시오.

import React, { useState } from 'react';

const ProfileComponent = () => {
const [profile, setProfile] = useState({ name: 'John', age: 30 });

const updateAge = () => {
setProfile({...profile, age: 31}); // Correctly updating the state
};

return (
<div>
<p>Name: {profile.name}</p>
<p>Age: {profile.age}</p>
<button onClick={updateAge}>Update Age</button>
</div>
);
};

export default ProfileComponent;

수정된 코드에서는 updateAge스프레드 연산자를 사용하여 profile상태 불변성을 유지하면서 업데이트된 수명으로 새 개체를 만듭니다.

실수 3: 비동기 업데이트에 대한 오해 ⏳

❌ 문제 이해

React의 상태 업데이트는 useState비동기식입니다. 이는 특히 여러 상태 업데이트가 빠르게 연속적으로 이루어질 때 혼란을 야기하는 경우가 많습니다. 개발자는 호출 직후 상태가 변경될 것으로 예상할 수 있지만 setState실제로 React는 성능상의 이유로 이러한 업데이트를 일괄 처리합니다.

이러한 오해로 인해 문제가 발생할 수 있는 일반적인 시나리오를 살펴보겠습니다.

import React, { useState } from 'react';

const AsyncCounterComponent = () => {
const [count, setCount] = useState(0);

const incrementCount = () => {
setCount(count + 1);
setCount(count + 1);
// Developer expects count to be incremented twice
};

return (
<div>
<p>Count: {count}</p>
<button onClick={incrementCount}>Increment Count</button>
</div>
);
};

export default AsyncCounterComponent;

이 예에서 개발자는 count두 배로 증가시키려고 합니다. 그러나 상태 업데이트의 비동기적 특성으로 인해 두 setCount호출 모두 동일한 초기 상태를 기반으로 하므로 결과는 count한 번만 증가됩니다.

✅ 수정사항:

비동기 업데이트를 올바르게 처리하려면 의 기능 업데이트 형식을 사용하세요 setCount. 이렇게 하면 각 업데이트가 가장 최근 상태를 기반으로 합니다.

import React, { useState } from 'react';

const AsyncCounterComponent = () => {
const [count, setCount] = useState(0);

const incrementCount = () => {
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount + 1);
// Now each update correctly depends on the most recent state
};
// Optional: Use useEffect to see the updated state
useEffect(() => {
console.log(count); // 2
}, [count]);

return (
<div>
<p>Count: {count}</p>
<button onClick={incrementCount}>Increment Count</button>
</div>
);
};

export default AsyncCounterComponent;

위 코드에서 각 호출은 setCount최신 상태 값을 사용하여 정확하고 순차적인 업데이트를 보장합니다. 이 접근 방식은 현재 상태에 의존하는 작업, 특히 여러 상태 업데이트가 빠르게 연속적으로 발생할 때 매우 중요합니다.

실수 4: 파생 데이터의 상태 오용 📊

❌ 문제 이해

자주 발생하는 오류는 기존 상태나 소품에서 파생될 수 있는 데이터에 상태를 사용하는 것입니다. 이러한 중복 상태는 복잡하고 오류가 발생하기 쉬운 코드로 이어질 수 있습니다.

예를 들어:

import React, { useState } from 'react';

const GreetingComponent = ({ name }) => {
const [greeting, setGreeting] = useState(`Hello, ${name}`);

return (
<div>{greeting}</div>
);
};

export default GreetingComponent;

여기서 greeting상태는 에서 직접 파생될 수 있으므로 필요하지 않습니다 name.

✅ 수정사항:

상태를 사용하는 대신 기존 상태나 소품에서 직접 데이터를 파생하세요.

import React from 'react';

const GreetingComponent = ({ name }) => {
const greeting = `Hello, ${name}`; // Directly derived from props

return (
<div>{greeting}</div>
);
};

export default GreetingComponent;

수정된 코드에서는 greeting가 prop에서 직접 계산되어 name구성 요소를 단순화하고 불필요한 상태 관리를 방지합니다.

결론 🚀

안정적이고 효율적인 애플리케이션을 구축하려면 React에서 후크를 효과적으로 사용하는 것이 useState중요합니다. 이전 상태 무시, 상태 불변성 관리 잘못, 비동기 업데이트 간과, 파생 데이터의 중복 상태 방지와 같은 일반적인 실수를 이해하고 방지함으로써 구성 요소 동작을 보다 원활하고 예측 가능하게 보장할 수 있습니다. 도움이 되었길 바랍니다!

How to choose Right Messaging Broker (Kafka vs RabbitMQ)

· 4 min read

image

역동적인 이벤트 중심 아키텍처 세계에서 효율적이고 확장 가능한 통신을 위해서는 올바른 메시징 브로커를 선택하는 것이 중요합니다. 가장 인기 있는 두 경쟁자는 Kafka와 RabbitMQ이며 각각 장점과 단점이 있습니다. 유사한 목적을 제공하지만 아키텍처, 성능 특성 및 사용 사례가 서로 다릅니다. 이 블로그 게시물에서는 아키텍처의 차이점, 성능 비교를 살펴보고 의사 결정 프로세스를 탐색하는 데 도움이 되는 Kafka 및 RabbitMQ의 몇 가지 일반적인 사용 사례를 살펴보겠습니다.

Architecture

Kafka

Apache Kafka는 높은 처리량, 내결함성 및 실시간 데이터 처리 기능으로 잘 알려진 오픈 소스 분산 이벤트 스트리밍 플랫폼입니다. Kafka는 생산자가 주제에 메시지를 쓰고 소비자가 해당 주제를 구독하여 메시지를 받는 pub-sub 모델을 따릅니다. Kafka는 메시지를 분산 커밋 로그에 저장하므로 높은 확장성과 내결함성을 제공합니다. 이를 통해 높은 처리량과 메시지 재생 기능이 가능하므로 실시간 데이터 처리 및 이벤트 소싱에 이상적입니다.

Kafka의 아키텍처는 생산자, 브로커, 소비자라는 세 가지 주요 구성 요소로 구성됩니다. 생산자는 Kafka 주제에 메시지를 게시하고 브로커는 Kafka 클러스터 전체에 데이터를 저장하고 복제하는 일을 담당합니다. 소비자는 하나 이상의 주제에서 데이터를 읽어 병렬 처리 및 확장성을 가능하게 합니다.

RabbitMQ

RabbitMQ는 AMQP(Advanced Message Queuing Protocol)를 구현하는 유연한 오픈 소스 메시지 브로커입니다. 이는 전통적인 메시지 대기열 모델(RabbitMQ 대기열)을 따르므로 애플리케이션이 메시지를 보내고 받고 특정 소비자에게 메시지를 전달함으로써 비동기적으로 통신할 수 있습니다. 이는 안정적인 메시지 순서와 메시지 라우팅의 유연성을 보장하므로 작업 처리 및 마이크로서비스 통신에 적합합니다.

RabbitMQ의 아키텍처는 생산자와 소비자 사이의 중개자 역할을 하는 중앙 메시지 브로커를 중심으로 합니다. 메시지 복제 및 보존을 위해 생산자는 교환에 메시지를 보내고 해당 교환은 미리 정의된 규칙에 따라 메시지를 대기열로 라우팅합니다. 그런 다음 소비자는 대기열에서 메시지를 검색하여 처리합니다.

Performance

Kafka

높은 처리량 및 실시간 데이터 스트리밍 시나리오에서 탁월하며 뛰어난 확장성과 낮은 대기 시간을 자랑합니다. 초당 수백만 개의 메시지를 처리할 수 있으므로 빠르고 지속적인 데이터 처리가 필요한 사용 사례에 적합합니다. 해당 아키텍처는 워크로드를 여러 브로커에 분산하여 수평적 확장을 허용하고 대용량 데이터를 효율적으로 처리합니다. 또한 메시지를 디스크에 유지함으로써 강력한 내구성을 보장하고 내결함성과 데이터 내구성을 보장합니다.

RabbitMQ

승인 및 메시지 지속성과 같은 기능을 제공하여 안정적인 메시지 전달을 제공합니다. 초당 수천 개의 메시지를 처리할 수 있으므로 중간 수준의 처리량 요구 사항이 있는 사용 사례에 적합합니다. 중앙 집중식 아키텍처로 인해 약간의 성능 오버헤드가 발생할 수 있지만 견고성과 메시지 무결성을 제공합니다. 수직으로 확장되는 동안 수평 확장 기능은 Kafka에 비해 제한됩니다.

Use Cases

Kafka

  • 실시간 분석 및 스트리밍 애플리케이션
  • 특히 빅 데이터와 관련된 이벤트 소싱, 수집 및 로그 집계입니다.
  • 대용량 메시지 처리를 통한 데이터 파이프라인 및 마이크로서비스 통신
  • 높은 확장성과 내결함성을 요구하는 애플리케이션

RabbitMQ

  • 측정항목 및 알림을 포함한 작업 처리, 서비스 통합, 워크플로 조정 및 워크플로 관리.
  • 마이크로서비스 간 비동기 통신
  • 메시지 우선 순위 및 특정한 복잡한 라우팅 요구 사항을 포함하여 안정적인 메시지 전달 기능을 갖춘 엔터프라이즈 메시징 시스템입니다.
  • 지점 간, 게시-구독 및 요청-응답과 같은 메시징 패턴을 지원하는 RabbitMQ의 유연성은 다양한 애플리케이션 시나리오에서 유용합니다.

Making the Choice

궁극적으로 최적의 선택은 특정 요구 사항에 따라 다릅니다.

  • 높은 처리량과 실시간 데이터 처리를 우선시하시겠습니까? Kafka
  • 적당한 작업 부하를 위해 안정적인 메시지 전달과 유연한 라우팅이 필요합니까? RabbitMQ
  • 메시지 재생 및 로그 집계를 고려하고 계십니까? Kafka
  • 대용량 마이크로서비스 통신을 위한 원활한 확장을 찾고 계십니까? Kafka

특정 요구 사항을 분석하고 중복성, 확장성, 고성능, 고가용성, 대규모 API 및 보안과 같은 요소를 고려하는 것은 모두 정보에 입각한 결정을 내리는 데 중요합니다.

Additional Considerations

  • 복잡성: Kafka의 분산 아키텍처 및 추가 전용 로그에는 RabbitMQ의 단순한 대기열 기반 접근 방식에 비해 더 많은 운영 전문 지식이 필요할 수 있습니다.
  • 커뮤니티 및 지원: 두 플랫폼 모두 대규모 커뮤니티와 활발한 개발을 누리고 있습니다.
  • 통합: 기존 인프라 및 도구와의 사용 가능한 통합을 평가합니다.

Conclusion

아키텍처 차이점, 성능 벤치마크 및 이상적인 사용 사례를 명확하게 이해하면 Kafka와 RabbitMQ 중에서 자신있게 선택할 수 있습니다. 따라서 프로젝트의 특정 요구 사항을 자세히 살펴보고 강력하고 효율적인 이벤트 중심 아키텍처를 향한 여정을 시작하십시오 !

Linux에서 Network 명령어 마스터하기!

· 4 min read

image

Linux에서 네트워크 명령어는 시스템 관리, 네트워크 관리 및 DevOps 영역에서 필수적으로 알아야 합니다. DevOps 전문가, 네트워크 관리자, 시스템 관리자는 물론 초보자도 네트워크를 효과적으로 관리하고 문제를 해결할 수 있도록 지원하는 상위 10개 명령을 살펴봅시다.

1. ping

  • 기능: 네트워크 연결에 대한 테스트로 pingICMP 에코 요청을 지정된 호스트 이름 또는 IP 주소로 보냅니다.
  • 사용법
ping google.com # Check reachability to Google
ping 192.168.1.10 # Test a specific IP address
  • 결과: 응답 시간(왕복 시간) 및 패킷 손실 통계는 네트워크 연결에 대한 체크에 도움이 됩니다.

2. nslookup

  • 기능: 도메인 이름 뒤에 숨은 ip를 알려줍니다. nslookupDNS 서버에 쿼리하여 호스트 이름(예: google.com)을 해당 IP 주소로 변환합니다.
  • 사용법
nslookup google.com # Discover the IP address behind Google
  • 출력: 호스트 이름과 연결된 IP 주소가 표시되어 도메인 이름이 물리적 시스템에 매핑되는 방식을 이해하는 데 도움이 됩니다.

3. ifconfig(or ip addr)

  • 기능: 네트워크 인터페이스 세부 정보를 보려면 ifconfig(이전 시스템의 경우) 또는 ip addr(최신 시스템의 경우) 이동 명령을 사용하세요. IP 주소, MAC 주소, 인터페이스 상태 등 네트워크 인터페이스에 대한 정보를 표시합니다.
  • 사용법
ifconfig # (older systems)
ip addr # (newer systems)
  • 출력: 네트워크 구성 및 문제 해결에 중요한 네트워크 인터페이스 목록 및 관련 세부 정보가 제공됩니다.

4. netstat

  • 기능: netstat 네트워크 활동에 대한 포괄적인 보기를 제공합니다. 활성 연결, 수신 포트 및 트래픽 통계를 표시하여 네트워크 활용도 및 잠재적인 문제에 대한 통찰력을 제공합니다.
  • 사용법
netstat -a # View all network connections (TCP and UDP)
netstat -ltpn # List listening TCP ports with process IDs and names
  • 결과: 네트워크 연결에 대한 풍부한 정보를 통해 리소스 집약적인 프로세스를 식별하고 연결 문제를 진단할 수 있습니다.

5. traceroute(or tracert)

  • 기능: 네트워크 경로가 흐려지면 traceroute(또는 tracert일부 시스템에서는) 도움을 받습니다. 이는 패킷이 대상에 도달하는 데 걸리는 경로를 추적하여 관련된 네트워크 홉을 드러냅니다.
  • 사용법
traceroute google.com # Trace the route to Google's servers
  • 출력: 경로를 따라 중간 홉 목록이 표시되어 시스템과 대상 대상 간의 잠재적인 병목 현상이나 연결 문제를 정확히 찾아내는 데 도움이 됩니다.

6. ip

  • 기능: 인터페이스 정보 외에도 ip 주소 할당, 경로 설정, 방화벽 규칙 조작 등 네트워크 구성 관리를 위한 강력한 명령 모음을 제공합니다.
  • 사용법
ip route add default via 192.168.1.1 # Add a default route
ip address add 10.0.0.1/24 dev eth0 # Assign an IP address to an interface
  • 출력: 사용된 특정 명령에 따라 다르지만 ip구성 변경에 대한 실시간 피드백을 제공합니다.

7. tcpdump(or wireshark)

  • 기능: 심층 패킷 검사 tcpdump(또는 그래픽 도구 Wireshark)를 사용하는 것이 좋습니다. 지정된 인터페이스에서 네트워크 트래픽을 캡처하여 개별 패킷을 검사하고 네트워크 프로토콜을 분석할 수 있습니다.
  • 사용법
tcpdump -i eth0 # Capture packets on interface eth0
  • 출력: 캡처된 패킷이 자세한 형식으로 표시되므로 네트워크 동작을 진단하고 보안 위협을 식별할 수 있습니다.

8. ssh

  • 기능: Secure Shell 또는 ssh은 원격 시스템 관리를 위한 도구입니다. 이를 통해 다른 Linux 시스템에 대한 보안 연결을 설정하고 로컬로 로그인한 것처럼 명령을 실행할 수 있습니다.
  • 사용법
ssh user@remote_server_ip # Connect to a remote server as user
  • 출력: 직접 출력은 없지만 연결에 성공하면 서버 관리를 위한 원격 셸이 부여됩니다.

9. nmap(Network Mapper)

  • 기능: 포괄적인 네트워크 정찰 및 보안 감사를 위한 nmap최고의 기능입니다. 대상 시스템을 검사하여 다음을 식별합니다.
  • 개방형 포트: 이는 통신을 위한 잠재적인 진입점입니다.
  • 해당 포트에서 실행되는 서비스: 포트를 사용하고 있는 애플리케이션이나 프로토콜이 표시됩니다.
  • 운영 체제(OS) 및 장치 유형: nmap응답을 기반으로 대상 시스템의 OS를 식별할 수 있는 경우가 많습니다.
  • 사용법
# Basic scan to identify open ports on a target
nmap scanme.nmap.org
# Scan with additional options:
nmap -sS -T4 scanme.nmap.org # Use SYN scan with faster timing template
nmap -A scanme.nmap.org # Aggressive scan for detailed OS and service detection
  • 결과: 다음을 포함한 풍부한 정보를 제공합니다.
  • 열린 포트 및 관련 서비스 목록입니다.
  • OS 감지 세부정보(성공한 경우)
  • 특정 서비스 또는 프로토콜과 관련된 보안 취약성(고급 사용)

10. iptables/nftables (firewalls)

  • 기능: 네트워크 보안을 위해서는 iptables(레거시) 또는 nftables(최신)과 같은 Linux 방화벽이 필수적입니다. 사전 정의된 규칙에 따라 들어오고 나가는 네트워크 트래픽을 제어하여 무단 액세스로부터 시스템을 보호합니다.
  • 사용법 (iptables example):
iptables -A INPUT -p tcp --dport 22 -j ACCEPT # Allow incoming SSH connections
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT # Allow outgoing traffic to port 80 (HTTP)
  • 출력: 사용된 특정 명령에 따라 다르지만 방화벽은 규칙 생성 및 상태에 대한 피드백을 제공합니다.

+ curl

  • 기능: 네트워크 진단을 넘어 curl HTTP(S)를 통해 데이터를 전송하는 다목적 도구입니다. 이를 통해 파일을 다운로드하고, 웹 API와 상호 작용하고, 명령줄에서 기본 웹 요청을 수행할 수 있습니다.
  • 사용법
curl https://google.com # Download the Google homepage
curl -o index.html https://website.com/index.html # Download a specific file
  • 출력: 요청이 실패하면 다운로드한 콘텐츠 또는 오류 메시지를 표시합니다.

위의 상위 10가지 명령을 숙지하면 Linux 네트워킹의 문제를 효과적으로 해결해 자신 있게 네트워크를 관리할 수 있는 준비를 갖추게 됩니다. 전문 지식이 성장함에 따라 더욱 발전된 도구를 탐색하고 네트워크 보안 및 최적화 기술을 더욱 깊이 탐구하며 즐거운 네트워킹을 즐겨보세요!

2024 AI Study Roadmap

· 13 min read

image

AI를 배우고 싶어 2024년에 어떻게 해야 할지 리서치 해보면서 글을 작성해 봤습니다.

AI를 정말로 배우기 위해서는 튜토리얼 지옥을 탈출하고 정말 배우고, 실습하고, 알고리즘을 작성하고, 논문을 구현하며, AI를 사용해 문제를 해결하는 사이드 프로젝트를 수행해야 합니다.

이제 AI를 공부하는 방식을 생각해 보면,

Top-down 접근방식

필요에 따라 배우는 것을 할 줄 알아야 합니다. 모든 것을 배우려면 한 개를 배우기에도 너무 깊은 분야이기에 필요에 따라 필요한 것들을 특정해 배워나가야 합니다.

그렇게 하려면 코드 우선, 이론 나중에로 진행하게 할 겁니다.

공개적으로 배워야 합니다!

AI를 사용하려면 배워야 할 것이 많고 새로운 혁명적인 논문과 아이디어가 매주 발표되니 학습해야 할 것이 끝이 없습니다.

그렇게 때문에 개인적으로 배우는 것은 가장 큰 실수입니다. 그렇게 하면 스스로에게 어떤 기회도 창출되지 않고 뭔가 완료했다고 말 할 수 있는 것 외에는 보여줄 것이 없습니다.

중요한 것은 무엇을 만들었고, 그것을 대중과 공유할 지식으로 어떻게 전환시켰고, 그 정보에서 어떤 참신한 아이디어와 솔루션이 나왔는가이기 때문입니다. 그래서 공개적으로 배워야 합니다!

블로그, 튜토리얼을 작성하거나 해커톤에 참여하며 다른 사람들과 협력하고, Discord 커뮤니티에서 질문하고 답변하고 사이드 프로젝트에 참여하세요!

이제 본격적으로 시작해 보겠습니다!

image

우선 수학을 알아야 합니다. 머신 러닝은 선형 대수학, 미적분학, 확률, 통계라는 수학의 세 가지 요소에 크게 의존합니다. 각각은 알고리즘이 효과적으로 작동하도록 하는 데 고유한 역할을 합니다.

  • 선형 대수학(Linear Algebra): 행렬과 벡터가 정보를 해석하고 처리하는 알고리즘용 언어를 형성하는 데이터 표현 및 조작을 위한 수학적 툴킷
  • 미적분학(Calculus): 기계 학습 최적화를 위한 엔진으로, 기울기와 변화율을 이해하여 알고리즘을 학습하고 개선할 수 있습니다.
  • 확률 및 통계: 불확실성 하에서의 의사결정을 위한 기반으로, 알고리즘이 결과를 예측하고 무작위성 및 변동성 모델을 통해 데이터로부터 학습할 수 있도록 합니다.

프로그래머의 관점에서 ML을 위한 수학에 대한 훌륭한 시리즈입니다. 가중치 및 편향을 통한 기계 학습을 위한 수학 ( 코드 )

선형 대수학에 대한 코드 우선 접근 방식을 원한다면 fast.ai 제작자가 만든 전산 선형 대수학 ( 비디오 , 코드 )을 수행하세요.

과정과 함께 Python을 사용한 응용 기계 학습을 위한 선형 대수학 소개를 읽어보세요.

좀 더 전통적인 것을 원한다면 Imperial College London 강의선형 대수학다변량 미적분학을 살펴보십시오.

3Blue1Brown의 선형 대수학의 본질미적분학의 본질을 시청하세요.

통계를 보려면 StatQuest의 통계 기초를 시청하세요.

보충

도구

image

파이썬

초보자는 여기서 시작하세요: 실용적인 Python 프로그래밍

이미 Python에 익숙하다면 고급 Python 마스터리를 수행하세요.

둘 다 Python Cookbook의 저자인 David Beazley가 만든 훌륭한 강좌입니다.

그 후 James Powell의 강연을 시청해 보세요.

Python 디자인 패턴을 읽어보세요 .

보충

파이토치

Aladdin PerssonPyTorch 튜토리얼 보기

PyTorch 웹사이트는 훌륭한 곳입니다.

몇 가지 퍼즐로 지식을 테스트해보세요

보충

기계 학습

image

100페이지 분량의 ML 책을 읽어보세요.

처음부터 쓰기

읽는 동안 알고리즘을 처음부터 작성하세요.

아래 저장소를 살펴보세요

도전해보고 싶다면 이 과정을 따라 처음부터 PyTorch를 작성해 보세요.

경쟁하다

배운 내용을 대회에서 적용해 보세요.

사이드 프로젝트를 해보세요

Vicki Boykis의 기계 학습을 프로덕션에 적용하기를 읽어보세요 .

그녀는 또한 책에 대한 의미론적 검색인 Viberary를 구축하면서 배운 내용에 대해 썼습니다 .

데이터 세트를 얻고 모델을 구축합니다(즉, Earthaccess를 사용하여 NASA 지구 데이터를 얻습니다).

Streamlit을 사용하여 UI를 만들고 Twitter에서 공유하세요.

배포

생산 중인 모델을 가져옵니다. 실험을 추적하세요. 모델을 모니터링하는 방법을 알아보세요. 데이터와 모델 드리프트를 직접 경험해보세요.

다음은 몇 가지 훌륭한 리소스입니다.

보충

딥러닝

image

문제를 해결하기 위해 코드 먼저 배우고 이론 배우기를 원한다면 fast.ai로 시작해 보세요.

Fast.ai

fast.ai를 좋아하시나요? 풀스택 딥러닝을 확인해 보세요 .

보다 포괄적이고 전통적인 과정을 원한다면 François FleuretUNIGE 14x050 — 딥 러닝을 확인하세요 .

어느 시점에서 이론에 도달해야 한다면 이 책은 훌륭한 책입니다.

트위터를 스크롤하는 대신 휴대폰에서 The Little Book of Deep Learning을 읽어보세요 .

신경망이 수렴되는 동안 이 내용을 읽어보세요.

더 많은 대회를 해보세요

서류 구현

labml.ai 주석이 달린 PyTorch 종이 구현을 확인해 보세요.

Papers with Code는 훌륭한 리소스입니다. 여기 웹사이트에 BERT가 설명되어 있습니다 .

다음은 딥 러닝 내 전문 분야에 대한 몇 가지 리소스입니다.

컴퓨터 시각 인식

많은 사람들이 CS231n: Deep Learning for Computer Vision을 추천합니다 . 어렵지만 이겨낸다면 그만한 가치가 있습니다.

강화 학습

RL의 경우 다음 두 가지가 훌륭합니다.

NLP

또 다른 훌륭한 스탠포드 코스, CS 224N | 딥러닝을 통한 자연어 처리

포옹 얼굴 배우기: 포옹 얼굴 NLP 과정

이 Super Duper NLP Repo를 확인하십시오.

좋은 기사와 고장

보충

대규모 언어 모델

image

먼저 Andrew의 [ 1시간 토크] 대규모 언어 모델 소개를시청하세요 .

Then Large Language Models in Five Formulas , 작성자: Alexander Rush — Cornell Tech

신경망 보기: Zero to Hero

역전파를 처음부터 설명하고 코딩하는 것으로 시작하여 처음부터 GPT를 작성하는 것으로 끝납니다.

신경망: Zero To Hero 저: Andrej Karpathy

방금 새 동영상을 공개했습니다. → GPT Tokenizer를 만들어 보겠습니다.

NumPy의 60줄에서 GPT를볼 수도 있습니다 .당신이 그것에 있는 동안 Jay Mody

무료 LLM 부트 캠프

Full Stack Deep Learning에서 무료로 출시한 유료 LLM Bootcamp 입니다.

프롬프트 엔지니어링, LLMOps, LLM용 UX 및 한 시간 안에 LLM 앱을 시작하는 방법을 가르칩니다.

이제 이 부트 캠프를 마친 후 빌드하고 싶으므로

LLM으로 구축

LLM으로 앱을 구축하고 싶으신가요?

Andrew Ng의 대규모 언어 모델을 사용한 애플리케이션 개발 보기

Huyen Chip의 생산용 LLM 애플리케이션 구축 읽기

Eugene Yan의 LLM 기반 시스템 및 제품 구축을 위한 패턴

레시피는 OpenAI Cookbook을 참조하세요 .

Vercel AI 템플릿을 사용하여 시작하세요.

해커톤에 참여하세요

lablab.ai에서는 매주 새로운 AI 해커톤이 열립니다. 팀을 이루고 싶다면 알려주세요 !

이론에 더 깊이 들어가 모든 것이 어떻게 작동하는지 이해하고 싶다면:

논문 읽기

대형 언어 모델 이해 에 관한 Sebastian Raschka 의 훌륭한 기사로 , 읽어야 할 몇 가지 논문을 나열합니다.

그는 또한 최근 미스트랄 모델을 다루는 2024년 1월에 읽어야 할 논문이 포함된 또 다른 기사를 발표했습니다 .

AI보다 앞서서 그의 서브스택을 따라가세요 .

Transformers를 처음부터 작성하세요.

Transformer 제품군 버전 2.0 읽기 | 개요를 보려면 Lil'Log를참조하세요.

가장 적합한 형식을 선택하고 처음부터 구현하세요.

종이

블로그

비디오

이제 변환기를 처음부터 코딩할 수 있습니다. 하지만 아직 더 많은 것이 있습니다.

Stanford CS25 — Transformers United동영상을 시청하세요.

좋은 블로그들

우마르 자밀 보기

그는 논문을 설명하는 환상적이고 심층적인 비디오를 보유하고 있습니다. 그는 또한 코드를 보여줍니다.

완전하지 않은 LLM과 관련된 추가 링크. LLM에 대한 보다 포괄적인 강의 계획서를 보려면 LLM 강의 계획서를 살펴보세요 .

오픈 소스 모델을 실행하는 방법을 알아보세요.

ollama 사용 : Llama 2, Mistral 및 기타 대규모 언어 모델을 로컬에서 시작 및 실행

그들은 최근 Python 및 JavaScript 라이브러리를 출시했습니다.

신속한 엔지니어링

프롬프트 엔지니어링 읽기 | 릴로그

Ise Fulford(OpenAI) 및 Andrew Ng의 개발자를 위한 ChatGPT 프롬프트 엔지니어링

DeepLearning.ai 에는 무료로 등록할 수 있는 다른 단기 강좌도 있습니다.

LLM 미세 조정

포옹 얼굴 미세 조정 가이드를 읽어보세요 .

좋은 가이드북: 미세 조정 — GenAI 가이드북

axolotl을 확인해보세요 .

이것은 좋은 기사입니다: Direct Preference Optimization을 사용하여 Mistral-7b 모델 미세 조정 | 막심 라본느

조각

Anyscale의 훌륭한 기사: 프로덕션용 RAG 기반 LLM 애플리케이션 구축

Aman Chadha검색 증강 생성 에 대한 포괄적인 개요

최신 정보를 유지하는 방법

뉴스레터 + 팟캐스트 + 트위터의 결합

논문은 AK(@_akhaliq)를 팔로우하세요.

팟캐스트 중 내가 찾은 최고는 Swyx & Alessio의 Latent Space 입니다.

그들의 불화에 동참하세요 .

또한 모든 대규모 AI 불일치를 요약한 뉴스레터 Smol Talk 도 있습니다 .

내가 좋아하는 다른 뉴스레터는 다음과 같습니다.

이 기사 에서 더 많은 정보를 얻으세요 .

유용할 수 있는 기타 커리큘럼/목록.

내 목록은 완전한 목록은 아니지만, 그래도 더 많은 것을 찾고 싶다면 여기 몇 가지를 참조하세요.

모두에게 AI 여정에 도움이 되기를 바랍니다.

NestJS 실시간 채팅 앱 구현

· 5 min read

image

서버와 클라이언트 간 통신이 실시간으로 발생해야 하는 경우가 종종 있습니다.

이런 기능은 대표적으로 채팅 앱에 많이 사용되는데요.

NestJS에서 WebSocket을 활용해 실시간 채팅 앱을 만들어 원리를 확인해 봅니다.

실시간 API란 무엇일까요?

실시간 API는 실시간으로 데이터를 교환하는 클라이언트와 서버 간의 통신입니다.

일반적으로 WebSocket을 활용해 구현하는데 WebSocket은 클라이언트와 서버 간 실시간 통신을 가능하게 하는 일종의 프로토콜이라고 보면 됩니다.

WebSocket을 구현하기 위해 프레임워크를 사용할 수 있습니다.(socket.io, ws)

프로젝트 구성

프로젝트 구조를 이야기 하자면, 아래와 같습니다.

- 클라이언트: ReactJS Wep App

- 서버: NestJS Realtime App

우선 프로젝트 폴더부터 생성하고,

mkdir nest-chat-app

프로젝트 폴더에 진입 후 NestJS로 서버 폴더를 설치합니다.

nest new server

서버 폴더에 진입 후 NestJS에서 WebSocket 작업을 시작하기 위해 패키지를 설치합니다.

npm i --save @nestjs/websockets @nestjs/platform-socket.io

서버는 얼추 설치가 마무리 됐고, 다시 프로젝트 폴더로 나온 뒤 이제 React 프로젝트를 생성합니다.

npx create-react-app client

클라이언트 폴더로 진입 후 React에서도 필요한 패키지를 설치합니다.

npm i --save socket.io-client

이렇게 프로젝트 기본 구성을 마쳤습니다!

이제 본격적으로 서버를 만들어 볼까요🔥

서버 구성

NestJS에서 WebSocket을 관리하려면 Gateway를 사용해야 하고 이것을 이용하면 간단히 @WebSocketGateway() 데코레이터를 이용해 간단히 설정이 가능해집니다.

그럼 이제 ChatGateway를 생성해 볼까요!

nest generate gateway chat

이렇게 하면 자동으로 chat 폴더에 chat.gateway.ts, chat.gateway.spec.ts 파일들를 자동으로 생성해 줍니다.

그리고 아래와 같이 ChatGateway 클래스에 @WebSocketGateway() 데코레이터가 추가되고 handleMessage 기능을 통해 메시지를 구독할 수 있게 됩니다. 이렇게 되면 클라이언트로부터 데이터를 전달하는 동안 들어오는 메시지를 처리할 수 있게 됩니다.

import { SubscribeMessage, WebSocketGateway } from '@nestjs/websockets';

@WebSocketGateway()
export class ChatGateway {
@SubscribeMessage('message') // subscribe to message events
handleMessage(client: any, payload: any): string {
return 'Hello world!'; // return the text
}
}

handleMessage 기능은 2개의 파라미터가 있는데, client: 플랫폼 별 소켓 인스턴스, payload: 클라이언트로부터 수신된 데이터 이렇게 2개가 있습니다.

클라이언트 측에서 메시지를 보내려면 어떻게 해야 하나요? socket.io-client 패키지를 활용해 이것이 가능합니다. 또한 아래 두번째 줄과 같이 서버에서 보낸 결과 데이터를 다룰 수도 있습니다.

socket.emit('events', { name: 'Nest' });
socket.emit('events', { name: 'Nest' }, (data) => console.log(data));

단순히 서버에서 클라이언트로 데이터를 반환하는 예를 보았는데, 그것이 아닌 메시지를 subscribe 중인 모든 고객에게 메시지를 broadcast 해 보겠습니다.

import {
SubscribeMessage,
WebSocketGateway,
WebSocketServer,
MessageBody,
} from '@nestjs/websockets';
import { Logger } from '@nestjs/common';
import { Server, Socket } from 'socket.io';

import { AddMessageDto } from './dto/add-message.dto';

@WebSocketGateway({ cors: { origin: '*' } })
export class ChatGateway {
@WebSocketServer()
server: Server;

private logger = new Logger('ChatGateway');

@SubscribeMessage('chat') // subscribe to chat event messages
handleMessage(@MessageBody() payload: AddMessageDto): AddMessageDto {
this.logger.log(`Message received: ${payload.author} - ${payload.body}`);
this.server.emit('chat', payload); // broadbast a message to all clients
return payload; // return the same payload data
}
}

위와 같이 데코레이터 @WebSocketServer()를 이용해 broadcast를 실행합니다.(chat을 구독중인 모두에게)

그리고 NestJS에서 제공하는 2개의 수명주기를 사용해 편리하게 소켓 연결 시기를 알 수 있습니다.

@WebSocketGateway({ cors: { origin: '*' } })
export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
...
...

// it will be handled when a client connects to the server
handleConnection(socket: Socket) {
this.logger.log(`Socket connected: ${socket.id}`);
}

// it will be handled when a client disconnects from the server
handleDisconnect(socket: Socket) {
this.logger.log(`Socket disconnected: ${socket.id}`);
}
}

위와 같이 OnGatewayConnection, OnGatewayDisconnect 2개에서 제공하는 handleConnection, handleDisconnect를 활용해 연결 시와 연결 끊김 시의 기능을 구현할 수 있습니다. 그리고 원래는 신뢰할 수 있는 주소에만 적용해야 하지만 테스트 중이니 cors를 모두 통과하도록 안전하지 않은 구성을 진행했습니다.

그럼 서버는 이제 마무리 했고 웹을 구현해 볼 차례입니다.

웹 구성

클라이언트에서 서버와 실시간으로 메시지를 보내고 받는 방법을 구현하기 위해 chat.tsx 파일에 만들 예정입니다.

import { useState, useEffect } from "react";
import { io } from "socket.io-client";

const SystemMessage = {
id: 1,
body: "Welcome to the Nest Chat app",
author: "Bot",
};

// create a new socket instance with localhost URL
const socket = io('http://localhost:4000', { autoConnect: false });

export function Chat({ currentUser, onLogout }) {
const [inputValue, setInputValue] = useState("");
const [messages, setMessages] = useState([SystemMessage]);

useEffect(() => {
socket.connect(); // connect to socket

socket.on("connect", () => { // fire when we have connection
console.log("Socket connected");
});

socket.on("disconnect", () => { // fire when socked is disconnected
console.log("Socket disconnected");
});

// listen chat event messages
socket.on("chat", (newMessage) => {
console.log("New message added", newMessage);
setMessages((previousMessages) => [...previousMessages, newMessage]);
});

// remove all event listeners
return () => {
socket.off("connect");
socket.off("disconnect");
socket.off("chat");
};
}, []);

const handleSendMessage = (e) => {
if (e.key !== "Enter" || inputValue.trim().length === 0) return;

// send a message to the server
socket.emit("chat", { author: currentUser, body: inputValue.trim() });
setInputValue("");
};

const handleLogout = () => {
socket.disconnect(); // disconnect when we do logout
onLogout();
};

return (
<div className="chat">
<div className="chat-header">
<span>Nest Chat App</span>
<button className="button" onClick={handleLogout}>
Logout
</button>
</div>
<div className="chat-message-list">
{messages.map((message, idx) => (
<div
key={idx}
className={`chat-message ${
currentUser === message.author ? "outgoing" : ""
}`}
>
<div className="chat-message-wrapper">
<span className="chat-message-author">{message.author}</span>
<div className="chat-message-bubble">
<span className="chat-message-body">{message.body}</span>
</div>
</div>
</div>
))}
</div>
<div className="chat-composer">
<input
className="chat-composer-input"
placeholder="Type message here"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyDown={handleSendMessage}
/>
</div>
</div>
);
}

이제 웹 클라이언트를 모두 만들었으니 실제 화면을 공유해 봅니다.

NestJS - ReactJS의 데모 앱 시연

git

결론

모든 코드를 확인하려면 여기에서 확인하세요!

도움이 되었기를 바랍니다!

windows 폴더 내 모든 파일의 확장자 확인

· One min read

image

어느 날 갑자기 폴더 내의 모든 파일들에 대한 확장자 종류에 대해 조사하라는 미션이 생겼다.

윈도우 자체를 거의 사용하지 않고 개발하면서 처음 겪는 미션이라 당황스러웠는데 검색하기도 좀 애매한 상황...

간단한 해결책이 있었다.(MS Copilot의 도움!)

Powershell을 활용하면 간단했다.

$folderPath = "C:\\YourFolderPath" # 여기에 원하는 폴더 경로를 입력하세요.
$outputFile = "C:\\YourOutputFile.txt" # 여기에 결과를 저장할 파일의 경로를 입력하세요.

Get-ChildItem -Path $folderPath -Recurse | # 재귀적으로 모든 하위 폴더와 파일을 가져옵니다.
Where-Object {!$_.PSIsContainer} | # 폴더는 제외하고 파일만 선택합니다.
ForEach-Object { $_.Extension } | # 각 파일의 확장자를 가져옵니다.
# ForEach-Object { $_.Extension.ToLower() } | # 각 파일의 확장자를 소문자로 변환하여 가져옵니다.
# ForEach-Object { $_.Extension.ToLower().Trim() } | # 각 파일의 확장자를 소문자로 변환하고 공백을 제거하여 가져옵니다.
Sort-Object | # 확장자를 정렬합니다.
Get-Unique | # 중복된 확장자를 제거합니다.
Out-File $outputFile # 결과를 텍스트 파일로 출력합니다.
# 만약 파일 이름까지 필요하다면, ForEach-Object { $_.Extension } 부분을 ForEach-Object { $_.Name }로 변경하면 됩니다.

이 방법을 활용해 테스트 폴더에서 먼저 테스트 해봤고 중복을 잘 걸러내며 모든 Extension을 불러와 내 수고를 덜어줄 수 있었다.

하지만 상당히 nested 한 폴더 구조와 많은 파일들이 있다면 당연히 시간이 오래 걸린다.

간단한 미션이지만 폴더 내의 구조가 상당히 복잡하다면 눈과 손으로 하기보다 스크립트로 하는 것이 도움이 될 듯 합니다. 누군가에게 도움이 됐으면 좋겠다.

2024년 사용하면 좋은 13가지 쿠버네티스 도구(2)

· 6 min read

image

이전 2024년 사용하면 좋은 13가지 쿠버네티스 도구(1) 에서 다뤘던 쿠버네티스 추천 도구들에 이어서 작성합니다. 

8. Skaffold

Skaffold는 쿠버네티스 앱의 지속적인 개발을 촉진하는 명령줄 도구입니다. 앱 구축, 푸시 및 배포를 위한 워크플로우를 자동화하여 개발자가 코드를 더 쉽게 반복할 수 있도록 합니다.

Skaffold 는 개발 단계에 이상적이기 때문에 개발자가 배포 프로세스에 대해 걱정하지 않고 코드 작성에 집중할 수 있게 해주기 때문에 개발 중 빠른 피드백을 통해 발전하고 싶은 팀에 유용합니다.

개발 및 배포 프로세스를 자동화하고 단순화하여, 여러 빌드 도구 및 배포 전략을 지원해 기존 CI/CD 파이프라인과 잘 통합할 수 있습니다.

GitHub: https://github.com/GoogleContainerTools/skaffold

 [GitHub - GoogleContainerTools/skaffold: Easy and Repeatable Kubernetes Development

Easy and Repeatable Kubernetes Development. Contribute to GoogleContainerTools/skaffold development by creating an account on GitHub.

github.com](https://github.com/GoogleContainerTools/skaffold)

웹사이트: https://skaffold.dev/

 [Skaffold

Easy and Repeatable Container & Kubernetes Development

skaffold.dev](https://skaffold.dev/)

사용 코드 예:

apiVersion: skaffold/v2beta13
kind: Config
build:
artifacts:
- image: my-app
deploy:
kubectl:
manifests:
- k8s-*

문서: https://skaffold.dev/docs/

 [Skaffold 2.0 Documentation

Easy and Repeatable Container & Kubernetes Development

skaffold.dev](https://skaffold.dev/docs/)

대안으로는 Tilt 가 있습니다.

9. Kubevela

Kubevela 는 기본 인프라의 복잡성을 추상화하여 앱 배포 및 관리를 단순화하는 최신 앱 배포 시스템입니다.

클라우드 네이티브 앱을 배포하고 관리하기 위해 높은 수준의 자동화 및 추상화가 필요한 환경에 가장 적합합니다.

서비스의 복잡성에 관계없이 앱 제공에 대한 단순하고 일관된 접근 방식을 제공하기 때문에 운영자에게 필요한 유연성과 성능을 유지하면서 개발자가 접근할 수 있습니다.

GitHub: https://github.com/oam-dev/kubevela

 [GitHub - kubevela/kubevela: The Modern Application Platform.

The Modern Application Platform. Contribute to kubevela/kubevela development by creating an account on GitHub.

github.com](https://github.com/oam-dev/kubevela)

웹사이트: https://kubevela.io/

 [Make shipping applications more enjoyable. | KubeVela

Make shipping applications more enjoyable.

kubevela.io](https://kubevela.io/)

사용 코드 예:

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: example-app
spec:
components:
- name: example-component
type: webservice
properties:
image: nginx
port: 80

문서: https://kubevela.io/docs/

 [Introduction | KubeVela

What is KubeVela?

kubevela.io](https://kubevela.io/docs/)

대안으로 Helm 가 있습니다.

10. Crossplane

Crossplane 은 클러스터를 확장하여 여러 공급업체 및 소스의 인프라를 표준 쿠버네티스 리소스로 관리하고 구성하는 오픈 소스 쿠버네티스 추가 기능입니다.

Crossplane 은 쿠버네티스 환경 내에서 코드형 인프라(IaC) 방식을 채택하려는 팀에 특히 유용하고, 쿠버네티스 API를 통해 데이터베이스, 클러스터, 스토리지 계정과 같은 외부 리소소를 관리할 수 있습니다.

선언적 구성을 사용하여 클라우드 네이티브 앱과 의존하는 인프라의 배포 및 관리를 통합할 수 있습니다.

GitHub: https://github.com/crossplane/crossplane

 [GitHub - crossplane/crossplane: The Cloud Native Control Plane

The Cloud Native Control Plane. Contribute to crossplane/crossplane development by creating an account on GitHub.

github.com](https://github.com/crossplane/crossplane)

홈페이지: https://crossplane.io/

 [Crossplane - The cloud-native control plane framework

Crossplane is a framework for building cloud native control planes without needing to write code. It has a highly extensible backend that enables you to build a control plane that can orchestrate applications and infrastructure no matter where they run, an

www.crossplane.io](https://crossplane.io/)

사용 코드 예:

apiVersion: database.example.org/v1alpha1
kind: MySQLInstance
metadata:
name: my-db-instance
spec:
engineVersion: "5.7"
storageGB: 20

문서: https://crossplane.io/docs/

 [Crossplane ·

docs.crossplane.io](https://crossplane.io/docs/)

대안으로는 Terraform 입니다.

11. Kube-bench

Kube-bench 는 CIS Kubernetes 벤치마크에 문서화된 검사를 실행하여 쿠버네티스 배포가 안전한지 확인하도록 설계 된 오픈 소스 도구입니다.

Kube-bench를 활용해 쿠버네티스 클러스터의 보안 준수 여부를 감사하여 CIS(Center for Internet Security) 모범 사례에 따라 잠재적 취약점을 식별하고 해결합니다.

쿠버네티스 클러스터가 CIS 벤치마크를 준수하는지 확인하면 일반적인 보안 위협으로부터 보호하고 안전한 쿠버네티스 배포를 위한 업계 표준에 맞춰 작업을 조정할 수 있습니다.

GitHub: https://github.com/aquasecurity/kube-bench

 [GitHub - aquasecurity/kube-bench: Checks whether Kubernetes is deployed according to security best practices as defined in the C

Checks whether Kubernetes is deployed according to security best practices as defined in the CIS Kubernetes Benchmark - aquasecurity/kube-bench

github.com](https://github.com/aquasecurity/kube-bench)

웹사이트: 모든 리소스와 문서는 GitHub 저장소를 참조하세요.

사용 코드 예: kube-bench를 실행하려면 일반적으로 Kubernetes 클러스터의 컨테이너 내에서 실행합니다.

kubectl run --rm -i -t kube-bench --image=aquasec/kube-bench:latest --restart=Never -- benchmarks/run

문서: GitHub 저장소의 README와 다양한 Kubernetes 버전에 대한 다양한 마크다운 파일을 통해 직접 사용할 수 있습니다.

대안으로는 Kube-hunter 입니다.

12. Kubernetes External Secrets

Kubernetes External Secrets 을 사용하면 AWS Secrets Manager 또는 HashiCorp Vault와 같은 외부 비밀 관리 시스템을 사용하여 쿠버네티스에 Secret을 안전하게 추가할 수 있습니다.

이 도구는 쿠버네티스의 기본 secret 처리 매커니즘을 외부에서 관리하고 쿠버네티스 앱 내에서 사용하기 위한 보안 브리지가 필요한 경우 필수입니다.

쿠버네티스의 기본 secret을 제공하는 것 이상으로 secret 순환, 중앙 집중식 감사, 접근 제어와 같은 고급 기능을 제공하는 전용 비밀 관리 시스템을 사용해 보안을 강화할 수 있습니다.

GitHub: https://github.com/external-secrets/kubernetes-external-secrets

 [GitHub - external-secrets/kubernetes-external-secrets: Integrate external secret management systems with Kubernetes

Integrate external secret management systems with Kubernetes - external-secrets/kubernetes-external-secrets

github.com](https://github.com/external-secrets/kubernetes-external-secrets)

웹사이트: GitHub 저장소는 정보 및 문서의 주요 소스 역할을 합니다.

사용 코드 예:

apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: my-database-secret
spec:
backendType: secretsManager
data:
- key: /my/organization/secrets/database/password
name: password

문서: 설정 지침, 구성 및 사용 예를 포함하여 GitHub 저장소 내에서 문서를 찾을 수 있습니다.

대안으로는 Kubernetes 통합이 포함된 HashiCorp Vault 이 있습니다.

13. Octant

Octant 는 쿠버네티스 클러스터에 대한 깊은 분석을 제공하는 확장성이 뛰어난 오픈 소스 개발자 중심의 쿠버네티스용 웹 인터페이스입니다. 클러스터 내에서 관리되는 리소스에 대한 포괄적인 보기와 문제 해결을 더 쉽게 해주는 기능을 제공합니다.

쿠버네티스 클러스터의 시각적 표현을 찾고, 문제를 디버그하고, 클러스터 리소스를 검사하거나 리소스 간 관계를 이해해야 할 때 유용하게 사용할 수 있습니다. 실시간 업데이트, 확장된 기능을 위한 플러그인 에코시스템, 쿠버네티스 리소스를 탐색할 수 있는 사용자 친화적 인터페이스를 제공하여 관리 및 문제 해결을 용이하게 합니다.

GitHub: https://github.com/vmware-tanzu/octant

 [GitHub - vmware-archive/octant: Highly extensible platform for developers to better understand the complexity of Kubernetes clus

Highly extensible platform for developers to better understand the complexity of Kubernetes clusters. - vmware-archive/octant

github.com](https://github.com/vmware-tanzu/octant)

웹사이트: https://octant.dev/

 [Octant

Real-time updates With a complete view of an object and all its related objects, you can more accurately assess the status of applications and avoid unfocused debugging when things go wrong.

octant.dev](https://octant.dev/)

사용 코드 예: Octant는 GUI 기반 도구이므로 일반적인 사용법에는 로컬 시스템에서 애플리케이션을 시작한 다음 Kubernetes 클러스터에 연결하는 것이 포함됩니다.

octant

문서: https://octant.dev/docs/

 [Documentation

If you are new to Octant check out our Getting Started guide which can help you get Octant installed and running. For complete documentation, from installation to how to get started developing plugins for Octant, visit our Octant Reference website.

octant.dev](https://octant.dev/docs/)

대안으로 Kubernetes Dashboard 가 있습니다.

지금까지 2024년에 쿠버네티스에 사용하면 좋은 도구들에 대해서 알아 봤습니다. 워낙 많은 도구들이 있어 모두 다룰 수는 없지만 알아 본 도구들을 알아두면 큰 도움이 될 것으로 보입니다! 감사합니다! 😊

2024년 사용하면 좋은 13가지 쿠버네티스 도구(1)

· 7 min read

image

최근 쿠버네티스에 관심이 생기면서 여러 가지 테스트를 해 보고 있는데, 쿠버네티스를 사용할 때 이용하면 좋은 13가지 도구를 소개해 보려고 합니다. 

쿠버네티스는 컨테이너 오케스트레이션 플랫폼 중 선도적 역할을 하고 있고 생태계 또한 아주 빠르게 발전하고 있기 때문에 데브옵스 전문가라면 배워두면 좋아 보입니다.

구성한 쿠버네티스의 구조가 복잡해 지고 방대해 질수록 이를 간소화하여 처리하기 위해 여러 도구가 필요합니다.

1. Argo CD

Argo CD는 쿠버네티스에 사용이 적합한 CD 도구로서 앱 배포를 자동화하고 Git 저장소에 저장된 구성과 일치하는지 지속적으로 체크합니다.

빠른 반복과 일관된 배포 방식이 중요한 환경에 가장 적합한데 Argo CD는 변경 사항에 대한 추적을 통해 개발 환경부터 운영 환경까지 다중 배포 전략에도 유용하게 사용합니다.

Argo CD는 GitOps 의 방식을 채택해서 팀이 Git 을 배포를 위한 단일 정보 소스로 활용해 프로세스를 단순호하고 보안 및 추적성을 향상 시킨 장점이 있습니다.

GitHub: https://github.com/argoproj/argo-cd

 [GitHub - argoproj/argo-cd: Declarative Continuous Deployment for Kubernetes

Declarative Continuous Deployment for Kubernetes. Contribute to argoproj/argo-cd development by creating an account on GitHub.

github.com](https://github.com/argoproj/argo-cd)

웹사이트: https://argoproj.github.io/argo-cd/

 [https://argoproj.github.io/argo-cd/

argoproj.github.io](https://argoproj.github.io/argo-cd/)

사용 코드 예:

argocd app create <앱 이름> \
--repo <your_repo_url> \
--path <path_to_app_manifests> \
--dest-server https://kubernetes.default.svc \
--dest-namespace <네임스페이스>

문서: https://argo-cd.readthedocs.io/en/stable/

 [Argo CD - Declarative GitOps CD for Kubernetes

Overview What Is Argo CD? Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. Why Argo CD? Application definitions, configurations, and environments should be declarative and version controlled. Application deployment and lifecycle ma

argo-cd.readthedocs.io](https://argo-cd.readthedocs.io/en/stable/)

대안 도구로 Flux가 있습니다.

2. Helm

Helm은 쿠버네티스용 패키지 관리자입니다. 개발자와 운영자가 쿠버네티스 클러스터에 앱을 쉽게 패키징, 구성하고 배포할 수 있게 합니다.

Helm은 간단한 명령줄 인터페이스를 통해 쿠버네티스 앱을 정의, 설치, 업그레이드 할 수 있고 복잡한 앱을 관리하기 좋습니다.

Helm 차트는 앱을 배포, 관리하며 복잡한 종속성을 지원해 간편하게 업데이트, 롤백을 수행할 수 있게 합니다.

GitHub: https://github.com/helm/helm

 [GitHub - helm/helm: The Kubernetes Package Manager

The Kubernetes Package Manager. Contribute to helm/helm development by creating an account on GitHub.

github.com](https://github.com/helm/helm)

웹사이트: https://helm.sh/

 [Helm

Helm - The Kubernetes Package Manager.

helm.sh](https://helm.sh/)

사용 코드 예:

helm install my -app ./ my -chart

문서: https://helm.sh/docs/

 [Docs Home

Everything you need to know about how the documentation is organized.

helm.sh](https://helm.sh/docs/)

대안 도구로 Kustomize 가 있습니다.

3. Kustomize

Kustomize 는 쿠버네티스의 자체 구성 관리 기능을 향상시키는 쿠버네티스 기반의 구성 관리 도구입니다.

다양한 환경, 배포 시나리오 처럼 하나의 앱에 약간씩 다른 여러 구성을 유지해야 할 때 특히 유용한 편입니다.

템플릿 처리나 수동 편집 없이 쿠버네티스 리소스 구성을 직접 정의할 수 있어 다양한 환경에서 앱 구성을 더 쉽게 관리할 수 있습니다.

GitHub: https://github.com/kubernetes-sigs/kustomize

 [GitHub - kubernetes-sigs/kustomize: Customization of kubernetes YAML configurations

Customization of kubernetes YAML configurations. Contribute to kubernetes-sigs/kustomize development by creating an account on GitHub.

github.com](https://github.com/kubernetes-sigs/kustomize)

웹사이트: https://kustomize.io/

 [Kustomize - Kubernetes native configuration management

Overview Kustomize traverses a Kubernetes manifest to add, remove or update configuration options without forking. It is available both as a standalone binary and as a native feature of kubectl. Purely declarative approach to configuration customization Na

kustomize.io](https://kustomize.io/)

사용 코드 예:

# kustomization.yaml
resources:
- deployment.yaml
- service.yaml

문서: https://kubectl.docs.kubernetes.io/

 [SIG CLI

Documentation for Kubectl and Kustomize

kubectl.docs.kubernetes.io](https://kubectl.docs.kubernetes.io/)

대안으로는 Helm 이 있습니다.

4. Prometheus

Prometheus는 차원 데이터 모델, 유연한 쿼리 언어 및 경고 기능을 갖춘 오픈 소스 모니터링 시스템입니다.

안정성과 확장성을 고려해 설계되었기 때문에 쿠버네티스 환경에 이상적인 모니터링 솔루션이라고 생각합니다.

metric을 시계열 데이터로 수집하고 저장하여 쿠버네티스 클러스터의 성능과 앱 상태에 대해 면밀한 분석이 가능합니다.

강력한 데이터 모델과 쿼리 언어(PromQL)를 통해 쿠버네티스 클러스터에 대한 자세한 관찰 및 실시간 모니터링을 지원하므로 문제를 더 쉽게 식별하고 해결할 수 있습니다.

GitHub: https://github.com/prometheus/prometheus

 [GitHub - prometheus/prometheus: The Prometheus monitoring system and time series database.

The Prometheus monitoring system and time series database. - prometheus/prometheus

github.com](https://github.com/prometheus/prometheus)

웹사이트: https://prometheus.io/

 [Prometheus - Monitoring system & time series database

An open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.

prometheus.io](https://prometheus.io/)

사용 코드 예:

# Prometheus scrape configuration
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod

문서: https://prometheus.io/docs/introduction/overview/

 [Overview | Prometheus

An open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.

prometheus.io](https://prometheus.io/docs/introduction/overview/)

대안으로는 Grafana for visualization, Thanos for long-term storage enhancement 가 있습니다.

5. Istio

Istio는 마이크로서비스가 데이터를 공유하는 방법을 제어하는 방법을 제공하는 강력한 service mesh 도구입니다.

앱에 고급 트랙픽 관리, 보안 기능 및 관찰 기능을 제공합니다.

Istio는 트래픽, 보안 정책 및 서비스 모니터링을 세밀하게 제어해야 하는 복잡한 마이크로서비스 아키텍처에 특히 유용합니다.

코드를 변경할 필요 없이 서비스를 보다 효과적으로 보호, 연결 및 모니터링 할 수 있는 추가 인프라 계층을 제공합니다.

GitHub: https://github.com/istio/istio

 [GitHub - istio/istio: Connect, secure, control, and observe services.

Connect, secure, control, and observe services. Contribute to istio/istio development by creating an account on GitHub.

github.com](https://github.com/istio/istio)

홈페이지: https://istio.io/

 [Istio

A service mesh for observability, security in depth, and management that speeds deployment cycles.

istio.io](https://istio.io/)

사용 코드 예:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"

문서: https://istio.io/latest/docs/

 [Documentation

Learn how to deploy, use, and operate Istio.

istio.io](https://istio.io/latest/docs/)

대안으로는 Linkerd 가 있습니다.

6. Tekton

Tekton은 CI/CD 시스템을 생성하기 위한 강력하고 유연한 쿠버네티스 기반 오픈 소스 프레임워크로, 개발자는 이를 이용해 클라우드와 온프레미스 시스템 전반에 걸쳐 구축, 테스트 및 배포할 수 있습니다.

쿠버네티스 기반 CI/CD 파이프라인을 구성하는데 가장 잘 활용됩니다. 클라우드 네이티브 방식으로 다양한 환경에서 개발 워크플로우를 표준화하려는 팀이 있다면 이것을 사용하면 좋습니다.

기본 구현 세부 정보를 추상화하고 CI/CD 파이프라인을 구축하고 실행하기 위한 표준화된 쿠버네티스 기반 구성 세트를 제공하여 확장성과 이식성이 뛰어납니다.

GitHub: https://github.com/tektoncd/pipeline

 [GitHub - tektoncd/pipeline: A cloud-native Pipeline resource.

A cloud-native Pipeline resource. Contribute to tektoncd/pipeline development by creating an account on GitHub.

github.com](https://github.com/tektoncd/pipeline)

웹사이트: https://tekton.dev/

 [Tekton

Cloud Native CI/CD

tekton.dev](https://tekton.dev/)

사용 코드 예:

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: hello-world
spec:
steps:
- name: echo
image: ubuntu
command:
- echo
args:
- "Hello World"

문서: https://tekton.dev/docs/

 [Welcome to Tekton

Cloud Native CI/CD

tekton.dev](https://tekton.dev/docs/)

대안으로 Jenkins X 가 있습니다.

7. Flux

Flux는 쿠버네티스 클러스터 관리에 대한 GitOps의 접근 방식을 채택한 도구입니다. 클러스터 상태가 Git 저장소에 설명되고 자동으로 적용 및 업데이트 됩니다.

쿠버네티스 앱 및 인프라 관리를 위해 GitIOps 원칙을 채택하는 팀에 특히 유용하며 클러스터 상태가 항상 Git 저장소와 동기화 되도록 보장합니다.

배포 프로세스를 자동화하고 재현성, 추적성을 향상하며 쿠버네티스와 원활하게 통합되어 휴먼 오류의 위험을 줄입니다.

GitHub: https://github.com/fluxcd/flux

 [GitHub - fluxcd/flux: Successor: https://github.com/fluxcd/flux2

Successor: https://github.com/fluxcd/flux2. Contribute to fluxcd/flux development by creating an account on GitHub.

github.com](https://github.com/fluxcd/flux)

홈페이지: https://fluxcd.io/

 [Flux - the GitOps family of projects

Flux is a set of continuous and progressive delivery solutions for Kubernetes, and they are open and extensible. The APIs of Flux are stable now.

fluxcd.io](https://fluxcd.io/)

사용 코드 예:

apiVersion: helm.fluxcd.io/v1
kind: HelmRelease
metadata:
name: my-app
spec:
chart:
repository: https://charts.my-company.com/
name: my-app
version: 1.2.3

문서: https://fluxcd.io/docs/

 [Flux Documentation

Open and extensible continuous delivery solution for Kubernetes.

fluxcd.io](https://fluxcd.io/docs/)

대안으로는 Argo CD 입니다.

Solidity vs Rust For Web3 App

· 5 min read

image

오늘날의 기술 환경에서 블록체인 기술의 중요성은 점점 커져가고 있습니다. 인기와 실용성이 높아지면서 어떤 기술과 프로그래밍 언어가 블록체인 개발에 가치가 있을지 알아보겠습니다.

다행히도 블록체인 개발에서는 C++, JavaScript, Solidity, Rust, Assembly Script 등과 같은 친숙한 코딩 언어를 활용합니다. 프로그래밍 가능한 블록체인의 필수 구성 요소인 스마트 계약에 맞춰진 최신 언어는 기본적인 코딩 지식이 있으면 비교적 쉽게 이해할 수 있습니다.

그러나 특정 언어를 살펴보기 전에 계획한 애플리케이션에 어떤 언어가 적합한지 조사하고 파악하는 것이 좋습니다. 프로그래밍 가능한 블록체인의 기본 요소인 스마트 계약을 작성할 때 두 가지 인기 있는 옵션인 Solidity와 Rust가 눈에 띕니다. 두 언어 모두 고유한 응용 프로그램을 갖고 있으며 플랫폼의 계획된 서비스에 따라 둘 중 하나를 선택할 수 있습니다.

우리는 Solidity와 Rust의 차이점을 살펴보고 독립형 레이어 1 분산 네트워크인 Vara Network가 Rust를 채택하여 실용적인 선택을 한 이유를 이해할 것입니다.

Solidity는 복잡한 기능보다는 데이터와 객체에 초점을 맞춘 객체지향 고급 언어입니다. 정적으로 입력되므로 컴파일 중에 오류를 포착할 수 있어 안정성이 더욱 높아집니다. 이더리움 블록체인의 스마트 계약을 위한 프로그래밍 언어로 만들어졌습니다.

Solidity는 Ethereum에만 국한되지 않습니다. Polygon, Avalanche, Polkadot, Optimism 및 Arbitrum과 같은 네트워크는 그 기능을 동등하게 수용합니다. 다양한 Polkadot 파라체인이 EVM을 통합했지만 모두가 이 기능을 채택한 것은 아닙니다. Solidity 설계를 통해 EVM 실행기를 사용하여 여러 장치에 이식할 수 있어 원활한 실행이 가능합니다.

Ethereum 호환성을 염두에 두고 Solidity를 스마트 계약 개발을 위한 인기 있는 선택으로 만드는 요인을 고려해 보겠습니다.

  1. **내장된 조건부
    **Solidity를 사용하면 특정 조건에 따라 작업을 쉽게 수행할 수 있습니다. 개발자는 복잡한 조건문을 별도로 작성할 필요가 없습니다. 대신 소스 코드에서 바로 해당 조건을 지정할 수 있습니다. 모든 요구 사항이 체크아웃되면 코드가 자동으로 작업을 실행합니다.
  2. **간편한 데이터 유형
    **Solidity는 정수, 문자열, 부동 소수점 숫자, 배열과 같은 일반적인 데이터 유형을 기본적으로 지원합니다. 또한 개발자는 스마트 계약에 대한 사용자 정의 데이터 유형을 생성할 수도 있습니다.
  3. **개발 중 안전
    **컴파일러는 개발자 코드를 작성할 때 오류가 있는지 확인하고 잠재적인 문제에 대해 알려줍니다. 이 기능은 특히 크고 복잡한 dApp을 처리할 때 유용합니다.

그러나 Solidity에는 단점도 있습니다. 고급 언어이기 때문에 다른 언어만큼 빠르지는 않습니다. 제한된 속도로 인해 까다로운 스마트 계약이나 수많은 거래를 처리할 때 문제가 발생할 수 있습니다. DAO 해킹을 기억하시나요 ? 이는 Solidity의 설계 결함이 어떻게 보안 문제를 일으키고 심지어 금전적 손실까지 초래할 수 있는지를 보여주는 완벽한 예입니다.

Rust

Rust는 2015년 출시 이후 개발자들 사이에서 상당한 관심을 받았습니다. Stack Overflow에서 가장 사랑받거나 존경받는 언어로 꾸준히(현재 8년) 등장하고 있습니다.

그렇다면 개발자(일반적으로)가 프로그래밍 언어를 좋아하는 이유는 무엇일까요? 글쎄, Rust는 보안을 손상시키지 않고 잠재적인 취약점으로부터 효과적으로 보호하면서 앱을 설계하기 위한 고성능 도구를 제공하는 과제를 성공적으로 해결합니다. Rust는 강력한 유형 시스템과 엄격한 메모리 안전성을 자랑합니다. 언어는 다음을 보장합니다.

성능 — Rust는 빠르고 메모리 효율적인 기능으로 유명합니다. 가비지 수집기가 없는 Rust는 성능이 중요한 서비스를 구동하고 임베디드 장치에서 실행하며 다른 언어와 원활하게 통합하는 데 적합합니다.

신뢰성 — Rust의 풍부한 유형 시스템과 소유권 모델은 메모리 안전성과 스레드 안전성을 보장하여 개발자가 컴파일 타임에 많은 버그를 제거할 수 있도록 하여 코드의 전반적인 신뢰성을 향상시킵니다.

생산성 — Rust는 뛰어난 문서, 유용한 오류 메시지가 포함된 친숙한 컴파일러 및 최고 수준의 도구를 제공합니다. 통합 패키지 관리자 및 빌드 도구, 자동 완성 및 유형 검사 기능을 갖춘 스마트 다중 편집기 지원, 자동 포맷터는 원활하고 효율적인 개발 환경에 기여합니다.

블록체인 개발을 위해 Rust로 전환해 보겠습니다.

개발자가 블록체인 애플리케이션에 대해 원하는 것은 무엇입니까? 안전성, 속도, 간편한 멀티 플랫폼 개발. Rust는 강력한 품질을 통해 블록체인 애플리케이션을 구축할 때 다음 특성을 보장합니다.

image

위 표에 설명된 대로(그리고 모든 언어와 마찬가지로) Rust에는 몇 가지 단점이 있습니다. 그러나 그 강점은 블록체인 개발의 약점보다 훨씬 큽니다. 또한 커뮤니티 지원과 Rust가 결함과 과제를 처리하는 방법은 적극적인 참여와 참여로 인해 프로그래밍 언어를 매력적으로 만듭니다. 비동기 프로그래밍 요청 및 구현은 Rust의 참여 커뮤니티를 강조합니다.

따라서 Rust는 안전하고 강력한 블록체인 애플리케이션을 구축하기 위한 탁월한 선택입니다. 고성능 및 낮은 수준의 제어를 통해 개발자는 코드를 최적화할 수 있습니다.

Rust와 Solidity 비교

Solidity와 Rust의 유사점을 이해하는 것은 매우 중요하며, 이 두 프로그래밍 언어가 특정 특성을 어떻게 공유하는지 보는 것은 매우 흥미롭습니다. 이들을 하나로 묶는 것이 무엇인지 자세히 살펴보겠습니다.

두 언어 모두 Turing Complete이므로 복잡함에도 불구하고 복잡한 계산 문제를 효과적으로 처리할 수 있습니다.

멀티체인 호환성을 통해 이러한 언어는 다양한 블록체인 네트워크에서 상호 운용성을 촉진합니다. Solidity는 레이어 2 및 모듈형 블록체인, 사이드체인 및 EVM 호환 레이어 1 블록체인을 포함하도록 지원을 확장했습니다. 마찬가지로 Rust는 Solana 및 Near와 같은 다양한 블록체인 네트워크로 지원을 확장하고 Substrate 프레임워크 기반 구현을 제공합니다.

공유된 유사성에도 불구하고 Rust와 Solidity는 아래 표에 강조된 것처럼 다양한 애플리케이션에서 다릅니다.

image

Rust의 놀라운 점 중 하나는 놀라울 정도로 효율적이고 플랫폼 독립적인 어셈블리인 Wasm(WebAssembly)으로 쉽게 컴파일된다는 것입니다. Vara Network는 현재 Rust 라이브러리 지원에 중점을 두고 있습니다. 그러나 Wasm의 뛰어난 효율성과 플랫폼 독립성은 다양한 블록체인 플랫폼의 런타임 및 스마트 계약 애플리케이션에서 탁월한 위치를 차지했습니다. Wasm은 이러한 목적을 위한 강력한 선택임이 입증되었지만 이것이 유일한 옵션은 아닙니다.

특정 애플리케이션에서는 다른 언어와 플랫폼이 더 적합하다고 판단하여 Wasm과 Solidity 간의 흥미로운 비교를 촉발할 수 있습니다. Wasm과 Solidity는 모두 블록체인 개발에서 강력한 도구입니다.

Rust를 선택한 이유

DeFi 애플리케이션이 과중한 작업 부하를 효율적으로 처리할 수 있도록 지원하는 탁월한 성능 때문에 Rust를 기본 언어로 선택했습니다. 우리가 혁신과 성능에 중점을 두는 만큼, 보안은 우리가 하는 모든 일의 핵심입니다. Rust의 메모리 안전 기능은 잠재적인 취약점의 위험을 크게 줄여 사용자에게 보안 및 신뢰성에 대한 확신을 심어줍니다.

게다가 Rust 프로그램을 작성하면 Wasm 바이트코드로 컴파일됩니다. 그리고 무엇을 추측합니까? 네트워크는 실행 프로그램이 아닌 Wasm 표준을 사용합니다.

image

Solidity는 확립된 커뮤니티 및 기존 코드베이스와 같은 자체 장점을 부인할 수 없이 자랑하지만 실용적인 접근 방식으로 Rust를 수용했습니다. 성능과 보안을 우선시하여 강력하고 안전한 DeFi 솔루션을 제공할 수 있습니다.