Skip to content

Commit

Permalink
[configmap] feat: add configmap document and code.
Browse files Browse the repository at this point in the history
  • Loading branch information
guangzhengli committed Aug 27, 2022
1 parent 0fb4f74 commit 7161f28
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 241 deletions.
269 changes: 76 additions & 193 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1091,7 +1091,7 @@ curl http://192.168.59.100/

## Namespace

在实际的开发当中,有时候我们需要不同的环境来做开发和测试,例如 `dev` 环境给开发使用,`test` 环境给 QA 使用,那么 k8s 能不能在不同环境 `dev` `test` `uat` `prod` 中区分资源,让不同环境的资源独立不影响呢,答案是肯定的,k8s 提供了名为 Namespace 的资源来帮助隔离资源。
在实际的开发当中,有时候我们需要不同的环境来做开发和测试,例如 `dev` 环境给开发使用,`test` 环境给 QA 使用,那么 k8s 能不能在不同环境 `dev` `test` `uat` `prod` 中区分资源,让不同环境的资源独立互相不影响呢,答案是肯定的,k8s 提供了名为 Namespace 的资源来帮助隔离资源。

在 Kubernetes 中,**名字空间(Namespace)** 提供一种机制,将同一集群中的资源划分为相互隔离的组。 同一名字空间内的资源名称要唯一,但跨名字空间时没有这个要求。 名字空间作用域仅针对带有名字空间的对象,例如 Deployment、Service 等。

Expand Down Expand Up @@ -1132,7 +1132,7 @@ kubectl get namespaces
# test Active 2m44s
```

那么如何在新的 namespace 下创建资源和获取资源呢?只需要在命令后面加上 `-n namespace` 即可。例如根据上面教程中,在名为 `dev` 的 namespace 下创建 `hellok8s:v3` 的 deployment。
那么如何在新的 namespace 下创建资源和获取资源呢?只需要在命令后面加上 `-n namespace` 即可。例如根据上面教程中,在名为 `dev` 的 namespace 下创建 `hellok8s:v3` 的 deployment 资源

```shell
kubectl apply -f deployment.yaml -n dev
Expand All @@ -1142,246 +1142,129 @@ kubectl get pods -n dev

## Configmap

在实际的开发当中,有一些配置是不适合放到 docker image 或者代码中的,例如在不同环境 `dev` `test` `uat` `prod` 中,数据库的地址往往是不一样的,这时就需要有一种资源,能够定义配置信息,并在不同的
上面的教程提到,我们在不同环境 `dev` `test` `uat` `prod` 中区分资源,可以让其资源独立互相不受影响,但是随之而来也会带来一些问题,例如不同环境的数据库的地址往往是不一样的,那么如果在代码中写同一个数据库的地址,就会出现问题。

```ruby
require "sinatra"
K8S 使用 ConfigMap 来将你的配置数据和应用程序代码分开,将非机密性的数据保存到键值对中。ConfigMap 在设计上不是用来保存大量数据的。在 ConfigMap 中保存的数据不可超过 1 MiB。如果你需要保存超出此尺寸限制的数据,你可能考虑挂载存储卷。

set :bind, "0.0.0.0"
下面我们可以来看一个例子,我们修改之前代码,假设不同环境的数据库地址不同,下面代码从环境变量中获取 `DB_URL`,并将它返回。

get "*" do
message = ENV.fetch("MESSAGE", "Hello, Kubernetes")
"[v4] #{message} (from #{`hostname`.strip})\n"
end
```
```go
package main
```
docker build . -t guangzhengli/hellok8s:v4
docker push guangzhengli/hellok8s:v4
import (
"fmt"
"io"
"net/http"
"os"
)
kubectl delete deployment,service,ingress --all
func hello(w http.ResponseWriter, r *http.Request) {
host, _ := os.Hostname()
dbURL := os.Getenv("DB_URL")
io.WriteString(w, fmt.Sprintf("[v4] Hello, Kubernetes! From host: %s, Get Database Connect URL: %s", host, dbURL))
}
func main() {
http.HandleFunc("/", hello)
http.ListenAndServe(":3000", nil)
}
```

```yaml
apiVersion: v1
kind: Service
metadata:
name: hellok8s-svc
spec:
type: NodePort
selector:
app: hellok8s
ports:
- port: 4567
nodePort: 30001
构建 `hellok8s:v4` 的镜像,推送到远程仓库。并删除之前创建的所有资源。

---
```shell
docker build . -t guangzhengli/hellok8s:v4
docker push guangzhengli/hellok8s:v4
apiVersion: apps/v1
kind: Deployment
metadata:
name: hellok8s
spec:
replicas: 2
selector:
matchLabels:
app: hellok8s
template:
metadata:
labels:
app: hellok8s
spec:
containers:
- image: guangzhengli/hellok8s:v4
name: hellok8s-container
kubectl delete deployment,service,ingress --all
```

```shell
kubectl apply -f hellok8s.yaml
接下来创建不同 namespace 的 configmap 来存放 `DB_URL`。

curl localhost:30001
# [v4] Hello, Kubernetes (from hellok8s-69dbd44879-vt8dv)
```
创建 `hellok8s-config-dev.yaml` 文件

```yaml
apiVersion: apps/v1
kind: Deployment
apiVersion: v1
kind: ConfigMap
metadata:
name: hellok8s
spec:
replicas: 2
selector:
matchLabels:
app: hellok8s
template:
metadata:
labels:
app: hellok8s
spec:
containers:
- image: guangzhengli/hellok8s:v4
name: hellok8s-container
env:
- name: MESSAGE
value: "It works!"
```
```shell
kubectl apply -f hellok8s.yaml

curl localhost:30001
# [v4] It works! (from hellok8s-568f64dd94-bfxhs)
name: hellok8s-config
data:
DB_URL: "http://DB_ADDRESS_DEV"
```

### configmap
创建 `hellok8s-config-test.yaml` 文件

```yaml
# hellok8s-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: hellok8s-config
data:
MESSAGE: "It works with a ConfigMap!"
DB_URL: "http://DB_ADDRESS_TEST"
```

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hellok8s
spec:
replicas: 2
selector:
matchLabels:
app: hellok8s
template:
metadata:
labels:
app: hellok8s
spec:
containers:
- image: guangzhengli/hellok8s:v4
name: hellok8s-container
env:
- name: MESSAGE
valueFrom:
configMapKeyRef:
name: hellok8s-config
key: MESSAGE
```
分别在 `dev` `test` 两个 namespace 下创建相同的 `ConfigMap`,名字都叫 hellok8s-config,但是存放的 Pair 对中 Value 值不一样。

```shell
kubectl apply -f hellok8s-config.yaml

kubectl apply -f hellok8s.yaml

kubectl apply -f service.yaml
kubectl apply -f hellok8s-config-dev.yaml -n dev
# configmap/hellok8s-config created
curl localhost:30001
# [v4] It works with a ConfigMap! (from hellok8s-54d5fb5765-nl62z)
```

### Getting all the variables from a ConfigMap
kubectl apply -f hellok8s-config-test.yaml -n test
# configmap/hellok8s-config created
kubectl get configmap --all-namespaces
NAMESPACE NAME DATA AGE
dev hellok8s-config 1 3m12s
test hellok8s-config 1 2m1s
```
env:
- name: VAR1
valueFrom:
configMapKeyRef:
name: hellok8s-config
key: VAR1
- name: VAR2
valueFrom:
configMapKeyRef:
name: hellok8s-config
key: VAR2

- name: VAR3
valueFrom:
configMapKeyRef:
name: hellok8s-config
key: VAR3
# ...
```
接着使用 POD 的方式来部署 `hellok8s:v4`,其中 `env.name` 表示的是将 configmap 中的值写进环境变量,这样代码从环境变量中获取 `DB_URL`,这个 KEY 名称必须保持一致。`valueFrom` 代表从哪里读取,`configMapKeyRef` 这里表示从名为 `hellok8s-config` 的 `configMap` 中读取 `KEY=DB_URL` 的 Value。

```yaml
apiVersion: apps/v1
kind: Deployment
apiVersion: v1
kind: Pod
metadata:
name: hellok8s
name: hellok8s-pod
spec:
replicas: 2
selector:
matchLabels:
app: hellok8s
template:
metadata:
labels:
app: hellok8s
spec:
containers:
- image: guangzhengli/hellok8s:v4
name: hellok8s-container
envFrom:
- configMapRef:
containers:
- name: hellok8s-container
image: guangzhengli/hellok8s:v4
env:
- name: DB_URL
valueFrom:
configMapKeyRef:
name: hellok8s-config
key: DB_URL
```

```
kubectl apply -f hellok8s-updated.yaml
下面分别在 `dev` `test` 两个 namespace 下创建 `hellok8s:v4`,接着通过 `port-forward` 的方式访问不同 namespace 的服务,可以看到返回的 `Get Database Connect URL: http://DB_ADDRESS_TEST` 是不一样的!

curl localhost:30001
# [v4] It works with a ConfigMap! (from hellok8s-54d5fb5765-nl62z)
```
```shell
kubectl apply -f hellok8s.yaml -n dev
# pod/hellok8s-pod created
### Exposing ConfigMap as files
kubectl apply -f hellok8s.yaml -n test
# pod/hellok8s-pod created
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hellok8s
spec:
replicas: 2
selector:
matchLabels:
app: hellok8s
template:
metadata:
labels:
app: hellok8s
spec:
volumes:
- name: config
configMap:
name: hellok8s-config
containers:
- image: guangzhengli/hellok8s:v4
name: hellok8s-container
volumeMounts:
- name: config
mountPath: /config
```
kubectl port-forward hellok8s-pod 3000:3000 -n dev
```shell
kubectl apply -f hellok8s.yaml
kubectl apply -f hellok8s-config.yaml
curl http://localhost:3000
# [v4] Hello, Kubernetes! From host: hellok8s-pod, Get Database Connect URL: http://DB_ADDRESS_DEV
kubectl get pods
# NAME READY STATUS
# hellok8s-8c56675c9-7gxpv 1/1 Running
# hellok8s-8c56675c9-bfk8t 1/1 Running
kubectl port-forward hellok8s-pod 3000:3000 -n test
# Replace the pod name to what you have running locally
kubectl exec -it hellok8s-8c56675c9-7gxpv -- sh
cat /config/MESSAGE
# It works with a ConfigMap!
curl http://localhost:3000
# [v4] Hello, Kubernetes! From host: hellok8s-pod, Get Database Connect URL: http://DB_ADDRESS_TEST
```

作业:如果环境变量有很多的话,还需要这样一个一个写吗?去官网找一种将所有环境变量都挂载的方式。

如何代码不是从环境变量中读取数据,而是从文件中读取呢?去官网找一种将 configmap 挂载到容器文件的方式。

## Secret

上面提到,我们会选择

```yaml
# hellok8s-secret.yaml
apiVersion: v1
Expand Down
19 changes: 15 additions & 4 deletions configmaps/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
FROM ruby:2.6.1-alpine3.9
# Dockerfile
FROM golang:1.16-buster AS builder
RUN mkdir /src
ADD . /src
WORKDIR /src

RUN apk add curl && gem install sinatra
COPY app.rb .
ENTRYPOINT ["ruby", "app.rb"]
RUN go env -w GO111MODULE=auto
RUN go build -o main .

FROM gcr.io/distroless/base-debian10

WORKDIR /

COPY --from=builder /src/main /main
EXPOSE 3000
ENTRYPOINT ["/main"]
8 changes: 0 additions & 8 deletions configmaps/app.rb

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ kind: ConfigMap
metadata:
name: hellok8s-config
data:
MESSAGE: "It works with a ConfigMap!"
DB_URL: "http://DB_ADDRESS_DEV"
6 changes: 6 additions & 0 deletions configmaps/hellok8s-config-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: hellok8s-config
data:
DB_URL: "http://DB_ADDRESS_TEST"
Loading

0 comments on commit 7161f28

Please sign in to comment.