k8s-基礎篇

搭建k8s環境

Myapp鏡像部署
擴容pod
自愈
負載均衡
DNS
外網訪問
滾動更新
YAML方式部署
獨立部署pod
RS副本控制器
Deployment-自動擴容
Deployment-更新版本
Deployment-回滾版本
daemonset
job
cronJob
初始化容器

鏈接://pan.baidu.com/s/1U_AWBEXsjESZ2eDPIH4TFA
提取碼:gmze

網盤裡有一些配置文件和系統組件可以自行下載使用。環境搭建很麻煩,如果發現失敗可與我聯繫或按照文檔重試幾次。以下步驟是完全可用的!

搭建k8s環境

環境準備

環境3台centos虛擬機每台虛擬機2核2G,一個master兩個node。搭建k8s環境如沒有特殊說明所有操作均在三個節點同時操作。

#1、給每一台機器設置主機名
hostnamectl set-hostname k8s-master01
hostnamectl set-hostname k8s-node01
hostnamectl set-hostname k8s-node02
#查看主機名
hostname
#配置IP host映射關係
vi /etc/hosts
192.168.66.10 k8s-master01
192.168.66.11 k8s-node01
192.168.66.12 k8s-node02
 
#2、安裝依賴環境,注意:每一台機器都需要安裝此依賴環境
yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat
libseccomp wget vim net-tools git iproute lrzsz bash-completion tree bridge-
utils unzip bind-utils gcc
 
#3、安裝iptables,啟動iptables,設置開機自啟,清空iptables規則,保存當前規則到默認規則
# 關閉防火牆
systemctl stop firewalld && systemctl disable firewalld
# 置空iptables
yum -y install iptables-services && systemctl start iptables && systemctl enable
iptables && iptables -F && service iptables save
 
#4、關閉selinux
#閉swap分區【虛擬記憶體】並且永久關閉虛擬記憶體
swapoff -a && sed -i ‘/ swap / s/^\(.*\)$/#\1/g’ /etc/fstab
#關閉selinux
setenforce 0 && sed -i ‘s/^SELINUX=.*/SELINUX=disabled/’ /etc/selinux/config
 
#5、調整內核參數,對於k8s
cat > kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
#將優化內核文件拷貝到/etc/sysctl.d/文件夾下,這樣優化文件開機的時候能夠被調用
cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
#手動刷新,讓優化文件立即生效
sysctl -p /etc/sysctl.d/kubernetes.conf
 
#6、調整系統臨時區 — 如果已經設置時區,可略過
#設置系統時區為中國/上海
timedatectl set-timezone Asia/Shanghai
#將當前的 UTC 時間寫入硬體時鐘
timedatectl set-local-rtc 0
#重啟依賴於系統時間的服務
systemctl restart rsyslog
systemctl restart crond
 
#7、關閉系統不需要的服務
systemctl stop postfix && systemctl disable postfix
 
#8、設置日誌保存方式
#1).創建保存日誌的目錄
mkdir /var/log/journal
#2).創建配置文件存放目錄
mkdir /etc/systemd/journald.conf.d
#3).創建配置文件
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
Storage=persistent
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
SystemMaxUse=10G
SystemMaxFileSize=200M
MaxRetentionSec=2week
ForwardToSyslog=no
EOF
#4).重啟systemd journald的配置
systemctl restart systemd-journald
 
#9、kube-proxy 開啟 ipvs 前置條件
modprobe br_netfilter
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe — ip_vs
modprobe — ip_vs_rr
modprobe — ip_vs_wrr
modprobe — ip_vs_sh
modprobe — nf_conntrack_ipv4
EOF
##使用lsmod命令查看這些文件是否被引導
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash
/etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e
nf_conntrack_ipv4

部署docker

curl -sSL //get.daocloud.io/docker | sh
systemctl enable docker && systemctl start docker

kubeadm[一鍵安裝k8s]

#1、安裝kubernetes的時候,需要安裝kubelet, kubeadm等包,但k8s官網給的yum源是
packages.cloud.google.com,中國訪問不了,此時我們可以使用阿里雲的yum倉庫鏡像。
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=//mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=//mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
//mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
#2、安裝kubeadm、kubelet、kubectl
yum install -y kubeadm-1.15.1 kubelet-1.15.1 kubectl-1.15.1
# 啟動 kubelet
systemctl enable kubelet && systemctl start kubelet

集群安裝

網盤中有鏡像文件kubeadm-basic.images

#1、導入鏡像腳本程式碼 (在任意目錄下創建sh腳本文件:image-load.sh)
#!/bin/bash
#注意 鏡像解壓的目錄位置
ls /root/kubeadm-basic.images > /tmp/images-list.txt
cd /root/kubeadm-basic.images
for i in $(cat /tmp/images-list.txt)
do
docker load -i $i
done
rm -rf /tmp/images-list.txt
#2、修改許可權,可執行許可權
chmod 755 image-load.sh
#3、開始執行,鏡像導入
./image-load.sh

k8s部署 

#初始化主節點 — 只需要在主節點執行
#1、拉去yaml資源配置文件
kubeadm config print init-defaults > kubeadm-config.yaml 
#2、修改yaml資源文件
localAPIEndpoint:
advertiseAddress: 192.168.66.10 # 注意:修改配置文件的IP地址
kubernetesVersion: v1.15.1 #注意:修改版本號,必須和kubectl版本保持一致
networking:
# 指定flannel模型通訊 pod網段地址,此網段和flannel網段一致
podSubnet: “10.244.0.0/16”
serviceSubnet: “10.96.0.0/12”
#指定使用ipvs網路進行通訊
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: kubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true
mode: ipvs
#3、初始化主節點,開始部署
kubeadm init –config=kubeadm-config.yaml –experimental-upload-certs | tee
kubeadm-init.log
#注意:執行此命令,CPU核心數量必須大於1核,否則無法執行成功
#4、初始化成功後執行如下命令
#創建目錄,保存連接配置快取,認證文件
mkdir -p $HOME/.kube
#拷貝集群管理配置文件
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
#授權給配置文件
chown $(id -u):$(id -g) $HOME/.kube/config 

flflannel插件

#部署flannel網路插件 — 只需要在主節點執行
#1、下載flannel網路插件
wget //raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-
flannel.yml
#2、部署flannel
kubectl create -f kube-flannel.yml 

節點Join

節點加入需要token和sha256,在主節點上執行以下命令獲取。

創建token

kubeadm token create

m9rrtc.2cm48k5w6ymsprwt

查看token可能有多個,選擇一個沒有過期的即可

kubeadm token list 

獲取 CA 證書 sha256 編碼 hash 值

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed ‘s/^.* //’

4a77cfd6f9e2a16a7a45351369275f102b9986b469d3f9f9865a87050e4bf0dc

在子節點執行以下命令

kubeadm join 主機IP:6443 –token 59mzkj.26xap2hzdhm74ptq –discovery-token-ca-cert-hash sha256:18acdb7c02c6ea696307fde451f44ea0d216e6ccb6777a2a87002d7d45f3845c

在主節點查看。我這裡node2虛擬機關閉了,電腦不行。正常情況下都是Ready

 
注意:如果master或node節點的ip變化了。
kubeadm reset 重置節點
master則重複k8s部署和flflannel插件兩個步驟。
node則重複節點join步驟

Myapp鏡像部署

需要在master和node上配置docker鏡像。

//cr.console.aliyun.com/cn-hangzhou/instances/mirrors?accounttraceid=0cd89c7411274ee48cb11fad06368ba3fxyw

創建pod(部署服務) : kubectl run myapp –image=ikubernetes/myapp:v1 –port=80 –replicas=2 (replicas指定pod數量默認1)

查詢pod創建詳細資訊: kubectl describe pod myapp-554864fdf4-f4gw9

查詢pod: kubectl get pod

查詢pod詳細資訊: kubectl get pod -o 

Kubectl run 首先創建deployment對象,kubectl run 指令執行後創建了3個資源對象(deployment,rs,pod)

注意: 上面這條指令沒有指定副本數量,默認創建了1個pod。如果只有master節點則創建失敗,至少有一個node

如果要刪除徹底刪除pod需要先刪除deployment,然後pod會自動刪除。

kubectl delete deployment myapp

擴容pod

kubectl scale deployment myapp –replicas=4

也可以再次縮容

自愈

K8s管理的pod不僅僅可以一鍵式部署,一鍵式擴容,同時k8s管理的pod還具有自愈能力。也就是說當pod發生故障,宕機,k8s將會自動對pod件重建,因此k8s的pod的副本永遠處於高可用狀態。

刪除所有的pod,查看pod是否還存在: kubectl delete pod –all

負載均衡

Pod有多個副本,訪問pod副本必須實現負載均衡訪問,那麼這個負載均衡訪問是通過service來實現的。因此對一組pod副本創建一個service,進行負載均衡

對一組pod副本創建service: kubectl expose deployment myapp –port=30000 –target-port=80

kubectl get svc

通過測試發現,k8s默認使用輪訓策略。

kubectl delete svc/myapp 刪除service

DNS

安裝k8s時候,安裝dns組件,dns(域名解析伺服器,根據域名解析出真實ip地址,通過dns可以通過服務名進行相互的訪問)

在容器內部通過服務名訪問其他容器

kubectl exec -it myapp-554864fdf4-wsr7h — sh

wget myapp:30000(service名稱) — 測試通過,說明可以通過服務名稱,訪問到外部網路,因此dns伺服器是ok的。

外網訪問

Service 和pod 之間的通訊都屬於區域網通訊訪問。無法對外網直接提供服務,service是一個虛擬化的概念,是一個虛擬IP地址,沒有與之對應的物理硬體資料,無法直接對外網提供服務,必須藉助於物理硬體資源進行數據包轉發。

kubectl edit svc myapp  — 編輯service對應資源對象配置文件,通過修改ip類型,來綁定物理埠。

可以發現32727就是我們所開闢物理埠,此埠可以在配置文件中自定義,也可以默認即可,默認埠範圍:30000 – 32767

滾動更新

項目迭代,不停的發布新的版本,如何實現不停機更新。一鍵式更新操作.滾動更新,發現訪問時候,已經是v2版本的服務.原來的pod開始沒有關閉

等到新版本的pod發布後才把老版本刪除。

YAML方式部署

通過yaml配置文件方式一鍵部署服務。yaml的詳細配置在網盤連接里有。YAML語法規範.md

現在我們要部署一個Nginx服務,先拉去一個docker鏡像,其實可以讓k8s自己下載,但是我要給Nginx打一個tag 

docker pull nginx

編寫yaml文件在網盤鏈接中有

apiVersion: apps/v1 
kind: Deployment 
metadata:
  name: nginx-deployment
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: mynginx
      release: stable
      env: test
  template:
    metadata:
      labels:
        app: mynginx
        release: stable
        env: test
    spec:
      containers:
      - name: my-nginx
        image: nginx:v1
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80

View Code

kubectl apply -f nginx-deploy.yaml 執行腳本

編寫service.yaml

apiVersion: v1 
kind: Service
metadata:
   name: nginx-svc
   namespace: default
spec:
   type: NodePort
   selector:
     app: mynginx
     release: stable
     env: test
   ports:
   - name: http
     port: 80
     targetPort: 80
     nodePort: 30003

View Code

獨立部署pod

自主式的pod: 單獨定義一個pod,這個沒有沒有副本控制器管理,也沒有對應deployment,可以直接刪除pod並且不會自愈。

apiVersion: v1
kind: Pod
metadata:
 name: init-pod
 labels:
   app: myapp
spec:
 containers:
 - name: myapp
   image: ikubernetes/myapp:v1

View Code

kubectl apply -f init-pod.yaml 執行腳本

RS副本控制器

ReplicationController (RC)用來確保容器應用的副本數始終保持在用戶定義的副本數,即如果有容器異常退出,會自動創建新的Pod來替代;而如果異常多出來的容器也會自動回收;

在新版本的Kubernetes中建議使用Replicaset來取代ReplicationController. ReplicaSet跟 ReplicationController沒有本質的不同,只是名字不一樣,並且ReplicaSet支援集合式的selector;

apiVersion: extensions/v1beta1 
kind: ReplicaSet 
metadata:
  name: frontend 
spec:
  replicas: 3
  selector:
    matchLabels: 
      tier: frontend 
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
        - name: myapp
          image: ikubernetes/myapp:v1

View Code

pod刪除後可以自愈

修改pod的標籤後pod就會脫離RS而RS也會重新生成一個pod

刪除副本控制器後pod也會刪除

Deployment-自動擴容

Deployment可以保證在升級時只有一定數量的Pod是down的。默認的,它會確保至少有比期望的Pod數量少一個是up狀態(最多一個不可用)

Deployment同時也可以確保只創建出超過期望數量的一定數量的Pod,默認的,它會確保最多比期望的Pod數量多一個的Pod是up的(最多1個surge )

apiVersion: extensions/v1beta1 
kind: Deployment 
metadata:
  name: nginx-deployment 
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx 
    spec:
      containers: 
        - name: myapp
          image: ikubernetes/myapp:v1

View Code

kubectl autoscale deployment nginx-deployment –min=2 –max=5 –cpu-percent=80

這條指令是說最少兩個pod最多5個單個pod的cpu使用率達到80則創建副本。

Deployment-更新版本

kubectl set image deployment appdeployment(deployment名稱) nginx(container名稱)=ikubernetes/myapp:v2(要更新的鏡像) 

Deployment-回滾版本

kubectl rollout undo deployment appdeployment(deployment名稱)

daemonset

確保只運行一個副本,運行在集群中每一個節點上。而deployment可能只將pod運行在一個節點上。daemonset沒有RS

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: my-deamon
  namespace: default
  labels: 
    app: daemonset
spec:
  selector:
    matchLabels:
      app: my-daemonset
  template:
    metadata:
      labels:
        app: my-daemonset
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1

View Code

job

job負責處理任務,即僅執行一次的任務,下面這個job從倉庫拉去一個鏡像,執行一個循環列印。

apiVersion: batch/v1
kind: Job
metadata:
  name: job-demo
spec:
  template:
    metadata:
      name: job-demo
    spec:
      restartPolicy: Never
      containers:
      - name: counter
        image: busybox
        command:
        - "bin/sh"
        - "-c"
        - "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"

View Code

cronJob

cronJob其實就是在`Job`的基礎上加上了時間調度,我們可以:在給定的時間點運行一個任務,也可以周期性地在給定時間點運行。

以下配置是1分鐘創建一個job執行

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: cronjob-demo
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: hello
            image: busybox
            args:
            - "bin/sh"
            - "-c"
            - "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"

View Code

初始化容器

Pod能夠持有多個容器,應用運行在容器裡面,但是它也可能有一個或多個先於應用容器啟動的Init容器。Init容器與普通的容器非常像,除了如下兩點:1 Init容器總是運行到成功完成為止 2 每個Init容器都必須在下一個Init容器啟動之前成功完成

如果Pod的Init容器失敗,Kubernetes會不斷地重啟該Pod,直到Init容器成功為止。然而,如果Pod對應的restartPolicy為Never,它不會重新啟動。

以下配置為初始化容器休眠2分鐘後創建。然後應用容器才會創建

apiVersion: v1
kind: Pod
metadata:
 name: init-pod
 labels:
   app: myapp
spec:
 containers:
 - name: myapp
   image: nginx
 initContainers:
 - name: init-mydb
   image: nginx
   command: ['sh', '-c', 'echo -n "running at " && date +%T && sleep 120']

View Code