1.3 Configuration
After the initial installation, we can start configuring the cluster. Because of the extended use of operators, nearly everything in OpenShift 4 is configured via custom resources. In some cases configmaps or templates are used, but this is clearly the minority.
Most of the configuration is done post-installation and can be used to better adapt the cluster to its environment or change its default behaviour. We are going to configure our own kubelet arguments and change the default project template in order to automatically create some NetworkPolicy resources.
Task 1.3.1: Configure kubelet arguments
OpenShift lets us change the kubelet configuration via the custom resource KubeletConfig.
But why change it at all?
The default kubelet configuration doesn’t reserve any memory or cpu for the kubelet or the operating system itself. It also defines an eviction threshold which, in some cases, is too low for the kubelet to react fast enough.
Configure a KubeletConfig resource each for master and worker nodes defining the following parameters:
- Set a hard eviction threshold to 500Mi available memory
- Set the reserved kubelet resources to 250m cpu and 1Gi memory
- Set the reserved system resources to 250m cpu and 1Gi memory
You can find relevant information on the OpenShift documentation pages here and here .
Hints
Change the masters’ configuration to this:
apiVersion: machineconfiguration.openshift.io/v1
kind: KubeletConfig
metadata:
name: master
spec:
kubeletConfig:
evictionHard:
memory.available: 500Mi
kubeReserved:
cpu: 250m
memory: 1Gi
systemReserved:
cpu: 250m
memory: 1Gi
machineConfigPoolSelector:
matchLabels:
'pools.operator.machineconfiguration.openshift.io/master': ''
And the worker nodes’ configuration to this:
apiVersion: machineconfiguration.openshift.io/v1
kind: KubeletConfig
metadata:
name: worker
spec:
kubeletConfig:
evictionHard:
memory.available: 500Mi
kubeReserved:
cpu: 250m
memory: 1Gi
systemReserved:
cpu: 250m
memory: 1Gi
machineConfigPoolSelector:
matchLabels:
'pools.operator.machineconfiguration.openshift.io/worker': ''
Note
Instead of defining specific systemReserved values, you could also simply supply a line defining .spec.autoSizingReserved: true.
That way OpenShift calculates recommended values for you.
Note
These resource files are also available at https://raw.githubusercontent.com/acend/openshift-operations-training/main/content/en/docs/01/resources/kubeletconfig_master.yaml and https://raw.githubusercontent.com/acend/openshift-operations-training/main/content/en/docs/01/resources/kubeletconfig_worker.yaml , respectively.
There are multiple possible ways to apply these configuration resources to the cluster. We are going to use one of the quickest methods and apply via URL:
oc apply -f https://raw.githubusercontent.com/acend/openshift-operations-training/main/content/en/docs/01/resources/kubeletconfig_master.yaml
oc apply -f https://raw.githubusercontent.com/acend/openshift-operations-training/main/content/en/docs/01/resources/kubeletconfig_worker.yaml
To learn more about kubelet configuration, check the Kubernetes and OpenShift documentation .
Task 1.3.2: Generate the default project template
When creating a new project using oc new-project, OpenShift instantiates a template using the information provided.
We can modify this template if we want to alter it or add more resources, such as NetworkPolicies or LimitRanges.
And this is exactly what you are going to do first of all:
Generate the default template according to the documentation
and change its name to project-request-extended.
Note
You might want to change the filename the template is written to to something more meaningful than what is used in the documentation (template.yaml).
A good practice is to use a naming convention such as <resource type>_<resource name>.yaml.
This allows you to quickly find the resource definition you’re looking for based on the filename in case it is part of a larger collection.Hints
Simply execute the command from the documentation with a slight change to the filename (according to the tip above):
oc adm create-bootstrap-project-template -o yaml > template_project-request-extended.yaml
Open the file using your favorite editor and change the name:
kind: Template
metadata:
creationTimestamp: null
name: project-request-extended
objects:
[...]
Task 1.3.3: Network policies
Now, what you usually want to ensure first on a new cluster is that the different namespaces are isolated from each other in terms of network traffic. User A’s pods in project A should not be able to directly talk to user B’s pods in project B. Except of course for certain use cases, but thanks to the flexibility of network policies, we can easily define a sane default and change it on a namespace-basis if necessary.
Add the necessary network policies to the default project template. A sane default is already provided by Red Hat in its documentation .
Hints
Your file should now look like this:
Note
For your convenience, we also provide a file containing all network policies at https://raw.githubusercontent.com/acend/openshift-operations-training/main/content/en/docs/01/resources/networkpolicies.yaml .
Note
Pay extra attention to the additional metadata.namespace fields added to the NetworkPolicy resources.
If you don’t add them, the network policies might end up being created in another namespace.
Note
Also note the additional namespace definition (openshift-config) at the top of the resource definition.
This is to make sure the template is going to be created in the correct namespace where OpenShift will be looking for it.
apiVersion: template.openshift.io/v1
kind: Template
metadata:
creationTimestamp: null
name: project-request-extended
namespace: openshift-config
objects:
- apiVersion: project.openshift.io/v1
kind: Project
metadata:
annotations:
openshift.io/description: ${PROJECT_DESCRIPTION}
openshift.io/display-name: ${PROJECT_DISPLAYNAME}
openshift.io/requester: ${PROJECT_REQUESTING_USER}
creationTimestamp: null
name: ${PROJECT_NAME}
spec: {}
status: {}
- apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: null
name: admin
namespace: ${PROJECT_NAME}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: ${PROJECT_ADMIN_USER}
- apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-openshift-ingress
namespace: ${PROJECT_NAME}
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
policy-group.network.openshift.io/ingress: ""
podSelector: {}
policyTypes:
- Ingress
- apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-openshift-monitoring
namespace: ${PROJECT_NAME}
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
network.openshift.io/policy-group: monitoring
podSelector: {}
policyTypes:
- Ingress
- apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-namespace
namespace: ${PROJECT_NAME}
spec:
podSelector:
ingress:
- from:
- podSelector: {}
- apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-kube-apiserver-operator
namespace: ${PROJECT_NAME}
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-kube-apiserver-operator
podSelector:
matchLabels:
app: kube-apiserver-operator
policyTypes:
- Ingress
parameters:
- name: PROJECT_NAME
- name: PROJECT_DISPLAYNAME
- name: PROJECT_DESCRIPTION
- name: PROJECT_ADMIN_USER
- name: PROJECT_REQUESTING_USER
Task 1.3.4: Limit range
Limit ranges are very important in keeping the resource usage on the cluster in check. In this training, we assume you already know about limit ranges. If not, the documentation provides a good foundation.
A good starting point could look as follows:
apiVersion: v1
kind: LimitRange
metadata:
name: limitrange
spec:
limits:
- default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 10m
memory: 32Mi
type: Container
Add the LimitRange resource to your default project template.
Hints
Your project template should now look like this:
apiVersion: template.openshift.io/v1
kind: Template
metadata:
name: project-request-extended
namespace: openshift-config
objects:
- apiVersion: project.openshift.io/v1
kind: Project
metadata:
annotations:
openshift.io/description: ${PROJECT_DESCRIPTION}
openshift.io/display-name: ${PROJECT_DISPLAYNAME}
openshift.io/requester: ${PROJECT_REQUESTING_USER}
name: ${PROJECT_NAME}
spec: {}
status: {}
- apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: admin
namespace: ${PROJECT_NAME}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: ${PROJECT_ADMIN_USER}
- apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-openshift-ingress
namespace: ${PROJECT_NAME}
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
policy-group.network.openshift.io/ingress: ""
podSelector: {}
policyTypes:
- Ingress
- apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-openshift-monitoring
namespace: ${PROJECT_NAME}
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
network.openshift.io/policy-group: monitoring
podSelector: {}
policyTypes:
- Ingress
- apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-namespace
namespace: ${PROJECT_NAME}
spec:
podSelector:
ingress:
- from:
- podSelector: {}
- apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-kube-apiserver-operator
namespace: ${PROJECT_NAME}
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: openshift-kube-apiserver-operator
podSelector:
matchLabels:
app: kube-apiserver-operator
policyTypes:
- Ingress
- apiVersion: v1
kind: LimitRange
metadata:
name: limitrange
namespace: ${PROJECT_NAME}
spec:
limits:
- default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 10m
memory: 32Mi
type: Container
parameters:
- name: PROJECT_NAME
- name: PROJECT_DISPLAYNAME
- name: PROJECT_DESCRIPTION
- name: PROJECT_ADMIN_USER
- name: PROJECT_REQUESTING_USER
Task 1.3.5: Configure the template
The only thing missing now is to configure the cluster to use the new template.
Create the template and configure all necessary resources so new projects use our custom template.
Note
You might want to have another look at the different documentation pages so you don’t forget anything.When you think everything is set up, create a new project and check that the NetworkPolicy and LimitRange resources were created automatically.
Hints
Create the template on the cluster by either using your own template:
oc apply -f template_project-request-extended.yaml
Or use our provided solution:
oc apply -f https://raw.githubusercontent.com/acend/openshift-operations-training/main/content/en/docs/01/resources/template_project-request-extended.yaml
And finally, we need to configure the Project custom resource:
oc patch project.config.openshift.io cluster --type=merge --patch '{"spec": {"projectRequestTemplate": {"name": "project-request-extended"}}}'
Task 1.3.6: Console URL
You probably already noticed the quite unwieldy console URL https://console-openshift-console.apps.+username+-ops-training.openshift.ch . It’s among a number of other route hostnames that are created by OpenShift this way by default.
Because the console URL is the one we probably will use the most, we are going to simplify it. Find the appropriate instructions in OpenShift’s documentation and adapt the route name.
Hints
The proper way is to edit the ingress config resource:
oc edit ingress.config.openshift.io cluster
Append the componentRoutes part so your resource looks similar to the example below:
apiVersion: config.openshift.io/v1
kind: Ingress
metadata:
name: cluster
spec:
componentRoutes:
- name: console
namespace: openshift-console
hostname: console.apps.+username+-ops-training.openshift.ch
domain: apps.+username+-ops-training.openshift.ch
[...]