How to change Linux kerner parameters in Azure Kubernetes?

4/6/2020

I have an Azure Kubernetes Cluster with 4 nodes (Linux boxes). I provisioned the AKS cluster using yaml manifests. I want to update the following kernel parameters: net.ipv4.tcp_fin_timeout=30, net.ipv4.ip_local_port_range=1024 65500. The yaml manifest is below. How to update the yaml to include the kernel parameters that I have to change?

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: jmeter-slaves
  labels:
    jmeter_mode: slave
spec:
  replicas: 1
  selector:
    matchLabels:
      jmeter_mode: slave
  template:
    metadata:
      labels:
        jmeter_mode: slave
    spec:
      securityContext:
        sysctls:
        - name: net.ipv4.ip_local_port_range
          value: "1024 65500"
      containers:
      - name: jmslave
        image: prabhaharanv/jmeter-slave:latest
        command: ["/jmeter/apache-jmeter-$(JMETERVERSION)/bin/jmeter-server"]
        args: ["-Dserver.rmi.ssl.keystore.file /jmeter/apache-jmeter-$(JMETERVERSION)/bin/rmi_keystore.jks","-Djava.rmi.server.hostname=$(MY_POD_IP)", "-Dserver.rmi.localport=50000", "-Dserver_port=1099"]
        resources:
          limits:
            cpu: "1"
          requests:
            cpu: "0.5"
        imagePullPolicy: Always
        ports:
        - containerPort: 1099
        - containerPort: 50000
        env:
          - name: MY_POD_IP
            valueFrom:
              fieldRef:
                fieldPath: status.podIP
          - name: JMETERVERSION
            value: "5.1.1"

---

apiVersion: v1
kind: Service
metadata:
  name: jmeter-slaves-svc
  labels:
    jmeter_mode: slave
spec:
  clusterIP: None
  ports:
    - port: 1099
      name: first
      targetPort: 1099
    - port: 50000
      name: second
      targetPort: 50000
  selector:
    jmeter_mode: slave

---
-- prabhaharan
azure-kubernetes
kubernetes
linux-kernel
yaml

1 Answer

4/6/2020

Take a look at this official kubernetes documentation section. There is all the information you need to set the mentioned kernel parameters or using different terminology - sysctls, in your Pod.

Note that there are so called safe and unsafe sysctls.

As to setting net.ipv4.ip_local_port_range=1024 65500, it is considered as safe one and you can set it for your Pod using a securityContext like below without a need to reconfigure the kubelet on your node:

apiVersion: v1
kind: Pod
metadata:
  name: sysctl-example
spec:
  securityContext:
    sysctls:
    - name: net.ipv4.ip_local_port_range
      value: "1024 65500"
    - name: net.ipv4.tcp_fin_timeout
      value: "30"
  ...

However if you try to set this way also net.ipv4.tcp_fin_timeout you'll see plenty of failed attempts to create a Pod with the status SysctlForbidden:

kubectl get pods
...
nginx-deployment-668d699fd8-zlvdm   0/1     SysctlForbidden   0          31s
nginx-deployment-668d699fd8-ztzpr   0/1     SysctlForbidden   0          58s
nginx-deployment-668d699fd8-zx4vq   0/1     SysctlForbidden   0          24s
...

It happens because net.ipv4.tcp_fin_timeout is an unsafe sysctl which needs to be explicitely allowed on node level by reconfiguring your kubelet.

To allow it you need to edit your kubelet configuration, specifically add one more option to those with which it is already started. You will typically find those options in file /etc/default/kubelet. You simply need to add one more:

--allowed-unsafe-sysctls 'net.ipv4.tcp_fin_timeout'

and restart your kubelet:

systemctl restart kubelet.service

Once net.ipv4.tcp_fin_timeout is allowed on node level, you can set it the same way as any safe sysctls i.e. via securityContext in your Pod specification.

-- mario
Source: StackOverflow