一個master、一個node、查看node節點是主機名 # 安裝順序:先在test1 上安裝完必要組件後,就開始在 test2 上單獨安裝node組件,實現node功能,再返回來配置test1加入集羣,實現node功能 # 本實驗 test1 節點不作安裝kubelet組件。只有安裝啓動了kubelet纔會生成csr,kube-apiserver經過csr請求後纔會成爲一個node。因此是node節點單獨安裝 # 注意:準備了三臺,這三臺都作了環境準備,可是k8s集羣只是使用了 test一、test2這兩個節點,若是把test3擴容進來,隨時均可以, # 注意:本實驗 test2 沒有安裝etcd,以前安裝的etcd給剔除了 # 本實驗 kubelet組件的參數中 --hostname-override= 寫的ip地址,經過 kubectl get nodes 查看獲得的name就是ip,若是填寫主機名,獲得的name就是主機名 實驗架構: # 注意:下面列出來的組件順序就是本實驗的組件安裝順序 test1: 192.168.0.91 etcd、kubectl工具、kube-apiserver、kube-controller-manager、kube-scheduler、kubelet組件、cni、kube-proxy test2: 192.168.0.92 docker、kubectl工具、kubelet組件、cni、kube-proxy、flannel、coredns test3:192.168.0.93 無 1、環境配置 # 以下操做在全部節點操做 修改主機名 # 注意修改 各自節點對應的 主機名 sed -i '$a\hostname=test1' /etc/hostname sed -i '$a\hostname=test1' /etc/sysconfig/network && hostnamectl set-hostname test1 配置hosts解析 cat >>/etc/hosts<<EOF 192.168.0.91 test1 192.168.0.92 test2 192.168.0.93 test3 EOF 禁用selinux sed -i 's/SELINUX=permissive/SELINUX=disabled/' /etc/sysconfig/selinux sed -i 's/enforcing/disabled/g' /etc/selinux/config 關閉swap # 註釋/etc/fstab文件裏swap相關的行 sed -i 's/\/dev\/mapper\/centos-swap/#\/dev\/mapper\/centos-swap/g' /etc/fstab 關掉防火牆 systemctl stop firewalld && systemctl disable firewalld 配置免密登陸 退出xshell查看主機名是否改變(必須) exit 開啓forward iptables -P FORWARD ACCEPT 配置轉發相關參數 cat > /etc/sysctl.d/k8s.conf <<EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 vm.swappiness=0 EOF 加載系統參數 sysctl --system 加載ipvs相關內核模塊 # 若是從新開機,須要從新加載 modprobe ip_vs modprobe ip_vs_rr modprobe ip_vs_wrr modprobe ip_vs_sh modprobe nf_conntrack_ipv4 lsmod | grep ip_vs 2、安裝etcd etcd安裝請參照: https://www.cnblogs.com/effortsing/p/10295261.html 下面開始安裝k8s組件,序號從6開始 6、分發二進制組件 # 只在test1 節點上操做 # 提早分發k8s全部組件二進制文件、順便安裝kubectl工具 # 安裝包解壓後包括 kubectl 工具,因此不須要單獨使用kubernetes-server-client-amd64.tar.gz 安裝包分發 kubectl 工具 下載、解壓安裝包 cd /server/software/k8s 下載連接:https://pan.baidu.com/s/1DXahqP8nXWP1aw5pIunJrw 提取碼:9xfp tar -xf kubernetes-server-linux-amd64.tar.gz 分發全部組件二進制文件, # 後面配置 kube-apiserver 等各個組件啓動文件裏面須要帶上各自二進制文件路徑 mkdir -p /usr/local/kubernetes/bin cd /server/software/k8s/kubernetes/server/bin cp kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/kubernetes/bin #這一步很關鍵 安裝kubectl工具 # 後面建立 admin kubeconfig等配置文件時候須要用到; # admin.conf = ~/.kube/config,由於是複製過來的 ; # kubectl做用:當kubelet組件經過bootstrap token 認證後,kubectl默認從 ~/.kube/config 文件讀取 kube-apiserver 地址、證書、用戶名等信息; cp /usr/local/kubernetes/bin/kubectl /usr/local/bin/kubectl 查看 kubectl 版本, # 出現下面的狀況就是正確的。did you specify the right host or port? 這個報錯忽略,由於尚未安裝kubelet服務 kubectl version [root@test1 bin]# kubectl version Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.0", GitCommit:"91e7b4fd31fcd3d5f436da26c980becec37ceefe", GitTreeState:"clean", BuildDate:"2018-06-27T20:17:28Z", GoVersion:"go1.10.2", Compiler:"gc", Platform:"linux/amd64"} The connection to the server localhost:8080 was refused - did you specify the right host or port? cd $HOME 7、生成admin的ca證書和私鑰 # 只在test1 節點上操做 # kubectl 做爲集羣的管理工具,須要被授予最高權限。這裏建立具備最高權限的 admin 證書、admin kubeconfig # 注意:後面只有apiserver和kubelet這兩個服務啓動參數會用到admin的ca證書;kubectl工具和kubelet服務不是一回事 cd $HOME/ssl cat >admin-csr.json<<EOF { "CN": "admin", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "system:masters", "OU": "System" } ] } EOF 生成 admin ca cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json \ -profile=kubernetes admin-csr.json | cfssljson -bare admin 查看生成的admin ca ls admin*.pem 八、配置 kube-apiserver ca # 只在 test1節點上操做 # 10.96.0.1 是 kube-apiserver 指定的 service-cluster-ip-range 網段的第一個IP cd $HOME/ssl cat >kube-apiserver-csr.json<<EOF { "CN": "kube-apiserver", "hosts": [ "127.0.0.1", "192.168.0.91", "192.168.0.92", "192.168.0.93", "10.96.0.1", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster", "kubernetes.default.svc.cluster.local" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "k8s", "OU": "System" } ] } EOF 生成 kube-apiserver ca cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json \ -profile=kubernetes kube-apiserver-csr.json | cfssljson -bare kube-apiserver 查看生成的kube-apiserver ca ls kube-apiserver*.pem 九、配置 kube-controller-manager ca # 只在 test1節點上操做 cd $HOME/ssl cat >kube-controller-manager-csr.json<<EOF { "CN": "system:kube-controller-manager", "hosts": [ "127.0.0.1", "192.168.0.91" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "system:kube-controller-manager", "OU": "System" } ] } EOF 生成 kube-controller-manager ca cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json \ -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager 查看生成的kube-controller-manager ca ls kube-controller-manager*.pem 十、配置 kube-scheduler ca # 只在test1 節點上操做 cd $HOME/ssl cat >kube-scheduler-csr.json<<EOF { "CN": "system:kube-scheduler", "hosts": [ "127.0.0.1", "192.168.0.91" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "system:kube-scheduler", "OU": "System" } ] } EOF 生成 kube-scheduler ca cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json \ -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler 查看生成的kube-scheduler ca ls kube-scheduler*.pem 十一、配置 kube-proxy ca # 只在test1節點上操做 # 注意:只是node節點須要用到kube-proxy ca cd $HOME/ssl cat >kube-proxy-csr.json<<EOF { "CN": "system:kube-proxy", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "system:kube-proxy", "OU": "System" } ] } EOF 生成 kube-proxy ca cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json \ -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy 查看生成的kube-proxy ca ls kube-proxy*.pem 12、複製全部的ca 證書到一個目錄裏面,方便管理 # 只在test1節點上操做 cd $HOME/ssl mkdir -p /etc/kubernetes/pki mkdir -p /etc/kubernetes/pki/etcd/ cp ca*.pem admin*.pem kube-proxy*.pem kube-scheduler*.pem kube-controller-manager*.pem kube-apiserver*.pem /etc/kubernetes/pki 13、開啓 bootstrap token 認證 ,kubelet TLS Boostrap機制 # 只在test1 節點上操做 # kube-apiserver、kubelet啓動文件須要用到token, # token中包含kubelet-bootstrap用戶 # 後面kubelet組件啓動參數中須要使用 kubelet-bootstrap.conf 文件向 kube-apiserver 發送 CSR 請求, # 請求經過後,kubectl纔會從 ~/.kube/config 文件讀取 kube-apiserver 地址、證書、用戶名等信息 靜態獲取token # 還有一種是用 kubeadm 動態獲取token,kubeadm token create,這樣可使用 TLS bootstrap 機制自動生成 client 和 server 證書,過時後自動輪轉。 # 本實驗採用靜態獲取,一天後過時 export BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ') 建立token.csv文件 # 只有kube-apiserver 啓動文件中須要用到 cat > /etc/kubernetes/token.csv <<EOF ${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap" EOF 建立kubelet-bootstrap.conf # 只有kubelet啓動文件須要用到 cd /etc/kubernetes export KUBE_APISERVER="https://192.168.0.91:6443" kubectl config set-cluster kubernetes \ --certificate-authority=/etc/kubernetes/pki/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=kubelet-bootstrap.conf kubectl config set-credentials kubelet-bootstrap \ --token=${BOOTSTRAP_TOKEN} \ --kubeconfig=kubelet-bootstrap.conf kubectl config set-context default \ --cluster=kubernetes \ --user=kubelet-bootstrap \ --kubeconfig=kubelet-bootstrap.conf kubectl config use-context default --kubeconfig=kubelet-bootstrap.conf 14、建立 admin kubeconfig # 只在test1節點上操做 # 只有kubelet服務啓動參數須要用到admin kubeconfig, # admin.conf = ~/.kube/config,由於複製過來的 ;kubectl 默認從 ~/.kube/config 文件讀取 kube-apiserver 地址、證書、用戶名等信息, cd /etc/kubernetes export KUBE_APISERVER="https://192.168.0.91:6443" 設置集羣參數 kubectl config set-cluster kubernetes \ --certificate-authority=/etc/kubernetes/pki/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=admin.conf 設置客戶端認證參數 kubectl config set-credentials admin \ --client-certificate=/etc/kubernetes/pki/admin.pem \ --client-key=/etc/kubernetes/pki/admin-key.pem \ --embed-certs=true \ --kubeconfig=admin.conf 設置上下文參數 kubectl config set-context default \ --cluster=kubernetes \ --user=admin \ --kubeconfig=admin.conf 設置默認上下文 kubectl config use-context default --kubeconfig=admin.conf 1五、建立 kube-controller-manager kubeconfig # 只在test1 節點上操做 cd /etc/kubernetes export KUBE_APISERVER="https://192.168.0.91:6443" kubectl config set-cluster kubernetes \ --certificate-authority=/etc/kubernetes/pki/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=kube-controller-manager.conf kubectl config set-credentials kube-controller-manager \ --client-certificate=/etc/kubernetes/pki/kube-controller-manager.pem \ --client-key=/etc/kubernetes/pki/kube-controller-manager-key.pem \ --embed-certs=true \ --kubeconfig=kube-controller-manager.conf kubectl config set-context default \ --cluster=kubernetes \ --user=kube-controller-manager \ --kubeconfig=kube-controller-manager.conf kubectl config use-context default --kubeconfig=kube-controller-manager.conf 1六、建立 kube-scheduler kubeconfig # 只在test1 節點上操做 cd /etc/kubernetes export KUBE_APISERVER="https://192.168.0.91:6443" kubectl config set-cluster kubernetes \ --certificate-authority=/etc/kubernetes/pki/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=kube-scheduler.conf kubectl config set-credentials kube-scheduler \ --client-certificate=/etc/kubernetes/pki/kube-scheduler.pem \ --client-key=/etc/kubernetes/pki/kube-scheduler-key.pem \ --embed-certs=true \ --kubeconfig=kube-scheduler.conf kubectl config set-context default \ --cluster=kubernetes \ --user=kube-scheduler \ --kubeconfig=kube-scheduler.conf kubectl config use-context default --kubeconfig=kube-scheduler.conf 1七、建立 kube-proxy kubeconfig # 只在test1 節點上操做 # 注意:只是node節點須要用到kube-proxy kubeconfig cd /etc/kubernetes export KUBE_APISERVER="https://192.168.0.91:6443" kubectl config set-cluster kubernetes \ --certificate-authority=/etc/kubernetes/pki/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=kube-proxy.conf kubectl config set-credentials kube-proxy \ --client-certificate=/etc/kubernetes/pki/kube-proxy.pem \ --client-key=/etc/kubernetes/pki/kube-proxy-key.pem \ --embed-certs=true \ --kubeconfig=kube-proxy.conf kubectl config set-context default \ --cluster=kubernetes \ --user=kube-proxy \ --kubeconfig=kube-proxy.conf kubectl config use-context default --kubeconfig=kube-proxy.conf cd $HOME 1八、配置啓動kube-apiserver # 只在test1 節點上操做 複製 etcd ca mkdir -pv /etc/kubernetes/pki/etcd cd $HOME/ssl cp etcd.pem etcd-key.pem ca-key.pem ca.pem /etc/kubernetes/pki/etcd 生成 service account key cd /etc/kubernetes/pki/ openssl genrsa -out /etc/kubernetes/pki/sa.key 2048 openssl rsa -in /etc/kubernetes/pki/sa.key -pubout -out /etc/kubernetes/pki/sa.pub ls /etc/kubernetes/pki/sa.* cd $HOME 配置啓動文件 cat >/etc/systemd/system/kube-apiserver.service<<EOF [Unit] Description=Kubernetes API Service Documentation=https://github.com/kubernetes/kubernetes After=network.target [Service] EnvironmentFile=-/etc/kubernetes/config EnvironmentFile=-/etc/kubernetes/apiserver ExecStart=/usr/local/kubernetes/bin/kube-apiserver \\ \$KUBE_LOGTOSTDERR \\ \$KUBE_LOG_LEVEL \\ \$KUBE_ETCD_ARGS \\ \$KUBE_API_ADDRESS \\ \$KUBE_SERVICE_ADDRESSES \\ \$KUBE_ADMISSION_CONTROL \\ \$KUBE_APISERVER_ARGS Restart=on-failure Type=notify LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF 配置參數變量文件 # 下面 kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy這些服務 都須要用到,這裏只配置一次,之後重複利用,後面的也寫了變量文件,只是爲了知道怎麼回事 cat >/etc/kubernetes/config<<EOF KUBE_LOGTOSTDERR="--logtostderr=true" KUBE_LOG_LEVEL="--v=2" EOF 配置apiserver # 注意參數--token-auth-file=/etc/kubernetes/token.csv 表示在 apiserver 中靜態配置bootstrap token,和後面開啓 bootstrap token 認證步驟相呼應,不是動態的,因此有過時時間, # 後面kubelet組件啓動參數中須要使用 kubelet-bootstrap.conf 文件向 kube-apiserver 發送 CSR 請求,--bootstrap-kubeconfig 文件裏面包含token和apiserver裏面的token是同樣的, cat >/etc/kubernetes/apiserver<<EOF KUBE_API_ADDRESS="--advertise-address=192.168.0.91" KUBE_ETCD_ARGS="--etcd-servers=https://192.168.0.91:2379 --etcd-cafile=/etc/kubernetes/pki/ca.pem --etcd-certfile=/etc/kubernetes/pki/etcd/etcd.pem --etcd-keyfile=/etc/kubernetes/pki/etcd/etcd-key.pem" KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.96.0.0/12" KUBE_ADMISSION_CONTROL="--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota" KUBE_APISERVER_ARGS="--allow-privileged=true --authorization-mode=Node,RBAC --enable-bootstrap-token-auth=true --token-auth-file=/etc/kubernetes/token.csv --service-node-port-range=0-60000 --tls-cert-file=/etc/kubernetes/pki/kube-apiserver.pem --tls-private-key-file=/etc/kubernetes/pki/kube-apiserver-key.pem --client-ca-file=/etc/kubernetes/pki/ca.pem --service-account-key-file=/etc/kubernetes/pki/sa.pub --enable-swagger-ui=true --secure-port=6443 --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --anonymous-auth=false --kubelet-client-certificate=/etc/kubernetes/pki/admin.pem --kubelet-client-key=/etc/kubernetes/pki/admin-key.pem" EOF 啓動 systemctl daemon-reload systemctl enable kube-apiserver systemctl start kube-apiserver systemctl status kube-apiserver 經過瀏覽器訪問測試 # 401 報錯正常,是由於沒有權限,不影響,之後解決 curl https://192.168.0.91:6443/swaggerapi [root@test1 ~]# curl https://192.168.0.91:6443/swaggerapi curl: (60) Peer's Certificate issuer is not recognized. More details here: http://curl.haxx.se/docs/sslcerts.html curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option. 1九、配置啓動kube-controller-manager # 只在test1 節點上操做 配置啓動文件 cat >/etc/systemd/system/kube-controller-manager.service<<EOF Description=Kubernetes Controller Manager Documentation=https://github.com/kubernetes/kubernetes After=network.target [Service] EnvironmentFile=-/etc/kubernetes/config EnvironmentFile=-/etc/kubernetes/controller-manager ExecStart=/usr/local/kubernetes/bin/kube-controller-manager \\ \$KUBE_LOGTOSTDERR \\ \$KUBE_LOG_LEVEL \\ \$KUBECONFIG \\ \$KUBE_CONTROLLER_MANAGER_ARGS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF 配置參數變量文件 # 配置kube-apiserver啓動文件時已經配置過參數變量文件,這裏就不須要再作,寫在這裏只是爲了知道下面配置文件裏的參數怎麼回事 cat >/etc/kubernetes/config<<EOF KUBE_LOGTOSTDERR="--logtostderr=true" KUBE_LOG_LEVEL="--v=2" EOF 配置controller-manager文件 # 特別注意:這裏的cluster-cidr地址要和 Kube-proxy裏面的cluster-cidr、flannel 裏面的Network 地址保持一致,這有這三個組件裏面有 10.244.0.0 cat >/etc/kubernetes/controller-manager<<EOF KUBECONFIG="--kubeconfig=/etc/kubernetes/kube-controller-manager.conf" KUBE_CONTROLLER_MANAGER_ARGS="--address=127.0.0.1 --cluster-cidr=10.244.0.0/16 --cluster-name=kubernetes --cluster-signing-cert-file=/etc/kubernetes/pki/ca.pem --cluster-signing-key-file=/etc/kubernetes/pki/ca-key.pem --service-account-private-key-file=/etc/kubernetes/pki/sa.key --root-ca-file=/etc/kubernetes/pki/ca.pem --leader-elect=true --use-service-account-credentials=true --node-monitor-grace-period=10s --pod-eviction-timeout=10s --allocate-node-cidrs=true --controllers=*,bootstrapsigner,tokencleaner" EOF 啓動 systemctl daemon-reload systemctl enable kube-controller-manager systemctl start kube-controller-manager systemctl status kube-controller-manager 20、配置啓動kube-scheduler # 只在test1 節點上操做 配置啓動文件 cat >/etc/systemd/system/kube-scheduler.service<<EOF [Unit] Description=Kubernetes Scheduler Plugin Documentation=https://github.com/kubernetes/kubernetes [Service] EnvironmentFile=-/etc/kubernetes/config EnvironmentFile=-/etc/kubernetes/scheduler ExecStart=/usr/local/kubernetes/bin/kube-scheduler \\ \$KUBE_LOGTOSTDERR \\ \$KUBE_LOG_LEVEL \\ \$KUBECONFIG \\ \$KUBE_SCHEDULER_ARGS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF 配置參數變量文件 # 配置kube-apiserver啓動文件時已經配置過參數變量文件,這裏就不須要再作,寫在這裏只是爲了知道下面配置文件裏的參數怎麼回事 cat >/etc/kubernetes/config<<EOF KUBE_LOGTOSTDERR="--logtostderr=true" KUBE_LOG_LEVEL="--v=2" EOF 配置scheduler文件 cat >/etc/kubernetes/scheduler<<EOF KUBECONFIG="--kubeconfig=/etc/kubernetes/kube-scheduler.conf" KUBE_SCHEDULER_ARGS="--leader-elect=true --address=127.0.0.1" EOF 啓動 systemctl daemon-reload systemctl enable kube-scheduler systemctl start kube-scheduler systemctl status kube-scheduler 給kubelet-bootstrap用戶受權 # 建立一個 clusterrolebinding,將 bootstrap token 文件中的 kubelet-bootstrap 用戶賦予 system:node-bootstrapper cluster 角色 # 默認狀況下,bootstrap這個 user 和 group 沒有建立 CSR 的權限,kubelet 會啓動失敗,因此要給kubelet-bootstrap角色受權 kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap # 若是沒有受權會出現下面錯誤: [root@test2 kubernetes]# journalctl -u kubelet |tail failed to run Kubelet: cannot create certificate signing request: certificatesigningrequests.certificates.k8s.io is forbidden: User "kubelet-bootstrap" cannot create certificatesigningrequests.certificates.k8s.io at the cluster scope 查看組件狀態 kubectl get componentstatuses [root@test2 ~]# kubectl get componentstatuses Unable to connect to the server: x509: certificate signed by unknown authority # 報錯緣由:通過排查後發現前面操做的幾個步驟中 ${KUBE_APISERVER} 這個變量寫成了 ${KUBE_ 又重作了一遍,正確的結果是下面 [root@test2 ~]# kubectl get componentstatuses NAME STATUS MESSAGE ERROR scheduler Healthy ok controller-manager Healthy ok etcd-0 Healthy {"health": "true"} # test1 節點安裝到此結束,下面開始單獨安裝node節點 21、單獨配置node 相關組件 環境配置 # 以下操做在全部節點操做 修改主機名 # 注意修改 各自節點對應的 主機名 sed -i '$a\hostname=test2' /etc/hostname sed -i '$a\hostname=test2' /etc/sysconfig/network && hostnamectl set-hostname test2 配置hosts解析 cat >>/etc/hosts<<EOF 192.168.0.91 test1 192.168.0.92 test2 192.168.0.93 test3 EOF 禁用selinux sed -i 's/SELINUX=permissive/SELINUX=disabled/' /etc/sysconfig/selinux sed -i 's/enforcing/disabled/g' /etc/selinux/config 永久關閉swap # 註釋/etc/fstab文件裏swap相關的行,須要重啓 sed -i 's/\/dev\/mapper\/centos-swap/#\/dev\/mapper\/centos-swap/g' /etc/fstab 臨時關閉swap swapoff -a 關掉防火牆 systemctl stop firewalld && systemctl disable firewalld 重啓 reboot 開啓forward iptables -P FORWARD ACCEPT 配置轉發相關參數 cat >> /etc/sysctl.d/k8s.conf <<EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 vm.swappiness=0 EOF 加載系統參數 sysctl --system 加載ipvs相關內核模塊 # 若是從新開機,須要從新加載 modprobe ip_vs modprobe ip_vs_rr modprobe ip_vs_wrr modprobe ip_vs_sh modprobe nf_conntrack_ipv4 lsmod | grep ip_vs 21.1、安裝docker # 只在 test2 節點上操做 # 注意:docker和flannel是一體的,哪一個節點上須要安裝flannel,哪一個節點上就須要安裝docker # docker 和kubelet組件、node狀態有關係, 以前停掉docker後,kubelet組件會自動停掉;node節點會變成 NotReady 狀態 # 可是停掉docker後,flanel、coredns 的pod 讓然是 running 狀態 # v1.11.0版本推薦使用docker v17.03, v1.11,v1.12,v1.13, 也可使用,再高版本的docker可能沒法正常使用。測試發現17.09沒法正常使用,不能使用資源限制(內存CPU) 卸載自帶docker yum remove -y docker-ce docker-ce-selinux container-selinux 下載Docker鏡像 下載連接:https://pan.baidu.com/s/1whfkq5wDODIew5_eqP63gA 提取碼:xmqq 下載連接:https://pan.baidu.com/s/1zZy_tbvuApZW2fsMPGv3Bg 提取碼:u3t3 添加至鏡像倉庫 rpm -ivh docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm rpm -ivh docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm 用安裝 Docker 和依賴包 yum install -y docker-ce-*.rpm 開機啓動 systemctl enable docker 啓動 docker 服務 systemctl start docker 21.2、部署 kubelet組件 # 只在test2 節點上操做 # kubelet的做用:向 test1 發起csr請求。 # 初次安裝完 kubelet,只要第一次啓動kubelet,經過kubelet get csr 就會獲得這串字符串:node-csr-Yiiv675wUCvQl3HH11jDr0cC9p3kbrXWrxvG3EjWGoE 下載、解壓安裝包 mkdir -p /server/software/k8s cd /server/software/k8s 下載連接:https://pan.baidu.com/s/1DXahqP8nXWP1aw5pIunJrw 提取碼:9xfp tar -xf kubernetes-server-linux-amd64.tar.gz 分發kubelet二進制文件 # 後面kubelet啓動文件須要用到kubelet二進制文件路徑 mkdir -p /usr/local/kubernetes/bin cp /server/software/k8s/kubernetes/server/bin/kubelet /usr/local/kubernetes/bin #這一步很關鍵 安裝kubectl工具 # kubecctl工具和kubelet服務不是一回事。安裝包解壓後包括 kubectl 工具,因此不須要單獨使用kubernetes-server-client-amd64.tar.gz 安裝包分發 kubectl 工具 # kubectl做用:當kubelet組件經過bootstrap token 認證後,kubectl 默認會從 ~/.kube/config 文件讀取 kube-apiserver 地址、證書、用戶名等信息; # admin.conf = ~/.kube/config,由於複製過來的 ; cp /server/software/k8s/kubernetes/server/bin/kubectl /usr/local/bin/kubectl 查看 kubectl 版本, # 出現下面的狀況就是正確的。did you specify the right host or port? 這個報錯忽略,由於尚未安裝kubelet服務 kubectl version [root@test1 bin]# kubectl version Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.0", GitCommit:"91e7b4fd31fcd3d5f436da26c980becec37ceefe", GitTreeState:"clean", BuildDate:"2018-06-27T20:17:28Z", GoVersion:"go1.10.2", Compiler:"gc", Platform:"linux/amd64"} The connection to the server localhost:8080 was refused - did you specify the right host or port? cd $HOME 拷貝admin.conf # 從test1上覆制admin.conf到test2節點 test2上建立目錄 mkdir -p /etc/kubernetes/ test2上覆制 scp /etc/kubernetes/admin.conf root@192.168.0.92:/etc/kubernetes/ 配置 /.kube/config 而且受權 # kubectl 默認從 ~/.kube/config 文件讀取 kube-apiserver 地址、證書、用戶名等信息,若是沒有配置,執行 kubectl 命令時可能會出錯: # /.kube/config 和 admin.conf 內容是同樣的,/.kube/config 是 admin.conf 複製過來的,改了下名字而已 rm -rf $HOME/.kube mkdir -p $HOME/.kube cp /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config 拷貝bootstrap.conf #從test1 上覆制 bootstrap.conf 到test2 節點 # 後面kubelet服務啓動參數中須要使用 kubelet-bootstrap.conf 向 kube-apiserver 發送 CSR 請求, # 當kubelet服務經過bootstrap token 認證後,kubectl 默認會從 ~/.kube/config 文件讀取 kube-apiserver 地址、證書、用戶名等信息; scp /etc/kubernetes/kubelet-bootstrap.conf root@192.168.0.92:/etc/kubernetes/ 安裝cni # kubelet 的啓動參數須要用到 cd /server/software/k8s 下載連接:https://pan.baidu.com/s/1DL1v4cH2SHUfobICjKXm3Q 提取碼:puel mkdir -p /opt/cni/bin mkdir -p /etc/cni/net.d/ tar -xf cni-plugins-amd64-v0.7.1.tgz -C /opt/cni/bin ls -l /opt/cni/bin cd $HOME 配置啓動kubelet 建立數據目錄 mkdir -p /data/kubelet 配置kubelet啓動文件 cat >/etc/systemd/system/kubelet.service<<EOF [Unit] Description=Kubernetes Kubelet Server Documentation=https://github.com/kubernetes/kubernetes After=docker.service Requires=docker.service [Service] WorkingDirectory=/data/kubelet EnvironmentFile=-/etc/kubernetes/config EnvironmentFile=-/etc/kubernetes/kubelet ExecStart=/usr/local/kubernetes/bin/kubelet \\ \$KUBE_LOGTOSTDERR \\ \$KUBE_LOG_LEVEL \\ \$KUBELET_CONFIG \\ \$KUBELET_HOSTNAME \\ \$KUBELET_POD_INFRA_CONTAINER \\ \$KUBELET_ARGS \ \$CADVISOR Restart=on-failure [Install] WantedBy=multi-user.target EOF 配置參數變量文件 cat >/etc/kubernetes/config<<EOF KUBE_LOGTOSTDERR="--logtostderr=true" KUBE_LOG_LEVEL="--v=2" EOF 配置kubelet文件 # 注意修改kubelet文件裏面的 --hostname-override= 要填寫test一、test二、test3 這三個節點改爲對應各自 ip ,或者各自的主機名。本實驗寫的主機名 # 若是--hostname-override= 填寫的是ip,那麼kubectl get nodes 獲得的name就顯示ip,若是填寫的是主機名,獲得的name就顯示主機名 # image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.1 這個鏡像跟 kubectl get componentstatuses 獲取不到資源沒有關係,跟docker也沒有關係 # 可是網上搜這個鏡像,說這個鏡像是基礎鏡像,目前被牆,最好下載放到本地 registry 上 # 注意 kubelet配置文件裏面的參數kubelet.conf 是kubelet啓動後生成的,不用管,就是這樣寫的 # 注意 /etc/kubernetes/pki 目錄裏面只放一個ca.pem 證書, # 啓動kubelet後/etc/kubernetes/pki 目錄裏面會自動生成四個文件 kubelet.crt、kubelet.key、kubelet-client-current.pem、kubelet-client-2019-01-22-10-07-06.pem # CADVISOR 代表開啓cadvisor監控,而後在啓動文件中加上 ExecStart=$CADVISOR 就能夠經過瀏覽器訪問cadvisor監控,不然是沒法訪問的, cat >/etc/kubernetes/kubelet<<EOF KUBELET_HOSTNAME="--hostname-override=test2" KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.1" CADVISOR="--cadvisor-port=4194 --storage-driver-db='cadvisor' --storage-driver-host='localhost:8086'" KUBELET_CONFIG="--config=/etc/kubernetes/kubelet-config.yml"KUBELET_ARGS="--bootstrap-kubeconfig=/etc/kubernetes/kubelet-bootstrap.conf --kubeconfig=/etc/kubernetes/kubelet.conf --cert-dir=/etc/kubernetes/pki --network-plugin=cni --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d/" EOF 拷貝ca.pem 證書 # 從test1 節點複製複製ca.pem 證書到test2 節點,下面kubelet-config.yml 文件參數須要用到 ca.pem tes2上建立目錄 mkdir -p /etc/kubernetes/pki test1上覆制文件 scp $HOME/ssl/ca.pem 192.168.0.92:/etc/kubernetes/pki/ 配置kubelet-config.yml文件 # 注意修改kubelet-config.yml相關ip,test1 test2 test3 使用各自ip # 注意下面kubelet-config.yml裏面的clusterDNS 地址要和coredns.yaml 裏面的 clusterIP 地址保持一致。只有kubelet、coredns裏面有 10.96.0.10,其餘的組件都沒有 cat >/etc/kubernetes/kubelet-config.yml<<EOF kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 address: 192.168.0.92 port: 10250 cgroupDriver: cgroupfs clusterDNS: - 10.96.0.10 clusterDomain: cluster.local. hairpinMode: promiscuous-bridge serializeImagePulls: false authentication: x509: clientCAFile: /etc/kubernetes/pki/ca.pem EOF 啓動 systemctl daemon-reload systemctl enable kubelet systemctl start kubelet # 啓動後就會生成csr systemctl status kubelet 查看日誌 # 啓動 kubelet後查看日誌會有報錯 # 報錯緣由是由於kubelet配置了network-plugin=cni,可是還沒安裝網絡插件 flannel,因此狀態會是NotReady,會報上面的錯誤,不想看這個報錯或者不須要網絡,就修改kubelet配置文件,去掉network-plugin=cni 就能夠了 [root@test2 ~]# journalctl -u kubelet |tail network plugin is not ready: cni config uninitialized 21.3、經過csr請求 # 在 test2 節點上操做就能夠 # 經過csr請求的目的就是要生成一個nodes 節點 # 注意:node-csr-Yiiv675wUCvQl3HH11jDr0cC9p3kbrXWrxvG3EjWGoE 這個長字符串是kubelet 初次啓動後生成的, # 查看csr # 若是獲取不到csr看日誌會出現下面錯誤: [root@test2 kubernetes]# journalctl -u kubelet |tail failed to run Kubelet: cannot create certificate signing request: certificatesigningrequests.certificates.k8s.io is forbidden: User "kubelet-bootstrap" cannot create certificatesigningrequests.certificates.k8s.io at the cluster scope # 緣由是由於沒有給kubelet-bootstrap受權,受權便可 kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap kubectl get csr 執行結果 [root@test2 ~]# kubectl get csr NAME AGE REQUESTOR CONDITION node-csr-Yiiv675wUCvQl3HH11jDr0cC9p3kbrXWrxvG3EjWGoE 18s kubelet-bootstrap Pending You have new mail in /var/spool/mail/root 經過csr請求,下面的長字符串填寫上一步的結果, kubectl certificate approve node-csr-Yiiv675wUCvQl3HH11jDr0cC9p3kbrXWrxvG3EjWGoE 執行結果: [root@test2 ~]# kubectl certificate approve node-csr-Yiiv675wUCvQl3HH11jDr0cC9p3kbrXWrxvG3EjWGoE certificatesigningrequest.certificates.k8s.io/node-csr-Yiiv675wUCvQl3HH11jDr0cC9p3kbrXWrxvG3EjWGoE approved 查看kubelet啓動後生成的文件 說明:kubelet 啓動後使用 --bootstrap-kubeconfig 向 kube-apiserver 發送 CSR 請求,當這個 CSR 被 approve 後,kube-controller-manager 爲 kubelet 建立 TLS 客戶端證書、私鑰和 --kubeletconfig 文件。 kubelet.conf文件決定了csr的存在,若是要想從新獲取csr,能夠停掉kubelet,刪除kubelet.conf文件,重啓kubelet就能夠得到csr ls -l /etc/kubernetes/kubelet.conf ls -l /etc/kubernetes/pki/kubelet* 查看結果 [root@test2 ~]# ls -l /etc/kubernetes/kubelet.conf -rw------- 1 root root 2295 Jan 22 10:07 /etc/kubernetes/kubelet.conf [root@test2 ~]# ls -l /etc/kubernetes/pki/kubelet* -rw------- 1 root root 1273 Jan 22 10:07 /etc/kubernetes/pki/kubelet-client-2019-01-22-10-07-06.pem lrwxrwxrwx 1 root root 58 Jan 22 10:07 /etc/kubernetes/pki/kubelet-client-current.pem -> /etc/kubernetes/pki/kubelet-client-2019-01-22-10-07-06.pem -rw-r--r-- 1 root root 2181 Jan 22 02:10 /etc/kubernetes/pki/kubelet.crt -rw------- 1 root root 1675 Jan 22 02:10 /etc/kubernetes/pki/kubelet.key 查看節點 # 此時節點狀態爲 NotReady,須要安裝flannel網絡後才能夠ready; # 可是此時就能夠設置集羣角色 # 此時查看只有一個node節點是由於test1 上並無安裝 kubelet 組件,只要 test1 安裝上kubelet而且啓動成功,就會生成csr,經過csr後,就會成爲node節點 # 若是 test1 上也安裝了kubelet,就能夠把 test1 節點設置爲master,由於 test1 節點上面安裝了 kube-apiserver、 kube-controller-manager、kube-scheduler # tes2 節點必須是node 節點,由於它沒有安裝 kube-apiserver、 kube-controller-manager、kube-scheduler 這幾個組件 kubectl get nodes [root@test2 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION test2 NotReady <none> 9h v1.11.0 設置集羣角色 # 在test2 節點上操做就能夠 # 設置 test2 爲 node 角色 kubectl label nodes test2 node-role.kubernetes.io/node= [root@test2 ~]# kubectl label nodes test2 node-role.kubernetes.io/node= node/test2 labeled 再次查看節點 [root@test2 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION test2 NotReady node 2m v1.11.0 21.四、配置啓動kube-proxy # 只在 test2 節點上操做 # 注意:關掉 kube-proxy 後仍然能夠訪問 svc curl "10.103.38.143:80" ,kube-proxy 的做用目前尚未發現 下載、解壓安裝包(省略) cd /server/software/k8s 下載連接:https://pan.baidu.com/s/1DXahqP8nXWP1aw5pIunJrw 提取碼:9xfp tar -xf kubernetes-server-linux-amd64.tar.gz 分發kube-proxy二進制文件 # 後面kube-proxy.service啓動文件須要用到kube-proxy二進制文件路徑 mkdir -p /usr/local/kubernetes/bin cp /server/software/k8s/kubernetes/server/bin/kube-proxy /usr/local/kubernetes/bin #這一步很關鍵 安裝依賴包 yum install -y conntrack-tools 拷貝kube-proxy.conf文件 把 test1 節點上的kube-proxy.conf複製到/etc/kubernetes/ 目錄下,kube-proxy.service啓動參數中proxy文件須要用到kube-proxy.conf scp /etc/kubernetes/kube-proxy.conf 192.168.0.92:/etc/kubernetes/ 配置啓動文件 cat >/etc/systemd/system/kube-proxy.service<<EOF [Unit] Description=Kubernetes Kube-Proxy Server Documentation=https://github.com/kubernetes/kubernetes After=network.target [Service] EnvironmentFile=-/etc/kubernetes/config EnvironmentFile=-/etc/kubernetes/proxy ExecStart=/usr/local/kubernetes/bin/kube-proxy \\ \$KUBE_LOGTOSTDERR \\ \$KUBE_LOG_LEVEL \\ \$KUBECONFIG \\ \$KUBE_PROXY_ARGS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF 配置參數變量文件 # 前面配置kubelet組件時已經配置過參數變量文件,這裏就不須要配置,寫在這裏這是知道是怎麼回事 cat >/etc/kubernetes/config<<EOF KUBE_LOGTOSTDERR="--logtostderr=true" KUBE_LOG_LEVEL="--v=2" EOF 配置proxy文件 # 注意修改相關ip,test1 test2 test3 使用各自ip # 看下面proxy文件'--proxy-mode=iptables',因爲採用iptables模式,由於 ipvs 模式在centos7上有bug沒法正常使用,1.11.0 之後的版本就可以使用 ipvs 模式了, # 本實驗採用centos7.五、kubernetes 1.11.0 版本,因此使用iptables模式, # 特別注意:下面的cluster-cidr地址要和controller-manager裏面的cluster-cidr、flannel 裏面的Network 地址保持一致,這有這三個組件裏面有 10.244.0.0 cat >/etc/kubernetes/proxy<<EOF KUBECONFIG="--kubeconfig=/etc/kubernetes/kube-proxy.conf" KUBE_PROXY_ARGS="--bind-address=192.168.0.92 --proxy-mode=iptables --hostname-override=192.168.0.92 --cluster-cidr=10.244.0.0/16" EOF 啓動 systemctl daemon-reload systemctl enable kube-proxy systemctl start kube-proxy systemctl status kube-proxy 21.5、安裝flannel網絡 # 只在test2 節點上操做 # flannel 做用之一: 讓 node節點從 NotReady狀態變爲ready狀態 # 注意: flanel 只須要安裝一次,不須要再往 test1 節點或者test2 節點上安裝 flanel # 只有在安裝了docker的節點上才能夠安裝flannel # 注意下面的網卡名稱要填寫對應的網卡名稱 下載配置文件 mkdir flannel && cd flannel 下載連接:https://pan.baidu.com/s/1kdrYzXYzURTzO_tXtv_R1A 提取碼:3kgd 查看下載的文件 [root@test2 flannel]# ls kube-flannel.yml 修改ip地址: # flannel網絡 分三種網絡 node network、service network、flannel network # node network:承載kubernetes集羣中各個「物理」Node(master和node)通訊的網絡 # 下面Network 就是 node network,由於當前尚未安裝 flannel,test2 節點爲 NotReady 狀態;安裝完 flannel後就是ready狀態, # 特別注意:下面的Network 地址要和controller-manager裏面的cluster-cidr、kube-proxy裏面的 cluster-cidr地址保持一致,這有這三個組件裏面有 10.244.0.0 [root@test2 flannel]# vi kube-flannel.yml net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan" } } 修改鏡像 # 因爲自帶的鏡像被牆,沒法下載,因此修改鏡像爲國內源 image: registry.cn-shanghai.aliyuncs.com/gcr-k8s/flannel:v0.10.0-amd64 # 注意 kube-flannel.yml 文件裏面有兩個 鏡像都須要改 [root@test2 flannel]# vi kube-flannel.yml containers: - name: kube-flannel image: registry.cn-shanghai.aliyuncs.com/gcr-k8s/flannel:v0.10.0-amd64 command: - /opt/bin/flanneld args: - --ip-masq - --kube-subnet-mgr - --iface=ens33 添加網卡參數 # 注意 - --iface=ens33 這個ens33 是 192.168.0.92 這臺虛擬機的網卡信息 # 若是Node有多個網卡的話,參考flannel issues 39701,https://github.com/kubernetes/kubernetes/issues/39701 # 目前須要在kube-flannel.yml中使用--iface參數指定集羣主機內網網卡的名稱,不然可能會出現dns沒法解析。容器沒法通訊的狀況, # flanneld啓動參數加上--iface=<iface-name> [root@test2 flannel]# vi kube-flannel.yml containers: - name: kube-flannel image: registry.cn-shanghai.aliyuncs.com/gcr-k8s/flannel:v0.10.0-amd64 command: - /opt/bin/flanneld args: - --ip-masq - --kube-subnet-mgr - --iface=ens33 啓動flanel kubectl apply -f kube-flannel.yml 查看pod # 若是flanel啓動失敗,頗有可能鏡像拉取失敗,因此最好仍是自建一個鏡像倉庫。有點慢等一會 kubectl get pods -n kube-system kubectl get svc [root@test2 flannel]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE kube-flannel-ds-zb2r2 1/1 Running 0 18s [root@test2 flannel]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22h 查看節點狀態 # 當 flannel pod 所有啓動以後,節點狀態才爲 Ready kubectl get no [root@test2 flannel]# kubectl get no NAME STATUS ROLES AGE VERSION test2 Ready node 11h v1.11.0 21.6、安裝coredns # 只在 test2 節點上操做 # coredns的做用:是實現pod裏面的DNS解析,就是能夠經過svc(service)來訪問服務,例如:curl nginx-service ,curl + svc # 注意:coredns 只安裝一次就能夠,不須要再往master角色或 其餘node角色上安裝 # 注意下面用的 coredns 1.2.0 版本 安裝jq工具 # 以前安裝coredns報錯找不到jq, 因此配置jq 源,而後用yum安裝,安裝jq 參照:https://www.cnblogs.com/effortsing/p/10307424.html yum install jq -y 下載coredns安裝文件 cd $HOME && mkdir coredns && cd coredns 下載連接:https://pan.baidu.com/s/1z7x4z2k2w3rdhOt89FDPww 提取碼:7vkf 查看下載的文件 [root@test2 coredns]# ls coredns.yaml 修改配置文件 # 把文件裏面的ip地址修改成10.96.0.10, # 注意:下面coredns.yaml裏面的clusterIP 地址要和 kubelet組件中kubelet-config.yml 配置文件裏面的 clusterDNS 地址保持一致。只有kubelet、coredns裏面有 10.96.0.10 [root@test2 coredns]# vi coredns.yaml spec: selector: k8s-app: kube-dns clusterIP: 10.96.0.10 ports: 啓動coredns kubectl apply -f coredns.yaml 查看coredns # 過幾分鐘纔會running ,有點慢 kubectl get pods -n kube-system kubectl get svc -n kube-system [root@test2 coredns]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE coredns-6c65fc5cbb-8ntpv 1/1 Running 0 34m coredns-6c65fc5cbb-sj65c 1/1 Running 0 34m kube-flannel-ds-zb2r2 1/1 Running 0 2h [root@test2 coredns]# kubectl get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 34m 測試coredns功能 # 啓動一個nginx容器,而後進行訪問nginx服務進行測試看是否能訪問 下載nginx.yaml文件 下載連接:https://pan.baidu.com/s/1PV8jyDhb8yBy6uyaeMMpSQ 提取碼:xt5f 查看下載的文件 [root@test2 ~]# ls nginx.yaml 配置nginx鏡像 # 用docker 找一個簡單的nginx鏡像,替換 nginx.yaml 裏面的鏡像,由於nginx.yaml裏面的鏡像都已通過時,沒法下載 docker search nginx [root@test2 ~]# docker search nginx nginxdemos/hello NGINX webserver that serves a simple page ... 9 [OK] [root@test2 ~]# vi nginx.yaml spec: containers: - name: http-test-con image: nginxdemos/hello ports: - containerPort: 80 建立nginx實例 # 須要過幾分鐘,拉取鏡像很慢的, kubectl create -f nginx.yaml 查看pod狀態 # 注意:使用kubectl工具養成帶上命名空間的習慣,雖然不帶default命名空間默認帶着的,可是這是個習慣,以前老是由於沒有帶命名空間出錯,排查半天,單耽誤時間, kubectl get deploy -o wide -n default kubectl get pods -o wide -n default kubectl get svc -o wide -n default kubectl describe svc example-service -n default [root@test2 ~]# kubectl get deploy -o wide -n default NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR http-test-dm2 1 1 1 1 52m http-test-con nginxdemos/hello name=http-test-dm2 [root@test2 ~]# kubectl get pods -o wide -n default NAME READY STATUS RESTARTS AGE IP NODE http-test-dm2-76d4b58b47-f4pqm 1/1 Running 0 52m 10.244.0.12 192.168.0.92 [root@test2 ~]# kubectl get svc -o wide -n default NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR http-nginx-ser NodePort 10.103.38.143 <none> 80:31000/TCP 5m name=http-test-dm2 kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d <none> [root@test2 ~]# kubectl describe pod http-test-dm2-76d4b58b47-f4pqm -n default 容器內測試coredns解析 # 啓動一個具備解析功能的 dns 實例,而後進到 pod 裏面用 nslookup、curl 工具進行訪問測試,下面這個實例啓動慢,等幾分鐘, # 若是啓動失敗,經過看日誌得知沒法拉取鏡像 infoblox/dnstools,極可能這個鏡像不存在了,那就經過 docker search dns 找一個dns鏡像代替infoblox/dnstools鏡像 kubectl run -it --rm --image=infoblox/dnstools dns-client nslookup kubernetes nslookup nginx-service curl nginx-service 執行結果: [root@test2 ~]# kubectl run -it --rm --image=infoblox/dnstools dns-client If you don't see a command prompt, try pressing enter. dnstools# nslookup kubernetes Server: 10.96.0.10 Address: 10.96.0.10#53 Name: kubernetes.default.svc.cluster.local Address: 10.96.0.1 dnstools# nslookup http-nginx-ser Server: 10.96.0.10 Address: 10.96.0.10#53 Name: http-nginx-ser.default.svc.cluster.local Address: 10.103.38.143 dnstools# curl http-nginx-ser <!DOCTYPE html> <html> <head> <title>Hello World</title> 容器外測試coredns解析 # 注意:是在 test2 節點進行訪問訪測試的, # 若是此時 去 test1 節點上訪問,是沒法訪問的,由於test1 節點上尚未安裝kubelet,什麼角色也不是,只要成爲node或master角色 就能夠訪問,測試過 # 若是test1節點安裝了 kubelet,而且是ready狀態,就必定能經過 curl "10.103.38.143:80" 訪問到,已經測試過, # coredns 多是節點內部域名解析,Traefik-ingress是節點外部域名解析 # 10.103.38.143 是查看svc時獲取到的clusterip,svc是service的縮寫 curl "10.103.38.143:80" 執行結果: [root@test2 ~]# curl "10.103.38.143:80" -n default <!DOCTYPE html> <html> <head> <title>Hello World</title> 經過瀏覽器訪問測試 # 31000 是查看svc時獲取到的 nodeport http://192.168.0.92:31000/ 22、關機重啓驗證 # 兩個節點都操做 # test一、test2 節點都關機重啓,從新執行上面的過程驗證是否無缺。本實驗重啓這兩個節點後一切是正常的 清理 kubectl delete -f nginx.yaml 23、回頭配置 test1 節點加入集羣 # 只在test1 節點上操做 # 目的是 在 test1 節點上安裝node組件,設置test1節點爲master節點。 # 注意:無論要設置master角色 仍是設置爲node角色,前提必須先安裝node組件,主要是kubelet 組件。就是說先把節點加入集羣,才能設置角色, # 加入集羣就是安裝啓動 kubelet 組件,經過csr請求後,就能夠加入集羣,而後才能夠設置集羣角色 23.1、安裝docker # 只在 test1 節點上操做 # 注意:docker和flannel是一體的,哪一個節點上須要安裝flannel,哪一個節點上就須要安裝docker # docker 和kubelet組件、node狀態有關係, 以前停掉docker後,kubelet組件會自動停掉;node節點會變成 NotReady 狀態 # 可是停掉docker後,flanel、coredns 的pod 讓然是 running 狀態 # v1.11.0版本推薦使用docker v17.03, v1.11,v1.12,v1.13, 也可使用,再高版本的docker可能沒法正常使用。測試發現17.09沒法正常使用,不能使用資源限制(內存CPU) 卸載自帶docker yum remove -y docker-ce docker-ce-selinux container-selinux 下載Docker鏡像 下載連接:https://pan.baidu.com/s/1whfkq5wDODIew5_eqP63gA 提取碼:xmqq 下載連接:https://pan.baidu.com/s/1zZy_tbvuApZW2fsMPGv3Bg 提取碼:u3t3 添加至鏡像倉庫 rpm -ivh docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm rpm -ivh docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm 用安裝 Docker 和依賴包 yum install -y docker-ce-*.rpm 開機啓動 systemctl enable docker 啓動 docker 服務 systemctl start docker 23.2、部署 kubelet組件 # 只在test1 節點上操做 # kubelet的做用:向 test1 發起csr請求。 # 初次安裝完 kubelet,只要第一次啓動kubelet,經過kubelet get csr 就會獲得這串字符串:node-csr-Yiiv675wUCvQl3HH11jDr0cC9p3kbrXWrxvG3EjWGoE 下載、解壓安裝包 mkdir -p /server/software/k8s cd /server/software/k8s 下載連接:https://pan.baidu.com/s/1DXahqP8nXWP1aw5pIunJrw 提取碼:9xfp tar -xf kubernetes-server-linux-amd64.tar.gz 分發kubelet二進制文件 # 後面kubelet啓動文件須要用到kubelet二進制文件路徑 mkdir -p /usr/local/kubernetes/bin cp /server/software/k8s/kubernetes/server/bin/kubelet /usr/local/kubernetes/bin #這一步很關鍵 查看組件狀態 kubectl get componentstatuses [root@test1 ~]# kubectl get componentstatuses Unable to connect to the server: x509: certificate signed by unknown authority # 報錯緣由:通過排查後發現前面操做的幾個步驟中 ${KUBE_APISERVER} 這個變量寫成了 ${KUBE_ 又重作了一遍,正確的結果是下面 [root@test2 ~]# kubectl get componentstatuses NAME STATUS MESSAGE ERROR scheduler Healthy ok controller-manager Healthy ok etcd-0 Healthy {"health": "true"} 配置 /.kube/config 而且受權 # kubectl 默認從 ~/.kube/config 文件讀取 kube-apiserver 地址、證書、用戶名等信息,若是沒有配置,執行 kubectl 命令時可能會出錯: # /.kube/config 和 admin.conf 內容是同樣的,/.kube/config 是 admin.conf 複製過來的,改了下名字而已 rm -rf $HOME/.kube mkdir -p $HOME/.kube cp /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config 安裝cni # kubelet 的啓動參數須要用到 cd /server/software/k8s 下載連接:https://pan.baidu.com/s/1DL1v4cH2SHUfobICjKXm3Q 提取碼:puel mkdir -p /opt/cni/bin tar -xf cni-plugins-amd64-v0.7.1.tgz -C /opt/cni/bin ls -l /opt/cni/bin cd $HOME 配置啓動kubelet 建立數據目錄 mkdir -p /data/kubelet 配置kubelet啓動文件 cat >/etc/systemd/system/kubelet.service<<EOF [Unit] Description=Kubernetes Kubelet Server Documentation=https://github.com/kubernetes/kubernetes After=docker.service Requires=docker.service [Service] WorkingDirectory=/data/kubelet EnvironmentFile=-/etc/kubernetes/config EnvironmentFile=-/etc/kubernetes/kubelet ExecStart=/usr/local/kubernetes/bin/kubelet \\ \$KUBE_LOGTOSTDERR \\ \$KUBE_LOG_LEVEL \\ \$KUBELET_CONFIG \\ \$KUBELET_HOSTNAME \\ \$KUBELET_POD_INFRA_CONTAINER \\ \$KUBELET_ARGS \\ \$CADVISOR Restart=on-failure [Install] WantedBy=multi-user.target EOF 配置參數變量文件 cat >/etc/kubernetes/config<<EOF KUBE_LOGTOSTDERR="--logtostderr=true" KUBE_LOG_LEVEL="--v=2" EOF 配置kubelet文件 # 注意修改kubelet文件裏面的 --hostname-override= 要填寫test一、test二、test3 這三個節點改爲對應各自 ip ,或者各自的主機名。本實驗寫的是主機名 # 若是--hostname-override= 填寫的是ip,那麼kubectl get nodes 獲得的name就顯示ip,若是填寫的是主機名,獲得的name就顯示主機名 # image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.1 這個鏡像跟 kubectl get componentstatuses 獲取不到資源沒有關係,跟docker也沒有關係 # 可是網上搜這個鏡像,說這個鏡像是基礎鏡像,目前被牆,最好下載放到本地 registry 上 # 注意 kubelet配置文件裏面的參數kubelet.conf 是kubelet啓動後生成的,不用管,就是這樣寫的 # 注意 /etc/kubernetes/pki 目錄裏面只放一個ca.pem 證書, # 啓動kubelet後/etc/kubernetes/pki 目錄裏面會自動生成四個文件 kubelet.crt、kubelet.key、kubelet-client-current.pem、kubelet-client-2219-01-22-10-07-06.pem # CADVISOR 代表開啓cadvisor監控,而後在啓動文件中加上 ExecStart=$CADVISOR 就能夠經過瀏覽器訪問cadvisor監控,不然是沒法訪問的, cat >/etc/kubernetes/kubelet<<EOF KUBELET_HOSTNAME="--hostname-override=test2" KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.1" KUBELET_CONFIG="--config=/etc/kubernetes/kubelet-config.yml" CADVISOR="--cadvisor-port=4194 --storage-driver-db='cadvisor' --storage-driver-host='localhost:8086'" KUBELET_ARGS="--bootstrap-kubeconfig=/etc/kubernetes/kubelet-bootstrap.conf --kubeconfig=/etc/kubernetes/kubelet.conf --cert-dir=/etc/kubernetes/pki --network-plugin=cni --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d" EOF 配置kubelet-config.yml文件 # 注意修改kubelet-config.yml相關ip,test1 test2 test3 使用各自ip # 注意下面kubelet-config.yml裏面的clusterDNS 地址要和coredns.yaml 裏面的 clusterIP 地址保持一致。只有kubelet、coredns裏面有 10.96.0.10,其餘的組件都沒有 cat >/etc/kubernetes/kubelet-config.yml<<EOF kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 address: 192.168.0.91 port: 10250 cgroupDriver: cgroupfs clusterDNS: - 10.96.0.10 clusterDomain: cluster.local. hairpinMode: promiscuous-bridge serializeImagePulls: false authentication: x509: clientCAFile: /etc/kubernetes/pki/ca.pem EOF 啓動 systemctl daemon-reload systemctl enable kubelet systemctl start kubelet # 啓動後就會生成 csr systemctl status kubelet 查看日誌 # 啓動 kubelet後查看日誌會有報錯 # 報錯緣由是由於kubelet配置了network-plugin=cni,可是還沒安裝網絡插件 flannel,因此狀態會是NotReady,會報上面的錯誤,不想看這個報錯或者不須要網絡,就修改kubelet配置文件,去掉network-plugin=cni 就能夠了 [root@test2 ~]# journalctl -u kubelet |tail network plugin is not ready: cni config uninitialized 23.3、經過csr請求 # 在 test1 節點上操做,也能夠在test2 節點上操做 # 經過csr請求的目的就是要加入集羣 # 注意:node-csr-Yiiv675wUCvQl3HH11jDr0cC9p3kbrXWrxvG3EjWGoE 這個長字符串是kubelet 初次啓動後生成的, # 在test2 節點上操做就能夠 查看csr # 若是獲取不到csr看日誌會出現下面錯誤: [root@test2 kubernetes]# journalctl -u kubelet |tail failed to run Kubelet: cannot create certificate signing request: certificatesigningrequests.certificates.k8s.io is forbidden: User "kubelet-bootstrap" cannot create certificatesigningrequests.certificates.k8s.io at the cluster scope # 緣由是由於沒有給kubelet-bootstrap受權,受權便可 kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap kubectl get csr 執行結果 [root@test1 ~]# kubectl get csr NAME AGE REQUESTOR CONDITION node-csr-0BVhjayOeu96EHndLS4vC4bijfh9zr2gH6iJCsmfOvQ 18s kubelet-bootstrap Pending 經過csr請求,下面的長字符串填寫上一步的結果, kubectl certificate approve node-csr-0BVhjayOeu96EHndLS4vC4bijfh9zr2gH6iJCsmfOvQ [root@test1 ~]# kubectl certificate approve node-csr-0BVhjayOeu96EHndLS4vC4bijfh9zr2gH6iJCsmfOvQ certificatesigningrequest.certificates.k8s.io/node-csr-0BVhjayOeu96EHndLS4vC4bijfh9zr2gH6iJCsmfOvQ approved 查看kubelet啓動後生成的文件 說明:kubelet 啓動後使用 --bootstrap-kubeconfig 向 kube-apiserver 發送 CSR 請求,當這個 CSR 被 approve 後,kube-controller-manager 爲 kubelet 建立 TLS 客戶端證書、私鑰和 --kubeletconfig 文件。 kubelet.conf文件決定了csr的存在,若是要想從新獲取csr,能夠停掉kubelet,刪除kubelet.conf文件,重啓kubelet就能夠得到csr ls -l /etc/kubernetes/kubelet.conf ls -l /etc/kubernetes/pki/kubelet* 查看結果 [root@test2 ~]# ls -l /etc/kubernetes/kubelet.conf -rw------- 1 root root 2295 Jan 22 10:07 /etc/kubernetes/kubelet.conf [root@test2 ~]# ls -l /etc/kubernetes/pki/kubelet* -rw------- 1 root root 1273 Jan 22 10:07 /etc/kubernetes/pki/kubelet-client-2019-01-22-10-07-06.pem lrwxrwxrwx 1 root root 58 Jan 22 10:07 /etc/kubernetes/pki/kubelet-client-current.pem -> /etc/kubernetes/pki/kubelet-client-2019-01-22-10-07-06.pem -rw-r--r-- 1 root root 2181 Jan 22 02:10 /etc/kubernetes/pki/kubelet.crt -rw------- 1 root root 1675 Jan 22 02:10 /etc/kubernetes/pki/kubelet.key 查看節點狀態 # 以前作完上一步,就去吃飯了,飯後回來正想安裝 flanel,忽然一看 192.168.0.91是Ready狀態,因此等一會狀態就會發生改變 # 解釋:此時節點狀態爲Ready,由於test2 節點已經安裝過 flannel,這裏就不須要再安裝。因此只要經過csr就是ready狀態, [root@test1 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION test1 Ready <none> 2h v1.11.0 test2 Ready node 21h v1.11.0 設置集羣角色 # 在test1 節點上操做 # 設置 test1 爲 master 角色 kubectl label nodes test1 node-role.kubernetes.io/master= # 設置 master 通常狀況下不接受負載 kubectl taint nodes test1 node-role.kubernetes.io/master=true:NoSchedule master運行pod kubectl taint nodes master.k8s node-role.kubernetes.io/master- master不運行pod kubectl taint nodes master.k8s node-role.kubernetes.io/master=:NoSchedule 執行結果: [root@test1 ~]# kubectl label nodes test1 node-role.kubernetes.io/master= node/192.168.0.91 labeled [root@master ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION test1 Ready master 2h v1.11.0 test1 Ready node 21h v1.11.0 [root@test1 k8s]# kubectl taint nodes test1 node-role.kubernetes.io/master=true:NoSchedule node/test1 tainted 23.四、配置啓動kube-proxy # 只在 test1 節點上操做 # 注意:關掉 kube-proxy 後仍然能夠訪問 svc curl "10.103.38.143:80" ,kube-proxy 的做用目前尚未發現 下載、解壓安裝包 mkdir -p /server/software/k8s cd /server/software/k8s 下載連接:https://pan.baidu.com/s/1DXahqP8nXWP1aw5pIunJrw 提取碼:9xfp tar -xf kubernetes-server-linux-amd64.tar.gz 分發kube-proxy二進制文件 # 後面kube-proxy.service啓動文件須要用到kube-proxy二進制文件路徑 mkdir -p /usr/local/kubernetes/bin cp /server/software/k8s/kubernetes/server/bin/kube-proxy /usr/local/kubernetes/bin #這一步很關鍵 安裝依賴包 yum install -y conntrack-tools 拷貝kube-proxy.conf文件 把 test1 節點上的kube-proxy.conf複製到/etc/kubernetes/ 目錄下,kube-proxy.service啓動參數中proxy文件須要用到kube-proxy.conf cp /etc/kubernetes/kube-proxy.conf /etc/kubernetes/ 配置啓動文件 cat >/etc/systemd/system/kube-proxy.service<<EOF [Unit] Description=Kubernetes Kube-Proxy Server Documentation=https://github.com/kubernetes/kubernetes After=network.target [Service] EnvironmentFile=-/etc/kubernetes/config EnvironmentFile=-/etc/kubernetes/proxy ExecStart=/usr/local/kubernetes/bin/kube-proxy \\ \$KUBE_LOGTOSTDERR \\ \$KUBE_LOG_LEVEL \\ \$KUBECONFIG \\ \$KUBE_PROXY_ARGS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF 配置參數變量文件 # 前面配置kubelet組件時已經配置過參數變量文件,這裏就不須要配置,寫在這裏這是知道是怎麼回事 cat >/etc/kubernetes/config<<EOF KUBE_LOGTOSTDERR="--logtostderr=true" KUBE_LOG_LEVEL="--v=2" EOF 配置proxy文件 # 注意修改相關ip,test1 test2 test3 使用各自ip # 看下面proxy文件'--proxy-mode=iptables',因爲採用iptables模式,由於 ipvs 模式在centos7上有bug沒法正常使用,1.11.0 之後的版本就可以使用 ipvs 模式了, # 本實驗採用centos7.五、kubernetes 1.11.0 版本,因此使用iptables模式, # 特別注意:下面的cluster-cidr地址要和controller-manager裏面的cluster-cidr、flannel 裏面的Network 地址保持一致,這有這三個組件裏面有 10.244.0.0 cat >/etc/kubernetes/proxy<<EOF KUBECONFIG="--kubeconfig=/etc/kubernetes/kube-proxy.conf" KUBE_PROXY_ARGS="--bind-address=192.168.0.91 --proxy-mode=iptables --hostname-override=192.168.0.91 --cluster-cidr=10.244.0.0/16" EOF 啓動 systemctl daemon-reload systemctl enable kube-proxy systemctl start kube-proxy systemctl status kube-proxy 23.5、容器外測試coredns解析 # 只在 test1 節點上操做 # 因爲以前 test2節點已經安裝過coredns,因此 test1節點就不須要安裝了,直接測試 # 這裏的 10.103.38.143:80 是以前在 test2 節點上查詢svc 獲得的結果 # 訪問成功, [root@master k8s]# curl "10.103.38.143:80" <!DOCTYPE html> <html> <head> <title>Hello World</title> 23.6、瀏覽器訪問 cadvisor監控服務 瀏覽器訪問http://192.168.0.91:4194/ 參照文檔: http://www.maogx.win/posts/35/ http://www.maogx.win/ https://juejin.im/user/59ffa2836fb9a0451c39c64f/posts http://blog.itpub.net/10995764/viewspace-2124022/