---
# System prepended metadata

title: Understanding k8s
tags: [gogoro]

---

# Understanding k8s 
###### tags: `gogoro`
## gogoro k8s structure
[k8s structure](https://app.diagrams.net/#G1d0D-cxjJsi1OsQDkGh44UCZ4rMdOjLks)
![](https://i.imgur.com/L8kahGI.png)

## 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是否要執行。因此只要設定該變數即可驅動該環境之部署。