Update ACI liveness/readiness probe handling to work with named ports (#333)
* Update ACI liveness/readiness probe handling to work with named ports
This commit is contained in:
committed by
Brian Goff
parent
ceb9b16c5c
commit
45d2ef06b2
32
examples/nginx-pod-probes-named-ports.yaml
Normal file
32
examples/nginx-pod-probes-named-ports.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx-named-ports
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx
|
||||
imagePullPolicy: Always
|
||||
name: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: http
|
||||
protocol: TCP
|
||||
- containerPort: 443
|
||||
name: https
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
nodeSelector:
|
||||
kubernetes.io/role: agent
|
||||
beta.kubernetes.io/os: linux
|
||||
type: virtual-kubelet
|
||||
tolerations:
|
||||
- key: virtual-kubelet.io/provider
|
||||
operator: Exists
|
||||
- key: azure.com/aci
|
||||
effect: NoSchedule
|
||||
33
examples/nginx-pod-probes-numbered-ports.yaml
Normal file
33
examples/nginx-pod-probes-numbered-ports.yaml
Normal file
@@ -0,0 +1,33 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx-named-ports
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx
|
||||
imagePullPolicy: Always
|
||||
name: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: http
|
||||
protocol: TCP
|
||||
- containerPort: 443
|
||||
name: https
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 80
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 80
|
||||
dnsPolicy: ClusterFirst
|
||||
nodeSelector:
|
||||
kubernetes.io/role: agent
|
||||
beta.kubernetes.io/os: linux
|
||||
type: virtual-kubelet
|
||||
tolerations:
|
||||
- key: virtual-kubelet.io/provider
|
||||
operator: Exists
|
||||
- key: azure.com/aci
|
||||
effect: NoSchedule
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
clientcmdv1 "k8s.io/client-go/tools/clientcmd/api/v1"
|
||||
"k8s.io/client-go/tools/remotecommand"
|
||||
stats "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1"
|
||||
@@ -58,7 +59,6 @@ const (
|
||||
gpuTypeAnnotation = "virtual-kubelet.io/gpu-type"
|
||||
)
|
||||
|
||||
|
||||
// ACIProvider implements the virtual-kubelet provider interface and communicates with Azure's ACI APIs.
|
||||
type ACIProvider struct {
|
||||
aciClient *aci.Client
|
||||
@@ -1238,7 +1238,7 @@ func (p *ACIProvider) getContainers(pod *v1.Pod) ([]aci.Container, error) {
|
||||
}
|
||||
|
||||
if container.LivenessProbe != nil {
|
||||
probe, err := getProbe(container.LivenessProbe)
|
||||
probe, err := getProbe(container.LivenessProbe, container.Ports)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1246,7 +1246,7 @@ func (p *ACIProvider) getContainers(pod *v1.Pod) ([]aci.Container, error) {
|
||||
}
|
||||
|
||||
if container.ReadinessProbe != nil {
|
||||
probe, err := getProbe(container.ReadinessProbe)
|
||||
probe, err := getProbe(container.ReadinessProbe, container.Ports)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1276,7 +1276,7 @@ func (p *ACIProvider) getGPUSKU(pod *v1.Pod) (aci.GPUSKU, error) {
|
||||
return p.gpuSKUs[0], nil
|
||||
}
|
||||
|
||||
func getProbe(probe *v1.Probe) (*aci.ContainerProbe, error) {
|
||||
func getProbe(probe *v1.Probe, ports []v1.ContainerPort) (*aci.ContainerProbe, error) {
|
||||
|
||||
if probe.Handler.Exec != nil && probe.Handler.HTTPGet != nil {
|
||||
return nil, fmt.Errorf("probe may not specify more than one of \"exec\" and \"httpGet\"")
|
||||
@@ -1298,8 +1298,26 @@ func getProbe(probe *v1.Probe) (*aci.ContainerProbe, error) {
|
||||
|
||||
var httpGET *aci.ContainerHTTPGetProbe
|
||||
if probe.Handler.HTTPGet != nil {
|
||||
var portValue int
|
||||
port := probe.Handler.HTTPGet.Port
|
||||
switch port.Type {
|
||||
case intstr.Int:
|
||||
portValue = port.IntValue()
|
||||
case intstr.String:
|
||||
portName := port.String()
|
||||
for _, p := range ports {
|
||||
if portName == p.Name {
|
||||
portValue = int(p.ContainerPort)
|
||||
break
|
||||
}
|
||||
}
|
||||
if portValue == 0 {
|
||||
return nil, fmt.Errorf("unable to find named port: %s", portName)
|
||||
}
|
||||
}
|
||||
|
||||
httpGET = &aci.ContainerHTTPGetProbe{
|
||||
Port: probe.Handler.HTTPGet.Port.IntValue(),
|
||||
Port: portValue,
|
||||
Path: probe.Handler.HTTPGet.Path,
|
||||
Scheme: string(probe.Handler.HTTPGet.Scheme),
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ func TestCreatePodWithGPU(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Tests create pod with GPU SKU in annotation.
|
||||
// Tests create pod with GPU SKU in annotation.
|
||||
func TestCreatePodWithGPUSKU(t *testing.T) {
|
||||
aadServerMocker := NewAADMock()
|
||||
aciServerMocker := NewACIMock()
|
||||
@@ -803,7 +803,7 @@ func prepareMocks() (*AADMock, *ACIMock, *ACIProvider, error) {
|
||||
return aadServerMocker, aciServerMocker, provider, nil
|
||||
}
|
||||
|
||||
func createTestProvider(aadServerMocker *AADMock, aciServerMocker*ACIMock) (*ACIProvider, error) {
|
||||
func createTestProvider(aadServerMocker *AADMock, aciServerMocker *ACIMock) (*ACIProvider, error) {
|
||||
auth := azure.NewAuthentication(
|
||||
azure.PublicCloud.Name,
|
||||
fakeClientID,
|
||||
@@ -850,6 +850,66 @@ func ptrQuantity(q resource.Quantity) *resource.Quantity {
|
||||
return &q
|
||||
}
|
||||
|
||||
func TestCreatePodWithNamedLivenessProbe(t *testing.T) {
|
||||
_, aciServerMocker, provider, err := prepareMocks()
|
||||
|
||||
if err != nil {
|
||||
t.Fatal("Unable to prepare the mocks", err)
|
||||
}
|
||||
|
||||
podName := "pod-" + uuid.New().String()
|
||||
podNamespace := "ns-" + uuid.New().String()
|
||||
|
||||
aciServerMocker.OnCreate = func(subscription, resourceGroup, containerGroup string, cg *aci.ContainerGroup) (int, interface{}) {
|
||||
assert.Check(t, cg.Containers[0].LivenessProbe != nil, "Liveness probe expected")
|
||||
assert.Check(t, is.Equal(10, cg.Containers[0].LivenessProbe.InitialDelaySeconds), "Initial Probe Delay doesn't match")
|
||||
assert.Check(t, is.Equal(5, cg.Containers[0].LivenessProbe.Period), "Probe Period doesn't match")
|
||||
assert.Check(t, is.Equal(60, cg.Containers[0].LivenessProbe.TimeoutSeconds), "Probe Timeout doesn't match")
|
||||
assert.Check(t, is.Equal(3, cg.Containers[0].LivenessProbe.SuccessThreshold), "Probe Success Threshold doesn't match")
|
||||
assert.Check(t, is.Equal(5, cg.Containers[0].LivenessProbe.FailureThreshold), "Probe Failure Threshold doesn't match")
|
||||
assert.Check(t, cg.Containers[0].LivenessProbe.HTTPGet != nil, "Expected an HTTP Get Probe")
|
||||
assert.Check(t, is.Equal(8080, cg.Containers[0].LivenessProbe.HTTPGet.Port), "Expected Port to be 8080")
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
v1.Container{
|
||||
Name: "nginx",
|
||||
Ports: []v1.ContainerPort{
|
||||
v1.ContainerPort{
|
||||
Name: "http",
|
||||
ContainerPort: 8080,
|
||||
},
|
||||
},
|
||||
LivenessProbe: &v1.Probe{
|
||||
Handler: v1.Handler{
|
||||
HTTPGet: &v1.HTTPGetAction{
|
||||
Port: intstr.FromString("http"),
|
||||
Path: "/",
|
||||
},
|
||||
},
|
||||
InitialDelaySeconds: 10,
|
||||
PeriodSeconds: 5,
|
||||
TimeoutSeconds: 60,
|
||||
SuccessThreshold: 3,
|
||||
FailureThreshold: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := provider.CreatePod(context.Background(), pod); err != nil {
|
||||
t.Fatal("Failed to create pod", err)
|
||||
}
|
||||
|
||||
return http.StatusOK, cg
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreatePodWithLivenessProbe(t *testing.T) {
|
||||
_, aciServerMocker, provider, err := prepareMocks()
|
||||
|
||||
@@ -891,7 +951,7 @@ func TestCreatePodWithLivenessProbe(t *testing.T) {
|
||||
LivenessProbe: &v1.Probe{
|
||||
Handler: v1.Handler{
|
||||
HTTPGet: &v1.HTTPGetAction{
|
||||
Port: intstr.FromString("8080"),
|
||||
Port: intstr.FromInt(8080),
|
||||
Path: "/",
|
||||
},
|
||||
},
|
||||
@@ -952,7 +1012,7 @@ func TestCreatePodWithReadinessProbe(t *testing.T) {
|
||||
ReadinessProbe: &v1.Probe{
|
||||
Handler: v1.Handler{
|
||||
HTTPGet: &v1.HTTPGetAction{
|
||||
Port: intstr.FromString("8080"),
|
||||
Port: intstr.FromInt(8080),
|
||||
Path: "/",
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user