# Understanding k8s
###### tags: `gogoro`
## gogoro k8s structure
[k8s structure](https://app.diagrams.net/#G1d0D-cxjJsi1OsQDkGh44UCZ4rMdOjLks)

## k8s Resource Object
### Category:
|Category | Resource Object Type Name|
| -------- | -------- |
|Workload| Pod, HorizontalPodAutoscaler|
|Controller| Deployment, ReplicaSet, ReplicationController, Job|
|Service Discovery| Service, Ingress|
|Policy| NetworkPolicy|
### Deployment:
- 功能: deployment定義服務要有幾個pods在線上運作,並且pods中的docker image為何。
- 目的: k8s由此確保app上版時、某個node故障時皆維持目標狀態的服務。
- 特點: 實現不停機的上版,因為k8s總是確保有n個pods在服務。
- 操作:
- 更新pods執行的container
`$ kubectl set image deployment/{my-deployment} {container_name}={new_image_name}`
### Service:
- 功能: 定義一系列Pod以及訪問這些Pod的策略的一層抽象。是對某一服務的一群pods的logic指稱。
- 特點:
- 管理一個服務與其他實體的溝通。k8s提供DNS server服務,讓client可以根據target service name取得相應的ip address,從而實現服務間的溝通。因為pods是非持久性的,每次起來後被分配的ip address都不同。service定義了一個服務,確保他被客戶端呼叫時,不依賴於實際的位置變化。
- 管理一個服務與集群外部的溝通。每一個pod都有一個獨特的ip address,但必需要利用Service,才可以將ip提供給集群外的服務做存取。gogoro不直接開放Service,而是在外面再定義一層Ingress向集群外部做開放。
- what:
- 有兩大類 NodePort, LoadBalancer
### Ingress:
- 功能: 設定某一hostname要導到哪個相應的Service。因為Ingress可以把一個ip address導向多個Service,我們僅需要管理一個Ingress就能管理背後所有的服務。
- 解決:
- 每一個Service一出來都會定義一個port,對AWS來說就必須去設定相應的防火牆port開放。用Ingress就只需開放一個port,其中Ingress設定某一hostname要導到哪個相應的Service。
- gogoro:
SRE/k8s deployment_guide.md中,定義Chart要定義如下:ingress.serviceUrl定義此服務向外界開放的hostname為何。
```yaml=
...
ingress:
albGroupName: nginx-public <-- ingress class name,指定使用哪一條load balancer
serviceUrl: goplatform.dev.gogoro.cc
basePath: /
...
```
### NetworkPolicy
- 功能: 在OSI layer 3, 4,定義某一服務與其他實體溝通的規則。
- 預設是ingress(from), egress(to)兩者都不會擋。
- how to define rule:
- k8s提供namespace and pod selector、ip address來定義ingress和egress。
- [egress rule using domain name](https://monzo.com/blog/controlling-outbound-traffic-from-kubernetes)
### ConfigMap
- app config如何從外部配置
## Helm
packageManager for k8s resource objects of your service/app/tool
### reference:
[baeldung reference](https://www.baeldung.com/ops/kubernetes-helm)
[helm](https://zhuanlan.zhihu.com/p/350328164)
### 3 concepts:
- repo: repo for chart
- chart: chart就是一個folder,裡面定義所有當前服務起來所需要的k8s resource object template,以及一個Value.yaml。Value.yaml將所有的參數都統一在一個位置讓你做resource object的配置。
- release: release是一個運行中的chart,w/ specific config value。helm使用release追蹤已經運行在k8s上的chart。
### syntax:
- 檢視當前template冠上value後的結果。
`$ helm template {path to chart root folder}`
- 用helm根據自定義Chart部署服務上k8s
`$ helm install {your name} {path to chart root folder}`
- 用helm更新已部署上k8s之release。
`$ helm upgrade {chart-name} {path to your chart} --set {key in Value.yaml}={value`
- 取得當前k8s某一namespace下的release。
`$ helm ls -n {namespace}`
- 取得某一release的所有資訊: k8s resource objects。
`$ helm get all {release name} -n {namespace}`
## gogoro如何在k8s上部署
gogoro使用chart來管理每一服務在k8s上的部署及後續更新。每一個group(ex:billing, platform)都有一個基礎的helm chart,基本上不需要寫新的chart即可進行部署。其中Value.yaml,定義基本的參數給外界做配置,因此對不同環境只需要準備相應的外部配置參數值i.e. value-{env}-{namespace}.yaml就可進行配置。第一次做部署請參考infra提供的文件[deployment_guide](http://10.0.1.31/SRE/k8s/-/blob/master/docs/deployment_guide.md),裡面介紹準備部署的幾個步驟及基本解釋。以下就幾個常見問題做補充。
- db, redis, kafka的連線資訊如何餵進去container。
- k8s deployment定義從兩個位置去吃外部配置,其中各專案提供的資料會壓過共同的配置。
- configMap: goplatform-db。目前包含redis的連線資訊。
- configMap: goplatform-{serviceName}。
- configMap一樣由helm chart做管理。helm會將每個專案中的k8s/value-{env}-{namespace}.yaml中的值,餵進configMap。請把db, kafka連線資訊由此餵進去。
- 如何部署不同namespace(ex: token, acl, gos-acl, mggr)?
- 這一題的範疇應該是gitlab-ci。簡單來說要部署上某一個namespace,就是要有一個相應的gitlab job來完成。我們的gitlab-ci模板以一個變數ex: DEPLOY_ACL:"true",來控制該job是否要執行。因此只要設定該變數即可驅動該環境之部署。