무한 루프 또는 교착 상태로 인해 애플리케이션이 응답을 중지하는 경우가 있으며, 이러한 경우 애플리케이션을 다시 시작할 수 있도록 하려면 애플리케이션 내 감지에 의존하지 않고 애플리케이션의 상태를 확인하는 메커니즘이 필요합니다.
K8s는 주로 이 메커니즘을 대상으로 하는 세 가지 프로브를 제공합니다.
-
Liveness probe : 컨테이너가 실행 중인지 확인하는 데 사용됩니다. 활동성 프로브가 실패하면 K8s는 컨테이너가 죽은 것으로 간주하고 컨테이너를 다시 시작하려고 시도합니다.
-
준비 프로브 : 컨테이너가 트래픽을 수신할 준비가 되었는지 확인하는 데 사용됩니다. 컨테이너가 준비되지 않은 경우 K8s는 트래픽을 해당 컨테이너로 라우팅하지 않습니다.
-
프로브 시작 : 컨테이너가 시작되었는지 확인하는 데 사용됩니다. 활동성 프로브와 달리 시작 프로브는 컨테이너가 실행되는 동안 계속 실행되는 것이 아니라 컨테이너가 시작될 때 한 번 실행됩니다.
프로브 확인 방법
-
exec : 컨테이너에서 지정된 명령을 실행하여 명령이 종료될 때 반환되는 상태 코드를 확인하고 반환된 상태 코드는 정상을 나타내는 0입니다.
-
httpGet : 컨테이너의 IP 주소, 포트, URL 경로에 GET 요청을 보내고 응답의 상태 코드가 200~399 사이이면 정상임을 의미합니다.
-
tcpSocket : 컨테이너의 IP 주소와 TCP에 지정된 포트를 확인하고 포트가 열려 있으면 TCP 소켓 설정에 성공한 것이므로 정상입니다.
구성 항목
-
initialDelaySeconds : 프로브 검사를 시작하기 전에 정의한 시간 동안 기다립니다.
-
periodSeconds : 프로브의 간격 시간
-
timeoutSeconds : 프로브의 시간 초과 기간으로 정의한 시간을 초과하면 실패로 간주됩니다.
-
successThreshold : 프로브의 최소 연속 성공 횟수
-
failureThreshold : 프로브에 대한 최소 연속 실패 수
프로브 시작
apiVersion: v1 # 必选 API的版本号
kind: Pod # 必选 类型Pod
metadata: # 必选 元数据
name: nginx # 必选 符合RFC 1035规范的Pod名称
#namespace: default # 可选 Pod所在的命名空间 不指定默认为default 可以使用-n指定namespace
labels: # 可选 标签选择器 一般用于过滤和区分Pod
app: nginx-ready
spec: # 必选 用于定义容器的详细信息
containers: # 必选 容器列表
- name: nginx # 必选 符合RFC 1035规范的容器名称
image: nginx:latest # 必选 容器所用的镜像的地址
imagePullPolicy: Always # 可选 镜像拉取策略 IfNotPresent:如果宿主机有这个镜像,就不用拉取了 Always:总是拉取 Never:不管存在不存在,都不拉取
ports: # 可选 容器需要暴露的端口号列表
- name: http # 端口名称
containerPort: 80 # 端口号
protocol: TCP # 端口协议 默认TCP
startupProbe: # 可选 检测容器内进程是否完成启动 注意三种检查方式同时只能使用一种
failureThreshold: 3 # 失败三次算探针失败
exec:
command: ['/bin/sh','-c','echo Hello World']
initialDelaySeconds: 3 # 容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 2 # 对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 1 # 对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 1 # 成功1次算探针OK
failureThreshold: 3 # 失败三次算探针失败
restartPolicy: Always # 可选 默认Always 容器故障或者没有启动成功 自动重启该容器 Onfailure: 容器以不为0的状态码终止 自动重启该容器 Never:无论何种状态 都不会重启
# kubectl apply -f pod.yaml
pod/nginx created
# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 0/1 ContainerCreating 0 4s
# kubectl describe pod nginx
준비 프로브
# grep -v '^#' pod.yaml
apiVersion: v1 # 必选 API的版本号
kind: Pod # 必选 类型Pod
metadata: # 必选 元数据
name: nginx # 必选 符合RFC 1035规范的Pod名称
#namespace: default # 可选 Pod所在的命名空间 不指定默认为default 可以使用-n指定namespace
labels: # 可选 标签选择器 一般用于过滤和区分Pod
app: nginx-ready
spec: # 必选 用于定义容器的详细信息
containers: # 必选 容器列表
- name: nginx # 必选 符合RFC 1035规范的容器名称
image: nginx:latest # 必选 容器所用的镜像的地址
imagePullPolicy: Always # 可选 镜像拉取策略 IfNotPresent:如果宿主机有这个镜像,就不用拉取了 Always:总是拉取 Never:不管存在不存在,都不拉取
ports: # 可选 容器需要暴露的端口号列表
- name: http # 端口名称
containerPort: 80 # 端口号
protocol: TCP # 端口协议 默认TCP
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3 # 容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 2 # 对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 1 # 对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 1 # 成功1次算探针OK
failureThreshold: 3 # 失败三次算探针失败
restartPolicy: Always # 可选 默认Always 容器故障或者没有启动成功 自动重启该容器 Onfailure: 容器以不为0的状态码终止 自动重启该容器 Never:无论何种状态 都不会重启
포트 감지가 정상임을 알 수 있습니다.
트래픽 액세스 확인을 위한 nodeport 유형 추가
# grep -v '^#' pod.yaml
apiVersion: v1 # 必选 API的版本号
kind: Pod # 必选 类型Pod
metadata: # 必选 元数据
name: nginx # 必选 符合RFC 1035规范的Pod名称
#namespace: default # 可选 Pod所在的命名空间 不指定默认为default 可以使用-n指定namespace
labels: # 可选 标签选择器 一般用于过滤和区分Pod
app: nginx-ready
spec: # 必选 用于定义容器的详细信息
containers: # 必选 容器列表
- name: nginx # 必选 符合RFC 1035规范的容器名称
image: nginx:latest # 必选 容器所用的镜像的地址
imagePullPolicy: Always # 可选 镜像拉取策略 IfNotPresent:如果宿主机有这个镜像,就不用拉取了 Always:总是拉取 Never:不管存在不存在,都不拉取
ports: # 可选 容器需要暴露的端口号列表
- name: http # 端口名称
containerPort: 80 # 端口号
protocol: TCP # 端口协议 默认TCP
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3 # 容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 2 # 对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 1 # 对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 1 # 成功1次算探针OK
failureThreshold: 3 # 失败三次算探针失败
restartPolicy: Always # 可选 默认Always 容器故障或者没有启动成功 自动重启该容器 Onfailure: 容器以不为0的状态码终止 自动重启该容器 Never:无论何种状态 都不会重启
---
apiVersion: v1
kind: Service
metadata:
name: ready-nodeport
labels:
name: ready-nodeport
spec:
type: NodePort
ports:
- port: 88
protocol: TCP
targetPort: 80
nodePort: 30880
selector:
app: nginx-ready
액세스 확인
# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 15s
[root@k8s-master01 ~]# kubectl get svc -owide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 72d <none>
ready-nodeport NodePort 10.96.93.159 <none> 88:30880/TCP 20s app=nginx-ready
[root@k8s-master01 ~]# curl http://192.168.10.10:30880
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
프로브 감지 실패를 시뮬레이션하기 위해 httpGet 또는 tcpSocket 포트를 81로 수정하십시오. 감지 실패의 트래픽이 입력에 할당됩니까?
# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 0/1 Running 0 22s
# kubectl get svc -owide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 72d <none>
ready-nodeport NodePort 10.96.115.11 <none> 88:30880/TCP 25s app=nginx-ready
[root@k8s-master01 ~]# curl http://192.168.10.10:30880
curl: (7) Failed connect to 192.168.10.10:30880; 拒绝连接
nginx 보기 설명
포트 81을 사용할 수 없고 준비 상태가 0이지만 포드가 실행 중이고 요청 결과가 연결 거부이며 트래픽 수신이 실패했음을 보여줍니다. 준비 상태 프로브가 실패하면 포드에 트래픽이 주입되지 않습니다.
생존 프로브
# grep -v '^#' pod.yaml
apiVersion: v1 # 必选 API的版本号
kind: Pod # 必选 类型Pod
metadata: # 必选 元数据
name: nginx # 必选 符合RFC 1035规范的Pod名称
#namespace: default # 可选 Pod所在的命名空间 不指定默认为default 可以使用-n指定namespace
labels: # 可选 标签选择器 一般用于过滤和区分Pod
app: nginx-ready
spec: # 必选 用于定义容器的详细信息
containers: # 必选 容器列表
- name: nginx # 必选 符合RFC 1035规范的容器名称
image: nginx:latest # 必选 容器所用的镜像的地址
imagePullPolicy: Always # 可选 镜像拉取策略 IfNotPresent:如果宿主机有这个镜像,就不用拉取了 Always:总是拉取 Never:不管存在不存在,都不拉取
ports: # 可选 容器需要暴露的端口号列表
- name: http # 端口名称
containerPort: 80 # 端口号
protocol: TCP # 端口协议 默认TCP
livenessProbe:
httpGet:
path: /
port: 80
scheme: HTTP
initialDelaySeconds: 3 # 容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 2 # 对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 1 # 对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 1 # 成功1次算探针OK
failureThreshold: 3 # 失败三次算探针失败
restartPolicy: Always # 可选 默认Always 容器故障或者没有启动成功 自动重启该容器 Onfailure: 容器以不为0的状态码终止 自动重启该容器 Never:无论何种状态 都不会重启
---
apiVersion: v1
kind: Service
metadata:
name: ready-nodeport
labels:
name: ready-nodeport
spec:
type: NodePort
ports:
- port: 88
protocol: TCP
targetPort: 80
nodePort: 30880
selector:
app: nginx-ready
팟(Pod) 및 서비스 작성 및 액세스 테스트
# kubectl apply -f pod.yaml
pod/nginx created
service/ready-nodeport created
[root@k8s-master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 4s
# kubectl get svc -owide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 72d <none>
ready-nodeport NodePort 10.96.54.68 <none> 88:30880/TCP 12s app=nginx-ready
[root@k8s-master01 ~]# curl 192.168.10.10:30880
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
감지 포트를 81로 수정하면 시뮬레이션 감지가 실패합니다.
프로브 감지가 실패하면 restartPolicy
다시 시작 정책에 따라 작동합니다.
기본적으로 항상 컨테이너는 실패하거나 성공적으로 시작하지 못한 경우 컨테이너를 자동으로 다시 시작합니다.
포드 재생성
# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 4s
# kubectl get svc -owide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 72d <none>
ready-nodeport NodePort 10.96.54.68 <none> 88:30880/TCP 7m28s app=nginx-ready
# curl http://192.168.10.10:30880
curl: (7) Failed connect to 192.168.10.10:30880; 拒绝连接
Pod가 다시 시작되었는지 확인하면 Pod가 5번 다시 시작되고 상태가 다음과 같이 변경된 것을 확인할 수 있습니다.CrashLoopBackOff
후속 조치
물론 Kubernetes에는 프로브 외에도 컨테이너의 가용성을 보장하기 위한 다음과 같은 메커니즘이 있습니다.
-
RC
또는ReplicaSet
: 지정된 수의 포드가 클러스터에서 실행 중인지 확인하는 데 사용됩니다. Pod가 노드에서 실패하거나 삭제되면 RC 또는 ReplicaSet가 새 Pod를 시작하여 대신합니다. -
배포 : Pod 및 ReplicaSet의 업데이트를 관리하는 데 사용됩니다. 배포는 롤링 업데이트를 수행하는 동안 애플리케이션의 가용성을 보장하고 이전 버전으로 되돌리기 위한 롤백 메커니즘을 제공할 수 있습니다.
-
Service : 실행 중인 Pod로 트래픽을 라우팅하는 데 사용됩니다. 서비스는 애플리케이션에 안정적인 IP 주소와 DNS 이름을 제공하고 필요에 따라 트래픽을 여러 포드에 로드 밸런싱할 수 있습니다.
-
네임스페이스 : 클러스터에서 리소스를 격리하고 구성하는 데 사용됩니다. 네임스페이스를 사용하면 서로 다른 애플리케이션 또는 팀을 격리하고 이들이 액세스할 수 있는 리소스를 제어할 수 있습니다.