티아카데미 컨테이너 오케스트레이션 쿠버네티스 살펴보기 TIL - 쿠버네티스 주요기능 실습
.
Data_Engineering_TIL(20201211)
study_program : 티아카데미 컨테이너 오케스트레이션 쿠버네티스 살펴보기
(URL : https://tacademy.skplanet.com/frontMain.action)
실습 시 참고한 URL : https://github.com/subicura/workshop-k8s-basic
- 아래와 같이 쿠버네티스 이해를 위한 주요 개념에 대해 실습해본다.
1) kubectl
2) pod
3) replicaset
4) deployment
5) service
6) ingress
- 실습환경 셋팅
ec2를 생성하고 ssh 접속해서 아래와 같이 명령어를 실행한다.
[ec2-user@ip-10-0-1-231 ~]$ sudo yum update -y
[ec2-user@ip-10-0-1-231 ~]$ sudo yum install jq -y
[ec2-user@ip-10-0-1-231 ~]$ sudo amazon-linux-extras install docker
[ec2-user@ip-10-0-1-231 ~]$ sudo service docker start
[ec2-user@ip-10-0-1-231 ~]$ sudo usermod -a -G docker ec2-user
[ec2-user@ip-10-0-1-231 ~]$ exit
# ssh 재접속
[ec2-user@ip-10-0-1-231 ~]$ docker info
Client:
Debug Mode: false
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 19.03.13-ce
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
runc version: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
init version: de40ad0 (expected: fec3683)
Security Options:
seccomp
Profile: default
Kernel Version: 4.14.193-149.317.amzn2.x86_64
Operating System: Amazon Linux 2
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 1.909GiB
Name: ip-10-0-1-231.ap-northeast-2.compute.internal
ID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
[ec2-user@ip-10-0-1-231 ~]$ curl -sfL https://get.k3s.io | sh -
[INFO] Finding release for channel stable
[INFO] Using v1.19.4+k3s1 as release
[INFO] Downloading hash https://github.com/rancher/k3s/releases/download/v1.19.4+k3s1/sha256sum-amd64.txt
[INFO] Downloading binary https://github.com/rancher/k3s/releases/download/v1.19.4+k3s1/k3s
[INFO] Verifying binary download
[INFO] Installing k3s to /usr/local/bin/k3s
[INFO] Creating /usr/local/bin/kubectl symlink to k3s
[INFO] Creating /usr/local/bin/crictl symlink to k3s
[INFO] Skipping /usr/local/bin/ctr symlink to k3s, command exists in PATH at /usr/bin/ctr
[INFO] Creating killall script /usr/local/bin/k3s-killall.sh
[INFO] Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO] env: Creating environment file /etc/systemd/system/k3s.service.env
[INFO] systemd: Creating service file /etc/systemd/system/k3s.service
[INFO] systemd: Enabling k3s unit
Created symlink from /etc/systemd/system/multi-user.target.wants/k3s.service to /etc/systemd/system/k3s.service.
[INFO] systemd: Starting k3s
[ec2-user@ip-10-0-1-231 ~]$ sudo chown ec2-user:ec2-user /etc/rancher/k3s/k3s.yaml
- 기본명령어 실습
get을 이용해서 각종정보를 조회해본다.
get은 object들을 list로 조회한다.
# 쿠버네티스 클러스터 현황확인
# ec2 한대밖에없어서 하나만 보인다.
# 실제 프로덕션 환경에서는 여러대를 클러스터링해서 사용한다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-10-0-1-231.ap-northeast-2.compute.internal Ready master 36s v1.19.4+k3s1
# -o wide 옵션을 주어 상세내용을 볼 수도 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ip-10-0-1-231.ap-northeast-2.compute.internal Ready master 23m v1.19.4+k3s1 10.0.1.231 <none> Amazon Linux 2 4.14.193-149.317.amzn2.x86_64 containerd://1.4.1-k3s1
# -o yaml 옵션을 주면 완전 자세한 내용을 확인할 수 있다.
# 쿠버네티스는 어떤형태의 상태를 관리하는 것이 목적인데 이런 상태를 체크하기에 적합한 옵션이다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get nodes -o yaml
# pod 현황확인
# 아직 만든게 없어서 노 리소스로 나온다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get pod
No resources found in default namespace.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get replicaset
No resources found in default namespace.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get deployment
No resources found in default namespace.
# 쿠버네티스에서 사용하는 서비스가 하나 보인다.
# 이거는 kubectl이 api 통신을 하기위해서 필요해서 떠있는 것이다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 9m46s
[ec2-user@ip-10-0-1-231 ~]$ kubectl get ingress
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
No resources found in default namespace.
# 전체 오브젝트는 kubectl api-resources 명령어로 조회가 가능하다.
# 아래와 같은 리소스들이 복잡하게 얽혀서 쿠버네티스 클러스터가 동작하는 것이다.
# 하지만 실제로 사용자가 사용하는건 위에서 확인한 몇가지 것들 위주다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl api-resources
NAME SHORTNAMES APIGROUP NAMESPACED KIND
bindings true Binding
componentstatuses cs false ComponentStatus
configmaps cm true ConfigMap
endpoints ep true Endpoints
events ev true Event
limitranges limits true LimitRange
namespaces ns false Namespace
nodes no false Node
persistentvolumeclaims pvc true PersistentVolumeClaim
persistentvolumes pv false PersistentVolume
pods po true Pod
podtemplates true PodTemplate
replicationcontrollers rc true ReplicationController
resourcequotas quota true ResourceQuota
secrets true Secret
serviceaccounts sa true ServiceAccount
services svc true Service
mutatingwebhookconfigurations admissionregistration.k8s.io false MutatingWebhookConfiguration
validatingwebhookconfigurations admissionregistration.k8s.io false ValidatingWebhookConfiguration
customresourcedefinitions crd,crds apiextensions.k8s.io false CustomResourceDefinition
apiservices apiregistration.k8s.io false APIService
controllerrevisions apps true ControllerRevision
daemonsets ds apps true DaemonSet
deployments deploy apps true Deployment
replicasets rs apps true ReplicaSet
statefulsets sts apps true StatefulSet
tokenreviews authentication.k8s.io false TokenReview
localsubjectaccessreviews authorization.k8s.io true LocalSubjectAccessReview
selfsubjectaccessreviews authorization.k8s.io false SelfSubjectAccessReview
selfsubjectrulesreviews authorization.k8s.io false SelfSubjectRulesReview
subjectaccessreviews authorization.k8s.io false SubjectAccessReview
horizontalpodautoscalers hpa autoscaling true HorizontalPodAutoscaler
cronjobs cj batch true CronJob
jobs batch true Job
certificatesigningrequests csr certificates.k8s.io false CertificateSigningRequest
leases coordination.k8s.io true Lease
endpointslices discovery.k8s.io true EndpointSlice
events ev events.k8s.io true Event
ingresses ing extensions true Ingress
helmchartconfigs helm.cattle.io true HelmChartConfig
helmcharts helm.cattle.io true HelmChart
addons k3s.cattle.io true Addon
nodes metrics.k8s.io false NodeMetrics
pods metrics.k8s.io true PodMetrics
ingressclasses networking.k8s.io false IngressClass
ingresses ing networking.k8s.io true Ingress
networkpolicies netpol networking.k8s.io true NetworkPolicy
runtimeclasses node.k8s.io false RuntimeClass
poddisruptionbudgets pdb policy true PodDisruptionBudget
podsecuritypolicies psp policy false PodSecurityPolicy
clusterrolebindings rbac.authorization.k8s.io false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io false ClusterRole
rolebindings rbac.authorization.k8s.io true RoleBinding
roles rbac.authorization.k8s.io true Role
priorityclasses pc scheduling.k8s.io false PriorityClass
csidrivers storage.k8s.io false CSIDriver
csinodes storage.k8s.io false CSINode
storageclasses sc storage.k8s.io false StorageClass
volumeattachments storage.k8s.io false VolumeAttachment
# pod, replicaset, deployment, service 한꺼번에 조회
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 20m
# json으로 나온 결과를 파이프로 받아서 jq라는 얘가 다시 그거를 처리하는 명령어이다.
# 현재 이노드의 네임과 cpu 메모리 정보 등을 확인할 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get nodes -o json | jq ".items[] | {name:.metadata.name} + .status.capacity"
{
"name": "ip-10-0-1-231.ap-northeast-2.compute.internal",
"cpu": "2",
"ephemeral-storage": "31444972Ki",
"hugepages-1Gi": "0",
"hugepages-2Mi": "0",
"memory": "2002012Ki",
"pods": "110"
}
- describe 명령어 실습
상세정보를 조회할때 사용한다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-10-0-1-231.ap-northeast-2.compute.internal Ready master 39m v1.19.4+k3s1
[ec2-user@ip-10-0-1-231 ~]$ kubectl describe node ip-10-0-1-231.ap-northeast-2.compute.internal
Name: ip-10-0-1-231.ap-northeast-2.compute.internal
Roles: master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/instance-type=k3s
beta.kubernetes.io/os=linux
k3s.io/hostname=ip-10-0-1-231.ap-northeast-2.compute.internal
k3s.io/internal-ip=10.0.1.231
kubernetes.io/arch=amd64
kubernetes.io/hostname=ip-10-0-1-231.ap-northeast-2.compute.internal
kubernetes.io/os=linux
node-role.kubernetes.io/master=true
node.kubernetes.io/instance-type=k3s
Annotations: flannel.alpha.coreos.com/backend-data: {"VtepMAC":"xxxxxxxxxxxxxxxxxxxx"}
flannel.alpha.coreos.com/backend-type: vxlan
flannel.alpha.coreos.com/kube-subnet-manager: true
flannel.alpha.coreos.com/public-ip: 10.0.1.231
k3s.io/node-args: ["server"]
k3s.io/node-config-hash: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx====
k3s.io/node-env: {"K3S_DATA_DIR":"/var/lib/rancher/k3s/data/xxxxxxxxxxxxxxxxxxxxxxxxxx"}
node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Fri, 11 Dec 2020 08:09:46 +0000
Taints: <none>
Unschedulable: false
Lease:
HolderIdentity: ip-10-0-1-231.ap-northeast-2.compute.internal
AcquireTime: <unset>
RenewTime: Fri, 11 Dec 2020 08:49:26 +0000
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
NetworkUnavailable False Fri, 11 Dec 2020 08:10:02 +0000 Fri, 11 Dec 2020 08:10:02 +0000 FlannelIsUp Flannel is running on this node
MemoryPressure False Fri, 11 Dec 2020 08:45:54 +0000 Fri, 11 Dec 2020 08:09:45 +0000 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Fri, 11 Dec 2020 08:45:54 +0000 Fri, 11 Dec 2020 08:09:45 +0000 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Fri, 11 Dec 2020 08:45:54 +0000 Fri, 11 Dec 2020 08:09:45 +0000 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Fri, 11 Dec 2020 08:45:54 +0000 Fri, 11 Dec 2020 08:09:56 +0000 KubeletReady kubelet is posting ready status
Addresses:
InternalIP: 10.0.1.231
Hostname: ip-10-0-1-231.ap-northeast-2.compute.internal
Capacity:
cpu: 2
ephemeral-storage: 31444972Ki
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 2002012Ki
pods: 110
Allocatable:
cpu: 2
ephemeral-storage: 30589668738
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 2002012Ki
pods: 110
System Info:
Machine ID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
System UUID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Boot ID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Kernel Version: 4.14.193-149.317.amzn2.x86_64
OS Image: Amazon Linux 2
Operating System: linux
Architecture: amd64
Container Runtime Version: containerd://1.4.1-k3s1
Kubelet Version: v1.19.4+k3s1
Kube-Proxy Version: v1.19.4+k3s1
PodCIDR: 10.42.0.0/24
PodCIDRs: 10.42.0.0/24
ProviderID: k3s://ip-10-0-1-231.ap-northeast-2.compute.internal
Non-terminated Pods: (5 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
--------- ---- ------------ ---------- --------------- ------------- ---
kube-system local-path-provisioner-7ff9579c6-vkqxc 0 (0%) 0 (0%) 0 (0%) 0 (0%) 39m
kube-system metrics-server-7b4f8b595-zpqnm 0 (0%) 0 (0%) 0 (0%) 0 (0%) 39m
kube-system coredns-66c464876b-hllht 100m (5%) 0 (0%) 70Mi (3%) 170Mi (8%) 39m
kube-system svclb-traefik-7czk5 0 (0%) 0 (0%) 0 (0%) 0 (0%) 39m
kube-system traefik-5dd496474-brj2s 0 (0%) 0 (0%) 0 (0%) 0 (0%) 39m
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 100m (5%) 0 (0%)
memory 70Mi (3%) 170Mi (8%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-1Gi 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Starting 39m kubelet Starting kubelet.
Warning InvalidDiskCapacity 39m kubelet invalid capacity 0 on image filesystem
Normal NodeHasSufficientPID 39m (x2 over 39m) kubelet Node ip-10-0-1-231.ap-northeast-2.compute.internal status is now: NodeHasSufficientPID
Normal NodeHasSufficientMemory 39m (x2 over 39m) kubelet Node ip-10-0-1-231.ap-northeast-2.compute.internal status is now: NodeHasSufficientMemory
Normal NodeHasNoDiskPressure 39m (x2 over 39m) kubelet Node ip-10-0-1-231.ap-northeast-2.compute.internal status is now: NodeHasNoDiskPressure
Normal NodeAllocatableEnforced 39m kubelet Updated Node Allocatable limit across pods
Normal Starting 39m kube-proxy Starting kube-proxy.
Normal NodeReady 39m kubelet Node ip-10-0-1-231.ap-northeast-2.compute.internal status is now: NodeReady
[ec2-user@ip-10-0-1-231 ~]$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 50m
[ec2-user@ip-10-0-1-231 ~]$ kubectl describe service kubernetes
Name: kubernetes
Namespace: default
Labels: component=apiserver
provider=kubernetes
Annotations: <none>
Selector: <none>
Type: ClusterIP
IP: 10.43.0.1
Port: https 443/TCP
TargetPort: 6443/TCP
Endpoints: 10.0.1.231:6443
Session Affinity: None
Events: <none>
- 가장 자주 사용하는 명령어는 아래와 같다.
kubectl exec -it
–> exec 명령어를 이용해서 특정 컨테이너에 접속할때
kubectl logs -f <POD_NAME | TYPE/NAME> |
–> 로그를 확인하거나
kubectl apply -f
–> 사용자가 정의한 상태를 apply
kubectl delete -f
–> 사용자가 정의한 상태를 delete
- 쿠버네티스의 배포단위인 pod을 만들어보자
프로덕션 환경에서는 yaml파일로 다 정의해놓고 pod을 만드는게 일반적이다.
# whoami 라는 이미지 속성을 넣어서 만들어보자.
# 네트워크가 연결되어 있지 않은 웹서비스 형태의 컨테이너를 실행시킨다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl run whoami --image subicura/whoami:1
pod/whoami created
[ec2-user@ip-10-0-1-231 ~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
whoami 1/1 Running 0 39s
[ec2-user@ip-10-0-1-231 ~]$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
whoami 1/1 Running 0 66s 10.42.0.8 ip-10-0-1-231.ap-northeast-2.compute.internal <none> <none>
[ec2-user@ip-10-0-1-231 ~]$ kubectl get pods -o yaml
apiVersion: v1
items:
- apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2020-12-11T09:11:26Z"
labels:
run: whoami
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:labels:
.: {}
f:run: {}
f:spec:
f:containers:
k:{"name":"whoami"}:
.: {}
f:image: {}
f:imagePullPolicy: {}
f:name: {}
f:resources: {}
f:terminationMessagePath: {}
f:terminationMessagePolicy: {}
f:dnsPolicy: {}
f:enableServiceLinks: {}
f:restartPolicy: {}
f:schedulerName: {}
f:securityContext: {}
f:terminationGracePeriodSeconds: {}
manager: kubectl-run
operation: Update
time: "2020-12-11T09:11:26Z"
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:status:
f:conditions:
k:{"type":"ContainersReady"}:
.: {}
f:lastProbeTime: {}
f:lastTransitionTime: {}
f:status: {}
f:type: {}
k:{"type":"Initialized"}:
.: {}
f:lastProbeTime: {}
f:lastTransitionTime: {}
f:status: {}
f:type: {}
k:{"type":"Ready"}:
.: {}
f:lastProbeTime: {}
f:lastTransitionTime: {}
f:status: {}
f:type: {}
f:containerStatuses: {}
f:hostIP: {}
f:phase: {}
f:podIP: {}
f:podIPs:
.: {}
k:{"ip":"xxxxxxxxxxxxxxx"}:
.: {}
f:ip: {}
f:startTime: {}
manager: k3s
operation: Update
time: "2020-12-11T09:11:36Z"
name: whoami
namespace: default
resourceVersion: "3162"
selfLink: /api/v1/namespaces/default/pods/whoami
uid: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
spec:
containers:
- image: subicura/whoami:1
imagePullPolicy: IfNotPresent
name: whoami
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-bklrx
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: ip-10-0-1-231.ap-northeast-2.compute.internal
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: default-token-bklrx
secret:
defaultMode: 420
secretName: default-token-bklrx
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2020-12-11T09:11:26Z"
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2020-12-11T09:11:36Z"
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2020-12-11T09:11:36Z"
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2020-12-11T09:11:26Z"
status: "True"
type: PodScheduled
containerStatuses:
- containerID: containerd://1c9288f23c00f9dd1eb867afb0e6d4febf05328939370d9dbc2b512de44598ee
image: docker.io/subicura/whoami:1
imageID: docker.io/subicura/whoami@sha256:b560f146bf9cf80ee34bd495ce04dc9661292086781364d36125ef6fc9292fc9
lastState: {}
name: whoami
ready: true
restartCount: 0
started: true
state:
running:
startedAt: "2020-12-11T09:11:36Z"
hostIP: 10.0.1.231
phase: Running
podIP: 10.42.0.8
podIPs:
- ip: 10.42.0.8
qosClass: BestEffort
startTime: "2020-12-11T09:11:26Z"
kind: List
metadata:
resourceVersion: ""
selfLink: ""
[ec2-user@ip-10-0-1-231 ~]$ kubectl get pods -o json
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"creationTimestamp": "2020-12-11T09:11:26Z",
"labels": {
"run": "whoami"
},
"managedFields": [
{
"apiVersion": "v1",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:metadata": {
"f:labels": {
".": {},
"f:run": {}
}
},
"f:spec": {
"f:containers": {
"k:{\"name\":\"whoami\"}": {
".": {},
"f:image": {},
"f:imagePullPolicy": {},
"f:name": {},
"f:resources": {},
"f:terminationMessagePath": {},
"f:terminationMessagePolicy": {}
}
},
"f:dnsPolicy": {},
"f:enableServiceLinks": {},
"f:restartPolicy": {},
"f:schedulerName": {},
"f:securityContext": {},
"f:terminationGracePeriodSeconds": {}
}
},
"manager": "kubectl-run",
"operation": "Update",
"time": "2020-12-11T09:11:26Z"
},
{
"apiVersion": "v1",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:status": {
"f:conditions": {
"k:{\"type\":\"ContainersReady\"}": {
".": {},
"f:lastProbeTime": {},
"f:lastTransitionTime": {},
"f:status": {},
"f:type": {}
},
"k:{\"type\":\"Initialized\"}": {
".": {},
"f:lastProbeTime": {},
"f:lastTransitionTime": {},
"f:status": {},
"f:type": {}
},
"k:{\"type\":\"Ready\"}": {
".": {},
"f:lastProbeTime": {},
"f:lastTransitionTime": {},
"f:status": {},
"f:type": {}
}
},
"f:containerStatuses": {},
"f:hostIP": {},
"f:phase": {},
"f:podIP": {},
"f:podIPs": {
".": {},
"k:{\"ip\":\"10.42.0.8\"}": {
".": {},
"f:ip": {}
}
},
"f:startTime": {}
}
},
"manager": "k3s",
"operation": "Update",
"time": "2020-12-11T09:11:36Z"
}
],
"name": "whoami",
"namespace": "default",
"resourceVersion": "3162",
"selfLink": "/api/v1/namespaces/default/pods/whoami",
"uid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"spec": {
"containers": [
{
"image": "subicura/whoami:1",
"imagePullPolicy": "IfNotPresent",
"name": "whoami",
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"name": "default-token-bklrx",
"readOnly": true
}
]
}
],
"dnsPolicy": "ClusterFirst",
"enableServiceLinks": true,
"nodeName": "ip-10-0-1-231.ap-northeast-2.compute.internal",
"preemptionPolicy": "PreemptLowerPriority",
"priority": 0,
"restartPolicy": "Always",
"schedulerName": "default-scheduler",
"securityContext": {},
"serviceAccount": "default",
"serviceAccountName": "default",
"terminationGracePeriodSeconds": 30,
"tolerations": [
{
"effect": "NoExecute",
"key": "node.kubernetes.io/not-ready",
"operator": "Exists",
"tolerationSeconds": 300
},
{
"effect": "NoExecute",
"key": "node.kubernetes.io/unreachable",
"operator": "Exists",
"tolerationSeconds": 300
}
],
"volumes": [
{
"name": "default-token-bklrx",
"secret": {
"defaultMode": 420,
"secretName": "default-token-bklrx"
}
}
]
},
"status": {
"conditions": [
{
"lastProbeTime": null,
"lastTransitionTime": "2020-12-11T09:11:26Z",
"status": "True",
"type": "Initialized"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2020-12-11T09:11:36Z",
"status": "True",
"type": "Ready"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2020-12-11T09:11:36Z",
"status": "True",
"type": "ContainersReady"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2020-12-11T09:11:26Z",
"status": "True",
"type": "PodScheduled"
}
],
"containerStatuses": [
{
"containerID": "containerd://1c9288f23c00f9dd1eb867afb0e6d4febf05328939370d9dbc2b512de44598ee",
"image": "docker.io/subicura/whoami:1",
"imageID": "docker.io/subicura/whoami@sha256:b560f146bf9cf80ee34bd495ce04dc9661292086781364d36125ef6fc9292fc9",
"lastState": {},
"name": "whoami",
"ready": true,
"restartCount": 0,
"started": true,
"state": {
"running": {
"startedAt": "2020-12-11T09:11:36Z"
}
}
}
],
"hostIP": "10.0.1.231",
"phase": "Running",
"podIP": "10.42.0.8",
"podIPs": [
{
"ip": "10.42.0.8"
}
],
"qosClass": "BestEffort",
"startTime": "2020-12-11T09:11:26Z"
}
}
],
"kind": "List",
"metadata": {
"resourceVersion": "",
"selfLink": ""
}
}
# 아래와 같은 명령어로 생성한 pod에 대해 log를 확인해보자.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
whoami 1/1 Running 0 6m20s
# pod에서 실행된 컨테이너의 로그를 확인할 수 있다.
# 현재서버에서 돌던 다른서버에서 돌던 알아서 api서버가 모아서 보여주기 때문에 한곳에서 모든 로그를 확인할 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl logs -f whoami
[2020-12-11 09:11:37] INFO WEBrick 1.3.1
[2020-12-11 09:11:37] INFO ruby 2.3.3 (2016-11-21) [x86_64-linux]
== Sinatra (v1.4.7) has taken the stage on 4567 for development with backup from WEBrick
[2020-12-11 09:11:37] INFO WEBrick::HTTPServer#start: pid=7 port=4567
^C
# 직접 접속해서 들어갈 수도 있다.
# 이거 역시 이게 어떤 노드에 존재하는지 몰라도 이 명령어를 실행하면 api가 알아서 프록시 연결로 연결을 해준다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl exec -it whoami sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/usr/src/app #
/usr/src/app # ls -al
total 16
drwxr-xr-x 1 root root 73 Feb 10 2017 .
drwxr-xr-x 1 root root 17 Feb 10 2017 ..
-rw-r--r-- 1 root root 193 Feb 11 2017 Dockerfile
-rw-r--r-- 1 root root 44 Feb 11 2017 Gemfile
-rw-r--r-- 1 root root 280 Feb 11 2017 Gemfile.lock
-rw-r--r-- 1 root root 73 Feb 11 2017 app.rb
/usr/src/app # cat app.rb
require 'sinatra'
require 'socket'
get '/' do
Socket.gethostname
end
/usr/src/app #
/usr/src/app # exit
# 또한 describe 명령으로 pod의 상세정보를 확인할 수 있다.
# 여기서 중요한 내용은 Events이다.
# 이벤트 부분을 보면 스케쥴러가 assign 해줬고, 내부적으로 도커이미지가 없으니까 pulling했고,
# 컨테이너를 생성하고, 러닝까지 했다는 것을 알 수 있다.
# 쿠버네티스를 쓰다보면 뭔가 실행을 했는데 pod이 안뜨는 경우가 있다. 이따 describe pod 명령을 이용하면 좋다.
# 이벤트에 어떤 Error가 났는지 다 확인할 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl describe pod whoami
Name: whoami
Namespace: default
Priority: 0
Node: ip-10-0-1-231.ap-northeast-2.compute.internal/10.0.1.231
Start Time: Fri, 11 Dec 2020 09:11:26 +0000
Labels: run=whoami
Annotations: <none>
Status: Running
IP: 10.42.0.8
IPs:
IP: 10.42.0.8
Containers:
whoami:
Container ID: containerd://1c9288f23c00f9dd1eb867afb0e6d4febf05328939370d9dbc2b512de44598ee
Image: subicura/whoami:1
Image ID: docker.io/subicura/whoami@sha256:b560f146bf9cf80ee34bd495ce04dc9661292086781364d36125ef6fc9292fc9
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 11 Dec 2020 09:11:36 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-bklrx (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-bklrx:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-bklrx
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 29m default-scheduler Successfully assigned default/whoami to ip-10-0-1-231.ap-northeast-2.compute.internal
Normal Pulling 29m kubelet Pulling image "subicura/whoami:1"
Normal Pulled 28m kubelet Successfully pulled image "subicura/whoami:1" in 9.413830827s
Normal Created 28m kubelet Created container whoami
Normal Started 28m kubelet Started container whoami
# 생성한 pod을 삭제해보자.
# 참고로 deployment라는 것은 pod을 원하는 갯수를 생성을해준다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl delete pod whoami
pod "whoami" deleted
[ec2-user@ip-10-0-1-231 ~]$ kubectl get pods
No resources found in default namespace.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get deployment
No resources found in default namespace.
- YAML 파일 예제
그러면 위에 명령어 위주로 pod을 실행했는데
yaml 형태로 정의해서 실습을 해보자.
[ec2-user@ip-10-0-1-231 ~]$ mkdir guide-03
[ec2-user@ip-10-0-1-231 ~]$ mkdir guide-03/task-02
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-02/whoami-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: whoami
labels:
type: app
spec:
containers:
- name: app
image: subicura/whoami:1
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-02/whoami-pod.yml
pod/whoami created
[ec2-user@ip-10-0-1-231 ~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
whoami 1/1 Running 0 46s
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/whoami 1/1 Running 0 2m54s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 110m
pod이 생성되는 과정을 보면 컨테이너를 생성하라고 지시하고, 해당 이미지를 다운로드를 받을 것이다. 그 다음에 컨테이너가 러닝이 되는데 러닝이 된다는 것은 process가 실행이 된다는 것이고, 근데 해당 process는 실행이 되자마자 바로 application을 요청을 받을수는 없을 것이다. 예를 들어서 예를 들어서 웹서비스를 띄운다고 하면 웹이 구동되는 시간이 있기 때문이다. 따라서 컨테이너가 running하는 시간과 최종적으로 application이 running되는 시간 사이에는 약간의 겝이 있다. 아직 app이 running되지 않았는데 네트워크를 연결하게 되면 error가 날 것이다. 따라서 그 웹이 구동되는 겝동안에 상태를 체크할 수 있는 값을 줄 수 있다. app이 실행되고나서도 주기적으로 체크를 하면서 컨테이너가 정상인지 아닌지를 판단을 하고, 정상이 아니면 자체적으로 재시작을 해서 정상여부를 확인을 한다.
이를 확인하는게 하나는 app이 실행되고나서 컨테이너가 정상인지 체크하는 livenessProbe라는게 있고, app이 준비가 잘 되었는지 체크하는 readinessProbe 라는게 있다.
아래에 작성하는 두 yaml에는 네트워크가 안되도록 작성이 된 내용이다. 따라서 해당 yaml을 실행하면 네트워크가 연결이 안되어서 error가 나는 것을 확인해보고자 한다.
- livenessProbe 예제
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-02/whoami-pod-lp.yml
apiVersion: v1
kind: Pod
metadata:
name: whoami-lp
labels:
type: app
spec:
containers:
- name: app
image: subicura/whoami:1
livenessProbe:
httpGet:
path: /not/exist
port: 8080
initialDelaySeconds: 5
timeoutSeconds: 2 # Default 1
periodSeconds: 5 # Defaults 10
failureThreshold: 1 # Defaults 3
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-02/whoami-pod-lp.yml
pod/whoami-lp created
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/whoami 1/1 Running 0 17m
pod/whoami-lp 1/1 Running 0 27s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 125m
# Liveness probe 상태가 지속적으로 fail난다는 것을 확인해서 계속 재시도하다가 killing을 시킨것을 알 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl describe pod/whoami-lp
Name: whoami-lp
Namespace: default
Priority: 0
Node: ip-10-0-1-231.ap-northeast-2.compute.internal/10.0.1.231
Start Time: Fri, 11 Dec 2020 10:14:50 +0000
Labels: type=app
Annotations: <none>
Status: Running
IP: 10.42.0.10
IPs:
IP: 10.42.0.10
Containers:
app:
Container ID: containerd://2fbcea98f85dbd9c513ab0ea994ea07cf12427ca85157ba1a4451797cfbc3ba7
Image: subicura/whoami:1
Image ID: docker.io/subicura/whoami@sha256:b560f146bf9cf80ee34bd495ce04dc9661292086781364d36125ef6fc9292fc9
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 11 Dec 2020 10:16:01 +0000
Last State: Terminated
Reason: Error
Exit Code: 137
Started: Fri, 11 Dec 2020 10:15:26 +0000
Finished: Fri, 11 Dec 2020 10:16:01 +0000
Ready: True
Restart Count: 2
Liveness: http-get http://:8080/not/exist delay=5s timeout=2s period=5s #success=1 #failure=1
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-bklrx (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-bklrx:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-bklrx
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 77s default-scheduler Successfully assigned default/whoami-lp to ip-10-0-1-231.ap-northeast-2.compute.internal
Normal Pulled 6s (x3 over 77s) kubelet Container image "subicura/whoami:1" already present on machine
Normal Created 6s (x3 over 77s) kubelet Created container app
Normal Started 6s (x3 over 76s) kubelet Started container app
Warning Unhealthy 1s (x3 over 71s) kubelet Liveness probe failed: Get "http://10.42.0.10:8080/not/exist": dial tcp 10.42.0.10:8080: connect: connection refused
Normal Killing 1s (x3 over 71s) kubelet Container app failed liveness probe, will be restarted
- readinessProbe 예제
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-02/whoami-pod-rp.yml
apiVersion: v1
kind: Pod
metadata:
name: whoami-rp
labels:
type: app
spec:
containers:
- name: app
image: subicura/whoami:1
readinessProbe:
httpGet:
path: /not/exist
port: 8080
initialDelaySeconds: 5
timeoutSeconds: 2 # Default 1
periodSeconds: 5 # Defaults 10
failureThreshold: 1 # Defaults 3
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-02/whoami-pod-rp.yml
pod/whoami-rp created
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/whoami 1/1 Running 0 45m
pod/whoami-lp 0/1 CrashLoopBackOff 13 28m
pod/whoami-rp 0/1 Running 0 8s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 153m
# pod/whoami-rp 0/1 를 봤을때 아예 뜨지 못하고 있는 모습을 확인할 수 있다.
# 상태를 아래와 같이 체크를 해보니 접속을 계속 시도하고 있는데 네트워크 접속이 안되고 있는 것을 알 수 있다.
# restart를 지정된 횟수가 넘어가 버리면 killing 된다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl describe pod/whoami-rp
Name: whoami-rp
Namespace: default
Priority: 0
Node: ip-10-0-1-231.ap-northeast-2.compute.internal/10.0.1.231
Start Time: Fri, 11 Dec 2020 10:42:56 +0000
Labels: type=app
Annotations: <none>
Status: Running
IP: 10.42.0.11
IPs:
IP: 10.42.0.11
Containers:
app:
Container ID: containerd://bb4127257fb82eb13625166274cc4ba0eb31c21e917efe32f4b62a070ca0eb61
Image: subicura/whoami:1
Image ID: docker.io/subicura/whoami@sha256:b560f146bf9cf80ee34bd495ce04dc9661292086781364d36125ef6fc9292fc9
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 11 Dec 2020 10:42:57 +0000
Ready: False
Restart Count: 0
Readiness: http-get http://:8080/not/exist delay=5s timeout=2s period=5s #success=1 #failure=1
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-bklrx (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
default-token-bklrx:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-bklrx
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m55s default-scheduler Successfully assigned default/whoami-rp to ip-10-0-1-231.ap-northeast-2.compute.internal
Normal Pulled 2m55s kubelet Container image "subicura/whoami:1" already present on machine
Normal Created 2m55s kubelet Created container app
Normal Started 2m55s kubelet Started container app
Warning Unhealthy 61s (x22 over 2m46s) kubelet Readiness probe failed: Get "http://10.42.0.11:8080/not/exist": dial tcp 10.42.0.11:8080: connect: connection refused
- health check 예제
livenessProbe와 readinessProbe를 전반적으로 체크하는 예제이다.
위에 있던 예제들은 일부러 네트워크가 안되도록 yaml을 작성해준 것이고, 아래의 yaml에서 4567 포트는 통신이 가능한 포트로 아래와 같이 yaml을 작성해서 실행하면 정상적으로 실행이 되는 것을 확인할 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-02/whoami-pod-health.yml
apiVersion: v1
kind: Pod
metadata:
name: whoami-health
labels:
type: app
spec:
containers:
- name: app
image: subicura/whoami:1
livenessProbe:
httpGet:
path: /
port: 4567
readinessProbe:
httpGet:
path: /
port: 4567
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-02/whoami-pod-health.yml
pod/whoami-health created
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/whoami 1/1 Running 0 51m
pod/whoami-rp 0/1 Running 0 6m52s
pod/whoami-lp 0/1 CrashLoopBackOff 15 34m
pod/whoami-health 0/1 Running 0 5s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 160m
[ec2-user@ip-10-0-1-231 ~]$ kubectl describe pod/whoami-health
Name: whoami-health
Namespace: default
Priority: 0
Node: ip-10-0-1-231.ap-northeast-2.compute.internal/10.0.1.231
Start Time: Fri, 11 Dec 2020 10:49:43 +0000
Labels: type=app
Annotations: <none>
Status: Running
IP: 10.42.0.12
IPs:
IP: 10.42.0.12
Containers:
app:
Container ID: containerd://3f6612c361698a62850363c6a20a51f075ff916d6b1f67639ad72a8ae170e3f8
Image: subicura/whoami:1
Image ID: docker.io/subicura/whoami@sha256:b560f146bf9cf80ee34bd495ce04dc9661292086781364d36125ef6fc9292fc9
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 11 Dec 2020 10:49:44 +0000
Ready: True
Restart Count: 0
Liveness: http-get http://:4567/ delay=0s timeout=1s period=10s #success=1 #failure=3
Readiness: http-get http://:4567/ delay=0s timeout=1s period=10s #success=1 #failure=3
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-bklrx (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-bklrx:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-bklrx
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 21s default-scheduler Successfully assigned default/whoami-health to ip-10-0-1-231.ap-northeast-2.compute.internal
Normal Pulled 20s kubelet Container image "subicura/whoami:1" already present on machine
Normal Created 20s kubelet Created container app
Normal Started 20s kubelet Started container app
지금까지는 pod 안에 컨테이너가 하나 있는거만 했는데 pod 하나에 두개 이상을 넣을 수도 있다.
- multi-container 예제
pod 안에 정의된 컨테이너는 동일한 ip를 사용한다. docker-compose 같은 경우에는 같은 네트워크 대역을 쓸뿐이지 같은 아이피주소를 쓰지는 않았지만 이 pod 안에서 뜨는 여러개의 컨테이너는 동일한 ip를 쓰고 서로다른 포트를 이용을 해서 통신을 한다.
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-02/whoami-pod-redis.yml
apiVersion: v1
kind: Pod
metadata:
name: whoami-redis
labels:
type: stack
spec:
containers:
- name: app
image: subicura/whoami-redis:1
env:
- name: REDIS_HOST
value: "localhost"
- name: db
image: redis
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-02/whoami-pod-redis.yml
pod/whoami-redis created
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/whoami 1/1 Running 0 66m
pod/whoami-rp 0/1 Running 0 21m
pod/whoami-health 1/1 Running 0 14m
pod/whoami-lp 0/1 CrashLoopBackOff 19 49m
pod/whoami-redis 0/2 ContainerCreating 0 4s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 174m
[ec2-user@ip-10-0-1-231 ~]$ kubectl describe pod/whoami-redis
Name: whoami-redis
Namespace: default
Priority: 0
Node: ip-10-0-1-231.ap-northeast-2.compute.internal/10.0.1.231
Start Time: Fri, 11 Dec 2020 11:04:20 +0000
Labels: type=stack
Annotations: <none>
Status: Pending
IP:
IPs: <none>
Containers:
app:
Container ID:
Image: subicura/whoami-redis:1
Image ID:
Port: <none>
Host Port: <none>
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Environment:
REDIS_HOST: localhost
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-bklrx (ro)
db:
Container ID:
Image: redis
Image ID:
Port: <none>
Host Port: <none>
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-bklrx (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
default-token-bklrx:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-bklrx
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 12s default-scheduler Successfully assigned default/whoami-redis to ip-10-0-1-231.ap-northeast-2.compute.internal
Normal Pulling 12s kubelet Pulling image "subicura/whoami-redis:1"
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/whoami 1/1 Running 0 67m
pod/whoami-rp 0/1 Running 0 22m
pod/whoami-health 1/1 Running 0 15m
pod/whoami-lp 0/1 CrashLoopBackOff 19 50m
pod/whoami-redis 2/2 Running 0 63s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 175m
# 이 pod 안에는 컨테이너가 두개 띄어져 있으니까 어떤 service에 대한 log를 보고 싶은지 몰라서 Error가 난다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl logs pod/whoami-redis
error: a container name must be specified for pod whoami-redis, choose one of: [app db]
[ec2-user@ip-10-0-1-231 ~]$ kubectl logs pod/whoami-redis app
[2020-12-11 11:04:36] INFO WEBrick 1.3.1
[2020-12-11 11:04:36] INFO ruby 2.3.8 (2018-10-18) [x86_64-linux-musl]
== Sinatra (v2.0.4) has taken the stage on 4567 for development with backup from WEBrick
[2020-12-11 11:04:36] INFO WEBrick::HTTPServer#start: pid=1 port=4567
[ec2-user@ip-10-0-1-231 ~]$ kubectl logs pod/whoami-redis db
1:C 11 Dec 2020 11:04:44.031 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 11 Dec 2020 11:04:44.031 # Redis version=6.0.9, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 11 Dec 2020 11:04:44.031 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 11 Dec 2020 11:04:44.033 * Running mode=standalone, port=6379.
1:M 11 Dec 2020 11:04:44.033 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 11 Dec 2020 11:04:44.033 # Server initialized
1:M 11 Dec 2020 11:04:44.033 * Ready to accept connections
# 아래 명령어와 같이 컨테이너에 직접 들어갈수도 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl exec -it whoami-redis -c db sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# ls -al
total 0
drwxr-xr-x 2 redis redis 6 Nov 18 08:28 .
drwxr-xr-x 1 root root 28 Dec 11 11:04 ..
# exit
# app이라는 컨테이너에 접속했는데 여기서 redis에 접속이 가능한지 테스트를 해보자.
# redis는 별도의 컨테이너이기 때문에 접속이 가능한지, 같은 아이피를 사용중인지 체크해본다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl exec -it whoami-redis -c app sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/usr/src/app # apk add curl busybox-extras
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
(1/5) Installing busybox-extras (1.28.4-r3)
Executing busybox-extras-1.28.4-r3.post-install
(2/5) Installing nghttp2-libs (1.39.2-r0)
(3/5) Installing libssh2 (1.9.0-r1)
(4/5) Installing libcurl (7.61.1-r3)
(5/5) Installing curl (7.61.1-r3)
Executing busybox-1.28.4-r1.trigger
OK: 16 MiB in 35 packages
/usr/src/app # curl localhost:4567
1
/usr/src/app # curl localhost:4567
2
/usr/src/app # curl localhost:4567
3
/usr/src/app # curl localhost:4567
4
/usr/src/app # telnet localhost 6379
dbsize
:1
keys *
*1
$5
count
GET count
$1
4
quit
+OK
Connection closed by foreign host
/usr/src/app # exit
command terminated with exit code 1
[ec2-user@ip-10-0-1-231 ~]$ kubectl describe pod/whoami-redis
Name: whoami-redis
Namespace: default
Priority: 0
Node: ip-10-0-1-231.ap-northeast-2.compute.internal/10.0.1.231
Start Time: Fri, 11 Dec 2020 11:04:20 +0000
Labels: type=stack
Annotations: <none>
Status: Running
IP: 10.42.0.13
IPs:
IP: 10.42.0.13
Containers:
app:
Container ID: containerd://64b0072264f511098ed05a0232b10fa1b3144bb06e1109caafc43c71c3fdfa6a
Image: subicura/whoami-redis:1
Image ID: docker.io/subicura/whoami-redis@sha256:4ebb7fcc2adc99f72aaf33f5a7a49c4f516aa413e87177542554573cb93c9454
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 11 Dec 2020 11:04:35 +0000
Ready: True
Restart Count: 0
Environment:
REDIS_HOST: localhost
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-bklrx (ro)
db:
Container ID: containerd://139ed68e3d9ece9956402d818b7e243d52d6d1fdc393316b2d3966822994e17d
Image: redis
Image ID: docker.io/library/redis@sha256:e2ae53ef2864fca0a117f9b80f287e2890dd1036271dd363c20b9dfc54a8664c
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 11 Dec 2020 11:04:44 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-bklrx (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-bklrx:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-bklrx
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 15m default-scheduler Successfully assigned default/whoami-redis to ip-10-0-1-231.ap-northeast-2.compute.internal
Normal Pulling 15m kubelet Pulling image "subicura/whoami-redis:1"
Normal Pulled 15m kubelet Successfully pulled image "subicura/whoami-redis:1" in 13.5701249s
Normal Created 15m kubelet Created container app
Normal Started 15m kubelet Started container app
Normal Pulling 15m kubelet Pulling image "redis"
Normal Pulled 15m kubelet Successfully pulled image "redis" in 8.099270678s
Normal Created 15m kubelet Created container db
Normal Started 15m kubelet Started container db
- 지금까지 실습했던 yaml을 싹 정리해주자.
[ec2-user@ip-10-0-1-231 ~]$ kubectl delete -f ./guide-03/task-02/
pod "whoami-health" deleted
pod "whoami-lp" deleted
pod "whoami-redis" deleted
pod "whoami-rp" deleted
pod "whoami" deleted
- Replicaset 실습
앞에서 만든 pod을 replicaset으로 만들어보자.
아래에서 replicaset은 1개로 할거고, selector는 리플리카셋 입장에서는 해당하는 라벨에 pod이 있는지 없는지를 판단한다. 타입이 app이고 service가 whoami라는 이름의 pod이 1개가 있는지를 체크한다. template는 만약에 타입이 app이고 service가 whoami라는 이름의 pod이 1개가 있는지를 체크를 해봤는데 해당하는 pod이 없으면 template 이해의 명세대로 pod을 만들라는 의미다. pod에 metadata를 보면 타입이 app이고 service가 whoami라는 라벨을 가진 pod을 만들거고 그 pod의 컨테이너는 subicura/whoami:1라는 이름의 pod을 만들겠다는 의미다.
실제 현업에서는 Replicas를 거의 쓰지는 않는데 우리가 알아야 하는 이유가 있다. deployment를 현업에서 많이 쓰는데 deployment가 내부적으로 replicas를 사용하고 있기 때문이다.
[ec2-user@ip-10-0-1-231 ~]$ ls
guide-03
[ec2-user@ip-10-0-1-231 ~]$ mkdir guide-03/task-03
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-03/whoami-rs.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: whoami-rs
spec:
replicas: 1
selector:
matchLabels:
type: app
service: whoami
template:
metadata:
labels:
type: app
service: whoami
spec:
containers:
- name: whoami
image: subicura/whoami:1
livenessProbe:
httpGet:
path: /
port: 4567
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-03/whoami-rs.yml
replicaset.apps/whoami-rs created
# 아까와 유사한데 replicaset.apps/whoami-rs라는 리플리카셋이 하나 생겼다.
# 그리고 리플리카셋이 생기면서 앞에서 정의했듯이 타입이 app이고 service가 whoami라는 라벨을 가진 pod을
# 찾았는데 없어서 templates 이하내용에 명시된 pod을 생성한 것이다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/whoami-rs-tjbrr 1/1 Running 0 115s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 21h
NAME DESIRED CURRENT READY AGE
replicaset.apps/whoami-rs 1 1 1 115s
# 아래와 같이 --show-labels 옵션을 주면 서비스는 whoami에 type는 app이라는 라벨정보를 확인할 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
whoami-rs-tjbrr 1/1 Running 0 4m41s service=whoami,type=app
# 위에 이 라벨링 정보는 사용자가 임의로 삭제&변경이 가능하다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl label pod/whoami-rs-tjbrr type-
pod/whoami-rs-tjbrr labeled
# 아래와 같이 pod/whoami-rs-tjbrr 에 대해서 type을 제거하니까
# whoami-rs-7d6xg가 강제로 새로 생긴것을 확인할 수 있다.
# 리플리카셋은 주기적으로 yaml에 명시되어 있는 pod을 찾기만 한다.
# 이게 최초에는 없어서 yaml이 실행되면서 pod이 1개 생성되어 replicaset 1 명시된대로 그대로 유지가 되었는데
# 지금 강제로 라벨을 제거하니까 리플리카셋 입장에서는 해당 relicaset이 없어진 것이라고 판단한 것이다.
# 그래서 yaml에 명시된 조건에 맞는 pod을 template를 이용해서 또 다른 pod을 생성을 한 것이다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
whoami-rs-tjbrr 1/1 Running 0 9m33s service=whoami
whoami-rs-7d6xg 1/1 Running 0 11s service=whoami,type=app
# 아래와 같이 pod을 제거를 했을때 pod/whoami-rs-7d6xg을 삭제할 경우
# 역시 리플리카셋 입장에서 해당 pod이 없어진 것이기 때문에 template로 새로 하나를
# 만드는 것을 확인할 수 있다. 상태를 체크하고 있는 것이다.
# 이런 이유로 쿠버네티스가 상태를 관리한다고 할 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl delete pod/whoami-rs-tjbrr
pod "whoami-rs-tjbrr" deleted
[ec2-user@ip-10-0-1-231 ~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
whoami-rs-7d6xg 1/1 Running 0 7m15s
[ec2-user@ip-10-0-1-231 ~]$ kubectl delete pod/whoami-rs-7d6xg
pod "whoami-rs-7d6xg" deleted
[ec2-user@ip-10-0-1-231 ~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
whoami-rs-zbdpk 1/1 Running 0 41s
# 그러면 replicaset 을 3으로 해서 다시 pod을 띄워보자
# 아까 yaml에서 replicas 만 1에서 3으로 바꿔준 것이다.
# 나머지 내용은 전부 동일하다.
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-03/whoami-rs.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: whoami-rs
spec:
replicas: 3
selector:
matchLabels:
type: app
service: whoami
template:
metadata:
labels:
type: app
service: whoami
spec:
containers:
- name: whoami
image: subicura/whoami:1
livenessProbe:
httpGet:
path: /
port: 4567
# 그런다음에 다시 띄우면 큐브컨트롤이 기존것과의 차이점을 인지해서 새로 명령을 내리게 된다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-03/whoami-rs.yml
replicaset.apps/whoami-rs configured
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/whoami-rs-zbdpk 1/1 Running 0 15m
pod/whoami-rs-rhxv2 1/1 Running 0 76s
pod/whoami-rs-b7khr 1/1 Running 0 76s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 21h
NAME DESIRED CURRENT READY AGE
replicaset.apps/whoami-rs 3 3 3 32m
# 위에 실습이 끝나면 아래와 같이 삭제를 해준다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl delete -f guide-03/task-03/
replicaset.apps "whoami-rs" deleted
- Deployment 실습
guide-03/task-04/whoami-deploy.yml는 위에서 replicas와 전혀 차이가 없다. kind와 metadata 이름만 다를 뿐이다.
Deployment는 버전을 관리하고 rollback 같은 기능이 있을뿐이고 replicaset과 거의 차이가 없다. 예를들어서 이미지의 tag 같은 것들이 바뀌면 Deployment는 이력을 모두 기록한다.
[ec2-user@ip-10-0-1-231 ~]$ ls
guide-03
[ec2-user@ip-10-0-1-231 ~]$ mkdir guide-03/task-04
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-04/whoami-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-deploy
spec:
replicas: 3
selector:
matchLabels:
type: app
service: whoami
template:
metadata:
labels:
type: app
service: whoami
spec:
containers:
- name: whoami
image: subicura/whoami:1
livenessProbe:
httpGet:
path: /
port: 4567
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-04/whoami-deploy.yml
deployment.apps/whoami-deploy created
# replicas와는 다르게 NAME 세번째에 deployment.apps/whoami-deploy 부분이 새로 생겼다.
# 이 deployment.apps/whoami-deploy가 replicaset을 만들었고, replicaset.apps/whoami-deploy-698f4ffd64가 만든 pod 세개가
# 추가된 것을 알 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/whoami-deploy-698f4ffd64-2ccjr 1/1 Running 0 5s
pod/whoami-deploy-698f4ffd64-ldd9t 1/1 Running 0 5s
pod/whoami-deploy-698f4ffd64-tpjrd 1/1 Running 0 5s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 22h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/whoami-deploy 3/3 3 3 5s
NAME DESIRED CURRENT READY AGE
replicaset.apps/whoami-deploy-698f4ffd64 3 3 3 5s
# 그러면 왜 deployment가 replicaset을 쓸까
# 아래와 같이 yaml에서 subicura/whoami:1을 subicura/whoami:2로 바꿔서 다시 실행해보자.
# 그러면 원래 pod은 그대로 있고 subicura/whoami:2가 실행이 된다.
# 그러다가 subicura/whoami:2가 실행이 다 완료되면 원래 있던 3개의 pod은 종료가 된다.
# 그리고 replicaset이 원래는 1개 였는데 2개가 된것을 알 수 있다.
# deployment는 버전을 업그레이드할때 replicaset을 이용을 한다.
# 위에서 순서대로 첫번째 replicaset은 버전 1을 관리한 replicaset이고
# 아래 replicaset은 버전 2을 관리하는 replicaset이다. 버전 2를 deployment를 이용해서 띄우면
# deployment가 처음에는 버전 1을 갖고있는 replicaset 한테 pod 3개를 띄우라고 했다가
# pod을 2개를 띄우라고 명령을 한다. 그리고 버전 2을 관리하는 replicaset에게 pod을 1개 띄우라고 한다.
# 이게 성공적으로 되면 버전 1을 갖고있는 replicaset에게 pod 두개띄우는걸 한개로 띄우라고하고,
# 그런 다음에 버전 2를 갖고 있는 얘한테 pod 1개 갖고 있는걸 2개를 띄우라고 한다. 이런식으로
# 기존의 버전과 새로운 버전을 바꿔치기 한다.
# deployment가 replicaset을 이용을 하는 것이다.
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-04/whoami-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-deploy
spec:
replicas: 3
selector:
matchLabels:
type: app
service: whoami
template:
metadata:
labels:
type: app
service: whoami
spec:
containers:
- name: whoami
image: subicura/whoami:2
livenessProbe:
httpGet:
path: /
port: 4567
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-04/whoami-deploy.yml
deployment.apps/whoami-deploy configured
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/whoami-deploy-698f4ffd64-2ccjr 1/1 Running 0 4m19s
pod/whoami-deploy-698f4ffd64-ldd9t 1/1 Running 0 4m19s
pod/whoami-deploy-698f4ffd64-tpjrd 1/1 Running 0 4m19s
pod/whoami-deploy-8686bdc7cc-f5ks5 0/1 ContainerCreating 0 7s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 22h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/whoami-deploy 3/3 1 3 4m19s
NAME DESIRED CURRENT READY AGE
replicaset.apps/whoami-deploy-698f4ffd64 3 3 3 4m19s
replicaset.apps/whoami-deploy-8686bdc7cc 1 1 0 7s
# 한 3초 있다가 다시 아래와 같이 조회해본다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/whoami-deploy-8686bdc7cc-f5ks5 1/1 Running 0 71s
pod/whoami-deploy-8686bdc7cc-vnzbf 1/1 Running 0 64s
pod/whoami-deploy-8686bdc7cc-dtmx5 1/1 Running 0 63s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 22h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/whoami-deploy 3/3 3 3 5m23s
NAME DESIRED CURRENT READY AGE
replicaset.apps/whoami-deploy-8686bdc7cc 3 3 3 71s
replicaset.apps/whoami-deploy-698f4ffd64 0 0 0 5m23s
# 그러면 위에서 언급한 내용이 실시간으로 어떻게 변화는지 아래와 같이 명령어를 실행해서 확인해보자.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get rs -w
NAME DESIRED CURRENT READY AGE
whoami-deploy-8686bdc7cc 3 3 3 17m
whoami-deploy-698f4ffd64 0 0 0 21m
## 프로세스가 계속 물고 있기 때문에 새로 터미널을 띄운다.
# subicura/whoami:2에서 다시 1로 바꿔서 실행해보자.
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-04/whoami-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-deploy
spec:
replicas: 3
selector:
matchLabels:
type: app
service: whoami
template:
metadata:
labels:
type: app
service: whoami
spec:
containers:
- name: whoami
image: subicura/whoami:1
livenessProbe:
httpGet:
path: /
port: 4567
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-04/whoami-deploy.yml
deployment.apps/whoami-deploy configured
## 아까 kubectl get rs -w 띄워놓은 터미널로 돌아가면
# pod 뜨고 죽는 현황을 확인할 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get rs -w
NAME DESIRED CURRENT READY AGE
whoami-deploy-8686bdc7cc 3 3 3 17m
whoami-deploy-698f4ffd64 0 0 0 21m
whoami-deploy-698f4ffd64 0 0 0 27m
whoami-deploy-698f4ffd64 1 0 0 27m
whoami-deploy-698f4ffd64 1 0 0 27m
whoami-deploy-698f4ffd64 1 1 0 27m
whoami-deploy-698f4ffd64 1 1 1 27m
whoami-deploy-8686bdc7cc 2 3 3 22m
whoami-deploy-698f4ffd64 2 1 1 27m
whoami-deploy-8686bdc7cc 2 3 3 22m
whoami-deploy-698f4ffd64 2 1 1 27m
whoami-deploy-8686bdc7cc 2 2 2 22m
whoami-deploy-698f4ffd64 2 2 1 27m
whoami-deploy-698f4ffd64 2 2 2 27m
whoami-deploy-8686bdc7cc 1 2 2 22m
whoami-deploy-698f4ffd64 3 2 2 27m
whoami-deploy-8686bdc7cc 1 2 2 22m
whoami-deploy-698f4ffd64 3 2 2 27m
whoami-deploy-8686bdc7cc 1 1 1 22m
whoami-deploy-698f4ffd64 3 3 2 27m
whoami-deploy-698f4ffd64 3 3 3 27m
whoami-deploy-8686bdc7cc 0 1 1 22m
whoami-deploy-8686bdc7cc 0 1 1 22m
whoami-deploy-8686bdc7cc 0 0 0 22m
^C
# deployment는 pod의 갯수 같은 것을 신경쓰는게 아니라 replicaset의 상태만 관리하고, replicaset에게 위임을 한다.
# 그러면 deployment가 버전관리가 가능한데 이걸 실습을 해보자.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
whoami-deploy 3/3 3 3 37m
# deployment가 replicaset에 명령했던 이력들을 event로 확인할 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl describe deployment/whoami-deploy
Name: whoami-deploy
Namespace: default
CreationTimestamp: Sat, 12 Dec 2020 06:27:12 +0000
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 3
Selector: service=whoami,type=app
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: service=whoami
type=app
Containers:
whoami:
Image: subicura/whoami:1
Port: <none>
Host Port: <none>
Liveness: http-get http://:4567/ delay=0s timeout=1s period=10s #success=1 #failure=3
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: whoami-deploy-698f4ffd64 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 34m deployment-controller Scaled up replica set whoami-deploy-8686bdc7cc to 1
Normal ScalingReplicaSet 33m deployment-controller Scaled down replica set whoami-deploy-698f4ffd64 to 2
Normal ScalingReplicaSet 33m deployment-controller Scaled up replica set whoami-deploy-8686bdc7cc to 2
Normal ScalingReplicaSet 33m deployment-controller Scaled down replica set whoami-deploy-698f4ffd64 to 1
Normal ScalingReplicaSet 33m deployment-controller Scaled up replica set whoami-deploy-8686bdc7cc to 3
Normal ScalingReplicaSet 33m deployment-controller Scaled down replica set whoami-deploy-698f4ffd64 to 0
Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set whoami-deploy-698f4ffd64 to 1
Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set whoami-deploy-8686bdc7cc to 2
Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set whoami-deploy-698f4ffd64 to 2
Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set whoami-deploy-8686bdc7cc to 1
Normal ScalingReplicaSet 11m (x2 over 38m) deployment-controller Scaled up replica set whoami-deploy-698f4ffd64 to 3
Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set whoami-deploy-8686bdc7cc to 0
# deployment의 history도 다음과 같은 명령어를 실행해서 확인할 수 있다.
# subicura/whoami:1 --> subicura/whoami:2 --> subicura/whoami:1 이렇게 세번 바뀌었기 떄문에
# revision이 세개가 있는것이고, 이미지 버전이 똑같은 경우에는 이전 기록을 지우기 때문에
# 총 버전이 세개지만 마지막 버전 2개만 보이는 것이다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl rollout history deployment/whoami-deploy
deployment.apps/whoami-deploy
REVISION CHANGE-CAUSE
2 <none>
3 <none>
# 특정 revision의 상세내역도 확인할 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl rollout history deployment/whoami-deploy --revision=2
deployment.apps/whoami-deploy with revision #2
Pod Template:
Labels: pod-template-hash=8686bdc7cc
service=whoami
type=app
Containers:
whoami:
Image: subicura/whoami:2
Port: <none>
Host Port: <none>
Liveness: http-get http://:4567/ delay=0s timeout=1s period=10s #success=1 #failure=3
Environment: <none>
Mounts: <none>
Volumes: <none>
[ec2-user@ip-10-0-1-231 ~]$ kubectl rollout history deployment/whoami-deploy --revision=3
deployment.apps/whoami-deploy with revision #3
Pod Template:
Labels: pod-template-hash=698f4ffd64
service=whoami
type=app
Containers:
whoami:
Image: subicura/whoami:1
Port: <none>
Host Port: <none>
Liveness: http-get http://:4567/ delay=0s timeout=1s period=10s #success=1 #failure=3
Environment: <none>
Mounts: <none>
Volumes: <none>
# 이런식으로 내가 버전을 하나 올렸는데 그 버전에 문제가 있다면 다시 rollback해야 한다.
# 이런 시나리오도 대처가 가능하다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl rollout undo deployment/whoami-deploy
deployment.apps/whoami-deploy rolled back
# 롤백을 하는데 revision을 롤백하는게 아니라 리비전 4번으로 하고, 이전의 상태를 롤백하는 개념이다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl rollout history deployment/whoami-deploy
deployment.apps/whoami-deploy
REVISION CHANGE-CAUSE
3 <none>
4 <none>
[ec2-user@ip-10-0-1-231 ~]$ kubectl rollout history deployment/whoami-deploy --revision=4
deployment.apps/whoami-deploy with revision #4
Pod Template:
Labels: pod-template-hash=8686bdc7cc
service=whoami
type=app
Containers:
whoami:
Image: subicura/whoami:2
Port: <none>
Host Port: <none>
Liveness: http-get http://:4567/ delay=0s timeout=1s period=10s #success=1 #failure=3
Environment: <none>
Mounts: <none>
Volumes: <none>
# deployment는 strategy라는 항목이 있다.
# 아까는 3개의 pod이 띄워져 있는 상태에서 버전이 변화하면 pod이 하나가 뜨면 하나가 죽고, 다시 하나가 뜨면 하나가 죽는
# 이런 방식인데 이게 만약에 pod이 100개라고 치면 pod이 한방에 50개뜨고 다 뜨면 50개 죽이고 이런식으로 하고 싶을 것이다.
# 이런걸 적용할 수 있는 옵션이다.
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-04/whoami-deploy-strategy.yml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: whoami-deploy
spec:
replicas: 3
selector:
matchLabels:
type: app
service: whoami
minReadySeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
labels:
type: app
service: whoami
spec:
containers:
- name: whoami
image: subicura/whoami:1
livenessProbe:
httpGet:
path: /
port: 4567
# 위에 실습이 끝나면 아래와 같이 삭제를 해준다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl delete -f guide-03/task-04/
deployment.apps "whoami-deploy" deleted
- Service 실습
지금까지는 컨테이너를 띄우기만 했지 실제 접속을 해보지는 않았다.
service라는 개념이해를 위해 아래의 URL을 참고한다.
https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0
docker-compose 같은 경우에는 host에 port를 연결하는 컨테이너가 있었고, host에 연결을 하지 않은 컨테이너가 있었는데 그거를 쿠버네티스에서는 명시적으로 구분을 한다.
그래서 clusterIP라는 용어가 있는데 이거는 도커에서 실습한 backend나 mongodb의 포트라고 생각하면 된다. clusterIP는 외부로 노출하는 IP가 아니라 내부적으로 통신할때 쓰는 IP를 말한다. docker-compose로 컨테이너를 띄울때는 아무설정을 하지 않아도 몽고디비 안에 있던 27017을 노출을 시킬 수 있었다. 하지만 쿠버네티스에서는 만약에 몽고디비의 27017을 개방하고 싶다 그러면 clusterIP로 지정을 해줘야 한다. 결론은 어떤 pod에 연결하기 위해서는 해당 pod에 반드시 clusterIP가 부여되어 있어야 한다.
그러면 외부에서 접속을 하려면 어떻게 해야하냐. 쿠버네티스에서는 nodeport라는 것을 제공한다. 도커 같은 경우에는 포트를 오픈하면 그 호스트에서만 포트가 열리는데 nodeport같은 경우에는 갖고 있는 모든 노드의 포트가 같이 열리게 된다. 예를 들어서 100개의 노드다 그러면 100개의 노드에 포트가 전부 열리게 된다. 그 100개중에 아무거나 하나접속하면 알아서 내부에 있는 pod을 찾아서 접속하게 설계가 되어 있다.
loadbalancer라는 것도 있다. AWS의 로드밸런서라고 보면 된다. nodeport를 열어주면 모든 노드의 해당 포트가 전부 열린다고 했다. loadbalancer를 쓰게 되면 실제로는 loadbalancer만 포트가 열리게 되고, 이게 서비스에 붙게 된다.
ingress라는 개념도 있다. 이거는 어떤 도메인과 path를 이용해서 원하는 서비스를 연결해주는 기능이다. ingress 안에 nginx가 있는경우가 많다. 이게 무슨의미냐면 ingress는 쿠버네티스에서 얘기하는 개념이고, 실제 구현체로 nginx도 있고, HAproxy도 있고, AWS ELB 또는 ALB도 ingress로 사용할 수 있다. 사용자가 어떻게 구현하느냐에 따라 다른 형태가 되는 것이다.
1) clusterIP 기능을 이용해서
내부서비스 간에 통신하는 것을 실습해보자.
# deployment로 redis를 띄울거고 deployment는 type은 db면서 service는 redis인 pod을 찾는다.
# 그래서 type은 db면서 service는 redis를 만족하는 pod이 없으면
# tempates를 이용해서 pod을 생성한다.
# ---밑에부분이 clusterIP에 관한 설정이다. ClusrterIP는 라벨이 type은 db면서 service는 redis인 pod을 바라본다.
# clusterIP의 selector가 그 역할을 한다.
# 아래와 같이 --- 구분을 통해 분리하는 것이 양식이다.
[ec2-user@ip-10-0-1-231 ~]$ mkdir guide-03/task-05/
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-05/redis-app.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
selector:
matchLabels:
type: db
service: redis
template:
metadata:
labels:
type: db
service: redis
spec:
containers:
- name: redis
image: redis
ports:
- containerPort: 6379
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: redis
spec:
ports:
- port: 6379
protocol: TCP
selector:
type: db
service: redis
# deployment와 service가 생성된 것을 알 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-05/redis-app.yml
deployment.apps/redis created
service/redis created
# deployment가 하나 생성되었고, 이 deployment가 replicaset을 생성했고,
# 이 replicaset이 pod을 생성했다. 그리고 여기에 redis라는 서비스가 추가가 된것이다.
# redis는 10.43.3.112를 부여받았는데 10.43.3.112로 접근하면 pod/redis-b6fd45ccc-lcg7j에 접근하는 것이다.
# 지금은 pod이 하나라서 무조건 pod/redis-b6fd45ccc-lcg7j로 접속하겠지만 만약에 pod이 여러개가 있으면
# 10.43.3.112로 접근했을때 내부적으로 로드밸런스처럼 여러개의 pod에 번갈아가면서 접속한다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/redis-b6fd45ccc-lcg7j 1/1 Running 0 27s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 24h
service/redis ClusterIP 10.43.3.112 <none> 6379/TCP 27s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/redis 1/1 1 1 27s
NAME DESIRED CURRENT READY AGE
replicaset.apps/redis-b6fd45ccc 1 1 1 27s
# 10.42.0.36:6379는 pod/redis-b6fd45ccc-lcg7j의 endpoin이다.
# 10.43.3.112로 접근하면 10.42.0.36:6379를 통해 pod/redis-b6fd45ccc-lcg7j에 접근할 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl describe service/redis
Name: redis
Namespace: default
Labels: <none>
Annotations: <none>
Selector: service=redis,type=db
Type: ClusterIP
IP: 10.43.3.112
Port: <unset> 6379/TCP
TargetPort: 6379/TCP
Endpoints: 10.42.0.36:6379
Session Affinity: None
Events: <none>
# pod을 세개로 늘려보자.
# 기존내용에서 replicas: 3만 추가한 것이다.
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-05/redis-app.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 3
selector:
matchLabels:
type: db
service: redis
template:
metadata:
labels:
type: db
service: redis
spec:
containers:
- name: redis
image: redis
ports:
- containerPort: 6379
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: redis
spec:
ports:
- port: 6379
protocol: TCP
selector:
type: db
service: redis
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-05/redis-app.yml
deployment.apps/redis configured
service/redis unchanged
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/redis-b6fd45ccc-lcg7j 1/1 Running 0 14m
pod/redis-b6fd45ccc-nlpn4 1/1 Running 0 7s
pod/redis-b6fd45ccc-vtnff 1/1 Running 0 7s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 24h
service/redis ClusterIP 10.43.3.112 <none> 6379/TCP 14m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/redis 3/3 3 3 14m
NAME DESIRED CURRENT READY AGE
replicaset.apps/redis-b6fd45ccc 3 3 3 14m
# 10.43.3.112로 접근했을때 바라보는게 아까는 엔드포인트가 하나였는데
# 지금은 세개가 되었다. 로드밸런서 처럼 동작할 것이다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl describe service/redis
Name: redis
Namespace: default
Labels: <none>
Annotations: <none>
Selector: service=redis,type=db
Type: ClusterIP
IP: 10.43.3.112
Port: <unset> 6379/TCP
TargetPort: 6379/TCP
Endpoints: 10.42.0.36:6379,10.42.0.37:6379,10.42.0.38:6379
Session Affinity: None
Events: <none>
# 리플리카셋을 다시 1로해서 적용해주자.
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-05/redis-app.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 1
selector:
matchLabels:
type: db
service: redis
template:
metadata:
labels:
type: db
service: redis
spec:
containers:
- name: redis
image: redis
ports:
- containerPort: 6379
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: redis
spec:
ports:
- port: 6379
protocol: TCP
selector:
type: db
service: redis
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-05/redis-app.yml
deployment.apps/redis configured
service/redis unchanged
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/redis-b6fd45ccc-lcg7j 1/1 Running 0 17m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 24h
service/redis ClusterIP 10.43.3.112 <none> 6379/TCP 17m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/redis 1/1 1 1 17m
NAME DESIRED CURRENT READY AGE
replicaset.apps/redis-b6fd45ccc 1 1 1 17m
# redis를 만들었으니까 그거를 바라보는 app을 만들어보자.
# 호스트를 redis로 사용을 했다. docker-compose에서 container의 이름이 곧 domain인 것처럼
# 동일하게 동작을 한다. 위에서 서비스의 이름을 redis로 지정해줬기 때문에
# whoami 입장에서는 redis로 접근을 하면 redis service로 접근을 한다. 서비스 이름이 곧 도메인 이름처럼 쓰인다.
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-05/whoami-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
spec:
selector:
matchLabels:
type: app
service: whoami
template:
metadata:
labels:
type: app
service: whoami
spec:
containers:
- name: whoami
image: subicura/whoami-redis:1
env:
- name: REDIS_HOST
value: "redis"
- name: REDIS_PORT
value: "6379"
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-05/whoami-deploy.yml
deployment.apps/whoami created
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/redis-b6fd45ccc-lcg7j 1/1 Running 0 24m
pod/whoami-676d78bbf8-8m29n 1/1 Running 0 7s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 25h
service/redis ClusterIP 10.43.3.112 <none> 6379/TCP 24m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/redis 1/1 1 1 24m
deployment.apps/whoami 1/1 1 1 7s
NAME DESIRED CURRENT READY AGE
replicaset.apps/redis-b6fd45ccc 1 1 1 24m
replicaset.apps/whoami-676d78bbf8 1 1 1 7s
# whoami가 잘떴고 실제 접속이 잘 되는지 테스트를 해보자.
# 아래와 같이 redis에 잘 접근하는 것을 확인할 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl exec -it whoami-676d78bbf8-8m29n sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/usr/src/app # apk add curl busybox-extras
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
(1/5) Installing busybox-extras (1.28.4-r3)
Executing busybox-extras-1.28.4-r3.post-install
(2/5) Installing nghttp2-libs (1.39.2-r0)
(3/5) Installing libssh2 (1.9.0-r1)
(4/5) Installing libcurl (7.61.1-r3)
(5/5) Installing curl (7.61.1-r3)
Executing busybox-1.28.4-r1.trigger
OK: 16 MiB in 35 packages
/usr/src/app # telnet redis 6379
keys *
*0
^C
Console escape. Commands are:
l go to line mode
c go to character mode
z suspend telnet
e exit telnet
/usr/src/app # curl localhost:4567
1
/usr/src/app # curl localhost:4567
2
/usr/src/app # curl localhost:4567
3
/usr/src/app # curl localhost:4567
4
/usr/src/app # telnet redis 6379
keys *
*1
$5
count
GET count
$1
4
^C
Console escape. Commands are:
l go to line mode
c go to character mode
z suspend telnet
e exit telnet
/usr/src/app # exit
[ec2-user@ip-10-0-1-231 ~]$
- nodeport 실습
nodeport 기능을 이용해서 외부와의 통신을해보자
app을 바라보는 nodeport를 적용해보자.
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-05/np.yml
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
type: NodePort
ports:
- port: 4567
protocol: TCP
selector:
type: app
service: whoami
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-05/np.yml
service/whoami created
# whoami라는 노드포트가 연결이 되었고, 포트를 보니까 내부에 4567이 30135에 물게된다.
# 따로지정 안하면 30000이상의 포트중에 랜덤하게 지정을 해준다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/redis-b6fd45ccc-lcg7j 1/1 Running 0 59m
pod/whoami-676d78bbf8-8m29n 1/1 Running 0 35m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 25h
service/redis ClusterIP 10.43.3.112 <none> 6379/TCP 59m
service/whoami NodePort 10.43.85.165 <none> 4567:30135/TCP 23s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/redis 1/1 1 1 59m
deployment.apps/whoami 1/1 1 1 35m
NAME DESIRED CURRENT READY AGE
replicaset.apps/redis-b6fd45ccc 1 1 1 59m
replicaset.apps/whoami-676d78bbf8 1 1 1 35m
## 웹브라우저를 열고 [ec2-public-ip]:30135 로 접속하면 숫자 5가 전시되는 것을 알 수 있다.
## 웹브라우저를 새로고침 할때마다 숫자가 올라가는 것을 확인할 수 있다.
- ingress 실습
ingress는 어떤 도메인을 지정하여 해당 도메인에 접근시 특정 서비스에 접근하도록 하는 기능임.
whoami-v1라는 이름으로 ingress를 만들것이다. whoami-v1은 도메인 루트로 접근을 할 것이다.
ssl이 아니더라도 redirect를 하지 않겠다는 옵션도 주었다. 그리고 rule을 지정해줘야 하는데 rule은 v1.whoami.3.35.175.198.sslip.io
이라는 도메인 주소로 접속을 하면 아래의 백앤드 서비스로 접속을 하겠다는 것이다.
아래에서 3.35.175.198
는 EC2의 public ip다.
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-05/in.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: whoami-v1
annotations:
ingress.kubernetes.io/rewrite-target: "/"
ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: v1.whoami.3.35.175.198.sslip.io
http:
paths:
- path: /
backend:
serviceName: whoami-v1
servicePort: 4567
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-05/in.yml
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.extensions/whoami-v1 created
# ingress가 생성된 것을 확인할 수 있고
[ec2-user@ip-10-0-1-231 ~]$ kubectl get ingress
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
whoami-v1 <none> v1.whoami.3.35.175.198.sslip.io 10.0.1.231 80 61s
# 웹브라우저에서 v1.whoami.3.35.175.198.sslip.io 로 접속을 해본다.
# 아마 404 not found가 뜰 것이다.
# 왜냐하면 이 ingress는 whoami-v1 서비스를 바라보게 했는데 whoami-v1 서비스가 없어서 그렇다.
# 그러면 whoami-v1 서비스를 만들고 다시 시도해보자.
# --- 밑에는 clusterIP 설정하는 부분인데 ingress가 해당하는 ip로 접근하겠다는 설정이다.
[ec2-user@ip-10-0-1-231 ~]$ sudo vim guide-03/task-05/whoami-v1.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-v1
spec:
replicas: 3
selector:
matchLabels:
type: app
service: whoami
version: v1
template:
metadata:
labels:
type: app
service: whoami
version: v1
spec:
containers:
- name: whoami
image: subicura/whoami:1
livenessProbe:
httpGet:
path: /
port: 4567
---
apiVersion: v1
kind: Service
metadata:
name: whoami-v1
spec:
ports:
- port: 4567
protocol: TCP
selector:
type: app
service: whoami
version: v1
[ec2-user@ip-10-0-1-231 ~]$ kubectl apply -f guide-03/task-05/whoami-v1.yml
deployment.apps/whoami-v1 created
service/whoami-v1 created
# whoami-v1가 만들어진 것을 볼 수 있다.
[ec2-user@ip-10-0-1-231 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/redis-b6fd45ccc-lcg7j 1/1 Running 0 92m
pod/whoami-676d78bbf8-8m29n 1/1 Running 0 68m
pod/whoami-v1-54588fd7-fm7hb 1/1 Running 0 27s
pod/whoami-v1-54588fd7-wt6lq 1/1 Running 0 27s
pod/whoami-v1-54588fd7-n6vk6 1/1 Running 0 27s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 26h
service/redis ClusterIP 10.43.3.112 <none> 6379/TCP 92m
service/whoami NodePort 10.43.85.165 <none> 4567:30135/TCP 33m
service/whoami-v1 ClusterIP 10.43.220.236 <none> 4567/TCP 27s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/redis 1/1 1 1 92m
deployment.apps/whoami 1/1 1 1 68m
deployment.apps/whoami-v1 3/3 3 3 27s
NAME DESIRED CURRENT READY AGE
replicaset.apps/redis-b6fd45ccc 1 1 1 92m
replicaset.apps/whoami-676d78bbf8 1 1 1 68m
replicaset.apps/whoami-v1-54588fd7 3 3 3 27s
# 그러면 아까 만든 ingress가 whoami-v1을 바라볼테니까 웹브라우저에서
# 다시한번 v1.whoami.3.35.175.198.sslip.io 로 접속해본다.
# 그러면 whoami-v1-54588fd7-n6vk6 와 같은 메세지가 나오는 것을 확인할 수 있다.
# 새로 고침을 할때마다 whoami-v1-54588fd7-wt6lq whoami-v1-54588fd7-fm7hb 이런식으로 세개가 번갈아가면서
# 나올 것이다. 왜냐하면 pod을 세개 띄웠기 때문에 ingress는 세개의 pod을 바라보는 서비스로 접속을 한거고
# 그래서 새로고침을 할때마다 세개의 팟이 내부적으로 번갈아가면서 접속이 되는 것을 확인할 수 있다.