---
# System prepended metadata

title: Kubernetes
tags: [k8s, kubernetes]

---

Kubernetes
==
速記一些常用的指令或概念作為primer
# 安裝
這章節紀錄跟k8s安裝相關的指令。大多時候應該不需要用到這節，除非是需要從頭開始打造自己cluster的人。
## 從ubuntu安裝k8s
這邊有個注意事項:
* 機器上不能有swap。如果不幸在安裝的時候有分割出swap空間，那可以修改/etc/fstab或是使用 swapoff -a 的指令把swap弄掉。
* 確認在區域網路中，預計使用的節點沒有任何的衝突。
### 讓iptables可以跟bridge traffic溝通
先確認br_netfilter有沒有放到kernel中(使用*lsmod | grep br_netfilter*指令就行。通常都會有安裝。如果沒有安裝就用*sudo modeprobe br_netfilter*即可)。把br_netfilter放到k8s.conf設定中:
```shell    
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
```
完畢後確認6443的port有沒有被占用:
```shell 
nc 127.0.0.1 6443
```
比較麻煩的地方是因為k8s後續就不跟進docker的玩法，所以使用dockershim的使用者要確認一下。確認的部分可以[參考這裡](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#installing-runtime)。
K8s官方說明文件指出，使用docker engine中間可以透過cri-docker來彌補dockershim的問題。所以就先[依照cri-docker文件將cri-docker裝上並製作出server](https://github.com/Mirantis/cri-dockerd)。
新版的ubuntu(依稀記得是20.04)在cgroup的driver有稍微更動。因此這邊還需要把一些cgroup的設定改一下:
```=
# Create required directories
sudo mkdir -p /etc/systemd/system/docker.service.d

# Create daemon json config file
sudo tee /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

# Start and enable Services
sudo systemctl daemon-reload 
sudo systemctl restart docker
sudo systemctl enable docker
```
### 安裝kubeadm
所有節點(包括主節點跟子節點)都需要安裝kubeadm
```shell=
sudo apt-get update && sudo apt-get install -y apt-transport-https curl
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
#sudo apt-mark hold kubelet kubeadm kubectl #暫時不鎖定版本。之前鎖定以後有出一點狀況。
```
[詳細安裝步驟](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)

#### 設定主節點
直接使用
```shell=
sudo kubeadm init

#之前不知道為什麼，CNI網路一直出包。這邊給予cidr紀錄，也就是pod發授ip就在這範圍
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
```
經過很多次的嘗試，不斷重新安裝也很重要。所以這邊也記錄砍掉目前kubeadm的指令:
```shell=
sudo kubeadm reset
```
接下來要設定一些使用者需要的環境變數。這邊只介紹如果不是root要怎麼辦。如果本身就是有root的權限也喜歡用root權限處理事情，那可以[參考這邊](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#more-information):
```shell=
rm -rf $HOME/.kube
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
```
最下面會出現一些訊息，記得記錄下來。因為這些訊息可以設定讓子節點加入。訊息大概會長這樣:
```shell
kubeadm join 192.168.71.211:6443 --token uuv6iv.trc3ht7wqnk3fj99 \
    --discovery-token-ca-cert-hash sha256:83b367f94a84ea0b135ae978b002d125a3909f3ad24a8fc538034ee798a9dcab
```
**以上訊息是給子節點用的**。這邊就是產生一個token跟告訴子節點會需要的資訊。日後如果還需要加入新的節點，可以用早就建立好的:
```shell
kubeadm token list
```
或是重新Create一個新的:
```shell
kubeadm token create --print-join-command
```
來產生上面的token。一個token的生命週期大概是24小時，24小時過後就需要重新create新的。有點龜毛喜歡用目前token的人，在取得token後應該還需要一個sha key。產生sha key的作法是:
```shell=
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
   openssl dgst -sha256 -hex | sed 's/^.* //'
```

## 設定子節點
子節點設計的原理就是"越不需要事前設定越好"，因此大概裝完kubeadm然後把token以kubeadm放到子節點上就完成了。
使用方式就是從master拿到上面的token，然後在子節點上用kubeadm join:
```shell 
sudo kubeadm join 192.168.71.211:6443 --token uuv6iv.trc3ht7wqnk3fj99 \
    --discovery-token-ca-cert-hash sha256:83b367f94a84ea0b135ae978b002d125a3909f3ad24a8fc538034exxxxxxxxxx
```

## 設定CNI網路
CNI負責的網路部分包括分配區域ip、橋接等等的網路功能。
上面主從節點都設定完成後，使用*kubectl get nodes*會得到STATUS為NotReady的節點狀態。如果要開始啟用這些節點，就還需要進行網路設定。當這些節點都可以透過網路連結後，就能開始使用了。
[網路的部分可以有很多種](https://zhuanlan.zhihu.com/p/53296042)。最常用的兩種是flannel跟Weavenet。flannel是設定最精簡的網路架構，但是也是安全性最差的。如果要練習或是k8s內部機器運算也不是太大，這種架構是建議的架構。但如果有安全性的考量，Weavenet就是比較常用的。

### Weavenet
Weavenet的設定比較方便，建議使用這邊的設定。
```shell
export kubever=$(kubectl version | base64 | tr -d '\n')
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$kubever"
```

### flannel
```shell 
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
```

### 移除網路
```shell 
kubectl delete -f <網路的yaml>
```
*網路的yaml*指的就是安裝的時候，有apply上面的網路，例如flannel就是 https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml 。這邊有測試過，如果中途想要換CNI，即使不先刪除而直接apply似乎也是可以用。所以這個指令的用途可能就是在某些debug的狀態下會比較需要。

# 使用

# 實用指令
### CNI網路出錯
如果使用journalctl查看節點log，出現 " 6843 cni.go:240] "Unable to update cni config" err="no networks found in /etc/cni/net.d" ，就是CNI的驅動有點問題。可以參考上面安裝**wavenet**的方式
### 基礎操作
```shell=
kubectl get nodes #查看節點狀態
journalctl -f -u kubelet # 想看kubelet的錯誤log
service kubelet restart #重啟k8s服務

```



###### tags: `kubernetes` `k8s`