mirror of https://github.com/k3s-io/k3s
Add httpHeaders to httpGet liveness probe
Also update existing documentation and try to steer users away from 'host'. Add validation.pull/6/head
parent
faa0fc3d8c
commit
a2d1bb7acf
|
@ -15902,11 +15902,36 @@
|
|||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"description": "Host name to connect to, defaults to the pod IP."
|
||||
"description": "Host name to connect to, defaults to the pod IP. You probably want to set \"Host\" in httpHeaders instead."
|
||||
},
|
||||
"scheme": {
|
||||
"type": "string",
|
||||
"description": "Scheme to use for connecting to the host. Defaults to HTTP."
|
||||
},
|
||||
"httpHeaders": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "v1.HTTPHeader"
|
||||
},
|
||||
"description": "Custom headers to set in the request. HTTP allows repeated headers."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.HTTPHeader": {
|
||||
"id": "v1.HTTPHeader",
|
||||
"description": "HTTPHeader describes a custom header to be used in HTTP probes",
|
||||
"required": [
|
||||
"name",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The header field name"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The header field value"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -4781,11 +4781,36 @@
|
|||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"description": "Host name to connect to, defaults to the pod IP."
|
||||
"description": "Host name to connect to, defaults to the pod IP. You probably want to set \"Host\" in httpHeaders instead."
|
||||
},
|
||||
"scheme": {
|
||||
"type": "string",
|
||||
"description": "Scheme to use for connecting to the host. Defaults to HTTP."
|
||||
},
|
||||
"httpHeaders": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "v1.HTTPHeader"
|
||||
},
|
||||
"description": "Custom headers to set in the request. HTTP allows repeated headers."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.HTTPHeader": {
|
||||
"id": "v1.HTTPHeader",
|
||||
"description": "HTTPHeader describes a custom header to be used in HTTP probes",
|
||||
"required": [
|
||||
"name",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The header field name"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The header field value"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -893,6 +893,47 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_httpheader">v1.HTTPHeader</h3>
|
||||
<div class="paragraph">
|
||||
<p>HTTPHeader describes a custom header to be used in HTTP probes</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">name</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The header field name</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">value</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The header field value</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_horizontalpodautoscalerstatus">v1beta1.HorizontalPodAutoscalerStatus</h3>
|
||||
|
@ -1562,7 +1603,7 @@ Both these may change in the future. Incoming requests are matched against the h
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">host</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Host name to connect to, defaults to the pod IP.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
|
@ -1574,6 +1615,13 @@ Both these may change in the future. Incoming requests are matched against the h
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">httpHeaders</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Custom headers to set in the request. HTTP allows repeated headers.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_httpheader">v1.HTTPHeader</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
@ -4838,7 +4886,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
|||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2016-02-05 15:52:54 UTC
|
||||
Last updated 2016-02-05 16:19:07 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -3432,6 +3432,89 @@ The resulting set of endpoints can be viewed as:<br>
|
|||
<div class="sect2">
|
||||
<h3 id="_v1_capability">v1.Capability</h3>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_podstatus">v1.PodStatus</h3>
|
||||
<div class="paragraph">
|
||||
<p>PodStatus represents information about the status of a pod. Status may trail the actual state of a system.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">phase</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Current condition of the pod. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-phase">http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-phase</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">conditions</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Current service state of pod. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions">http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_podcondition">v1.PodCondition</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">message</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">A human readable message indicating details about why the pod is in this condition.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">reason</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">A brief CamelCase message indicating details about why the pod is in this state. e.g. <em>OutOfDisk</em></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">hostIP</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">IP address of the host to which the pod is assigned. Empty if not yet scheduled.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">podIP</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">IP address allocated to the pod. Routable at least within the cluster. Empty if not yet allocated.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">startTime</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">RFC 3339 date and time at which the object was acknowledged by the Kubelet. This is before the Kubelet pulled the container image(s) for the pod.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">containerStatuses</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The list has one entry per container in the manifest. Each entry is currently the output of <code>docker inspect</code>. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-statuses">http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-statuses</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_containerstatus">v1.ContainerStatus</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_limitrange">v1.LimitRange</h3>
|
||||
|
@ -3528,89 +3611,6 @@ The resulting set of endpoints can be viewed as:<br>
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_podstatus">v1.PodStatus</h3>
|
||||
<div class="paragraph">
|
||||
<p>PodStatus represents information about the status of a pod. Status may trail the actual state of a system.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">phase</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Current condition of the pod. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-phase">http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-phase</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">conditions</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Current service state of pod. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions">http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_podcondition">v1.PodCondition</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">message</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">A human readable message indicating details about why the pod is in this condition.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">reason</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">A brief CamelCase message indicating details about why the pod is in this state. e.g. <em>OutOfDisk</em></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">hostIP</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">IP address of the host to which the pod is assigned. Empty if not yet scheduled.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">podIP</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">IP address allocated to the pod. Routable at least within the cluster. Empty if not yet allocated.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">startTime</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">RFC 3339 date and time at which the object was acknowledged by the Kubelet. This is before the Kubelet pulled the container image(s) for the pod.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">containerStatuses</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The list has one entry per container in the manifest. Each entry is currently the output of <code>docker inspect</code>. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-statuses">http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-statuses</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_containerstatus">v1.ContainerStatus</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_podspec">v1.PodSpec</h3>
|
||||
|
@ -4520,6 +4520,47 @@ The resulting set of endpoints can be viewed as:<br>
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_httpheader">v1.HTTPHeader</h3>
|
||||
<div class="paragraph">
|
||||
<p>HTTPHeader describes a custom header to be used in HTTP probes</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">name</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The header field name</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">value</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The header field value</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_fcvolumesource">v1.FCVolumeSource</h3>
|
||||
|
@ -4759,7 +4800,7 @@ The resulting set of endpoints can be viewed as:<br>
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">host</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Host name to connect to, defaults to the pod IP.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
|
@ -4771,6 +4812,13 @@ The resulting set of endpoints can be viewed as:<br>
|
|||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">httpHeaders</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Custom headers to set in the request. HTTP allows repeated headers.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_httpheader">v1.HTTPHeader</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
@ -7268,7 +7316,7 @@ The resulting set of endpoints can be viewed as:<br>
|
|||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2016-02-01 21:08:06 UTC
|
||||
Last updated 2016-02-02 15:03:04 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -66,11 +66,14 @@ The [http-liveness.yaml](http-liveness.yaml) demonstrates the HTTP check.
|
|||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
httpHeaders:
|
||||
- name: X-Custom-Header
|
||||
value: Awesome
|
||||
initialDelaySeconds: 15
|
||||
timeoutSeconds: 1
|
||||
```
|
||||
|
||||
The Kubelet sends an HTTP request to the specified path and port to perform the health check. If you take a look at image/server.go, you will see the server starts to respond with an error code 500 after 10 seconds, so the check fails. The Kubelet sends the probe to the container's ip address by default which could be specified with `host` as part of httpGet probe. If the container listens on `127.0.0.1`, `host` should be specified as `127.0.0.1`. In general, if the container listens on its ip address or on all interfaces (0.0.0.0), there is no need to specify the `host` as part of the httpGet probe.
|
||||
The Kubelet sends an HTTP request to the specified path and port to perform the health check. If you take a look at image/server.go, you will see the server starts to respond with an error code 500 after 10 seconds, so the check fails. The Kubelet sends probes to the container's IP address, unless overridden by the optional `host` field in httpGet. If the container listens on `127.0.0.1` and `hostNetwork` is `true` (i.e., it does not use the pod-specific network), then `host` should be specified as `127.0.0.1`. Be warned that, outside of less common cases like that, `host` does probably not result in what you would expect. If you set it to a non-existing hostname (or your competitor's!), probes will never reach the pod, defeating the whole point of health checks. If your pod relies on e.g. virtual hosts, which is probably the more common case, you should not use `host`, but rather set the `Host` header in `httpHeaders`.
|
||||
|
||||
This [guide](../walkthrough/k8s201.md#health-checking) has more information on health checks.
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@ spec:
|
|||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
httpHeaders:
|
||||
- name: X-Custom-Header
|
||||
value: Awesome
|
||||
initialDelaySeconds: 15
|
||||
timeoutSeconds: 1
|
||||
name: liveness
|
||||
|
|
|
@ -76,6 +76,7 @@ func init() {
|
|||
DeepCopy_api_GitRepoVolumeSource,
|
||||
DeepCopy_api_GlusterfsVolumeSource,
|
||||
DeepCopy_api_HTTPGetAction,
|
||||
DeepCopy_api_HTTPHeader,
|
||||
DeepCopy_api_Handler,
|
||||
DeepCopy_api_HostPathVolumeSource,
|
||||
DeepCopy_api_ISCSIVolumeSource,
|
||||
|
@ -930,6 +931,23 @@ func DeepCopy_api_HTTPGetAction(in HTTPGetAction, out *HTTPGetAction, c *convers
|
|||
}
|
||||
out.Host = in.Host
|
||||
out.Scheme = in.Scheme
|
||||
if in.HTTPHeaders != nil {
|
||||
in, out := in.HTTPHeaders, &out.HTTPHeaders
|
||||
*out = make([]HTTPHeader, len(in))
|
||||
for i := range in {
|
||||
if err := DeepCopy_api_HTTPHeader(in[i], &(*out)[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.HTTPHeaders = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func DeepCopy_api_HTTPHeader(in HTTPHeader, out *HTTPHeader, c *conversion.Cloner) error {
|
||||
out.Name = in.Name
|
||||
out.Value = in.Value
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -752,16 +752,27 @@ type SecretKeySelector struct {
|
|||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
// HTTPHeader describes a custom header to be used in HTTP probes
|
||||
type HTTPHeader struct {
|
||||
// The header field name
|
||||
Name string `json:"name"`
|
||||
// The header field value
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// HTTPGetAction describes an action based on HTTP Get requests.
|
||||
type HTTPGetAction struct {
|
||||
// Optional: Path to access on the HTTP server.
|
||||
Path string `json:"path,omitempty"`
|
||||
// Required: Name or number of the port to access on the container.
|
||||
Port intstr.IntOrString `json:"port,omitempty"`
|
||||
// Optional: Host name to connect to, defaults to the pod IP.
|
||||
// Optional: Host name to connect to, defaults to the pod IP. You
|
||||
// probably want to set "Host" in httpHeaders instead.
|
||||
Host string `json:"host,omitempty"`
|
||||
// Optional: Scheme to use for connecting to the host, defaults to HTTP.
|
||||
Scheme URIScheme `json:"scheme,omitempty"`
|
||||
// Optional: Custom headers to set in the request. HTTP allows repeated headers.
|
||||
HTTPHeaders []HTTPHeader `json:"httpHeaders,omitempty"`
|
||||
}
|
||||
|
||||
// URIScheme identifies the scheme used for connection to a host for Get actions
|
||||
|
|
|
@ -977,6 +977,16 @@ func autoConvert_api_HTTPGetAction_To_v1_HTTPGetAction(in *api.HTTPGetAction, ou
|
|||
}
|
||||
out.Host = in.Host
|
||||
out.Scheme = URIScheme(in.Scheme)
|
||||
if in.HTTPHeaders != nil {
|
||||
out.HTTPHeaders = make([]HTTPHeader, len(in.HTTPHeaders))
|
||||
for i := range in.HTTPHeaders {
|
||||
if err := Convert_api_HTTPHeader_To_v1_HTTPHeader(&in.HTTPHeaders[i], &out.HTTPHeaders[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.HTTPHeaders = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -984,6 +994,19 @@ func Convert_api_HTTPGetAction_To_v1_HTTPGetAction(in *api.HTTPGetAction, out *H
|
|||
return autoConvert_api_HTTPGetAction_To_v1_HTTPGetAction(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_api_HTTPHeader_To_v1_HTTPHeader(in *api.HTTPHeader, out *HTTPHeader, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*api.HTTPHeader))(in)
|
||||
}
|
||||
out.Name = in.Name
|
||||
out.Value = in.Value
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_api_HTTPHeader_To_v1_HTTPHeader(in *api.HTTPHeader, out *HTTPHeader, s conversion.Scope) error {
|
||||
return autoConvert_api_HTTPHeader_To_v1_HTTPHeader(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_api_Handler_To_v1_Handler(in *api.Handler, out *Handler, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*api.Handler))(in)
|
||||
|
@ -4155,6 +4178,16 @@ func autoConvert_v1_HTTPGetAction_To_api_HTTPGetAction(in *HTTPGetAction, out *a
|
|||
}
|
||||
out.Host = in.Host
|
||||
out.Scheme = api.URIScheme(in.Scheme)
|
||||
if in.HTTPHeaders != nil {
|
||||
out.HTTPHeaders = make([]api.HTTPHeader, len(in.HTTPHeaders))
|
||||
for i := range in.HTTPHeaders {
|
||||
if err := Convert_v1_HTTPHeader_To_api_HTTPHeader(&in.HTTPHeaders[i], &out.HTTPHeaders[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.HTTPHeaders = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -4162,6 +4195,19 @@ func Convert_v1_HTTPGetAction_To_api_HTTPGetAction(in *HTTPGetAction, out *api.H
|
|||
return autoConvert_v1_HTTPGetAction_To_api_HTTPGetAction(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_HTTPHeader_To_api_HTTPHeader(in *HTTPHeader, out *api.HTTPHeader, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*HTTPHeader))(in)
|
||||
}
|
||||
out.Name = in.Name
|
||||
out.Value = in.Value
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_HTTPHeader_To_api_HTTPHeader(in *HTTPHeader, out *api.HTTPHeader, s conversion.Scope) error {
|
||||
return autoConvert_v1_HTTPHeader_To_api_HTTPHeader(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_Handler_To_api_Handler(in *Handler, out *api.Handler, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*Handler))(in)
|
||||
|
@ -6279,6 +6325,7 @@ func init() {
|
|||
autoConvert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource,
|
||||
autoConvert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource,
|
||||
autoConvert_api_HTTPGetAction_To_v1_HTTPGetAction,
|
||||
autoConvert_api_HTTPHeader_To_v1_HTTPHeader,
|
||||
autoConvert_api_Handler_To_v1_Handler,
|
||||
autoConvert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource,
|
||||
autoConvert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource,
|
||||
|
@ -6405,6 +6452,7 @@ func init() {
|
|||
autoConvert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource,
|
||||
autoConvert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource,
|
||||
autoConvert_v1_HTTPGetAction_To_api_HTTPGetAction,
|
||||
autoConvert_v1_HTTPHeader_To_api_HTTPHeader,
|
||||
autoConvert_v1_Handler_To_api_Handler,
|
||||
autoConvert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource,
|
||||
autoConvert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource,
|
||||
|
|
|
@ -749,6 +749,22 @@ func deepCopy_v1_HTTPGetAction(in HTTPGetAction, out *HTTPGetAction, c *conversi
|
|||
}
|
||||
out.Host = in.Host
|
||||
out.Scheme = in.Scheme
|
||||
if in.HTTPHeaders != nil {
|
||||
out.HTTPHeaders = make([]HTTPHeader, len(in.HTTPHeaders))
|
||||
for i := range in.HTTPHeaders {
|
||||
if err := deepCopy_v1_HTTPHeader(in.HTTPHeaders[i], &out.HTTPHeaders[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.HTTPHeaders = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_HTTPHeader(in HTTPHeader, out *HTTPHeader, c *conversion.Cloner) error {
|
||||
out.Name = in.Name
|
||||
out.Value = in.Value
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -2576,6 +2592,7 @@ func init() {
|
|||
deepCopy_v1_GitRepoVolumeSource,
|
||||
deepCopy_v1_GlusterfsVolumeSource,
|
||||
deepCopy_v1_HTTPGetAction,
|
||||
deepCopy_v1_HTTPHeader,
|
||||
deepCopy_v1_Handler,
|
||||
deepCopy_v1_HostPathVolumeSource,
|
||||
deepCopy_v1_ISCSIVolumeSource,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -877,6 +877,14 @@ type SecretKeySelector struct {
|
|||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
// HTTPHeader describes a custom header to be used in HTTP probes
|
||||
type HTTPHeader struct {
|
||||
// The header field name
|
||||
Name string `json:"name"`
|
||||
// The header field value
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// HTTPGetAction describes an action based on HTTP Get requests.
|
||||
type HTTPGetAction struct {
|
||||
// Path to access on the HTTP server.
|
||||
|
@ -885,11 +893,14 @@ type HTTPGetAction struct {
|
|||
// Number must be in the range 1 to 65535.
|
||||
// Name must be an IANA_SVC_NAME.
|
||||
Port intstr.IntOrString `json:"port"`
|
||||
// Host name to connect to, defaults to the pod IP.
|
||||
// Host name to connect to, defaults to the pod IP. You probably want to set
|
||||
// "Host" in httpHeaders instead.
|
||||
Host string `json:"host,omitempty"`
|
||||
// Scheme to use for connecting to the host.
|
||||
// Defaults to HTTP.
|
||||
Scheme URIScheme `json:"scheme,omitempty"`
|
||||
// Custom headers to set in the request. HTTP allows repeated headers.
|
||||
HTTPHeaders []HTTPHeader `json:"httpHeaders,omitempty"`
|
||||
}
|
||||
|
||||
// URIScheme identifies the scheme used for connection to a host for Get actions
|
||||
|
|
|
@ -509,17 +509,28 @@ func (GlusterfsVolumeSource) SwaggerDoc() map[string]string {
|
|||
}
|
||||
|
||||
var map_HTTPGetAction = map[string]string{
|
||||
"": "HTTPGetAction describes an action based on HTTP Get requests.",
|
||||
"path": "Path to access on the HTTP server.",
|
||||
"port": "Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME.",
|
||||
"host": "Host name to connect to, defaults to the pod IP.",
|
||||
"scheme": "Scheme to use for connecting to the host. Defaults to HTTP.",
|
||||
"": "HTTPGetAction describes an action based on HTTP Get requests.",
|
||||
"path": "Path to access on the HTTP server.",
|
||||
"port": "Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME.",
|
||||
"host": "Host name to connect to, defaults to the pod IP. You probably want to set \"Host\" in httpHeaders instead.",
|
||||
"scheme": "Scheme to use for connecting to the host. Defaults to HTTP.",
|
||||
"httpHeaders": "Custom headers to set in the request. HTTP allows repeated headers.",
|
||||
}
|
||||
|
||||
func (HTTPGetAction) SwaggerDoc() map[string]string {
|
||||
return map_HTTPGetAction
|
||||
}
|
||||
|
||||
var map_HTTPHeader = map[string]string{
|
||||
"": "HTTPHeader describes a custom header to be used in HTTP probes",
|
||||
"name": "The header field name",
|
||||
"value": "The header field value",
|
||||
}
|
||||
|
||||
func (HTTPHeader) SwaggerDoc() map[string]string {
|
||||
return map_HTTPHeader
|
||||
}
|
||||
|
||||
var map_Handler = map[string]string{
|
||||
"": "Handler defines a specific action that should be taken",
|
||||
"exec": "One and only one of the following should be specified. Exec specifies the action to take.",
|
||||
|
|
|
@ -1128,6 +1128,11 @@ func validateHTTPGetAction(http *api.HTTPGetAction, fldPath *field.Path) field.E
|
|||
if !supportedSchemes.Has(string(http.Scheme)) {
|
||||
allErrors = append(allErrors, field.Invalid(fldPath.Child("scheme"), http.Scheme, fmt.Sprintf("must be one of %v", supportedSchemes.List())))
|
||||
}
|
||||
for _, header := range http.HTTPHeaders {
|
||||
if !validation.IsHTTPHeaderName(header.Name) {
|
||||
allErrors = append(allErrors, field.Invalid(fldPath.Child("httpHeaders"), header.Name, fmt.Sprintf("name must match %s", validation.HTTPHeaderNameFmt)))
|
||||
}
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
|
|
|
@ -1082,6 +1082,8 @@ func TestValidateHandler(t *testing.T) {
|
|||
{HTTPGet: &api.HTTPGetAction{Path: "/", Port: intstr.FromInt(1), Host: "", Scheme: "HTTP"}},
|
||||
{HTTPGet: &api.HTTPGetAction{Path: "/foo", Port: intstr.FromInt(65535), Host: "host", Scheme: "HTTP"}},
|
||||
{HTTPGet: &api.HTTPGetAction{Path: "/", Port: intstr.FromString("port"), Host: "", Scheme: "HTTP"}},
|
||||
{HTTPGet: &api.HTTPGetAction{Path: "/", Port: intstr.FromString("port"), Host: "", Scheme: "HTTP", HTTPHeaders: []api.HTTPHeader{{"Host", "foo.example.com"}}}},
|
||||
{HTTPGet: &api.HTTPGetAction{Path: "/", Port: intstr.FromString("port"), Host: "", Scheme: "HTTP", HTTPHeaders: []api.HTTPHeader{{"X-Forwarded-For", "1.2.3.4"}, {"X-Forwarded-For", "5.6.7.8"}}}},
|
||||
}
|
||||
for _, h := range successCases {
|
||||
if errs := validateHandler(&h, field.NewPath("field")); len(errs) != 0 {
|
||||
|
@ -1095,6 +1097,8 @@ func TestValidateHandler(t *testing.T) {
|
|||
{HTTPGet: &api.HTTPGetAction{Path: "", Port: intstr.FromInt(0), Host: ""}},
|
||||
{HTTPGet: &api.HTTPGetAction{Path: "/foo", Port: intstr.FromInt(65536), Host: "host"}},
|
||||
{HTTPGet: &api.HTTPGetAction{Path: "", Port: intstr.FromString(""), Host: ""}},
|
||||
{HTTPGet: &api.HTTPGetAction{Path: "/", Port: intstr.FromString("port"), Host: "", Scheme: "HTTP", HTTPHeaders: []api.HTTPHeader{{"Host:", "foo.example.com"}}}},
|
||||
{HTTPGet: &api.HTTPGetAction{Path: "/", Port: intstr.FromString("port"), Host: "", Scheme: "HTTP", HTTPHeaders: []api.HTTPHeader{{"X_Forwarded_For", "foo.example.com"}}}},
|
||||
}
|
||||
for _, h := range errorCases {
|
||||
if errs := validateHandler(&h, field.NewPath("field")); len(errs) == 0 {
|
||||
|
|
|
@ -502,6 +502,16 @@ func autoConvert_api_HTTPGetAction_To_v1_HTTPGetAction(in *api.HTTPGetAction, ou
|
|||
}
|
||||
out.Host = in.Host
|
||||
out.Scheme = v1.URIScheme(in.Scheme)
|
||||
if in.HTTPHeaders != nil {
|
||||
out.HTTPHeaders = make([]v1.HTTPHeader, len(in.HTTPHeaders))
|
||||
for i := range in.HTTPHeaders {
|
||||
if err := Convert_api_HTTPHeader_To_v1_HTTPHeader(&in.HTTPHeaders[i], &out.HTTPHeaders[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.HTTPHeaders = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -509,6 +519,19 @@ func Convert_api_HTTPGetAction_To_v1_HTTPGetAction(in *api.HTTPGetAction, out *v
|
|||
return autoConvert_api_HTTPGetAction_To_v1_HTTPGetAction(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_api_HTTPHeader_To_v1_HTTPHeader(in *api.HTTPHeader, out *v1.HTTPHeader, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*api.HTTPHeader))(in)
|
||||
}
|
||||
out.Name = in.Name
|
||||
out.Value = in.Value
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_api_HTTPHeader_To_v1_HTTPHeader(in *api.HTTPHeader, out *v1.HTTPHeader, s conversion.Scope) error {
|
||||
return autoConvert_api_HTTPHeader_To_v1_HTTPHeader(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_api_Handler_To_v1_Handler(in *api.Handler, out *v1.Handler, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*api.Handler))(in)
|
||||
|
@ -1764,6 +1787,16 @@ func autoConvert_v1_HTTPGetAction_To_api_HTTPGetAction(in *v1.HTTPGetAction, out
|
|||
}
|
||||
out.Host = in.Host
|
||||
out.Scheme = api.URIScheme(in.Scheme)
|
||||
if in.HTTPHeaders != nil {
|
||||
out.HTTPHeaders = make([]api.HTTPHeader, len(in.HTTPHeaders))
|
||||
for i := range in.HTTPHeaders {
|
||||
if err := Convert_v1_HTTPHeader_To_api_HTTPHeader(&in.HTTPHeaders[i], &out.HTTPHeaders[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.HTTPHeaders = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1771,6 +1804,19 @@ func Convert_v1_HTTPGetAction_To_api_HTTPGetAction(in *v1.HTTPGetAction, out *ap
|
|||
return autoConvert_v1_HTTPGetAction_To_api_HTTPGetAction(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_HTTPHeader_To_api_HTTPHeader(in *v1.HTTPHeader, out *api.HTTPHeader, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*v1.HTTPHeader))(in)
|
||||
}
|
||||
out.Name = in.Name
|
||||
out.Value = in.Value
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_HTTPHeader_To_api_HTTPHeader(in *v1.HTTPHeader, out *api.HTTPHeader, s conversion.Scope) error {
|
||||
return autoConvert_v1_HTTPHeader_To_api_HTTPHeader(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_Handler_To_api_Handler(in *v1.Handler, out *api.Handler, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*v1.Handler))(in)
|
||||
|
@ -5132,6 +5178,7 @@ func init() {
|
|||
autoConvert_api_GitRepoVolumeSource_To_v1_GitRepoVolumeSource,
|
||||
autoConvert_api_GlusterfsVolumeSource_To_v1_GlusterfsVolumeSource,
|
||||
autoConvert_api_HTTPGetAction_To_v1_HTTPGetAction,
|
||||
autoConvert_api_HTTPHeader_To_v1_HTTPHeader,
|
||||
autoConvert_api_Handler_To_v1_Handler,
|
||||
autoConvert_api_HostPathVolumeSource_To_v1_HostPathVolumeSource,
|
||||
autoConvert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource,
|
||||
|
@ -5237,6 +5284,7 @@ func init() {
|
|||
autoConvert_v1_GitRepoVolumeSource_To_api_GitRepoVolumeSource,
|
||||
autoConvert_v1_GlusterfsVolumeSource_To_api_GlusterfsVolumeSource,
|
||||
autoConvert_v1_HTTPGetAction_To_api_HTTPGetAction,
|
||||
autoConvert_v1_HTTPHeader_To_api_HTTPHeader,
|
||||
autoConvert_v1_Handler_To_api_Handler,
|
||||
autoConvert_v1_HostPathVolumeSource_To_api_HostPathVolumeSource,
|
||||
autoConvert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource,
|
||||
|
|
|
@ -392,6 +392,22 @@ func deepCopy_v1_HTTPGetAction(in v1.HTTPGetAction, out *v1.HTTPGetAction, c *co
|
|||
}
|
||||
out.Host = in.Host
|
||||
out.Scheme = in.Scheme
|
||||
if in.HTTPHeaders != nil {
|
||||
out.HTTPHeaders = make([]v1.HTTPHeader, len(in.HTTPHeaders))
|
||||
for i := range in.HTTPHeaders {
|
||||
if err := deepCopy_v1_HTTPHeader(in.HTTPHeaders[i], &out.HTTPHeaders[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.HTTPHeaders = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_HTTPHeader(in v1.HTTPHeader, out *v1.HTTPHeader, c *conversion.Cloner) error {
|
||||
out.Name = in.Name
|
||||
out.Value = in.Value
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1967,6 +1983,7 @@ func init() {
|
|||
deepCopy_v1_GitRepoVolumeSource,
|
||||
deepCopy_v1_GlusterfsVolumeSource,
|
||||
deepCopy_v1_HTTPGetAction,
|
||||
deepCopy_v1_HTTPHeader,
|
||||
deepCopy_v1_Handler,
|
||||
deepCopy_v1_HostPathVolumeSource,
|
||||
deepCopy_v1_ISCSIVolumeSource,
|
||||
|
|
|
@ -59,7 +59,7 @@ func (server *Server) DoServerCheck(prober httpprober.HTTPProber) (probe.Result,
|
|||
}
|
||||
url := utilnet.FormatURL(scheme, server.Addr, server.Port, server.Path)
|
||||
|
||||
result, data, err := prober.Probe(url, probeTimeOut)
|
||||
result, data, err := prober.Probe(url, nil, probeTimeOut)
|
||||
|
||||
if err != nil {
|
||||
return probe.Unknown, "", err
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/probe"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
@ -32,7 +33,7 @@ type fakeHttpProber struct {
|
|||
err error
|
||||
}
|
||||
|
||||
func (f *fakeHttpProber) Probe(*url.URL, time.Duration) (probe.Result, string, error) {
|
||||
func (f *fakeHttpProber) Probe(*url.URL, http.Header, time.Duration) (probe.Result, string, error) {
|
||||
return f.result, f.body, f.err
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package prober
|
|||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -126,6 +127,16 @@ func (pb *prober) runProbeWithRetries(p *api.Probe, pod *api.Pod, status api.Pod
|
|||
return result, output, err
|
||||
}
|
||||
|
||||
// buildHeaderMap takes a list of HTTPHeader <name, value> string
|
||||
// pairs and returns a a populated string->[]string http.Header map.
|
||||
func buildHeader(headerList []api.HTTPHeader) http.Header {
|
||||
headers := make(http.Header)
|
||||
for _, header := range headerList {
|
||||
headers[header.Name] = append(headers[header.Name], header.Value)
|
||||
}
|
||||
return headers
|
||||
}
|
||||
|
||||
func (pb *prober) runProbe(p *api.Probe, pod *api.Pod, status api.PodStatus, container api.Container, containerID kubecontainer.ContainerID) (probe.Result, string, error) {
|
||||
timeout := time.Duration(p.TimeoutSeconds) * time.Second
|
||||
if p.Exec != nil {
|
||||
|
@ -145,7 +156,9 @@ func (pb *prober) runProbe(p *api.Probe, pod *api.Pod, status api.PodStatus, con
|
|||
path := p.HTTPGet.Path
|
||||
glog.V(4).Infof("HTTP-Probe Host: %v://%v, Port: %v, Path: %v", scheme, host, port, path)
|
||||
url := formatURL(scheme, host, port, path)
|
||||
return pb.http.Probe(url, timeout)
|
||||
headers := buildHeader(p.HTTPGet.HTTPHeaders)
|
||||
glog.V(4).Infof("HTTP-Probe Headers: %v", headers)
|
||||
return pb.http.Probe(url, headers, timeout)
|
||||
}
|
||||
if p.TCPSocket != nil {
|
||||
port, err := extractPort(p.TCPSocket.Port, container)
|
||||
|
|
|
@ -19,6 +19,8 @@ package prober
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
|
@ -164,6 +166,33 @@ func TestGetTCPAddrParts(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestHTTPHeaders(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input []api.HTTPHeader
|
||||
output http.Header
|
||||
}{
|
||||
{[]api.HTTPHeader{}, http.Header{}},
|
||||
{[]api.HTTPHeader{
|
||||
{"X-Muffins-Or-Cupcakes", "Muffins"},
|
||||
}, http.Header{"X-Muffins-Or-Cupcakes": {"Muffins"}}},
|
||||
{[]api.HTTPHeader{
|
||||
{"X-Muffins-Or-Cupcakes", "Muffins"},
|
||||
{"X-Muffins-Or-Plumcakes", "Muffins!"},
|
||||
}, http.Header{"X-Muffins-Or-Cupcakes": {"Muffins"},
|
||||
"X-Muffins-Or-Plumcakes": {"Muffins!"}}},
|
||||
{[]api.HTTPHeader{
|
||||
{"X-Muffins-Or-Cupcakes", "Muffins"},
|
||||
{"X-Muffins-Or-Cupcakes", "Cupcakes, too"},
|
||||
}, http.Header{"X-Muffins-Or-Cupcakes": {"Muffins", "Cupcakes, too"}}},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
headers := buildHeader(test.input)
|
||||
if !reflect.DeepEqual(test.output, headers) {
|
||||
t.Errorf("Expected %#v, got %#v", test.output, headers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProbe(t *testing.T) {
|
||||
prober := &prober{
|
||||
refManager: kubecontainer.NewRefManager(),
|
||||
|
|
|
@ -36,7 +36,7 @@ func New() HTTPProber {
|
|||
}
|
||||
|
||||
type HTTPProber interface {
|
||||
Probe(url *url.URL, timeout time.Duration) (probe.Result, string, error)
|
||||
Probe(url *url.URL, headers http.Header, timeout time.Duration) (probe.Result, string, error)
|
||||
}
|
||||
|
||||
type httpProber struct {
|
||||
|
@ -44,20 +44,26 @@ type httpProber struct {
|
|||
}
|
||||
|
||||
// Probe returns a ProbeRunner capable of running an http check.
|
||||
func (pr httpProber) Probe(url *url.URL, timeout time.Duration) (probe.Result, string, error) {
|
||||
return DoHTTPProbe(url, &http.Client{Timeout: timeout, Transport: pr.transport})
|
||||
func (pr httpProber) Probe(url *url.URL, headers http.Header, timeout time.Duration) (probe.Result, string, error) {
|
||||
return DoHTTPProbe(url, headers, &http.Client{Timeout: timeout, Transport: pr.transport})
|
||||
}
|
||||
|
||||
type HTTPGetInterface interface {
|
||||
Get(u string) (*http.Response, error)
|
||||
Do(req *http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
// DoHTTPProbe checks if a GET request to the url succeeds.
|
||||
// If the HTTP response code is successful (i.e. 400 > code >= 200), it returns Success.
|
||||
// If the HTTP response code is unsuccessful or HTTP communication fails, it returns Failure.
|
||||
// This is exported because some other packages may want to do direct HTTP probes.
|
||||
func DoHTTPProbe(url *url.URL, client HTTPGetInterface) (probe.Result, string, error) {
|
||||
res, err := client.Get(url.String())
|
||||
func DoHTTPProbe(url *url.URL, headers http.Header, client HTTPGetInterface) (probe.Result, string, error) {
|
||||
req, err := http.NewRequest("GET", url.String(), nil)
|
||||
if err != nil {
|
||||
// Convert errors into failures to catch timeouts.
|
||||
return probe.Failure, err.Error(), nil
|
||||
}
|
||||
req.Header = headers
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
// Convert errors into failures to catch timeouts.
|
||||
return probe.Failure, err.Error(), nil
|
||||
|
|
|
@ -42,8 +42,8 @@ func containsAny(s string, substrs []string) bool {
|
|||
}
|
||||
|
||||
func TestHTTPProbeChecker(t *testing.T) {
|
||||
handleReq := func(s int, body string) func(w http.ResponseWriter) {
|
||||
return func(w http.ResponseWriter) {
|
||||
handleReq := func(s int, body string) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(s)
|
||||
w.Write([]byte(body))
|
||||
}
|
||||
|
@ -51,8 +51,9 @@ func TestHTTPProbeChecker(t *testing.T) {
|
|||
|
||||
prober := New()
|
||||
testCases := []struct {
|
||||
handler func(w http.ResponseWriter)
|
||||
health probe.Result
|
||||
handler func(w http.ResponseWriter, r *http.Request)
|
||||
reqHeaders http.Header
|
||||
health probe.Result
|
||||
// go1.5: error message changed for timeout, need to support
|
||||
// both old and new
|
||||
accBodies []string
|
||||
|
@ -60,18 +61,41 @@ func TestHTTPProbeChecker(t *testing.T) {
|
|||
// The probe will be filled in below. This is primarily testing that an HTTP GET happens.
|
||||
{
|
||||
handleReq(http.StatusOK, "ok body"),
|
||||
nil,
|
||||
probe.Success,
|
||||
[]string{"ok body"},
|
||||
},
|
||||
{
|
||||
// Echo handler that returns the contents of request headers in the body
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(200)
|
||||
output := ""
|
||||
for k, arr := range r.Header {
|
||||
for _, v := range arr {
|
||||
output += fmt.Sprintf("%s: %s\n", k, v)
|
||||
}
|
||||
}
|
||||
w.Write([]byte(output))
|
||||
},
|
||||
http.Header{
|
||||
"X-Muffins-Or-Cupcakes": {"muffins"},
|
||||
},
|
||||
probe.Success,
|
||||
[]string{
|
||||
"X-Muffins-Or-Cupcakes: muffins",
|
||||
},
|
||||
},
|
||||
{
|
||||
handleReq(FailureCode, "fail body"),
|
||||
nil,
|
||||
probe.Failure,
|
||||
[]string{fmt.Sprintf("HTTP probe failed with statuscode: %d", FailureCode)},
|
||||
},
|
||||
{
|
||||
func(w http.ResponseWriter) {
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
time.Sleep(3 * time.Second)
|
||||
},
|
||||
nil,
|
||||
probe.Failure,
|
||||
[]string{
|
||||
"use of closed network connection",
|
||||
|
@ -82,7 +106,7 @@ func TestHTTPProbeChecker(t *testing.T) {
|
|||
for _, test := range testCases {
|
||||
// TODO: Close() this when fix #19254
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
test.handler(w)
|
||||
test.handler(w, r)
|
||||
}))
|
||||
u, err := url.Parse(server.URL)
|
||||
if err != nil {
|
||||
|
@ -96,7 +120,7 @@ func TestHTTPProbeChecker(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
health, output, err := prober.Probe(u, 1*time.Second)
|
||||
health, output, err := prober.Probe(u, test.reqHeaders, 1*time.Second)
|
||||
if test.health == probe.Unknown && err == nil {
|
||||
t.Errorf("Expected error")
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/apiserver"
|
||||
"k8s.io/kubernetes/pkg/probe"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
@ -36,7 +37,7 @@ type fakeHttpProber struct {
|
|||
err error
|
||||
}
|
||||
|
||||
func (f *fakeHttpProber) Probe(*url.URL, time.Duration) (probe.Result, string, error) {
|
||||
func (f *fakeHttpProber) Probe(*url.URL, http.Header, time.Duration) (probe.Result, string, error) {
|
||||
return f.result, f.body, f.err
|
||||
}
|
||||
|
||||
|
|
|
@ -167,3 +167,13 @@ var percentRegexp = regexp.MustCompile("^" + percentFmt + "$")
|
|||
func IsValidPercent(percent string) bool {
|
||||
return percentRegexp.MatchString(percent)
|
||||
}
|
||||
|
||||
const HTTPHeaderNameFmt string = "[-A-Za-z0-9]+"
|
||||
|
||||
var httpHeaderNameRegexp = regexp.MustCompile("^" + HTTPHeaderNameFmt + "$")
|
||||
|
||||
// IsHTTPHeaderName checks that a string conforms to the Go HTTP library's
|
||||
// definition of a valid header field name (a stricter subset than RFC7230).
|
||||
func IsHTTPHeaderName(value string) bool {
|
||||
return httpHeaderNameRegexp.MatchString(value)
|
||||
}
|
||||
|
|
|
@ -308,3 +308,30 @@ func TestIsValidIP(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsHTTPHeaderName(t *testing.T) {
|
||||
goodValues := []string{
|
||||
// Common ones
|
||||
"Accept-Encoding", "Host", "If-Modified-Since", "X-Forwarded-For",
|
||||
// Weirdo, but still conforming names
|
||||
"a", "ab", "abc", "a1", "-a", "a-", "a-b", "a-1", "a--1--2--b", "--abc-123",
|
||||
"A", "AB", "AbC", "A1", "-A", "A-", "A-B", "A-1", "A--1--2--B", "--123-ABC",
|
||||
}
|
||||
for _, val := range goodValues {
|
||||
if !IsHTTPHeaderName(val) {
|
||||
t.Errorf("expected true for '%s'", val)
|
||||
}
|
||||
}
|
||||
|
||||
badValues := []string{
|
||||
"Host:", "X-Forwarded-For:", "X-@Home",
|
||||
"", "_", "a_", "_a", "1_", "1_2", ".", "a.", ".a", "a.b", "1.", ".1", "1.2",
|
||||
" ", "a ", " a", "a b", "1 ", " 1", "1 2", "#a#", "^", ",", ";", "=", "<",
|
||||
"?", "@", "{",
|
||||
}
|
||||
for _, val := range badValues {
|
||||
if IsHTTPHeaderName(val) {
|
||||
t.Errorf("expected false for '%s'", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue