{"id":6210,"date":"2019-07-23T05:59:47","date_gmt":"2019-07-23T05:59:47","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=6210"},"modified":"2023-09-28T07:04:46","modified_gmt":"2023-09-28T07:04:46","slug":"how-to-check-containers-health-inside-a-kubernetes-pod-using-livenessprobe","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/how-to-check-containers-health-inside-a-kubernetes-pod-using-livenessprobe\/","title":{"rendered":"How to check Containers health inside a kubernetes pod using livenessProbe?"},"content":{"rendered":"\n<p>A Probe is a diagnostic performed periodically by the kubelet on a Container. To perform a diagnostic, the kubelet calls a Handler implemented by the Container. <strong>There are three types of handlers:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>ExecAction:<\/strong> Executes a specified command inside the Container. The diagnostic is considered successful if the command exits with a status code of 0.<\/li>\n\n\n\n<li><strong>TCPSocketAction:<\/strong> Performs a TCP check against the Container\u2019s IP address on a specified port. The diagnostic is considered successful if the port is open.<\/li>\n\n\n\n<li><strong>HTTPGetAction: <\/strong>Performs an HTTP Get request against the Container\u2019s IP address on a specified port and path. The diagnostic is considered successful if the response has a status code greater than or equal to 200 and less than 400.<\/li>\n\n\n\n<li><\/li>\n<\/ul>\n\n\n\n<p><strong>Each probe has one of three results:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Success: The Container passed the diagnostic.<\/li>\n\n\n\n<li>Failure: The Container failed the diagnostic.<\/li>\n\n\n\n<li>Unknown: The diagnostic failed, so no action should be taken.<\/li>\n<\/ul>\n\n\n\n<p>The kubelet can perform and react to two kinds of probes on running Containers:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>livenessProbe: <\/strong>Indicates whether the Container is running. If the liveness probe fails, the kubelet kills the Container, and the Container is subjected to its restart policy. If a Container does not provide a liveness probe, the default state is Success.<\/li>\n\n\n\n<li><strong>readinessProbe: I<\/strong>ndicates whether the Container is ready to service requests. If the readiness probe fails, the endpoints controller removes the Pod\u2019s IP address from the endpoints of all Services that match the Pod. The default state of readiness before the initial delay is Failure. If a Container does not provide a readiness probe, the default state is Success.<\/li>\n<\/ul>\n\n\n\n<p>In this excercise, I would like to discuss on livenessProbe.<\/p>\n\n\n\n<p><strong>Here is the example for livenessProbe using ExecAction<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">apiVersion: v1\r\n<span class=\"hljs-attr\">kind<\/span>: Pod\r\n<span class=\"hljs-attr\">metadata<\/span>:\r\n  labels:\r\n    test: liveness\r\n  <span class=\"hljs-attr\">name<\/span>: liveness-exec\r\n<span class=\"hljs-attr\">spec<\/span>:\r\n  containers:\r\n  - name: liveness\r\n    <span class=\"hljs-attr\">image<\/span>: registry.k8s.io\/busybox\r\n    <span class=\"hljs-attr\">args<\/span>:\r\n    - <span class=\"hljs-regexp\">\/bin\/<\/span>sh\r\n    - -c\r\n    - touch \/tmp\/healthy; sleep <span class=\"hljs-number\">30<\/span>; rm -f \/tmp\/healthy; sleep <span class=\"hljs-number\">600<\/span>\r\n    <span class=\"hljs-attr\">livenessProbe<\/span>:\r\n      exec:\r\n        command:\r\n        - cat\r\n        - <span class=\"hljs-regexp\">\/tmp\/<\/span>healthy\r\n      <span class=\"hljs-attr\">initialDelaySeconds<\/span>: <span class=\"hljs-number\">5<\/span>\r\n      <span class=\"hljs-attr\">periodSeconds<\/span>: <span class=\"hljs-number\">5<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>Here is the example for livenessProbe using TCPSocketAction<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">apiVersion: v1\nkind: Service\nmetadata:\n  name: wordpress-mysql\n  labels:\n    app: wordpress\nspec:\n  ports:\n    - port: <span class=\"hljs-number\">3306<\/span>\n  selector:\n    app: wordpress\n    tier: mysql\n  clusterIP: None\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: mysql-pv-claim\n  labels:\n    app: wordpress\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: <span class=\"hljs-number\">20<\/span>Gi\n---\napiVersion: apps\/v1 <span class=\"hljs-comment\"># for k8s versions before 1.9.0 use apps\/v1beta2  and before 1.8.0 use extensions\/v1beta1<\/span>\nkind: Deployment\nmetadata:\n  name: wordpress-mysql\n  labels:\n    app: wordpress\nspec:\n  selector:\n    matchLabels:\n      app: wordpress\n      tier: mysql\n  strategy:\n    type: Recreate\n  template:\n    metadata:\n      labels:\n        app: wordpress\n        tier: mysql\n    spec:\n      containers:\n      - image: mysql:<span class=\"hljs-number\">5.6<\/span>\n        name: mysql\n        env:\n        - name: MYSQL_ROOT_PASSWORD\n          valueFrom:\n            secretKeyRef:\n              name: mysql-pass\n              key: password\n        livenessProbe:\n          tcpSocket:\n            port: <span class=\"hljs-number\">3306<\/span>\n        ports:\n        - containerPort: <span class=\"hljs-number\">3306<\/span>\n          name: mysql\n        volumeMounts:\n        - name: mysql-persistent-storage\n          mountPath: \/<span class=\"hljs-keyword\">var<\/span>\/lib\/mysql\n      volumes:\n      - name: mysql-persistent-storage\n        persistentVolumeClaim:\n          claimName: mysql-pv-claim\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Here is the example for livenessProbe using HTTPGetAction<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">apiVersion: v1\nkind: Service\nmetadata:\n  name: nginxsvc\n  labels:\n    app: nginx\nspec:\n  type: NodePort\n  ports:\n  - port: <span class=\"hljs-number\">80<\/span>\n    protocol: TCP\n    name: http\n  - port: <span class=\"hljs-number\">443<\/span>\n    protocol: TCP\n    name: https\n  selector:\n    app: nginx\n---\napiVersion: v1\nkind: ReplicationController\nmetadata:\n  name: my-nginx\nspec:\n  replicas: <span class=\"hljs-number\">1<\/span>\n  template:\n    metadata:\n      labels:\n        app: nginx\n    spec:\n      volumes:\n      - name: secret-volume\n        secret:\n          secretName: nginxsecret\n      - name: configmap-volume\n        configMap:\n          name: nginxconfigmap\n      containers:\n      - name: nginxhttps\n        image: ymqytw\/nginxhttps:<span class=\"hljs-number\">1.5<\/span>\n        command: &#91;<span class=\"hljs-string\">\"\/home\/auto-reload-nginx.sh\"<\/span>]\n        ports:\n        - containerPort: <span class=\"hljs-number\">443<\/span>\n        - containerPort: <span class=\"hljs-number\">80<\/span>\n        livenessProbe:\n          httpGet:\n            path: \/index.html\n            port: <span class=\"hljs-number\">80<\/span>\n          initialDelaySeconds: <span class=\"hljs-number\">30<\/span>\n          timeoutSeconds: <span class=\"hljs-number\">1<\/span>\n        volumeMounts:\n        - mountPath: \/etc\/nginx\/ssl\n          name: secret-volume\n        - mountPath: \/etc\/nginx\/conf.d\n          name: configmap-volume\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-css-opacity\"\/>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">Define a liveness command\napiVersion: v1\nkind: Pod\nmetadata:\n  labels:\n    test: liveness\n  name: liveness-exec\nspec:\n  containers:\n  - name: liveness\n    image: k8s.gcr.io\/busybox\n    args:\n    - \/bin\/sh\n    - -c\n    - touch \/tmp\/healthy; sleep <span class=\"hljs-number\">30<\/span>; rm -rf \/tmp\/healthy; sleep <span class=\"hljs-number\">600<\/span>\n    livenessProbe:\n      exec:\n        command:\n        - cat\n        - \/tmp\/healthy\n      initialDelaySeconds: <span class=\"hljs-number\">5<\/span>\n      periodSeconds: <span class=\"hljs-number\">5<\/span>\n\nDefine a liveness HTTP request\napiVersion: v1\nkind: Pod\nmetadata:\n  labels:\n    test: liveness\n  name: liveness-http\nspec:\n  containers:\n  - name: liveness\n    image: k8s.gcr.io\/liveness\n    args:\n    - \/server\n    livenessProbe:\n      httpGet:\n        path: \/healthz\n        port: <span class=\"hljs-number\">8080<\/span>\n        httpHeaders:\n        - name: X-Custom-Header\n          value: Awesome\n      initialDelaySeconds: <span class=\"hljs-number\">3<\/span>\n      periodSeconds: <span class=\"hljs-number\">3<\/span>\n\n\n\nHere is the configuration file <span class=\"hljs-keyword\">for<\/span> the Pod:\napiVersion: v1\nkind: Pod\nmetadata:\n  labels:\n    test: liveness\n  name: liveness-exec\nspec:\n  containers:\n  - name: liveness\n    image: k8s.gcr.io\/busybox\n    args:\n    - \/bin\/sh\n    - -c\n    - touch \/tmp\/healthy; sleep <span class=\"hljs-number\">30<\/span>; rm -rf \/tmp\/healthy; sleep <span class=\"hljs-number\">600<\/span>\n    livenessProbe:\n      exec:\n        command:\n        - cat\n        - \/tmp\/healthy\n      initialDelaySeconds: <span class=\"hljs-number\">5<\/span>\n      periodSeconds: <span class=\"hljs-number\">5<\/span>\n\nHere is an example config <span class=\"hljs-keyword\">for<\/span> a Pod with an HTTP health check\napiVersion: v1\nkind: Pod\nmetadata:\n  name: pod-with-http-healthcheck\nspec:\n  containers:\n  - name: nginx\n    image: nginx\n    <span class=\"hljs-comment\"># defines the health checking<\/span>\n    livenessProbe:\n      <span class=\"hljs-comment\"># an http probe<\/span>\n      httpGet:\n        path: \/_status\/healthz\n        port: <span class=\"hljs-number\">80<\/span>\n      <span class=\"hljs-comment\"># length of time to wait for a pod to initialize<\/span>\n      <span class=\"hljs-comment\"># after pod startup, before applying health checking<\/span>\n      initialDelaySeconds: <span class=\"hljs-number\">30<\/span>\n      timeoutSeconds: <span class=\"hljs-number\">1<\/span>\n    ports:\n    - containerPort: <span class=\"hljs-number\">80<\/span>\n\n<span class=\"hljs-keyword\">And<\/span> here is an example config <span class=\"hljs-keyword\">for<\/span> a Pod with a TCP Socket health check\napiVersion: v1\nkind: Pod\nmetadata:\n  name: pod-with-tcp-socket-healthcheck\nspec:\n  containers:\n  - name: redis\n    image: redis\n    <span class=\"hljs-comment\"># defines the health checking<\/span>\n    livenessProbe:\n      <span class=\"hljs-comment\"># a TCP socket probe<\/span>\n      tcpSocket:\n        port: <span class=\"hljs-number\">6379<\/span>\n      <span class=\"hljs-comment\"># length of time to wait for a pod to initialize<\/span>\n      <span class=\"hljs-comment\"># after pod startup, before applying health checking<\/span>\n      initialDelaySeconds: <span class=\"hljs-number\">30<\/span>\n      timeoutSeconds: <span class=\"hljs-number\">1<\/span>\n    ports:\n    - containerPort: <span class=\"hljs-number\">6379<\/span>\n\napiVersion: extensions\/v1beta1\nkind: Deployment\nmetadata:\n  name: helloworld-deployment\nspec:\n  replicas: <span class=\"hljs-number\">3<\/span>\n  template:\n    metadata:\n      labels:\n        app: helloworld\n    spec:\n      containers:\n      - name: k8s-demo\n        image: wardviaene\/k8s-demo\n        ports:\n        - name: nodejs-port\n          containerPort: <span class=\"hljs-number\">3000<\/span>\n        livenessProbe:\n          httpGet:\n            path: \/\n            port: nodejs-port\n          initialDelaySeconds: <span class=\"hljs-number\">15<\/span>\n          timeoutSeconds: <span class=\"hljs-number\">30<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>","protected":false},"excerpt":{"rendered":"<p>A Probe is a diagnostic performed periodically by the kubelet on a Container. To perform a diagnostic, the kubelet calls a Handler implemented by the Container. There are three types of handlers: Each probe has one of three results: The kubelet can perform and react to two kinds of probes on running Containers: In this&#8230;<\/p>\n","protected":false},"author":1,"featured_media":7916,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","_joinchat":[],"footnotes":""},"categories":[4859],"tags":[1194,5449,4860,5543,5566],"class_list":["post-6210","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-kubernetes","tag-container","tag-devopsschool","tag-kubernetes","tag-pod","tag-probe"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/6210","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=6210"}],"version-history":[{"count":3,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/6210\/revisions"}],"predecessor-version":[{"id":40525,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/6210\/revisions\/40525"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media\/7916"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=6210"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=6210"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=6210"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}