k3s 踩坑
Kubernetes 之前很火, 但是因为对每个计算节点的配置要求非常之高, 我一直是在使用 Rancher 的
Cattle
开始安装
已知问题
因为默认的 Ingress
traefik
Initializing
同时因为
traefik
nginx-ingress
因为我是要跨平台组集群 而
flannel
flannel
calico
zerotier
此处主控和节点已经处在同一个 zerotier 网络中
安装主控端
curl -sfL https://get.k3s.io -o k3s.sh
chmod +x k3s.sh
bash k3s.sh --no-deploy traefik --no-flannel
rm -f k3s.sh
修改主控端 node ip
如果你和我一样是使用的 zerotier 或者 wireguard 等软件搭建的内网, 需要修改 server 和 agent 的启动参数
在运行安装脚本的时候加入
--node-ip 内网IP --flannel-iface 网卡
安装 calico
curl https://docs.projectcalico.org/v3.6/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml -O
sed -i -e "s?192.168.0.0/16?10.42.0.0/16?g" calico.yaml
kubectl apply -f calico.yaml
安装被控端
curl -sfL https://get.k3s.io -o k3s.sh
chmod +x k3s.sh
K3S_URL=https://SERVER_IP:6443 \
K3S_TOKEN=TOKEN \
bash k3s.sh --no-flannel
rm -f k3s.sh
Token 可以从主控端的
中获得/var/lib/rancher/k3s/server/node-token
使用
安装 Nginx-Ingress
apply 这个 yml
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: nginx-ingress
namespace: kube-system
spec:
chart: stable/nginx-ingress
valuesContent: |-
controller:
kind: DaemonSet
daemonset:
useHostPort: true
nodeSelector:
nodeRole: nginx-edge
service:
type: ClusterIP
注意要给能 nginx 访问的 node 打上
的 labelnodeRole=nginx-edge
安装 cert-manager
此处例子为配置 DNS 解析, 使用 DigitalOcean 更多操作请查看 官方文档
因为 k3s 的问题, 我们需要部署不带 webhook 的 cert-manager
Issue in cert-manager #1519 Issue in k3s #117 Issue in k3s #120
kubectl create namespace cert-manager
kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true
kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.7/deploy/manifests/cert-manager-no-webhook.yaml
然后这时候 cert-manager 就安装完了 新建一个 Screct 存一下 DO 的 API Key
echo "TOKEN" > token
kubectl create secret generic digitalocean-dns-api --namespace=cert-manager --from-file=token
然后创建一个 Issuer
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: digitalocean-issuer
namespace: kube-system
spec:
acme:
email: [email protected]
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: acme-issuer-account-key
dns01:
providers:
- name: digitalocean-acme
digitalocean:
tokenSecretRef:
name: digitalocean-dns-api
key: token
然后我们就能签下来我们的证书了
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: dashboard-cert
namespace: kube-system
spec:
secretName: dashboard-cert-tls
issuerRef:
name: digitalocean-issuer
kind: ClusterIssuer
commonName: 'kubernetes.bogon.dev'
dnsNames:
- kubernetes.bogon.dev
acme:
config:
- dns01:
provider: digitalocean-acme
domains:
- kubernetes.bogon.dev
安装 kubernetes dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml
然后我们需要建立一个能够 Cluster Role view 的账户
apiVersion: v1
kind: ServiceAccount
metadata:
name: kubedash
namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: dashboard
subjects:
- kind: ServiceAccount
name: kubedash
namespace: kube-system
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
然后使用
kubectl apply -f
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep kubedash | awk '{print $1}')
获取到账户的 Token
为了能进行外网访问, 我们还需要建立一个 Ingress 来将其开放到公网
创建一个 TLS 证书类型的 secret
如果你使用 cert-manager 创建证书的话, 可以跳过此步
kubectl create secret tls dashboard-cert-tls --key k8s.key --cert k8s.crt --namespace=kube-system
# 证书哪里拿我应该不用讲了
创建 Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: dashboard-ingress
namespace: kube-system
annotations:
ingress.kubernetes.io/protocol: https
nginx.ingress.kubernetes.io/backend-protocol: https
spec:
rules:
- host: kubernetes.bogon.dev
http:
paths:
- backend:
serviceName: kubernetes-dashboard
servicePort: 443
tls:
- hosts:
- kubernetes.bogon.dev
secretName: dashboard-cert-tls
然后我们就完成了最简单的一部分
踩坑
Dind 中创建出来的容器 MTU 不正常
这个其实不是 k3s 的锅, 事实上你就算是 k8s 也有这个问题
这个问题困扰了我很久, 最后我在 Drone 的论坛中发现了一个解决方法
在创建 dind 的容器时修改 iptables 开启
clamp-mss-to-pmtu
就算你给 docker daemon 或者修改了 config 改掉了 docker 的网卡 MTU, 创建出来容器中的 bridge 网卡 MTU 还是 1500
- name: drone-dind
image: "docker:17.12.0-ce-dind"
imagePullPolicy: IfNotPresent
command: ["/bin/sh"]
args:
- "-c"
- "iptables -N DOCKER-USER; iptables -I DOCKER-USER -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu; dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375"
修改 Calico 网卡的 MTU
有时候因为用了虚拟网卡, 需要修改 calico 网卡的 MTU
kubectl edit cm -n kube-system calico-config# 修改 veth_mtu 的值kubectl delete pod $(kubectl get pod -n kube-system | grep calico-node | awk '{print $1}') -n kube-system
ChangeLog
- 2019/8/14: 添加了 修改主控端 node ip 部分, 修改了 HelmCharts 的 apiVersion, 对应 Release v0.6.1