230711-EKS

soo·2023년 7월 11일
0

AWS

목록 보기
5/9

통상적인 K8S 구조: 3개 이상의 Master Node(Control Node) 생성 -> Master Node가 저장된 서버가 망가지면 전체 서비스가 중단되기 때문에 다수의 Master Node를 클러스터 구조로 연결해서 서비스를 제공.

On-Premise OCP 구성 순서: 개발/검증 OCP 환경에서 Test 후 실제 구축

Hybird Cloud 구조 사용 이유: Front 부분은 Flexible해야하므로 Cloud 환경을 사용함.

K8S: Container Orchestration Tool. 대량의 컨테이너를 자동 배포하는 도구.


K8S 실습 환경 준비

  1. 가상 머신 생성(CPU: core 2, RAM: 2GiB, OS: ubuntu 20.0)
  1. ubuntu 설치

  2. 화면 조정 - 1280 & 800.

  3. ubuntu setting에서 IPv4 설정 + 전원 사용안함 설정.
    IP : 10.100.0.105, 서브넷마스크 : 255.255.255.0(24), 게이트웨이 : 10.100.0.1 , DNS : 10.100.0.1

  1. terminal에서 sudo passwd root 명령어로 root 계정의 암호 설정. (sudo su - 명령어로 root 계정 접속 후에 암호 변경이 가능함)

  2. ping 8.8.8.8로 인터넷 연결 확인

  3. sudo apt-get update

  4. sudo apt-get install -y openssh-server curl vim tree 명령어로 ssh 다운로드 + sudo systemctl start sshd

  5. xShell 에서 원격 터미널 접속. (호스트: 127.0.0.1 -> 포트번호 : 105로 설정.)

  6. /etc/hostname 파일 내용 변경

Master

  1. /etc/hosts 파일 내용 변경. IP, 이름 추가

  2. docker 설치

  1. 스냅샷 생성
sudo rm /etc/containerd/config.toml
sudo systemctl restart containerd

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml

worknode 생성

  1. Master Node를 Stop 후 복제본 생성 -> work node로 만듦
    옵션: 복제 설정 -> 완전 복제

  2. work1의 /etc/hosts 파일과 /etc/hostname 파일 내용 수정

swapon && cat /etc/fstab
swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab
setenforce 0
ufw disable
systemctl stop firewalld
systemctl disable firewalld
modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF 
sudo sysctl --system
sysctl net.bridge.bridge-nf-call-iptables
sysctl net.bridge.bridge-nf-call-ip6tables
apt install selinux-utils
setenforce 0
cat /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
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
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo vim /etc/apt/sources.list.d/kubernetes.list
cat /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl kubernetes-cni
sudo apt-mark hold kubelet kubeadm kubectl
sudo mkdir /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF
sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker

현재 실행중인 pod를 -o yaml 옵션으로 yaml파일 저장이 가능함


K8S 주요 명령어

cordon: 장애 발생시 스케쥴링을 중지하는 명령어

uncordon: 스케줄링 재시작

drain: 노드의 pod들을 옮기는 명령어 -> 부하 문제가 발생하지 않음

kubectl get pod -n kube-system
의미 : kube-system 의 pod 조회

kubectl get nodes
의미 : node 상태확인

kubectl get nodes -o wide
의미 : node 에 대한 자세한 정보

kubectl get pod --all-namespaces
의미 : 모든 네임스페이스 pod 리스트

kubectl get pods -n green (특정한 네임스페이스에서 정보를 볼떼)
의미 : green 이란 이름의 pods 조회

watch kubectl get pods -o wide
으미 : 2초 간격으로 상태 모니터링 하겠다.

kubectl get pods -n green -o wide (상세정보볼때)
의미 : green 이란 이름의 pods 상세조회

kubectl apply -f obj.yaml
의미 : obj.yaml 파일로 pod,deployment,service 등 생성하겠다.

kubectl delete -f obj.yaml
의미 : obj.yaml 파일로 만들어진 pod,deployment,service 삭제

kubectl create deployment demo-deployment --image=nginx:1.14
의미 : demo-deployment 란 deployment 를 배포하고 컨테이너 이미지는 nginx:1.14 를 사용

kubectl create deployment demo-deployment --image=nginx:1.14 --replicas=5
의미 : demo-deployment 란 deployment 를 배포하고 컨테이너 이미지는 nginx:1.14 를 사용하고 5개의 레플리카를 사용

kubectl scale deployment demo-deployment --replicas=10
의미 : demo-deployment 의 레플리카 개수를 10개로 변경

kubectl get deployment
의미 : 배포 목록 확인

kubectl get deployment.apps demo-deployment -o yaml
의미 : demo-deployment 의 .yaml 파일을 확인

kubectl get deployment.apps demo-deployment -o yaml > demo-deployment.yaml
의미 : demo-deployment 의 .yaml 파일을 demo-deployment.yaml로 저장

cat(vi) demo-deployment.yaml
의미: demo-deployment.yaml를 본다

kubectl delete deployments.apps demo-deployment
의미: demo-deployment 를 지운다

kubectl get po
의미 : get pods 과 같은 의미(현재 네임스페이스의 pods 리스트 )

kubectl get rs
의미 : get replicaset 과같은 의미(현재 네임스페이스의 replicaset 리스트)

kubectl get deploy
의미 : kubectl get deployment 와 같은 의미(배포 목록 확인)

watch kubectl get po -o wide
의미 : pod 의 상세정보를 실시간 확인

kubectl delete pod pod-exam
의미 : pod-exam pod 삭제

kubectl delete rs demo-deployment-6d8dbd56d7
의미 : demo-deployment-6d8dbd56d7 replicaset 삭제

kubectl delete deploy demo-deployment
의미 : demo-deployment deployment 삭제

========================================================3/28
kubectl cordon node3.example.com
의미 : node3.example.com 노드의 포드들이 더이상 스케쥴링 실행 x

kubectl drain node2.example.com
의미 : node2.example.com 노드의 포드들을 다른곳으로 이동

kubectl get nodes
의미 : node 상태확인

kubectl uncordon node3.example.com
의미 : node3.example.com 노드의 포드들이 정상적으로 스케쥴링

kubectl drain node2.example.com --ignore-daemonsets
의미 : node2.example.com 노드의 데몬셋을 이용한 포드들을 제외한 다른포드들이 다른곳으로 이동

kubectl delete nodes node3.example.com
의미 : node3.example.com 노드 제거

kubeadm token list
의미: token 값 조회

kubeadm token create
의미 : token 생성

worker node 에서 설정

kubeadm reset
의미 : kubeadm 초기화

kubeadm join --token 4gun4p.v..b 10.100.0.104:6443 --discovery-token-unsafe-skip-ca-verification
의미 : token 을 워커노드에 join

docker build -t hub.example.com/nginx .
의미 : hub.example.com/nginx 테그를 이용해 도커 생성

docker push hub.example.com/nginx
의미 : hub.example.com/nginx 이미지

kubectl create deployment nginx --image=nginx1.14
의미 : nginx 란 deployment 를 배포하고 컨테이너 이미지는 nginx:1.14 를 사용

kubectl expose deploy nginx --type=ClusterIP --port 80
의미 : nginx 란 deployment 를 80포트로 외부 노출

docker version
의미 : docker 버전확인

watch kubectl get pods -o wide
의미 : pods 의 상세정보를 실시간 확인

kubectl drain nodeX.example.com --dry-run=client
의미 : nodeX.example.com 노드의 포드들을 다른곳으로 이동할 정보를 미리보기

kubectl drain nodeX.example.com --ignore-daemonsets
의미 : nodeX.example.com 노드의 데몬셋을 이용한 포드들을 제외한 다른포드들이 다른곳으로 이동

kubectl drain nodeX.example.com --force
의미 : nodeX.example.com 노드의 포드들을 다른곳으로 이동할떄 중요한역할을 하는 포드의 경우 삭제되지 않아서 drain 이 진행되지않기때문에 --force 옵션을 주면 강제로 삭제

kubectl uncordon nodeX.example.com
의미 : nodeX.example.com 노드의 포드들이 정상적으로 스케쥴링

kubectl drain nodeX.example.com --ignore-daemonsets
의미 : nodeX.example.com 노드의 데몬셋을 이용한 포드들을 제외한 다른포드들이 다른곳으로 이동

kubectl delete node nodeX.example.com
의미 : nodeX.example.com 노드 제거

kubectl logs multipod -c nginx-container
의미 : 멀티pod 내의 컨테이너 로그 출력

kubectl get pods --show-labels
의미 : pods 의 레이블 정보 확인

kubectl get pod -L <label_type>
의미 : pods 의 레이블 타입 확인

kubectl get pod
의미 : 현재 네임스페이스의 pods 조회

kubectl get pod --show-labels
의미 : pod 의 레이블 정보 확인

kubectl label pod redis-pod app=db
의미 : redis-pod 에 app=db 라는 레이블 부여

kubectl label pod nginx-pod app=web-services type=frontend
의미 : nginx-pod 에 app=web-services 라는 레이블 부여 타입은 frontend

kubectl label po label-pod app=web-services --overwrite
의미 : label-pod 에 app=web-services 라는 레이블 로 변경

kubectl get pod --show-labels
의미 : pod 의 레이블 조회

kubectl get pod -L app,type
의미 : pod 의 레이블의 app,type 정보 조회

kubectl get nodes --show-labels
의미 : nodes 의 레이블 정보 확인

kubectl get nodes -L beta.kubernetes.io/arch
의미 : 레이블이 beta.kubernetes.io/arch 라는 nods 조회

kubectl delete pod nodeselector-pod
의미 : nodeselector-pod 삭제

kubectl label node node2.example.com ssd-
의미 : node2.example.com 노드에 디스크가 ssd 인 레이블 추가

kubectl create -f pod-nodeselector.yaml
의미 : pod-nodeselector.yaml 파일 생성

kubectl label node node1.example.com ssd=true
의미 : node1.example.com 노드에 디스크가 ssd 인 레이블 추가

kubectl get pods nodeselector-pod -o wide
의미 : nodeselector-pod 란 pod 의 상세정보 확인

kubectl describe pod nginx-pod
의미 : nginx-pod 의 full 정보 확인

kubectl delete pod testpod
의미 : testpod 삭제

kubectl delete pod -l release=canary
의미 : release=canary란 레이블을 가진 pod 삭제

kubectl create -f pod-liveness.yaml
의미 : pod-liveness.yaml 생성

kubectl describe pod liveness-pod
의미 : liveness-pod 의 full 정보 확인

kubectl get pod testpod
의미 : testpod 조회

kubectl get pod testpod -o yaml
의미 : testpod 의 yaml 상세정보 확인

kubectl get pod testpod -o json
의미 : testpod 의 json 상세정보 확인

kubectl logs testpod
의미 : testpod의 로그 확인

kubectl logs testpod -c appjs-container
의미 : testpod 의 appjs-container 로그 확인

kubectl port-forward testpod 8888:8080
의미 : testpod 888:8080 으로 포트 포워딩

curl localhost:8888
의미: localhost:8888 연결 확인

kubectl label pod testpod2 env=debug --overwrite
의미 : testpod2 에 env=debug 라는 레이블 로 변경

kubectl get po -L app,env
의미 : pod 의 레이블의 app,type 정보 조회

kubectl get po -l app=hpe
의미 : 레이블이 app=hpe 인 pod 조회

kubectl get po -l '!env'
의미 : 레이블이 '!env' 인 pod 조회

kubectl delete pod test-gpu
의미 : test-gpu 삭제

kubectl delete po -l app=hpe
의미 :레이블이 app=hpe 인 pod 삭제

kubectl delete po --all
의미 : 모든 포드 삭제

kubectl get rc
의미 : replication controller 정보 조회

kubectl get pods
의미 : pods 조회

kubectl get pods -o wide
의미 : pods 의 상세정보 조회

kubectl delete pod nginx-rc-jm99k
의미 : nginx-rc-jm99k pod 삭제

kubectl delete replictioncontroller nginx-rc
의미 : replictioncontroller nginx-rc 삭제

kubectl edit replicationcontroller nginx-rc
의미 : replicationcontroller nginx-rc 수정

kubectl create -f rs-nginx.yaml
의미 : rs-nginx.yaml 파일 생성

kubectl get rs
의미 : replicaset 조회

kubectl get pods
의미 : pods 조회

kubectl describe pod rs-nginx-XXXX
의미 : rs-nginx-XXXX full 정보 확인

kubectl get all
의미 : 모든 pod,service,deployment,replicaset 조회

kubectl scale deployment nginx-deploy --replicas=2
의미 : nginx-deploy의 replicas 를 2로 변경

kubectl delete deployments.apps nginx-deploy
의미 : nginx-deploy 삭제

kubectl get daemonsets.apps -n kube-system
의미 : default 로 존재하는 데몬셋 확인

kubectl get pods -n kube-system -o wide | grep -e proxy -e weave
의미 : kube-system 네임스페이스에 속하고 proxy 왕 weave 가 들어간 상세정보 조회

kubectl get pod -o wide
의미 : pod 의 상세정보 조회

kubectl get daemonsets.apps
의미 : 데몬셋 정보 조회

kubectl edit daemonsets.apps fluentd
의미 : 데몬셋을 fluentd(로그수집기)로 업데이트

kubectl rollout history daemonset
의미 : daemonset 변경내역 확인

kubectl rollout undo daemonset fluentd
의미 : 바로 직전버전으로 롤백

kubectl rollout status daemonset fluentd
의미 : daemonset fluentd 의 rollout status 확인

kubectl describe pod fluentd-
의미 : fluentd- 상세정보 확인

kubectl delete daemonsets.apps fluentd
의미 : daemonsets.apps fluentd 삭제

kubectl apply -f job-centos.yaml
의미 : job-centos.yaml 수행

kubectl get pods --watch
의미 : pods 실시간 확인

kubectl get events
의미 : events 확인

kubectl create deployment my-first-deploy --image=nginx:1.14
의미 : my-first-deploy 란 deployment 를 배포하고 컨테이너 이미지는 nginx:1.14 를 사용

kubectl scale deployment my-first-deploy --replicas=2
의미 : my-first-deploy 의 replicas 를 2로 변경

kubectl get pods
의미 : pods 확인

kubectl get pods -o wide
의미 : pods의 상세확인

kubectl describe replicaset my-first-deploy-zzz
의미 : replicaset my-first-deploy-zzz의 full 정보 확인

kubectl get deployment
의미 : 배포목록 확인

kubectl expose deployment my-first-deploy --port=80 --type=NodePort
의미 : my-first-deploy 란 deployment 를 80포트로 외부 노출 타입은 nodeport

kubectl get svc
의미 : 서비스 확인

kubectl describe svc my-first-deploy
의미 : my-first-deploy란 서비스의 full 정보 확인

kubectl delete deployment my-first-deploy
의미 : my-first-deploy 삭제

kubectl delete svc my-first-deploy
의미 : my-first-deploy 삭제

kubectl create -f replicationcontroller-definition.yaml
의미 : replicationcontroller-definition.yaml 파일 생성

watch kubectl get pods
의미 : pods 목록 실시간 확인

kubectl get rc
의미 : replication controller 정보 조회

kubectl describe rc myapp
의미 : myapp란 replication controller 의 full 정보 확인

kubectl get pod --show-labels
의미 : pod의 label 정보 조회

kubectl label pod myapp-rc-XXX app=nginx --overwrite
의미 : myapp-rc-XXX pod 에 app=nginx 라는 레이블로 변경

kubectl get pods --show-labels
의미 : pod의 label 정보 조회

kubectl get pod -L app,type
의미 : pod 의 레이블의 app,type 정보 조회

kubectl scale rc myapp-rc --replicas=5
의미 : myapp-rc 라는 replication controller 의 replicas를 5로 변경

kubectl edit rc myapp-rc
의미 : myapp-rc 수정

kubectl scale rc myapp-rc --replicas=3
의미 : myapp-rc 라는 replication controller 의 replicas를 3으로 변경

kubectl get pods -L app
의미 : pod 의 레이블의 app 정보 조회

kubectl describe pod myapp-rc-xxx
의미 : myapp-rc-xxx 의 full 정보 확인

kubectl get rs
의미 : replicaset 조회

kubectl get pods -L app,type
의미 : pods 의 레이블의 app,type 정보 조회

kubectl delete rs myapp-rs
의미 : myapp-rs 라는 replicaset 삭제

kubectl delete pod --all
의미 : 모든 포드 삭제

kubectl label nodes node1.example.com ssd=true
의미 : node1.example.com 노드에 디스크가 ssd 인 레이블 추가

kubectl label nodes node3.example.com ssd=true
의미 : node3.example.com 노드에 디스크가 ssd 인 레이블 추가

kubectl get nodes --selector ssd=true
의미 : ssd=true 인 nodes 확인

kubectl get node --show-labels
의미 : node의 레이블 확인

kubectl get nodes -L ssd
의미 : ssd 라는 레이블의 nodes 확인

kubectl label nodes node1.example.com ssd
의미 : ssd 라는 레이블을 node1.example.com node 에 추가

kubectl get pods -o wide
의미 : pods 의 상세정보 확인

kubectl get pod -o wide
의미 : pods 의 상세정보 확인

kubectl get svc
의미 : service 정보 확인

iptables -t nat -S | grep 80
의미 : nat 테이블 중 80이들어간 목록 확인

kubectl get pod --show-labels -o wide
의미 : pod의 레이블 상세정보 확인

kubectl get svc
의미 : service 정보 확인

kubectl describe svc appjs-service
의미 : appjs-service 라는 service 의 full 정보 확인

kubectl get endpoints
의미 : endpoints 정보 확인

kubectl describe svc my-service
의미 : my-service 라는 service 의 full 정보 확인

cp svc-appjs.yaml svc-node.yaml
의미 : svc-appjs.yaml 라는 파일을 svc-node.yaml이름으로 현위치에 복사

cat svc-node.yaml
의미 : svc-node.yaml 확인

systemctl start nginx && systemctl enable nginx
의미 : nginx(웹서버) 실행 / nginx(웹서버) 자동 시작 등록

systemctl status nginx
의미 : nginx 상태 확인

firewall-cmd --add-service=http
의미 : http service 추가

firewall-cmd --add-service=http --permanent
의미 : http service 추가 [시스템 재부팅 이나 방화벽 재시작후에도 적용되도록 설정]

setsebool -P httpd_can_network_connect 1
의미 : httpd 프로세스에서 네트워크 연결 허용

systemctl restart nginx
의미 : nginx 재시작

kubectl get pod -n kube-system -l k8s-app=kube-dns
의미 : kube-system 의 pod 중 레이블이 k8s-app=kube-dns 인 pod 확인

kubectl get service
의미 : service 확인

kubectl exec -it centos-pod -- /bin/bash
의미 : centos-pod 에 접속

kubectl expose deploy ev237 --port 80
의미 : ev237 란 deployment 를 80포트로 외부 노출

kubectl get service
의미 : service 확인

kubectl get endpoints
의미 : endpoints 확인

kubectl edit service ev237
의미 : ev237 란 service 를 수정

cp rs-appjs.yaml readiness-appjs.yaml
의미 : rs-appjs.yaml 라는 파일을 readiness-appjs.yaml 이름으로 현위치에 복사

vim readiness-appjs.yaml
의미 : readiness-appjs.yaml 조회

kubectl get namespaces
의미 : namespaces 확인

kubectl delete pod nginx-pod-request
의미 : nginx-pod-request pod 삭제

vim nginx-pod-request.yaml
의미 : nginx-pod-request.yaml 조회

kubectl create -f nginx-pod-request.yaml
의미 : nginx-pod-request.yaml 파일 생성

kubectl get pods
의미 : pod 확인

kubectl get ns

의미 : namespaces 확인

kubectl get pod --namespace kube-system
의미 : kube-system 라는 namespace 의 pod 확인

kubectl create namespace custom-namespace
의미 : custom-namespace 라는 namespaces 생성

kubectl create -f testpod.yaml -n custom-namespace
의미 : testpod.yaml 파일과 namespace custom-namespace 를 생성

kubectl get namespaces
의미 : namespaces 확인

kubectl delete namespace custom
의미 : custom 이란 namespace 삭제

kubectl get pod -o wide --watch
의미 : pod 상세정보를 실시간 확인

kubectl delete deployments.apps stressful
의미 : deployments.apps stressful 제거

kubectl get pod -n ingress-nginx
의미 : ingress-nginx pod 확인

kubectl exec -n ingress-nginx ingress-nginx-controller-69fb496d7d-hrmrb -- /nginx-ingress-controller --version
의미 : ingress-nginx ingress-nginx-controller-69fb496d7d-hrmrb 를 실행시키고 nginx-ingress-controller의 버전 확인

kubectl get svc -n ingress-nginx
의미 : ingress-nginx 란 이름의 service 확인

kubectl config current-context
의미 : 현재 context 확인

kubectl config set-context ingress-nginx --namespace=ingress-nginx --cluster=kubernetes --user=kubernetes-admin
의미 : ingress-nginx 란 context 를 생성하고 namespace 는 ingress-nginx cluster는 kubernetes user는 kubernetes-admin 으로 세팅한다

kubectl config view
의미 : kubeconfig 확인

kubectl config use-context ingress-nginx
의미 : ingress-nginx context 를 사용한다

kubectl config current-context
의미 : 현재 context 확인

dynamic-web Pod 내의 web-server 컨테이너의 마운트 디렉토리를 사용해보자.
touch 명령으로 파일을 생성할 수 있는가?

kubectl exec dynamic-web -c web-server -- ls /usr/share/nginx/html
의미 : dynamic-web파드에 접속하여 [container은 web-server] /usr/share/nginx/html 경로에있는 파일 목록을 보여준다

kubectl exec dynamic-web -c web-server -- touch /usr/share/nginx/html/test.html
의미 : dynamic-web파드에 접속하여 [container은 web-server] /usr/share/nginx/html 경로에 test.html 파일을 생성한다

kubectl get pods -o wide -n kube-system
의미 : kube-system란 namespace를 가지고있는 pods의 상세정보

kubectl exec -n kube-system -it fluentd-elasticsearch-2dqfp -- bash
의미 : fluentd-elasticsearch-2dqfp 포드에 접근

ls /var/log
의미 : ls /var/log 경로의 파일 목록 확인

ls /var/lib/docker/containers
의미 : ls /var/lib/docker/containers 경로의 파일 목록 확인

exit
의미 : 나가기

kubectl create -f pv1.yaml -f pv2.yaml -f pv3.yaml -f pv4.yaml
의미 : pv1.yaml , pv2.yaml , pv3.yaml , pv4.yaml 파일 생성

kubectl get pv
의미 : Persistent Volume 확인

kubectl create -f pvc.yaml
의미 : pvc.yaml 파일 생성

kubectl get pvc
의미 : Persistent Volume Claim 확인

kubectl create -f pod-mongodb.yaml
의미 : pod-mongodb.yaml 파일 생성

kubectl exec -it mongodb-pod -- mongo
의미 : mongodb-pod pod 에 접근

kubectl delete pod mongodb-pod
의미 : mongodb-pod 삭제

kubectl delete pvc mongo-pvc
의미 : mongo-pvc 삭제

kubectl get pv,pvc
의미 : Persistent Volume,Persistent Volume Claim 확인

profile
이것저것 공부하는

0개의 댓글