47 How to Write Kubernetes Resource Definition Files #
Hello, I’m Kong Lingfei.
In the next 48 lessons, I will introduce how to deploy IAM applications based on Tencent Cloud EKS. EKS is actually a standard Kubernetes cluster. To deploy applications in a Kubernetes cluster, you need to write YAML (Yet Another Markup Language) definition files for Kubernetes resources, such as Service, Deployment, ConfigMap, Secret, StatefulSet, and so on.
These YAML definition files have many configuration options that we need to configure, and some of them may be difficult to understand. In order to make it easier for you to learn in the next lesson, let’s first learn how to write Kubernetes YAML files.
Why choose the YAML format to define Kubernetes resources? #
First of all, let’s explain why we use the YAML format to define various types of resources in Kubernetes. This is because compared to other formats such as XML and JSON, YAML not only supports rich data, but also has a clear structure, clear hierarchy, strong expressiveness, and is easy to maintain. It is very suitable for developers to configure and manage Kubernetes resources.
In fact, Kubernetes supports both YAML and JSON formats. JSON format is usually used as the data format for message transmission between interfaces, while YAML format is used for resource configuration and management. YAML and JSON formats can be converted between each other. You can use online tools like json2yaml to automatically convert YAML and JSON data formats.
For example, here is the content of a YAML file:
apiVersion: v1
kind: Service
metadata:
name: iam-apiserver
spec:
clusterIP: 192.168.0.231
externalTrafficPolicy: Cluster
ports:
- name: https
nodePort: 30443
port: 8443
protocol: TCP
targetPort: 8443
selector:
app: iam-apiserver
sessionAffinity: None
type: NodePort
The corresponding content in JSON format is:
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "iam-apiserver"
},
"spec": {
"clusterIP": "192.168.0.231",
"externalTrafficPolicy": "Cluster",
"ports": [
{
"name": "https",
"nodePort": 30443,
"port": 8443,
"protocol": "TCP",
"targetPort": 8443
}
],
"selector": {
"app": "iam-apiserver"
},
"sessionAffinity": "None",
"type": "NodePort"
}
}
I used the json2yaml
online tool to convert between YAML and JSON. You can see the screenshot below:
During the process of writing Kubernetes resource definition files, if the indentation of the configuration items in the YAML file is too deep, making it difficult to determine the level of the configuration item, you can convert it to JSON format and use JSON format to determine the hierarchy of the configuration.
If you want to learn more about YAML, you can refer to YAML 1.2 (3rd Edition). Here, let’s take a look at the basic syntax of YAML that I have organized:
- Properties and values are case-sensitive.
- Use indentation to represent the hierarchical relationship.
- Do not use the Tab key for indentation, only use spaces, and it is recommended to use two spaces as the indentation for one level. If elements are left-aligned, it means that the two aligned elements belong to the same level.
- Use
#
for comments until the end of the line. - There should be a space after the colon in the
key: value
format. - A hyphen represents a list item, use a hyphen followed by a space; multiple items use the same indentation level as the same list.
- Use
---
to indicate the beginning of a new YAML file.
Now you know that Kubernetes supports both YAML and JSON formats, and they can be converted between each other. However, considering the advantages of the YAML format, I suggest that you use the YAML format to define various types of resources in Kubernetes.
Overview of Kubernetes Resource Definitions #
There are many built-in resources in Kubernetes, some of which are commonly used, such as Deployment, StatefulSet, ConfigMap, Service, Secret, Nodes, Pods, Events, Jobs, and DaemonSets. In addition, there are other resources in Kubernetes. If the built-in resources in Kubernetes cannot meet your needs, you can also define custom resources.
You can view the list of resources in Kubernetes by executing the following command:
$ kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
In the above output, the meanings of each column are as follows:
- NAME: The name of the resource.
- SHORTNAMES: The shorthand name of the resource.
- APIVERSION: The API version of the resource, also known as the group.
- NAMESPACED: Whether the resource has a Namespace attribute.
- KIND: The category of the resource.
These resources have some common configurations and some specific configurations. Here, let’s first look at the common configurations of these resources.
The following configurations are common to all types of resources in Kubernetes:
---
apiVersion: <string> # A string that specifies the name of the group, it defaults to core. You can use the `kubectl api-versions` command to get all the groups supported by the current Kubernetes version.
kind: <string> # A string that specifies the type of the resource.
metadata: <Object> # The metadata of the resource.
name: <string> # A string that specifies the name of the resource.
namespace: <string> # A string that specifies the namespace the resource belongs to.
labels: <map[string]string> # A map that specifies the labels of the resource.
annotations: <map[string]string> # A map that specifies the annotations of the resource.
selfLink: <string> # The REST API path of the resource, in the format: /api/<group>/namespaces/<namespace>/<type>/<name>. For example: /api/v1/namespaces/default/services/iam-apiserver
spec: <Object> # Defines the desired state of the resource.
status: <Object> # The current status of the resource, displaying the most recent state of the resource in a read-only manner. This field is maintained by Kubernetes and cannot be defined by users.
You can use the kubectl explain <object>
command to view the introduction of the Object resource object, and use kubectl explain <object1>.<object2>
to view the introduction of the <object2>
sub-object of <object1>
, for example:
$ kubectl explain service
$ kubectl explain service.spec
$ kubectl explain service.spec.ports
Kubernetes resource definition YAML files support the following data types:
- string, representing a string type.
- object, representing an object that requires nesting multiple fields.
- map[string]string, representing a mapping consisting of key:value pairs.
- []string, representing a list of strings.
- []object, representing a list of objects.
- boolean, representing a boolean type.
- integer, representing an integer type.
Common Kubernetes Resource Definitions #
As mentioned earlier, there are many resources in Kubernetes, among which Pod, Deployment, Service, and ConfigMap are commonly used resources. Let me introduce each one.
Pod Resource Definition #
Below is a YAML definition for a Pod:
apiVersion: v1 # Required. The version number, commonly used v1 or apps/v1
kind: Pod # Required
metadata: # Required. Metadata
name: string # Required. Name
namespace: string # Required. Namespace. The default is 'default', but it is recommended to create separate namespaces for better security in a production environment
labels: # Optional. Labels (list of values)
- name: string
annotations: # Optional. Annotations (list of values)
- name: string
spec: # Required. Detailed definition of the container
containers: # Required. List of containers
- name: string # Required. Name of the first container
image: string # Required. Image used by the first container
imagePullPolicy: [Always|Never|IfNotPresent] # Optional. Image pull policy. Default is Always
command: [string] # Optional. List of command-line arguments. If not specified, it uses the entrypoint command when the image was built
args: [string] # Optional. List of arguments passed to the command-line
workingDir: string # Optional. Working directory inside the container
volumeMounts: # Optional. Configuration for mounting storage volumes inside the container
- name: string # Optional. Volume name, must match the name defined in [@1]
readOnly: boolean # Optional. Read/write mode. Default is read-write
ports: # Optional. Ports to be exposed
- name: string # Optional. Port name
containerPort: int # Optional. Port number
hostPort: int # Optional. Port number listened by the host machine. Note that multiple pods on the same host cannot have the same port number. It is recommended not to set this value
protocol: [tcp|udp] # Optional. Protocol used by the port. Default is TCP
env: # Optional. Environment variables
- name: string # Optional. Environment variable name
value: string # Optional. Key-value pair for the environment variable
resources: # Optional. Resource limits
limits: # Optional. Maximum resource usage limit for the container. Container will be terminated if it exceeds this value
cpu: string # Optional. CPU resource, in cores starting from 0.1
memory: string # Optional. Memory limit, in MiB or GiB
requests: # Optional. Resources allocated at startup
cpu: string
memory: string
livenessProbe: # Optional. Probe for container health checks
exec: # Command probe
command: [string] # Probe command or script
httpGet: # httpGet probe
path: string # Probe path, e.g., http://ip:port/path
port: number
host: string
scheme: string
httpHeaders:
- name: string
value: string
tcpSocket: # tcpSocket probe, checks if a port exists
port: number
initialDelaySeconds: 0 # Number of seconds to wait after container startup before the first probe, in seconds
timeoutSeconds: 0 # Timeout for probe response. Default is 1 second. If the probe fails, the container is considered unhealthy and will be restarted
periodSeconds: 0 # Probe interval. Default is 10 seconds
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
restartPolicy: [Always|Never|OnFailure] # Restart policy for the container
nodeSelector: object # Specifies the host for running the container
imagePullSecrets: # Secrets name used for container download, must match the one defined in volumes.secret
- name: string
hostNetwork: false
volumes: ## Types of shared storage volumes mounted
- name: string # Optional. [@1]
emptyDir: {}
hostPath:
path: string
secret: # Secret type storage volume, uses the items value inside the secret as environment variables
secretName: string
items:
- key: string
path: string
configMap: ## ConfigMap type storage volume
Note: Please replace the placeholder [@1] with the corresponding value.
name: string
items:
- key: string
path: string
Pod is the most important resource in Kubernetes. We can create a Pod using a Pod YAML definition, or we can create a Pod using DaemonSet, Deployment, ReplicaSet, StatefulSet, Job, or CronJob.
Deployment Resource Definition #
The Deployment resource definition YAML file is as follows:
apiVersion: apps/v1
kind: Deployment
metadata:
labels: # Set labels for the resource
app: iam-apiserver
name: iam-apiserver
namespace: default
spec:
progressDeadlineSeconds: 10 # Specify the time limit for completing rolling updates before failure
replicas: 1 # Declare the number of replicas, recommended >= 2
revisionHistoryLimit: 5 # Set the number of historical versions to retain, default is 10
selector: # Selector
matchLabels: # Match labels
app: iam-apiserver # Label format is key: value pairs
strategy: # Specify the deployment strategy
rollingUpdate:
maxSurge: 1 # The maximum number of additional replicas that can be present, can be a percentage or an integer
maxUnavailable: 1 # The maximum number of Pods that can enter the unavailable state during the update process, can be a percentage or an integer
type: RollingUpdate # Update strategy, including: Recreate, RollingUpdate
template: # Specify the Pod creation template. Note: the following definitions are for Pod resource
metadata: # Specify metadata for the Pod
labels: # Specify labels for the Pod
app: iam-apiserver
spec:
affinity:
podAntiAffinity: # Pod anti-affinity, avoid scheduling the same application to the same Node if possible
preferredDuringSchedulingIgnoredDuringExecution: # Soft requirements
- podAffinityTerm:
labelSelector:
matchExpressions: # Multiple options, only Nodes that satisfy all these conditions can run the Pod
- key: app
operator: In # Set the relationship between label key and a set of values, In, NotIn, Exists, DoesNotExist
values:
- iam-apiserver
topologyKey: kubernetes.io/hostname
weight: 100 # The range of values for the weight field is 1-100.
containers:
- command: # Specify the running command
- /opt/iam/bin/iam-apiserver # Run parameters
- --config=/etc/iam/iam-apiserver.yaml
image: ccr.ccs.tencentyun.com/lkccc/iam-apiserver-amd64:v1.0.6 # Image name, follow the image naming convention
imagePullPolicy: Always # Image pull policy. IfNotPresent: prefer to use local image; Never: use local image, if the local image does not exist, an error will occur; Always: default value, always pull the image
# lifecycle: # Kubernetes supports postStart and preStop events. After a container starts, Kubernetes immediately sends a postStart event; before a container is terminated, Kubernetes sends a preStop event
name: iam-apiserver # Container name, consistent with the application name
ports: # Port settings
- containerPort: 8443 # Port exposed by the container
name: secure # Port name
protocol: TCP # Protocol, TCP or UDP
livenessProbe: # Liveness probe, checks if the container is working properly, restarts the instance if it's not
httpGet: # HTTP request check method
path: /healthz # Request path
port: 8080 # Check port
scheme: HTTP # Check protocol
initialDelaySeconds: 5 # Startup delay, the time delay for the container to start health checks
periodSeconds: 10 # Interval, the time interval for health checks
successThreshold: 1 # Health threshold, the number of consecutive successful health checks needed for the backend container to go from failure to success
failureThreshold: 1 # Unhealth threshold, the number of consecutive successful health checks needed for the backend container to go from success to failure
timeoutSeconds: 3 # Response timeout, the maximum timeout for each health check response
readinessProbe: # Readiness probe, checks if the container is ready, stops forwarding traffic to the current instance if it's not
httpGet: # HTTP request check method
path: /healthz # Request path
port: 8080 # Check port
scheme: HTTP # Check protocol
initialDelaySeconds: 5 # Startup delay, the time delay for the container to start health checks
periodSeconds: 10 # Interval, the time interval for health checks
successThreshold: 1 # Health threshold, the number of consecutive successful health checks needed for the backend container to go from failure to success
failureThreshold: 1 # Unhealth threshold, the number of consecutive successful health checks needed for the backend container to go from success to failure
timeoutSeconds: 3 # Response timeout, maximum timeout for each health check response
startupProbe: # Startup probe, determines when the application container has started
failureThreshold: 10
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 3
resources: # Resource management
limits: # Limit the maximum resources used by the container to prevent excessive resource consumption in exceptional cases
cpu: "1" # Set the CPU limit, 1 core = 1000m
memory: 1Gi # Set the memory limit, 1G = 1024Mi
requests: # Pre-allocate resources, container creation fails if the nodes in the cluster do not have the requested amount of resources
cpu: 250m # Set the CPU request
memory: 500Mi # Set the memory request
terminationMessagePath: /dev/termination-log # The path where the container's termination message is saved
terminationMessagePolicy: File # Retrieve the termination message only from the termination message file
volumeMounts: # Mount log volumes
- mountPath: /etc/iam/iam-apiserver.yaml # Mount path in the container
name: iam # Name of the referenced volume
subPath: iam-apiserver.yaml # Specify the subpath within the referenced volume, not its root path.
- mountPath: /etc/iam/cert
name: iam-cert
dnsPolicy: ClusterFirst
restartPolicy: Always # Restart policy: Always, OnFailure, Never
schedulerName: default-scheduler # Specify the name of the scheduler
imagePullSecrets: # Set ImagePullSecrets in the Pod so that only Pods with the provided secret can access private repositories
- name: ccr-registry # Secrets for the image repository need to be manually created in the cluster
securityContext: {} # Specify the security context
terminationGracePeriodSeconds: 5 # Graceful shutdown time, Kubernetes will forcefully kill if graceful shutdown is not completed within this time
volumes: # Configure data volumes, see https://kubernetes.io/docs/concepts/storage/volumes for volume types
- configMap: # ConfigMap volume type
defaultMode: 420 # Permission setting (0~0777), default is 0664
items:
- key: iam-apiserver.yaml
path: iam-apiserver.yaml
name: iam # ConfigMap name
name: iam # Set the volume name, corresponding to the volumeMounts name
- configMap:
defaultMode: 420
name: iam-cert
name: iam-cert
When deploying, you can configure the corresponding fields according to your needs. Common fields that need to be configured include: `labels`, `name`, `namespace`, `replicas`, `command`, `imagePullPolicy`, `container.name`, `livenessProbe`, `readinessProbe`, `resources`, `volumeMounts`, `volumes`, `imagePullSecrets`, etc.
In addition, when deploying applications, it is often necessary to provide configuration files for the processes inside the container to load and use. The most common method is to mount a ConfigMap into the application container. So, how do you mount a ConfigMap into a container?
When referencing a ConfigMap object, you can use its name in the volume. You can customize the path that a specific entry in the ConfigMap should use. The following configuration shows how to mount a ConfigMap named `log-config` into a Pod named `configmap-pod`:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: test
image: busybox
volumeMounts:
- name: config-vol
mountPath: /etc/config
volumes:
- name: config-vol
configMap:
name: log-config
items:
- key: log_level
path: log_level
The log-config
ConfigMap is mounted as a volume, and all the content stored in the log_level
entry is mounted to the path /etc/config/log_level
inside the Pod. Note that this path is derived from the mountPath
of the volume and the path
corresponding to the log_level
key.
Here, it is important to note that before using ConfigMap, you need to create it first. Next, let’s take a look at ConfigMap resource definitions.
ConfigMap Resource Definition #
The following is an example of a ConfigMap YAML:
apiVersion: v1
kind: ConfigMap
metadata:
name: test-config4
data: # Stores the configuration content
db.host: 172.168.10.1 # Stored in the format key: value
db.port: 3306
As we can see, the YAML definition for ConfigMap is relatively simple. Assuming we save the above YAML in a file named iam-configmap.yaml
, we can execute the following command to create the ConfigMap:
$ kubectl create -f iam-configmap.yaml
In addition to that, the kubectl
command-line tool provides 3 ways to create a ConfigMap. Let me explain each of them.
- Creating with the
--from-literal
parameter:
The creation command is as follows:
$ kubectl create configmap iam-configmap --from-literal=db.host=172.168.10.1 --from-literal=db.port='3306'
- Creating with the
--from-file=<file>
parameter:
The creation command is as follows:
$ echo -n 172.168.10.1 > ./db.host
$ echo -n 3306 > ./db.port
$ kubectl create cm iam-configmap --from-file=./db.host --from-file=./db.port
The value of --from-file
can also be a directory. When the value is a directory, the filenames in the directory are used as the keys and the contents of the directory are used as the values.
- Creating with the
--from-env-file
parameter:
The creation command is as follows:
$ cat << EOF > env.txt
db.host=172.168.10.1
db.port=3306
EOF
$ kubectl create cm iam-configmap --from-env-file=env.txt
Service Resource Definition #
Service is another core resource in Kubernetes. By creating a Service, you can provide a unified entry point with a single address for a group of containers with the same functionality, and load balance the requests to the various backend containers. The YAML definition for a Service resource is as follows:
apiVersion: v1
kind: Service
metadata:
labels:
app: iam-apiserver
name: iam-apiserver
namespace: default
spec:
clusterIP: 192.168.0.231 # Virtual service address
externalTrafficPolicy: Cluster # Indicates whether this service wants to route external traffic to local or cluster-wide endpoints
ports: # List of ports that the service needs to expose
- name: https # Port name
nodePort: 30443 # When type = NodePort, specify the port number mapped to the physical machine
port: 8443 # Port number that the service listens on
protocol: TCP # Port protocol, supports TCP and UDP, default is TCP
targetPort: 8443 # Port number to forward to the backend Pod
selector: # Label selector configuration that selects Pods with the app label as its backend ReplicaSet
app: iam-apiserver
sessionAffinity: None # Whether to support session affinity
type: NodePort # Service type, specifies the access method for the service, default is ClusterIP
Above, I have introduced the content of the commonly used Kubernetes YAML file. When deploying applications, we need to manually write these files. Next, I will explain some commonly used writing techniques during the writing process.
Tips for Writing YAML Files #
Here I will introduce three tips.
- Use online tools to generate template YAML files.
YAML files can be complicated, and it is unnecessary to start from scratch and manually write a YAML definition file, which can be time-consuming and error-prone. I recommend using tools to generate the required YAML.
Here I recommend using the k8syaml tool. k8syaml
is an online YAML generator that can currently generate YAML files for Deployment, StatefulSet, and DaemonSet. k8syaml
provides default values and detailed explanations for each field, which can be referenced when filling in the parameters.
-
Use the
kubectl run
command to get YAML templates:$ kubectl run –dry-run=client –image=nginx nginx -o yaml > my-nginx.yaml $ cat my-nginx.yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: nginx name: nginx spec: containers:
- image: nginx name: nginx resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {}
Then, we can modify the configuration based on this template to create the final YAML file.
- Export existing resource descriptions from the cluster.
Sometimes, if we want to create a Kubernetes resource and find that the description of the resource is similar or identical to the ones already created in the cluster, we can choose to export the YAML description of the existing resource in the cluster and modify it to obtain the desired YAML. For example:
$ kubectl get deployment iam-apiserver -o yaml > iam-authz-server.yaml
Then, modify iam-authz-server.yaml
. Typically, we need to remove the fields automatically added by Kubernetes, such as kubectl.kubernetes.io/last-applied-configuration
, deployment.kubernetes.io/revision
, creationTimestamp
, generation
, resourceVersion
, selfLink
, uid
, status
.
These tips can help us better write and use Kubernetes YAML files.
Recommended Tools for Using Kubernetes YAML #
Next, I will introduce some popular tools that you can choose from based on your needs.
kubeval #
kubeval can be used to validate if a Kubernetes YAML file conforms to the Kubernetes API schema.
To install it, follow these steps:
$ wget https://github.com/instrumenta/kubeval/releases/latest/download/kubeval-linux-amd64.tar.gz
$ tar xf kubeval-linux-amd64.tar.gz
$ mv kubeval $HOME/bin
Once installed, we can validate a Kubernetes YAML file:
$ kubeval deployments/iam.invalid.yaml
ERR - iam/templates/iam-configmap.yaml: Duplicate 'ConfigMap' resource 'iam' in namespace ''
Based on the error message, check the iam.yaml
file and find that there are two ConfigMaps named iam
defined in the file:
apiVersion: v1
kind: ConfigMap
metadata:
name: iam
data:
{}
---
# Source: iam/templates/iam-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: iam
data:
iam-: ""
iam-apiserver.yaml: |
...
Using tools like kubeval
allows us to catch YAML errors early in the deployment process without needing to access the cluster.
kube-score #
kube-score can analyze Kubernetes YAML files and rate them based on built-in checks derived from security recommendations and best practices, such as:
- Containers being run as non-root users.
- Setting health checks for Pods.
- Defining resource requests and limits.
To install it, run the following command:
$ go get github.com/zegl/kube-score/cmd/kube-score
Then, we can score a Kubernetes YAML file:
$ kube-score score -o ci deployments/iam.invalid.yaml
[OK] iam-apiserver apps/v1/Deployment
[OK] iam-apiserver apps/v1/Deployment
[OK] iam-apiserver apps/v1/Deployment
[OK] iam-apiserver apps/v1/Deployment
[CRITICAL] iam-apiserver apps/v1/Deployment: The pod does not have a matching NetworkPolicy
[CRITICAL] iam-apiserver apps/v1/Deployment: Container has the same readiness and liveness probe
[CRITICAL] iam-apiserver apps/v1/Deployment: (iam-apiserver) The pod has a container with a writable root filesystem
[CRITICAL] iam-apiserver apps/v1/Deployment: (iam-apiserver) The container is running with a low user ID
[CRITICAL] iam-apiserver apps/v1/Deployment: (iam-apiserver) The container running with a low group ID
[OK] iam-apiserver apps/v1/Deployment
...
The results of the checks can be OK
, SKIPPED
, WARNING
, or CRITICAL
. CRITICAL
means it needs to be fixed, WARNING
means it needs to be investigated, SKIPPED
means it skipped the check for some reason, and OK
means it passed the validation.
To see the detailed explanation and possible solutions for the errors, use the -o human
option, for example:
$ kube-score score -o human deployments/iam.invalid.yaml
The command above will check the YAML resource definition file and report the level, category, and details of the errors as shown in the image below:
In addition to kubeval
and kube-score
, there are other Kubernetes validation tools available, such as config-lint, copper, conftest, and polaris.
I recommend the following approach when choosing these tools: start with kubeval
for basic YAML file validation. Once the validation passes, move on to perform further testing. If you don’t have complex YAML validation requirements and just need some common checks, then kube-score
is suitable. If you have complex validation requirements and want to customize the validation policies, consider using copper
. Of course, it’s worth trying out polaris
, config-lint
, and copper
as well.
Summary #
Today, I mainly talked about how to write Kubernetes YAML files.
YAML format has rich data expression capabilities, clear structure and hierarchy, so it is used in the definition files of Kubernetes resources. If you want to deploy your application in a Kubernetes cluster, you need to create multiple associated K8s resources, and currently, the most common way to create K8s resources is to write YAML definition files.
In this lecture, I introduced the YAML writing methods of the four most commonly used resources in K8s (Pod, Deployment, Service, ConfigMap). You can review them frequently.
In addition, when writing YAML files, there are also some techniques. For example, you can use the online tool k8syaml to generate the initial version of the YAML file, and then make secondary modifications based on this YAML file to form the final version.
Lastly, I also shared with you various tools provided by the community for writing and using Kubernetes YAML. For example, kubeval can validate YAML, and kube-score can score YAML files. After learning how to write Kubernetes YAML files, I believe you will have a smoother learning experience in the next lecture.
Exercises #
- Think about how to mount Keys from ConfigMap into the same directory, with file names being the Key names.
- Use kubeval to check the K8s YAML definition files of the projects you are currently or previously involved in. Look for any error messages, and make necessary modifications and optimizations.
Feel free to leave a message in the comment section to discuss and exchange ideas. See you in the next lesson.