前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubernetes 入门实战 Part1

Kubernetes 入门实战 Part1

作者头像
Yifans_Z
发布2023-08-23 18:59:51
1700
发布2023-08-23 18:59:51
举报

01 初识 Docker

代码语言:javascript
复制
apt install -y docker.io
service docker start
usermod -aG docker ${USER}
代码语言:javascript
复制
docker version
docker info
docker ps
docker pull busybox
# show all images
docker images

https://docs.docker.com/get-started/overview/

02 被隔离的进程

代码语言:javascript
复制
docker pull alpine
docker run -it alpine sh
cat /etc/os-release

隔离资源,保证系统安全,提高资源的利用率。

资源隔离提供了三种技术:namespace、 cgroup、chroot(pivot_rott)。

03 容器化的应用

Build once, Run anywhere.

应用程序不再直接和操作系统打交道,而是封装成镜像,再交给容器环境去运行。

代码语言:javascript
复制
# remove image
docker rmi busybox
# 开启一个交互式操作的 Shell
docker run -it busybox
# 在后台运行
docker run -d busybox
# 为容器起一个名字
docker run -d --name xxx busybox
# 不保存容器,只要运行完毕就自动清除
docker run --rm busybox echo "hello docker"

docker stop xxx
# remove container
docker rm xxx

# show all container
docker ps -a
docker exec xxx echo "hello docker"

05 镜像仓库

用户名/应用名:标签 官方镜像用户名是 library

  • slim 经过精简的
  • fat 包含了较多的辅助工具
  • rc 候选版本,release candidate
代码语言:javascript
复制
docker build -t
docker tag ngx-app chronolaw/ngx-app:1.0
docker push chronolaw/ngx-app:1.0

save 和 load 这两个镜像归档命令:

代码语言:javascript
复制
docker save ngx-app:latest -o ngx.tar
docker load -i ngx.tar

06 打破次元壁

代码语言:javascript
复制
docker run -d --rm --name ubu phusion/baseimage:jammy-1.0.1
echo "hello" > a.txt
# a.txt 拷贝到容器 tmp
docker cp a.txt ubu:/tmp
docker exec -it ubu bash
# 考出容器
docker cp ubu:/tmp/a.txt ./b.txt

容器和主机共享本地目录:

代码语言:javascript
复制
# --mount
# -v /tmp:/tmp:ro 只读
docker run -d --rm -v /tmp:/tmp --name ubu phusion/baseimage:jammy-1.0.1
docker exec -it ubu bash
代码语言:javascript
复制
docker pull python:alpine
docker run -it --rm -v `pwd`:/tmp python:alpine sh

网络模式:null host bridge

代码语言:javascript
复制
# host
docker run -d --rm --net=host --name=ng nginx:alpine
docker exec ng ip addr
docker inspect ng | grep IPAddress
docker stop ng
代码语言:javascript
复制
# bridge 默认模式
docker run -d --rm --name=ng nginx:alpine
docker inspect ng | grep IPAddress
# "IPAddress": "172.17.0.3"
docker run -d --rm --name=rd redis
docker inspect rd | grep IPAddress
# "IPAddress": "172.17.0.4"

分配服务端口号

代码语言:javascript
复制
docker run -d -p 80:80 --rm nginx:alpine
docker run -d -p 8080:80 --rm nginx:alpine
# 分别“映射”到了两个容器里的 80 端口

07 玩转 Docker

Container Image Registry

https://registry.hub.docker.com/_/registry/

代码语言:javascript
复制
docker run -d -p 5000:5000 registry
# 使用 docker tag 命令给镜像打标签再上传
docker tag nginx:alpine 127.0.0.1:5000/nginx:alpine
docker push 127.0.0.1:5000/nginx:alpine
# 本次重新拉取测试
docker rmi 127.0.0.1:5000/nginx:alpine
docker pull 127.0.0.1:5000/nginx:alpine

https://docs.docker.com/registry/spec/api/

代码语言:javascript
复制
# Listing Repositories
curl 127.1:5000/v2/_catalog
# {"repositories":["nginx"]}
curl 127.1:5000/v2/nginx/tags/list
# {"name":"nginx","tags":["alpine"]}

registry 默认会把镜像存储在 Docker 内部目录 /var/lib/registry

搭建 WordPress:

代码语言:javascript
复制
docker run -d --rm \
    --env MARIADB_DATABASE=db \
    --env MARIADB_USER=wp \
    --env MARIADB_PASSWORD=123 \
    --env MARIADB_ROOT_PASSWORD=123 \
    --name mariadb \
    mariadb:10
# 进入 mariadb
docker exec -it mariadb mysql -uwp -p123
# show mariadb ip
docker inspect mariadb | grep IPAddress
# "IPAddress": "172.17.0.2"

docker run -d --rm \
    --env WORDPRESS_DB_HOST=172.17.0.2 \
    --env WORDPRESS_DB_USER=wp \
    --env WORDPRESS_DB_PASSWORD=123 \
    --env WORDPRESS_DB_NAME=db \
    --name wp \
    wordpress:5
docker inspect wp | grep IPAddress
# "IPAddress": "172.17.0.4"
代码语言:javascript
复制
vim wp.conf

server {
  listen 80;
  default_type text/html;
  location / {
      proxy_http_version 1.1;
      proxy_set_header Host $host;
      # wordpress server
      proxy_pass http://172.17.0.4;
  }
}
代码语言:javascript
复制
# 感觉可以直接用 wordpress 的 80,无需再代理一次
docker run -d --rm \
    -p 80:80 \
    -v `pwd`/wp.conf:/etc/nginx/conf.d/default.conf \
    --name ng \
    nginx:alpine
代码语言:javascript
复制
# show logs
docker logs mariadb
docker logs ng
docker logs wp

08 入门篇总结

代码语言:javascript
复制
docker pull alpine
docker run -it alpine sh
uname -a
# Linux de3852b4ec42 5.15.49-linuxkit #1 SMP Tue Sep 13 07:51:46 UTC 2022 x86_64 Linux

# Darwin V_YFANZHAO-MB1 19.6.0 Darwin Kernel Version 19.6.0: Tue Jun 21 21:18:39 PDT 2022; root:xnu-6153.141.66~1/RELEASE_X86_64 x86_64

构建自己的镜像:

https://github.com/chronolaw/k8s_study/blob/master/ch1/Dockerfile

代码语言:javascript
复制
ARG IMAGE_BASE="nginx"
ARG IMAGE_TAG="1.21-alpine"

FROM ${IMAGE_BASE}:${IMAGE_TAG}

ENV PATH=$PATH:/tmp
ENV DEBUG=OFF

COPY ./default.conf /etc/nginx/conf.d/

RUN cd /usr/share/nginx/html \
    && echo "hello nginx" > a.txt

EXPOSE 8081 8082 8083

WORKDIR /etc/nginx
代码语言:javascript
复制
docker build -t ngx-app:1.0 .
docker run -it --rm ngx-app:1.0 sh
docker save ngx-app:1.0 -o ngx.tar
docker load -i ngx.tar

09 Kubernetes 环境

容器编排 Container Orchestration

Kubernetes 就是一个生产级别的容器编排平台和集群管理系统。

https://minikube.sigs.k8s.io/docs/start/

代码语言:javascript
复制
minikube version
# minikube version: v1.29.0
# commit: ddac20b4b34a9c8c857fc602203b6ba2679794d3

# 统一实验环境
minikube start --kubernetes-version=v1.23.3
# 查看状态
minikube status
minikube node list
# minikube 192.168.49.2

# 登录到这个节点上
minikube ssh
uname -a
# Linux minikube 5.15.49-linuxkit #1 SMP Tue Sep 13 07:51:46 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
ip add
代码语言:javascript
复制
# minikube 管理 Kubernetes 集群环境
# kubectl 操作实际的 Kubernetes 功能
# install kubectl
minikube kubectl

minikube kubectl -- version
alias kubectl="minikube kubectl --"
kubectl version

# 启动一个镜像
kubectl run ngx --image=nginx:alpine

# like docker ps
kubectl get pod

https://kubernetes.io/zh/

10 Kubernetes 工作机制

Kubernetes 采用了现今流行的“控制面 / 数据面”(Control Plane / Data Plane)架构,集群里的计算机被称为“节点”(Node),可以是实机也可以是虚机,少量的节点用作控制面来执行集群的管理维护工作,其他的大部分节点都被划归数据面,用来跑业务应用。Master 节点实现管理控制功能,Worker 节点运行具体业务。

代码语言:javascript
复制
kubectl get node
# NAME       STATUS   ROLES                  AGE   VERSION
# minikube   Ready    control-plane,master   38m   v1.23.3

# 查看 master Component pod
kubectl get pod -n kube-system
# NAME                               READY   STATUS    RESTARTS        AGE
# coredns-65c54cc984-4pckd           1/1     Running   0               40m
# etcd-minikube                      1/1     Running   0               40m
# kube-apiserver-minikube            1/1     Running   0               40m
# kube-controller-manager-minikube   1/1     Running   0               40m
# kube-proxy-88wt2                   1/1     Running   0               40m
# kube-scheduler-minikube            1/1     Running   0               40m
# storage-provisioner                1/1     Running   3 (6m39s ago)   40m
代码语言:javascript
复制
# worker node
minikube ssh
# show kube-proxy
docker ps |grep kube-proxy
# show kubelet, not exist docker
ps -ef|grep kubelet
代码语言:javascript
复制
# show addons list
minikube addons list

minikube dashboard

11 YAML

YAML 是 JSON 的超集。

Shell 脚本和 Dockerfile 可以很好地描述“命令式”(Imperative)。“声明式”(Declarative)注重结果。

apiserver 采用了 HTTP 协议的 URL 资源理念,API 风格也用 RESTful,被称为是“API 对象”了。

代码语言:javascript
复制
# 查看 kubectl api-service 支持的所有对象
kubectl api-resources

# 显示出详细的命令执行过程
kubectl get pod --v=9
# 自带的 API 文档 https://kubernetes.io/docs/reference/kubernetes-api/
kubectl explain pod
kubectl explain pod.metadata

# 命令式
kubectl run ngx --image=nginx:alpine
# 转换为 YAML 声名式
kubectl run ngx --image=nginx:alpine --dry-run=client -o yaml > ngx-pod.yml
kubectl apply -f ngx-pod.yml
kubectl delete -f ngx-pod.yml

12 Pod

为了解决这样多应用联合运行的问题,同时还要不破坏容器的隔离,就需要在容器外面再建立一个“收纳舱”。

代码语言:javascript
复制
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: ngx
  name: ngx
spec:
  containers:
    - image: nginx:alpine
      name: ngx
      resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
代码语言:javascript
复制
vim ngx-pod.yml
kubectl apply -f ngx-pod.yml
kubectl logs ngx
kubectl get pod
kubectl describe pod ngx

# cp file to pod
echo 'aaa' > a.txt
kubectl cp a.txt ngx:/tmp

# exec need --
kubectl exec -it ngx -- sh

13 Job CronJob 离线业务

“单一职责”的意思是对象应该只专注于做好一件事情,不要贪大求全,保持足够小的粒度才更方便复用和管理。

“组合优于继承”的意思是应该尽量让对象在运行时产生联系,保持松耦合,而不要用硬编码的方式固定对象的关系。

代码语言:javascript
复制
kubectl create job echo-job --image=busybox --dry-run=client -o yaml > job.yml
代码语言:javascript
复制
apiVersion: batch/v1
kind: Job
metadata:
  creationTimestamp: null
  name: echo-job
spec:
  template:
    metadata:
      creationTimestamp: null
    spec:
      containers:
        - image: busybox
          name: echo-job
          resources: {}
          # 补充输出
          command: ["/bin/echo"]
          args: ["hello", "world"]
      restartPolicy: Never
status: {}
代码语言:javascript
复制
kubectl apply -f job.yml
kubectl get job
# NAME       COMPLETIONS   DURATION   AGE
# echo-job   1/1           16s        33s
kubectl get pod
# NAME             READY   STATUS      RESTARTS   AGE
# echo-job-g2bf6   0/1     Completed   0          68s
kubectl logs echo-job
# hello world
代码语言:javascript
复制
apiVersion: batch/v1
kind: Job
metadata:
  creationTimestamp: null
  name: sleep-job
spec:
  # 设置 Pod 运行的超时时间
  activeDeadlineSeconds: 60
  # 设置 Pod 的失败重试次数
  backoffLimit: 2
  # Job 完成需要运行多少个 Pod,默认是 1
  completions: 4
  # 它与 completions 相关,表示允许并发运行的 Pod 数量,避免过多占用资源
  parallelism: 2

  template:
    metadata:
      creationTimestamp: null
    spec:
      containers:
        - image: busybox
          name: echo-job
          resources: {}
          # 随机休眠
          command:
            - sh
            - -c
            - sleep $(($RANDOM % 10 + 1)) && echo done
      restartPolicy: Never
status: {}
代码语言:javascript
复制
kubectl apply -f sleep-job.yaml

kubectl get pod -w
# NAME              READY   STATUS      RESTARTS   AGE
# sleep-job-92m4d   0/1     Completed   0          30s
# sleep-job-g8pmj   0/1     Completed   0          15s
# sleep-job-tsncl   0/1     Completed   0          30s
# sleep-job-x4qlp   0/1     Completed   0          15s
代码语言:javascript
复制
# cronjob
kubectl create cj echo-cj --image=busybox --schedule="*/1 * * * *" --dry-run=client -o yaml > echo-cj.yaml
代码语言:javascript
复制
apiVersion: batch/v1
kind: CronJob
metadata:
  creationTimestamp: null
  name: echo-cj
spec:
  jobTemplate:
    metadata:
      creationTimestamp: null
      name: echo-cj
    spec:
      template:
        metadata:
          creationTimestamp: null
        spec:
          containers:
            - image: busybox
              name: echo-cj
              resources: {}
              # 补充输出
              command: ["/bin/echo"]
              args: ["hello", "world"]
          restartPolicy: OnFailure
  schedule: "*/1 * * * *"
status: {}
代码语言:javascript
复制
kubectl apply -f echo-cj.yaml
kubectl get cj
# NAME      SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
# echo-cj   */1 * * * *   False     1        5s              8s
kubectl get pod
# NAME                     READY   STATUS      RESTARTS   AGE
# echo-cj-27942326-qng4j   0/1     Completed   0          93s
# echo-cj-27942327-vlrvs   0/1     Completed   0          33s

14 ConfigMap Secret 管理配置信息

代码语言:javascript
复制
kubectl create cm info --from-literal=name=zhao --dry-run=client -o yaml > cm.yml
kubectl apply -f cm.yml
kubectl get cm
kubectl describe cm info
代码语言:javascript
复制
kubectl create secret generic user --from-literal=name=root --dry-run=client -o yaml > secret.yml

# -n 去掉字符串里隐含的换行符
echo -n "root" | base64
kubectl apply -f secret.yml
kubectl get secret
kubectl describe secret user
代码语言:javascript
复制
kubectl explain pod.spec.containers.env.valueFrom
代码语言:javascript
复制
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: ngx
  name: ngx
spec:
  containers:
    - image: nginx:alpine
      name: ngx
      resources: {}
      env:
        - name: NAME
          valueFrom:
            configMapKeyRef:
              name: info
              key: name
        - name: SNAME
          valueFrom:
            secretKeyRef:
              name: user
              key: name
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
代码语言:javascript
复制
kubectl apply -f env-pod.yml
kubectl exec -it ngx -- sh

echo $NAME $SNAME
代码语言:javascript
复制
# 以 Volume 的方式使用 ConfigMap/Secret
apiVersion: v1
kind: Pod
metadata:
  name: vol-pod
spec:
  # Volume 属于 Pod 与 containers 同级
  volumes:
    - name: cm-vol
      configMap:
        name: info
    - name: sec-vol
      secret:
        secretName: user
  containers:
    # 挂载到容器里的某个路径下
    - volumeMounts:
        - mountPath: /tmp/cm-items
          name: cm-vol
        - mountPath: /tmp/sec-items
          name: sec-vol
      image: nginx:alpine
      name: ngx
      resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
代码语言:javascript
复制
vim vol-pod.yml
kubectl apply -f vol-pod.yml
kubectl get pod
kubectl exec -it vol-pod -- sh

cat /tmp/cm-items/name
cat /tmp/sec-items/name
# ConfigMap 和 Secret 都变成了目录的形式,而它们里面的 Key-Value 变成了一个个的文件,而文件名就是 Key。

15 玩转 Kubernetes

搭建 WordPress 环境:

代码语言:javascript
复制
# vim mariadb-pod.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: maria-cm
data:
  DATABASE: "db"
  USER: "wp"
  PASSWORD: "123"
  ROOT_PASSWORD: "123"

---
apiVersion: v1
kind: Pod
metadata:
  name: maria-pod
  labels:
    app: wordpress
    role: database
spec:
  containers:
    - image: mariadb:10
      name: maria
      imagePullPolicy: IfNotPresent
      ports:
        - containerPort: 3306
      envFrom:
        - prefix: "MARIADB_"
          configMapRef:
            name: maria-cm
代码语言:javascript
复制
kubectl apply -f mariadb-pod.yml
# 获取 IP 地址需要加上参数 -o wide
kubectl get pod -o wide
# NAME        READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
# maria-pod   1/1     Running   0          64s   172.17.0.5   minikube   <none>           <none>
代码语言:javascript
复制
# vim wp-pod.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: wp-cm
data:
  # MariaDB Pod 的 IP
  HOST: "172.17.0.5"
  USER: "wp"
  PASSWORD: "123"
  NAME: "db"

---
apiVersion: v1
kind: Pod
metadata:
  name: wp-pod
  labels:
    app: wordpress
    role: website
spec:
  containers:
    - image: wordpress:5
      name: wp-pod
      imagePullPolicy: IfNotPresent
      ports:
        - containerPort: 80
      envFrom:
        - prefix: "WORDPRESS_DB_"
          configMapRef:
            name: wp-cm
代码语言:javascript
复制
kubectl apply -f wp-pod.yml
kubectl get pod -o wide
# NAME        READY   STATUS    RESTARTS   AGE     IP           NODE       NOMINATED NODE   READINESS GATES
# maria-pod   1/1     Running   0          160m    172.17.0.5   minikube   <none>           <none>
# wp-pod      1/1     Running   0          2m47s   172.17.0.6   minikube   <none>           <none>
代码语言:javascript
复制
# 本地的 “8080” 映射到 WordPress Pod 的“80”
kubectl port-forward wp-pod 8080:80 &
# Forwarding from 127.0.0.1:8080 -> 80
# Forwarding from [::1]:8080 -> 80
# fg

16 初级篇总结

代码语言:javascript
复制
minikube version
minikube status
minikube start --kubernetes-version=v1.23.3
minikube node list

kubectl version
kubectl run ngx --image=nginx:alpine

# apiserver 等核心组件是在 kube-system 名字空间
kubectl get pod -n kube-system

kubectl api-resources
kubectl explain pod.metadata

export out="--dry-run=client -o yaml"
kubectl run ngx --image=nginx:alpine $out > pod.yml

kubectl apply -f ngx-pod.yml
kubectl get pod
kubectl logs ngx-pod
kubectl exec -it ngx-pod -- sh
kubectl delete -f ngx-pod

kubectl create job echo-job --image=busybox $out
kubectl apply -f job.yml
kubectl get job
kubectl get pod
kubectl logs echo-job-l52l7

kubectl create cj echo-cj --image=busybox --schedule="* * * * *" $out
kubectl apply -f cronjob.yml
kubectl get cj
kubectl get pod

kubectl create cm info --from-literal=k=v $out
kubectl get cm
kubectl describe cm info

kubectl create secret generic user --from-literal=name=root $out
kubectl get secret
kubectl describe secret user

echo cm9vdA== | base64 -d

References

– EOF –

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-02-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01 初识 Docker
  • 02 被隔离的进程
  • 03 容器化的应用
  • 05 镜像仓库
  • 06 打破次元壁
  • 07 玩转 Docker
  • 08 入门篇总结
  • 09 Kubernetes 环境
  • 10 Kubernetes 工作机制
  • 11 YAML
  • 12 Pod
  • 13 Job CronJob 离线业务
  • 14 ConfigMap Secret 管理配置信息
  • 15 玩转 Kubernetes
  • 16 初级篇总结
  • References
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com