kubeadm安裝kubernetes 1.16.2


簡介

當前kubernetes的最新版本已經到了1.16,而kubernetes官方推出的安裝工具kubeadm也已經GA。本文就基於kubeadm來安裝最新的kubernetes集群。

各組件示意圖如下:

k8s-component

環境說明

部署環境:

主機名 ip地址 節點類型 系統版本
master.example.com 192.168.0.1 master、etcd centos7
node1.example.com 192.168.0.2 node centos7

相關組件版本說明:

組件 版本 說明
kubernetes 1.16.2 主程序
docker 19.03.3 容器
flannel 0.11.0 網絡插件
etcd 3.3.15 數據庫
coredns 1.6.2 dns組件
kubernetes-dashboard 2.0.0-beta5 web界面
ingress-nginx 0.26.1 ingress

安裝

安裝步驟說明:

  • 配置主機名、防火牆、yum源
  • 配置內核參數
  • 加載內核模塊
  • 安裝Docker
  • 安裝kubelet、kubectl、kubeadm
  • 編輯kubeadm-config.yml文件
  • 安裝master節點
  • 配置網絡插件
  • 添加node節點
  • 安裝addons之kubernetes dashboard
  • 安裝ingress

准備基礎環境

修改主機名:

hostnamectl set-hostname master.example.com --static
hostnamectl set-hostname node1.example.com --static

清空防火牆規則和selinux:

iptables -F
setenforce 0 

設置yum源:

wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

修改內核參數:

# cat  /etc/sysctl.conf
net.ipv.ip_forward = 1

sysctl -p 

加載內核模塊:


cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- br_netfilter
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF

chmod 755 /etc/sysconfig/modules/ipvs.modules && \
bash /etc/sysconfig/modules/ipvs.modules && \
lsmod | grep -E "ip_vs|nf_conntrack_ipv4"

安裝docker

yum install -y yum-utils

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

yum install -y docker-ce

mkdir /etc/docker

cat > /etc/docker/daemon.json << EOF
{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "log-driver": "json-file",
    "log-opts": {
        "max-size": "100m",
        "max-file": "10"
    },
    "bip": "169.254.123.1/24",
    "oom-score-adjust": -1000,
    "registry-mirrors": ["https://pqbap4ya.mirror.aliyuncs.com"],
    "storage-driver": "overlay2",
    "storage-opts":["overlay2.override_kernel_check=true"],
    "live-restore": false
}
EOF

systemctl restart docker
systemctl enable docker

安裝kubeadm、kubelet、kubectl

cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

yum install -y kubelet kubeadm kubectl

配置kubeadm-config.yaml

通過如下指令創建默認的kubeadm-config.yaml文件:

kubeadm config print init-defaults  > kubeadm-config.yaml

kubeadm-config.yaml組成部署說明:

  • InitConfiguration: 用於定義一些初始化配置,如初始化使用的token以及apiserver地址等
  • ClusterConfiguration:用於定義apiserver、etcd、network、scheduler、controller-manager等master組件相關配置項
  • KubeletConfiguration:用於定義kubelet組件相關的配置項
  • KubeProxyConfiguration:用於定義kube-proxy組件相關的配置項

可以看到,在默認的kubeadm-config.yaml文件中只有InitConfiguration、ClusterConfiguration 兩部分。我們可以通過如下操作生成另外兩部分的示例文件:

# 生成KubeletConfiguration示例文件 
kubeadm config print init-defaults --component-configs KubeletConfiguration

# 生成KubeProxyConfiguration示例文件 
kubeadm config print init-defaults --component-configs KubeProxyConfiguration

最終修改kubeadm-config.yaml文件如下:

apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.0.1
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: master.example.com
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
---
apiServer:
  timeoutForControlPlane: 4m0s
  bind-address: 172.26.159.88
  secure-port: 6443
  authorization-mode: Node,RBAC
  runtime-config: "api/all=true"
  kubelet-https: true
  anonymous-auth: false
  requestheader-allowd-names: ""
  requestheader-extra-headers-prefix: "X-Remote-Extra-"
  requestheader-group-headers: X-Remote-Group
  requestheader-username-headers: X-remote-User
  disable-admission-plugins: PersistentVolumeLabel
  enable-admission-plugins: NodeRestriction
  enable-swagger-ui: true
  allow-privileged: true
  audit-log-maxage: 30
  audit-log-maxbackup: 3
  audit-log-maxsize: 100
  event-ttl: 1h
  v: 2
  logtostderr: true
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager:
  address: 127.0.0.1
  node-monitor-grace-period: 40s
  node-monitor-period: 5s
  pod-eviction-timeout: 1m0s
  controllers: "*,bootstrapsigner,tokencleaner"
  horizontal-pod-autoscaler-use-rest-clients: true      
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: gcr.azk8s.cn/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.16.2
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/16
  podSubnet: 10.244.0.0/16
scheduler:
  leader-elect: true
  address: 127.0.0.1
  v: 2
  logtostderr: true
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
imageRepository: gcr.azk8s.cn/google_containers
kubeProxy:
  config:
    featureGates:
      SupportIPVSProxyMode: true
    mode: ipvs
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
clusterDNS:
- 10.96.0.10

關於kubeadm-config.yaml更多配置語法參考: https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2

使用kubeadm-config.yaml配置主節點:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/control-plane-flags/

kube-proxy開啟ipvs參考: https://github.com/kubernetes/kubernetes/blob/master/pkg/proxy/ipvs/README.md

kubelet的配置示例參考: https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/kubelet-integration/#configure-kubelets-using-kubeadm

部署master

安裝master節點:

kubeadm init --config kubeadm-config.yaml

配置訪問集群:

mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -u) $HOME/.kube/config

完成部署之后,發現兩個問題:

  1. master節點一直notready
  2. coredns pod一直pending

其實這兩個問題都是因為還沒有安裝網絡插件導致的,接下來開始安裝網絡插件

安裝flannel網絡插件


wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

sed -i 's@quay.io/coreos@quay.azk8s.cn/coreos@g' kube-flannel.yml

kubectl apply -f kube-flannel.yml

添加節點

生成用於添加節點的kubeadm-config.yaml文件

kubeadm config print join-defaults > kubeadm-config.yaml

# kubeadm-config.yaml內容如下:

apiVersion: kubeadm.k8s.io/v1beta2
caCertPath: /etc/kubernetes/pki/ca.crt
discovery:
  bootstrapToken:
    apiServerEndpoint: kube-apiserver:6443
    token: abcdef.0123456789abcdef
    unsafeSkipCAVerification: true
  timeout: 5m0s
  tlsBootstrapToken: abcdef.0123456789abcdef
kind: JoinConfiguration
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: node1.example.com
  taints: null

這里需要修改三個地方:

  1. apiServerEndpoint:連接apiserver的地址,即master的api地址,這里可以改為192.168.0.1:6443,如果master集群部署的話,這里需要改為集群vip地址
  2. token及tlsBootstrapToken:連接master使用的token,這里需要與master上的InitConfiguration中的token配置一致
  3. name:node節點的名稱,如果使用主機名,需要確保master節點可以解析該主機名。否則的話可直接使用ip地址

添加節點:

kubeadm join --config kubeadm-config.yaml

需要說明的是,添加node節點,也可以直接使用master安裝完成時給出的添加方式,類似如下:kubeadm join 192.168.0.1:6443 --token abcdef.0123456789abcdef
--discovery-token-ca-cert-hash sha256:cad3fa778559b724dff47bb1ad427bd39d97dd76e934b9467507a2eb990a50c7

安裝dashboard

dashboard的github倉庫地址:https://github.com/kubernetes/dashboard

代碼倉庫當中,有給出安裝示例的相關部署文件,我們可以直接獲取之后,直接部署即可:

wget https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended.yaml
kubectl apply -f ./recommended.yaml

默認這個部署文件當中,會單獨創建一個名為kubernetes-dashboard的命名空間,並將kubernetes-dashboard部署在該命名空間下。dashboard的鏡像來自docker hub官方,所以可不用修改鏡像地址,直接從官方獲取即可。

但是在默認情況下,dashboard並不對外開放訪問端口,我這里簡化操作,直接使用nodePort的方式將其端口暴露出來,修改serivce部分的定義:

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 32443
  type: NodePort
  selector:
    k8s-app: kubernetes-dashboard

重新創建service:

kubectl delete svc kubernetes-dashboard -n kubernetes-dashboard
kubectl apply -f ./recommended.yaml

此時,即可通過瀏覽器訪問web端,端口為32443:

kubernetes-dashboard

可以看到出現如上圖畫面,需要我們輸入一個kubeconfig文件或者一個token。事實上在安裝dashboard時,也為我們默認創建好了一個serviceaccount,為kubernetes-dashboard,並為其生成好了token,我們可以通過如下指令獲取該sa的token:

 kubectl describe secret -n kubernetes-dashboard $(kubectl get secret -n kubernetes-dashboard |grep  kubernetes-dashboard-token | awk '{print $1}') |grep token | awk '{print $2}'
 
 
 eyJhbGciOiJSUzI1NiIsImtpZCI6IkUtYTBrbU44TlhMUjhYWXU0VDZFV1JlX2NQZ0QxV0dPRjBNUHhCbUNGRzAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291eeeeeeLWRhc2hib2FyZC10b2tlbi1rbXBuMiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFxxxxxxxxxxxxxxxxxxxxxxxGZmZmYxLWJhOTAtNDU5Ni1hMzgxLTRhNDk5NzMzYWI0YiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDprdWJlcm5ldGVzLWRhc2hib2FyZCJ9.UwAsemOra-EGl2OzKc3lur8Wtg5adqadulxH7djFpmpWmDj1b8n1YFiX-AwZKSbv_jMZd-mvyyyyyyyyyyyyyyyMYLyVub98kurq0eSWbJdzvzCvBTXwYHl4m0RdQKzx9IwZznzWyk2E5kLYd4QHaydCw7vH26by4cZmsqbRkTsU6_0oJIs0YF0YbCqZKbVhrSVPp2Fw5IyVP-ue27MjaXNCSSNxLX7GNfK1W1E68CrdbX5qqz0-Ma72EclidSxgs17T34p9mnRq1-aQ3ji8bZwvhxuTtCw2DkeU7DbKfzXvJw9ENBB-A0fN4bewP6Og07Q

通過該token登入集群以后,發現很多namespace包括一些其他的資源都沒有足夠的權限查看。這是因為默認我們使用的這個帳戶只有有限的權限。我們可以通過對該sa授予cluster-admin權限來解決這個問題:

修改ClusterRoleBinding資源內容如下:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard

重新創建clusterrolebinding:

kubectl delete clusterrolebindgin  kubernetes-dashboard -n kubernetes-dashboard
kubectl apply -f ./recommended.yaml

此時,kubernetes-dashboard相關配置即完成。

部署ingress

ingress提供外部訪問kubernetes內部應用的入口。社區提供眾多的組件實現,這里就直接使用官方的ingress-nginx組件。

github倉庫地址:

和dashboard一樣,代碼倉庫當中也提供部署文件示例,我們直接獲取即可:

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

獲取到部署文件之后,還需要改兩個東西:

  1. 替換鏡像地址
sed -i 's/quay.io/quay.azk8s.cn/g' mandatory.yaml
  1. 默認ingress會監聽在80和443端口,我們需要讓其監聽在宿主機的80和443上,以實現外部訪問,修改deployment資源,添加一個hostNetwork: true配置項:
...
      hostNetwork: true
      containers:
        - name: nginx-ingress-controller
          image: quay.azk8s.cn/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx
            - --annotations-prefix=nginx.ingress.kubernetes.io
...

部署:

kubectl apply -f ./mandatory.yaml

同樣的,該文件會創建一個名為ingress-nginx的命名空間,並部署ingress-nginx pod至該命名空間下。

[root@master ~]# kubectl get pods -n ingress-nginx
NAME                                       READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-8fbcc4d76-vvgj5   1/1     Running   0          3m9s

默認情況下,ingress容器可隨意在節點間調度,這樣其實也存在一個問題,作為外部的訪問入口,如果無法確定ingress容器所在的節點ip,則等於找不到入口。一個有效的解決方法是通過打標簽的方式將ingress固定在特定的節點上,並且通過污點和容忍將這些特定節點上的其他應用排干,只用於入口流量轉發

重置集群

下面給出重置集群的方法:

kubeadm reset
ifconfig cni0 down
ip link delete cni0
ifconfig flannel.1 down
ip link delete flannel.1
rm -rf /var/lib/cni/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM