Kubernetes 101
Kubernetes를 경험하는 가장 쉬운 방법은 nginx 컨테이너를 실행한 다음 kubectl을 사용하여 컨테이너를 조작하는 것입니다. Kubernetes는 컨테이너를 쉽게 생성할 수 있는 docker run
명령어와 유사한 kubectl run
를 제공합니다. (실제로 Deployment로 관리되는 팟을 생성함):
$ kubectl run --image=nginx:alpine nginx-app --port=80
deployment "nginx-app" created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-app-4028413181-cnt1i 1/1 Running 0 52s
컨테이너가 Running 상태가 될 때까지 기다린 다음, kubectl 명령을 사용하여 조작할 수 있습니다. 예를 들면 다음과 같습니다.
kubectl get
-docker ps
와 유사. 자원 목록을 질의kubectl describe
-docker inspect
와 유사. 자원에 대한 세부 정보 조회kubectl logs
-docker logs
와 유사. 컨테이너 로그를 조회kubectl exec
-docker exec
와 유사. 컨테이너 내에서 명령어를 실행
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-app-4028413181-cnt1i 1/1 Running 0 6m
$ kubectl exec nginx-app-4028413181-cnt1i ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.5 31736 5108 ? Ss 00:19 0:00 nginx: master process nginx -g daemon off;
nginx 5 0.0 0.2 32124 2844 ? S 00:19 0:00 nginx: worker process
root 18 0.0 0.2 17500 2112 ? Rs 00:25 0:00 ps aux
$ kubectl describe pod nginx-app-4028413181-cnt1i
Name: nginx-app-4028413181-cnt1i
Namespace: default
Node: boot2docker/192.168.64.12
Start Time: Tue, 06 Sep 2016 08:18:41 +0800
Labels: pod-template-hash=4028413181
run=nginx-app
Status: Running
IP: 172.17.0.3
Controllers: ReplicaSet/nginx-app-4028413181
Containers:
nginx-app:
Container ID: docker://4ef989b57d0a7638ad9c5bbc22e16d5ea5b459281c77074fc982eba50973107f
Image: nginx
Image ID: docker://sha256:4efb2fcdb1ab05fb03c9435234343c1cc65289eeb016be86193e88d3a5d84f6b
Port: 80/TCP
State: Running
Started: Tue, 06 Sep 2016 08:19:30 +0800
Ready: True
Restart Count: 0
Environment Variables: <none>
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-9o8ks:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-9o8ks
QoS Tier: BestEffort
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
8m 8m 1 {default-scheduler } Normal Scheduled Successfully assigned nginx-app-4028413181-cnt1i to boot2docker
8m 8m 1 {kubelet boot2docker} spec.containers{nginx-app} Normal Pulling pulling image "nginx"
7m 7m 1 {kubelet boot2docker} spec.containers{nginx-app} Normal Pulled Successfully pulled image "nginx"
7m 7m 1 {kubelet boot2docker} spec.containers{nginx-app} Normal Created Created container with docker id 4ef989b57d0a
7m 7m 1 {kubelet boot2docker} spec.containers{nginx-app} Normal Started Started container with docker id 4ef989b57d0a
$ curl http://172.17.0.3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
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>
$ kubectl logs nginx-app-4028413181-cnt1i
127.0.0.1 - - [06/Sep/2016:00:27:13 +0000] "GET / HTTP/1.0 " 200 612 "-" "-" "-"
Yaml을 사용해 Pod을 정의하기
위에서 kubectl run
을 통해 첫 번째 팟을 시작했는데, kubectl run
은 모든 기능을 지원하지 않습니다. Kubernetes에서 자원을 정의할 때에는 yaml 파일이 더 자주 사용됩니다. 자원은 kubectl create -f file.yaml
으로 생성됩니다. 예를 들어, 간단한 nginx 팟은 다음과 같이 정의할 수 있습니다:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
앞서 말한 kubectl run
으로 팟을 직접 생성하는 대신, Deployment 자원(replicas = 1)을 만들게 되면, Deployment와 연결된 ReplicaSet에 의해서 자동으로 팟이 생성됩니다. 이를 테면, 다음과 같은 설정과 동일하게 말이죠:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
run: nginx-app
name: nginx-app
namespace: default
spec:
replicas: 1
selector:
matchLabels:
run: nginx-app
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
run: nginx-app
spec:
containers:
- image: nginx
name: nginx-app
ports:
- containerPort: 80
protocol: TCP
dnsPolicy: ClusterFirst
restartPolicy: Always
Volume 사용하기
팟의 수명주기는 일반적으로 상대적으로 짧습니다. 예외가 발생하게 되면 새로운 팟으로 교체됩니다. 컨테이너에 데이터를 생성했다구요? 팟이 죽으면 컨테이너의 데이터가 자동으로 사라집니다. 볼륨은 컨테이너 데이터를 유지하기 위해 만들어졌습니다. 예를 들어, 다음과 깉이 redis 데이터를 저장할 hostPath 볼륨을 지닌 redis 컨테이너를 지정할 수 있습니다:
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-persistent-storage
mountPath: /data/redis
volumes:
- name: redis-persistent-storage
hostPath:
path: /data/
Kubernetes 볼륨은 다양한 플러그인을 지원합니다. 실제 필요에 따라 다음과 같이 선택할 수 있습니다.
- emptyDir
- hostPath
- gcePersistentDisk
- awsElasticBlockStore
- nfs
- iscsi
- flocker
- glusterfs
- rbd
- cephfs
- gitRepo
- secret
- persistentVolumeClaim
- downwardAPI
- azureFileVolume
- vsphereVolume
Service 사용하기
앞서 팟을 생성했다고 하더라도 Kubernetes에서 팟의 IP 주소는 팟의 재부팅과 함께 변경됩니다. 팟의 IP를 직접 취해 인터랙션하는 것은 권장되지 않습니다. 그럼, 팟이 제공하는 서비스에 어떻게 억세스할 수 있을까요? 서비스를 이용하는 것입니다. 서비스는 팟 집합(레이블로 선택되는)에 대한 통합 포털을 제공하고 로드 밸런싱 및 자동 서비스 검색 기능을 제공합니다. 예를 들어, 이전의nginx-app
에 대한 서비스를 만들 수 있습니다:
$ kubectl expose deployment nginx-app --port=80 --target-port=80 --type=NodePort
service "nginx-app" exposed
$ kubectl describe service nginx-app
Name: nginx-app
Namespace: default
Labels: run=nginx-app
Selector: run=nginx-app
Type: ClusterIP
IP: 10.0.0.66
Port: <unset> 80/TCP
NodePort: <unset> 30772/TCP
Endpoints: 172.17.0.3:80
Session Affinity: None
No events.
이런 식으로 nginx-app는 http://10.0.0.66
과 http://node-ip:30772
를 통해 클러스터 내에서 접근할 수 있습니다. 외부의 클러스터에서는 http://node-ip:30772
를 통해서만 액세스할 수 있습니다.