k8s general
k8s is a platform to manage containerized workloads and services.
Concepts
kubernetes Objects
- Kubernetes abstract a desired state of cluster as objects.
- an object configuration includes:
- spec: describe the desired state
- apiVersion: the api version of kubernetes
- metadata: the name & namespace
- spec: the desired state definition.
- status: describe the actual state of the object
- spec: describe the desired state
- cluster state (understanding kubernetes objects):
- what containerized applications are running and where they’re running
- how many resources (disk, network, etc.) are attached to the the container
- the policies around how the application behaves, such as restart policies, fault-tolerance, etc.
Workloads
Objects that set deployment rules of pods.
All controllers are workloads.
POD
pod is a minimize runnable object in k8s object model.
A Pod encapsulates an application container (or, in some cases, multiple containers), storage resources, a unique network IP, and options that govern how the container(s) should run.
It represents a single instances of application.
There’re two common use cases:
- Pods that run a single container, which is the most case. So often pod is a synomynous with container.
- Pods that run multiple containers that need to work together. All the containers in a pod share the storage & network, which means they use the same ip and same storage volume.
Pod lifecycle
A pod doesn’t self-heal & self-scale. It’s just a running instance. It stopped & deleted when the process is finished, or the node is failed, or the resource is exhaused… Controllers (eg. deployment, statefulSet…) instead can create and manage multiple pods.
Pod restarting is different from container restarting. Pod provides the env for containers: os, storage, network…
Controllers
Controllers (eg. deployment, statefulSet…) instead can create and manage multiple pods.
StatefulSet????
When using a Kubernetes StatefulSet, each pod in the StatefulSet is typically assigned its own unique and stable hostname and ordinal index. This allows each pod to have its own identity and ensures that the pods maintain a predictable and consistent network identity across restarts or rescheduling.
By default, each pod in a StatefulSet is provisioned with its own volume(s), which can be backed by physical storage or cloud-based storage solutions. This ensures data isolation and allows each pod to have its own storage space.
However, it is possible to configure a StatefulSet to use shared storage among its pods. This can be achieved by using a shared network file system (NFS) or a distributed file system (such as CephFS or GlusterFS) as the underlying storage solution. With this configuration, all pods in the StatefulSet can mount the same shared storage, allowing them to access and share data stored within that storage.
To achieve shared storage with StatefulSet, you would need to configure the appropriate volume and volume mount settings in the StatefulSet’s pod template specification. The specific configuration details depend on the storage solution you are using.
It’s important to note that while sharing storage among pods can provide benefits like data sharing and consistency, it may introduce potential performance and scalability considerations. It’s recommended to carefully evaluate your requirements and choose the appropriate storage solution based on your specific use case.
Service
Service is an abstraction which defines a logical set of pods, and a policy by which to access the pods.
It enables the decoupling of access & the real pods, which means you can access by service name/ip rather than the pod ip, while pod ip is not stable.
Q: How does k8s get all pod endpoints by service?
A: By
LabelSelector
. You can define labels for each pod. And we defineLabelSelector
in service, so that k8s can search pod node by label first, and then using thetargetPort
to locate the pod on node.
Secrets???
In Kubernetes (k8s), a secret is an API object used to store sensitive data such as passwords, API keys, and TLS certificates. Secrets are typically used to securely provide this sensitive information to applications running within Kubernetes pods.
Kubernetes supports different types of secrets, each designed for specific use cases. Here are a few examples:
- Opaque: The most commonly used secret type in Kubernetes. It stores arbitrary key-value pairs as Base64-encoded strings. These secrets are useful for storing generic sensitive data.
Example:
1 | apiVersion: v1 |
- TLS: Specifically used for storing TLS certificates and private keys. This type of secret is often used for securing HTTPS connections.
Example:
1 | apiVersion: v1 |
- Docker-registry: Used to store authentication information for private Docker registries.
Example:
1 | apiVersion: v1 |
These are just a few examples of secret types in Kubernetes. Secrets allow you to securely manage sensitive information and provide it to your applications when needed.
By default, echo
command adds a newline character at the end of the output. The -n
option prevents echo
from appending the newline, ensuring that only the encoded string is printed without any additional characters.
1 | echo -n "test" | base64 |
kubernetes control plane
- the control plane manage the cluster state to match the desired state of objects
- the control plane consists of a collection of processes for the above intention.
- kubernetes master:
- is responsible for the maintaining the desired state.
- “master” in fact refers to three processes: kube-apiserver, kube-controller-manager and kube-scheduler.
- these three processes are typically run on single node in the cluster. This node is called “master”, too. The master can also be replicated for avaibility and redundancy.
- kubernetes nodes:
- the nodes to run applications.
- there’re two process in each node:
- kubelet: communicate with the master
- kube-proxy: a network proxy.
- kubernetes master:
kubernetes api
The api communicates with master to operate on kubernetes objects.
kubectl is a cli to implement the above intention. It in fact calls the api internally.
All kinds of sdk (java, python…) encapsulate the api, too.
There are two kinds of api groups:
- core groups: the original k8s api
- other groups: other api to extend the core group, like you may want to abstract more objects?
Access services on cluster
There are several levels.
ip:
- pod ip:
- cluster ip: the virtual ip for a service
- node ip
In-pod access
Each pod has a unique IP. And all containers in a pod share the ip, which means that they can access each other by localhost
In-cluster access
By default, a service can be accessed by other pods in the same cluster, through:
cluster-ip:port
- cluster ip is the virtual ip of a service
- port is is the node port of the service.
Every node on k8s has a kube-proxy
. It installs iptable rules which keep a simple record of (servicename:clusterip:serviceport).
In some node:
- call cluster-ip:port————— In a pod
- the kube-proxy search the iptable, and get some info.———— pod => kube-proxy of node where the pod resides.
- the kube-proxy using the info to ask master for the real endpoints.—— kube-proxy of node => master kube-api
- the kube-proxy chooses a endpoint by
SessionAffinity
defined in service (round-robin by default) —— in kube-proxy - the kube-proxy redirect request to
pod-ip:podPort
—— kube-proxy => pod endpoint
kube-proxy: enables the Kubernetes service abstraction by maintaining network rules on the host and performing connection forwarding
servicename.namespacename
When accessing by service name, there’re two ways:
environement viaribles
when create a service, k8s will create some env for each serivce, e.g. {SVCNAME_CAPTIPAL}_SERVICE_HOST
. So the kube-proxy in fact gets the service cluster ip from these envs first. When a pod calls a service, the service must be created before the pod so that the envs are created.
1 | # the cluster ip |
DNS
DNS is an add-on k8s object, which can be chosed to add to the cluster.
It’s an in-cluster dns, which serves DNS records for Kubernetes services.
It watches the k8s api for new services and create DNS SVC records for each.
Containers started by Kubernetes automatically include this DNS server in their DNS searches.
between-cluster access
- NodePort: expose nodeIP
- LoadBalancer: expose loadbalancer ip
- Ingress: expose loadbalancer & path
Ingress
what’s ingress
Ingress is a k8s resource to route external traffic into k8x cluster services. From functionality perspective, it provides:
load balance
routing
reverse proxy
service discovery
…
It can route by http path, host name, http method, etc.
IngressController
However, Ingress itself is just a definition. IngressController is the one to really routing, load-balancing, and so on. IngressController config the load balancer etc. based on the ingress resource. And it routes based on the rules defined in ingress.
IngressController is an independent component. There’re many implementations. And different controller has different features, i.e. not all IngressControllers have all the above functionalities.
nginx ingress controller: in this case, it converts the ingress object innto nginx config, and apply this config to nginx server.
traefix ingress controller
istio ingress gateway
contour ingress controller: based on Envoy proxy.
kong ingress controller: a kinds of api gateways
ambassador api gateway: k8s-native api gateway
expose the service
When external user wants to access some cluser service, the entrypoint is the address of IngressController. To expose IngressController, several ways:
1. NodePort
Expose service to all nodes in cluster.
2. HostNetwork(共享主机网络)
Expose ingressController to the network namespace of host node, so that we can access IngressController by the host ip.
3. LoadBalancer
Expose IngressController to the LB, and then access through LB
4. ExternalIPs
Designate externalIP for ingressController, and access throught that.