Introduction
Overview of Kubernetes
Kubernetes (K8s) is an open-source container orchestration platform that automates the deployment, scaling, and management of containers. In K8s, applications typically run as containers, organized into different resource objects such as Deployments, Services, ConfigMaps, and Secrets. To ensure stable operation of applications in different environments (development, testing, pre-production, and production), customized configurations are needed for each environment.
The Importance of Values Files
Values files are configuration files used when managing Kubernetes application deployments using Helm, typically in YAML format. Helm is the package manager for Kubernetes, packaging and managing Kubernetes resources as a whole, called a Chart. Values files play a crucial role in this, allowing us to modify and adjust application configurations in different deployment environments without altering the application code or Kubernetes resource definition files. This ensures the application runs as expected at different stages, while maintaining configuration flexibility and maintainability.
Differences in configuration requirements for different environments
- Development environment: Primarily used by developers for code development and debugging. It typically involves frequent configuration updates, may use relatively small resources, and has relatively lower performance and reliability requirements. For example, a development environment can use a local database or a simple development environment database, and the log level can be set to verbose to allow developers to promptly identify and resolve issues in the code.
- Test environment: Used for functional testing, integration testing, and performance testing, it needs to have a similar configuration to the production environment, but allows for a certain degree of flexibility. The database in the test environment may be dedicated to testing, and its data and performance requirements may vary depending on the testing purpose; for example, it may simulate the data volume or load of the production environment.
- Pre-production environment: This is a rehearsal of the production environment, designed to simulate the production environment as closely as possible, including configuration, resource scale, and performance requirements, to ensure that potential problems are identified and resolved before the official launch.
- Production environment: requires the highest stability, performance, and security, needs to use real production databases, usually has a large resource scale, and has strict requirements for service availability and performance.
Implementation Method
Creating a Helm Chart
First, you need to create a Helm Chart, which is a directory structure containing the application's Kubernetes resource template and default Values files. You can create a new Helm Chart using the following command:
helm create my-application
This command will create a my-application directory named <directory_name> containing multiple subdirectories and files. The templates directory contains template files for Kubernetes resources, while values.yaml is the default Values file.
Modify the default Values file
In the values.yaml configuration file, you can define various configuration parameters for the application, such as:
replicaCount: 1
image:
repository: my-image
tag: latest
service:
type: ClusterIP
port: 80
environment: development
database:
url: jdbc:mysql://localhost:3306/devdb
username: devuser
password: devpass
This section defines the number of replicas, image information, service type, port, and database connection information. However, these configurations are generic, and we need to customize them for different environments.
Create customized Values files for different environments
Create a separate Values file for each environment and save it in the Chart directory. For example:
Development environment: values-dev.yaml
replicaCount: 1
image:
repository: my-image-dev
tag: latest-dev
service:
type: ClusterIP
port: 8080
environment: development
database:
url: jdbc:mysql://dev-db-server:3306/devdb
username: devuser
password: devpass
logging:
level: debug
Test environment: values-test.yaml
replicaCount: 2
image:
repository: my-image-test
tag: latest-test
service:
type: NodePort
port: 8081
environment: testing
database:
url: jdbc:mysql://test-db-server:3306/testdb
username: testuser
password: testpass
logging:
level: info
Pre-release environment: values-preprod.yaml
replicaCount: 3
image:
repository: my-image-preprod
tag: latest-preprod
service:
type: LoadBalancer
port: 80
environment: preproduction
database:
url: jdbc:mysql://preprod-db-server:3306/preproddb
username: preproduser
password: preprodpass
logging:
level: warn
Production environment: values-prod.yaml
replicaCount: 5
image:
repository: my-image-prod
tag: latest-prod
service:
type: LoadBalancer
port: 80
environment: production
database:
url: jdbc:mysql://prod-db-server:3306/proddb
username: produser
password: prodpass
logging:
level: error
Using template languages
In the templates Kubernetes resource template file within the directory, you can use Helm's template language to reference configurations from the Values file. For example, in the deployment.yaml template file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{.Release.Name }}-my-application
spec:
replicas: {{.Values.replicaCount }}
selector:
matchLabels:
app: {{.Release.Name }}-my-application
template:
metadata:
labels:
app: {{.Release.Name }}-my-application
spec:
containers:
- name: my-application
image: {{.Values.image.repository }}:{{.Values.image.tag }}
ports:
- containerPort: {{.Values.service.port }}
env:
- name: DATABASE_URL
value: {{.Values.database.url }}
- name: DATABASE_USER
value: {{.Values.database.username }}
- name: DATABASE_PASSWORD
value: {{.Values.database.password }}
- name: LOGGING_LEVEL
value: {{.Values.database.logging.level }}
Here, we use {{.Values.xxx }} syntax to reference the configuration in the Values file and insert them into the appropriate locations in the Kubernetes resources.
Deploying the application
Use Helm commands to deploy using the appropriate Values file based on different environments:
Development environment:
helm install my-application-dev my-application --values my-application/values-dev.yaml
Test environment:
helm install my-application-test my-application --values my-application/values-test.yaml
Pre-release environment:
helm install my-application-preprod my-application --values my-application/values-preprod.yaml
Production environment:
helm install my-application-prod my-application --values my-application/values-prod.yaml
Implementation Case
Suppose we have a simple web application; here is a complete implementation example:
Creating a Helm Chart
helm create my-webapp
Modify the values.yaml document:
appName: my-webapp
replicaCount: 1
image:
repository: my-webapp-image
tag: latest
service:
type: ClusterIP
port: 80
database:
url: jdbc:mysql://default-db:3306/defaultdb
username: defaultuser
password: defaultpass
logging:
level: info
Creating Values files for different environments:
Development environment: values-dev.yaml
appName: my-webapp-dev
replicaCount: 1
image:
repository: my-webapp-dev-image
tag: latest-dev
service:
type: ClusterIP
port: 8080
database:
url: jdbc:mysql://dev-db:3306/devdb
username: devuser
password: devpass
logging:
level: debug
Test environment: values-test.yaml
appName: my-webapp-test
replicaCount: 2
image:
repository: my-webapp-test-image
tag: latest-test
service:
type: NodePort
port: 8081
database:
url: jdbc:mysql://test-db:3306/testdb
username: testuser
password: testpass
logging:
level: info
Pre-release environment: values-preprod.yaml
appName: my-webapp-preprod
replicaCount: 3
image:
repository: my-webapp-preprod-image
tag: latest-preprod
service:
type: LoadBalancer
port: 80
database:
url: jdbc:mysql://preprod-db:3306/preproddb
username: preproduser
password: preprodpass
logging:
level: warn
Production environment: values-prod.yaml
appName: my-webapp-prod
replicaCount: 5
image:
repository: my-webapp-prod-image
tag: latest-prod
service:
type: LoadBalancer
port: 80
database:
url: jdbc:mysql://prod-db:3306/proddb
username: produser
password: prodpass
logging:
level: error
Modify the template file
In templates/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{.Release.Name }}-{{.Values.appName }}
spec:
replicas: {{.Values.replicaCount }}
selector:
matchLabels:
app: {{.Release.Name }}-{{.Values.appName }}
template:
metadata:
labels:
app: {{.Release.Name }}-{{.Values.appName }}
spec:
containers:
- name: {{.Values.appName }}
image: {{.Values.image.repository }}:{{.Values.image.tag }}
ports:
- containerPort: {{.Values.service.port }}
env:
- name: DATABASE_URL
value: {{.Values.database.url }}
- name: DATABASE_USER
value: {{.Values.database.username }}
- name: DATABASE_PASSWORD
value: {{.Values.database.password }}
- name: LOGGING_LEVEL
value: {{.Values.logging.level }}
Deploying the application
Use the following command to deploy the application to different environments:
Development environment:
helm install my-webapp-dev my-webapp --values my-webapp/values-dev.yaml
Test environment:
helm install my-webapp-test my-webapp --values my-webapp/values-test.yaml
Pre-release environment:
helm install my-webapp-preprod my-webapp --values my-webapp/values-preprod.yaml
Production environment:
helm install my-webapp-prod my-webapp --values my-webapp/values-prod.yaml
In this way, we can easily deploy applications in different environments and customize the configuration according to the characteristics of each environment. This approach ensures the flexibility and manageability of applications in different environments, while reducing problems caused by configuration errors.
Summary
Using Values files to customize application configurations across different Kubernetes environments is a powerful and flexible approach. Leveraging Helm's template capabilities, it allows developers and operations personnel to easily adjust application configurations at different deployment stages without modifying code or Kubernetes resource definition files. By using Values files appropriately, we can better manage application development, testing, pre-production, and production environments, ensuring smooth operation at each stage and meeting corresponding performance, security, and availability requirements. Simultaneously, this approach facilitates continuous integration and continuous deployment (CI/CD) processes, enabling teams to deliver and maintain software more efficiently.
Please remember that in practical applications, appropriate adjustments and optimizations are needed based on the specific requirements of the application and the characteristics of the Kubernetes cluster to ensure the accuracy and effectiveness of the configuration. At the same time, pay attention to the management of sensitive information (such as database passwords), avoid storing it in plaintext in configuration files, and consider using Kubernetes' Secret resources for storage and management.
Top comments (0)