๊ธฐ์ฌ์ ๋ฒ์ญ์ ๊ณผ์ ์์ ์ ๋ ์ ์ค๋น๋์์ต๋๋ค.
์ด ๊ธ์ ์ฝ๊ณ ๊ณ์๋ค๋ฉด ์๋ง๋ Kubernetes์ ๋ํด ๋ค์ด๋ณด์
จ์ ๊ฒ์
๋๋ค(์๋๋ฉด ์ด๋ป๊ฒ ์ฌ๊ธฐ๊น์ง ์ค์
จ๋์?). ํ์ง๋ง Kubernetes๋ ์ ํํ ๋ฌด์์ธ๊ฐ์? ์ด๊ฒ
์์งํ ๋งํด์ 100% ํ์ ํ ์๋ ์์ต๋๋ค. ํ์ง๋ง ๋ด๋ถ๋ฅผ ํํค์ณ ์ฌ๋ฌ ์ถ์ํ ๊ณ์ธต ์๋ Kubernetes์์ ์ค์ ๋ก ๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์ง ๋ณด๋ ๊ฒ์ ํฅ๋ฏธ๋กญ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ผ ์ฌ๋ฏธ์ผ์ ์ต์ํ์ "Kubernetes ํด๋ฌ์คํฐ"๊ฐ ์ค์ ๋ก ์ด๋ป๊ฒ ๋ณด์ด๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค. (์ด๊ฒ์ ๊ฒ๋ณด๋ค ํจ์ฌ ์ฌ์ธ ๊ฒ์
๋๋ค.
Kubernetes, Linux ๋ฐ ์ปจํ
์ด๋์ ๋ํ ๊ธฐ๋ณธ ์ง์์ด ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค. ์ฌ๊ธฐ์ ์ด์ผ๊ธฐํ๋ ๋ชจ๋ ๋ด์ฉ์ ์ฐ๊ตฌ/ํ์ต ๋ชฉ์ ์ผ๋ก๋ง ์ฌ์ฉ๋๋ฉฐ ํ๋ก๋์
์ ์ ์ฉ๋์ง ์์ต๋๋ค!
๊ฒํ
Kubernetes์๋ ๋ง์ ๊ตฌ์ฑ ์์๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ์ ๋ฐ๋ฅด๋ฉด
์ฌ๊ธฐ์๋ ์ต์ XNUMX๊ฐ์ ๊ตฌ์ฑ ์์๊ฐ ํ์๋์ด ์์ง๋ง ๋๋ถ๋ถ์ ๋ฌด์ํ๊ฒ ์ต๋๋ค. Kubernetes๋ผ๊ณ ํฉ๋ฆฌ์ ์ผ๋ก ๋ถ๋ฅผ ์ ์๋ ์ต์ํ์ ์์๋ ์ธ ๊ฐ์ง ์ฃผ์ ๊ตฌ์ฑ ์์๋ก ๊ตฌ์ฑ๋์ด ์๋ค๊ณ ๋งํ๊ณ ์ถ์ต๋๋ค.
- Kubelet
- kube-apiserver(etcd์ ๋ฐ๋ผ ๋ค๋ฆ - ํด๋น ๋ฐ์ดํฐ๋ฒ ์ด์ค)
- ์ปจํ ์ด๋ ๋ฐํ์(์ด ๊ฒฝ์ฐ Docker)
๋ฌธ์์์ ๊ฐ๊ฐ์ ๋ํด ๋ญ๋ผ๊ณ ๋งํ๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค(
ํด๋ฌ์คํฐ์ ๊ฐ ๋ ธ๋์์ ์คํ๋๋ ์์ด์ ํธ์ ๋๋ค. ์ปจํ ์ด๋๊ฐ ํฌ๋์์ ์คํ๋๊ณ ์๋์ง ํ์ธํฉ๋๋ค.
์ถฉ๋ถํ ๊ฐ๋จํ๊ฒ ๋ค๋ฆฝ๋๋ค. ๋ ์ด๋ ์ปจํ ์ด๋ ๋ฐํ์ (์ปจํ ์ด๋ ๋ฐํ์)?
์ปจํ ์ด๋ ๋ฐํ์์ ์ปจํ ์ด๋๋ฅผ ์คํํ๋๋ก ์ค๊ณ๋ ํ๋ก๊ทธ๋จ์ ๋๋ค.
๋งค์ฐ ์ ์ตํฉ๋๋ค. ํ์ง๋ง Docker์ ์ต์ํ๋ค๋ฉด Docker๊ฐ ์ํํ๋ ์์ ์ ๋ํ ์ผ๋ฐ์ ์ธ ์์ด๋์ด๊ฐ ์์ด์ผ ํฉ๋๋ค. (์ปจํ ์ด๋ ๋ฐํ์๊ณผ kubelet ๊ฐ์ ์ฑ ์ ๋ถ๋ฆฌ์ ๋ํ ์ธ๋ถ ์ฌํญ์ ์ค์ ๋ก ๋งค์ฐ ๋ฏธ๋ฌํ๋ฏ๋ก ์ฌ๊ธฐ์๋ ๋ค๋ฃจ์ง ์๊ฒ ์ต๋๋ค.)
ะ API ์๋ฒ?
API ์๋ฒ๋ Kubernetes API๋ฅผ ๋ ธ์ถํ๋ Kubernetes ์ ์ดํ ๊ตฌ์ฑ ์์์ ๋๋ค. API ์๋ฒ๋ Kubernetes ์ ์ดํ์ ํด๋ผ์ด์ธํธ ์ธก์ ๋๋ค.
Kubernetes๋ฅผ ์ฌ์ฉํด ๋ณธ ์ ์ด ์๋ ์ฌ๋์ด๋ผ๋ฉด ๋๊ตฌ๋ ์ง์ ๋๋ kubectl์ ํตํด API์ ์ํธ์์ฉํด์ผ ํ์ต๋๋ค. ์ด๊ฒ์ด Kubernetes Kubernetes๋ฅผ ๋ง๋๋ ํต์ฌ์ ๋๋ค. ์ฐ๋ฆฌ ๋ชจ๋๊ฐ ์๊ณ ์ฌ๋ํ๋(?) ์ฐ๋๋ฏธ ๊ฐ์ YAML์ ์๋ํ๋ ์ธํ๋ผ๋ก ๋ฐ๊พธ๋ ๋๋์ ๋๋ค. API๊ฐ ์ต์ํ์ ๊ตฌ์ฑ์ ์์ด์ผ ํ๋ค๋ ๊ฒ์ ๋ถ๋ช ํ ๊ฒ ๊ฐ์ต๋๋ค.
์ ์ ์กฐ๊ฑด
- ๋ฃจํธ ์ก์ธ์ค ๊ถํ์ด ์๋ Linux ๊ฐ์ ๋๋ ๋ฌผ๋ฆฌ์ ๋จธ์ (๊ฐ์ ๋จธ์ ์์ Ubuntu 18.04๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค).
- ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ ๋ค์ผ!
์ง๋ฃจํ ์ค์น
์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ ๋จธ์ ์ Docker๋ฅผ ์ค์นํด์ผ ํฉ๋๋ค. (Docker์ ์ปจํ
์ด๋์ ์๋ ๋ฐฉ์์ ๋ํด์๋ ์์ธํ ์ค๋ช
ํ์ง ์๊ฒ ์ต๋๋ค. ๊ด์ฌ์ด ์์ผ์๋ฉด apt
:
$ sudo apt install docker.io
$ sudo systemctl start docker
๊ทธ๋ฐ ๋ค์ Kubernetes ๋ฐ์ด๋๋ฆฌ๋ฅผ ๊ฐ์ ธ์์ผ ํฉ๋๋ค. ์ค์ ๋ก "ํด๋ฌ์คํฐ"๋ฅผ ์ฒ์ ์์ํ๋ ๊ฒฝ์ฐ์๋ง ํ์ํฉ๋๋ค. kubelet
, ๋ค๋ฅธ ์๋ฒ ๊ตฌ์ฑ์์๋ฅผ ์คํํ๊ธฐ ์ํด ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก kubelet
. ํด๋ฌ์คํฐ๊ฐ ์คํ๋ ํ ํด๋ฌ์คํฐ์ ์ํธ ์์ฉํ๊ธฐ ์ํด ๋ค์๋ ์ฌ์ฉํฉ๋๋ค. kubectl
.
$ curl -L https://dl.k8s.io/v1.18.5/kubernetes-server-linux-amd64.tar.gz > server.tar.gz
$ tar xzvf server.tar.gz
$ cp kubernetes/server/bin/kubelet .
$ cp kubernetes/server/bin/kubectl .
$ ./kubelet --version
Kubernetes v1.18.5
๊ทธ๋ฅ ๋ฌ๋ฆฌ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? kubelet
?
$ ./kubelet
F0609 04:03:29.105194 4583 server.go:254] mkdir /var/lib/kubelet: permission denied
kubelet
๋ฃจํธ๋ก ์คํํด์ผ ํฉ๋๋ค. ๊ทธ๋ ์ ์ฒด ๋
ธ๋๋ฅผ ๊ด๋ฆฌํด์ผ ํ๋ฏ๋ก ๋งค์ฐ ๋
ผ๋ฆฌ์ ์
๋๋ค. ํด๋น ๋งค๊ฐ๋ณ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
$ ./kubelet -h
<ัะปะธัะบะพะผ ะผะฝะพะณะพ ัััะพะบ, ััะพะฑั ัะฐะทะผะตััะธัั ะทะดะตัั>
$ ./kubelet -h | wc -l
284
์, ์ต์ ์ด ๋๋ฌด ๋ง์์! ์ด ์ข๊ฒ๋ ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ๋ค ์ค ๋ช ๊ฐ๋ง ํ์ํฉ๋๋ค. ์ฐ๋ฆฌ๊ฐ ๊ด์ฌ์ ๊ฐ๊ณ ์๋ ๋งค๊ฐ๋ณ์ ์ค ํ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
--pod-manifest-path string
์ ์ ํฌ๋์ฉ ํ์ผ์ด ํฌํจ๋ ๋๋ ํฐ๋ฆฌ ๊ฒฝ๋ก ๋๋ ์ ์ ํฌ๋๋ฅผ ์ค๋ช
ํ๋ ํ์ผ ๊ฒฝ๋ก์
๋๋ค. ์ ์ผ๋ก ์์ํ๋ ํ์ผ์ ๋ฌด์๋ฉ๋๋ค. (์ง์ ์ค๋จ๋จ: ์ด ์ต์
์ --config ์ต์
์ ํตํด Kubelet์ ์ ๋ฌ๋ ๊ตฌ์ฑ ํ์ผ์ ์ค์ ๋์ด์ผ ํฉ๋๋ค. ์์ธํ ๋ด์ฉ์ ๋ค์์ ์ฐธ์กฐํ์ธ์.
์ด ์ต์
์ ์ฌ์ฉํ๋ฉด ๋ค์์ ์คํํ ์ ์์ต๋๋ค.
๋จผ์ ์ ์ ํฌ๋์ฉ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ ์คํํฉ๋๋ค. kubelet
:
$ mkdir pods
$ sudo ./kubelet --pod-manifest-path=pods
๊ทธ๋ฐ ๋ค์ ๋ค๋ฅธ ํฐ๋ฏธ๋/tmux ์ฐฝ ๋ฑ์์ ํฌ๋ ๋งค๋ํ์คํธ๋ฅผ ์์ฑํฉ๋๋ค.
$ cat <<EOF > pods/hello.yaml
apiVersion: v1
kind: Pod
metadata:
name: hello
spec:
containers:
- image: busybox
name: hello
command: ["echo", "hello world!"]
EOF
kubelet
๋ช ๊ฐ์ง ๊ฒฝ๊ณ ๋ฅผ ์ฐ๊ธฐ ์์ํ๋๋ฐ ์๋ฌด ์ผ๋ ์ผ์ด๋์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ํ์ง๋ง ๊ทธ๊ฒ์ ์ฌ์ค์ด ์๋๋๋ค! ๋์ปค๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค:
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8c8a35e26663 busybox "echo 'hello world!'" 36 seconds ago Exited (0) 36 seconds ago k8s_hello_hello-mink8s_default_ab61ef0307c6e0dee2ab05dc1ff94812_4
68f670c3c85f k8s.gcr.io/pause:3.2 "/pause" 2 minutes ago Up 2 minutes k8s_POD_hello-mink8s_default_ab61ef0307c6e0dee2ab05dc1ff94812_0
$ sudo docker logs k8s_hello_hello-mink8s_default_ab61ef0307c6e0dee2ab05dc1ff94812_4
hello world!
kubelet
๋๋ ํฌ๋ ๋งค๋ํ์คํธ๋ฅผ ์ฝ๊ณ ์ฐ๋ฆฌ ์ฌ์์ ๋ฐ๋ผ ๋ ๊ฐ์ ์ปจํ
์ด๋๋ฅผ ์์ํ๋ผ๋ ๋ช
๋ น์ Docker์ ์ ๊ณตํ์ต๋๋ค. ("์ผ์ ์ค์ง" ์ปจํ
์ด๋์ ๋ํด ๊ถ๊ธํ๋ค๋ฉด ์ด๋ Kubernetes ํดํน์
๋๋ค. busybox
์ง์ ๋ ๋ช
๋ น์ ์ฌ์ฉํ๋ฉด ์ ์ ํฌ๋๊ฐ ์ญ์ ๋ ๋๊น์ง ๋ฌด๊ธฐํ ๋ค์ ์์๋ฉ๋๋ค.
์์ ์ ์ถํํฉ๋๋ค. ์ฐ๋ฆฌ๋ ํฐ๋ฏธ๋์ ํ ์คํธ๋ฅผ ์ถ๋ ฅํ๋ ๊ฐ์ฅ ํผ๋์ค๋ฌ์ด ๋ฐฉ๋ฒ ์ค ํ๋๋ฅผ ์๊ฐํด๋์ต๋๋ค!
etcd ์คํ
์ฐ๋ฆฌ์ ๊ถ๊ทน์ ์ธ ๋ชฉํ๋ Kubernetes API๋ฅผ ์คํํ๋ ๊ฒ์
๋๋ค. ํ์ง๋ง ๊ทธ๋ฌ๊ธฐ ์ํด์๋ ๋จผ์ ๋ค์์ ์คํํด์ผ ํฉ๋๋ค. pods/etcd.yaml
):
apiVersion: v1
kind: Pod
metadata:
name: etcd
namespace: kube-system
spec:
containers:
- name: etcd
command:
- etcd
- --data-dir=/var/lib/etcd
image: k8s.gcr.io/etcd:3.4.3-0
volumeMounts:
- mountPath: /var/lib/etcd
name: etcd-data
hostNetwork: true
volumes:
- hostPath:
path: /var/lib/etcd
type: DirectoryOrCreate
name: etcd-data
Kubernetes๋ฅผ ์ฌ์ฉํด ๋ณธ ์ ์ด ์๋ค๋ฉด ์ด๋ฌํ YAML ํ์ผ์ด ์ต์ํ ๊ฒ์ ๋๋ค. ์ฌ๊ธฐ์ ์ฃผ๋ชฉํ ๋งํ ์ ์ ๋ ๊ฐ์ง๋ฟ์ ๋๋ค.
ํธ์คํธ ํด๋๋ฅผ ๋ง์ดํธํ์ต๋๋ค /var/lib/etcd
๋ค์ ์์ํ ํ etcd ๋ฐ์ดํฐ๊ฐ ๋ณด์กด๋๋๋ก ํฌ๋์์(์ด๋ ๊ฒ ํ์ง ์์ผ๋ฉด ํฌ๋๋ฅผ ๋ค์ ์์ํ ๋๋ง๋ค ํด๋ฌ์คํฐ ์ํ๊ฐ ์ง์์ง๋ฏ๋ก ์ต์ํ์ Kubernetes ์ค์น์๋ ์ ํฉํ์ง ์์ต๋๋ค).
์ฐ๋ฆฌ๋ ์ค์นํ์ต๋๋ค hostNetwork: true
. ๋น์ฐํ ์ด ์ค์ ์ Pod์ ๋ด๋ถ ๋คํธ์ํฌ ๋์ ํธ์คํธ ๋คํธ์ํฌ๋ฅผ ์ฌ์ฉํ๋๋ก etcd๋ฅผ ๊ตฌ์ฑํฉ๋๋ค(์ด๋ ๊ฒ ํ๋ฉด API ์๋ฒ๊ฐ etcd ํด๋ฌ์คํฐ๋ฅผ ๋ ์ฝ๊ฒ ์ฐพ์ ์ ์์ต๋๋ค).
๊ฐ๋จํ ๊ฒ์ฌ๋ฅผ ํตํด etcd๊ฐ ์ค์ ๋ก localhost์์ ์คํ ์ค์ด๊ณ ๋ฐ์ดํฐ๋ฅผ ๋์คํฌ์ ์ ์ฅํ๊ณ ์์์ ์ ์ ์์ต๋๋ค.
$ curl localhost:2379/version
{"etcdserver":"3.4.3","etcdcluster":"3.4.0"}
$ sudo tree /var/lib/etcd/
/var/lib/etcd/
โโโ member
โโโ snap
โ โโโ db
โโโ wal
โโโ 0.tmp
โโโ 0000000000000000-0000000000000000.wal
API ์๋ฒ ์์
Kubernetes API ์๋ฒ๋ฅผ ์คํํ๋ ๊ฒ์ด ํจ์ฌ ๋ ์ฝ์ต๋๋ค. ์ ๋ฌํด์ผ ํ๋ ์ ์ผํ ๋งค๊ฐ๋ณ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. --etcd-servers
, ์์ํ ๋๋ก ์ํ๋ฉ๋๋ค.
apiVersion: v1
kind: Pod
metadata:
name: kube-apiserver
namespace: kube-system
spec:
containers:
- name: kube-apiserver
command:
- kube-apiserver
- --etcd-servers=http://127.0.0.1:2379
image: k8s.gcr.io/kube-apiserver:v1.18.5
hostNetwork: true
์ด YAML ํ์ผ์ ๋๋ ํฐ๋ฆฌ์ ๋ฐฐ์นํฉ๋๋ค. pods
, API ์๋ฒ๊ฐ ์์๋ฉ๋๋ค. ํ์ธ ์ค curl
Kubernetes API๊ฐ ์์ ํ ๊ฐ๋ฐฉ๋ ์ก์ธ์ค๋ก ํฌํธ 8080์์ ์์ ๋๊ธฐํ๊ณ ์์์ ๋ณด์ฌ์ค๋๋ค. ์ธ์ฆ์ด ํ์ํ์ง ์์ต๋๋ค.
$ curl localhost:8080/healthz
ok
$ curl localhost:8080/api/v1/pods
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/pods",
"resourceVersion": "59"
},
"items": []
}
(๋ค์ ํ๋ฒ ๋งํ์ง๋ง, ์ด๊ฒ์ ํ๋ก๋์ ํ๊ฒฝ์์ ์คํํ์ง ๋ง์ธ์! ๊ธฐ๋ณธ ์ค์ ์ด ๋๋ฌด ์์ ํ์ง ์์์ ์กฐ๊ธ ๋๋์ต๋๋ค. ํ์ง๋ง ์ด๊ฒ์ด ๊ฐ๋ฐ๊ณผ ํ ์คํธ๋ฅผ ๋ ์ฝ๊ฒ ํ๊ธฐ ์ํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.)
๊ทธ๋ฆฌ๊ณ ๋๋๊ฒ๋ kubectl์ ์ถ๊ฐ ์ค์ ์์ด ์ฆ์ ์๋ํฉ๋๋ค!
$ ./kubectl version
Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.5", GitCommit:"e6503f8d8f769ace2f338794c914a96fc335df0f", GitTreeState:"clean", BuildDate:"2020-06-26T03:47:41Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.5", GitCommit:"e6503f8d8f769ace2f338794c914a96fc335df0f", GitTreeState:"clean", BuildDate:"2020-06-26T03:39:24Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
$ ./kubectl get pod
No resources found in default namespace.
๋ฌธ์
ํ์ง๋ง ์กฐ๊ธ ๋ ๊น์ด ํ๊ณ ๋ค์ด ๋ณด๋ฉด ๋ญ๊ฐ ์๋ชป๋๊ณ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
$ ./kubectl get pod -n kube-system
No resources found in kube-system namespace.
์ฐ๋ฆฌ๊ฐ ๋ง๋ ์ ์ ํฌ๋๊ฐ ์ฌ๋ผ์ก์ต๋๋ค! ์ค์ ๋ก kubelet ๋ ธ๋๋ ์ ํ ๊ฒ์๋์ง ์์ต๋๋ค.
$ ./kubectl get nodes
No resources found in default namespace.
๋ฌด์จ ์ผ์ด์ผ? ๋ช ๋จ๋ฝ ์ ์ ๊ธฐ์ตํ์ ๋ค๋ฉด, ์ฐ๋ฆฌ๋ ๋งค์ฐ ๊ฐ๋จํ ๋ช ๋ น์ค ๋งค๊ฐ๋ณ์ ์ธํธ๋ก kubelet์ ์์ํ๊ธฐ ๋๋ฌธ์ kubelet์ API ์๋ฒ์ ์ ์ํ๊ณ ์ํ๋ฅผ ์๋ฆฌ๋ ๋ฐฉ๋ฒ์ ์์ง ๋ชปํฉ๋๋ค. ๋ฌธ์๋ฅผ ์ฐ๊ตฌํ ํ ํด๋น ํ๋๊ทธ๋ฅผ ์ฐพ์ต๋๋ค.
--kubeconfig string
ํ์ผ์ ๊ฒฝ๋ก kubeconfig
, API ์๋ฒ์ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์ง์ ํฉ๋๋ค. ์ ํจ์ฑ --kubeconfig
API ์๋ฒ ๋ชจ๋๋ฅผ ํ์ฑํํฉ๋๋ค. ์๋์ --kubeconfig
์คํ๋ผ์ธ ๋ชจ๋๋ฅผ ํ์ฑํํฉ๋๋ค.
๊ทธ๋์ ์ฐ๋ฆฌ๋ ์์ ๋ ๋ชจ๋ฅด๊ฒ kubelet์ "์คํ๋ผ์ธ ๋ชจ๋"๋ก ์คํํ๊ณ ์์์ต๋๋ค. (ํํ์ ์ผ๋ก ๋งํ๋ฉด ๋ ๋ฆฝํ kubelet์ "์ต์ ์คํ ๊ฐ๋ฅํ Kubernetes"๋ก ์๊ฐํ ์ ์์ง๋ง ์ด๋ ๋งค์ฐ ์ง๋ฃจํ ๊ฒ์ ๋๋ค). "์ค์ " ๊ตฌ์ฑ์ด ์๋ํ๋๋ก ํ๋ ค๋ฉด kubeconfig ํ์ผ์ kubelet์ ์ ๋ฌํ์ฌ API ์๋ฒ์ ํต์ ํ๋ ๋ฐฉ๋ฒ์ ์์์ผ ํฉ๋๋ค. ์ด ์ข๊ฒ๋ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค(์ธ์ฆ์ด๋ ์ธ์ฆ์ ๋ฌธ์ ๊ฐ ์๊ธฐ ๋๋ฌธ์).
apiVersion: v1
kind: Config
clusters:
- cluster:
server: http://127.0.0.1:8080
name: mink8s
contexts:
- context:
cluster: mink8s
name: mink8s
current-context: mink8s
์ด๊ฒ์ ๋ค๋ฅธ ์ด๋ฆ์ผ๋ก ์ ์ฅ kubeconfig.yaml
, ํ๋ก์ธ์ค ์ข
๋ฃ kubelet
ํ์ํ ๋งค๊ฐ๋ณ์๋ก ๋ค์ ์์ํฉ๋๋ค.
$ sudo ./kubelet --pod-manifest-path=pods --kubeconfig=kubeconfig.yaml
(๊ทธ๋ฐ๋ฐ, kubelet์ด ์คํ๋์ง ์์ ๋ ์ปฌ์ ํตํด API์ ์ ๊ทผํ๋ ค๊ณ ํ๋ฉด ์ฌ์ ํ ์คํ ์ค์ด๋ผ๋ ๊ฒ์ ์๊ฒ ๋ ๊ฒ์ ๋๋ค! Kubelet์ Docker์ ๊ฐ์ Pod์ "์์"๊ฐ ์๋๋ผ "์ปจํธ๋กค"์ ๊ฐ๊น์ต๋๋ค. daemon.โ kubelet์ด ๊ด๋ฆฌํ๋ ์ปจํ ์ด๋๋ kubelet์ด ์ค์งํ ๋๊น์ง ๊ณ์ ์คํ๋ฉ๋๋ค.)
๋ช ๋ถ ์์ kubectl
์์ํ ๋๋ก ํฌ๋์ ๋
ธ๋๊ฐ ํ์๋์ด์ผ ํฉ๋๋ค.
$ ./kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
default hello-mink8s 0/1 CrashLoopBackOff 261 21h
kube-system etcd-mink8s 1/1 Running 0 21h
kube-system kube-apiserver-mink8s 1/1 Running 0 21h
$ ./kubectl get nodes -owide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
mink8s Ready <none> 21h v1.18.5 10.70.10.228 <none> Ubuntu 18.04.4 LTS 4.15.0-109-generic docker://19.3.6
์ด๋ฒ์๋ ์ ๋ง๋ก ์ถํํด ๋ด ์๋ค(์ด๋ฏธ ์ถํํ๋ค๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค). ์์ ํ ๊ธฐ๋ฅ์ ๊ฐ์ถ API๋ก ์คํ๋๋ ์ต์ํ์ Kubernetes "ํด๋ฌ์คํฐ"๊ฐ ์์ต๋๋ค!
์ฐ๋ฆฌ๋ ์๋์์ ์์ํฉ๋๋ค
์ด์ API๊ฐ ๋ฌด์์ ํ ์ ์๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค. nginx ํฌ๋๋ถํฐ ์์ํด ๋ณด๊ฒ ์ต๋๋ค.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
์ฌ๊ธฐ์๋ ๋ค์ ํฅ๋ฏธ๋ก์ด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
$ ./kubectl apply -f nginx.yaml
Error from server (Forbidden): error when creating "nginx.yaml": pods "nginx" is
forbidden: error looking up service account default/default: serviceaccount
"default" not found
$ ./kubectl get serviceaccounts
No resources found in default namespace.
์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ Kubernetes ํ๊ฒฝ์ด ์ผ๋ง๋ ๋น์ฐธํ ์ ๋๋ก ๋ถ์์ ํ์ง ์ ์ ์์ต๋๋ค. ์๋น์ค์ ๋ํ ๊ณ์ ์ด ์์ต๋๋ค. ์๋น์ค ๊ณ์ ์ ์๋์ผ๋ก ๋ง๋ค์ด ๋ค์ ์๋ํ๊ณ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
$ cat <<EOS | ./kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
namespace: default
EOS
serviceaccount/default created
$ ./kubectl apply -f nginx.yaml
Error from server (ServerTimeout): error when creating "nginx.yaml": No API
token found for service account "default", retry after the token is
automatically created and added to the service account
์๋น์ค ๊ณ์ ์ ์๋์ผ๋ก ์์ฑํ๋๋ผ๋ ์ธ์ฆ ํ ํฐ์ด ์์ฑ๋์ง ์์ต๋๋ค. ์ต์ํ์ "ํด๋ฌ์คํฐ"๋ฅผ ๊ณ์ ์คํํด ๋ณด๋ฉด ์ผ๋ฐ์ ์ผ๋ก ์๋์ผ๋ก ๋ฐ์ํ๋ ๋๋ถ๋ถ์ ์ ์ฉํ ๊ธฐ๋ฅ์ด ๋๋ฝ๋๋ค๋ ์ฌ์ค์ ์๊ฒ ๋ ๊ฒ์ ๋๋ค. Kubernetes API ์๋ฒ๋ ์์ง ์คํ๋์ง ์์ ๋ค์ํ ์ปจํธ๋กค๋ฌ ๋ฐ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์์ ๋๋ถ๋ถ์ ๋ฌด๊ฑฐ์ด ์์ ๋ฐ ์๋ ๊ตฌ์ฑ์ด ๋ฐ์ํ๋ฏ๋ก ๋งค์ฐ ๋ฏธ๋๋ฉํฉ๋๋ค.
์ต์
์ ์ค์ ํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค. automountServiceAccountToken
์๋น์ค ๊ณ์ ์ ๊ฒฝ์ฐ(์ด์ฐจํผ ์ฌ์ฉํ ํ์๊ฐ ์์ผ๋ฏ๋ก):
$ cat <<EOS | ./kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
namespace: default
automountServiceAccountToken: false
EOS
serviceaccount/default configured
$ ./kubectl apply -f nginx.yaml
pod/nginx created
$ ./kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 0/1 Pending 0 13m
๋๋์ด ํ์ด ๋ฑ์ฅํ์ด์! ํ์ง๋ง ์ค์ ๋ก๋ ์ฐ๋ฆฌ๊ฐ ์๊ธฐ ๋๋ฌธ์ ์์๋์ง ์์ต๋๋ค
์ค์ ๋ก Pod๋ฅผ ์คํํ๋ ๋ฐ ์ค์ผ์ค๋ฌ๊ฐ ํ์ํ์ง ์์ต๋๋ค. ๋งค๊ฐ๋ณ์์ ๋งค๋ํ์คํธ์ ๋
ธ๋๋ฅผ ์๋์ผ๋ก ์ถ๊ฐํ ์ ์์ต๋๋ค. nodeName
:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
nodeName: mink8s
(๋ฐ๊พธ๋ค mink8s
๋
ธ๋ ์ด๋ฆ์.) ์ญ์ ํ๊ณ ์ ์ฉํ ํ nginx๊ฐ ์์๋์ด ๋ด๋ถ IP ์ฃผ์๋ฅผ ์์ ํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
$ ./kubectl delete pod nginx
pod "nginx" deleted
$ ./kubectl apply -f nginx.yaml
pod/nginx created
$ ./kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 30s 172.17.0.2 mink8s <none> <none>
$ curl -s 172.17.0.2 | head -4
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
ํฌ๋ ๊ฐ์ ๋คํธ์ํฌ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํ๊ธฐ ์ํด ๋ค๋ฅธ ํฌ๋์์ ์ปฌ์ ์คํํ ์ ์์ต๋๋ค.
$ cat <<EOS | ./kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: curl
spec:
containers:
- image: curlimages/curl
name: curl
command: ["curl", "172.17.0.2"]
nodeName: mink8s
EOS
pod/curl created
$ ./kubectl logs curl | head -6
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
์ด ํ๊ฒฝ์ ํํค์ณ ๋ฌด์์ด ํจ๊ณผ๊ฐ ์๊ณ ๋ฌด์์ด ํจ๊ณผ๊ฐ ์๋์ง ์์๋ณด๋ ๊ฒ์ ๋งค์ฐ ํฅ๋ฏธ๋กญ์ต๋๋ค. ConfigMap๊ณผ Secret์ ์์๋๋ก ์๋ํ์ง๋ง Service์ ๋ฐฐํฌ๋ ์๋ํ์ง ์๋ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค.
์ฑ๊ณต!
ํฌ์คํ ์ด ๋๋ฌด ๊ธธ์ด์ ธ์ ์น๋ฆฌ๋ฅผ ์ ์ธํ๊ณ ์ด๊ฒ์ด "Kubernetes"๋ผ๊ณ ๋ถ๋ฅผ ์ ์๋ ์คํ ๊ฐ๋ฅํ ๊ตฌ์ฑ์ด๋ผ๊ณ ๋งํ๊ณ ์ถ์ต๋๋ค. ์์ฝํ์๋ฉด: 45๊ฐ์ ๋ฐ์ด๋๋ฆฌ, XNUMX๊ฐ์ ๋ช ๋ น์ค ๋งค๊ฐ๋ณ์ ๋ฐ "๋จ์ง" XNUMX์ค์ YAML(์๋๋๋ค) Kubernetes ํ์ค์ ๋ฐ๋ฅด๋ฉด ๊ทธ ์ ๋) ์ฐ๋ฆฌ๋ ๋ช ๊ฐ์ง ์์ ์ ์ํํ๊ณ ์์ต๋๋ค.
- Pod๋ ์ผ๋ฐ Kubernetes API๋ฅผ ์ฌ์ฉํ์ฌ ๊ด๋ฆฌ๋ฉ๋๋ค(๋ช ๊ฐ์ง ํดํน ํฌํจ).
- ๊ณต์ฉ ์ปจํ ์ด๋ ์ด๋ฏธ์ง๋ฅผ ์ ๋ก๋ํ๊ณ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
- ํฌ๋๋ ํ์ฑ ์ํ๋ก ์ ์ง๋๋ฉฐ ์๋์ผ๋ก ๋ค์ ์์๋ฉ๋๋ค.
- ๋์ผํ ๋ ธ๋ ๋ด์ ํฌ๋ ๊ฐ ๋คํธ์ํน์ ๋งค์ฐ ์ ์๋ํฉ๋๋ค.
- ConfigMap, Secret ๋ฐ ๊ฐ๋จํ ์คํ ๋ฆฌ์ง ๋ง์ดํ ์ด ์์๋๋ก ์๋ํฉ๋๋ค.
๊ทธ๋ฌ๋ Kubernetes๋ฅผ ์ง์ ์ผ๋ก ์ ์ฉํ๊ฒ ๋ง๋๋ ๋ค์๊ณผ ๊ฐ์ ๋ง์ ์์๊ฐ ์์ง ๋๋ฝ๋์์ต๋๋ค.
- ํฌ๋ ์ค์ผ์ค๋ฌ
- ์ธ์ฆ/์น์ธ
- ๋ค์ค ๋ ธ๋
- ์๋น์ค ๋คํธ์ํฌ
- ํด๋ฌ์คํฐ๋ง๋ ๋ด๋ถ DNS
- ์๋น์ค ๊ณ์ , ๋ฐฐํฌ, ํด๋ผ์ฐ๋ ์ ๊ณต์ ์ฒด์์ ํตํฉ ๋ฐ Kubernetes๊ฐ ์ ๊ณตํ๋ ๋๋ถ๋ถ์ ๊ธฐํ ๊ธฐ๋ฅ์ ์ํ ์ปจํธ๋กค๋ฌ
๊ทธ๋ ๋ค๋ฉด ์ฐ๋ฆฌ๋ ์ค์ ๋ก ๋ฌด์์ ์ป์์ต๋๊น? ์์ฒด์ ์ผ๋ก ์คํ๋๋ Kubernetes API๋ ์ค์ ๋ก๋ ์ปจํ ์ด๋ ์๋ํ. API๋ฅผ ์ฌ์ฉํ๋ ๋ค์ํ ์ปจํธ๋กค๋ฌ์ ์ด์์๋ฅผ ์ํ ์์ ์ด์ง๋ง, ์๋ํ๋ฅผ ์ํ ์ผ๊ด๋ ํ๊ฒฝ์ ์ ๊ณตํฉ๋๋ค.
๋ ์ฝ์ด๋ณด๊ธฐ :
์์คํ ๊ด๋ฆฌ์, ๊ฐ๋ฐ์ ๋ฐ ํ ์คํฐ๊ฐ DevOps ์ฌ๋ก๋ฅผ ๋ฐฐ์์ผ ํ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น? ํ๋ ธ์ค - ํ์ฅ ๊ฐ๋ฅํ ํ๋ก๋ฉํ ์ฐ์ค GitLab QA ํ์ด GitLab ์ฑ๋ฅ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ Loki - Prometheus ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ์ฌ ๋ก๊ทธ ์์ง DevOps ์ํ์ ํ๋ฃจ
์ถ์ฒ : habr.com