---
# System prepended metadata

title: Kubernetes
tags: [IBM, Infra, QCT]

---

Kubernetes
===

###### tags: `Infra` `QCT` `IBM`

## Architecture
![](https://i.imgur.com/Q38cST1.png)

### kube-proxy
在Worker Node上，kube-proxy 會監視 Control Plane 對 Service 和 Endpoints 的添加和移除，以對每個 Service 配置 iptables 規則，使得該 Service 的 clusterIP:port 請求被重新定向到 Service 後端中的某個 Pod 上。
![](https://d33wubrfki0l68.cloudfront.net/27b2978647a8d7bdc2a96b213f0c0d3242ef9ce0/e8c9b/images/docs/services-iptables-overview.svg)

### kube-controller-manager
- [Replication Controller, Node Controller, ResourceQuota Controller, Namespace Controller, Endpoint Controller, Service Controller](https://www.huweihuang.com/article/kubernetes/core-principle/kubernetes-core-principle-controller-manager/)

---

## CRI, CSI, CNI
[Kubernetes中的开放接口CRI、CNI、CSI](https://zhuanlan.zhihu.com/p/33390023)
![](https://i.imgur.com/yjBLxT5.png)

### CRI
![](https://i.imgur.com/htiLYpz.png)
* Kubernetes implements a Container Runtime Interface that permits pluggability of the container runtime.
* The container runtime is responsible for downloading images and running containers.
* Container Runtime
  * Docker
  * rkt
  * CRI-O 

---

## Namespace
* namespace = virtual cluster
* switch context
  * [Subdividing your cluster using Kubernetes namespace](https://kubernetes.io/docs/tasks/administer-cluster/namespaces/#subdividing-your-cluster-using-kubernetes-namespaces)
* object counts in a namespace
```kubectl get all --namespace=<namespace>```
* Resource Quota
  * [Requests vs. Limits](https://kubernetes.io/docs/concepts/policy/resource-quotas/#requests-vs-limits)
If the quota has a value specified for ```requests.cpu``` or ```requests.memory```, then it requires that every incoming container makes an explicit request for those resources. If the quota has a value specified for ```limits.cpu``` or ```limits.memory```, then it requires that every incoming container specifies an explicit limit for those resources.
* Delete namespace when stuck
```
kubectl proxy & kubectl get namespace NAMESPACE -o json | jq '.spec = {"finalizers":[]}' > temp.json
curl -k -H "Content-Type: application/json" -X PUT --data-binary @temp.json 127.0.0.1:8001/api/v1/namespaces/NAMESPACE/finalize
```

---

## Label & Label Selector
- [Kubernetes基本概念之Label](https://www.jianshu.com/p/cd6b4b4caaab)

---

## Resources

### Service
```
apiVersion: v1
kind: Namespace
metadata:
  name: abby-ns

---
apiVersion: v1
kind: Pod
metadata:
  name: my-nginx
  namespace: abby-ns
  labels:
    app: my-nginx
spec:
  containers:
  - image: nginx
    name: nginx
    ports:
    - containerPort: 80
  restartPolicy: Always

---
apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: abby-ns
spec:
  type: NodePort
  ports:
  - protocol: TCP  
    nodePort: 30033
    targetPort: 80
    port: 1234
  selector:
    app: my-nginx
```
:::info
**spec.ports.targetPort** Pod的port number。
**spec.ports.port** Service的Cluster IP的port number。
**spec.ports.nodePort** Node的port number。
:::

---

### Ingress
- [Ingress控制器详解](https://www.cnblogs.com/along21/p/10333086.html)
- Ingress Controller
Ingress 本身並沒有提供負載平衡的功能，還需要透過Ingress Controller 來實現。
```
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml
```
![](https://i.imgur.com/V6Pp7tH.png)
- Ingress Resource
Ingress resource為rule的集合。
```
apiVersion: v1
kind: Namespace
metadata:
  name: abby-ns

---
apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: abby-ns
spec:
  selector:
    app: my-app
  ports:
  - name: http
    targetPort: 80
    port: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
  namespace: abby-ns
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: ikubernetes/myapp:v2
        ports:
        - name: http
          containerPort: 80

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  namespace: abby-ns
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
    
```
![](https://i.imgur.com/IBatqB4.png)

---

### [ConfigMap vs. Secret](https://ithelp.ithome.com.tw/articles/10224066)

---

### [DaemonSet](https://ithelp.ithome.com.tw/articles/10251596)

---

### RBAC (Role-Based Access Control)
- [老闆！我可以做什麼：RBAC](https://ithelp.ithome.com.tw/articles/10195944)

---

## [Kubernetes kubectl run 命令详解](http://docs.kubernetes.org.cn/468.html)
  * restart option
  The restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to 'Always' a deployment is created, if set to 'OnFailure' a job is created, if set to 'Never', a regular pod is created. For the latter two --replicas must be 1. Default 'Always', for CronJobs Never.

---

## Create resources from scratch
You can easily get the basic skeleton of a Deployment, Job or Pod.
```kubectl create service clusterip foobar --tcp=80:80 -o yaml --dry-run```
```kubectl create service clusterip foobar --tcp=80:80 -o yaml --save-config```
**--save-config**
If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.

---

## Change YAML of live objects
* [Imperative/Declarative and a Few `kubectl` tricks](https://medium.com/bitnami-perspectives/imperative-declarative-and-a-few-kubectl-tricks-9d6deabdde)
* Declarative management
  * 若檔案無修改，就不會做更新
檔案來自annotation (kubectl.kubernetes.io/last-applied-configuration)
```kubectl apply -f <FILENAME>```
* Imperative management 
To create and manage/modify using the CLI so that all operations are done on live objects.
  * 若檔案無修改，就不會做更新
```kubectl edit <RESOURCE> <RESOURCE NAME>```
  * 直接砍掉，重新產生Resource
```kubectl get <RESOURCE> <RESOURCE NAME> -o yaml --export > <FILENAME>``` 
```Kubectl replace --force -f <FILENAME>```\

---

## Helm Charts
- [Helm Quickstart Guide](https://helm.sh/docs/using_helm/)
- [Helm chart](https://jimmysong.io/kubernetes-handbook/practice/helm.html)是用来封装kubernetes原生应用程序的yaml文件
- [Kubeapps Hub](https://hub.kubeapps.com/)
- [Go template syntax](https://golang.org/pkg/text/template/)
- Upgrade
  * [Helm Edit](https://github.com/mstrzele/helm-edit)
  * Helm commands 
```
helm upgrade -f ingress-controller/values.yml nginx-ingress stable/nginx-ingress
```

---

## Output Filter
* [JSONPath](https://kubernetes.io/docs/reference/kubectl/jsonpath/)